Skip to content

Commit def17cd

Browse files
Elliott Marquezcopybara-github
authored andcommitted
feat(m3-fab-*): refactor JS & styles to support internal frameworks
* split fab.ts into fab.ts and fab-shared.ts * applied .m3-fab--regular to non-extended fab * styles refactored to support lack of shadow DOM PiperOrigin-RevId: 401646398
1 parent c713177 commit def17cd

File tree

10 files changed

+212
-139
lines changed

10 files changed

+212
-139
lines changed

components/fab/_fab-extended-theme.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
@forward "./lib/fab-extended-theme" show theme;
7+
@forward "./lib/fab-extended-theme" show theme, $light-theme, $dark-theme;

components/fab/_fab-theme.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
@forward "./lib/fab-theme" show theme;
7+
@forward "./lib/fab-theme" show theme, $light-theme, $dark-theme;

components/fab/lib/_fab-extended-theme.scss

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ $primary: #6200ee;
2222
$primary-state-layer: #6200ee;
2323
$primary-state-content: #6200ee;
2424

25+
$dark-surface: #1f1f1f;
26+
$dark-primary: #bb86fc;
27+
$dark-secondary: #018786;
28+
$dark-on-primary: #000;
29+
$dark-on-secondary: #fff;
30+
2531
$light-theme: (
2632
container-color: $surface,
2733
container-elevation: $_elevation-3-dp,
@@ -58,6 +64,22 @@ $light-theme: (
5864
surface-tint-layer-color: $primary,
5965
);
6066

67+
$dark-theme: (
68+
container-color: $dark-surface,
69+
icon-color: $dark-primary,
70+
surface-tint-layer-color: $dark-primary,
71+
hover-icon-color: $dark-primary,
72+
hover-state-layer-color: $dark-primary,
73+
focus-icon-color: $dark-primary,
74+
focus-state-layer-color: $dark-primary,
75+
pressed-icon-color: $dark-primary,
76+
pressed-state-layer-color: $dark-primary,
77+
label-text-color: $dark-primary,
78+
focus-label-text-color: $dark-primary,
79+
hover-label-text-color: $dark-primary,
80+
pressed-label-text-color: $dark-primary,
81+
);
82+
6183
@mixin theme($theme, $resolvers: resolvers.$material) {
6284
@include theme.validate-theme($light-theme, $theme);
6385

components/fab/lib/_fab-shared-theme.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ $selectors: (
144144
.md3-fab__icon {
145145
@include theme.property(width, $size);
146146
@include theme.property(height, $size);
147+
@include theme.property(font-size, $size);
147148
@include theme.property(--mdc-icon-size, $size);
148149
}
149150
}

components/fab/lib/_fab-theme.scss

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ $primary: #6200ee;
2020
$primary-state-layer: #6200ee;
2121
$primary-state-content: #6200ee;
2222

23+
$dark-surface: #1f1f1f;
24+
$dark-primary: #bb86fc;
25+
$dark-secondary: #018786;
26+
$dark-on-primary: #000;
27+
$dark-on-secondary: #fff;
28+
2329
$light-theme: (
2430
container-color: $surface,
2531
container-elevation: $_elevation-3-dp,
@@ -48,6 +54,18 @@ $light-theme: (
4854
surface-tint-layer-color: $primary,
4955
);
5056

57+
$dark-theme: (
58+
container-color: $dark-surface,
59+
icon-color: $dark-primary,
60+
surface-tint-layer-color: $dark-primary,
61+
hover-icon-color: $dark-primary,
62+
hover-state-layer-color: $dark-primary,
63+
focus-icon-color: $dark-primary,
64+
focus-state-layer-color: $dark-primary,
65+
pressed-icon-color: $dark-primary,
66+
pressed-state-layer-color: $dark-primary,
67+
);
68+
5169
@mixin theme($theme, $resolvers: resolvers.$material) {
5270
@include theme.validate-theme($light-theme, $theme);
5371

components/fab/lib/_fab.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
@use '@material/theme/selector-ext';
1010

1111
@mixin static-styles() {
12-
:host {
12+
:host,
13+
// remove once b/b/201687177 is resolved
14+
.md3-fab__host {
1315
@include host-root;
1416
@include selector-ext.append-strict(&, '[disabled]') {
1517
@include disabled;

components/fab/lib/fab-extended-styles.scss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
* Copyright 2021 Google LLC
44
* SPDX-License-Identifier: Apache-2.0
55
*/
6-
7-
@use './fab-extended';
86
@use './fab-extended-theme';
7+
@use './fab-extended';
98

109
@include fab-extended.static-styles();
1110

components/fab/lib/fab-extended.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@
77
// Style preference for leading underscores.
88
// tslint:disable:strip-private-property-underscore
99

10-
import {html} from 'lit';
10+
import {html, TemplateResult} from 'lit';
1111
import {ClassInfo} from 'lit/directives/class-map.js';
1212

13-
import {Fab} from './fab';
13+
import {FabShared} from './fab-shared';
1414

15-
export class FabExtended extends Fab {
15+
/**
16+
* Fab Extended Base class logic and template definition
17+
* @soyCompatible
18+
*/
19+
export class FabExtended extends FabShared {
1620
/** @soyTemplate */
1721
protected override getRootClasses(): ClassInfo {
1822
return {
@@ -22,7 +26,7 @@ export class FabExtended extends Fab {
2226
}
2327

2428
/** @soyTemplate */
25-
protected override renderLabel() {
29+
protected override renderLabel(): TemplateResult {
2630
return html`<span class="md3-fab__label">${this.label}</span>`;
2731
}
2832
}

components/fab/lib/fab-shared.ts

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/**
2+
* @license
3+
* Copyright 2021 Google LLC
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
// Style preference for leading underscores.
8+
// tslint:disable:strip-private-property-underscore
9+
10+
import '@material/mwc-ripple/mwc-ripple';
11+
12+
import {Ripple} from '@material/mwc-ripple/mwc-ripple';
13+
import {RippleHandlers} from '@material/mwc-ripple/ripple-handlers';
14+
import {html, LitElement, TemplateResult} from 'lit';
15+
import {eventOptions, property, queryAsync, state} from 'lit/decorators.js';
16+
import {ClassInfo, classMap} from 'lit/directives/class-map.js';
17+
18+
/**
19+
* Fab Base class logic and template definition
20+
* @soyCompatible
21+
*/
22+
export class FabShared extends LitElement {
23+
static override shadowRootOptions:
24+
ShadowRootInit = {mode: 'open', delegatesFocus: true};
25+
26+
@queryAsync('mwc-ripple') ripple!: Promise<Ripple|null>;
27+
28+
@property({type: Boolean}) disabled = false;
29+
30+
@property() icon = '';
31+
32+
@property() label = '';
33+
34+
@property({type: Boolean}) lowered = false;
35+
36+
@state() protected shouldRenderRipple = false;
37+
38+
protected rippleHandlers = new RippleHandlers(() => {
39+
this.shouldRenderRipple = true;
40+
return this.ripple;
41+
});
42+
43+
/**
44+
* @soyTemplate
45+
* @soyClasses fabClasses: .md3-fab
46+
*/
47+
protected override render(): TemplateResult {
48+
const ariaLabel = this.label ? this.label : this.icon;
49+
50+
/*
51+
* Some internal styling is sensitive to whitespace in this template, take
52+
* care when modifying it.
53+
*/
54+
return html`
55+
<button
56+
class="md3-fab md3-surface ${classMap(this.getRootClasses())}"
57+
?disabled="${this.disabled}"
58+
aria-label="${ariaLabel}"
59+
@mouseenter=${this.handleRippleMouseEnter}
60+
@mouseleave=${this.handleRippleMouseLeave}
61+
@focus=${this.handleRippleFocus}
62+
@blur=${this.handleRippleBlur}
63+
@mousedown=${this.handleRippleActivate}
64+
@touchstart=${this.handleRippleStartPress}
65+
@touchend=${this.handleRippleDeactivate}
66+
@touchcancel=${this.handleRippleDeactivate}><!--
67+
-->${this.renderElevationOverlay()}<!--
68+
-->${this.renderRipple()}<!--
69+
--><span class="material-icons md3-fab__icon"><!--
70+
--><slot name="icon">${this.icon}</slot><!--
71+
--></span><!--
72+
-->${this.renderLabel()}<!--
73+
-->${this.renderTouchTarget()}<!--
74+
</button>`;
75+
}
76+
77+
/** @soyTemplate */
78+
protected getRootClasses(): ClassInfo {
79+
return {'md3-fab--lowered': this.lowered};
80+
}
81+
82+
/** @soyTemplate */
83+
protected renderIcon(): TemplateResult {
84+
// TODO(b/191914389): reimplement once Wit issue is resolved
85+
return html``;
86+
}
87+
88+
/** @soyTemplate */
89+
protected renderTouchTarget(): TemplateResult {
90+
return html``;
91+
}
92+
93+
/** @soyTemplate */
94+
protected renderLabel(): TemplateResult {
95+
return html``;
96+
}
97+
98+
/** @soyTemplate */
99+
protected renderElevationOverlay(): TemplateResult {
100+
return html`<div class="md3-elevation-overlay"></div>`;
101+
}
102+
103+
/** @soyTemplate */
104+
protected renderRipple(): TemplateResult {
105+
return this.shouldRenderRipple ? html`
106+
<mwc-ripple
107+
class="md3-fab__ripple"
108+
internalUseStateLayerCustomProperties>
109+
</mwc-ripple>` :
110+
html``;
111+
}
112+
113+
protected handleRippleActivate(event?: Event) {
114+
const onUp = () => {
115+
window.removeEventListener('mouseup', onUp);
116+
117+
this.handleRippleDeactivate();
118+
};
119+
120+
window.addEventListener('mouseup', onUp);
121+
this.handleRippleStartPress(event);
122+
}
123+
124+
@eventOptions({passive: true})
125+
protected handleRippleStartPress(event?: Event) {
126+
this.rippleHandlers.startPress(event);
127+
}
128+
129+
protected handleRippleDeactivate() {
130+
this.rippleHandlers.endPress();
131+
}
132+
133+
protected handleRippleMouseEnter() {
134+
this.rippleHandlers.startHover();
135+
}
136+
137+
protected handleRippleMouseLeave() {
138+
this.rippleHandlers.endHover();
139+
}
140+
141+
protected handleRippleFocus() {
142+
this.rippleHandlers.startFocus();
143+
}
144+
145+
protected handleRippleBlur() {
146+
this.rippleHandlers.endFocus();
147+
}
148+
}

0 commit comments

Comments
 (0)