From 0ab5fd595d8c163065860a2e0deec8b77c8c9d77 Mon Sep 17 00:00:00 2001 From: Elizabeth Mitchell Date: Tue, 11 Jul 2023 21:00:54 -0700 Subject: [PATCH] fix(field): move padding to slotted content PiperOrigin-RevId: 547375880 --- field/demo/stories.ts | 14 -------------- field/lib/_content.scss | 15 +++++++++++---- field/lib/_filled-field.scss | 24 +++++++++++++++--------- field/lib/_label.scss | 13 +++++++++++++ field/lib/_outlined-field.scss | 24 +++++++++++++++++------- field/lib/_shared.scss | 2 -- field/lib/field.ts | 10 ++++++---- select/lib/_shared.scss | 4 ---- select/lib/select.ts | 4 +--- textfield/lib/_input.scss | 24 ++++++++++++++++-------- textfield/lib/text-field.ts | 2 +- 11 files changed, 80 insertions(+), 56 deletions(-) diff --git a/field/demo/stories.ts b/field/demo/stories.ts index 50bd7e583d..22e3a46c6d 100644 --- a/field/demo/stories.ts +++ b/field/demo/stories.ts @@ -36,20 +36,6 @@ const styles = css` md-outlined-field { width: 256px; } - - input, - textarea { - background: none; - border: none; - box-sizing: border-box; - color: currentColor; - font: inherit; - outline: 1px dashed currentColor; - padding: 0; - resize: none; - margin: 0; - width: 100%; - } `; const filled: MaterialStoryInit = { diff --git a/field/lib/_content.scss b/field/lib/_content.scss index 51bcf16e98..a63cf2b9ea 100644 --- a/field/lib/_content.scss +++ b/field/lib/_content.scss @@ -74,13 +74,9 @@ $_enter-delay: $_label-duration - $_visible-duration; } .content { - // Content elements provided to the field (such as ) may use - // `currentColor` to inherit this property. color: var(--_content-color); display: flex; flex: 1; - // Content elements provided to the field (such as ) may inherit font - font: var(--_content-type); opacity: 0; transition: opacity $_visible-duration map.get($_md-sys-motion, 'easing-emphasized'); @@ -93,6 +89,17 @@ $_enter-delay: $_label-duration - $_visible-duration; transition-delay: $_enter-delay; } + .content ::slotted(*) { + all: unset; + // Use `currentColor` to inherit the various state colors that are set + // below. + color: currentColor; + font: var(--_content-type); + padding-top: var(--_top-space); + padding-bottom: var(--_bottom-space); + width: 100%; + } + :hover .content { color: var(--_hover-content-color); } diff --git a/field/lib/_filled-field.scss b/field/lib/_filled-field.scss index b47764797d..00c36811be 100644 --- a/field/lib/_filled-field.scss +++ b/field/lib/_filled-field.scss @@ -92,7 +92,15 @@ $_md-sys-motion: tokens.md-sys-motion-values(); .label.floating { position: absolute; - top: 0; + top: var(--_with-label-top-space); + } + + .field:not(.with-start) .label-space { + margin-inline-start: var(--_leading-space); + } + + .field:not(.with-end) .label-space { + margin-inline-end: var(--_trailing-space); } .active-indicator { @@ -125,21 +133,19 @@ $_md-sys-motion: tokens.md-sys-motion-values(); opacity: 1; } - .field:not(.with-start) .start { + .field:not(.with-start) .content ::slotted(*) { padding-inline-start: var(--_leading-space); } - .field:not(.with-end) .end { + .field:not(.with-end) .content ::slotted(*) { padding-inline-end: var(--_trailing-space); } - .field:not(.no-label) .container { + .field:not(.no-label) .content ::slotted(*) { padding-bottom: var(--_with-label-bottom-space); - padding-top: var(--_with-label-top-space); - } - - .field:not(.no-label) .middle { - padding-top: var(--_label-text-populated-line-height); + padding-top: calc( + var(--_with-label-top-space) + var(--_label-text-populated-line-height) + ); } :hover .active-indicator::before { diff --git a/field/lib/_label.scss b/field/lib/_label.scss index 0b65c1d0db..0aaf01cacb 100644 --- a/field/lib/_label.scss +++ b/field/lib/_label.scss @@ -5,6 +5,7 @@ @mixin styles() { .label { + box-sizing: border-box; color: var(--_label-text-color); overflow: hidden; max-width: 100%; @@ -22,6 +23,7 @@ white-space: nowrap; z-index: 1; font: var(--_label-text-type); + width: min-content; } .label.resting { @@ -44,6 +46,17 @@ display: none; } + // Labels need start/end padding when there isn't start/end content so they + // don't sit on the edge of the field. We use a wrapper element around the + // labels so as not to affect the dimensions used in the label keyframes. + .label-space { + inset: 0; + position: absolute; + // Don't let setting text-align on the field change the label's alignment. + // It should only impact content text. + text-align: initial; + } + :hover .label { color: var(--_hover-label-text-color); } diff --git a/field/lib/_outlined-field.scss b/field/lib/_outlined-field.scss index 88e28b56f2..f1dfb30d5e 100644 --- a/field/lib/_outlined-field.scss +++ b/field/lib/_outlined-field.scss @@ -226,17 +226,27 @@ $_md-sys-motion: tokens.md-sys-motion-values(); var(--_container-shape-start-end), var(--_container-shape-end-end) ); + $start-space: max( + var(--_leading-space), + $shape-start + var(--_outline-label-padding) + ); + $end-space: max(var(--_trailing-space), $shape-end); .outline-start, - .field:not(.with-start) .start { - padding-inline-start: max( - var(--_leading-space), - $shape-start + var(--_outline-label-padding) - ); + .field:not(.with-start) .content ::slotted(*) { + padding-inline-start: $start-space; + } + + .field:not(.with-start) .label-space { + margin-inline-start: $start-space; + } + + .field:not(.with-end) .content ::slotted(*) { + padding-inline-end: $end-space; } - .field:not(.with-end) .end { - padding-inline-end: max(var(--_trailing-space), $shape-end); + .field:not(.with-end) .label-space { + margin-inline-end: $end-space; } .outline-start::before, diff --git a/field/lib/_shared.scss b/field/lib/_shared.scss index c0514ae831..208a1de90a 100644 --- a/field/lib/_shared.scss +++ b/field/lib/_shared.scss @@ -46,8 +46,6 @@ flex: 1; min-width: min-content; overflow: hidden; - padding-top: var(--_top-space); - padding-bottom: var(--_bottom-space); position: relative; } diff --git a/field/lib/field.ts b/field/lib/field.ts index f7ab2cb381..b715925482 100644 --- a/field/lib/field.ts +++ b/field/lib/field.ts @@ -112,16 +112,16 @@ export class Field extends LitElement implements SurfacePositionTarget { return html`
- ${outline} ${this.renderBackground?.()} - ${this.renderIndicator?.()}
- ${restingLabel} - ${outline ? nothing : floatingLabel} +
+ ${restingLabel} + ${outline ? nothing : floatingLabel} +
@@ -130,6 +130,8 @@ export class Field extends LitElement implements SurfacePositionTarget {
+ ${outline} + ${this.renderIndicator?.()}
${this.renderSupportingText()}
diff --git a/select/lib/_shared.scss b/select/lib/_shared.scss index 02d9e09873..b28c589c7c 100644 --- a/select/lib/_shared.scss +++ b/select/lib/_shared.scss @@ -46,10 +46,6 @@ display: inline-flex; } - .label { - width: 100%; - } - :host([disabled]) { pointer-events: none; } diff --git a/select/lib/select.ts b/select/lib/select.ts index 5e9f63ef0c..34cddcc06f 100644 --- a/select/lib/select.ts +++ b/select/lib/select.ts @@ -244,9 +244,7 @@ export abstract class Select extends LitElement { private renderLabel() { // need to render   so that line-height can apply and give it a // non-zero height - return html`
${this.displayText || html` `}
`; + return html`
${this.displayText || html` `}
`; } private renderMenu() { diff --git a/textfield/lib/_input.scss b/textfield/lib/_input.scss index 1454c67edd..2703cf4362 100644 --- a/textfield/lib/_input.scss +++ b/textfield/lib/_input.scss @@ -4,17 +4,20 @@ // @mixin styles() { + .content { + display: flex; + } + + input, + .prefix, + .suffix { + all: inherit; + padding: 0; + } + input { - appearance: none; - background: none; - border: none; caret-color: var(--_caret-color); - color: currentColor; - font: inherit; - outline: none; - padding: 0; text-align: inherit; - width: 100%; &::placeholder { color: currentColor; @@ -51,6 +54,11 @@ color: var(--_input-text-placeholder-color); } + .prefix, + .suffix { + width: min-content; + } + .prefix { padding-inline-end: var(--_input-text-prefix-trailing-space); } diff --git a/textfield/lib/text-field.ts b/textfield/lib/text-field.ts index 3b1d0e93fd..587e646ab6 100644 --- a/textfield/lib/text-field.ts +++ b/textfield/lib/text-field.ts @@ -517,7 +517,7 @@ export abstract class TextField extends LitElement { max=${this.maxLength} > ${this.renderLeadingIcon()} - ${prefix}${input}${suffix} +
${prefix}${input}${suffix}
${this.renderTrailingIcon()} `; }