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

Commit 3effc35

Browse files
fix(checkbox): Disable transitions when using mdc-checkbox-anim* classes (#285)
- Adds a mdc-checkbox--upgraded mod class which is attached by the foundation when a JS checkbox is used. - Disables all transitions when the animation classes are used. Fixes an issue in Safari where the the paint/compositing looked janky/broken due to animations and transitions conflicting with one another. - (tech debt) Removed template strings from cssClasses object. This will be required in order for our internal infra to work correctly. Fixes #205
1 parent fd0ac4e commit 3effc35

File tree

4 files changed

+40
-16
lines changed

4 files changed

+40
-16
lines changed

packages/mdc-checkbox/constants.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@
1515
*/
1616

1717
const ROOT = 'mdc-checkbox';
18-
const ANIM = `${ROOT}--anim`;
1918

2019
export const cssClasses = {
21-
ROOT,
22-
CHECKED: `${ROOT}--checked`,
23-
INDETERMINATE: `${ROOT}--indeterminate`,
24-
ANIM_UNCHECKED_CHECKED: `${ANIM}-unchecked-checked`,
25-
ANIM_UNCHECKED_INDETERMINATE: `${ANIM}-unchecked-indeterminate`,
26-
ANIM_CHECKED_UNCHECKED: `${ANIM}-checked-unchecked`,
27-
ANIM_CHECKED_INDETERMINATE: `${ANIM}-checked-indeterminate`,
28-
ANIM_INDETERMINATE_CHECKED: `${ANIM}-indeterminate-checked`,
29-
ANIM_INDETERMINATE_UNCHECKED: `${ANIM}-indeterminate-unchecked`,
20+
ROOT: 'mdc-checkbox',
21+
UPGRADED: 'mdc-checkbox--upgraded',
22+
CHECKED: 'mdc-checkbox--checked',
23+
INDETERMINATE: 'mdc-checkbox--indeterminate',
24+
ANIM_UNCHECKED_CHECKED: 'mdc-checkbox--anim-unchecked-checked',
25+
ANIM_UNCHECKED_INDETERMINATE: 'mdc-checkbox--anim-unchecked-indeterminate',
26+
ANIM_CHECKED_UNCHECKED: 'mdc-checkbox--anim-checked-unchecked',
27+
ANIM_CHECKED_INDETERMINATE: 'mdc-checkbox--anim-checked-indeterminate',
28+
ANIM_INDETERMINATE_CHECKED: 'mdc-checkbox--anim-indeterminate-checked',
29+
ANIM_INDETERMINATE_UNCHECKED: 'mdc-checkbox--anim-indeterminate-unchecked',
3030
};
3131

3232
export const strings = {

packages/mdc-checkbox/foundation.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export default class MDCCheckboxFoundation extends MDCFoundation {
6363
}
6464

6565
init() {
66+
this.adapter_.addClass(cssClasses.UPGRADED);
6667
this.adapter_.registerChangeHandler(this.changeHandler_);
6768
this.installPropertyChangeHooks_();
6869
}

packages/mdc-checkbox/mdc-checkbox.scss

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
//
1+
//
22
// Copyright 2016 Google Inc. All Rights Reserved.
3-
//
3+
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
66
// You may obtain a copy of the License at
7-
//
7+
//
88
// http://www.apache.org/licenses/LICENSE-2.0
9-
//
9+
//
1010
// Unless required by applicable law or agreed to in writing, software
1111
// distributed under the License is distributed on an "AS IS" BASIS,
1212
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -235,6 +235,19 @@ fieldset:disabled .mdc-checkbox__native-control,
235235
}
236236
}
237237

238+
.mdc-checkbox--upgraded {
239+
.mdc-checkbox__background,
240+
.mdc-checkbox__checkmark,
241+
.mdc-checkbox__checkmark__path,
242+
.mdc-checkbox__mixedmark {
243+
// Due to the myriad of selector combos used to properly style a CSS-only checkbox, all of
244+
// which have varying selector precedence and make use of transitions, it is cleaner and more
245+
// efficient here to simply use !important, since the mdc-checkbox--anim-* classes will take
246+
// over from here.
247+
transition: none !important;
248+
}
249+
}
250+
238251
.mdc-checkbox--anim {
239252
$_mdc-checkbox-indeterminate-change-duration: 500ms;
240253

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ test('defaultAdapter returns a complete adapter implementation', (t) => {
123123
t.end();
124124
});
125125

126+
test('#init adds the upgraded class to the root element', (t) => {
127+
const {foundation, mockAdapter} = setupTest();
128+
129+
foundation.init();
130+
t.doesNotThrow(() => td.verify(mockAdapter.addClass(cssClasses.UPGRADED)));
131+
t.end();
132+
});
133+
126134
test('#init calls adapter.registerChangeHandler() with a change handler function', (t) => {
127135
const {foundation, mockAdapter} = setupTest();
128136
const {isA} = td.matchers;
@@ -406,19 +414,21 @@ test('change handler triggers layout for changes within the same frame to correc
406414

407415
test('change handler does not add animation classes when isAttachedToDOM() is falsy', (t) => {
408416
const {mockAdapter, change} = setupChangeHandlerTest();
417+
const animClassArg = td.matchers.argThat((cls) => cls.indexOf('mdc-checkbox--anim') >= 0);
409418
td.when(mockAdapter.isAttachedToDOM()).thenReturn(false);
410419

411420
change({checked: true, indeterminate: false});
412-
t.doesNotThrow(() => td.verify(mockAdapter.addClass(td.matchers.anything()), {times: 0}));
421+
t.doesNotThrow(() => td.verify(mockAdapter.addClass(animClassArg), {times: 0}));
413422

414423
t.end();
415424
});
416425

417426
test('change handler does not add animation classes for bogus changes (init -> unchecked)', (t) => {
418427
const {mockAdapter, change} = setupChangeHandlerTest();
428+
const animClassArg = td.matchers.argThat((cls) => cls.indexOf('mdc-checkbox--anim') >= 0);
419429

420430
change({checked: false, indeterminate: false});
421-
t.doesNotThrow(() => td.verify(mockAdapter.addClass(td.matchers.anything()), {times: 0}));
431+
t.doesNotThrow(() => td.verify(mockAdapter.addClass(animClassArg), {times: 0}));
422432
t.end();
423433
});
424434

0 commit comments

Comments
 (0)