Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

Commit 1e10ac2

Browse files
kfranqueiroKenneth G. Franqueiro
authored andcommitted
fix(ripple): Register focus/blur handlers in IE (#3294)
(cherry picked from commit 1186f9b)
1 parent c4fc932 commit 1e10ac2

File tree

5 files changed

+57
-48
lines changed

5 files changed

+57
-48
lines changed

packages/mdc-checkbox/_variables.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// limitations under the License.
1515
//
1616

17+
@import "@material/ripple/variables";
1718
@import "@material/theme/variables";
1819

1920
$mdc-checkbox-mark-color: mdc-theme-prop-value(on-primary);
@@ -28,8 +29,7 @@ $mdc-checkbox-mark-stroke-size: 2/15 * $mdc-checkbox-size;
2829
$mdc-checkbox-border-width: 2px;
2930
$mdc-checkbox-transition-duration: 90ms;
3031
$mdc-checkbox-item-spacing: 4px;
31-
$mdc-checkbox-ripple-opacity: .14;
32-
$mdc-checkbox-focus-indicator-opacity: .26;
32+
$mdc-checkbox-focus-indicator-opacity: map-get($mdc-ripple-dark-ink-opacities, focus);
3333

3434
// Manual calculation done on SVG
3535
$mdc-checkbox-mark-path-length_: 29.7833385;

packages/mdc-checkbox/mdc-checkbox.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
@include mdc-checkbox__focus-indicator_;
9191
}
9292

93-
.mdc-ripple-upgraded--unbounded .mdc-checkbox__background::before {
93+
.mdc-ripple-upgraded--background-focused .mdc-checkbox__background::before {
9494
@include mdc-checkbox__focus-indicator--ripple-upgraded-unbounded_;
9595
}
9696

packages/mdc-radio/mdc-radio.scss

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
@import "@material/animation/functions";
1818
@import "@material/ripple/common";
1919
@import "@material/ripple/mixins";
20+
@import "@material/ripple/variables";
2021
@import "./functions";
2122
@import "./mixins";
2223
@import "./variables";
@@ -108,7 +109,7 @@
108109
}
109110

