2020// THE SOFTWARE.
2121//
2222
23+ // stylelint-disable selector-class-pattern --
24+ // Selector '.mdc-*' should only be used in this project.
25+
26+ @use ' sass:list' ;
27+ @use ' sass:meta' ;
28+ @use ' @material/theme/custom-properties' ;
29+ @use ' @material/theme/theme' ;
30+ @use ' @material/shape/functions' as shape-functions ;
31+ @use ' @material/shape/mixins' as shape-mixins ;
32+ @use ' @material/floating-label/mixins' as floating-label-mixins ;
33+ @use ' @material/feature-targeting/feature-targeting' ;
34+ @use ' @material/rtl/rtl' ;
35+
2336// Keep this in sync with constants.numbers.MIN_LEADING_STROKE_EDGE_POSITION
2437$min-leading-stroke-edge-position : 12px !default ;
2538// The gap between the stroke end and floating label
@@ -36,3 +49,279 @@ $label-box-height: 13.5px !default;
3649/// Label adjust offset applied to floating label when it is notched. Since notch without upgraded has different font
3750/// size we add additional offset value.
3851$label-adjust-absolute : 2.5px !default ;
52+
53+ @mixin theme-styles ($query : feature-targeting .all ()) {
54+ $feat-structure : feature-targeting .create-target ($query , structure );
55+
56+ .mdc-notched-outline {
57+ & __leading ,
58+ & __notch ,
59+ & __trailing {
60+ @include feature-targeting .targets ($feat-structure ) {
61+ border-top : $border-width solid ;
62+ border-bottom : $border-width solid ;
63+ }
64+ }
65+
66+ & __leading {
67+ @include feature-targeting .targets ($feat-structure ) {
68+ @include rtl .reflexive-property (border , $border-width solid , none );
69+
70+ width : $leading-width ;
71+ }
72+ }
73+
74+ & __trailing {
75+ @include feature-targeting .targets ($feat-structure ) {
76+ @include rtl .reflexive-property (border , none , $border-width solid );
77+ }
78+ }
79+
80+ & __notch {
81+ @include feature-targeting .targets ($feat-structure ) {
82+ max-width : calc (100% - #{$leading-width } * 2 );
83+ }
84+ }
85+ }
86+ }
87+
88+ @mixin color ($color , $query : feature-targeting .all ()) {
89+ $feat-color : feature-targeting .create-target ($query , color );
90+
91+ .mdc-notched-outline__leading ,
92+ .mdc-notched-outline__notch ,
93+ .mdc-notched-outline__trailing {
94+ @include feature-targeting .targets ($feat-color ) {
95+ @include theme .property (border-color , $color );
96+ }
97+ }
98+ }
99+
100+ @mixin stroke-width ($width , $query : feature-targeting .all ()) {
101+ $feat-structure : feature-targeting .create-target ($query , structure );
102+
103+ .mdc-notched-outline__leading ,
104+ .mdc-notched-outline__notch ,
105+ .mdc-notched-outline__trailing {
106+ @include feature-targeting .targets ($feat-structure ) {
107+ @include theme .property (border-width , $width );
108+ }
109+ }
110+ }
111+
112+ ///
113+ /// Adds top offset to compensate for border width box size when it is notched.
114+ /// Use this when floating label is aligned to center to prevent label jump on focus.
115+ /// @param {Number} $stroke-width Stroke width of notched outline that needs to be offset.
116+ ///
117+ @mixin notch-offset ($stroke-width , $query : feature-targeting .all ()) {
118+ $feat-structure : feature-targeting .create-target ($query , structure );
119+
120+ .mdc-notched-outline--notched .mdc-notched-outline__notch {
121+ @include feature-targeting .targets ($feat-structure ) {
122+ padding-top : $stroke-width ;
123+ }
124+ }
125+ }
126+
127+ @mixin shape-radius (
128+ $radius ,
129+ $rtl-reflexive : false,
130+ $component-height : null,
131+ $query : feature-targeting .all ()
132+ ) {
133+ $feat-structure : feature-targeting .create-target ($query , structure );
134+ // Resolve the radius relative to the notched outline component's height. The
135+ // component should provide its current height from its density. The resolved
136+ // radius allows percentage radii to be converted to pixels.
137+ $resolved-radius : shape-functions .resolve-radius (
138+ $radius ,
139+ $component-height : $component-height
140+ );
141+
142+ // Grab the top-left radius. We'll need it to adjust the leading for the
143+ // label notch if the resulting radius shape is larger than the default
144+ // leading.
145+ $top-left-radius : list .nth (
146+ shape-functions .unpack-radius ($resolved-radius ),
147+ 1
148+ );
149+ $top-left-is-custom-prop : custom-properties .is-custom-prop ($top-left-radius );
150+ $top-left-radius-px : $top-left-radius ;
151+ @if ($top-left-is-custom-prop ) {
152+ $top-left-radius-px : custom-properties .get-fallback ($top-left-radius );
153+ }
154+
155+ .mdc-notched-outline__leading {
156+ // mask the leading to apply the top-left and bottom-left corners
157+ @include shape-mixins .radius (
158+ shape-functions .mask-radius ($radius , 1 0 0 1 ),
159+ $rtl-reflexive : true,
160+ $component-height : $component-height ,
161+ $query : $query
162+ );
163+
164+ @include feature-targeting .targets ($feat-structure ) {
165+ @if ($top-left-radius-px > $leading-width ) {
166+ // If the radius is bigger than the default leading width, we need to
167+ // increase the leading width
168+ width : $top-left-radius-px ;
169+ @if ($top-left-is-custom-prop ) {
170+ // The radius may be a custom property, in which case the above width
171+ // is the IE11 fallback value.
172+ /* @alternate */
173+ }
174+ }
175+
176+ @if ($top-left-is-custom-prop ) {
177+ // If the top-left radius is dynamic, the width of the leading is
178+ // the max of whichever is larger: the default leading width or the
179+ // value of the custom property.
180+ $var : custom-properties .create-var ($top-left-radius );
181+ // Interpolation is a workaround for sass/sass#3259.
182+ @supports (top : max (#{0% } )) {
183+ width : max (#{$leading-width } , #{$var } );
184+ }
185+ }
186+ }
187+ }
188+
189+ // Similar to above, adjust the max-width of the notch if we adjusted the
190+ // leading's width.
191+ .mdc-notched-outline__notch {
192+ @include feature-targeting .targets ($feat-structure ) {
193+ @if ($top-left-radius-px > $leading-width ) {
194+ max-width : calc (100% - #{$top-left-radius-px } * 2 );
195+ @if ($top-left-is-custom-prop ) {
196+ /* @alternate */
197+ }
198+ }
199+
200+ @if ($top-left-is-custom-prop ) {
201+ $var : custom-properties .create-var ($top-left-radius );
202+ // Interpolation is a workaround for sass/sass#3259.
203+ @supports (top : max (#{0% } )) {
204+ max-width : calc (100% - max (#{$leading-width } , #{$var } ) * 2 );
205+ }
206+ }
207+ }
208+ }
209+
210+ .mdc-notched-outline__trailing {
211+ // mask the leading to apply the top-right and bottom-right corners
212+ @include shape-mixins .radius (
213+ shape-functions .mask-radius ($radius , 0 1 1 0 ),
214+ $rtl-reflexive : true,
215+ $component-height : $component-height ,
216+ $query : $query
217+ );
218+ }
219+ }
220+
221+ @mixin floating-label-float-position (
222+ $positionY ,
223+ $positionX : 0% ,
224+ $scale : 0.75 ,
225+ $query : feature-targeting .all ()
226+ ) {
227+ $feat-structure : feature-targeting .create-target ($query , structure );
228+
229+ @include floating-label-mixins .float-position (
230+ $positionY + $label-adjust ,
231+ $positionX ,
232+ 1 ,
233+ $query : $query
234+ );
235+
236+ .mdc-floating-label--float-above {
237+ @include feature-targeting .targets ($feat-structure ) {
238+ font-size : ($scale * 1rem );
239+ }
240+ }
241+
242+ // Two selectors to ensure we select the appropriate class when applied from this component or a parent component.
243+ & .mdc-notched-outline--upgraded ,
244+ .mdc-notched-outline--upgraded {
245+ @include floating-label-mixins .float-position (
246+ $positionY ,
247+ $positionX ,
248+ $scale ,
249+ $query : $query
250+ );
251+
252+ .mdc-floating-label--float-above {
253+ @include feature-targeting .targets ($feat-structure ) {
254+ font-size : 1rem ;
255+ }
256+ }
257+ }
258+ }
259+
260+ ///
261+ /// Sets floating label position in notched outline when label is afloat.
262+ ///
263+ /// @param {Number} $positionY Absolute Y-axis position in `px`.
264+ /// @param {Number} $positionX Absolute X-axis position in `px`. Defaults to `0`.
265+ /// @param {Number} $scale Defaults to `.75`.
266+ ///
267+ /// @todo Replace mixin `mdc-notched-outline-floating-label-float-position` with this mixin when floating label is
268+ /// center aligned in all the places.
269+ ///
270+ @mixin floating-label-float-position-absolute (
271+ $positionY ,
272+ $positionX : 0 ,
273+ $scale : 0.75 ,
274+ $query : feature-targeting .all ()
275+ ) {
276+ $feat-structure : feature-targeting .create-target ($query , structure );
277+ $float-positionY : if (
278+ meta .type-of ($positionY ) == ' calculation' ,
279+ calc ($positionY + $label-adjust-absolute ),
280+ $positionY + $label-adjust-absolute
281+ );
282+
283+ @include floating-label-mixins .float-position (
284+ $float-positionY ,
285+ $positionX ,
286+ $scale : 1 ,
287+ $query : $query
288+ );
289+
290+ .mdc-floating-label--float-above {
291+ @include feature-targeting .targets ($feat-structure ) {
292+ font-size : ($scale * 1rem );
293+ }
294+ }
295+
296+ // Two selectors to ensure we select the appropriate class when applied from this component or a parent component.
297+ & .mdc-notched-outline--upgraded ,
298+ .mdc-notched-outline--upgraded {
299+ @include floating-label-mixins .float-position (
300+ $positionY ,
301+ $positionX ,
302+ $scale ,
303+ $query : $query
304+ );
305+
306+ .mdc-floating-label--float-above {
307+ @include feature-targeting .targets ($feat-structure ) {
308+ font-size : 1rem ;
309+ }
310+ }
311+ }
312+ }
313+
314+ ///
315+ /// Sets the max-width for the notch
316+ ///
317+ /// @param {Number} $max-width Max-width for the notch
318+ ///
319+ @mixin notch-max-width ($max-width , $query : feature-targeting .all ()) {
320+ $feat-structure : feature-targeting .create-target ($query , structure );
321+
322+ :not (.mdc-notched-outline--notched ) .mdc-notched-outline__notch {
323+ @include feature-targeting .targets ($feat-structure ) {
324+ max-width : $max-width ;
325+ }
326+ }
327+ }
0 commit comments