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

Commit e29742a

Browse files
author
Matt Goo
authored
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.
1 parent 8286045 commit e29742a

File tree

6 files changed

+181
-238
lines changed

6 files changed

+181
-238
lines changed

packages/mdc-select/README.md

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ path: /catalog/input-controls/select-menus/
99
## Important - Default Style Deprecation Notice
1010

1111
The existing default select style will be changed in an upcoming release. The Material spec indicates that
12-
the default style will be the filled variant (currently referred to as the box variant). This will become the
13-
default style. Continuing to add the `mdc-select--box` class to the select will result in no change.
12+
the default style will be the filled variant (currently referred to as the box variant). This will become the
13+
default style. Continuing to add the `mdc-select--box` class to the select will result in no change.
1414

1515
# Select Menus
1616

@@ -100,7 +100,7 @@ modifier class on the root element.
100100

101101
### Outlined Select
102102

103-
The Select Outlined variant uses the `mdc-notched-outline` in place of the `mdc-line-ripple` element and adds the
103+
The Select Outlined variant uses the `mdc-notched-outline` in place of the `mdc-line-ripple` element and adds the
104104
`mdc-select--outlined` modifier class on the root element.
105105

106106
```html
@@ -247,19 +247,14 @@ If you are using a JavaScript framework, such as React or Angular, you can creat
247247
| `floatLabel(value: boolean) => void` | Floats or defloats label. |
248248
| `activateBottomLine() => void` | Activates the bottom line component. |
249249
| `deactivateBottomLine() => void` | Deactivates the bottom line component. |
250-
| `setDisabled(disabled: boolean) => void` | Sets the `disabled` property of the `<select>` element. |
251-
| `registerInteractionHandler(type: string, handler: EventListener) => void` | Adds an event listener `handler` for event type `type` on the `<select>` element. |
252-
| `deregisterInteractionHandler(type: string, handler: EventListener) => void` | Removes an event listener `handler` for event type `type` on the `<select>` element. |
253-
| `getSelectedIndex() => number` | Returns the selected index of the `<select>` element. |
254-
| `setSelectedIndex(index: number) => void` | Sets the selected index of the `<select>` element. |
255-
| `getValue() => string` | Returns the value selected on the `<select>` element. |
256-
| `setValue(value: string) => void` | Sets the value of the `<select>` element. |
250+
| `getValue() => string` | Returns the value selected on the `select` element. |
257251

258252
### `MDCSelectFoundation`
259253

260254
| Method Signature | Description |
261255
| --- | --- |
262256
| `notchOutline(openNotch: boolean) => void` | Opens/closes the notched outline. |
263-
| `setValue(value: string) => void` | Sets the value of the component. |
264-
| `setDisabled(disabled: boolean) => void` | Adds/removes disabled class, and sets disabled attribute on the component. |
265-
| `setSelectedIndex(selectedIndex: number) => void` | Sets the selected index of the component. |
257+
| `updateDisabledStyle(disabled: boolean) => void` | Updates appearance based on disabled state. This must be called whenever the `disabled` state changes. |
258+
| `handleFocus() => void` | Handles a focus event on the `select` element. |
259+
| `handleBlur() => void` | Handles a blur event on the `select` element. |
260+
| `handleChange() => void` | Handles a change to the `select` element's value. This must be called both for `change` events and programmatic changes requested via the component API. |

packages/mdc-select/foundation.js

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,7 @@ export default class MDCSelectFoundation extends MDCFoundation {
3838
floatLabel: (/* value: boolean */) => {},
3939
activateBottomLine: () => {},
4040
deactivateBottomLine: () => {},
41-
registerInteractionHandler: (/* type: string, handler: EventListener */) => {},
42-
deregisterInteractionHandler: (/* type: string, handler: EventListener */) => {},
43-
getSelectedIndex: () => /* number */ -1,
44-
setSelectedIndex: (/* index: number */) => {},
45-
setDisabled: (/* disabled: boolean */) => {},
46-
getValue: () => /* string */ '',
47-
setValue: (/* value: string */) => {},
41+
getValue: () => {},
4842
isRtl: () => false,
4943
hasLabel: () => {},
5044
getLabelWidth: () => {},
@@ -59,62 +53,34 @@ export default class MDCSelectFoundation extends MDCFoundation {
5953

6054
this.focusHandler_ = (evt) => this.handleFocus_(evt);
6155
this.blurHandler_ = (evt) => this.handleBlur_(evt);
62-
this.selectionHandler_ = (evt) => this.handleSelect_(evt);
6356
}
6457

65-
init() {
66-
this.adapter_.registerInteractionHandler('focus', this.focusHandler_);
67-
this.adapter_.registerInteractionHandler('blur', this.blurHandler_);
68-
this.adapter_.registerInteractionHandler('change', this.selectionHandler_);
69-
}
70-
71-
destroy() {
72-
this.adapter_.deregisterInteractionHandler('focus', this.focusHandler_);
73-
this.adapter_.deregisterInteractionHandler('blur', this.blurHandler_);
74-
this.adapter_.deregisterInteractionHandler('change', this.selectionHandler_);
75-
}
76-
77-
setSelectedIndex(index) {
78-
this.adapter_.setSelectedIndex(index);
79-
this.floatLabelWithValue_();
80-
}
81-
82-
setValue(value) {
83-
this.adapter_.setValue(value);
84-
this.setSelectedIndex(this.adapter_.getSelectedIndex());
85-
}
86-
87-
setDisabled(disabled) {
58+
updateDisabledStyle(disabled) {
8859
const {DISABLED} = MDCSelectFoundation.cssClasses;
89-
this.adapter_.setDisabled(disabled);
9060
if (disabled) {
9161
this.adapter_.addClass(DISABLED);
9262
} else {
9363
this.adapter_.removeClass(DISABLED);
9464
}
9565
}
9666

97-
floatLabelWithValue_() {
67+
handleChange() {
9868
const optionHasValue = this.adapter_.getValue().length > 0;
9969
this.adapter_.floatLabel(optionHasValue);
10070
this.notchOutline(optionHasValue);
10171
}
10272

103-
handleFocus_() {
73+
handleFocus() {
10474
this.adapter_.floatLabel(true);
10575
this.notchOutline(true);
10676
this.adapter_.activateBottomLine();
10777
}
10878

109-
handleBlur_() {
110-
this.floatLabelWithValue_();
79+
handleBlur() {
80+
this.handleChange();
11181
this.adapter_.deactivateBottomLine();
11282
}
11383

114-
handleSelect_() {
115-
this.setSelectedIndex(this.adapter_.getSelectedIndex());
116-
}
117-
11884
/**
11985
* Opens/closes the notched outline.
12086
* @param {boolean} openNotch

packages/mdc-select/index.js

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,26 @@ export class MDCSelect extends MDCComponent {
3535
}
3636

3737
set value(value) {
38-
this.foundation_.setValue(value);
38+
this.nativeControl_.value = value;
39+
this.foundation_.handleChange();
3940
}
4041

4142
get selectedIndex() {
4243
return this.nativeControl_.selectedIndex;
4344
}
4445

4546
set selectedIndex(selectedIndex) {
46-
this.foundation_.setSelectedIndex(selectedIndex);
47+
this.nativeControl_.selectedIndex = selectedIndex;
48+
this.foundation_.handleChange();
4749
}
4850

4951
get disabled() {
5052
return this.nativeControl_.disabled;
5153
}
5254

5355
set disabled(disabled) {
54-
this.foundation_.setDisabled(disabled);
56+
this.nativeControl_.disabled = disabled;
57+
this.foundation_.updateDisabledStyle(disabled);
5558
}
5659

5760
/**
@@ -94,6 +97,38 @@ export class MDCSelect extends MDCComponent {
9497
return new MDCRipple(this.root_, foundation);
9598
}
9699

100+
initialSyncWithDOM() {
101+
this.handleChange_ = () => this.foundation_.handleChange();
102+
this.handleFocus_ = () => this.foundation_.handleFocus();
103+
this.handleBlur_ = () => this.foundation_.handleBlur();
104+
105+
this.nativeControl_.addEventListener('change', this.handleChange_);
106+
this.nativeControl_.addEventListener('focus', this.handleFocus_);
107+
this.nativeControl_.addEventListener('blur', this.handleBlur_);
108+
109+
// Initially sync floating label
110+
this.foundation_.handleChange();
111+
112+
if (this.nativeControl_.disabled) {
113+
this.disabled = true;
114+
}
115+
}
116+
117+
destroy() {
118+
this.nativeControl_.removeEventListener('change', this.handleChange_);
119+
this.nativeControl_.removeEventListener('focus', this.handleFocus_);
120+
this.nativeControl_.removeEventListener('blur', this.handleBlur_);
121+
122+
if (this.ripple) {
123+
this.ripple.destroy();
124+
}
125+
if (this.outline_) {
126+
this.outline_.destroy();
127+
}
128+
129+
super.destroy();
130+
}
131+
97132
getDefaultFoundation() {
98133
return new MDCSelectFoundation((Object.assign({
99134
addClass: (className) => this.root_.classList.add(className),
@@ -109,39 +144,14 @@ export class MDCSelect extends MDCComponent {
109144
this.lineRipple_.deactivate();
110145
}
111146
},
112-
setDisabled: (disabled) => this.nativeControl_.disabled = disabled,
113-
registerInteractionHandler: (type, handler) => this.nativeControl_.addEventListener(type, handler),
114-
deregisterInteractionHandler: (type, handler) => this.nativeControl_.removeEventListener(type, handler),
115-
getSelectedIndex: () => this.nativeControl_.selectedIndex,
116-
setSelectedIndex: (index) => this.nativeControl_.selectedIndex = index,
117-
getValue: () => this.nativeControl_.value,
118-
setValue: (value) => this.nativeControl_.value = value,
119147
isRtl: () => window.getComputedStyle(this.root_).getPropertyValue('direction') === 'rtl',
148+
getValue: () => this.nativeControl_.value,
120149
},
121150
this.getOutlineAdapterMethods_(),
122151
this.getLabelAdapterMethods_()))
123152
);
124153
}
125154

126-
initialSyncWithDOM() {
127-
// needed to sync floating label
128-
this.selectedIndex = this.nativeControl_.selectedIndex;
129-
130-
if (this.nativeControl_.disabled) {
131-
this.disabled = true;
132-
}
133-
}
134-
135-
destroy() {
136-
if (this.ripple) {
137-
this.ripple.destroy();
138-
}
139-
if (this.outline_) {
140-
this.outline_.destroy();
141-
}
142-
super.destroy();
143-
}
144-
145155
/**
146156
* @return {!{
147157
* notchOutline: function(number, boolean): undefined,

test/unit/mdc-select/foundation-events.test.js

Lines changed: 0 additions & 71 deletions
This file was deleted.

0 commit comments

Comments
 (0)