| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669 |
- //
- // Copyright 2017 Google Inc.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- // stylelint-disable selector-class-pattern --
- // Selector '.mdc-*' should only be used in this project.
- @use 'sass:math';
- @use 'sass:list';
- @use 'sass:meta';
- @use 'sass:map';
- @use '@material/animation/animation';
- @use '@material/theme/css';
- @use '@material/density/functions' as density-functions;
- @use '@material/dom/dom';
- @use '@material/floating-label/mixins' as floating-label-mixins;
- @use '@material/floating-label/variables' as floating-label-variables;
- @use '@material/line-ripple/mixins' as line-ripple-mixins;
- @use '@material/notched-outline/mixins' as notched-outline-mixins;
- @use '@material/notched-outline/variables' as notched-outline-variables;
- @use '@material/ripple/ripple';
- @use '@material/ripple/ripple-theme';
- @use '@material/theme/custom-properties';
- @use '@material/theme/theme';
- @use '@material/shape/mixins' as shape-mixins;
- @use '@material/shape/functions' as shape-functions;
- @use '@material/feature-targeting/feature-targeting';
- @use '@material/typography/typography';
- @use 'helper-text/mixins' as helper-text-mixins;
- @use 'character-counter/mixins' as character-counter-mixins;
- @use 'icon/mixins' as icon-mixins;
- @use 'icon/variables' as icon-variables;
- @use './variables';
- @use '@material/rtl/rtl';
- $_density-config: map.merge(
- variables.$density-config,
- (
- minimum: math.min(variables.$minimum-height, 36px),
- )
- );
- @mixin core-styles($query: feature-targeting.all()) {
- @include ripple($query);
- @include static-styles($query);
- @include helper-text-mixins.helper-text-core-styles($query);
- @include character-counter-mixins.character-counter-core-styles($query);
- @include icon-mixins.icon-core-styles($query);
- }
- /// @deprecated Use static-styles() instead.
- @mixin without-ripple($query: feature-targeting.all()) {
- @include static-styles($query);
- }
- @mixin static-styles($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- // Baseline
- // postcss-bem-linter: define text-field
- .mdc-text-field {
- @include _base($query);
- }
- .mdc-text-field__input {
- @include _input($query);
- @include placeholder-selector_ {
- @include _input-placeholder($query);
- }
- // Always show placeholder for text fields that has no
- // label and show only on focused state when label is present.
- .mdc-text-field--no-label &,
- .mdc-text-field--focused & {
- @include placeholder-selector_ {
- @include _input-placeholder-visible($query);
- }
- }
- }
- .mdc-text-field__affix {
- @include _affix($query: $query);
- .mdc-text-field--label-floating &,
- .mdc-text-field--no-label & {
- @include _affix-visible($query: $query);
- }
- // Safari only
- @supports (-webkit-hyphens: none) {
- .mdc-text-field--outlined & {
- @include _centered-affix-safari-support($query: $query);
- }
- }
- }
- .mdc-text-field__affix--prefix {
- @include _prefix($query: $query);
- .mdc-text-field--end-aligned & {
- @include _prefix-end-aligned($query: $query);
- }
- }
- .mdc-text-field__affix--suffix {
- @include _suffix($query: $query);
- .mdc-text-field--end-aligned & {
- @include _suffix-end-aligned($query: $query);
- }
- }
- // Variants
- .mdc-text-field--filled {
- @include _filled($query);
- &.mdc-text-field--no-label {
- @include filled-no-label($query);
- }
- }
- .mdc-text-field--outlined {
- @include outlined_($query);
- .mdc-notched-outline {
- @include _outlined-notched-outline($query);
- }
- }
- // Other Variations
- .mdc-text-field--textarea {
- @include textarea_($query);
- .mdc-text-field__input {
- @include _textarea-input($query);
- }
- &.mdc-text-field--filled {
- @include _textarea-filled($query);
- .mdc-text-field__input {
- @include _textarea-filled-input($query);
- }
- &.mdc-text-field--no-label {
- .mdc-text-field__input {
- @include _textarea-filled-no-label-input($query);
- }
- }
- }
- &.mdc-text-field--outlined {
- @include _textarea-outlined($query);
- .mdc-text-field__input {
- @include _textarea-outlined-input($query);
- }
- .mdc-floating-label {
- @include _textarea-outlined-floating-label($query);
- }
- }
- &.mdc-text-field--with-internal-counter {
- .mdc-text-field__input {
- @include _textarea-input-with-internal-counter($query);
- }
- .mdc-text-field-character-counter {
- @include _textarea-internal-counter($query);
- }
- }
- }
- // Resizer element does not need to be under mdc-text-field--textarea, that
- // just adds specificity
- .mdc-text-field__resizer {
- @include _textarea-resizer($query);
- .mdc-text-field--filled & {
- @include _textarea-filled-resizer($query);
- .mdc-text-field__input,
- .mdc-text-field-character-counter {
- @include _textarea-filled-resizer-children($query);
- }
- }
- .mdc-text-field--outlined & {
- @include _textarea-outlined-resizer($query);
- .mdc-text-field__input,
- .mdc-text-field-character-counter {
- @include _textarea-outlined-resizer-children($query);
- }
- }
- }
- .mdc-text-field--with-leading-icon {
- @include _padding-horizontal-with-leading-icon($query);
- &.mdc-text-field--filled {
- @include with-leading-icon_($query);
- }
- &.mdc-text-field--outlined {
- @include outlined-with-leading-icon_($query);
- }
- }
- .mdc-text-field--with-trailing-icon {
- @include _padding-horizontal-with-trailing-icon($query);
- &.mdc-text-field--filled {
- @include _with-trailing-icon($query);
- }
- &.mdc-text-field--outlined {
- @include _outlined-with-trailing-icon($query);
- }
- }
- .mdc-text-field--with-leading-icon.mdc-text-field--with-trailing-icon {
- @include _padding-horizontal-with-both-icons($query);
- &.mdc-text-field--filled {
- @include _with-leading-and-trailing-icon($query);
- }
- }
- // postcss-bem-linter: define text-field-helper-text
- .mdc-text-field-helper-line {
- @include feature-targeting.targets($feat-structure) {
- display: flex;
- justify-content: space-between;
- box-sizing: border-box;
- }
- .mdc-text-field + & {
- @include feature-targeting.targets($feat-structure) {
- padding-right: variables.$helper-line-padding;
- padding-left: variables.$helper-line-padding;
- }
- }
- }
- // postcss-bem-linter: end
- // mdc-form-field tweaks to align text field label correctly
- // stylelint-disable selector-max-type --
- // TODO: document why this disable is neccessary
- .mdc-form-field > .mdc-text-field + label {
- @include feature-targeting.targets($feat-structure) {
- align-self: flex-start;
- }
- }
- // stylelint-enable selector-max-type
- // States
- .mdc-text-field--focused {
- @include focused_($query);
- &.mdc-text-field--outlined {
- @include _focused-outlined($query);
- &.mdc-text-field--textarea {
- @include _focused-outlined-textarea($query);
- }
- }
- }
- .mdc-text-field--invalid {
- @include invalid_($query);
- }
- .mdc-text-field--disabled {
- @include disabled_($query);
- &.mdc-text-field--filled {
- @include _disabled-filled($query);
- }
- .mdc-text-field__input {
- @include _disabled-input($query);
- }
- }
- .mdc-text-field--end-aligned {
- @include end-aligned_($query);
- }
- .mdc-text-field--ltr-text {
- @include _ltr-text($query);
- &.mdc-text-field--end-aligned {
- @include _ltr-text-end-aligned($query);
- }
- }
- }
- // This API is intended for use by frameworks that may want to separate the ripple-related styles
- // from the other text field styles. It is recommended that most users use `mdc-text-field-core-styles` instead.
- @mixin ripple($query: feature-targeting.all()) {
- @include ripple.common($query); // COPYBARA_COMMENT_THIS_LINE
- .mdc-text-field--filled {
- @include ripple.surface(
- $query: $query,
- $ripple-target: variables.$ripple-target
- );
- @include ripple.radius-bounded(
- $query: $query,
- $ripple-target: variables.$ripple-target
- );
- }
- #{variables.$ripple-target} {
- @include ripple.target-common($query: $query);
- }
- }
- ///
- /// Sets density scale for default text field variant.
- ///
- /// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values `-4`,
- /// `-3`, `-2`, `-1`, `0`. Default is `0`.
- /// @param {Number} $minimum-height-for-filled-label Sets the minimum height for
- /// filled textfields at which to allow floating labels.
- ///
- @mixin density(
- $density-scale,
- $minimum-height-for-filled-label: variables.$minimum-height-for-filled-label,
- $query: feature-targeting.all()
- ) {
- $height: density-functions.prop-value(
- $density-config: $_density-config,
- $density-scale: $density-scale,
- $property-name: height,
- );
- @include height(
- $height,
- $minimum-height-for-filled-label: $minimum-height-for-filled-label,
- $query: $query
- );
- // TODO(b/151839219): resize icons and adjust label position
- // @if $density-scale < 0 {
- // @include icon-mixins.size(icon-variables.$dense-icon-size);
- // }
- }
- ///
- /// Sets density scale for outlined text field (Excluding outlined text field with leading icon).
- ///
- /// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values `-4`,
- /// `-3`, `-2`, `-1`, `0`. Default is `0`.
- ///
- @mixin outlined-density($density-scale, $query: feature-targeting.all()) {
- $height: density-functions.prop-value(
- $density-config: $_density-config,
- $density-scale: $density-scale,
- $property-name: height,
- );
- @include outlined-height($height, $query: $query);
- // TODO(b/151839219): resize icons and adjust label position
- // @if $density-scale < 0 {
- // @include icon-mixins.size(icon-variables.$dense-icon-size);
- // }
- }
- ///
- /// Sets density scale for outlined text field with leading icon.
- ///
- /// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values `-4`,
- /// `-3`, `-2`, `-1`, `0`. Default is `0`.
- ///
- @mixin outlined-with-leading-icon-density(
- $density-scale,
- $query: feature-targeting.all()
- ) {
- $height: density-functions.prop-value(
- $density-config: $_density-config,
- $density-scale: $density-scale,
- $property-name: height,
- );
- @include outlined-with-leading-icon-height($height, $query: $query);
- // TODO(b/151839219): resize icons and adjust label position
- // @if $density-scale < 0 {
- // @include icon-mixins.size(icon-variables.$dense-icon-size);
- // }
- }
- ///
- /// Sets density scale for filled textarea.
- ///
- /// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values `-4`,
- /// `-3`, `-2`, `-1`, `0`. Default is `0`.
- ///
- @mixin filled-textarea-density(
- $density-scale,
- $query: feature-targeting.all()
- ) {
- $feat-structure: feature-targeting.create-target($query, structure);
- $textfield-height: density-functions.prop-value(
- $density-config: $_density-config,
- $density-scale: $density-scale,
- $property-name: height,
- );
- $no-label-margin-top: density-functions.prop-value(
- $density-config: variables.$textarea-filled-no-label-density-config,
- $density-scale: math.div($density-scale, 2),
- $property-name: margin-top,
- );
- $no-label-margin-bottom: density-functions.prop-value(
- $density-config: variables.$textarea-filled-no-label-density-config,
- $density-scale: math.div($density-scale, 2),
- $property-name: margin-bottom,
- );
- // Textarea mixins require two modifier classes since two are used internally
- // for styles (textarea and filled). An extra class is added for the public
- // mixin so that only a single public class is needed for specificity.
- &.mdc-text-field--filled {
- .mdc-text-field__resizer {
- @include feature-targeting.targets($feat-structure) {
- min-height: $textfield-height;
- }
- }
- @if $density-scale >= -1 {
- $keyframe-suffix: text-field-filled-#{$density-scale};
- $label-top: density-functions.prop-value(
- $density-config: variables.$textarea-filled-label-density-config,
- $density-scale: math.div($density-scale, 2),
- $property-name: top,
- );
- // Adjust the floating position and animation/keyframes of the floating
- // label by the new position of the resting label
- $label-top-difference: variables.$textarea-outlined-label-top -
- $label-top;
- // Floating label position
- @include floating-label-mixins.float-position(
- variables.$textarea-filled-label-position-y - $label-top-difference,
- $query: $query
- );
- // Floating label animation
- @include floating-label-mixins.shake-animation(
- $keyframe-suffix,
- $query: $query
- );
- @at-root {
- @include floating-label-mixins.shake-keyframes(
- $keyframe-suffix,
- variables.$textarea-filled-label-position-y - $label-top-difference,
- 0%,
- $query: $query
- );
- }
- // Resting label position
- .mdc-floating-label {
- @include feature-targeting.targets($feat-structure) {
- top: $label-top;
- }
- }
- $margin-bottom: density-functions.prop-value(
- $density-config: variables.$textarea-filled-density-config,
- $density-scale: $density-scale,
- $property-name: margin-bottom,
- );
- .mdc-text-field__input {
- @include feature-targeting.targets($feat-structure) {
- margin-bottom: $margin-bottom;
- }
- }
- } @else {
- // The textarea is too dense to show a floating label
- .mdc-floating-label {
- @include feature-targeting.targets($feat-structure) {
- display: none;
- }
- }
- .mdc-text-field__input {
- @include feature-targeting.targets($feat-structure) {
- margin-top: $no-label-margin-top;
- margin-bottom: $no-label-margin-bottom;
- }
- }
- }
- &.mdc-text-field--no-label {
- .mdc-text-field__input {
- @include feature-targeting.targets($feat-structure) {
- margin-top: $no-label-margin-top;
- margin-bottom: $no-label-margin-bottom;
- }
- }
- }
- &.mdc-text-field--with-internal-counter {
- .mdc-text-field__input {
- // Space between textarea and internal counter should not be affected
- @include _textarea-input-with-internal-counter($query);
- }
- }
- }
- }
- ///
- /// Sets density scale for outlined textarea.
- ///
- /// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values `-4`,
- /// `-3`, `-2`, `-1`, `0`. Default is `0`.
- ///
- @mixin outlined-textarea-density(
- $density-scale,
- $query: feature-targeting.all()
- ) {
- $feat-structure: feature-targeting.create-target($query, structure);
- $keyframe-suffix: text-field-outlined-#{$density-scale};
- $label-top: density-functions.prop-value(
- $density-config: variables.$textarea-outlined-label-density-config,
- $density-scale: math.div($density-scale, 2),
- $property-name: top,
- );
- $textfield-height: density-functions.prop-value(
- $density-config: $_density-config,
- $density-scale: $density-scale,
- $property-name: height,
- );
- $margin-top: density-functions.prop-value(
- $density-config: variables.$textarea-outlined-density-config,
- $density-scale: math.div($density-scale, 2),
- $property-name: margin-top,
- );
- $margin-bottom: density-functions.prop-value(
- $density-config: variables.$textarea-outlined-density-config,
- $density-scale: math.div($density-scale, 2),
- $property-name: margin-bottom,
- );
- // Textarea mixins require two modifier classes since two are used internally
- // for styles (textarea and outlined). An extra class is added for the public
- // mixin so that only a single public class is needed for specificity.
- &.mdc-text-field--outlined {
- // Adjust the floating position and animation/keyframes of the floating
- // label by the new position of the resting label
- $label-top-difference: variables.$textarea-outlined-label-top - $label-top;
- // Floating label position
- @include notched-outline-mixins.floating-label-float-position-absolute(
- variables.$textarea-outlined-label-position-y - $label-top-difference,
- $query: $query
- );
- // Floating label animation
- @include floating-label-mixins.shake-animation(
- $keyframe-suffix,
- $query: $query
- );
- @at-root {
- @include floating-label-mixins.shake-keyframes(
- $keyframe-suffix,
- variables.$textarea-outlined-label-position-y - $label-top-difference,
- 0%,
- $query: $query
- );
- }
- // Resting label position
- .mdc-floating-label {
- @include feature-targeting.targets($feat-structure) {
- top: $label-top;
- }
- }
- .mdc-text-field__resizer {
- @include feature-targeting.targets($feat-structure) {
- min-height: $textfield-height;
- }
- }
- .mdc-text-field__input {
- @include feature-targeting.targets($feat-structure) {
- margin-top: $margin-top;
- margin-bottom: $margin-bottom;
- }
- }
- &.mdc-text-field--with-internal-counter {
- .mdc-text-field__input {
- // Space between textarea and internal counter should not be affected
- @include _textarea-input-with-internal-counter($query);
- }
- }
- }
- }
- ///
- /// Sets the minimum number of rows for a textarea a textarea may be resized to.
- ///
- /// For IE11 this mixin can be used instead of the rows attribute.
- ///
- /// @param {Number} $rows - The minimum number of rows for a textarea.
- /// @param {Number} $line-height - The line-height of the textarea.
- ///
- @mixin textarea-min-rows(
- $rows,
- $line-height: variables.$textarea-line-height,
- $query: feature-targeting.all()
- ) {
- $feat-structure: feature-targeting.create-target($query, structure);
- .mdc-text-field__input {
- @include feature-targeting.targets($feat-structure) {
- min-height: $rows * $line-height;
- }
- }
- }
- ///
- /// Sets height of default text field variant.
- ///
- /// @param {Number} $height
- /// @param {Number} $minimum-height-for-filled-label Sets the minimum height for
- /// filled textfields at which to allow floating labels.
- /// @access public
- ///
- @mixin height(
- $height,
- $minimum-height-for-filled-label: variables.$minimum-height-for-filled-label,
- $query: feature-targeting.all()
- ) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- @include theme.property(height, $height);
- }
- // We can only hide the label (when there's not enough vertical space for it)
- // if we know the container height at compilation time.
- // That's not the case when $height is a custom property.
- @if not custom-properties.is-custom-prop($height) {
- @if $height < $minimum-height-for-filled-label {
- @include filled-no-label($query: $query);
- }
- }
- }
- ///
- /// Sets height of outlined text field variant (Excluding outlined text field with leading icon).
- ///
- /// @param {Number} $height
- /// @param {String} $keyframe-suffix - Optional suffix to use for generated
- /// floating label keyframes
- /// @access public
- ///
- @mixin outlined-height(
- $height,
- $keyframe-suffix: text-field-outlined-#{$height},
- $query: feature-targeting.all()
- ) {
- $feat-structure: feature-targeting.create-target($query, structure);
- $positionY: variables.get-outlined-label-position-y($height);
- // Floating label position
- @include notched-outline-mixins.floating-label-float-position-absolute(
- $positionY,
- $query: $query
- );
- // Floating label animation
- @include floating-label-mixins.shake-animation(
- $keyframe-suffix,
- $query: $query
- );
- @at-root {
- @include floating-label-mixins.shake-keyframes(
- $keyframe-suffix,
- $positionY,
- $query: $query
- );
- }
- @include feature-targeting.targets($feat-structure) {
- height: $height;
- }
- }
- ///
- /// Sets height of outlined text field with leading icon variant.
- ///
- /// @param {Number} $height
- /// @param {String} $keyframe-suffix - Optional suffix to use for generated
- /// floating label keyframes
- /// @access public
- ///
- @mixin outlined-with-leading-icon-height(
- $height,
- $keyframe-suffix: null,
- $query: feature-targeting.all()
- ) {
- $feat-structure: feature-targeting.create-target($query, structure);
- // This extra specificity is needed because textfield applies the below mixin
- // already to two selectors (outlined + with-leading-icon). To override
- // them with a new label position and animation, another selector is needed.
- &.mdc-text-field--outlined {
- @include _outlined-with-leading-icon-floating-label-position-animation(
- $height,
- $keyframe-suffix,
- $query
- );
- }
- @include feature-targeting.targets($feat-structure) {
- height: $height;
- }
- }
- // Mixin that sets the floating label position and animations for a given height.
- // This mixin is separate to allow outlined-with-leading-icon-height() to
- // provide greater specificity over the default mixin that adds styles for
- // outlined with leading icons.
- @mixin _outlined-with-leading-icon-floating-label-position-animation(
- $height,
- $keyframe-suffix: text-field-outlined-with-leading-icon-#{$height},
- $query: feature-targeting.all()
- ) {
- $positionY: variables.get-outlined-label-position-y($height);
- // Floating label position
- @include notched-outline-mixins.floating-label-float-position-absolute(
- $positionY,
- variables.$outlined-with-leading-icon-label-position-x,
- $query: $query
- );
- // Floating label animation
- @include floating-label-mixins.shake-animation(
- $keyframe-suffix,
- $query: $query
- );
- @at-root {
- @include floating-label-mixins.shake-keyframes(
- $keyframe-suffix,
- $positionY,
- variables.$outlined-with-leading-icon-label-position-x,
- $query: $query
- );
- }
- $keyframe-suffix-rtl: #{$keyframe-suffix}-rtl;
- @include rtl.rtl {
- @include floating-label-mixins.shake-animation(
- $keyframe-suffix,
- $query: $query
- );
- }
- @at-root {
- @include floating-label-mixins.shake-keyframes(
- $keyframe-suffix-rtl,
- $positionY,
- -(variables.$outlined-with-leading-icon-label-position-x),
- $query: $query
- );
- }
- }
- ///
- /// Sets shape radius of default text field variant.
- ///
- /// @param {Number} $radius Shape radius value in `px` or in percentage.
- /// @param {Number} $text-field-height Height of default text field variant. Required only when `$radius` is in
- /// percentage unit and if text field has custom height. Defaults to `variables.$height`.
- /// @param {Boolean} $rtl-reflexive Set to true to flip shape radius in RTL context. Defaults to `false`.
- ///
- @mixin shape-radius(
- $radius,
- $density-scale: variables.$density-scale,
- $rtl-reflexive: false,
- $query: feature-targeting.all()
- ) {
- @if (meta.type-of($radius) == 'list') and
- (list.length($radius) > 2) and
- (list.nth($radius, 3) != 0 or list.nth($radius, 4) != 0)
- {
- @error "mdc-textfield: Invalid radius #{$radius}. Only top-left and top-right corners may be customized.";
- }
- $height: density-functions.prop-value(
- $density-config: $_density-config,
- $density-scale: $density-scale,
- $property-name: height,
- );
- $masked-radius: shape-functions.mask-radius($radius, 1 1 0 0);
- $fallback: if(
- custom-properties.is-custom-prop($radius),
- custom-properties.get-fallback($radius),
- null
- );
- @if meta.type-of($fallback) == 'list' {
- $fallback: css.unpack-value($fallback);
- $first: list.nth($masked-radius, 1);
- $second: list.nth($masked-radius, 2);
- $third: list.nth($masked-radius, 3);
- $fourth: list.nth($masked-radius, 4);
- $masked-radius: (
- if(
- custom-properties.is-custom-prop($first),
- custom-properties.set-fallback($first, list.nth($fallback, 1)),
- $first
- ),
- if(
- custom-properties.is-custom-prop($second),
- custom-properties.set-fallback($second, list.nth($fallback, 2)),
- $second
- ),
- if(
- custom-properties.is-custom-prop($third),
- custom-properties.set-fallback($third, list.nth($fallback, 3)),
- $third
- ),
- if(
- custom-properties.is-custom-prop($fourth),
- custom-properties.set-fallback($fourth, list.nth($fallback, 4)),
- $fourth
- )
- );
- }
- @include shape-mixins.radius(
- $masked-radius,
- $rtl-reflexive,
- $component-height: $height,
- $query: $query
- );
- }
- @mixin textarea-shape-radius(
- $radius,
- $rtl-reflexive: false,
- $query: feature-targeting.all()
- ) {
- @include notched-outline-mixins.shape-radius(
- $radius,
- $rtl-reflexive,
- $query: $query
- );
- }
- ///
- /// Customizes the color of the text entered into an enabled text field.
- /// @param {Color} $color - The desired input text color.
- ///
- @mixin ink-color($color, $query: feature-targeting.all()) {
- @include if-enabled_ {
- @include ink-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the color of the entered text in a disabled text field.
- /// @param {Color} $color - The desired input text color.
- ///
- @mixin disabled-ink-color($color, $query: feature-targeting.all()) {
- @include if-disabled_ {
- @include ink-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the color of the placeholder in an enabled text field.
- /// @param {Color} $color - The desired placeholder text color.
- ///
- @mixin placeholder-color($color, $query: feature-targeting.all()) {
- @include if-enabled_ {
- @include placeholder-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the color of the placeholder in a disabled text field.
- /// @param {Color} $color - The desired placeholder text color.
- ///
- @mixin disabled-placeholder-color($color, $query: feature-targeting.all()) {
- @include if-disabled_ {
- @include placeholder-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the background color of the text field or textarea when enabled.
- /// @param {Color} $color - The desired background color.
- ///
- @mixin fill-color($color, $query: feature-targeting.all()) {
- @include if-enabled_ {
- @include fill-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the background color of the text field or textarea when disabled.
- /// @param {Color} $color - The desired background color.
- ///
- @mixin disabled-fill-color($color, $query: feature-targeting.all()) {
- @include if-disabled_ {
- @include fill-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the text field bottom line color for the filled variant.
- /// @param {Color} $color - The desired bottom line color.
- ///
- @mixin bottom-line-color($color, $query: feature-targeting.all()) {
- @include if-enabled_ {
- @include bottom-line-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the disabled text field bottom line color for the filled variant.
- /// @param {Color} $color - The desired bottom line color.
- ///
- @mixin disabled-bottom-line-color($color, $query: feature-targeting.all()) {
- @include if-disabled_ {
- @include bottom-line-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the hover text field bottom line color for the filled variant.
- /// @param {Color} $color - The desired bottom line color.
- ///
- @mixin hover-bottom-line-color($color, $query: feature-targeting.all()) {
- @include if-enabled_ {
- @include hover-bottom-line-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the color of the default line ripple of the text field.
- /// @param {Color} $color - The desired line ripple color.
- ///
- @mixin line-ripple-color($color, $query: feature-targeting.all()) {
- @include if-enabled_ {
- @include line-ripple-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the text color of the label in an enabled text field.
- /// @param {Color} $color - The desired label text color.
- ///
- @mixin label-color($color, $query: feature-targeting.all()) {
- @include if-enabled_ {
- @include label-ink-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the text color of the label in a disabled text field.
- /// @param {Color} $color - The desired label text color.
- ///
- @mixin disabled-label-color($color, $query: feature-targeting.all()) {
- @include if-disabled_ {
- @include label-ink-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the border color of the outlined text field or textarea.
- /// @param {Color} $color - The desired outline border color.
- ///
- @mixin outline-color($color, $query: feature-targeting.all()) {
- @include if-enabled_ {
- @include notched-outline-mixins.color($color, $query: $query);
- }
- }
- ///
- /// Customizes the outline border color when the text field or textarea is hovered.
- /// @param {Color} $color - The desired outline border color.
- ///
- @mixin hover-outline-color($color, $query: feature-targeting.all()) {
- @include if-enabled_ {
- @include hover-outline-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the outline border color when the text field or textarea is focused.
- /// @param {Color} $color - The desired outline border color.
- ///
- @mixin focused-outline-color($color, $query: feature-targeting.all()) {
- @include if-enabled_ {
- @include focused-outline-color_($color, $query: $query);
- }
- }
- ///
- /// Customizes the outline border color when the text field or textarea is disabled.
- /// @param {Color} $color - The desired outline border color.
- ///
- @mixin disabled-outline-color($color, $query: feature-targeting.all()) {
- @include if-disabled_ {
- @include notched-outline-mixins.color($color, $query: $query);
- }
- }
- ///
- /// Customizes the caret color of the text field or textarea.
- /// @param {Color} $color - The desired caret color.
- ///
- @mixin caret-color($color, $query: feature-targeting.all()) {
- $feat-color: feature-targeting.create-target($query, color);
- .mdc-text-field__input {
- @include feature-targeting.targets($feat-color) {
- @include theme.property(caret-color, $color);
- }
- }
- }
- ///
- /// Customizes the color of the prefix text for an enabled text field.
- /// @param {Color} $color - The desired prefix text color.
- ///
- @mixin prefix-color($color, $query: feature-targeting.all()) {
- @include if-enabled_ {
- @include _prefix-color($color, $query: $query);
- }
- }
- ///
- /// Customizes the color of the prefix text for a disabled text field.
- /// @param {Color} $color - The desired prefix text color.
- ///
- @mixin disabled-prefix-color($color, $query: feature-targeting.all()) {
- @include if-disabled_ {
- @include _prefix-color($color, $query: $query);
- }
- }
- ///
- /// Customizes the color of the suffix text for an enabled text field.
- /// @param {Color} $color - The desired suffix text color.
- ///
- @mixin suffix-color($color, $query: feature-targeting.all()) {
- @include if-enabled_ {
- @include _suffix-color($color, $query: $query);
- }
- }
- ///
- /// Customizes the color of the suffix text for a disabled text field.
- /// @param {Color} $color - The desired suffix text color.
- ///
- @mixin disabled-suffix-color($color, $query: feature-targeting.all()) {
- @include if-disabled_ {
- @include _suffix-color($color, $query: $query);
- }
- }
- ///
- /// Sets shape radius of outlined text field variant.
- ///
- /// @param {Number} $radius Shape radius value in `px` or in percentage.
- /// @param {Number} $text-field-height Height of outlined text field variant. Required only when `$radius` is in
- /// percentage unit and if text field has custom height. Defaults to `variables.$height`.
- /// @param {Boolean} $rtl-reflexive Set to true to flip shape radius in RTL context. Defaults to `false`.
- ///
- @mixin outline-shape-radius(
- $radius,
- $density-scale: variables.$density-scale,
- $rtl-reflexive: false,
- $query: feature-targeting.all()
- ) {
- $feat-structure: feature-targeting.create-target($query, structure);
- $height: density-functions.prop-value(
- $density-config: $_density-config,
- $density-scale: $density-scale,
- $property-name: height,
- );
- .mdc-notched-outline {
- @include notched-outline-mixins.shape-radius(
- $radius,
- $rtl-reflexive,
- $component-height: $height,
- $query: $query
- );
- }
- $resolved-radius: shape-functions.resolve-radius(
- $radius,
- $component-height: $height
- );
- $unpacked-radius: shape-functions.unpack-radius($resolved-radius);
- $top-left-radius: list.nth($unpacked-radius, 1);
- $top-left-is-custom-prop: custom-properties.is-custom-prop($top-left-radius);
- $top-left-radius-px: $top-left-radius;
- @if ($top-left-is-custom-prop) {
- $top-left-radius-px: custom-properties.get-fallback($top-left-radius);
- }
- $top-right-radius: list.nth($unpacked-radius, 2);
- $top-right-is-custom-prop: custom-properties.is-custom-prop(
- $top-right-radius
- );
- @if (
- $top-left-is-custom-prop or
- $top-right-is-custom-prop or
- $top-left-radius-px >
- notched-outline-variables.$leading-width
- ) {
- // The horizontal padding only needs to be overriden from the base padding
- // if the radius is a custom property, or if the top-left radius is a value
- // that is large than that default notched outline's leading width.
- @include _outline-shape-radius-horizontal-padding(
- $top-left-radius,
- $top-right-radius,
- $query: $query
- );
- + .mdc-text-field-helper-line {
- @include _outline-shape-radius-horizontal-padding(
- $top-left-radius,
- $top-right-radius,
- $query: $query
- );
- }
- // Ensure that leading/trailing icon padding is overriden. Even if the
- // top left/right isn't a custom property or the leading isn't larger, we
- // still need to override. The above left/right padding rules have more
- // specificty than the original leading/trailing icon rules, so we need to
- // re-apply them.
- // Additionally, if the top left/right radii _are_ custom properties, we
- // should use those instead.
- &.mdc-text-field--with-leading-icon {
- @if ($top-right-is-custom-prop) {
- @include feature-targeting.targets($feat-structure) {
- @include rtl.ignore-next-line();
- padding-left: 0;
- }
- @include _apply-outline-shape-padding(
- padding-right,
- $top-right-radius,
- $query: $query
- );
- @include rtl.rtl {
- @include _apply-outline-shape-padding(
- padding-left,
- $top-right-radius,
- $query: $query
- );
- @include feature-targeting.targets($feat-structure) {
- @include rtl.ignore-next-line();
- padding-right: 0;
- }
- }
- } @else {
- @include _padding-horizontal-with-leading-icon($query);
- }
- }
- &.mdc-text-field--with-trailing-icon {
- @if (
- $top-left-is-custom-prop or
- $top-left-radius-px >
- notched-outline-variables.$leading-width
- ) {
- @include _apply-outline-shape-padding(
- padding-left,
- $top-left-radius,
- $add-label-padding: true,
- $query: $query
- );
- @include feature-targeting.targets($feat-structure) {
- @include rtl.ignore-next-line();
- padding-right: 0;
- }
- @include rtl.rtl {
- @include feature-targeting.targets($feat-structure) {
- @include rtl.ignore-next-line();
- padding-left: 0;
- }
- @include _apply-outline-shape-padding(
- padding-right,
- $top-left-radius,
- $add-label-padding: true,
- $query: $query
- );
- }
- } @else {
- @include _padding-horizontal-with-trailing-icon($query);
- }
- }
- &.mdc-text-field--with-leading-icon.mdc-text-field--with-trailing-icon {
- @include _padding-horizontal-with-both-icons($query);
- }
- }
- }
- @mixin _outline-shape-radius-horizontal-padding(
- $top-left-radius,
- $top-right-radius,
- $query: feature-targeting.all()
- ) {
- @include _apply-outline-shape-padding(
- padding-left,
- $top-left-radius,
- $add-label-padding: true,
- $query: $query
- );
- @include _apply-outline-shape-padding(
- padding-right,
- $top-right-radius,
- $query: $query
- );
- $top-left-is-custom-prop: custom-properties.is-custom-prop($top-left-radius);
- $top-left-radius-px: $top-left-radius;
- @if ($top-left-is-custom-prop) {
- $top-left-radius-px: custom-properties.get-fallback($top-left-radius);
- }
- $top-right-is-custom-prop: custom-properties.is-custom-prop(
- $top-right-radius
- );
- $top-right-radius-px: $top-right-radius;
- @if ($top-right-is-custom-prop) {
- $top-right-radius-px: custom-properties.get-fallback($top-right-radius);
- }
- @if (
- (
- $top-left-is-custom-prop and
- $top-right-is-custom-prop and not
- custom-properties.are-equal($top-left-radius, $top-right-radius)
- ) or
- $top-left-radius-px !=
- $top-right-radius-px
- ) {
- // Normally base horizontal padding doesn't need RTL, but if the values
- // are different or they are two different custom properties, they need to
- // be reversed.
- @include rtl.rtl {
- @include _apply-outline-shape-padding(
- padding-right,
- $top-left-radius,
- $add-label-padding: true,
- $query: $query
- );
- @include _apply-outline-shape-padding(
- padding-left,
- $top-right-radius,
- $query: $query
- );
- }
- }
- }
- @mixin _apply-outline-shape-padding(
- $property,
- $padding,
- $add-label-padding: false,
- $query: feature-targeting.all()
- ) {
- $feat-structure: feature-targeting.create-target($query, structure);
- $padding-is-custom-prop: custom-properties.is-custom-prop($padding);
- $padding-px: $padding;
- @if ($padding-is-custom-prop) {
- $padding-px: custom-properties.get-fallback($padding);
- }
- @include feature-targeting.targets($feat-structure) {
- // The shape should only change the padding if the radius becomes greater
- // than the default padding. That means we need to add more padding.
- @if ($padding-px > variables.$padding-horizontal) {
- // Set a px value if it's greater. This is either the only value (if
- // we're given an exact value), or an IE11 fallback if we're given a
- // custom property and the fallback value is greater than the padding.
- $value: $padding-px;
- @if ($add-label-padding) {
- // If this is for the top-left leading, add the notched outline padding
- // to keep it aligned with the label
- $value: $padding-px + notched-outline-variables.$padding;
- }
- @include rtl.ignore-next-line();
- #{$property}: $value;
- @if ($padding-is-custom-prop) {
- // Add an alternate GSS tag b/c this was an IE11 fallback and we're
- // going to add another property with the var() value
- /* @alternate */
- }
- }
- @if ($padding-is-custom-prop) {
- // If it's a custom property, always add it since the value may change
- // to be greater than the padding at runtime, even if the fallback is
- // not currently greater than the default padding.
- $value: custom-properties.create-var($padding);
- @if ($add-label-padding) {
- $value: calc(#{$value} + #{notched-outline-variables.$padding});
- }
- // Interpolation is a workaround for sass/sass#3259.
- @supports (top: max(#{0%})) {
- // A max() function makes this runtime dynamic. The padding will be
- // whichever is greater: the default horizontal padding, or the calculated
- // custom property plus extra padding.
- @include rtl.ignore-next-line();
- #{$property}: max(#{variables.$padding-horizontal}, #{$value});
- }
- }
- }
- }
- ///
- /// Sets the CSS transition for the floating label's 'float' animation.
- ///
- /// @param {Number} $duration-ms - Duration (in ms) of the animation.
- /// @param {String} $timing-function - Optionally overrides the default animation timing function.
- ///
- @mixin floating-label-float-transition(
- $duration-ms,
- $timing-function: null,
- $query: feature-targeting.all()
- ) {
- .mdc-floating-label {
- @include floating-label-mixins.float-transition(
- $duration-ms,
- $timing-function,
- $query: $query
- );
- }
- }
- ///
- /// Sets custom font size of the input.
- ///
- /// @param {number} $font-size - Overrides the font size.
- ///
- @mixin input-font-size($font-size, $query: feature-targeting.all()) {
- $feat-typography: feature-targeting.create-target($query, typography);
- .mdc-text-field__input,
- .mdc-text-field__affix--suffix,
- .mdc-text-field__affix--prefix {
- @include feature-targeting.targets($feat-typography) {
- font-size: $font-size;
- }
- }
- }
- ///
- /// Sets custom font family of the input.
- ///
- /// @param {String} $font-family - Selected font family.
- ///
- @mixin input-font-family($font-family, $query: feature-targeting.all()) {
- $feat-typography: feature-targeting.create-target($query, typography);
- .mdc-text-field__input {
- @include feature-targeting.targets($feat-typography) {
- font-family: $font-family;
- }
- }
- }
- // Private mixins
- // Base shared styles
- @mixin _base($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- // Shape
- @include shape-radius(variables.$shape-radius, $query: $query);
- // Colors
- @include label-color(variables.$label, $query: $query);
- @include ink-color(variables.$ink-color, $query: $query);
- @include placeholder-color(variables.$placeholder-ink-color, $query: $query);
- @include caret-color(primary, $query: $query);
- @include helper-text-mixins.helper-text-color(
- variables.$helper-text-color,
- $query: $query
- );
- @include character-counter-mixins.character-counter-color(
- variables.$helper-text-color,
- $query: $query
- );
- @include icon-mixins.leading-icon-color(
- variables.$icon-color,
- $query: $query
- );
- @include icon-mixins.trailing-icon-color(
- variables.$icon-color,
- $query: $query
- );
- @include prefix-color(variables.$affix-color, $query: $query);
- @include suffix-color(variables.$affix-color, $query: $query);
- // Floating Label
- @include floating-label_($query);
- @include feature-targeting.targets($feat-structure) {
- // display and align-items are necessary to make the text field participate
- // in baseline alignment, even though some variants are 'centered'. Those
- // variants should use the _baseline-center-aligned() mixin
- display: inline-flex;
- align-items: baseline;
- padding: 0 variables.$padding-horizontal;
- position: relative;
- box-sizing: border-box;
- overflow: hidden;
- /* @alternate */
- will-change: opacity, transform, color;
- }
- }
- // This mixin adds styles to visually center the text within the text field.
- // Sibling text will align to the baseline and appear centered next to the
- // text field.
- @mixin _baseline-center-aligned($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- // In order for a flexbox container to participate in baseline alignment,
- // it follows these rules to determine where its baseline is:
- // https://www.w3.org/TR/css-flexbox-1/#flex-baselines
- //
- // In order to avoid leading icons 'controlling' the baseline (since they
- // are the first child), flexbox will generate a baseline from any child
- // flex items that participate in baseline alignment.
- //
- // Icons are set to "align-self: center", while all other children are
- // aligned to baseline. The next problem is deciding which child is
- // used to determine the baseline.
- //
- // According to spec, the item with the largest distance between its
- // baseline and the edge of the cross axis is placed flush with that edge,
- // making it the baseline of the container.
- // https://www.w3.org/TR/css-flexbox-1/#baseline-participation
- //
- // For the filled variant, the pseudo ::before strut is the 'largest'
- // child since the input has a height of 28px and the strut is 40px. We
- // can emulate center alignment and force the baseline to use the input
- // text by making the input the full height of the container and removing
- // the baseline strut.
- // IE11 does not respect this, and makes the leading icon (if present) the
- // baseline. This is a gap with IE11 that we have accepted.
- .mdc-text-field__input {
- height: 100%;
- }
- }
- }
- @mixin _padding-horizontal-with-leading-icon($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- @include rtl.reflexive-property(padding, 0, variables.$padding-horizontal);
- }
- }
- @mixin _padding-horizontal-with-trailing-icon($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- @include rtl.reflexive-property(padding, variables.$padding-horizontal, 0);
- }
- }
- @mixin _padding-horizontal-with-both-icons($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- @include rtl.ignore-next-line();
- padding-left: 0;
- @include rtl.ignore-next-line();
- padding-right: 0;
- }
- }
- @mixin floating-label_($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- .mdc-floating-label {
- @include feature-targeting.targets($feat-structure) {
- top: 50%;
- transform: translateY(-50%);
- pointer-events: none;
- }
- }
- }
- // Filled
- @mixin _filled($query: feature-targeting.all()) {
- // Text Field intentionally omits press ripple, so each state needs to be specified individually.
- @include ripple-theme.states-base-color(
- variables.$ink-color,
- $query: $query,
- $ripple-target: variables.$ripple-target
- );
- @include ripple-theme.states-hover-opacity(
- ripple-theme.states-opacity(variables.$ink-color, hover),
- $query: $query,
- $ripple-target: variables.$ripple-target
- );
- @include ripple-theme.states-focus-opacity(
- ripple-theme.states-opacity(variables.$ink-color, focus),
- $query: $query,
- $ripple-target: variables.$ripple-target
- );
- @include height(variables.$height, $query: $query);
- @include typography.baseline-top(
- variables.$filled-baseline-top,
- $query: $query
- );
- @include fill-color(variables.$background, $query: $query);
- @include bottom-line-color(variables.$bottom-line-idle, $query: $query);
- @include hover-bottom-line-color(
- variables.$bottom-line-hover,
- $query: $query
- );
- @include line-ripple-color_(primary, $query: $query);
- @include _filled-floating-label($query);
- }
- @mixin _filled-floating-label($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- .mdc-floating-label {
- @include feature-targeting.targets($feat-structure) {
- @include rtl.reflexive-position(left, variables.$label-offset);
- }
- }
- @include floating-label-mixins.float-position(
- variables.$label-position-y,
- $query: $query
- );
- }
- // Filled variant with no label. This variant centers the text elements and
- // hides the label and is used with there is explicitly no label provided or
- // when the height of the text field is too small for a label to be allowed.
- @mixin filled-no-label($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include _baseline-center-aligned($query);
- @include feature-targeting.targets($feat-structure) {
- .mdc-floating-label {
- display: none;
- }
- &::before {
- // Remove baseline-top strut
- display: none;
- }
- }
- // Safari only
- @supports (-webkit-hyphens: none) {
- .mdc-text-field__affix {
- @include _centered-affix-safari-support($query: $query);
- }
- }
- }
- // Outlined
- @mixin outlined_($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include outlined-height(
- $height: variables.$height,
- $keyframe-suffix: text-field-outlined,
- $query: $query
- );
- @include _baseline-center-aligned($query: $query);
- @include outline-color(variables.$outlined-idle-border, $query: $query);
- @include hover-outline-color(
- variables.$outlined-hover-border,
- $query: $query
- );
- @include focused-outline-color(primary, $query: $query);
- @include outline-shape-radius(variables.$shape-radius, $query: $query);
- @include notched-outline-mixins.notch-offset(
- notched-outline-variables.$border-width,
- $query: $query
- );
- @include ripple-theme.states-base-color(
- transparent,
- $query: $query,
- $ripple-target: variables.$ripple-target
- );
- @include _outlined-floating-label($query);
- @include feature-targeting.targets($feat-structure) {
- overflow: visible;
- }
- .mdc-text-field__input {
- @include feature-targeting.targets($feat-structure) {
- // TODO(b/154349735): Investigate the neccessity of these styles
- display: flex;
- // stylelint-disable-next-line declaration-no-important --
- // FF adds unwanted border in HC mode on windows.
- border: none !important;
- background-color: transparent;
- }
- }
- }
- @mixin _outlined-floating-label($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- .mdc-floating-label {
- @include feature-targeting.targets($feat-structure) {
- @include rtl.reflexive-position(left, notched-outline-variables.$padding);
- }
- }
- }
- @mixin _outlined-notched-outline($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- // Force the outline to appear "above" the textfield elements, even though
- // it is absolutely positioned and comes before the input in the DOM. This
- // is primarily for the textarea scrollbar and resize elements, which may
- // clip with with outline border.
- z-index: 1;
- }
- }
- // States
- @mixin disabled_($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include ink-color_(variables.$disabled-ink-color, $query: $query);
- @include placeholder-color_(
- variables.$disabled-placeholder-ink-color,
- $query: $query
- );
- @include label-ink-color_(variables.$disabled-label-color, $query: $query);
- @include helper-text-mixins.helper-text-color_(
- variables.$disabled-helper-text-color,
- $query: $query
- );
- @include character-counter-mixins.character-counter-color_(
- variables.$disabled-helper-text-color,
- $query: $query
- );
- @include icon-mixins.leading-icon-color_(
- variables.$disabled-icon,
- $query: $query
- );
- @include icon-mixins.trailing-icon-color_(
- variables.$disabled-icon,
- $query: $query
- );
- @include _prefix-color(variables.$disabled-affix-color, $query: $query);
- @include _suffix-color(variables.$disabled-affix-color, $query: $query);
- // Mixins that are ok to include since they target variant-specific elements
- @include bottom-line-color_(variables.$disabled-border, $query: $query);
- @include notched-outline-mixins.color(
- variables.$outlined-disabled-border,
- $query: $query
- );
- @include dom.forced-colors-mode {
- @include placeholder-color_(GrayText, $query: $query);
- @include label-ink-color_(GrayText, $query: $query);
- @include helper-text-mixins.helper-text-color_(GrayText, $query: $query);
- @include character-counter-mixins.character-counter-color_(
- GrayText,
- $query: $query
- );
- @include icon-mixins.leading-icon-color_(GrayText, $query: $query);
- @include icon-mixins.trailing-icon-color_(GrayText, $query: $query);
- @include _prefix-color(GrayText, $query: $query);
- @include _suffix-color(GrayText, $query: $query);
- // Mixins that are ok to include since they target variant-specific elements
- @include bottom-line-color_(GrayText, $query: $query);
- @include notched-outline-mixins.color(GrayText, $query: $query);
- }
- @include dom.forced-colors-mode($exclude-ie11: true) {
- .mdc-text-field__input {
- @include feature-targeting.targets($feat-structure) {
- background-color: Window;
- }
- }
- .mdc-floating-label {
- @include feature-targeting.targets($feat-structure) {
- z-index: 1;
- }
- }
- }
- @include feature-targeting.targets($feat-structure) {
- pointer-events: none;
- }
- .mdc-floating-label {
- @include feature-targeting.targets($feat-structure) {
- cursor: default;
- }
- }
- }
- @mixin _disabled-input($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- // disabled inputs should still allow users to interact with them to select
- // text and scroll for textareas
- pointer-events: auto;
- }
- }
- @mixin _disabled-filled($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include fill-color_(variables.$disabled-background, $query: $query);
- #{variables.$ripple-target} {
- @include feature-targeting.targets($feat-structure) {
- // prevent ripple from displaying on hover when some interactible
- // elements like input and resize handles are hovered
- display: none;
- }
- }
- }
- @mixin invalid_($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include hover-bottom-line-color(variables.$error, $query: $query);
- @include line-ripple-color(variables.$error, $query: $query);
- @include label-color(variables.$error, $query: $query);
- @include helper-text-mixins.helper-text-validation-color(
- variables.$error,
- $query: $query
- );
- @include caret-color(variables.$error, $query: $query);
- @include icon-mixins.trailing-icon-color(variables.$error, $query: $query);
- // Mixins that are ok to include since they target variant-specific elements
- @include bottom-line-color(variables.$error, $query: $query);
- @include outline-color(variables.$error, $query: $query);
- @include hover-outline-color(variables.$error, $query: $query);
- @include focused-outline-color(variables.$error, $query: $query);
- + .mdc-text-field-helper-line .mdc-text-field-helper-text--validation-msg {
- @include feature-targeting.targets($feat-structure) {
- opacity: 1;
- }
- }
- }
- @mixin focused_($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include label-color(variables.$focused-label-color, $query: $query);
- // Mixins that are ok to include since they target variant-specific elements
- @include notched-outline-mixins.stroke-width(
- variables.$outlined-stroke-width,
- $query: $query
- );
- + .mdc-text-field-helper-line
- .mdc-text-field-helper-text:not(
- .mdc-text-field-helper-text--validation-msg
- ) {
- @include feature-targeting.targets($feat-structure) {
- opacity: 1;
- }
- }
- }
- @mixin _focused-outlined($query: feature-targeting.all()) {
- @include notched-outline-mixins.notch-offset(
- variables.$outlined-stroke-width,
- $query: $query
- );
- }
- @mixin _focused-outlined-textarea($query: feature-targeting.all()) {
- @include notched-outline-mixins.notch-offset(0, $query: $query);
- }
- // Icons
- @mixin with-leading-icon_($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- $icon-padding: icon-variables.$leading-icon-padding-left +
- icon-variables.$icon-size + icon-variables.$leading-icon-padding-right;
- .mdc-floating-label {
- @include _truncate-floating-label-max-width($icon-padding, $query: $query);
- @include feature-targeting.targets($feat-structure) {
- @include rtl.reflexive-position(left, $icon-padding);
- }
- }
- $truncation: $icon-padding + variables.$padding-horizontal;
- .mdc-floating-label--float-above {
- @include _truncate-floating-label-floated-max-width(
- $truncation,
- $query: $query
- );
- }
- }
- @mixin _with-trailing-icon($query: feature-targeting.all()) {
- $truncation: icon-variables.$trailing-icon-padding-left +
- icon-variables.$icon-size + icon-variables.$trailing-icon-padding-right +
- variables.$label-offset;
- .mdc-floating-label {
- @include _truncate-floating-label-max-width($truncation, $query: $query);
- }
- .mdc-floating-label--float-above {
- @include _truncate-floating-label-floated-max-width(
- $truncation,
- $query: $query
- );
- }
- }
- @mixin _with-leading-and-trailing-icon($query: feature-targeting.all()) {
- $leading-icon: icon-variables.$leading-icon-padding-left +
- icon-variables.$icon-size + icon-variables.$leading-icon-padding-right;
- $trailing-icon: icon-variables.$trailing-icon-padding-left +
- icon-variables.$icon-size + icon-variables.$trailing-icon-padding-right;
- $truncation: $leading-icon + $trailing-icon;
- .mdc-floating-label {
- @include _truncate-floating-label-max-width($truncation, $query: $query);
- }
- .mdc-floating-label--float-above {
- @include _truncate-floating-label-floated-max-width(
- $truncation,
- $query: $query
- );
- }
- }
- @mixin outlined-with-leading-icon_($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- // Resting label position
- $icon-padding: icon-variables.$leading-icon-padding-left +
- icon-variables.$icon-size + icon-variables.$leading-icon-padding-right;
- $left-spacing: $icon-padding - notched-outline-variables.$leading-width;
- .mdc-floating-label {
- @include feature-targeting.targets($feat-structure) {
- @include rtl.reflexive-position(left, $left-spacing);
- }
- }
- // Notch width
- $notch-truncation: $icon-padding + notched-outline-variables.$leading-width;
- @include _truncate-notched-outline-max-width(
- $notch-truncation,
- $query: $query
- );
- // Floating label position and animation
- @include _outlined-with-leading-icon-floating-label-position-animation(
- $height: variables.$height,
- $keyframe-suffix: text-field-outlined-leading-icon,
- $query: $query
- );
- }
- ///
- /// Applied to the outlined text field with a trailing icon
- ///
- @mixin _outlined-with-trailing-icon($query: feature-targeting.all()) {
- // Resting label position
- $icon-padding: icon-variables.$trailing-icon-padding-left +
- icon-variables.$icon-size + icon-variables.$trailing-icon-padding-right;
- // Notch width
- $notch-truncation: $icon-padding + notched-outline-variables.$leading-width;
- @include _truncate-notched-outline-max-width(
- $notch-truncation,
- $query: $query
- );
- }
- ///
- /// Truncates the max-width of the notched outline by the given amount
- ///
- /// @param {Number} $truncation - Amount to truncate the notched outline max-width
- ///
- @mixin _truncate-notched-outline-max-width(
- $truncation,
- $query: feature-targeting.all()
- ) {
- @include notched-outline-mixins.notch-max-width(
- calc(100% - #{$truncation}),
- $query: $query
- );
- }
- ///
- /// Truncates the max-width of the floating label by the given amount
- ///
- /// @param {Number} $truncation - Amount to truncate the floating label max-width
- ///
- @mixin _truncate-floating-label-max-width(
- $truncation,
- $query: feature-targeting.all()
- ) {
- @include floating-label-mixins.max-width(
- calc(100% - #{$truncation}),
- $query: $query
- );
- }
- ///
- /// Truncates the max-width of the floating label by the given amount while scaling by the given scale value
- ///
- /// @param {Number} $truncation - Amount to truncate the floating label max-width
- ///
- @mixin _truncate-floating-label-floated-max-width(
- $truncation,
- $query: feature-targeting.all()
- ) {
- $scale: floating-label-variables.$float-scale;
- @include floating-label-mixins.max-width(
- calc(100% / #{$scale} - #{$truncation} / #{$scale}),
- $query: $query
- );
- }
- // Textarea
- @mixin textarea_($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- $feat-animation: feature-targeting.create-target($query, animation);
- @include _textarea-floating-label($query);
- @include feature-targeting.targets($feat-structure) {
- flex-direction: column;
- align-items: center;
- width: auto;
- height: auto;
- padding: 0; // see below for explanation
- }
- @include feature-targeting.targets($feat-animation) {
- transition: none;
- }
- }
- @mixin _textarea-resizer($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- align-self: stretch;
- display: inline-flex;
- flex-direction: column;
- flex-grow: 1;
- max-height: 100%;
- max-width: 100%;
- min-height: variables.$height;
- // 'stretch' is the preferred rule here. It will allow the textarea to grow
- // to the min/max width of the container, but if an explicit width is set,
- // it cannot be resized horizontally.
- // Stretch is still a working draft. Chrome and Firefox have it implemented
- // with 'available' prefixes. fit-content is another good target for
- // Safari since it works in almost all use cases except when an explicit
- // width is set (the user can make the textarea smaller than the container).
- // None of this matters for IE11, which doesn't support resize.
- min-width: fit-content;
- /* @alternate */
- min-width: -moz-available;
- /* @alternate */
- min-width: -webkit-fill-available;
- overflow: hidden;
- resize: both;
- }
- }
- @mixin _textarea-filled-resizer($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- // Shift the resizer element up by a margin amount to make space for the
- // resize handle. For filled elements, the resize handle directly touches
- // the bottom line and is hard to see.
- // Using a margin affects the width and positioning of the overall component
- // and underlying textarea, which is why a transform is used instead.
- $y: -1 * variables.$textarea-input-handle-margin;
- @include feature-targeting.targets($feat-structure) {
- transform: translateY($y);
- }
- }
- @mixin _textarea-filled-resizer-children($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- // See above. After shifting the resize wrapper element, all of its children
- // should be shifted in the opposite direction (down) to compensate.
- $y: variables.$textarea-input-handle-margin;
- @include feature-targeting.targets($feat-structure) {
- transform: translateY($y);
- }
- }
- @mixin _textarea-outlined-resizer($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- // Shift the resizer element left/up by a margin amount to make space for the
- // resize handle. For outlined elements, the resize handle directly touches
- // the outline and is hard to see.
- // Using a margin affects the width and positioning of the overall component
- // and underlying textarea, which is why a transform is used instead.
- $x: -1 * variables.$textarea-input-handle-margin;
- $y: -1 * variables.$textarea-input-handle-margin;
- @include feature-targeting.targets($feat-structure) {
- @include rtl.ignore-next-line();
- transform: translateX($x) translateY($y);
- @include rtl.rtl {
- // Flip the horizontal shifting direction for RTL
- @include rtl.ignore-next-line();
- transform: translateX(-1 * $x) translateY($y);
- }
- }
- }
- @mixin _textarea-outlined-resizer-children($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- // See above. After shifting the resize wrapper element, all of its children
- // should be shifted in the opposite direction (right and down) to compensate.
- $x: variables.$textarea-input-handle-margin;
- $y: variables.$textarea-input-handle-margin;
- @include feature-targeting.targets($feat-structure) {
- @include rtl.ignore-next-line();
- transform: translateX($x) translateY($y);
- @include rtl.rtl {
- // Flip the horizontal shifting direction for RTL
- @include rtl.ignore-next-line();
- transform: translateX(-1 * $x) translateY($y);
- }
- }
- }
- @mixin _textarea-floating-label($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- // Resting label position
- .mdc-floating-label {
- @include feature-targeting.targets($feat-structure) {
- top: variables.$textarea-label-top;
- }
- // Resets center aligning the floating label.
- &:not(.mdc-floating-label--float-above) {
- @include feature-targeting.targets($feat-structure) {
- transform: none;
- }
- }
- }
- }
- @mixin _textarea-input($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- $feat-typography: feature-targeting.create-target($query, typography);
- @include feature-targeting.targets($feat-structure) {
- flex-grow: 1;
- height: auto;
- min-height: variables.$textarea-line-height;
- overflow-x: hidden; // https://bugzilla.mozilla.org/show_bug.cgi?id=33654
- overflow-y: auto;
- box-sizing: border-box;
- resize: none;
- // Textarea has horizontal padding instead of the container. This allows the
- // resize handle to extend to the edge of the container.
- padding: 0 variables.$padding-horizontal;
- }
- @include feature-targeting.targets($feat-typography) {
- line-height: variables.$textarea-line-height;
- }
- }
- @mixin _textarea-internal-counter($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include typography.baseline-bottom(
- variables.$textarea-internal-counter-baseline-bottom,
- $query: $query
- );
- @include feature-targeting.targets($feat-structure) {
- align-self: flex-end;
- // Needed since padding is on the textarea and not the container
- padding: 0 variables.$padding-horizontal;
- &::before {
- // Remove baseline-top
- display: none;
- }
- }
- }
- @mixin _textarea-input-with-internal-counter($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- margin-bottom: variables.$textarea-internal-counter-input-margin-bottom;
- }
- }
- @mixin _textarea-filled($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- &::before {
- // <textarea> does not align to baseline when it does not have a value,
- // unlike <input>, so we have to use padding to fake it instead
- display: none;
- }
- }
- // Floating label position
- @include floating-label-mixins.float-position(
- variables.$textarea-filled-label-position-y,
- $query: $query
- );
- // Floating label animation
- @include floating-label-mixins.shake-animation(
- textarea-filled,
- $query: $query
- );
- @at-root {
- @include floating-label-mixins.shake-keyframes(
- textarea-filled,
- variables.$textarea-filled-label-position-y,
- 0%,
- $query: $query
- );
- }
- }
- @mixin _textarea-filled-input($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- margin-top: variables.$textarea-filled-input-margin-top;
- margin-bottom: variables.$textarea-filled-input-margin-bottom;
- }
- }
- @mixin _textarea-filled-no-label-input($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- margin-top: variables.$textarea-filled-no-label-input-margin-top;
- margin-bottom: variables.$textarea-filled-no-label-input-margin-bottom;
- }
- }
- @mixin _textarea-outlined($query: feature-targeting.all()) {
- @include notched-outline-mixins.notch-offset(0, $query: $query);
- // Floating label position
- @include notched-outline-mixins.floating-label-float-position-absolute(
- variables.$textarea-outlined-label-position-y,
- $query: $query
- );
- // Floating label animation
- @include floating-label-mixins.shake-animation(
- textarea-outlined,
- $query: $query
- );
- @at-root {
- @include floating-label-mixins.shake-keyframes(
- textarea-outlined,
- variables.$textarea-outlined-label-position-y,
- 0%,
- $query: $query
- );
- }
- }
- @mixin _textarea-outlined-floating-label($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- top: variables.$textarea-outlined-label-top;
- }
- }
- @mixin _textarea-outlined-input($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- margin-top: variables.$textarea-outlined-input-margin-top;
- margin-bottom: variables.$textarea-outlined-input-margin-bottom;
- }
- }
- // Text, Prefix and Suffix
- // Common styles for the text of the text field, including the prefix, suffix,
- // and input.
- @mixin _text($query: feature-targeting.all()) {
- $feat-animation: feature-targeting.create-target($query, animation);
- $feat-structure: feature-targeting.create-target($query, structure);
- // Exclude setting line-height to keep caret (text cursor) same height as the input text in iOS browser.
- @include typography.typography(
- subtitle1,
- $exclude-props: (line-height),
- $query: $query
- );
- @include feature-targeting.targets($feat-structure) {
- height: variables.$input-height;
- }
- @include feature-targeting.targets($feat-animation) {
- transition: animation.standard(opacity, 150ms);
- }
- }
- @mixin _input($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include _text($query: $query);
- @include feature-targeting.targets($feat-structure) {
- width: 100%;
- min-width: 0; // Fixes flex issues on Firefox
- border: none;
- border-radius: 0;
- background: none;
- appearance: none;
- padding: 0;
- // Remove built-in trailing clear icon on IE11. IE vendor prefixes cannot
- // be combined with other vendor prefixes like the webkit one below.
- &::-ms-clear {
- display: none;
- }
- // Remove built-in datepicker icon on Chrome
- &::-webkit-calendar-picker-indicator {
- display: none;
- }
- &:focus {
- outline: none;
- }
- // Remove red outline on firefox
- &:invalid {
- box-shadow: none;
- }
- }
- }
- @mixin _input-placeholder($query: feature-targeting.all()) {
- $feat-animation: feature-targeting.create-target($query, animation);
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-animation) {
- transition: animation.standard(opacity, 67ms);
- }
- @include feature-targeting.targets($feat-structure) {
- opacity: 0;
- }
- }
- @mixin _input-placeholder-visible($query: feature-targeting.all()) {
- $feat-animation: feature-targeting.create-target($query, animation);
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-animation) {
- transition-delay: 40ms;
- transition-duration: 110ms;
- }
- @include feature-targeting.targets($feat-structure) {
- opacity: 1;
- }
- }
- @mixin _affix($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include _text($query: $query);
- @include feature-targeting.targets($feat-structure) {
- opacity: 0;
- white-space: nowrap;
- }
- }
- // TODO(b/155467610): Remove when Safari supports baseline alignment
- // https://github.com/material-components/material-components-web/issues/5879
- @mixin _centered-affix-safari-support($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- align-items: center;
- align-self: center;
- display: inline-flex;
- height: 100%;
- }
- }
- @mixin _affix-visible($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- opacity: 1;
- }
- }
- @mixin _prefix($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- @include rtl.reflexive-box(padding, right, variables.$prefix-padding);
- }
- }
- @mixin _prefix-end-aligned($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- @include rtl.reflexive-box(
- padding,
- right,
- variables.$prefix-end-aligned-padding
- );
- }
- }
- @mixin _suffix($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- @include rtl.reflexive-box(padding, left, variables.$suffix-padding);
- }
- }
- @mixin _suffix-end-aligned($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- @include rtl.reflexive-box(
- padding,
- left,
- variables.$suffix-end-aligned-padding
- );
- }
- }
- // End aligned
- @mixin end-aligned_($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- .mdc-text-field__input {
- @include feature-targeting.targets($feat-structure) {
- // IE11 does not support text-align: end
- @include rtl.ignore-next-line();
- text-align: right;
- }
- @include rtl.rtl {
- @include feature-targeting.targets($feat-structure) {
- @include rtl.ignore-next-line();
- text-align: left;
- }
- }
- }
- }
- // Forces input, prefix, and suffix to be LTR when in an RTL environment. Other
- // elements such as labels and icons will remain RTL.
- @mixin _ltr-text($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- @include rtl.rtl {
- .mdc-text-field__input,
- .mdc-text-field__affix {
- @include rtl.ignore-next-line();
- direction: ltr;
- }
- .mdc-text-field__affix--prefix {
- @include rtl.ignore-next-line();
- padding-left: 0;
- @include rtl.ignore-next-line();
- padding-right: variables.$prefix-padding;
- }
- .mdc-text-field__affix--suffix {
- @include rtl.ignore-next-line();
- padding-left: variables.$suffix-padding;
- @include rtl.ignore-next-line();
- padding-right: 0;
- }
- // Need to specify an order for all elements since icons maintain their
- // original positions. We can't just reverse the container.
- .mdc-text-field__icon--leading {
- order: 1;
- }
- .mdc-text-field__affix--suffix {
- order: 2;
- }
- .mdc-text-field__input {
- order: 3;
- }
- .mdc-text-field__affix--prefix {
- order: 4;
- }
- .mdc-text-field__icon--trailing {
- order: 5;
- }
- }
- }
- }
- // Forces input, prefix, and suffix that are already forced to LTR to also be
- // end-aligned. This mixin should be used alongside the styles provided in
- // _ltr-text().
- @mixin _ltr-text-end-aligned($query: feature-targeting.all()) {
- $feat-structure: feature-targeting.create-target($query, structure);
- @include feature-targeting.targets($feat-structure) {
- @include rtl.rtl {
- .mdc-text-field__input {
- // IE11 does not support text-align: end, so we need to duplicate
- // the LTR end-aligned style here.
- @include rtl.ignore-next-line();
- text-align: right;
- }
- .mdc-text-field__affix--prefix {
- // padding-left: 0 provided by _ltr-text mixin
- @include rtl.ignore-next-line();
- padding-right: variables.$prefix-end-aligned-padding;
- }
- .mdc-text-field__affix--suffix {
- @include rtl.ignore-next-line();
- padding-left: variables.$suffix-end-aligned-padding;
- // padding-right: 0 provided by _ltr-text mixin
- }
- }
- }
- }
- // Customization
- @mixin ink-color_($color, $query: feature-targeting.all()) {
- $feat-color: feature-targeting.create-target($query, color);
- .mdc-text-field__input {
- @include feature-targeting.targets($feat-color) {
- @include theme.property(color, $color);
- }
- }
- }
- @mixin placeholder-color_($color, $query: feature-targeting.all()) {
- $feat-color: feature-targeting.create-target($query, color);
- @include feature-targeting.targets($feat-color) {
- .mdc-text-field__input {
- @include placeholder-selector_ {
- @include theme.property(color, $color);
- }
- }
- }
- }
- @mixin fill-color_(
- $color,
- $query: feature-targeting.all(),
- $addAlternate: false
- ) {
- $feat-color: feature-targeting.create-target($query, color);
- @include feature-targeting.targets($feat-color) {
- @if ($addAlternate) {
- /* @alternate */
- }
- @include theme.property(background-color, $color);
- }
- }
- @mixin bottom-line-color_($color, $query: feature-targeting.all()) {
- .mdc-line-ripple {
- @include line-ripple-mixins.inactive-color($color, $query: $query);
- }
- }
- @mixin hover-bottom-line-color_($color, $query: feature-targeting.all()) {
- $feat-color: feature-targeting.create-target($query, color);
- &:hover .mdc-line-ripple {
- @include line-ripple-mixins.inactive-color($color, $query: $query);
- }
- }
- @mixin line-ripple-color_($color, $query: feature-targeting.all()) {
- .mdc-line-ripple {
- @include line-ripple-mixins.active-color($color, $query: $query);
- }
- }
- @mixin hover-outline-color_($color, $query: feature-targeting.all()) {
- &:not(.mdc-text-field--focused):hover {
- .mdc-notched-outline {
- @include notched-outline-mixins.color($color, $query: $query);
- }
- }
- }
- @mixin focused-outline-color_($color, $query: feature-targeting.all()) {
- &.mdc-text-field--focused {
- @include notched-outline-mixins.color($color, $query: $query);
- }
- }
- @mixin label-ink-color_($color, $query: feature-targeting.all()) {
- .mdc-floating-label {
- @include floating-label-mixins.ink-color($color, $query: $query);
- }
- }
- @mixin _prefix-color($color, $query: feature-targeting.all()) {
- $feat-color: feature-targeting.create-target($query, color);
- @include feature-targeting.targets($feat-color) {
- .mdc-text-field__affix--prefix {
- @include theme.property(color, $color);
- }
- }
- }
- @mixin _suffix-color($color, $query: feature-targeting.all()) {
- $feat-color: feature-targeting.create-target($query, color);
- @include feature-targeting.targets($feat-color) {
- .mdc-text-field__affix--suffix {
- @include theme.property(color, $color);
- }
- }
- }
- // Selectors
- @mixin placeholder-selector_ {
- // GSS will combine selectors with the same content, and some browsers have a
- // CSS quirk where it drops a rule if it does not recognize one of the
- // selectors.
- // To avoid GSS combining the ::placeholder and :-ms-input-placeholder
- // selectors, we wrap them in `@media all`.
- // TODO(b/142329051)
- @media all {
- // ::placeholder needs to be wrapped because IE11 will drop other selectors
- // with the same content
- &::placeholder {
- @content;
- }
- }
- @media all {
- // :-ms-input-placeholder needs to be wrapped because Firefox will drop
- // other selectors with the same content
- &:-ms-input-placeholder {
- @content;
- }
- }
- }
- // State qualifiers
- ///
- /// Helps style the text-field only when it's enabled.
- /// @access private
- ///
- @mixin if-enabled_ {
- &:not(.mdc-text-field--disabled) {
- @content;
- }
- }
- ///
- /// Helps style the text-field only when it's disabled.
- /// @access private
- ///
- @mixin if-disabled_ {
- &.mdc-text-field--disabled {
- @content;
- }
- }
|