Skip to content

Commit

Permalink
fix(select): add adapter (#3233)
Browse files Browse the repository at this point in the history

(cherry picked from commit 43b3ac1)
  • Loading branch information
Matt Goo authored and Kenneth G. Franqueiro committed Aug 13, 2018
1 parent 5459dab commit 3b20de8
Show file tree
Hide file tree
Showing 6 changed files with 263 additions and 35 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@
"mdc-notched-outline",
"mdc-radio",
"mdc-ripple",
"mdc-select",
"mdc-selection-control",
"mdc-slider",
"mdc-switch",
Expand Down
9 changes: 8 additions & 1 deletion packages/mdc-select/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,17 @@ If you are using a JavaScript framework, such as React or Angular, you can creat
| --- | --- |
| `addClass(className: string) => void` | Adds a class to the root element. |
| `removeClass(className: string) => void` | Removes a class from the root element. |
| `floatLabel(value: boolean) => void` | Floats or defloats label. |
| `hasClass(className: string) => boolean` | Returns true if the root element has the className in its classList. |
| `activateBottomLine() => void` | Activates the bottom line component. |
| `deactivateBottomLine() => void` | Deactivates the bottom line component. |
| `getValue() => string` | Returns the value selected on the `select` element. |
| `isRtl() => boolean` | Returns true if a parent of the root element is in RTL. |
| `hasLabel() => boolean` | Returns true if the `select` has a label associated with it. |
| `floatLabel(value: boolean) => void` | Floats or defloats label. |
| `getLabelWidth() => number` | Returns the offsetWidth of the label element. |
| `hasOutline() => boolean` | Returns true if the `select` has the notched outline element. |
| `notchOutline(labelWidth: number, isRtl, boolean) => void` | Switches the notched outline element to its "notched state." |
| `closeOutline() => void` | Switches the notched outline element to its closed state. |

### `MDCSelectFoundation`

Expand Down
117 changes: 117 additions & 0 deletions packages/mdc-select/adapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* @license
* Copyright 2018 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* eslint no-unused-vars: [2, {"args": "none"}] */

/**
* Adapter for MDC Select. Provides an interface for managing
* - classes
* - dom
* - event handlers
*
* Additionally, provides type information for the adapter to the Closure
* compiler.
*
* Implement this adapter for your framework of choice to delegate updates to
* the component in your framework of choice. See architecture documentation
* for more details.
* https://github.com/material-components/material-components-web/blob/master/docs/code/architecture.md
*
* @record
*/

class MDCSelectAdapter {
/**
* Adds class to root element.
* @param {string} className
*/
addClass(className) {}

/**
* Removes a class from the root element.
* @param {string} className
*/
removeClass(className) {}

/**
* Returns true if the root element contains the given class name.
* @param {string} className
* @return {boolean}
*/
hasClass(className) {}

/**
* Activates the bottom line, showing a focused state.
*/
activateBottomLine() {}

/**
* Deactivates the bottom line.
*/
deactivateBottomLine() {}

/**
* Returns the selected value of the select element.
* @return {string}
*/
getValue() {}

/**
* Returns true if the direction of the root element is set to RTL.
* @return {boolean}
*/
isRtl() {}

/**
* Returns true if label element exists, false if it doesn't.
* @return {boolean}
*/
hasLabel() {}

/**
* Floats label determined based off of the shouldFloat argument.
* @param {boolean} shouldFloat
*/
floatLabel(shouldFloat) {}

/**
* Returns width of label in pixels, if the label exists.
* @return {number}
*/
getLabelWidth() {}

/**
* Returns true if outline element exists, false if it doesn't.
* @return {boolean}
*/
hasOutline() {}

/**
* Updates SVG Path and outline element based on the
* label element width and RTL context, if the outline exists.
* @param {number} labelWidth
* @param {boolean=} isRtl
*/
notchOutline(labelWidth, isRtl) {}

/**
* Closes notch in outline element, if the outline exists.
*/
closeOutline() {}
}

export default MDCSelectAdapter;
4 changes: 4 additions & 0 deletions packages/mdc-select/constants.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/**
* @license
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -13,13 +14,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/** @enum {string} */
const cssClasses = {
BOX: 'mdc-select--box',
DISABLED: 'mdc-select--disabled',
ROOT: 'mdc-select',
OUTLINED: 'mdc-select--outlined',
};

/** @enum {string} */
const strings = {
CHANGE_EVENT: 'MDCSelect:change',
LINE_RIPPLE_SELECTOR: '.mdc-line-ripple',
Expand Down
50 changes: 40 additions & 10 deletions packages/mdc-select/foundation.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,46 +15,65 @@
*/

import {MDCFoundation} from '@material/base/index';
/* eslint-disable no-unused-vars */
import MDCSelectAdapter from './adapter';
/* eslint-enable no-unused-vars */
import {cssClasses, strings, numbers} from './constants';

export default class MDCSelectFoundation extends MDCFoundation {
/**
* @extends {MDCFoundation<!MDCSelectAdapter>}
* @final
*/
class MDCSelectFoundation extends MDCFoundation {
/** @return enum {string} */
static get cssClasses() {
return cssClasses;
}

/** @return enum {number} */
static get numbers() {
return numbers;
}

/** @return enum {string} */
static get strings() {
return strings;
}

/**
* {@see MDCSelectAdapter} for typing information on parameters and return
* types.
* @return {!MDCSelectAdapter}
*/
static get defaultAdapter() {
return {
return /** @type {!MDCSelectAdapter} */ ({
addClass: (/* className: string */) => {},
removeClass: (/* className: string */) => {},
hasClass: (/* className: string */) => false,
floatLabel: (/* value: boolean */) => {},
activateBottomLine: () => {},
deactivateBottomLine: () => {},
getValue: () => {},
isRtl: () => false,
hasLabel: () => {},
hasLabel: () => false,
floatLabel: (/* value: boolean */) => {},
getLabelWidth: () => {},
hasOutline: () => {},
notchOutline: () => {},
hasOutline: () => false,
notchOutline: (/* labelWidth: number, isRtl: boolean */) => {},
closeOutline: () => {},
};
});
}

/**
* @param {!MDCSelectAdapter} adapter
*/
constructor(adapter) {
super(Object.assign(MDCSelectFoundation.defaultAdapter, adapter));

this.focusHandler_ = (evt) => this.handleFocus_(evt);
this.blurHandler_ = (evt) => this.handleBlur_(evt);
}

/**
* Updates the styles of the select to show the disasbled state.
* @param {boolean} disabled
*/
updateDisabledStyle(disabled) {
const {DISABLED} = MDCSelectFoundation.cssClasses;
if (disabled) {
Expand All @@ -64,18 +83,27 @@ export default class MDCSelectFoundation extends MDCFoundation {
}
}

/**
* Handles value changes, via change event or programmatic updates.
*/
handleChange() {
const optionHasValue = this.adapter_.getValue().length > 0;
this.adapter_.floatLabel(optionHasValue);
this.notchOutline(optionHasValue);
}

/**
* Handles focus events from root element.
*/
handleFocus() {
this.adapter_.floatLabel(true);
this.notchOutline(true);
this.adapter_.activateBottomLine();
}

/**
* Handles blur events from root element.
*/
handleBlur() {
this.handleChange();
this.adapter_.deactivateBottomLine();
Expand All @@ -100,3 +128,5 @@ export default class MDCSelectFoundation extends MDCFoundation {
}
}
}

export default MDCSelectFoundation;
Loading

0 comments on commit 3b20de8

Please sign in to comment.