1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | import { __assign, __extends } from "tslib";
|
24 | import { MDCFoundation } from '@material/base/foundation';
|
25 | import { KEY, normalizeKey } from '@material/dom/keyboard';
|
26 | import { Corner } from '@material/menu-surface/constants';
|
27 | import { cssClasses, numbers, strings } from './constants';
|
28 | var MDCSelectFoundation = (function (_super) {
|
29 | __extends(MDCSelectFoundation, _super);
|
30 |
|
31 | |
32 |
|
33 |
|
34 |
|
35 | function MDCSelectFoundation(adapter, foundationMap) {
|
36 | if (foundationMap === void 0) { foundationMap = {}; }
|
37 | var _this = _super.call(this, __assign(__assign({}, MDCSelectFoundation.defaultAdapter), adapter)) || this;
|
38 |
|
39 | _this.disabled = false;
|
40 |
|
41 |
|
42 |
|
43 |
|
44 | _this.isMenuOpen = false;
|
45 |
|
46 | _this.useDefaultValidation = true;
|
47 | _this.customValidity = true;
|
48 | _this.lastSelectedIndex = numbers.UNSET_INDEX;
|
49 | _this.clickDebounceTimeout = 0;
|
50 | _this.recentlyClicked = false;
|
51 | _this.leadingIcon = foundationMap.leadingIcon;
|
52 | _this.helperText = foundationMap.helperText;
|
53 | return _this;
|
54 | }
|
55 | Object.defineProperty(MDCSelectFoundation, "cssClasses", {
|
56 | get: function () {
|
57 | return cssClasses;
|
58 | },
|
59 | enumerable: false,
|
60 | configurable: true
|
61 | });
|
62 | Object.defineProperty(MDCSelectFoundation, "numbers", {
|
63 | get: function () {
|
64 | return numbers;
|
65 | },
|
66 | enumerable: false,
|
67 | configurable: true
|
68 | });
|
69 | Object.defineProperty(MDCSelectFoundation, "strings", {
|
70 | get: function () {
|
71 | return strings;
|
72 | },
|
73 | enumerable: false,
|
74 | configurable: true
|
75 | });
|
76 | Object.defineProperty(MDCSelectFoundation, "defaultAdapter", {
|
77 | |
78 |
|
79 |
|
80 | get: function () {
|
81 |
|
82 | return {
|
83 | addClass: function () { return undefined; },
|
84 | removeClass: function () { return undefined; },
|
85 | hasClass: function () { return false; },
|
86 | activateBottomLine: function () { return undefined; },
|
87 | deactivateBottomLine: function () { return undefined; },
|
88 | getSelectedIndex: function () { return -1; },
|
89 | setSelectedIndex: function () { return undefined; },
|
90 | hasLabel: function () { return false; },
|
91 | floatLabel: function () { return undefined; },
|
92 | getLabelWidth: function () { return 0; },
|
93 | setLabelRequired: function () { return undefined; },
|
94 | hasOutline: function () { return false; },
|
95 | notchOutline: function () { return undefined; },
|
96 | closeOutline: function () { return undefined; },
|
97 | setRippleCenter: function () { return undefined; },
|
98 | notifyChange: function () { return undefined; },
|
99 | setSelectedText: function () { return undefined; },
|
100 | isSelectAnchorFocused: function () { return false; },
|
101 | getSelectAnchorAttr: function () { return ''; },
|
102 | setSelectAnchorAttr: function () { return undefined; },
|
103 | removeSelectAnchorAttr: function () { return undefined; },
|
104 | addMenuClass: function () { return undefined; },
|
105 | removeMenuClass: function () { return undefined; },
|
106 | openMenu: function () { return undefined; },
|
107 | closeMenu: function () { return undefined; },
|
108 | getAnchorElement: function () { return null; },
|
109 | setMenuAnchorElement: function () { return undefined; },
|
110 | setMenuAnchorCorner: function () { return undefined; },
|
111 | setMenuWrapFocus: function () { return undefined; },
|
112 | focusMenuItemAtIndex: function () { return undefined; },
|
113 | getMenuItemCount: function () { return 0; },
|
114 | getMenuItemValues: function () { return []; },
|
115 | getMenuItemTextAtIndex: function () { return ''; },
|
116 | isTypeaheadInProgress: function () { return false; },
|
117 | typeaheadMatchItem: function () { return -1; },
|
118 | };
|
119 |
|
120 | },
|
121 | enumerable: false,
|
122 | configurable: true
|
123 | });
|
124 |
|
125 | MDCSelectFoundation.prototype.getSelectedIndex = function () {
|
126 | return this.adapter.getSelectedIndex();
|
127 | };
|
128 | MDCSelectFoundation.prototype.setSelectedIndex = function (index, closeMenu, skipNotify) {
|
129 | if (closeMenu === void 0) { closeMenu = false; }
|
130 | if (skipNotify === void 0) { skipNotify = false; }
|
131 | if (index >= this.adapter.getMenuItemCount()) {
|
132 | return;
|
133 | }
|
134 | if (index === numbers.UNSET_INDEX) {
|
135 | this.adapter.setSelectedText('');
|
136 | }
|
137 | else {
|
138 | this.adapter.setSelectedText(this.adapter.getMenuItemTextAtIndex(index).trim());
|
139 | }
|
140 | this.adapter.setSelectedIndex(index);
|
141 | if (closeMenu) {
|
142 | this.adapter.closeMenu();
|
143 | }
|
144 | if (!skipNotify && this.lastSelectedIndex !== index) {
|
145 | this.handleChange();
|
146 | }
|
147 | this.lastSelectedIndex = index;
|
148 | };
|
149 | MDCSelectFoundation.prototype.setValue = function (value, skipNotify) {
|
150 | if (skipNotify === void 0) { skipNotify = false; }
|
151 | var index = this.adapter.getMenuItemValues().indexOf(value);
|
152 | this.setSelectedIndex(index, false, skipNotify);
|
153 | };
|
154 | MDCSelectFoundation.prototype.getValue = function () {
|
155 | var index = this.adapter.getSelectedIndex();
|
156 | var menuItemValues = this.adapter.getMenuItemValues();
|
157 | return index !== numbers.UNSET_INDEX ? menuItemValues[index] : '';
|
158 | };
|
159 | MDCSelectFoundation.prototype.getDisabled = function () {
|
160 | return this.disabled;
|
161 | };
|
162 | MDCSelectFoundation.prototype.setDisabled = function (isDisabled) {
|
163 | this.disabled = isDisabled;
|
164 | if (this.disabled) {
|
165 | this.adapter.addClass(cssClasses.DISABLED);
|
166 | this.adapter.closeMenu();
|
167 | }
|
168 | else {
|
169 | this.adapter.removeClass(cssClasses.DISABLED);
|
170 | }
|
171 | if (this.leadingIcon) {
|
172 | this.leadingIcon.setDisabled(this.disabled);
|
173 | }
|
174 | if (this.disabled) {
|
175 |
|
176 |
|
177 | this.adapter.removeSelectAnchorAttr('tabindex');
|
178 | }
|
179 | else {
|
180 | this.adapter.setSelectAnchorAttr('tabindex', '0');
|
181 | }
|
182 | this.adapter.setSelectAnchorAttr('aria-disabled', this.disabled.toString());
|
183 | };
|
184 |
|
185 | MDCSelectFoundation.prototype.openMenu = function () {
|
186 | this.adapter.addClass(cssClasses.ACTIVATED);
|
187 | this.adapter.openMenu();
|
188 | this.isMenuOpen = true;
|
189 | this.adapter.setSelectAnchorAttr('aria-expanded', 'true');
|
190 | };
|
191 | |
192 |
|
193 |
|
194 | MDCSelectFoundation.prototype.setHelperTextContent = function (content) {
|
195 | if (this.helperText) {
|
196 | this.helperText.setContent(content);
|
197 | }
|
198 | };
|
199 | |
200 |
|
201 |
|
202 |
|
203 | MDCSelectFoundation.prototype.layout = function () {
|
204 | if (this.adapter.hasLabel()) {
|
205 | var optionHasValue = this.getValue().length > 0;
|
206 | var isFocused = this.adapter.hasClass(cssClasses.FOCUSED);
|
207 | var shouldFloatAndNotch = optionHasValue || isFocused;
|
208 | var isRequired = this.adapter.hasClass(cssClasses.REQUIRED);
|
209 | this.notchOutline(shouldFloatAndNotch);
|
210 | this.adapter.floatLabel(shouldFloatAndNotch);
|
211 | this.adapter.setLabelRequired(isRequired);
|
212 | }
|
213 | };
|
214 | |
215 |
|
216 |
|
217 |
|
218 | MDCSelectFoundation.prototype.layoutOptions = function () {
|
219 | var menuItemValues = this.adapter.getMenuItemValues();
|
220 | var selectedIndex = menuItemValues.indexOf(this.getValue());
|
221 | this.setSelectedIndex(selectedIndex, false, true);
|
222 | };
|
223 | MDCSelectFoundation.prototype.handleMenuOpened = function () {
|
224 | if (this.adapter.getMenuItemValues().length === 0) {
|
225 | return;
|
226 | }
|
227 |
|
228 | var selectedIndex = this.getSelectedIndex();
|
229 | var focusItemIndex = selectedIndex >= 0 ? selectedIndex : 0;
|
230 | this.adapter.focusMenuItemAtIndex(focusItemIndex);
|
231 | };
|
232 | MDCSelectFoundation.prototype.handleMenuClosing = function () {
|
233 | this.adapter.setSelectAnchorAttr('aria-expanded', 'false');
|
234 | };
|
235 | MDCSelectFoundation.prototype.handleMenuClosed = function () {
|
236 | this.adapter.removeClass(cssClasses.ACTIVATED);
|
237 | this.isMenuOpen = false;
|
238 |
|
239 | if (!this.adapter.isSelectAnchorFocused()) {
|
240 | this.blur();
|
241 | }
|
242 | };
|
243 | |
244 |
|
245 |
|
246 | MDCSelectFoundation.prototype.handleChange = function () {
|
247 | this.layout();
|
248 | this.adapter.notifyChange(this.getValue());
|
249 | var isRequired = this.adapter.hasClass(cssClasses.REQUIRED);
|
250 | if (isRequired && this.useDefaultValidation) {
|
251 | this.setValid(this.isValid());
|
252 | }
|
253 | };
|
254 | MDCSelectFoundation.prototype.handleMenuItemAction = function (index) {
|
255 | this.setSelectedIndex(index, true);
|
256 | };
|
257 | |
258 |
|
259 |
|
260 | MDCSelectFoundation.prototype.handleFocus = function () {
|
261 | this.adapter.addClass(cssClasses.FOCUSED);
|
262 | this.layout();
|
263 | this.adapter.activateBottomLine();
|
264 | };
|
265 | |
266 |
|
267 |
|
268 | MDCSelectFoundation.prototype.handleBlur = function () {
|
269 | if (this.isMenuOpen) {
|
270 | return;
|
271 | }
|
272 | this.blur();
|
273 | };
|
274 | MDCSelectFoundation.prototype.handleClick = function (normalizedX) {
|
275 | if (this.disabled || this.recentlyClicked) {
|
276 | return;
|
277 | }
|
278 | this.setClickDebounceTimeout();
|
279 | if (this.isMenuOpen) {
|
280 | this.adapter.closeMenu();
|
281 | return;
|
282 | }
|
283 | this.adapter.setRippleCenter(normalizedX);
|
284 | this.openMenu();
|
285 | };
|
286 | |
287 |
|
288 |
|
289 |
|
290 | MDCSelectFoundation.prototype.handleKeydown = function (event) {
|
291 | if (this.isMenuOpen || !this.adapter.hasClass(cssClasses.FOCUSED)) {
|
292 | return;
|
293 | }
|
294 | var isEnter = normalizeKey(event) === KEY.ENTER;
|
295 | var isSpace = normalizeKey(event) === KEY.SPACEBAR;
|
296 | var arrowUp = normalizeKey(event) === KEY.ARROW_UP;
|
297 | var arrowDown = normalizeKey(event) === KEY.ARROW_DOWN;
|
298 | var isModifier = event.ctrlKey || event.metaKey;
|
299 |
|
300 | if (!isModifier &&
|
301 | (!isSpace && event.key && event.key.length === 1 ||
|
302 | isSpace && this.adapter.isTypeaheadInProgress())) {
|
303 | var key = isSpace ? ' ' : event.key;
|
304 | var typeaheadNextIndex = this.adapter.typeaheadMatchItem(key, this.getSelectedIndex());
|
305 | if (typeaheadNextIndex >= 0) {
|
306 | this.setSelectedIndex(typeaheadNextIndex);
|
307 | }
|
308 | event.preventDefault();
|
309 | return;
|
310 | }
|
311 | if (!isEnter && !isSpace && !arrowUp && !arrowDown) {
|
312 | return;
|
313 | }
|
314 | this.openMenu();
|
315 | event.preventDefault();
|
316 | };
|
317 | |
318 |
|
319 |
|
320 | MDCSelectFoundation.prototype.notchOutline = function (openNotch) {
|
321 | if (!this.adapter.hasOutline()) {
|
322 | return;
|
323 | }
|
324 | var isFocused = this.adapter.hasClass(cssClasses.FOCUSED);
|
325 | if (openNotch) {
|
326 | var labelScale = numbers.LABEL_SCALE;
|
327 | var labelWidth = this.adapter.getLabelWidth() * labelScale;
|
328 | this.adapter.notchOutline(labelWidth);
|
329 | }
|
330 | else if (!isFocused) {
|
331 | this.adapter.closeOutline();
|
332 | }
|
333 | };
|
334 | |
335 |
|
336 |
|
337 | MDCSelectFoundation.prototype.setLeadingIconAriaLabel = function (label) {
|
338 | if (this.leadingIcon) {
|
339 | this.leadingIcon.setAriaLabel(label);
|
340 | }
|
341 | };
|
342 | |
343 |
|
344 |
|
345 | MDCSelectFoundation.prototype.setLeadingIconContent = function (content) {
|
346 | if (this.leadingIcon) {
|
347 | this.leadingIcon.setContent(content);
|
348 | }
|
349 | };
|
350 | MDCSelectFoundation.prototype.getUseDefaultValidation = function () {
|
351 | return this.useDefaultValidation;
|
352 | };
|
353 | MDCSelectFoundation.prototype.setUseDefaultValidation = function (useDefaultValidation) {
|
354 | this.useDefaultValidation = useDefaultValidation;
|
355 | };
|
356 | MDCSelectFoundation.prototype.setValid = function (isValid) {
|
357 | if (!this.useDefaultValidation) {
|
358 | this.customValidity = isValid;
|
359 | }
|
360 | this.adapter.setSelectAnchorAttr('aria-invalid', (!isValid).toString());
|
361 | if (isValid) {
|
362 | this.adapter.removeClass(cssClasses.INVALID);
|
363 | this.adapter.removeMenuClass(cssClasses.MENU_INVALID);
|
364 | }
|
365 | else {
|
366 | this.adapter.addClass(cssClasses.INVALID);
|
367 | this.adapter.addMenuClass(cssClasses.MENU_INVALID);
|
368 | }
|
369 | this.syncHelperTextValidity(isValid);
|
370 | };
|
371 | MDCSelectFoundation.prototype.isValid = function () {
|
372 | if (this.useDefaultValidation &&
|
373 | this.adapter.hasClass(cssClasses.REQUIRED) &&
|
374 | !this.adapter.hasClass(cssClasses.DISABLED)) {
|
375 |
|
376 |
|
377 | return this.getSelectedIndex() !== numbers.UNSET_INDEX &&
|
378 | (this.getSelectedIndex() !== 0 || Boolean(this.getValue()));
|
379 | }
|
380 | return this.customValidity;
|
381 | };
|
382 | MDCSelectFoundation.prototype.setRequired = function (isRequired) {
|
383 | if (isRequired) {
|
384 | this.adapter.addClass(cssClasses.REQUIRED);
|
385 | }
|
386 | else {
|
387 | this.adapter.removeClass(cssClasses.REQUIRED);
|
388 | }
|
389 | this.adapter.setSelectAnchorAttr('aria-required', isRequired.toString());
|
390 | this.adapter.setLabelRequired(isRequired);
|
391 | };
|
392 | MDCSelectFoundation.prototype.getRequired = function () {
|
393 | return this.adapter.getSelectAnchorAttr('aria-required') === 'true';
|
394 | };
|
395 | MDCSelectFoundation.prototype.init = function () {
|
396 | var anchorEl = this.adapter.getAnchorElement();
|
397 | if (anchorEl) {
|
398 | this.adapter.setMenuAnchorElement(anchorEl);
|
399 | this.adapter.setMenuAnchorCorner(Corner.BOTTOM_START);
|
400 | }
|
401 | this.adapter.setMenuWrapFocus(false);
|
402 | this.setDisabled(this.adapter.hasClass(cssClasses.DISABLED));
|
403 | this.syncHelperTextValidity(!this.adapter.hasClass(cssClasses.INVALID));
|
404 | this.layout();
|
405 | this.layoutOptions();
|
406 | };
|
407 | |
408 |
|
409 |
|
410 | MDCSelectFoundation.prototype.blur = function () {
|
411 | this.adapter.removeClass(cssClasses.FOCUSED);
|
412 | this.layout();
|
413 | this.adapter.deactivateBottomLine();
|
414 | var isRequired = this.adapter.hasClass(cssClasses.REQUIRED);
|
415 | if (isRequired && this.useDefaultValidation) {
|
416 | this.setValid(this.isValid());
|
417 | }
|
418 | };
|
419 | MDCSelectFoundation.prototype.syncHelperTextValidity = function (isValid) {
|
420 | if (!this.helperText) {
|
421 | return;
|
422 | }
|
423 | this.helperText.setValidity(isValid);
|
424 | var helperTextVisible = this.helperText.isVisible();
|
425 | var helperTextId = this.helperText.getId();
|
426 | if (helperTextVisible && helperTextId) {
|
427 | this.adapter.setSelectAnchorAttr(strings.ARIA_DESCRIBEDBY, helperTextId);
|
428 | }
|
429 | else {
|
430 |
|
431 |
|
432 | this.adapter.removeSelectAnchorAttr(strings.ARIA_DESCRIBEDBY);
|
433 | }
|
434 | };
|
435 | MDCSelectFoundation.prototype.setClickDebounceTimeout = function () {
|
436 | var _this = this;
|
437 | clearTimeout(this.clickDebounceTimeout);
|
438 | this.clickDebounceTimeout = setTimeout(function () {
|
439 | _this.recentlyClicked = false;
|
440 | }, numbers.CLICK_DEBOUNCE_TIMEOUT_MS);
|
441 | this.recentlyClicked = true;
|
442 | };
|
443 | return MDCSelectFoundation;
|
444 | }(MDCFoundation));
|
445 | export { MDCSelectFoundation };
|
446 |
|
447 | export default MDCSelectFoundation;
|
448 |
|
\ | No newline at end of file |