From e29742abe2556b6b9a9b57a145d57c0d8ffd666d Mon Sep 17 00:00:00 2001 From: Matt Goo Date: Wed, 25 Jul 2018 14:05:59 -0700 Subject: [PATCH] fix(select): reduce adapter apis not used in MDCReact and update events to new pattern (#3204) BREAKING CHANGE: Removed some adapter APIs (setDisabled, setSelectedIndex, getSelectedIndex, setValue, registerInteractionHandler, deregisterInteractionHandler) and shifted responsibility of event handling and programmatic select element updates out of the foundation and into the component. --- packages/mdc-select/README.md | 21 ++- packages/mdc-select/foundation.js | 46 +----- packages/mdc-select/index.js | 68 +++++---- .../unit/mdc-select/foundation-events.test.js | 71 ---------- test/unit/mdc-select/foundation.test.js | 134 ++++++++++-------- test/unit/mdc-select/mdc-select.test.js | 79 +++++++---- 6 files changed, 181 insertions(+), 238 deletions(-) delete mode 100644 test/unit/mdc-select/foundation-events.test.js diff --git a/packages/mdc-select/README.md b/packages/mdc-select/README.md index b1499fa6213..bed761707dc 100644 --- a/packages/mdc-select/README.md +++ b/packages/mdc-select/README.md @@ -9,8 +9,8 @@ path: /catalog/input-controls/select-menus/ ## Important - Default Style Deprecation Notice The existing default select style will be changed in an upcoming release. The Material spec indicates that -the default style will be the filled variant (currently referred to as the box variant). This will become the -default style. Continuing to add the `mdc-select--box` class to the select will result in no change. +the default style will be the filled variant (currently referred to as the box variant). This will become the +default style. Continuing to add the `mdc-select--box` class to the select will result in no change. # Select Menus @@ -100,7 +100,7 @@ modifier class on the root element. ### Outlined Select -The Select Outlined variant uses the `mdc-notched-outline` in place of the `mdc-line-ripple` element and adds the +The Select Outlined variant uses the `mdc-notched-outline` in place of the `mdc-line-ripple` element and adds the `mdc-select--outlined` modifier class on the root element. ```html @@ -247,19 +247,14 @@ If you are using a JavaScript framework, such as React or Angular, you can creat | `floatLabel(value: boolean) => void` | Floats or defloats label. | | `activateBottomLine() => void` | Activates the bottom line component. | | `deactivateBottomLine() => void` | Deactivates the bottom line component. | -| `setDisabled(disabled: boolean) => void` | Sets the `disabled` property of the `` element. | -| `deregisterInteractionHandler(type: string, handler: EventListener) => void` | Removes an event listener `handler` for event type `type` on the `` element. | -| `setSelectedIndex(index: number) => void` | Sets the selected index of the `` element. | -| `setValue(value: string) => void` | Sets the value of the `', () => { assert.equal(nativeControl.value, 'orange'); }); +test('#set value calls foundation.handleChange', () => { + const {component} = setupTest(); + component.foundation_.handleChange = td.func(); + component.value = 'orange'; + td.verify(component.foundation_.handleChange(), {times: 1}); +}); + +test('#set selectedIndex calls foundation.handleChange', () => { + const {component} = setupTest(); + component.foundation_.handleChange = td.func(); + component.selectedIndex = 1; + td.verify(component.foundation_.handleChange(), {times: 1}); +}); + +test('#set disabled calls foundation.updateDisabledStyle', () => { + const {component} = setupTest(); + component.foundation_.updateDisabledStyle = td.func(); + component.disabled = true; + td.verify(component.foundation_.updateDisabledStyle(true), {times: 1}); +}); + test('#initialSyncWithDOM sets the selected index if an option has the selected attr', () => { const fixture = bel`
@@ -338,37 +359,47 @@ test('adapter#deactivateBottomLine removes active class from the bottom line', ( td.verify(bottomLine.deactivate()); }); -test('adapter#registerInteractionHandler adds an event listener to the nativeControl element', () => { +test('change event triggers foundation.handleChange()', () => { + const {component, nativeControl} = setupTest(); + component.foundation_.handleChange = td.func(); + domEvents.emit(nativeControl, 'change'); + td.verify(component.foundation_.handleChange(), {times: 1}); +}); + +test('focus event triggers foundation.handleFocus()', () => { const {component, nativeControl} = setupTest(); - const listener = td.func('eventlistener'); - component.getDefaultFoundation().adapter_.registerInteractionHandler('click', listener); - domEvents.emit(nativeControl, 'click'); - td.verify(listener(td.matchers.anything())); + component.foundation_.handleFocus = td.func(); + domEvents.emit(nativeControl, 'focus'); + td.verify(component.foundation_.handleFocus(), {times: 1}); }); -test('adapter#deregisterInteractionHandler removes an event listener from the nativeControl element', () => { +test('blur event triggers foundation.handleBlur()', () => { const {component, nativeControl} = setupTest(); - const listener = td.func('eventlistener'); - nativeControl.addEventListener('click', listener); - component.getDefaultFoundation().adapter_.deregisterInteractionHandler('click', listener); - domEvents.emit(nativeControl, 'click'); - td.verify(listener(td.matchers.anything()), {times: 0}); + component.foundation_.handleBlur = td.func(); + domEvents.emit(nativeControl, 'blur'); + td.verify(component.foundation_.handleBlur(), {times: 1}); }); -test('adapter#setValue sets the value of the select to the correct option', () => { - const {nativeControl, component} = setupTest(); - component.getDefaultFoundation().adapter_.setValue('orange'); - assert.equal(nativeControl.value, 'orange'); +test('#destroy removes the change handler', () => { + const {component, nativeControl} = setupTest(); + component.foundation_.handleChange = td.func(); + component.destroy(); + domEvents.emit(nativeControl, 'change'); + td.verify(component.foundation_.handleChange(), {times: 0}); }); -test('adapter#getValue returns the nativeControl value', () => { - const {nativeControl, component} = setupTest(); - nativeControl.value = 'orange'; - assert.equal(component.getDefaultFoundation().adapter_.getValue(), 'orange'); +test('#destroy removes the focus handler', () => { + const {component, nativeControl} = setupTest(); + component.foundation_.handleFocus = td.func(); + component.destroy(); + domEvents.emit(nativeControl, 'focus'); + td.verify(component.foundation_.handleFocus(), {times: 0}); }); -test('adapter#getSelectedIndex returns selected index', () => { - const {component} = setupTest(); - component.selectedIndex = 1; - assert.equal(component.getDefaultFoundation().adapter_.getSelectedIndex(), 1); +test('#destroy removes the blur handler', () => { + const {component, nativeControl} = setupTest(); + component.foundation_.handleBlur = td.func(); + component.destroy(); + domEvents.emit(nativeControl, 'blur'); + td.verify(component.foundation_.handleBlur(), {times: 0}); });