diff --git a/docs/components/fab.md b/docs/components/fab.md index 754159067d..c4d62638c3 100644 --- a/docs/components/fab.md +++ b/docs/components/fab.md @@ -142,7 +142,7 @@ additional context if needed. By supplying the `label` attribute, the extended FAB will make sure that the icon is not announced. ```html - + edit ``` @@ -169,11 +169,6 @@ FABs should display a clear and understandable icon. FABs may be extended with a label for additional emphasis. Extended FABs can omit their icon. -*SSR note:* extended FABs with icons should add the `has-icon` attribute to -avoid a flash of unstyled content. Otherwise, the client will automatically -detect if an icon is slotted into the element, but that event is not fired upon -hydration of a SSRd declarative shadow DOM template. - ![An extended FAB with an edit icon and the visible text edit](images/fab/usage-extended.webp) @@ -182,7 +177,7 @@ hydration of a SSRd declarative shadow DOM template. ```html - + edit ``` @@ -421,7 +416,7 @@ Token | Default value background-color: #f4fbfa; } - + edit ``` diff --git a/docs/components/figures/fab/extended-fabs.html b/docs/components/figures/fab/extended-fabs.html index 09d442bf65..a32b9a7538 100644 --- a/docs/components/figures/fab/extended-fabs.html +++ b/docs/components/figures/fab/extended-fabs.html @@ -7,7 +7,7 @@
- +
diff --git a/docs/components/figures/fab/theming-extended.html b/docs/components/figures/fab/theming-extended.html index ea01a2c468..bac4e865ef 100644 --- a/docs/components/figures/fab/theming-extended.html +++ b/docs/components/figures/fab/theming-extended.html @@ -10,7 +10,7 @@ --md-fab-container-shape: 0px; } - + edit diff --git a/docs/components/figures/fab/usage-extended.html b/docs/components/figures/fab/usage-extended.html index 4ed45e619f..7ce6c0955e 100644 --- a/docs/components/figures/fab/usage-extended.html +++ b/docs/components/figures/fab/usage-extended.html @@ -2,7 +2,7 @@
- + edit
diff --git a/fab/demo/demo.ts b/fab/demo/demo.ts index e18c67a166..c587a30066 100644 --- a/fab/demo/demo.ts +++ b/fab/demo/demo.ts @@ -38,7 +38,6 @@ const collection = new MaterialCollection>('Fab', [ ] }) }), - new Knob('hasIcon', {defaultValue: true, ui: boolInput()}), ]); collection.addStories(...materialInitsToStoryInits(stories)); diff --git a/fab/demo/stories.ts b/fab/demo/stories.ts index c0c8a16c44..1556378a06 100644 --- a/fab/demo/stories.ts +++ b/fab/demo/stories.ts @@ -19,7 +19,6 @@ export interface StoryKnobs { lowered: boolean; size: FabSize|undefined; variant: FabVariant|undefined; - hasIcon: boolean; } const styles = css` @@ -31,15 +30,14 @@ const styles = css` const standard: MaterialStoryInit = { name: '', styles, - render({icon, label, lowered, size, variant, hasIcon}) { + render({icon, label, lowered, size, variant}) { return html` + .size=${size!}> ${icon} `; @@ -49,14 +47,13 @@ const standard: MaterialStoryInit = { const branded: MaterialStoryInit = { name: '', styles, - render({label, lowered, size, hasIcon}) { + render({label, lowered, size}) { return html` + .size=${size!}> diff --git a/fab/internal/_fab.scss b/fab/internal/_fab.scss index 67177ce975..5ed322e0a0 100644 --- a/fab/internal/_fab.scss +++ b/fab/internal/_fab.scss @@ -173,16 +173,19 @@ } } - .fab:not(.hasIcon) { - padding-inline-start: 20px; - } - - .fab:not(.hasIcon) .icon { - display: none; - } - - .fab:not(.hasIcon) .label { - padding-inline-start: 0; + /* + * The default content is needed because we do a bit of trickery. If there is + * no slotted icon we need to have `padding-inline: 20px` but if there is, we + * need padding-inline: 16px 20px. + * + * So what this approach does is make the margin / padding-inline of the outer + * button `padding-inline: 16px 20px`, so if there is something slotted, it + * renders correctly. This default content span then fills the extra `4px` + * inline spacing if nothing is slotted which effectively makes the button's + * inlne spacing `20px/20px`. + */ + .fab.extended slot span { + padding-inline-start: 4px; } .fab.small { diff --git a/fab/internal/_shared.scss b/fab/internal/_shared.scss index d68bc64414..53ffbcc2c7 100644 --- a/fab/internal/_shared.scss +++ b/fab/internal/_shared.scss @@ -133,13 +133,16 @@ $_md-sys-motion: tokens.md-sys-motion-values(); } .label { - padding-inline-start: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: var(--_label-text-type); } + .fab.extended .icon ::slotted(*) { + margin-inline-end: 12px; + } + .ripple { overflow: hidden; } diff --git a/fab/internal/shared.ts b/fab/internal/shared.ts index 60f580b670..ad6ffca338 100644 --- a/fab/internal/shared.ts +++ b/fab/internal/shared.ts @@ -51,14 +51,6 @@ export abstract class SharedFab extends LitElement { */ @property({type: Boolean}) lowered = false; - /** - * NOTE: For SSR use only as it will be overriden by icon slotchange event. - * - * Whether to display the icon or not in extended FAB. Does nothing on branded - * and non-extended FABs. - */ - @property({type: Boolean, attribute: 'has-icon'}) hasIcon = false; - protected override render() { // Needed for closure conformance const {ariaLabel} = this as ARIAMixinStrict; @@ -84,7 +76,6 @@ export abstract class SharedFab extends LitElement { 'small': this.size === 'small' && !isExtended, 'large': this.size === 'large' && !isExtended, 'extended': isExtended, - 'hasIcon': !isExtended || this.hasIcon, }; } @@ -102,15 +93,9 @@ export abstract class SharedFab extends LitElement { + ariaLabel || this.label ? 'true' : nothing as unknown as 'false'}> + `; } - - private onSlotchange(event: Event) { - const slotEl = event.target as HTMLSlotElement; - const slottedEls = slotEl.assignedElements({flatten: true}); - this.hasIcon = slottedEls.length !== 0; - } }