110111
// stylelint-disable plugin/selector-bem-pattern
111-
&.mdc-ripple-upgraded {
112+
&.mdc-ripple-upgraded--background-focused {
112113
.mdc-radio__background::before {
113114
content: none;
114115
}
@@ -164,7 +165,7 @@
164165
+ .mdc-radio__background::before {
165166
transform: scale(2, 2);
166167
transition: mdc-radio-enter(opacity), mdc-radio-enter(transform);
167-
opacity: .26;
168+
opacity: map-get($mdc-ripple-dark-ink-opacities, focus);
168169
}
169170
}
170171

packages/mdc-ripple/foundation.js

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ class MDCRippleFoundation extends MDCFoundation {
176176
* @return {boolean}
177177
* @private
178178
*/
179-
isSupported_() {
179+
supportsPressRipple_() {
180180
return this.adapter_.browserSupportsCssVars();
181181
}
182182

@@ -196,57 +196,61 @@ class MDCRippleFoundation extends MDCFoundation {
196196

197197
/** @override */
198198
init() {
199-
if (!this.isSupported_()) {
200-
return;
201-
}
202-
this.registerRootHandlers_();
199+
const supportsPressRipple = this.supportsPressRipple_();
203200

204-
const {ROOT, UNBOUNDED} = MDCRippleFoundation.cssClasses;
205-
requestAnimationFrame(() => {
206-
this.adapter_.addClass(ROOT);
207-
if (this.adapter_.isUnbounded()) {
208-
this.adapter_.addClass(UNBOUNDED);
209-
// Unbounded ripples need layout logic applied immediately to set coordinates for both shade and ripple
210-
this.layoutInternal_();
211-
}
212-
});
201+
this.registerRootHandlers_(supportsPressRipple);
202+
203+
if (supportsPressRipple) {
204+
const {ROOT, UNBOUNDED} = MDCRippleFoundation.cssClasses;
205+
requestAnimationFrame(() => {
206+
this.adapter_.addClass(ROOT);
207+
if (this.adapter_.isUnbounded()) {
208+
this.adapter_.addClass(UNBOUNDED);
209+
// Unbounded ripples need layout logic applied immediately to set coordinates for both shade and ripple
210+
this.layoutInternal_();
211+
}
212+
});
213+
}
213214
}
214215

215216
/** @override */
216217
destroy() {
217-
if (!this.isSupported_()) {
218-
return;
219-
}
218+
if (this.supportsPressRipple_()) {
219+
if (this.activationTimer_) {
220+
clearTimeout(this.activationTimer_);
221+
this.activationTimer_ = 0;
222+
const {FG_ACTIVATION} = MDCRippleFoundation.cssClasses;
223+
this.adapter_.removeClass(FG_ACTIVATION);
224+
}
220225

221-
if (this.activationTimer_) {
222-
clearTimeout(this.activationTimer_);
223-
this.activationTimer_ = 0;
224-
const {FG_ACTIVATION} = MDCRippleFoundation.cssClasses;
225-
this.adapter_.removeClass(FG_ACTIVATION);
226+
const {ROOT, UNBOUNDED} = MDCRippleFoundation.cssClasses;
227+
requestAnimationFrame(() => {
228+
this.adapter_.removeClass(ROOT);
229+
this.adapter_.removeClass(UNBOUNDED);
230+
this.removeCssVars_();
231+
});
226232
}
227233

228234
this.deregisterRootHandlers_();
229235
this.deregisterDeactivationHandlers_();
230-
231-
const {ROOT, UNBOUNDED} = MDCRippleFoundation.cssClasses;
232-
requestAnimationFrame(() => {
233-
this.adapter_.removeClass(ROOT);
234-
this.adapter_.removeClass(UNBOUNDED);
235-
this.removeCssVars_();
236-
});
237236
}
238237

239-
/** @private */
240-
registerRootHandlers_() {
241-
ACTIVATION_EVENT_TYPES.forEach((type) => {
242-
this.adapter_.registerInteractionHandler(type, this.activateHandler_);
243-
});
238+
/**
239+
* @param {boolean} supportsPressRipple Passed from init to save a redundant function call
240+
* @private
241+
*/
242+
registerRootHandlers_(supportsPressRipple) {
243+
if (supportsPressRipple) {
244+
ACTIVATION_EVENT_TYPES.forEach((type) => {
245+
this.adapter_.registerInteractionHandler(type, this.activateHandler_);
246+
});
247+
if (this.adapter_.isUnbounded()) {
248+
this.adapter_.registerResizeHandler(this.resizeHandler_);
249+
}
250+
}
251+
244252
this.adapter_.registerInteractionHandler('focus', this.focusHandler_);
245253
this.adapter_.registerInteractionHandler('blur', this.blurHandler_);
246-
247-
if (this.adapter_.isUnbounded()) {
248-
this.adapter_.registerResizeHandler(this.resizeHandler_);
249-
}
250254
}
251255

252256
/**

test/unit/mdc-ripple/foundation.test.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,13 @@ testFoundation('#init does not register a resize handler for bounded ripple', ({
9898
td.verify(adapter.registerResizeHandler(td.matchers.isA(Function)), {times: 0});
9999
});
100100

101-
testFoundation('#init does not register events if CSS custom properties not supported', ({foundation, adapter}) => {
101+
testFoundation('#init only registers focus/blur if CSS custom properties not supported', ({foundation, adapter}) => {
102102
td.when(adapter.browserSupportsCssVars()).thenReturn(false);
103103
foundation.init();
104104

105-
td.verify(adapter.registerInteractionHandler(td.matchers.isA(String), td.matchers.isA(Function)), {times: 0});
105+
td.verify(adapter.registerInteractionHandler(td.matchers.isA(String), td.matchers.isA(Function)), {times: 2});
106+
td.verify(adapter.registerInteractionHandler('focus', td.matchers.isA(Function)));
107+
td.verify(adapter.registerInteractionHandler('blur', td.matchers.isA(Function)));
106108
});
107109

108110
testFoundation('#destroy unregisters all bound interaction handlers', ({foundation, adapter}) => {
@@ -185,14 +187,16 @@ testFoundation('#destroy clears the timer if activation is interrupted',
185187
assert.equal(foundation.activationTimer_, 0);
186188
});
187189

188-
testFoundation('#destroy does nothing if CSS custom properties are not supported', ({foundation, adapter, mockRaf}) => {
190+
testFoundation('#destroy when CSS custom properties are not supported', ({foundation, adapter, mockRaf}) => {
189191
const isA = td.matchers.isA;
190192
td.when(adapter.browserSupportsCssVars()).thenReturn(false);
191193
foundation.destroy();
192194
mockRaf.flush();
193195

194-
td.verify(adapter.deregisterInteractionHandler(isA(String), isA(Function)), {times: 0});
195-
td.verify(adapter.deregisterResizeHandler(isA(Function)), {times: 0});
196+
// #destroy w/o CSS vars still calls event deregistration functions (to deregister focus/blur; the rest are no-ops)
197+
td.verify(adapter.deregisterInteractionHandler('focus', isA(Function)));
198+
td.verify(adapter.deregisterInteractionHandler('blur', isA(Function)));
199+
// #destroy w/o CSS vars doesn't change any CSS classes or custom properties
196200
td.verify(adapter.removeClass(isA(String)), {times: 0});
197201
td.verify(adapter.updateCssVariable(isA(String), isA(String)), {times: 0});
198202
});

0 commit comments

Comments
 (0)