Skip to content

Instantly share code, notes, and snippets.

@rodydavis
Created August 12, 2020 23:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rodydavis/8fe8ee9934844265da09f403f102bb56 to your computer and use it in GitHub Desktop.
Save rodydavis/8fe8ee9934844265da09f403f102bb56 to your computer and use it in GitHub Desktop.
MWC + MDC Material Bundle for Static Sites
This file has been truncated, but you can view the full file.
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssPropertyNameMap = {
animation: {
prefixed: '-webkit-animation',
standard: 'animation',
},
transform: {
prefixed: '-webkit-transform',
standard: 'transform',
},
transition: {
prefixed: '-webkit-transition',
standard: 'transition',
},
};
var jsEventTypeMap = {
animationend: {
cssProperty: 'animation',
prefixed: 'webkitAnimationEnd',
standard: 'animationend',
},
animationiteration: {
cssProperty: 'animation',
prefixed: 'webkitAnimationIteration',
standard: 'animationiteration',
},
animationstart: {
cssProperty: 'animation',
prefixed: 'webkitAnimationStart',
standard: 'animationstart',
},
transitionend: {
cssProperty: 'transition',
prefixed: 'webkitTransitionEnd',
standard: 'transitionend',
},
};
function isWindow(windowObj) {
return Boolean(windowObj.document) && typeof windowObj.document.createElement === 'function';
}
function getCorrectPropertyName(windowObj, cssProperty) {
if (isWindow(windowObj) && cssProperty in cssPropertyNameMap) {
var el = windowObj.document.createElement('div');
var _a = cssPropertyNameMap[cssProperty], standard = _a.standard, prefixed = _a.prefixed;
var isStandard = standard in el.style;
return isStandard ? standard : prefixed;
}
return cssProperty;
}
function getCorrectEventName(windowObj, eventType) {
if (isWindow(windowObj) && eventType in jsEventTypeMap) {
var el = windowObj.document.createElement('div');
var _a = jsEventTypeMap[eventType], standard = _a.standard, prefixed = _a.prefixed, cssProperty = _a.cssProperty;
var isStandard = cssProperty in el.style;
return isStandard ? standard : prefixed;
}
return eventType;
}
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCFoundation = /** @class */ (function () {
function MDCFoundation(adapter) {
if (adapter === void 0) { adapter = {}; }
this.adapter_ = adapter;
}
Object.defineProperty(MDCFoundation, "cssClasses", {
get: function () {
// Classes extending MDCFoundation should implement this method to return an object which exports every
// CSS class the foundation class needs as a property. e.g. {ACTIVE: 'mdc-component--active'}
return {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFoundation, "strings", {
get: function () {
// Classes extending MDCFoundation should implement this method to return an object which exports all
// semantic strings as constants. e.g. {ARIA_ROLE: 'tablist'}
return {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFoundation, "numbers", {
get: function () {
// Classes extending MDCFoundation should implement this method to return an object which exports all
// of its semantic numbers as constants. e.g. {ANIMATION_DELAY_MS: 350}
return {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFoundation, "defaultAdapter", {
get: function () {
// Classes extending MDCFoundation may choose to implement this getter in order to provide a convenient
// way of viewing the necessary methods of an adapter. In the future, this could also be used for adapter
// validation.
return {};
},
enumerable: true,
configurable: true
});
MDCFoundation.prototype.init = function () {
// Subclasses should override this method to perform initialization routines (registering events, etc.)
};
MDCFoundation.prototype.destroy = function () {
// Subclasses should override this method to perform de-initialization routines (de-registering events, etc.)
};
return MDCFoundation;
}());
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCComponent = /** @class */ (function () {
function MDCComponent(root, foundation) {
var args = [];
for (var _i = 2; _i < arguments.length; _i++) {
args[_i - 2] = arguments[_i];
}
this.root_ = root;
this.initialize.apply(this, __spread(args));
// Note that we initialize foundation here and not within the constructor's default param so that
// this.root_ is defined and can be used within the foundation class.
this.foundation_ = foundation === undefined ? this.getDefaultFoundation() : foundation;
this.foundation_.init();
this.initialSyncWithDOM();
}
MDCComponent.attachTo = function (root) {
// Subclasses which extend MDCBase should provide an attachTo() method that takes a root element and
// returns an instantiated component with its root set to that element. Also note that in the cases of
// subclasses, an explicit foundation class will not have to be passed in; it will simply be initialized
// from getDefaultFoundation().
return new MDCComponent(root, new MDCFoundation({}));
};
/* istanbul ignore next: method param only exists for typing purposes; it does not need to be unit tested */
MDCComponent.prototype.initialize = function () {
var _args = [];
for (var _i = 0; _i < arguments.length; _i++) {
_args[_i] = arguments[_i];
}
// Subclasses can override this to do any additional setup work that would be considered part of a
// "constructor". Essentially, it is a hook into the parent constructor before the foundation is
// initialized. Any additional arguments besides root and foundation will be passed in here.
};
MDCComponent.prototype.getDefaultFoundation = function () {
// Subclasses must override this method to return a properly configured foundation class for the
// component.
throw new Error('Subclasses must override getDefaultFoundation to return a properly configured ' +
'foundation class');
};
MDCComponent.prototype.initialSyncWithDOM = function () {
// Subclasses should override this method if they need to perform work to synchronize with a host DOM
// object. An example of this would be a form control wrapper that needs to synchronize its internal state
// to some property or attribute of the host DOM. Please note: this is *not* the place to perform DOM
// reads/writes that would cause layout / paint, as this is called synchronously from within the constructor.
};
MDCComponent.prototype.destroy = function () {
// Subclasses may implement this method to release any resources / deregister any listeners they have
// attached. An example of this might be deregistering a resize event from the window object.
this.foundation_.destroy();
};
MDCComponent.prototype.listen = function (evtType, handler, options) {
this.root_.addEventListener(evtType, handler, options);
};
MDCComponent.prototype.unlisten = function (evtType, handler, options) {
this.root_.removeEventListener(evtType, handler, options);
};
/**
* Fires a cross-browser-compatible custom event from the component root of the given type, with the given data.
*/
MDCComponent.prototype.emit = function (evtType, evtData, shouldBubble) {
if (shouldBubble === void 0) { shouldBubble = false; }
var evt;
if (typeof CustomEvent === 'function') {
evt = new CustomEvent(evtType, {
bubbles: shouldBubble,
detail: evtData,
});
}
else {
evt = document.createEvent('CustomEvent');
evt.initCustomEvent(evtType, shouldBubble, false, evtData);
}
this.root_.dispatchEvent(evt);
};
return MDCComponent;
}());
/**
* @license
* Copyright 2019 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* Stores result from applyPassive to avoid redundant processing to detect
* passive event listener support.
*/
var supportsPassive_;
/**
* Determine whether the current browser supports passive event listeners, and
* if so, use them.
*/
function applyPassive(globalObj, forceRefresh) {
if (globalObj === void 0) { globalObj = window; }
if (forceRefresh === void 0) { forceRefresh = false; }
if (supportsPassive_ === undefined || forceRefresh) {
var isSupported_1 = false;
try {
globalObj.document.addEventListener('test', function () { return undefined; }, {
get passive() {
isSupported_1 = true;
return isSupported_1;
},
});
}
catch (e) {
} // tslint:disable-line:no-empty cannot throw error due to tests. tslint also disables console.log.
supportsPassive_ = isSupported_1;
}
return supportsPassive_ ? { passive: true } : false;
}
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @fileoverview A "ponyfill" is a polyfill that doesn't modify the global prototype chain.
* This makes ponyfills safer than traditional polyfills, especially for libraries like MDC.
*/
function closest(element, selector) {
if (element.closest) {
return element.closest(selector);
}
var el = element;
while (el) {
if (matches(el, selector)) {
return el;
}
el = el.parentElement;
}
return null;
}
function matches(element, selector) {
var nativeMatches = element.matches
|| element.webkitMatchesSelector
|| element.msMatchesSelector;
return nativeMatches.call(element, selector);
}
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses = {
// Ripple is a special case where the "root" component is really a "mixin" of sorts,
// given that it's an 'upgrade' to an existing component. That being said it is the root
// CSS class that all other CSS classes derive from.
BG_FOCUSED: 'mdc-ripple-upgraded--background-focused',
FG_ACTIVATION: 'mdc-ripple-upgraded--foreground-activation',
FG_DEACTIVATION: 'mdc-ripple-upgraded--foreground-deactivation',
ROOT: 'mdc-ripple-upgraded',
UNBOUNDED: 'mdc-ripple-upgraded--unbounded',
};
var strings = {
VAR_FG_SCALE: '--mdc-ripple-fg-scale',
VAR_FG_SIZE: '--mdc-ripple-fg-size',
VAR_FG_TRANSLATE_END: '--mdc-ripple-fg-translate-end',
VAR_FG_TRANSLATE_START: '--mdc-ripple-fg-translate-start',
VAR_LEFT: '--mdc-ripple-left',
VAR_TOP: '--mdc-ripple-top',
};
var numbers = {
DEACTIVATION_TIMEOUT_MS: 225,
FG_DEACTIVATION_MS: 150,
INITIAL_ORIGIN_SCALE: 0.6,
PADDING: 10,
TAP_DELAY_MS: 300,
};
/**
* Stores result from supportsCssVariables to avoid redundant processing to
* detect CSS custom variable support.
*/
var supportsCssVariables_;
function detectEdgePseudoVarBug(windowObj) {
// Detect versions of Edge with buggy var() support
// See: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11495448/
var document = windowObj.document;
var node = document.createElement('div');
node.className = 'mdc-ripple-surface--test-edge-var-bug';
// Append to head instead of body because this script might be invoked in the
// head, in which case the body doesn't exist yet. The probe works either way.
document.head.appendChild(node);
// The bug exists if ::before style ends up propagating to the parent element.
// Additionally, getComputedStyle returns null in iframes with display: "none" in Firefox,
// but Firefox is known to support CSS custom properties correctly.
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=548397
var computedStyle = windowObj.getComputedStyle(node);
var hasPseudoVarBug = computedStyle !== null && computedStyle.borderTopStyle === 'solid';
if (node.parentNode) {
node.parentNode.removeChild(node);
}
return hasPseudoVarBug;
}
function supportsCssVariables(windowObj, forceRefresh) {
if (forceRefresh === void 0) { forceRefresh = false; }
var CSS = windowObj.CSS;
var supportsCssVars = supportsCssVariables_;
if (typeof supportsCssVariables_ === 'boolean' && !forceRefresh) {
return supportsCssVariables_;
}
var supportsFunctionPresent = CSS && typeof CSS.supports === 'function';
if (!supportsFunctionPresent) {
return false;
}
var explicitlySupportsCssVars = CSS.supports('--css-vars', 'yes');
// See: https://bugs.webkit.org/show_bug.cgi?id=154669
// See: README section on Safari
var weAreFeatureDetectingSafari10plus = (CSS.supports('(--css-vars: yes)') &&
CSS.supports('color', '#00000000'));
if (explicitlySupportsCssVars || weAreFeatureDetectingSafari10plus) {
supportsCssVars = !detectEdgePseudoVarBug(windowObj);
}
else {
supportsCssVars = false;
}
if (!forceRefresh) {
supportsCssVariables_ = supportsCssVars;
}
return supportsCssVars;
}
function getNormalizedEventCoords(evt, pageOffset, clientRect) {
if (!evt) {
return { x: 0, y: 0 };
}
var x = pageOffset.x, y = pageOffset.y;
var documentX = x + clientRect.left;
var documentY = y + clientRect.top;
var normalizedX;
var normalizedY;
// Determine touch point relative to the ripple container.
if (evt.type === 'touchstart') {
var touchEvent = evt;
normalizedX = touchEvent.changedTouches[0].pageX - documentX;
normalizedY = touchEvent.changedTouches[0].pageY - documentY;
}
else {
var mouseEvent = evt;
normalizedX = mouseEvent.pageX - documentX;
normalizedY = mouseEvent.pageY - documentY;
}
return { x: normalizedX, y: normalizedY };
}
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Activation events registered on the root element of each instance for activation
var ACTIVATION_EVENT_TYPES = [
'touchstart', 'pointerdown', 'mousedown', 'keydown',
];
// Deactivation events registered on documentElement when a pointer-related down event occurs
var POINTER_DEACTIVATION_EVENT_TYPES = [
'touchend', 'pointerup', 'mouseup', 'contextmenu',
];
// simultaneous nested activations
var activatedTargets = [];
var MDCRippleFoundation = /** @class */ (function (_super) {
__extends(MDCRippleFoundation, _super);
function MDCRippleFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCRippleFoundation.defaultAdapter, adapter)) || this;
_this.activationAnimationHasEnded_ = false;
_this.activationTimer_ = 0;
_this.fgDeactivationRemovalTimer_ = 0;
_this.fgScale_ = '0';
_this.frame_ = { width: 0, height: 0 };
_this.initialSize_ = 0;
_this.layoutFrame_ = 0;
_this.maxRadius_ = 0;
_this.unboundedCoords_ = { left: 0, top: 0 };
_this.activationState_ = _this.defaultActivationState_();
_this.activationTimerCallback_ = function () {
_this.activationAnimationHasEnded_ = true;
_this.runDeactivationUXLogicIfReady_();
};
_this.activateHandler_ = function (e) { return _this.activate_(e); };
_this.deactivateHandler_ = function () { return _this.deactivate_(); };
_this.focusHandler_ = function () { return _this.handleFocus(); };
_this.blurHandler_ = function () { return _this.handleBlur(); };
_this.resizeHandler_ = function () { return _this.layout(); };
return _this;
}
Object.defineProperty(MDCRippleFoundation, "cssClasses", {
get: function () {
return cssClasses;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCRippleFoundation, "strings", {
get: function () {
return strings;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCRippleFoundation, "numbers", {
get: function () {
return numbers;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCRippleFoundation, "defaultAdapter", {
get: function () {
return {
addClass: function () { return undefined; },
browserSupportsCssVars: function () { return true; },
computeBoundingRect: function () { return ({ top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 }); },
containsEventTarget: function () { return true; },
deregisterDocumentInteractionHandler: function () { return undefined; },
deregisterInteractionHandler: function () { return undefined; },
deregisterResizeHandler: function () { return undefined; },
getWindowPageOffset: function () { return ({ x: 0, y: 0 }); },
isSurfaceActive: function () { return true; },
isSurfaceDisabled: function () { return true; },
isUnbounded: function () { return true; },
registerDocumentInteractionHandler: function () { return undefined; },
registerInteractionHandler: function () { return undefined; },
registerResizeHandler: function () { return undefined; },
removeClass: function () { return undefined; },
updateCssVariable: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCRippleFoundation.prototype.init = function () {
var _this = this;
var supportsPressRipple = this.supportsPressRipple_();
this.registerRootHandlers_(supportsPressRipple);
if (supportsPressRipple) {
var _a = MDCRippleFoundation.cssClasses, ROOT_1 = _a.ROOT, UNBOUNDED_1 = _a.UNBOUNDED;
requestAnimationFrame(function () {
_this.adapter_.addClass(ROOT_1);
if (_this.adapter_.isUnbounded()) {
_this.adapter_.addClass(UNBOUNDED_1);
// Unbounded ripples need layout logic applied immediately to set coordinates for both shade and ripple
_this.layoutInternal_();
}
});
}
};
MDCRippleFoundation.prototype.destroy = function () {
var _this = this;
if (this.supportsPressRipple_()) {
if (this.activationTimer_) {
clearTimeout(this.activationTimer_);
this.activationTimer_ = 0;
this.adapter_.removeClass(MDCRippleFoundation.cssClasses.FG_ACTIVATION);
}
if (this.fgDeactivationRemovalTimer_) {
clearTimeout(this.fgDeactivationRemovalTimer_);
this.fgDeactivationRemovalTimer_ = 0;
this.adapter_.removeClass(MDCRippleFoundation.cssClasses.FG_DEACTIVATION);
}
var _a = MDCRippleFoundation.cssClasses, ROOT_2 = _a.ROOT, UNBOUNDED_2 = _a.UNBOUNDED;
requestAnimationFrame(function () {
_this.adapter_.removeClass(ROOT_2);
_this.adapter_.removeClass(UNBOUNDED_2);
_this.removeCssVars_();
});
}
this.deregisterRootHandlers_();
this.deregisterDeactivationHandlers_();
};
/**
* @param evt Optional event containing position information.
*/
MDCRippleFoundation.prototype.activate = function (evt) {
this.activate_(evt);
};
MDCRippleFoundation.prototype.deactivate = function () {
this.deactivate_();
};
MDCRippleFoundation.prototype.layout = function () {
var _this = this;
if (this.layoutFrame_) {
cancelAnimationFrame(this.layoutFrame_);
}
this.layoutFrame_ = requestAnimationFrame(function () {
_this.layoutInternal_();
_this.layoutFrame_ = 0;
});
};
MDCRippleFoundation.prototype.setUnbounded = function (unbounded) {
var UNBOUNDED = MDCRippleFoundation.cssClasses.UNBOUNDED;
if (unbounded) {
this.adapter_.addClass(UNBOUNDED);
}
else {
this.adapter_.removeClass(UNBOUNDED);
}
};
MDCRippleFoundation.prototype.handleFocus = function () {
var _this = this;
requestAnimationFrame(function () {
return _this.adapter_.addClass(MDCRippleFoundation.cssClasses.BG_FOCUSED);
});
};
MDCRippleFoundation.prototype.handleBlur = function () {
var _this = this;
requestAnimationFrame(function () {
return _this.adapter_.removeClass(MDCRippleFoundation.cssClasses.BG_FOCUSED);
});
};
/**
* We compute this property so that we are not querying information about the client
* until the point in time where the foundation requests it. This prevents scenarios where
* client-side feature-detection may happen too early, such as when components are rendered on the server
* and then initialized at mount time on the client.
*/
MDCRippleFoundation.prototype.supportsPressRipple_ = function () {
return this.adapter_.browserSupportsCssVars();
};
MDCRippleFoundation.prototype.defaultActivationState_ = function () {
return {
activationEvent: undefined,
hasDeactivationUXRun: false,
isActivated: false,
isProgrammatic: false,
wasActivatedByPointer: false,
wasElementMadeActive: false,
};
};
/**
* supportsPressRipple Passed from init to save a redundant function call
*/
MDCRippleFoundation.prototype.registerRootHandlers_ = function (supportsPressRipple) {
var _this = this;
if (supportsPressRipple) {
ACTIVATION_EVENT_TYPES.forEach(function (evtType) {
_this.adapter_.registerInteractionHandler(evtType, _this.activateHandler_);
});
if (this.adapter_.isUnbounded()) {
this.adapter_.registerResizeHandler(this.resizeHandler_);
}
}
this.adapter_.registerInteractionHandler('focus', this.focusHandler_);
this.adapter_.registerInteractionHandler('blur', this.blurHandler_);
};
MDCRippleFoundation.prototype.registerDeactivationHandlers_ = function (evt) {
var _this = this;
if (evt.type === 'keydown') {
this.adapter_.registerInteractionHandler('keyup', this.deactivateHandler_);
}
else {
POINTER_DEACTIVATION_EVENT_TYPES.forEach(function (evtType) {
_this.adapter_.registerDocumentInteractionHandler(evtType, _this.deactivateHandler_);
});
}
};
MDCRippleFoundation.prototype.deregisterRootHandlers_ = function () {
var _this = this;
ACTIVATION_EVENT_TYPES.forEach(function (evtType) {
_this.adapter_.deregisterInteractionHandler(evtType, _this.activateHandler_);
});
this.adapter_.deregisterInteractionHandler('focus', this.focusHandler_);
this.adapter_.deregisterInteractionHandler('blur', this.blurHandler_);
if (this.adapter_.isUnbounded()) {
this.adapter_.deregisterResizeHandler(this.resizeHandler_);
}
};
MDCRippleFoundation.prototype.deregisterDeactivationHandlers_ = function () {
var _this = this;
this.adapter_.deregisterInteractionHandler('keyup', this.deactivateHandler_);
POINTER_DEACTIVATION_EVENT_TYPES.forEach(function (evtType) {
_this.adapter_.deregisterDocumentInteractionHandler(evtType, _this.deactivateHandler_);
});
};
MDCRippleFoundation.prototype.removeCssVars_ = function () {
var _this = this;
var rippleStrings = MDCRippleFoundation.strings;
var keys = Object.keys(rippleStrings);
keys.forEach(function (key) {
if (key.indexOf('VAR_') === 0) {
_this.adapter_.updateCssVariable(rippleStrings[key], null);
}
});
};
MDCRippleFoundation.prototype.activate_ = function (evt) {
var _this = this;
if (this.adapter_.isSurfaceDisabled()) {
return;
}
var activationState = this.activationState_;
if (activationState.isActivated) {
return;
}
// Avoid reacting to follow-on events fired by touch device after an already-processed user interaction
var previousActivationEvent = this.previousActivationEvent_;
var isSameInteraction = previousActivationEvent && evt !== undefined && previousActivationEvent.type !== evt.type;
if (isSameInteraction) {
return;
}
activationState.isActivated = true;
activationState.isProgrammatic = evt === undefined;
activationState.activationEvent = evt;
activationState.wasActivatedByPointer = activationState.isProgrammatic ? false : evt !== undefined && (evt.type === 'mousedown' || evt.type === 'touchstart' || evt.type === 'pointerdown');
var hasActivatedChild = evt !== undefined && activatedTargets.length > 0 && activatedTargets.some(function (target) { return _this.adapter_.containsEventTarget(target); });
if (hasActivatedChild) {
// Immediately reset activation state, while preserving logic that prevents touch follow-on events
this.resetActivationState_();
return;
}
if (evt !== undefined) {
activatedTargets.push(evt.target);
this.registerDeactivationHandlers_(evt);
}
activationState.wasElementMadeActive = this.checkElementMadeActive_(evt);
if (activationState.wasElementMadeActive) {
this.animateActivation_();
}
requestAnimationFrame(function () {
// Reset array on next frame after the current event has had a chance to bubble to prevent ancestor ripples
activatedTargets = [];
if (!activationState.wasElementMadeActive
&& evt !== undefined
&& (evt.key === ' ' || evt.keyCode === 32)) {
// If space was pressed, try again within an rAF call to detect :active, because different UAs report
// active states inconsistently when they're called within event handling code:
// - https://bugs.chromium.org/p/chromium/issues/detail?id=635971
// - https://bugzilla.mozilla.org/show_bug.cgi?id=1293741
// We try first outside rAF to support Edge, which does not exhibit this problem, but will crash if a CSS
// variable is set within a rAF callback for a submit button interaction (#2241).
activationState.wasElementMadeActive = _this.checkElementMadeActive_(evt);
if (activationState.wasElementMadeActive) {
_this.animateActivation_();
}
}
if (!activationState.wasElementMadeActive) {
// Reset activation state immediately if element was not made active.
_this.activationState_ = _this.defaultActivationState_();
}
});
};
MDCRippleFoundation.prototype.checkElementMadeActive_ = function (evt) {
return (evt !== undefined && evt.type === 'keydown') ? this.adapter_.isSurfaceActive() : true;
};
MDCRippleFoundation.prototype.animateActivation_ = function () {
var _this = this;
var _a = MDCRippleFoundation.strings, VAR_FG_TRANSLATE_START = _a.VAR_FG_TRANSLATE_START, VAR_FG_TRANSLATE_END = _a.VAR_FG_TRANSLATE_END;
var _b = MDCRippleFoundation.cssClasses, FG_DEACTIVATION = _b.FG_DEACTIVATION, FG_ACTIVATION = _b.FG_ACTIVATION;
var DEACTIVATION_TIMEOUT_MS = MDCRippleFoundation.numbers.DEACTIVATION_TIMEOUT_MS;
this.layoutInternal_();
var translateStart = '';
var translateEnd = '';
if (!this.adapter_.isUnbounded()) {
var _c = this.getFgTranslationCoordinates_(), startPoint = _c.startPoint, endPoint = _c.endPoint;
translateStart = startPoint.x + "px, " + startPoint.y + "px";
translateEnd = endPoint.x + "px, " + endPoint.y + "px";
}
this.adapter_.updateCssVariable(VAR_FG_TRANSLATE_START, translateStart);
this.adapter_.updateCssVariable(VAR_FG_TRANSLATE_END, translateEnd);
// Cancel any ongoing activation/deactivation animations
clearTimeout(this.activationTimer_);
clearTimeout(this.fgDeactivationRemovalTimer_);
this.rmBoundedActivationClasses_();
this.adapter_.removeClass(FG_DEACTIVATION);
// Force layout in order to re-trigger the animation.
this.adapter_.computeBoundingRect();
this.adapter_.addClass(FG_ACTIVATION);
this.activationTimer_ = setTimeout(function () { return _this.activationTimerCallback_(); }, DEACTIVATION_TIMEOUT_MS);
};
MDCRippleFoundation.prototype.getFgTranslationCoordinates_ = function () {
var _a = this.activationState_, activationEvent = _a.activationEvent, wasActivatedByPointer = _a.wasActivatedByPointer;
var startPoint;
if (wasActivatedByPointer) {
startPoint = getNormalizedEventCoords(activationEvent, this.adapter_.getWindowPageOffset(), this.adapter_.computeBoundingRect());
}
else {
startPoint = {
x: this.frame_.width / 2,
y: this.frame_.height / 2,
};
}
// Center the element around the start point.
startPoint = {
x: startPoint.x - (this.initialSize_ / 2),
y: startPoint.y - (this.initialSize_ / 2),
};
var endPoint = {
x: (this.frame_.width / 2) - (this.initialSize_ / 2),
y: (this.frame_.height / 2) - (this.initialSize_ / 2),
};
return { startPoint: startPoint, endPoint: endPoint };
};
MDCRippleFoundation.prototype.runDeactivationUXLogicIfReady_ = function () {
var _this = this;
// This method is called both when a pointing device is released, and when the activation animation ends.
// The deactivation animation should only run after both of those occur.
var FG_DEACTIVATION = MDCRippleFoundation.cssClasses.FG_DEACTIVATION;
var _a = this.activationState_, hasDeactivationUXRun = _a.hasDeactivationUXRun, isActivated = _a.isActivated;
var activationHasEnded = hasDeactivationUXRun || !isActivated;
if (activationHasEnded && this.activationAnimationHasEnded_) {
this.rmBoundedActivationClasses_();
this.adapter_.addClass(FG_DEACTIVATION);
this.fgDeactivationRemovalTimer_ = setTimeout(function () {
_this.adapter_.removeClass(FG_DEACTIVATION);
}, numbers.FG_DEACTIVATION_MS);
}
};
MDCRippleFoundation.prototype.rmBoundedActivationClasses_ = function () {
var FG_ACTIVATION = MDCRippleFoundation.cssClasses.FG_ACTIVATION;
this.adapter_.removeClass(FG_ACTIVATION);
this.activationAnimationHasEnded_ = false;
this.adapter_.computeBoundingRect();
};
MDCRippleFoundation.prototype.resetActivationState_ = function () {
var _this = this;
this.previousActivationEvent_ = this.activationState_.activationEvent;
this.activationState_ = this.defaultActivationState_();
// Touch devices may fire additional events for the same interaction within a short time.
// Store the previous event until it's safe to assume that subsequent events are for new interactions.
setTimeout(function () { return _this.previousActivationEvent_ = undefined; }, MDCRippleFoundation.numbers.TAP_DELAY_MS);
};
MDCRippleFoundation.prototype.deactivate_ = function () {
var _this = this;
var activationState = this.activationState_;
// This can happen in scenarios such as when you have a keyup event that blurs the element.
if (!activationState.isActivated) {
return;
}
var state = __assign({}, activationState);
if (activationState.isProgrammatic) {
requestAnimationFrame(function () { return _this.animateDeactivation_(state); });
this.resetActivationState_();
}
else {
this.deregisterDeactivationHandlers_();
requestAnimationFrame(function () {
_this.activationState_.hasDeactivationUXRun = true;
_this.animateDeactivation_(state);
_this.resetActivationState_();
});
}
};
MDCRippleFoundation.prototype.animateDeactivation_ = function (_a) {
var wasActivatedByPointer = _a.wasActivatedByPointer, wasElementMadeActive = _a.wasElementMadeActive;
if (wasActivatedByPointer || wasElementMadeActive) {
this.runDeactivationUXLogicIfReady_();
}
};
MDCRippleFoundation.prototype.layoutInternal_ = function () {
var _this = this;
this.frame_ = this.adapter_.computeBoundingRect();
var maxDim = Math.max(this.frame_.height, this.frame_.width);
// Surface diameter is treated differently for unbounded vs. bounded ripples.
// Unbounded ripple diameter is calculated smaller since the surface is expected to already be padded appropriately
// to extend the hitbox, and the ripple is expected to meet the edges of the padded hitbox (which is typically
// square). Bounded ripples, on the other hand, are fully expected to expand beyond the surface's longest diameter
// (calculated based on the diagonal plus a constant padding), and are clipped at the surface's border via
// `overflow: hidden`.
var getBoundedRadius = function () {
var hypotenuse = Math.sqrt(Math.pow(_this.frame_.width, 2) + Math.pow(_this.frame_.height, 2));
return hypotenuse + MDCRippleFoundation.numbers.PADDING;
};
this.maxRadius_ = this.adapter_.isUnbounded() ? maxDim : getBoundedRadius();
// Ripple is sized as a fraction of the largest dimension of the surface, then scales up using a CSS scale transform
this.initialSize_ = Math.floor(maxDim * MDCRippleFoundation.numbers.INITIAL_ORIGIN_SCALE);
this.fgScale_ = "" + this.maxRadius_ / this.initialSize_;
this.updateLayoutCssVars_();
};
MDCRippleFoundation.prototype.updateLayoutCssVars_ = function () {
var _a = MDCRippleFoundation.strings, VAR_FG_SIZE = _a.VAR_FG_SIZE, VAR_LEFT = _a.VAR_LEFT, VAR_TOP = _a.VAR_TOP, VAR_FG_SCALE = _a.VAR_FG_SCALE;
this.adapter_.updateCssVariable(VAR_FG_SIZE, this.initialSize_ + "px");
this.adapter_.updateCssVariable(VAR_FG_SCALE, this.fgScale_);
if (this.adapter_.isUnbounded()) {
this.unboundedCoords_ = {
left: Math.round((this.frame_.width / 2) - (this.initialSize_ / 2)),
top: Math.round((this.frame_.height / 2) - (this.initialSize_ / 2)),
};
this.adapter_.updateCssVariable(VAR_LEFT, this.unboundedCoords_.left + "px");
this.adapter_.updateCssVariable(VAR_TOP, this.unboundedCoords_.top + "px");
}
};
return MDCRippleFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCRipple = /** @class */ (function (_super) {
__extends(MDCRipple, _super);
function MDCRipple() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.disabled = false;
return _this;
}
MDCRipple.attachTo = function (root, opts) {
if (opts === void 0) { opts = { isUnbounded: undefined }; }
var ripple = new MDCRipple(root);
// Only override unbounded behavior if option is explicitly specified
if (opts.isUnbounded !== undefined) {
ripple.unbounded = opts.isUnbounded;
}
return ripple;
};
MDCRipple.createAdapter = function (instance) {
return {
addClass: function (className) { return instance.root_.classList.add(className); },
browserSupportsCssVars: function () { return supportsCssVariables(window); },
computeBoundingRect: function () { return instance.root_.getBoundingClientRect(); },
containsEventTarget: function (target) { return instance.root_.contains(target); },
deregisterDocumentInteractionHandler: function (evtType, handler) {
return document.documentElement.removeEventListener(evtType, handler, applyPassive());
},
deregisterInteractionHandler: function (evtType, handler) {
return instance.root_.removeEventListener(evtType, handler, applyPassive());
},
deregisterResizeHandler: function (handler) { return window.removeEventListener('resize', handler); },
getWindowPageOffset: function () { return ({ x: window.pageXOffset, y: window.pageYOffset }); },
isSurfaceActive: function () { return matches(instance.root_, ':active'); },
isSurfaceDisabled: function () { return Boolean(instance.disabled); },
isUnbounded: function () { return Boolean(instance.unbounded); },
registerDocumentInteractionHandler: function (evtType, handler) {
return document.documentElement.addEventListener(evtType, handler, applyPassive());
},
registerInteractionHandler: function (evtType, handler) {
return instance.root_.addEventListener(evtType, handler, applyPassive());
},
registerResizeHandler: function (handler) { return window.addEventListener('resize', handler); },
removeClass: function (className) { return instance.root_.classList.remove(className); },
updateCssVariable: function (varName, value) { return instance.root_.style.setProperty(varName, value); },
};
};
Object.defineProperty(MDCRipple.prototype, "unbounded", {
get: function () {
return Boolean(this.unbounded_);
},
set: function (unbounded) {
this.unbounded_ = Boolean(unbounded);
this.setUnbounded_();
},
enumerable: true,
configurable: true
});
MDCRipple.prototype.activate = function () {
this.foundation_.activate();
};
MDCRipple.prototype.deactivate = function () {
this.foundation_.deactivate();
};
MDCRipple.prototype.layout = function () {
this.foundation_.layout();
};
MDCRipple.prototype.getDefaultFoundation = function () {
return new MDCRippleFoundation(MDCRipple.createAdapter(this));
};
MDCRipple.prototype.initialSyncWithDOM = function () {
var root = this.root_;
this.unbounded = 'mdcRippleIsUnbounded' in root.dataset;
};
/**
* Closure Compiler throws an access control error when directly accessing a
* protected or private property inside a getter/setter, like unbounded above.
* By accessing the protected property inside a method, we solve that problem.
* That's why this function exists.
*/
MDCRipple.prototype.setUnbounded_ = function () {
this.foundation_.setUnbounded(Boolean(this.unbounded_));
};
return MDCRipple;
}(MDCComponent));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$1 = {
ANIM_CHECKED_INDETERMINATE: 'mdc-checkbox--anim-checked-indeterminate',
ANIM_CHECKED_UNCHECKED: 'mdc-checkbox--anim-checked-unchecked',
ANIM_INDETERMINATE_CHECKED: 'mdc-checkbox--anim-indeterminate-checked',
ANIM_INDETERMINATE_UNCHECKED: 'mdc-checkbox--anim-indeterminate-unchecked',
ANIM_UNCHECKED_CHECKED: 'mdc-checkbox--anim-unchecked-checked',
ANIM_UNCHECKED_INDETERMINATE: 'mdc-checkbox--anim-unchecked-indeterminate',
BACKGROUND: 'mdc-checkbox__background',
CHECKED: 'mdc-checkbox--checked',
CHECKMARK: 'mdc-checkbox__checkmark',
CHECKMARK_PATH: 'mdc-checkbox__checkmark-path',
DISABLED: 'mdc-checkbox--disabled',
INDETERMINATE: 'mdc-checkbox--indeterminate',
MIXEDMARK: 'mdc-checkbox__mixedmark',
NATIVE_CONTROL: 'mdc-checkbox__native-control',
ROOT: 'mdc-checkbox',
SELECTED: 'mdc-checkbox--selected',
UPGRADED: 'mdc-checkbox--upgraded',
};
var strings$1 = {
ARIA_CHECKED_ATTR: 'aria-checked',
ARIA_CHECKED_INDETERMINATE_VALUE: 'mixed',
NATIVE_CONTROL_SELECTOR: '.mdc-checkbox__native-control',
TRANSITION_STATE_CHECKED: 'checked',
TRANSITION_STATE_INDETERMINATE: 'indeterminate',
TRANSITION_STATE_INIT: 'init',
TRANSITION_STATE_UNCHECKED: 'unchecked',
};
var numbers$1 = {
ANIM_END_LATCH_MS: 250,
};
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCCheckboxFoundation = /** @class */ (function (_super) {
__extends(MDCCheckboxFoundation, _super);
function MDCCheckboxFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCCheckboxFoundation.defaultAdapter, adapter)) || this;
_this.currentCheckState_ = strings$1.TRANSITION_STATE_INIT;
_this.currentAnimationClass_ = '';
_this.animEndLatchTimer_ = 0;
_this.enableAnimationEndHandler_ = false;
return _this;
}
Object.defineProperty(MDCCheckboxFoundation, "cssClasses", {
get: function () {
return cssClasses$1;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCCheckboxFoundation, "strings", {
get: function () {
return strings$1;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCCheckboxFoundation, "numbers", {
get: function () {
return numbers$1;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCCheckboxFoundation, "defaultAdapter", {
get: function () {
return {
addClass: function () { return undefined; },
forceLayout: function () { return undefined; },
hasNativeControl: function () { return false; },
isAttachedToDOM: function () { return false; },
isChecked: function () { return false; },
isIndeterminate: function () { return false; },
removeClass: function () { return undefined; },
removeNativeControlAttr: function () { return undefined; },
setNativeControlAttr: function () { return undefined; },
setNativeControlDisabled: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCCheckboxFoundation.prototype.init = function () {
this.currentCheckState_ = this.determineCheckState_();
this.updateAriaChecked_();
this.adapter_.addClass(cssClasses$1.UPGRADED);
};
MDCCheckboxFoundation.prototype.destroy = function () {
clearTimeout(this.animEndLatchTimer_);
};
MDCCheckboxFoundation.prototype.setDisabled = function (disabled) {
this.adapter_.setNativeControlDisabled(disabled);
if (disabled) {
this.adapter_.addClass(cssClasses$1.DISABLED);
}
else {
this.adapter_.removeClass(cssClasses$1.DISABLED);
}
};
/**
* Handles the animationend event for the checkbox
*/
MDCCheckboxFoundation.prototype.handleAnimationEnd = function () {
var _this = this;
if (!this.enableAnimationEndHandler_) {
return;
}
clearTimeout(this.animEndLatchTimer_);
this.animEndLatchTimer_ = setTimeout(function () {
_this.adapter_.removeClass(_this.currentAnimationClass_);
_this.enableAnimationEndHandler_ = false;
}, numbers$1.ANIM_END_LATCH_MS);
};
/**
* Handles the change event for the checkbox
*/
MDCCheckboxFoundation.prototype.handleChange = function () {
this.transitionCheckState_();
};
MDCCheckboxFoundation.prototype.transitionCheckState_ = function () {
if (!this.adapter_.hasNativeControl()) {
return;
}
var oldState = this.currentCheckState_;
var newState = this.determineCheckState_();
if (oldState === newState) {
return;
}
this.updateAriaChecked_();
var TRANSITION_STATE_UNCHECKED = strings$1.TRANSITION_STATE_UNCHECKED;
var SELECTED = cssClasses$1.SELECTED;
if (newState === TRANSITION_STATE_UNCHECKED) {
this.adapter_.removeClass(SELECTED);
}
else {
this.adapter_.addClass(SELECTED);
}
// Check to ensure that there isn't a previously existing animation class, in case for example
// the user interacted with the checkbox before the animation was finished.
if (this.currentAnimationClass_.length > 0) {
clearTimeout(this.animEndLatchTimer_);
this.adapter_.forceLayout();
this.adapter_.removeClass(this.currentAnimationClass_);
}
this.currentAnimationClass_ = this.getTransitionAnimationClass_(oldState, newState);
this.currentCheckState_ = newState;
// Check for parentNode so that animations are only run when the element is attached
// to the DOM.
if (this.adapter_.isAttachedToDOM() && this.currentAnimationClass_.length > 0) {
this.adapter_.addClass(this.currentAnimationClass_);
this.enableAnimationEndHandler_ = true;
}
};
MDCCheckboxFoundation.prototype.determineCheckState_ = function () {
var TRANSITION_STATE_INDETERMINATE = strings$1.TRANSITION_STATE_INDETERMINATE, TRANSITION_STATE_CHECKED = strings$1.TRANSITION_STATE_CHECKED, TRANSITION_STATE_UNCHECKED = strings$1.TRANSITION_STATE_UNCHECKED;
if (this.adapter_.isIndeterminate()) {
return TRANSITION_STATE_INDETERMINATE;
}
return this.adapter_.isChecked() ? TRANSITION_STATE_CHECKED : TRANSITION_STATE_UNCHECKED;
};
MDCCheckboxFoundation.prototype.getTransitionAnimationClass_ = function (oldState, newState) {
var TRANSITION_STATE_INIT = strings$1.TRANSITION_STATE_INIT, TRANSITION_STATE_CHECKED = strings$1.TRANSITION_STATE_CHECKED, TRANSITION_STATE_UNCHECKED = strings$1.TRANSITION_STATE_UNCHECKED;
var _a = MDCCheckboxFoundation.cssClasses, ANIM_UNCHECKED_CHECKED = _a.ANIM_UNCHECKED_CHECKED, ANIM_UNCHECKED_INDETERMINATE = _a.ANIM_UNCHECKED_INDETERMINATE, ANIM_CHECKED_UNCHECKED = _a.ANIM_CHECKED_UNCHECKED, ANIM_CHECKED_INDETERMINATE = _a.ANIM_CHECKED_INDETERMINATE, ANIM_INDETERMINATE_CHECKED = _a.ANIM_INDETERMINATE_CHECKED, ANIM_INDETERMINATE_UNCHECKED = _a.ANIM_INDETERMINATE_UNCHECKED;
switch (oldState) {
case TRANSITION_STATE_INIT:
if (newState === TRANSITION_STATE_UNCHECKED) {
return '';
}
return newState === TRANSITION_STATE_CHECKED ? ANIM_INDETERMINATE_CHECKED : ANIM_INDETERMINATE_UNCHECKED;
case TRANSITION_STATE_UNCHECKED:
return newState === TRANSITION_STATE_CHECKED ? ANIM_UNCHECKED_CHECKED : ANIM_UNCHECKED_INDETERMINATE;
case TRANSITION_STATE_CHECKED:
return newState === TRANSITION_STATE_UNCHECKED ? ANIM_CHECKED_UNCHECKED : ANIM_CHECKED_INDETERMINATE;
default: // TRANSITION_STATE_INDETERMINATE
return newState === TRANSITION_STATE_CHECKED ? ANIM_INDETERMINATE_CHECKED : ANIM_INDETERMINATE_UNCHECKED;
}
};
MDCCheckboxFoundation.prototype.updateAriaChecked_ = function () {
// Ensure aria-checked is set to mixed if checkbox is in indeterminate state.
if (this.adapter_.isIndeterminate()) {
this.adapter_.setNativeControlAttr(strings$1.ARIA_CHECKED_ATTR, strings$1.ARIA_CHECKED_INDETERMINATE_VALUE);
}
else {
// The on/off state does not need to keep track of aria-checked, since
// the screenreader uses the checked property on the checkbox element.
this.adapter_.removeNativeControlAttr(strings$1.ARIA_CHECKED_ATTR);
}
};
return MDCCheckboxFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var CB_PROTO_PROPS = ['checked', 'indeterminate'];
var MDCCheckbox = /** @class */ (function (_super) {
__extends(MDCCheckbox, _super);
function MDCCheckbox() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.ripple_ = _this.createRipple_();
return _this;
}
MDCCheckbox.attachTo = function (root) {
return new MDCCheckbox(root);
};
Object.defineProperty(MDCCheckbox.prototype, "ripple", {
get: function () {
return this.ripple_;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCCheckbox.prototype, "checked", {
get: function () {
return this.nativeControl_.checked;
},
set: function (checked) {
this.nativeControl_.checked = checked;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCCheckbox.prototype, "indeterminate", {
get: function () {
return this.nativeControl_.indeterminate;
},
set: function (indeterminate) {
this.nativeControl_.indeterminate = indeterminate;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCCheckbox.prototype, "disabled", {
get: function () {
return this.nativeControl_.disabled;
},
set: function (disabled) {
this.foundation_.setDisabled(disabled);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCCheckbox.prototype, "value", {
get: function () {
return this.nativeControl_.value;
},
set: function (value) {
this.nativeControl_.value = value;
},
enumerable: true,
configurable: true
});
MDCCheckbox.prototype.initialSyncWithDOM = function () {
var _this = this;
this.handleChange_ = function () { return _this.foundation_.handleChange(); };
this.handleAnimationEnd_ = function () { return _this.foundation_.handleAnimationEnd(); };
this.nativeControl_.addEventListener('change', this.handleChange_);
this.listen(getCorrectEventName(window, 'animationend'), this.handleAnimationEnd_);
this.installPropertyChangeHooks_();
};
MDCCheckbox.prototype.destroy = function () {
this.ripple_.destroy();
this.nativeControl_.removeEventListener('change', this.handleChange_);
this.unlisten(getCorrectEventName(window, 'animationend'), this.handleAnimationEnd_);
this.uninstallPropertyChangeHooks_();
_super.prototype.destroy.call(this);
};
MDCCheckbox.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
forceLayout: function () { return _this.root_.offsetWidth; },
hasNativeControl: function () { return !!_this.nativeControl_; },
isAttachedToDOM: function () { return Boolean(_this.root_.parentNode); },
isChecked: function () { return _this.checked; },
isIndeterminate: function () { return _this.indeterminate; },
removeClass: function (className) { return _this.root_.classList.remove(className); },
removeNativeControlAttr: function (attr) { return _this.nativeControl_.removeAttribute(attr); },
setNativeControlAttr: function (attr, value) { return _this.nativeControl_.setAttribute(attr, value); },
setNativeControlDisabled: function (disabled) { return _this.nativeControl_.disabled = disabled; },
};
return new MDCCheckboxFoundation(adapter);
};
MDCCheckbox.prototype.createRipple_ = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = __assign({}, MDCRipple.createAdapter(this), { deregisterInteractionHandler: function (evtType, handler) { return _this.nativeControl_.removeEventListener(evtType, handler, applyPassive()); }, isSurfaceActive: function () { return matches(_this.nativeControl_, ':active'); }, isUnbounded: function () { return true; }, registerInteractionHandler: function (evtType, handler) { return _this.nativeControl_.addEventListener(evtType, handler, applyPassive()); } });
return new MDCRipple(this.root_, new MDCRippleFoundation(adapter));
};
MDCCheckbox.prototype.installPropertyChangeHooks_ = function () {
var _this = this;
var nativeCb = this.nativeControl_;
var cbProto = Object.getPrototypeOf(nativeCb);
CB_PROTO_PROPS.forEach(function (controlState) {
var desc = Object.getOwnPropertyDescriptor(cbProto, controlState);
// We have to check for this descriptor, since some browsers (Safari) don't support its return.
// See: https://bugs.webkit.org/show_bug.cgi?id=49739
if (!validDescriptor(desc)) {
return;
}
// Type cast is needed for compatibility with Closure Compiler.
var nativeGetter = desc.get;
var nativeCbDesc = {
configurable: desc.configurable,
enumerable: desc.enumerable,
get: nativeGetter,
set: function (state) {
desc.set.call(nativeCb, state);
_this.foundation_.handleChange();
},
};
Object.defineProperty(nativeCb, controlState, nativeCbDesc);
});
};
MDCCheckbox.prototype.uninstallPropertyChangeHooks_ = function () {
var nativeCb = this.nativeControl_;
var cbProto = Object.getPrototypeOf(nativeCb);
CB_PROTO_PROPS.forEach(function (controlState) {
var desc = Object.getOwnPropertyDescriptor(cbProto, controlState);
if (!validDescriptor(desc)) {
return;
}
Object.defineProperty(nativeCb, controlState, desc);
});
};
Object.defineProperty(MDCCheckbox.prototype, "nativeControl_", {
get: function () {
var NATIVE_CONTROL_SELECTOR = MDCCheckboxFoundation.strings.NATIVE_CONTROL_SELECTOR;
var el = this.root_.querySelector(NATIVE_CONTROL_SELECTOR);
if (!el) {
throw new Error("Checkbox component requires a " + NATIVE_CONTROL_SELECTOR + " element");
}
return el;
},
enumerable: true,
configurable: true
});
return MDCCheckbox;
}(MDCComponent));
function validDescriptor(inputPropDesc) {
return !!inputPropDesc && typeof inputPropDesc.set === 'function';
}
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var strings$2 = {
ARIA_CHECKED: 'aria-checked',
CHECKMARK_SELECTOR: '.mdc-chip__checkmark',
ENTRY_ANIMATION_NAME: 'mdc-chip-entry',
INTERACTION_EVENT: 'MDCChip:interaction',
LEADING_ICON_SELECTOR: '.mdc-chip__icon--leading',
REMOVAL_EVENT: 'MDCChip:removal',
SELECTION_EVENT: 'MDCChip:selection',
TRAILING_ICON_INTERACTION_EVENT: 'MDCChip:trailingIconInteraction',
TRAILING_ICON_SELECTOR: '.mdc-chip__icon--trailing',
};
var cssClasses$2 = {
CHECKMARK: 'mdc-chip__checkmark',
CHIP_EXIT: 'mdc-chip--exit',
HIDDEN_LEADING_ICON: 'mdc-chip__icon--leading-hidden',
LEADING_ICON: 'mdc-chip__icon--leading',
SELECTED: 'mdc-chip--selected',
TRAILING_ICON: 'mdc-chip__icon--trailing',
};
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var emptyClientRect = {
bottom: 0,
height: 0,
left: 0,
right: 0,
top: 0,
width: 0,
};
var MDCChipFoundation = /** @class */ (function (_super) {
__extends(MDCChipFoundation, _super);
function MDCChipFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCChipFoundation.defaultAdapter, adapter)) || this;
/**
* Whether a trailing icon click should immediately trigger exit/removal of the chip.
*/
_this.shouldRemoveOnTrailingIconClick_ = true;
return _this;
}
Object.defineProperty(MDCChipFoundation, "strings", {
get: function () {
return strings$2;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCChipFoundation, "cssClasses", {
get: function () {
return cssClasses$2;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCChipFoundation, "defaultAdapter", {
get: function () {
return {
addClass: function () { return undefined; },
addClassToLeadingIcon: function () { return undefined; },
eventTargetHasClass: function () { return false; },
getCheckmarkBoundingClientRect: function () { return emptyClientRect; },
getComputedStyleValue: function () { return ''; },
getRootBoundingClientRect: function () { return emptyClientRect; },
hasClass: function () { return false; },
hasLeadingIcon: function () { return false; },
notifyInteraction: function () { return undefined; },
notifyRemoval: function () { return undefined; },
notifySelection: function () { return undefined; },
notifyTrailingIconInteraction: function () { return undefined; },
removeClass: function () { return undefined; },
removeClassFromLeadingIcon: function () { return undefined; },
setAttr: function () { return undefined; },
setStyleProperty: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCChipFoundation.prototype.isSelected = function () {
return this.adapter_.hasClass(cssClasses$2.SELECTED);
};
MDCChipFoundation.prototype.setSelected = function (selected) {
if (selected) {
this.adapter_.addClass(cssClasses$2.SELECTED);
this.adapter_.setAttr(strings$2.ARIA_CHECKED, 'true');
}
else {
this.adapter_.removeClass(cssClasses$2.SELECTED);
this.adapter_.setAttr(strings$2.ARIA_CHECKED, 'false');
}
this.adapter_.notifySelection(selected);
};
MDCChipFoundation.prototype.getShouldRemoveOnTrailingIconClick = function () {
return this.shouldRemoveOnTrailingIconClick_;
};
MDCChipFoundation.prototype.setShouldRemoveOnTrailingIconClick = function (shouldRemove) {
this.shouldRemoveOnTrailingIconClick_ = shouldRemove;
};
MDCChipFoundation.prototype.getDimensions = function () {
var _this = this;
var getRootRect = function () { return _this.adapter_.getRootBoundingClientRect(); };
var getCheckmarkRect = function () { return _this.adapter_.getCheckmarkBoundingClientRect(); };
// When a chip has a checkmark and not a leading icon, the bounding rect changes in size depending on the current
// size of the checkmark.
if (!this.adapter_.hasLeadingIcon()) {
var checkmarkRect = getCheckmarkRect();
if (checkmarkRect) {
var rootRect = getRootRect();
// Checkmark is a square, meaning the client rect's width and height are identical once the animation completes.
// However, the checkbox is initially hidden by setting the width to 0.
// To account for an initial width of 0, we use the checkbox's height instead (which equals the end-state width)
// when adding it to the root client rect's width.
return {
bottom: rootRect.bottom,
height: rootRect.height,
left: rootRect.left,
right: rootRect.right,
top: rootRect.top,
width: rootRect.width + checkmarkRect.height,
};
}
}
return getRootRect();
};
/**
* Begins the exit animation which leads to removal of the chip.
*/
MDCChipFoundation.prototype.beginExit = function () {
this.adapter_.addClass(cssClasses$2.CHIP_EXIT);
};
/**
* Handles an interaction event on the root element.
*/
MDCChipFoundation.prototype.handleInteraction = function (evt) {
var isEnter = evt.key === 'Enter' || evt.keyCode === 13;
if (evt.type === 'click' || isEnter) {
this.adapter_.notifyInteraction();
}
};
/**
* Handles a transition end event on the root element.
*/
MDCChipFoundation.prototype.handleTransitionEnd = function (evt) {
var _this = this;
// Handle transition end event on the chip when it is about to be removed.
if (this.adapter_.eventTargetHasClass(evt.target, cssClasses$2.CHIP_EXIT)) {
if (evt.propertyName === 'width') {
this.adapter_.notifyRemoval();
}
else if (evt.propertyName === 'opacity') {
// See: https://css-tricks.com/using-css-transitions-auto-dimensions/#article-header-id-5
var chipWidth_1 = this.adapter_.getComputedStyleValue('width');
// On the next frame (once we get the computed width), explicitly set the chip's width
// to its current pixel width, so we aren't transitioning out of 'auto'.
requestAnimationFrame(function () {
_this.adapter_.setStyleProperty('width', chipWidth_1);
// To mitigate jitter, start transitioning padding and margin before width.
_this.adapter_.setStyleProperty('padding', '0');
_this.adapter_.setStyleProperty('margin', '0');
// On the next frame (once width is explicitly set), transition width to 0.
requestAnimationFrame(function () {
_this.adapter_.setStyleProperty('width', '0');
});
});
}
return;
}
// Handle a transition end event on the leading icon or checkmark, since the transition end event bubbles.
if (evt.propertyName !== 'opacity') {
return;
}
if (this.adapter_.eventTargetHasClass(evt.target, cssClasses$2.LEADING_ICON) &&
this.adapter_.hasClass(cssClasses$2.SELECTED)) {
this.adapter_.addClassToLeadingIcon(cssClasses$2.HIDDEN_LEADING_ICON);
}
else if (this.adapter_.eventTargetHasClass(evt.target, cssClasses$2.CHECKMARK) &&
!this.adapter_.hasClass(cssClasses$2.SELECTED)) {
this.adapter_.removeClassFromLeadingIcon(cssClasses$2.HIDDEN_LEADING_ICON);
}
};
/**
* Handles an interaction event on the trailing icon element. This is used to
* prevent the ripple from activating on interaction with the trailing icon.
*/
MDCChipFoundation.prototype.handleTrailingIconInteraction = function (evt) {
var isEnter = evt.key === 'Enter' || evt.keyCode === 13;
evt.stopPropagation();
if (evt.type === 'click' || isEnter) {
this.adapter_.notifyTrailingIconInteraction();
if (this.shouldRemoveOnTrailingIconClick_) {
this.beginExit();
}
}
};
return MDCChipFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var INTERACTION_EVENTS = ['click', 'keydown'];
var MDCChip = /** @class */ (function (_super) {
__extends(MDCChip, _super);
function MDCChip() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(MDCChip.prototype, "selected", {
/**
* @return Whether the chip is selected.
*/
get: function () {
return this.foundation_.isSelected();
},
/**
* Sets selected state on the chip.
*/
set: function (selected) {
this.foundation_.setSelected(selected);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCChip.prototype, "shouldRemoveOnTrailingIconClick", {
/**
* @return Whether a trailing icon click should trigger exit/removal of the chip.
*/
get: function () {
return this.foundation_.getShouldRemoveOnTrailingIconClick();
},
/**
* Sets whether a trailing icon click should trigger exit/removal of the chip.
*/
set: function (shouldRemove) {
this.foundation_.setShouldRemoveOnTrailingIconClick(shouldRemove);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCChip.prototype, "ripple", {
get: function () {
return this.ripple_;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCChip.prototype, "id", {
get: function () {
return this.root_.id;
},
enumerable: true,
configurable: true
});
MDCChip.attachTo = function (root) {
return new MDCChip(root);
};
MDCChip.prototype.initialize = function (rippleFactory) {
var _this = this;
if (rippleFactory === void 0) { rippleFactory = function (el, foundation) { return new MDCRipple(el, foundation); }; }
this.leadingIcon_ = this.root_.querySelector(strings$2.LEADING_ICON_SELECTOR);
this.trailingIcon_ = this.root_.querySelector(strings$2.TRAILING_ICON_SELECTOR);
this.checkmark_ = this.root_.querySelector(strings$2.CHECKMARK_SELECTOR);
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var rippleAdapter = __assign({}, MDCRipple.createAdapter(this), { computeBoundingRect: function () { return _this.foundation_.getDimensions(); } });
this.ripple_ = rippleFactory(this.root_, new MDCRippleFoundation(rippleAdapter));
};
MDCChip.prototype.initialSyncWithDOM = function () {
var _this = this;
this.handleInteraction_ = function (evt) { return _this.foundation_.handleInteraction(evt); };
this.handleTransitionEnd_ = function (evt) { return _this.foundation_.handleTransitionEnd(evt); };
this.handleTrailingIconInteraction_ = function (evt) {
return _this.foundation_.handleTrailingIconInteraction(evt);
};
INTERACTION_EVENTS.forEach(function (evtType) {
_this.listen(evtType, _this.handleInteraction_);
});
this.listen('transitionend', this.handleTransitionEnd_);
if (this.trailingIcon_) {
INTERACTION_EVENTS.forEach(function (evtType) {
_this.trailingIcon_.addEventListener(evtType, _this.handleTrailingIconInteraction_);
});
}
};
MDCChip.prototype.destroy = function () {
var _this = this;
this.ripple_.destroy();
INTERACTION_EVENTS.forEach(function (evtType) {
_this.unlisten(evtType, _this.handleInteraction_);
});
this.unlisten('transitionend', this.handleTransitionEnd_);
if (this.trailingIcon_) {
INTERACTION_EVENTS.forEach(function (evtType) {
_this.trailingIcon_.removeEventListener(evtType, _this.handleTrailingIconInteraction_);
});
}
_super.prototype.destroy.call(this);
};
/**
* Begins the exit animation which leads to removal of the chip.
*/
MDCChip.prototype.beginExit = function () {
this.foundation_.beginExit();
};
MDCChip.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
addClassToLeadingIcon: function (className) {
if (_this.leadingIcon_) {
_this.leadingIcon_.classList.add(className);
}
},
eventTargetHasClass: function (target, className) { return target ? target.classList.contains(className) : false; },
getCheckmarkBoundingClientRect: function () { return _this.checkmark_ ? _this.checkmark_.getBoundingClientRect() : null; },
getComputedStyleValue: function (propertyName) { return window.getComputedStyle(_this.root_).getPropertyValue(propertyName); },
getRootBoundingClientRect: function () { return _this.root_.getBoundingClientRect(); },
hasClass: function (className) { return _this.root_.classList.contains(className); },
hasLeadingIcon: function () { return !!_this.leadingIcon_; },
notifyInteraction: function () { return _this.emit(strings$2.INTERACTION_EVENT, { chipId: _this.id }, true /* shouldBubble */); },
notifyRemoval: function () { return _this.emit(strings$2.REMOVAL_EVENT, { chipId: _this.id, root: _this.root_ }, true /* shouldBubble */); },
notifySelection: function (selected) { return _this.emit(strings$2.SELECTION_EVENT, { chipId: _this.id, selected: selected }, true /* shouldBubble */); },
notifyTrailingIconInteraction: function () { return _this.emit(strings$2.TRAILING_ICON_INTERACTION_EVENT, { chipId: _this.id }, true /* shouldBubble */); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
removeClassFromLeadingIcon: function (className) {
if (_this.leadingIcon_) {
_this.leadingIcon_.classList.remove(className);
}
},
setAttr: function (attr, value) { return _this.root_.setAttribute(attr, value); },
setStyleProperty: function (propertyName, value) { return _this.root_.style.setProperty(propertyName, value); },
};
return new MDCChipFoundation(adapter);
};
return MDCChip;
}(MDCComponent));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var strings$3 = {
CHIP_SELECTOR: '.mdc-chip',
};
var cssClasses$3 = {
CHOICE: 'mdc-chip-set--choice',
FILTER: 'mdc-chip-set--filter',
};
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCChipSetFoundation = /** @class */ (function (_super) {
__extends(MDCChipSetFoundation, _super);
function MDCChipSetFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCChipSetFoundation.defaultAdapter, adapter)) || this;
/**
* The ids of the selected chips in the set. Only used for choice chip set or filter chip set.
*/
_this.selectedChipIds_ = [];
return _this;
}
Object.defineProperty(MDCChipSetFoundation, "strings", {
get: function () {
return strings$3;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCChipSetFoundation, "cssClasses", {
get: function () {
return cssClasses$3;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCChipSetFoundation, "defaultAdapter", {
get: function () {
return {
hasClass: function () { return false; },
removeChip: function () { return undefined; },
setSelected: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
/**
* Returns an array of the IDs of all selected chips.
*/
MDCChipSetFoundation.prototype.getSelectedChipIds = function () {
return this.selectedChipIds_.slice();
};
/**
* Selects the chip with the given id. Deselects all other chips if the chip set is of the choice variant.
*/
MDCChipSetFoundation.prototype.select = function (chipId) {
if (this.selectedChipIds_.indexOf(chipId) >= 0) {
return;
}
if (this.adapter_.hasClass(cssClasses$3.CHOICE) && this.selectedChipIds_.length > 0) {
var previouslySelectedChip = this.selectedChipIds_[0];
this.selectedChipIds_.length = 0;
this.adapter_.setSelected(previouslySelectedChip, false);
}
this.selectedChipIds_.push(chipId);
this.adapter_.setSelected(chipId, true);
};
/**
* Handles a chip interaction event
*/
MDCChipSetFoundation.prototype.handleChipInteraction = function (chipId) {
if (this.adapter_.hasClass(cssClasses$3.CHOICE) || this.adapter_.hasClass(cssClasses$3.FILTER)) {
this.toggleSelect_(chipId);
}
};
/**
* Handles a chip selection event, used to handle discrepancy when selection state is set directly on the Chip.
*/
MDCChipSetFoundation.prototype.handleChipSelection = function (chipId, selected) {
var chipIsSelected = this.selectedChipIds_.indexOf(chipId) >= 0;
if (selected && !chipIsSelected) {
this.select(chipId);
}
else if (!selected && chipIsSelected) {
this.deselect_(chipId);
}
};
/**
* Handles the event when a chip is removed.
*/
MDCChipSetFoundation.prototype.handleChipRemoval = function (chipId) {
this.deselect_(chipId);
this.adapter_.removeChip(chipId);
};
/**
* Deselects the chip with the given id.
*/
MDCChipSetFoundation.prototype.deselect_ = function (chipId) {
var index = this.selectedChipIds_.indexOf(chipId);
if (index >= 0) {
this.selectedChipIds_.splice(index, 1);
this.adapter_.setSelected(chipId, false);
}
};
/**
* Toggles selection of the chip with the given id.
*/
MDCChipSetFoundation.prototype.toggleSelect_ = function (chipId) {
if (this.selectedChipIds_.indexOf(chipId) >= 0) {
this.deselect_(chipId);
}
else {
this.select(chipId);
}
};
return MDCChipSetFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var _a = MDCChipFoundation.strings, INTERACTION_EVENT = _a.INTERACTION_EVENT, SELECTION_EVENT = _a.SELECTION_EVENT, REMOVAL_EVENT = _a.REMOVAL_EVENT;
var CHIP_SELECTOR = MDCChipSetFoundation.strings.CHIP_SELECTOR;
var idCounter = 0;
var MDCChipSet = /** @class */ (function (_super) {
__extends(MDCChipSet, _super);
function MDCChipSet() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCChipSet.attachTo = function (root) {
return new MDCChipSet(root);
};
Object.defineProperty(MDCChipSet.prototype, "chips", {
get: function () {
return this.chips_.slice();
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCChipSet.prototype, "selectedChipIds", {
/**
* @return An array of the IDs of all selected chips.
*/
get: function () {
return this.foundation_.getSelectedChipIds();
},
enumerable: true,
configurable: true
});
/**
* @param chipFactory A function which creates a new MDCChip.
*/
MDCChipSet.prototype.initialize = function (chipFactory) {
if (chipFactory === void 0) { chipFactory = function (el) { return new MDCChip(el); }; }
this.chipFactory_ = chipFactory;
this.chips_ = this.instantiateChips_(this.chipFactory_);
};
MDCChipSet.prototype.initialSyncWithDOM = function () {
var _this = this;
this.chips_.forEach(function (chip) {
if (chip.id && chip.selected) {
_this.foundation_.select(chip.id);
}
});
this.handleChipInteraction_ = function (evt) { return _this.foundation_.handleChipInteraction(evt.detail.chipId); };
this.handleChipSelection_ = function (evt) { return _this.foundation_.handleChipSelection(evt.detail.chipId, evt.detail.selected); };
this.handleChipRemoval_ = function (evt) { return _this.foundation_.handleChipRemoval(evt.detail.chipId); };
this.listen(INTERACTION_EVENT, this.handleChipInteraction_);
this.listen(SELECTION_EVENT, this.handleChipSelection_);
this.listen(REMOVAL_EVENT, this.handleChipRemoval_);
};
MDCChipSet.prototype.destroy = function () {
this.chips_.forEach(function (chip) {
chip.destroy();
});
this.unlisten(INTERACTION_EVENT, this.handleChipInteraction_);
this.unlisten(SELECTION_EVENT, this.handleChipSelection_);
this.unlisten(REMOVAL_EVENT, this.handleChipRemoval_);
_super.prototype.destroy.call(this);
};
/**
* Adds a new chip object to the chip set from the given chip element.
*/
MDCChipSet.prototype.addChip = function (chipEl) {
chipEl.id = chipEl.id || "mdc-chip-" + ++idCounter;
this.chips_.push(this.chipFactory_(chipEl));
};
MDCChipSet.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = {
hasClass: function (className) { return _this.root_.classList.contains(className); },
removeChip: function (chipId) {
var index = _this.findChipIndex_(chipId);
if (index >= 0) {
_this.chips_[index].destroy();
_this.chips_.splice(index, 1);
}
},
setSelected: function (chipId, selected) {
var index = _this.findChipIndex_(chipId);
if (index >= 0) {
_this.chips_[index].selected = selected;
}
},
};
return new MDCChipSetFoundation(adapter);
};
/**
* Instantiates chip components on all of the chip set's child chip elements.
*/
MDCChipSet.prototype.instantiateChips_ = function (chipFactory) {
var chipElements = [].slice.call(this.root_.querySelectorAll(CHIP_SELECTOR));
return chipElements.map(function (el) {
el.id = el.id || "mdc-chip-" + ++idCounter;
return chipFactory(el);
});
};
/**
* Returns the index of the chip with the given id, or -1 if the chip does not exist.
*/
MDCChipSet.prototype.findChipIndex_ = function (chipId) {
for (var i = 0; i < this.chips_.length; i++) {
if (this.chips_[i].id === chipId) {
return i;
}
}
return -1;
};
return MDCChipSet;
}(MDCComponent));
var candidateSelectors = [
'input',
'select',
'textarea',
'a[href]',
'button',
'[tabindex]',
'audio[controls]',
'video[controls]',
'[contenteditable]:not([contenteditable="false"])',
];
var candidateSelector = candidateSelectors.join(',');
var matches$1 = typeof Element === 'undefined'
? function () {}
: Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
function tabbable(el, options) {
options = options || {};
var regularTabbables = [];
var orderedTabbables = [];
var candidates = el.querySelectorAll(candidateSelector);
if (options.includeContainer) {
if (matches$1.call(el, candidateSelector)) {
candidates = Array.prototype.slice.apply(candidates);
candidates.unshift(el);
}
}
var i, candidate, candidateTabindex;
for (i = 0; i < candidates.length; i++) {
candidate = candidates[i];
if (!isNodeMatchingSelectorTabbable(candidate)) continue;
candidateTabindex = getTabindex(candidate);
if (candidateTabindex === 0) {
regularTabbables.push(candidate);
} else {
orderedTabbables.push({
documentOrder: i,
tabIndex: candidateTabindex,
node: candidate,
});
}
}
var tabbableNodes = orderedTabbables
.sort(sortOrderedTabbables)
.map(function(a) { return a.node })
.concat(regularTabbables);
return tabbableNodes;
}
tabbable.isTabbable = isTabbable;
tabbable.isFocusable = isFocusable;
function isNodeMatchingSelectorTabbable(node) {
if (
!isNodeMatchingSelectorFocusable(node)
|| isNonTabbableRadio(node)
|| getTabindex(node) < 0
) {
return false;
}
return true;
}
function isTabbable(node) {
if (!node) throw new Error('No node provided');
if (matches$1.call(node, candidateSelector) === false) return false;
return isNodeMatchingSelectorTabbable(node);
}
function isNodeMatchingSelectorFocusable(node) {
if (
node.disabled
|| isHiddenInput(node)
|| isHidden(node)
) {
return false;
}
return true;
}
var focusableCandidateSelector = candidateSelectors.concat('iframe').join(',');
function isFocusable(node) {
if (!node) throw new Error('No node provided');
if (matches$1.call(node, focusableCandidateSelector) === false) return false;
return isNodeMatchingSelectorFocusable(node);
}
function getTabindex(node) {
var tabindexAttr = parseInt(node.getAttribute('tabindex'), 10);
if (!isNaN(tabindexAttr)) return tabindexAttr;
// Browsers do not return `tabIndex` correctly for contentEditable nodes;
// so if they don't have a tabindex attribute specifically set, assume it's 0.
if (isContentEditable(node)) return 0;
return node.tabIndex;
}
function sortOrderedTabbables(a, b) {
return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex;
}
function isContentEditable(node) {
return node.contentEditable === 'true';
}
function isInput(node) {
return node.tagName === 'INPUT';
}
function isHiddenInput(node) {
return isInput(node) && node.type === 'hidden';
}
function isRadio(node) {
return isInput(node) && node.type === 'radio';
}
function isNonTabbableRadio(node) {
return isRadio(node) && !isTabbableRadio(node);
}
function getCheckedRadio(nodes) {
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].checked) {
return nodes[i];
}
}
}
function isTabbableRadio(node) {
if (!node.name) return true;
// This won't account for the edge case where you have radio groups with the same
// in separate forms on the same page.
var radioSet = node.ownerDocument.querySelectorAll('input[type="radio"][name="' + node.name + '"]');
var checked = getCheckedRadio(radioSet);
return !checked || checked === node;
}
function isHidden(node) {
// offsetParent being null will allow detecting cases where an element is invisible or inside an invisible element,
// as long as the element does not use position: fixed. For them, their visibility has to be checked directly as well.
return node.offsetParent === null || getComputedStyle(node).visibility === 'hidden';
}
var tabbable_1 = tabbable;
var immutable = extend;
var hasOwnProperty = Object.prototype.hasOwnProperty;
function extend() {
var target = {};
for (var i = 0; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target
}
var activeFocusDelay;
var activeFocusTraps = (function() {
var trapQueue = [];
return {
activateTrap: function(trap) {
if (trapQueue.length > 0) {
var activeTrap = trapQueue[trapQueue.length - 1];
if (activeTrap !== trap) {
activeTrap.pause();
}
}
var trapIndex = trapQueue.indexOf(trap);
if (trapIndex === -1) {
trapQueue.push(trap);
} else {
// move this existing trap to the front of the queue
trapQueue.splice(trapIndex, 1);
trapQueue.push(trap);
}
},
deactivateTrap: function(trap) {
var trapIndex = trapQueue.indexOf(trap);
if (trapIndex !== -1) {
trapQueue.splice(trapIndex, 1);
}
if (trapQueue.length > 0) {
trapQueue[trapQueue.length - 1].unpause();
}
}
};
})();
function focusTrap(element, userOptions) {
var doc = document;
var container =
typeof element === 'string' ? doc.querySelector(element) : element;
var config = immutable(
{
returnFocusOnDeactivate: true,
escapeDeactivates: true
},
userOptions
);
var state = {
firstTabbableNode: null,
lastTabbableNode: null,
nodeFocusedBeforeActivation: null,
mostRecentlyFocusedNode: null,
active: false,
paused: false
};
var trap = {
activate: activate,
deactivate: deactivate,
pause: pause,
unpause: unpause
};
return trap;
function activate(activateOptions) {
if (state.active) return;
updateTabbableNodes();
state.active = true;
state.paused = false;
state.nodeFocusedBeforeActivation = doc.activeElement;
var onActivate =
activateOptions && activateOptions.onActivate
? activateOptions.onActivate
: config.onActivate;
if (onActivate) {
onActivate();
}
addListeners();
return trap;
}
function deactivate(deactivateOptions) {
if (!state.active) return;
clearTimeout(activeFocusDelay);
removeListeners();
state.active = false;
state.paused = false;
activeFocusTraps.deactivateTrap(trap);
var onDeactivate =
deactivateOptions && deactivateOptions.onDeactivate !== undefined
? deactivateOptions.onDeactivate
: config.onDeactivate;
if (onDeactivate) {
onDeactivate();
}
var returnFocus =
deactivateOptions && deactivateOptions.returnFocus !== undefined
? deactivateOptions.returnFocus
: config.returnFocusOnDeactivate;
if (returnFocus) {
delay(function() {
tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
});
}
return trap;
}
function pause() {
if (state.paused || !state.active) return;
state.paused = true;
removeListeners();
}
function unpause() {
if (!state.paused || !state.active) return;
state.paused = false;
updateTabbableNodes();
addListeners();
}
function addListeners() {
if (!state.active) return;
// There can be only one listening focus trap at a time
activeFocusTraps.activateTrap(trap);
// Delay ensures that the focused element doesn't capture the event
// that caused the focus trap activation.
activeFocusDelay = delay(function() {
tryFocus(getInitialFocusNode());
});
doc.addEventListener('focusin', checkFocusIn, true);
doc.addEventListener('mousedown', checkPointerDown, {
capture: true,
passive: false
});
doc.addEventListener('touchstart', checkPointerDown, {
capture: true,
passive: false
});
doc.addEventListener('click', checkClick, {
capture: true,
passive: false
});
doc.addEventListener('keydown', checkKey, {
capture: true,
passive: false
});
return trap;
}
function removeListeners() {
if (!state.active) return;
doc.removeEventListener('focusin', checkFocusIn, true);
doc.removeEventListener('mousedown', checkPointerDown, true);
doc.removeEventListener('touchstart', checkPointerDown, true);
doc.removeEventListener('click', checkClick, true);
doc.removeEventListener('keydown', checkKey, true);
return trap;
}
function getNodeForOption(optionName) {
var optionValue = config[optionName];
var node = optionValue;
if (!optionValue) {
return null;
}
if (typeof optionValue === 'string') {
node = doc.querySelector(optionValue);
if (!node) {
throw new Error('`' + optionName + '` refers to no known node');
}
}
if (typeof optionValue === 'function') {
node = optionValue();
if (!node) {
throw new Error('`' + optionName + '` did not return a node');
}
}
return node;
}
function getInitialFocusNode() {
var node;
if (getNodeForOption('initialFocus') !== null) {
node = getNodeForOption('initialFocus');
} else if (container.contains(doc.activeElement)) {
node = doc.activeElement;
} else {
node = state.firstTabbableNode || getNodeForOption('fallbackFocus');
}
if (!node) {
throw new Error(
'Your focus-trap needs to have at least one focusable element'
);
}
return node;
}
function getReturnFocusNode(previousActiveElement) {
var node = getNodeForOption('setReturnFocus');
return node ? node : previousActiveElement;
}
// This needs to be done on mousedown and touchstart instead of click
// so that it precedes the focus event.
function checkPointerDown(e) {
if (container.contains(e.target)) return;
if (config.clickOutsideDeactivates) {
deactivate({
returnFocus: !tabbable_1.isFocusable(e.target)
});
return;
}
// This is needed for mobile devices.
// (If we'll only let `click` events through,
// then on mobile they will be blocked anyways if `touchstart` is blocked.)
if (config.allowOutsideClick && config.allowOutsideClick(e)) {
return;
}
e.preventDefault();
}
// In case focus escapes the trap for some strange reason, pull it back in.
function checkFocusIn(e) {
// In Firefox when you Tab out of an iframe the Document is briefly focused.
if (container.contains(e.target) || e.target instanceof Document) {
return;
}
e.stopImmediatePropagation();
tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
}
function checkKey(e) {
if (config.escapeDeactivates !== false && isEscapeEvent(e)) {
e.preventDefault();
deactivate();
return;
}
if (isTabEvent(e)) {
checkTab(e);
return;
}
}
// Hijack Tab events on the first and last focusable nodes of the trap,
// in order to prevent focus from escaping. If it escapes for even a
// moment it can end up scrolling the page and causing confusion so we
// kind of need to capture the action at the keydown phase.
function checkTab(e) {
updateTabbableNodes();
if (e.shiftKey && e.target === state.firstTabbableNode) {
e.preventDefault();
tryFocus(state.lastTabbableNode);
return;
}
if (!e.shiftKey && e.target === state.lastTabbableNode) {
e.preventDefault();
tryFocus(state.firstTabbableNode);
return;
}
}
function checkClick(e) {
if (config.clickOutsideDeactivates) return;
if (container.contains(e.target)) return;
if (config.allowOutsideClick && config.allowOutsideClick(e)) {
return;
}
e.preventDefault();
e.stopImmediatePropagation();
}
function updateTabbableNodes() {
var tabbableNodes = tabbable_1(container);
state.firstTabbableNode = tabbableNodes[0] || getInitialFocusNode();
state.lastTabbableNode =
tabbableNodes[tabbableNodes.length - 1] || getInitialFocusNode();
}
function tryFocus(node) {
if (node === doc.activeElement) return;
if (!node || !node.focus) {
tryFocus(getInitialFocusNode());
return;
}
node.focus();
state.mostRecentlyFocusedNode = node;
if (isSelectableInput(node)) {
node.select();
}
}
}
function isSelectableInput(node) {
return (
node.tagName &&
node.tagName.toLowerCase() === 'input' &&
typeof node.select === 'function'
);
}
function isEscapeEvent(e) {
return e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27;
}
function isTabEvent(e) {
return e.key === 'Tab' || e.keyCode === 9;
}
function delay(fn) {
return setTimeout(fn, 0);
}
var focusTrap_1 = focusTrap;
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
function createFocusTrapInstance(surfaceEl, focusTrapFactory, initialFocusEl) {
if (focusTrapFactory === void 0) { focusTrapFactory = focusTrap_1; }
return focusTrapFactory(surfaceEl, {
clickOutsideDeactivates: true,
escapeDeactivates: false,
initialFocus: initialFocusEl,
});
}
function isScrollable(el) {
return el ? el.scrollHeight > el.offsetHeight : false;
}
function areTopsMisaligned(els) {
var tops = new Set();
[].forEach.call(els, function (el) { return tops.add(el.offsetTop); });
return tops.size > 1;
}
var util = /*#__PURE__*/Object.freeze({
__proto__: null,
createFocusTrapInstance: createFocusTrapInstance,
isScrollable: isScrollable,
areTopsMisaligned: areTopsMisaligned
});
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$4 = {
CLOSING: 'mdc-dialog--closing',
OPEN: 'mdc-dialog--open',
OPENING: 'mdc-dialog--opening',
SCROLLABLE: 'mdc-dialog--scrollable',
SCROLL_LOCK: 'mdc-dialog-scroll-lock',
STACKED: 'mdc-dialog--stacked',
};
var strings$4 = {
ACTION_ATTRIBUTE: 'data-mdc-dialog-action',
BUTTON_DEFAULT_ATTRIBUTE: 'data-mdc-dialog-button-default',
BUTTON_SELECTOR: '.mdc-dialog__button',
CLOSED_EVENT: 'MDCDialog:closed',
CLOSE_ACTION: 'close',
CLOSING_EVENT: 'MDCDialog:closing',
CONTAINER_SELECTOR: '.mdc-dialog__container',
CONTENT_SELECTOR: '.mdc-dialog__content',
DESTROY_ACTION: 'destroy',
INITIAL_FOCUS_ATTRIBUTE: 'data-mdc-dialog-initial-focus',
OPENED_EVENT: 'MDCDialog:opened',
OPENING_EVENT: 'MDCDialog:opening',
SCRIM_SELECTOR: '.mdc-dialog__scrim',
SUPPRESS_DEFAULT_PRESS_SELECTOR: [
'textarea',
'.mdc-menu .mdc-list-item',
].join(', '),
SURFACE_SELECTOR: '.mdc-dialog__surface',
};
var numbers$2 = {
DIALOG_ANIMATION_CLOSE_TIME_MS: 75,
DIALOG_ANIMATION_OPEN_TIME_MS: 150,
};
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCDialogFoundation = /** @class */ (function (_super) {
__extends(MDCDialogFoundation, _super);
function MDCDialogFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCDialogFoundation.defaultAdapter, adapter)) || this;
_this.isOpen_ = false;
_this.animationFrame_ = 0;
_this.animationTimer_ = 0;
_this.layoutFrame_ = 0;
_this.escapeKeyAction_ = strings$4.CLOSE_ACTION;
_this.scrimClickAction_ = strings$4.CLOSE_ACTION;
_this.autoStackButtons_ = true;
_this.areButtonsStacked_ = false;
return _this;
}
Object.defineProperty(MDCDialogFoundation, "cssClasses", {
get: function () {
return cssClasses$4;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCDialogFoundation, "strings", {
get: function () {
return strings$4;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCDialogFoundation, "numbers", {
get: function () {
return numbers$2;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCDialogFoundation, "defaultAdapter", {
get: function () {
return {
addBodyClass: function () { return undefined; },
addClass: function () { return undefined; },
areButtonsStacked: function () { return false; },
clickDefaultButton: function () { return undefined; },
eventTargetMatches: function () { return false; },
getActionFromEvent: function () { return ''; },
getInitialFocusEl: function () { return null; },
hasClass: function () { return false; },
isContentScrollable: function () { return false; },
notifyClosed: function () { return undefined; },
notifyClosing: function () { return undefined; },
notifyOpened: function () { return undefined; },
notifyOpening: function () { return undefined; },
releaseFocus: function () { return undefined; },
removeBodyClass: function () { return undefined; },
removeClass: function () { return undefined; },
reverseButtons: function () { return undefined; },
trapFocus: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCDialogFoundation.prototype.init = function () {
if (this.adapter_.hasClass(cssClasses$4.STACKED)) {
this.setAutoStackButtons(false);
}
};
MDCDialogFoundation.prototype.destroy = function () {
if (this.isOpen_) {
this.close(strings$4.DESTROY_ACTION);
}
if (this.animationTimer_) {
clearTimeout(this.animationTimer_);
this.handleAnimationTimerEnd_();
}
if (this.layoutFrame_) {
cancelAnimationFrame(this.layoutFrame_);
this.layoutFrame_ = 0;
}
};
MDCDialogFoundation.prototype.open = function () {
var _this = this;
this.isOpen_ = true;
this.adapter_.notifyOpening();
this.adapter_.addClass(cssClasses$4.OPENING);
// Wait a frame once display is no longer "none", to establish basis for animation
this.runNextAnimationFrame_(function () {
_this.adapter_.addClass(cssClasses$4.OPEN);
_this.adapter_.addBodyClass(cssClasses$4.SCROLL_LOCK);
_this.layout();
_this.animationTimer_ = setTimeout(function () {
_this.handleAnimationTimerEnd_();
_this.adapter_.trapFocus(_this.adapter_.getInitialFocusEl());
_this.adapter_.notifyOpened();
}, numbers$2.DIALOG_ANIMATION_OPEN_TIME_MS);
});
};
MDCDialogFoundation.prototype.close = function (action) {
var _this = this;
if (action === void 0) { action = ''; }
if (!this.isOpen_) {
// Avoid redundant close calls (and events), e.g. from keydown on elements that inherently emit click
return;
}
this.isOpen_ = false;
this.adapter_.notifyClosing(action);
this.adapter_.addClass(cssClasses$4.CLOSING);
this.adapter_.removeClass(cssClasses$4.OPEN);
this.adapter_.removeBodyClass(cssClasses$4.SCROLL_LOCK);
cancelAnimationFrame(this.animationFrame_);
this.animationFrame_ = 0;
clearTimeout(this.animationTimer_);
this.animationTimer_ = setTimeout(function () {
_this.adapter_.releaseFocus();
_this.handleAnimationTimerEnd_();
_this.adapter_.notifyClosed(action);
}, numbers$2.DIALOG_ANIMATION_CLOSE_TIME_MS);
};
MDCDialogFoundation.prototype.isOpen = function () {
return this.isOpen_;
};
MDCDialogFoundation.prototype.getEscapeKeyAction = function () {
return this.escapeKeyAction_;
};
MDCDialogFoundation.prototype.setEscapeKeyAction = function (action) {
this.escapeKeyAction_ = action;
};
MDCDialogFoundation.prototype.getScrimClickAction = function () {
return this.scrimClickAction_;
};
MDCDialogFoundation.prototype.setScrimClickAction = function (action) {
this.scrimClickAction_ = action;
};
MDCDialogFoundation.prototype.getAutoStackButtons = function () {
return this.autoStackButtons_;
};
MDCDialogFoundation.prototype.setAutoStackButtons = function (autoStack) {
this.autoStackButtons_ = autoStack;
};
MDCDialogFoundation.prototype.layout = function () {
var _this = this;
if (this.layoutFrame_) {
cancelAnimationFrame(this.layoutFrame_);
}
this.layoutFrame_ = requestAnimationFrame(function () {
_this.layoutInternal_();
_this.layoutFrame_ = 0;
});
};
/** Handles click on the dialog root element. */
MDCDialogFoundation.prototype.handleClick = function (evt) {
var isScrim = this.adapter_.eventTargetMatches(evt.target, strings$4.SCRIM_SELECTOR);
// Check for scrim click first since it doesn't require querying ancestors.
if (isScrim && this.scrimClickAction_ !== '') {
this.close(this.scrimClickAction_);
}
else {
var action = this.adapter_.getActionFromEvent(evt);
if (action) {
this.close(action);
}
}
};
/** Handles keydown on the dialog root element. */
MDCDialogFoundation.prototype.handleKeydown = function (evt) {
var isEnter = evt.key === 'Enter' || evt.keyCode === 13;
if (!isEnter) {
return;
}
var action = this.adapter_.getActionFromEvent(evt);
if (action) {
// Action button callback is handled in `handleClick`,
// since space/enter keydowns on buttons trigger click events.
return;
}
var isDefault = !this.adapter_.eventTargetMatches(evt.target, strings$4.SUPPRESS_DEFAULT_PRESS_SELECTOR);
if (isEnter && isDefault) {
this.adapter_.clickDefaultButton();
}
};
/** Handles keydown on the document. */
MDCDialogFoundation.prototype.handleDocumentKeydown = function (evt) {
var isEscape = evt.key === 'Escape' || evt.keyCode === 27;
if (isEscape && this.escapeKeyAction_ !== '') {
this.close(this.escapeKeyAction_);
}
};
MDCDialogFoundation.prototype.layoutInternal_ = function () {
if (this.autoStackButtons_) {
this.detectStackedButtons_();
}
this.detectScrollableContent_();
};
MDCDialogFoundation.prototype.handleAnimationTimerEnd_ = function () {
this.animationTimer_ = 0;
this.adapter_.removeClass(cssClasses$4.OPENING);
this.adapter_.removeClass(cssClasses$4.CLOSING);
};
/**
* Runs the given logic on the next animation frame, using setTimeout to factor in Firefox reflow behavior.
*/
MDCDialogFoundation.prototype.runNextAnimationFrame_ = function (callback) {
var _this = this;
cancelAnimationFrame(this.animationFrame_);
this.animationFrame_ = requestAnimationFrame(function () {
_this.animationFrame_ = 0;
clearTimeout(_this.animationTimer_);
_this.animationTimer_ = setTimeout(callback, 0);
});
};
MDCDialogFoundation.prototype.detectStackedButtons_ = function () {
// Remove the class first to let us measure the buttons' natural positions.
this.adapter_.removeClass(cssClasses$4.STACKED);
var areButtonsStacked = this.adapter_.areButtonsStacked();
if (areButtonsStacked) {
this.adapter_.addClass(cssClasses$4.STACKED);
}
if (areButtonsStacked !== this.areButtonsStacked_) {
this.adapter_.reverseButtons();
this.areButtonsStacked_ = areButtonsStacked;
}
};
MDCDialogFoundation.prototype.detectScrollableContent_ = function () {
// Remove the class first to let us measure the natural height of the content.
this.adapter_.removeClass(cssClasses$4.SCROLLABLE);
if (this.adapter_.isContentScrollable()) {
this.adapter_.addClass(cssClasses$4.SCROLLABLE);
}
};
return MDCDialogFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var strings$5 = MDCDialogFoundation.strings;
var MDCDialog = /** @class */ (function (_super) {
__extends(MDCDialog, _super);
function MDCDialog() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(MDCDialog.prototype, "isOpen", {
get: function () {
return this.foundation_.isOpen();
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCDialog.prototype, "escapeKeyAction", {
get: function () {
return this.foundation_.getEscapeKeyAction();
},
set: function (action) {
this.foundation_.setEscapeKeyAction(action);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCDialog.prototype, "scrimClickAction", {
get: function () {
return this.foundation_.getScrimClickAction();
},
set: function (action) {
this.foundation_.setScrimClickAction(action);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCDialog.prototype, "autoStackButtons", {
get: function () {
return this.foundation_.getAutoStackButtons();
},
set: function (autoStack) {
this.foundation_.setAutoStackButtons(autoStack);
},
enumerable: true,
configurable: true
});
MDCDialog.attachTo = function (root) {
return new MDCDialog(root);
};
MDCDialog.prototype.initialize = function (focusTrapFactory) {
var e_1, _a;
var container = this.root_.querySelector(strings$5.CONTAINER_SELECTOR);
if (!container) {
throw new Error("Dialog component requires a " + strings$5.CONTAINER_SELECTOR + " container element");
}
this.container_ = container;
this.content_ = this.root_.querySelector(strings$5.CONTENT_SELECTOR);
this.buttons_ = [].slice.call(this.root_.querySelectorAll(strings$5.BUTTON_SELECTOR));
this.defaultButton_ = this.root_.querySelector("[" + strings$5.BUTTON_DEFAULT_ATTRIBUTE + "]");
this.focusTrapFactory_ = focusTrapFactory;
this.buttonRipples_ = [];
try {
for (var _b = __values(this.buttons_), _c = _b.next(); !_c.done; _c = _b.next()) {
var buttonEl = _c.value;
this.buttonRipples_.push(new MDCRipple(buttonEl));
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
};
MDCDialog.prototype.initialSyncWithDOM = function () {
var _this = this;
this.focusTrap_ = createFocusTrapInstance(this.container_, this.focusTrapFactory_, this.getInitialFocusEl_() || undefined);
this.handleClick_ = this.foundation_.handleClick.bind(this.foundation_);
this.handleKeydown_ = this.foundation_.handleKeydown.bind(this.foundation_);
this.handleDocumentKeydown_ = this.foundation_.handleDocumentKeydown.bind(this.foundation_);
this.handleLayout_ = this.layout.bind(this);
var LAYOUT_EVENTS = ['resize', 'orientationchange'];
this.handleOpening_ = function () {
LAYOUT_EVENTS.forEach(function (evtType) { return window.addEventListener(evtType, _this.handleLayout_); });
document.addEventListener('keydown', _this.handleDocumentKeydown_);
};
this.handleClosing_ = function () {
LAYOUT_EVENTS.forEach(function (evtType) { return window.removeEventListener(evtType, _this.handleLayout_); });
document.removeEventListener('keydown', _this.handleDocumentKeydown_);
};
this.listen('click', this.handleClick_);
this.listen('keydown', this.handleKeydown_);
this.listen(strings$5.OPENING_EVENT, this.handleOpening_);
this.listen(strings$5.CLOSING_EVENT, this.handleClosing_);
};
MDCDialog.prototype.destroy = function () {
this.unlisten('click', this.handleClick_);
this.unlisten('keydown', this.handleKeydown_);
this.unlisten(strings$5.OPENING_EVENT, this.handleOpening_);
this.unlisten(strings$5.CLOSING_EVENT, this.handleClosing_);
this.handleClosing_();
this.buttonRipples_.forEach(function (ripple) { return ripple.destroy(); });
_super.prototype.destroy.call(this);
};
MDCDialog.prototype.layout = function () {
this.foundation_.layout();
};
MDCDialog.prototype.open = function () {
this.foundation_.open();
};
MDCDialog.prototype.close = function (action) {
if (action === void 0) { action = ''; }
this.foundation_.close(action);
};
MDCDialog.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = {
addBodyClass: function (className) { return document.body.classList.add(className); },
addClass: function (className) { return _this.root_.classList.add(className); },
areButtonsStacked: function () { return areTopsMisaligned(_this.buttons_); },
clickDefaultButton: function () { return _this.defaultButton_ && _this.defaultButton_.click(); },
eventTargetMatches: function (target, selector) { return target ? matches(target, selector) : false; },
getActionFromEvent: function (evt) {
if (!evt.target) {
return '';
}
var element = closest(evt.target, "[" + strings$5.ACTION_ATTRIBUTE + "]");
return element && element.getAttribute(strings$5.ACTION_ATTRIBUTE);
},
getInitialFocusEl: function () { return _this.getInitialFocusEl_(); },
hasClass: function (className) { return _this.root_.classList.contains(className); },
isContentScrollable: function () { return isScrollable(_this.content_); },
notifyClosed: function (action) { return _this.emit(strings$5.CLOSED_EVENT, action ? { action: action } : {}); },
notifyClosing: function (action) { return _this.emit(strings$5.CLOSING_EVENT, action ? { action: action } : {}); },
notifyOpened: function () { return _this.emit(strings$5.OPENED_EVENT, {}); },
notifyOpening: function () { return _this.emit(strings$5.OPENING_EVENT, {}); },
releaseFocus: function () { return _this.focusTrap_.deactivate(); },
removeBodyClass: function (className) { return document.body.classList.remove(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
reverseButtons: function () {
_this.buttons_.reverse();
_this.buttons_.forEach(function (button) {
button.parentElement.appendChild(button);
});
},
trapFocus: function () { return _this.focusTrap_.activate(); },
};
return new MDCDialogFoundation(adapter);
};
MDCDialog.prototype.getInitialFocusEl_ = function () {
return document.querySelector("[" + strings$5.INITIAL_FOCUS_ATTRIBUTE + "]");
};
return MDCDialog;
}(MDCComponent));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
function createFocusTrapInstance$1(surfaceEl, focusTrapFactory) {
if (focusTrapFactory === void 0) { focusTrapFactory = focusTrap_1; }
return focusTrapFactory(surfaceEl, {
clickOutsideDeactivates: true,
escapeDeactivates: false,
initialFocus: undefined,
returnFocusOnDeactivate: false,
});
}
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$5 = {
LIST_ITEM_ACTIVATED_CLASS: 'mdc-list-item--activated',
LIST_ITEM_CLASS: 'mdc-list-item',
LIST_ITEM_DISABLED_CLASS: 'mdc-list-item--disabled',
LIST_ITEM_SELECTED_CLASS: 'mdc-list-item--selected',
ROOT: 'mdc-list',
};
var strings$6 = {
ACTION_EVENT: 'MDCList:action',
ARIA_CHECKED: 'aria-checked',
ARIA_CHECKED_CHECKBOX_SELECTOR: '[role="checkbox"][aria-checked="true"]',
ARIA_CHECKED_RADIO_SELECTOR: '[role="radio"][aria-checked="true"]',
ARIA_CURRENT: 'aria-current',
ARIA_DISABLED: 'aria-disabled',
ARIA_ORIENTATION: 'aria-orientation',
ARIA_ORIENTATION_HORIZONTAL: 'horizontal',
ARIA_ROLE_CHECKBOX_SELECTOR: '[role="checkbox"]',
ARIA_SELECTED: 'aria-selected',
CHECKBOX_RADIO_SELECTOR: 'input[type="checkbox"]:not(:disabled), input[type="radio"]:not(:disabled)',
CHECKBOX_SELECTOR: 'input[type="checkbox"]:not(:disabled)',
CHILD_ELEMENTS_TO_TOGGLE_TABINDEX: "\n ." + cssClasses$5.LIST_ITEM_CLASS + " button:not(:disabled),\n ." + cssClasses$5.LIST_ITEM_CLASS + " a\n ",
FOCUSABLE_CHILD_ELEMENTS: "\n ." + cssClasses$5.LIST_ITEM_CLASS + " button:not(:disabled),\n ." + cssClasses$5.LIST_ITEM_CLASS + " a,\n ." + cssClasses$5.LIST_ITEM_CLASS + " input[type=\"radio\"]:not(:disabled),\n ." + cssClasses$5.LIST_ITEM_CLASS + " input[type=\"checkbox\"]:not(:disabled)\n ",
RADIO_SELECTOR: 'input[type="radio"]:not(:disabled)',
};
var numbers$3 = {
UNSET_INDEX: -1,
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var ELEMENTS_KEY_ALLOWED_IN = ['input', 'button', 'textarea', 'select'];
function isNumberArray(selectedIndex) {
return selectedIndex instanceof Array;
}
var MDCListFoundation = /** @class */ (function (_super) {
__extends(MDCListFoundation, _super);
function MDCListFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCListFoundation.defaultAdapter, adapter)) || this;
_this.wrapFocus_ = false;
_this.isVertical_ = true;
_this.isSingleSelectionList_ = false;
_this.selectedIndex_ = numbers$3.UNSET_INDEX;
_this.focusedItemIndex_ = numbers$3.UNSET_INDEX;
_this.useActivatedClass_ = false;
_this.ariaCurrentAttrValue_ = null;
_this.isCheckboxList_ = false;
_this.isRadioList_ = false;
return _this;
}
Object.defineProperty(MDCListFoundation, "strings", {
get: function () {
return strings$6;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCListFoundation, "cssClasses", {
get: function () {
return cssClasses$5;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCListFoundation, "numbers", {
get: function () {
return numbers$3;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCListFoundation, "defaultAdapter", {
get: function () {
return {
addClassForElementIndex: function () { return undefined; },
focusItemAtIndex: function () { return undefined; },
getAttributeForElementIndex: function () { return null; },
getFocusedElementIndex: function () { return 0; },
getListItemCount: function () { return 0; },
hasCheckboxAtIndex: function () { return false; },
hasRadioAtIndex: function () { return false; },
isCheckboxCheckedAtIndex: function () { return false; },
isFocusInsideList: function () { return false; },
isRootFocused: function () { return false; },
notifyAction: function () { return undefined; },
removeClassForElementIndex: function () { return undefined; },
setAttributeForElementIndex: function () { return undefined; },
setCheckedCheckboxOrRadioAtIndex: function () { return undefined; },
setTabIndexForListItemChildren: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCListFoundation.prototype.layout = function () {
if (this.adapter_.getListItemCount() === 0) {
return;
}
if (this.adapter_.hasCheckboxAtIndex(0)) {
this.isCheckboxList_ = true;
}
else if (this.adapter_.hasRadioAtIndex(0)) {
this.isRadioList_ = true;
}
};
/**
* Sets the private wrapFocus_ variable.
*/
MDCListFoundation.prototype.setWrapFocus = function (value) {
this.wrapFocus_ = value;
};
/**
* Sets the isVertical_ private variable.
*/
MDCListFoundation.prototype.setVerticalOrientation = function (value) {
this.isVertical_ = value;
};
/**
* Sets the isSingleSelectionList_ private variable.
*/
MDCListFoundation.prototype.setSingleSelection = function (value) {
this.isSingleSelectionList_ = value;
};
/**
* Sets the useActivatedClass_ private variable.
*/
MDCListFoundation.prototype.setUseActivatedClass = function (useActivated) {
this.useActivatedClass_ = useActivated;
};
MDCListFoundation.prototype.getSelectedIndex = function () {
return this.selectedIndex_;
};
MDCListFoundation.prototype.setSelectedIndex = function (index) {
if (!this.isIndexValid_(index)) {
return;
}
if (this.isCheckboxList_) {
this.setCheckboxAtIndex_(index);
}
else if (this.isRadioList_) {
this.setRadioAtIndex_(index);
}
else {
this.setSingleSelectionAtIndex_(index);
}
};
/**
* Focus in handler for the list items.
*/
MDCListFoundation.prototype.handleFocusIn = function (_, listItemIndex) {
if (listItemIndex >= 0) {
this.adapter_.setTabIndexForListItemChildren(listItemIndex, '0');
}
};
/**
* Focus out handler for the list items.
*/
MDCListFoundation.prototype.handleFocusOut = function (_, listItemIndex) {
var _this = this;
if (listItemIndex >= 0) {
this.adapter_.setTabIndexForListItemChildren(listItemIndex, '-1');
}
/**
* Between Focusout & Focusin some browsers do not have focus on any element. Setting a delay to wait till the focus
* is moved to next element.
*/
setTimeout(function () {
if (!_this.adapter_.isFocusInsideList()) {
_this.setTabindexToFirstSelectedItem_();
}
}, 0);
};
/**
* Key handler for the list.
*/
MDCListFoundation.prototype.handleKeydown = function (evt, isRootListItem, listItemIndex) {
var isArrowLeft = evt.key === 'ArrowLeft' || evt.keyCode === 37;
var isArrowUp = evt.key === 'ArrowUp' || evt.keyCode === 38;
var isArrowRight = evt.key === 'ArrowRight' || evt.keyCode === 39;
var isArrowDown = evt.key === 'ArrowDown' || evt.keyCode === 40;
var isHome = evt.key === 'Home' || evt.keyCode === 36;
var isEnd = evt.key === 'End' || evt.keyCode === 35;
var isEnter = evt.key === 'Enter' || evt.keyCode === 13;
var isSpace = evt.key === 'Space' || evt.keyCode === 32;
if (this.adapter_.isRootFocused()) {
if (isArrowUp || isEnd) {
evt.preventDefault();
this.focusLastElement();
}
else if (isArrowDown || isHome) {
evt.preventDefault();
this.focusFirstElement();
}
return;
}
var currentIndex = this.adapter_.getFocusedElementIndex();
if (currentIndex === -1) {
currentIndex = listItemIndex;
if (currentIndex < 0) {
// If this event doesn't have a mdc-list-item ancestor from the
// current list (not from a sublist), return early.
return;
}
}
var nextIndex;
if ((this.isVertical_ && isArrowDown) || (!this.isVertical_ && isArrowRight)) {
this.preventDefaultEvent_(evt);
nextIndex = this.focusNextElement(currentIndex);
}
else if ((this.isVertical_ && isArrowUp) || (!this.isVertical_ && isArrowLeft)) {
this.preventDefaultEvent_(evt);
nextIndex = this.focusPrevElement(currentIndex);
}
else if (isHome) {
this.preventDefaultEvent_(evt);
nextIndex = this.focusFirstElement();
}
else if (isEnd) {
this.preventDefaultEvent_(evt);
nextIndex = this.focusLastElement();
}
else if (isEnter || isSpace) {
if (isRootListItem) {
// Return early if enter key is pressed on anchor element which triggers synthetic MouseEvent event.
var target = evt.target;
if (target && target.tagName === 'A' && isEnter) {
return;
}
this.preventDefaultEvent_(evt);
if (this.isSelectableList_()) {
this.setSelectedIndexOnAction_(currentIndex);
}
this.adapter_.notifyAction(currentIndex);
}
}
this.focusedItemIndex_ = currentIndex;
if (nextIndex !== undefined) {
this.setTabindexAtIndex_(nextIndex);
this.focusedItemIndex_ = nextIndex;
}
};
/**
* Click handler for the list.
*/
MDCListFoundation.prototype.handleClick = function (index, toggleCheckbox) {
if (index === numbers$3.UNSET_INDEX) {
return;
}
if (this.isSelectableList_()) {
this.setSelectedIndexOnAction_(index, toggleCheckbox);
}
this.adapter_.notifyAction(index);
this.setTabindexAtIndex_(index);
this.focusedItemIndex_ = index;
};
/**
* Focuses the next element on the list.
*/
MDCListFoundation.prototype.focusNextElement = function (index) {
var count = this.adapter_.getListItemCount();
var nextIndex = index + 1;
if (nextIndex >= count) {
if (this.wrapFocus_) {
nextIndex = 0;
}
else {
// Return early because last item is already focused.
return index;
}
}
this.adapter_.focusItemAtIndex(nextIndex);
return nextIndex;
};
/**
* Focuses the previous element on the list.
*/
MDCListFoundation.prototype.focusPrevElement = function (index) {
var prevIndex = index - 1;
if (prevIndex < 0) {
if (this.wrapFocus_) {
prevIndex = this.adapter_.getListItemCount() - 1;
}
else {
// Return early because first item is already focused.
return index;
}
}
this.adapter_.focusItemAtIndex(prevIndex);
return prevIndex;
};
MDCListFoundation.prototype.focusFirstElement = function () {
this.adapter_.focusItemAtIndex(0);
return 0;
};
MDCListFoundation.prototype.focusLastElement = function () {
var lastIndex = this.adapter_.getListItemCount() - 1;
this.adapter_.focusItemAtIndex(lastIndex);
return lastIndex;
};
/**
* @param itemIndex Index of the list item
* @param isEnabled Sets the list item to enabled or disabled.
*/
MDCListFoundation.prototype.setEnabled = function (itemIndex, isEnabled) {
if (!this.isIndexValid_(itemIndex)) {
return;
}
if (isEnabled) {
this.adapter_.removeClassForElementIndex(itemIndex, cssClasses$5.LIST_ITEM_DISABLED_CLASS);
this.adapter_.setAttributeForElementIndex(itemIndex, strings$6.ARIA_DISABLED, 'false');
}
else {
this.adapter_.addClassForElementIndex(itemIndex, cssClasses$5.LIST_ITEM_DISABLED_CLASS);
this.adapter_.setAttributeForElementIndex(itemIndex, strings$6.ARIA_DISABLED, 'true');
}
};
/**
* Ensures that preventDefault is only called if the containing element doesn't
* consume the event, and it will cause an unintended scroll.
*/
MDCListFoundation.prototype.preventDefaultEvent_ = function (evt) {
var target = evt.target;
var tagName = ("" + target.tagName).toLowerCase();
if (ELEMENTS_KEY_ALLOWED_IN.indexOf(tagName) === -1) {
evt.preventDefault();
}
};
MDCListFoundation.prototype.setSingleSelectionAtIndex_ = function (index) {
if (this.selectedIndex_ === index) {
return;
}
var selectedClassName = cssClasses$5.LIST_ITEM_SELECTED_CLASS;
if (this.useActivatedClass_) {
selectedClassName = cssClasses$5.LIST_ITEM_ACTIVATED_CLASS;
}
if (this.selectedIndex_ !== numbers$3.UNSET_INDEX) {
this.adapter_.removeClassForElementIndex(this.selectedIndex_, selectedClassName);
}
this.adapter_.addClassForElementIndex(index, selectedClassName);
this.setAriaForSingleSelectionAtIndex_(index);
this.selectedIndex_ = index;
};
/**
* Sets aria attribute for single selection at given index.
*/
MDCListFoundation.prototype.setAriaForSingleSelectionAtIndex_ = function (index) {
// Detect the presence of aria-current and get the value only during list initialization when it is in unset state.
if (this.selectedIndex_ === numbers$3.UNSET_INDEX) {
this.ariaCurrentAttrValue_ =
this.adapter_.getAttributeForElementIndex(index, strings$6.ARIA_CURRENT);
}
var isAriaCurrent = this.ariaCurrentAttrValue_ !== null;
var ariaAttribute = isAriaCurrent ? strings$6.ARIA_CURRENT : strings$6.ARIA_SELECTED;
if (this.selectedIndex_ !== numbers$3.UNSET_INDEX) {
this.adapter_.setAttributeForElementIndex(this.selectedIndex_, ariaAttribute, 'false');
}
var ariaAttributeValue = isAriaCurrent ? this.ariaCurrentAttrValue_ : 'true';
this.adapter_.setAttributeForElementIndex(index, ariaAttribute, ariaAttributeValue);
};
/**
* Toggles radio at give index. Radio doesn't change the checked state if it is already checked.
*/
MDCListFoundation.prototype.setRadioAtIndex_ = function (index) {
this.adapter_.setCheckedCheckboxOrRadioAtIndex(index, true);
if (this.selectedIndex_ !== numbers$3.UNSET_INDEX) {
this.adapter_.setAttributeForElementIndex(this.selectedIndex_, strings$6.ARIA_CHECKED, 'false');
}
this.adapter_.setAttributeForElementIndex(index, strings$6.ARIA_CHECKED, 'true');
this.selectedIndex_ = index;
};
MDCListFoundation.prototype.setCheckboxAtIndex_ = function (index) {
for (var i = 0; i < this.adapter_.getListItemCount(); i++) {
var isChecked = false;
if (index.indexOf(i) >= 0) {
isChecked = true;
}
this.adapter_.setCheckedCheckboxOrRadioAtIndex(i, isChecked);
this.adapter_.setAttributeForElementIndex(i, strings$6.ARIA_CHECKED, isChecked ? 'true' : 'false');
}
this.selectedIndex_ = index;
};
MDCListFoundation.prototype.setTabindexAtIndex_ = function (index) {
if (this.focusedItemIndex_ === numbers$3.UNSET_INDEX && index !== 0) {
// If no list item was selected set first list item's tabindex to -1.
// Generally, tabindex is set to 0 on first list item of list that has no preselected items.
this.adapter_.setAttributeForElementIndex(0, 'tabindex', '-1');
}
else if (this.focusedItemIndex_ >= 0 && this.focusedItemIndex_ !== index) {
this.adapter_.setAttributeForElementIndex(this.focusedItemIndex_, 'tabindex', '-1');
}
this.adapter_.setAttributeForElementIndex(index, 'tabindex', '0');
};
/**
* @return Return true if it is single selectin list, checkbox list or radio list.
*/
MDCListFoundation.prototype.isSelectableList_ = function () {
return this.isSingleSelectionList_ || this.isCheckboxList_ || this.isRadioList_;
};
MDCListFoundation.prototype.setTabindexToFirstSelectedItem_ = function () {
var targetIndex = 0;
if (this.isSelectableList_()) {
if (typeof this.selectedIndex_ === 'number' && this.selectedIndex_ !== numbers$3.UNSET_INDEX) {
targetIndex = this.selectedIndex_;
}
else if (isNumberArray(this.selectedIndex_) && this.selectedIndex_.length > 0) {
targetIndex = this.selectedIndex_.reduce(function (currentIndex, minIndex) { return Math.min(currentIndex, minIndex); });
}
}
this.setTabindexAtIndex_(targetIndex);
};
MDCListFoundation.prototype.isIndexValid_ = function (index) {
var _this = this;
if (index instanceof Array) {
if (!this.isCheckboxList_) {
throw new Error('MDCListFoundation: Array of index is only supported for checkbox based list');
}
if (index.length === 0) {
return true;
}
else {
return index.some(function (i) { return _this.isIndexInRange_(i); });
}
}
else if (typeof index === 'number') {
if (this.isCheckboxList_) {
throw new Error('MDCListFoundation: Expected array of index for checkbox based list but got number: ' + index);
}
return this.isIndexInRange_(index);
}
else {
return false;
}
};
MDCListFoundation.prototype.isIndexInRange_ = function (index) {
var listSize = this.adapter_.getListItemCount();
return index >= 0 && index < listSize;
};
MDCListFoundation.prototype.setSelectedIndexOnAction_ = function (index, toggleCheckbox) {
if (toggleCheckbox === void 0) { toggleCheckbox = true; }
if (this.isCheckboxList_) {
this.toggleCheckboxAtIndex_(index, toggleCheckbox);
}
else {
this.setSelectedIndex(index);
}
};
MDCListFoundation.prototype.toggleCheckboxAtIndex_ = function (index, toggleCheckbox) {
var isChecked = this.adapter_.isCheckboxCheckedAtIndex(index);
if (toggleCheckbox) {
isChecked = !isChecked;
this.adapter_.setCheckedCheckboxOrRadioAtIndex(index, isChecked);
}
this.adapter_.setAttributeForElementIndex(index, strings$6.ARIA_CHECKED, isChecked ? 'true' : 'false');
// If none of the checkbox items are selected and selectedIndex is not initialized then provide a default value.
var selectedIndexes = this.selectedIndex_ === numbers$3.UNSET_INDEX ? [] : this.selectedIndex_.slice();
if (isChecked) {
selectedIndexes.push(index);
}
else {
selectedIndexes = selectedIndexes.filter(function (i) { return i !== index; });
}
this.selectedIndex_ = selectedIndexes;
};
return MDCListFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCList = /** @class */ (function (_super) {
__extends(MDCList, _super);
function MDCList() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(MDCList.prototype, "vertical", {
set: function (value) {
this.foundation_.setVerticalOrientation(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCList.prototype, "listElements", {
get: function () {
return [].slice.call(this.root_.querySelectorAll("." + cssClasses$5.LIST_ITEM_CLASS));
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCList.prototype, "wrapFocus", {
set: function (value) {
this.foundation_.setWrapFocus(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCList.prototype, "singleSelection", {
set: function (isSingleSelectionList) {
this.foundation_.setSingleSelection(isSingleSelectionList);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCList.prototype, "selectedIndex", {
get: function () {
return this.foundation_.getSelectedIndex();
},
set: function (index) {
this.foundation_.setSelectedIndex(index);
},
enumerable: true,
configurable: true
});
MDCList.attachTo = function (root) {
return new MDCList(root);
};
MDCList.prototype.initialSyncWithDOM = function () {
this.handleClick_ = this.handleClickEvent_.bind(this);
this.handleKeydown_ = this.handleKeydownEvent_.bind(this);
this.focusInEventListener_ = this.handleFocusInEvent_.bind(this);
this.focusOutEventListener_ = this.handleFocusOutEvent_.bind(this);
this.listen('keydown', this.handleKeydown_);
this.listen('click', this.handleClick_);
this.listen('focusin', this.focusInEventListener_);
this.listen('focusout', this.focusOutEventListener_);
this.layout();
this.initializeListType();
};
MDCList.prototype.destroy = function () {
this.unlisten('keydown', this.handleKeydown_);
this.unlisten('click', this.handleClick_);
this.unlisten('focusin', this.focusInEventListener_);
this.unlisten('focusout', this.focusOutEventListener_);
};
MDCList.prototype.layout = function () {
var direction = this.root_.getAttribute(strings$6.ARIA_ORIENTATION);
this.vertical = direction !== strings$6.ARIA_ORIENTATION_HORIZONTAL;
// List items need to have at least tabindex=-1 to be focusable.
[].slice.call(this.root_.querySelectorAll('.mdc-list-item:not([tabindex])'))
.forEach(function (el) {
el.setAttribute('tabindex', '-1');
});
// Child button/a elements are not tabbable until the list item is focused.
[].slice.call(this.root_.querySelectorAll(strings$6.FOCUSABLE_CHILD_ELEMENTS))
.forEach(function (el) { return el.setAttribute('tabindex', '-1'); });
this.foundation_.layout();
};
/**
* Initialize selectedIndex value based on pre-selected checkbox list items, single selection or radio.
*/
MDCList.prototype.initializeListType = function () {
var _this = this;
var checkboxListItems = this.root_.querySelectorAll(strings$6.ARIA_ROLE_CHECKBOX_SELECTOR);
var singleSelectedListItem = this.root_.querySelector("\n ." + cssClasses$5.LIST_ITEM_ACTIVATED_CLASS + ",\n ." + cssClasses$5.LIST_ITEM_SELECTED_CLASS + "\n ");
var radioSelectedListItem = this.root_.querySelector(strings$6.ARIA_CHECKED_RADIO_SELECTOR);
if (checkboxListItems.length) {
var preselectedItems = this.root_.querySelectorAll(strings$6.ARIA_CHECKED_CHECKBOX_SELECTOR);
this.selectedIndex =
[].map.call(preselectedItems, function (listItem) { return _this.listElements.indexOf(listItem); });
}
else if (singleSelectedListItem) {
if (singleSelectedListItem.classList.contains(cssClasses$5.LIST_ITEM_ACTIVATED_CLASS)) {
this.foundation_.setUseActivatedClass(true);
}
this.singleSelection = true;
this.selectedIndex = this.listElements.indexOf(singleSelectedListItem);
}
else if (radioSelectedListItem) {
this.selectedIndex = this.listElements.indexOf(radioSelectedListItem);
}
};
/**
* Updates the list item at itemIndex to the desired isEnabled state.
* @param itemIndex Index of the list item
* @param isEnabled Sets the list item to enabled or disabled.
*/
MDCList.prototype.setEnabled = function (itemIndex, isEnabled) {
this.foundation_.setEnabled(itemIndex, isEnabled);
};
MDCList.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = {
addClassForElementIndex: function (index, className) {
var element = _this.listElements[index];
if (element) {
element.classList.add(className);
}
},
focusItemAtIndex: function (index) {
var element = _this.listElements[index];
if (element) {
element.focus();
}
},
getAttributeForElementIndex: function (index, attr) { return _this.listElements[index].getAttribute(attr); },
getFocusedElementIndex: function () { return _this.listElements.indexOf(document.activeElement); },
getListItemCount: function () { return _this.listElements.length; },
hasCheckboxAtIndex: function (index) {
var listItem = _this.listElements[index];
return !!listItem.querySelector(strings$6.CHECKBOX_SELECTOR);
},
hasRadioAtIndex: function (index) {
var listItem = _this.listElements[index];
return !!listItem.querySelector(strings$6.RADIO_SELECTOR);
},
isCheckboxCheckedAtIndex: function (index) {
var listItem = _this.listElements[index];
var toggleEl = listItem.querySelector(strings$6.CHECKBOX_SELECTOR);
return toggleEl.checked;
},
isFocusInsideList: function () {
return _this.root_.contains(document.activeElement);
},
isRootFocused: function () { return document.activeElement === _this.root_; },
notifyAction: function (index) {
_this.emit(strings$6.ACTION_EVENT, { index: index }, /** shouldBubble */ true);
},
removeClassForElementIndex: function (index, className) {
var element = _this.listElements[index];
if (element) {
element.classList.remove(className);
}
},
setAttributeForElementIndex: function (index, attr, value) {
var element = _this.listElements[index];
if (element) {
element.setAttribute(attr, value);
}
},
setCheckedCheckboxOrRadioAtIndex: function (index, isChecked) {
var listItem = _this.listElements[index];
var toggleEl = listItem.querySelector(strings$6.CHECKBOX_RADIO_SELECTOR);
toggleEl.checked = isChecked;
var event = document.createEvent('Event');
event.initEvent('change', true, true);
toggleEl.dispatchEvent(event);
},
setTabIndexForListItemChildren: function (listItemIndex, tabIndexValue) {
var element = _this.listElements[listItemIndex];
var listItemChildren = [].slice.call(element.querySelectorAll(strings$6.CHILD_ELEMENTS_TO_TOGGLE_TABINDEX));
listItemChildren.forEach(function (el) { return el.setAttribute('tabindex', tabIndexValue); });
},
};
return new MDCListFoundation(adapter);
};
/**
* Used to figure out which list item this event is targetting. Or returns -1 if
* there is no list item
*/
MDCList.prototype.getListItemIndex_ = function (evt) {
var eventTarget = evt.target;
var nearestParent = closest(eventTarget, "." + cssClasses$5.LIST_ITEM_CLASS + ", ." + cssClasses$5.ROOT);
// Get the index of the element if it is a list item.
if (nearestParent && matches(nearestParent, "." + cssClasses$5.LIST_ITEM_CLASS)) {
return this.listElements.indexOf(nearestParent);
}
return -1;
};
/**
* Used to figure out which element was clicked before sending the event to the foundation.
*/
MDCList.prototype.handleFocusInEvent_ = function (evt) {
var index = this.getListItemIndex_(evt);
this.foundation_.handleFocusIn(evt, index);
};
/**
* Used to figure out which element was clicked before sending the event to the foundation.
*/
MDCList.prototype.handleFocusOutEvent_ = function (evt) {
var index = this.getListItemIndex_(evt);
this.foundation_.handleFocusOut(evt, index);
};
/**
* Used to figure out which element was focused when keydown event occurred before sending the event to the
* foundation.
*/
MDCList.prototype.handleKeydownEvent_ = function (evt) {
var index = this.getListItemIndex_(evt);
var target = evt.target;
this.foundation_.handleKeydown(evt, target.classList.contains(cssClasses$5.LIST_ITEM_CLASS), index);
};
/**
* Used to figure out which element was clicked before sending the event to the foundation.
*/
MDCList.prototype.handleClickEvent_ = function (evt) {
var index = this.getListItemIndex_(evt);
var target = evt.target;
// Toggle the checkbox only if it's not the target of the event, or the checkbox will have 2 change events.
var toggleCheckbox = !matches(target, strings$6.CHECKBOX_RADIO_SELECTOR);
this.foundation_.handleClick(index, toggleCheckbox);
};
return MDCList;
}(MDCComponent));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$6 = {
ANIMATE: 'mdc-drawer--animate',
CLOSING: 'mdc-drawer--closing',
DISMISSIBLE: 'mdc-drawer--dismissible',
MODAL: 'mdc-drawer--modal',
OPEN: 'mdc-drawer--open',
OPENING: 'mdc-drawer--opening',
ROOT: 'mdc-drawer',
};
var strings$7 = {
APP_CONTENT_SELECTOR: '.mdc-drawer-app-content',
CLOSE_EVENT: 'MDCDrawer:closed',
OPEN_EVENT: 'MDCDrawer:opened',
SCRIM_SELECTOR: '.mdc-drawer-scrim',
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCDismissibleDrawerFoundation = /** @class */ (function (_super) {
__extends(MDCDismissibleDrawerFoundation, _super);
function MDCDismissibleDrawerFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCDismissibleDrawerFoundation.defaultAdapter, adapter)) || this;
_this.animationFrame_ = 0;
_this.animationTimer_ = 0;
return _this;
}
Object.defineProperty(MDCDismissibleDrawerFoundation, "strings", {
get: function () {
return strings$7;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCDismissibleDrawerFoundation, "cssClasses", {
get: function () {
return cssClasses$6;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCDismissibleDrawerFoundation, "defaultAdapter", {
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
hasClass: function () { return false; },
elementHasClass: function () { return false; },
notifyClose: function () { return undefined; },
notifyOpen: function () { return undefined; },
saveFocus: function () { return undefined; },
restoreFocus: function () { return undefined; },
focusActiveNavigationItem: function () { return undefined; },
trapFocus: function () { return undefined; },
releaseFocus: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCDismissibleDrawerFoundation.prototype.destroy = function () {
if (this.animationFrame_) {
cancelAnimationFrame(this.animationFrame_);
}
if (this.animationTimer_) {
clearTimeout(this.animationTimer_);
}
};
/**
* Opens the drawer from the closed state.
*/
MDCDismissibleDrawerFoundation.prototype.open = function () {
var _this = this;
if (this.isOpen() || this.isOpening() || this.isClosing()) {
return;
}
this.adapter_.addClass(cssClasses$6.OPEN);
this.adapter_.addClass(cssClasses$6.ANIMATE);
// Wait a frame once display is no longer "none", to establish basis for animation
this.runNextAnimationFrame_(function () {
_this.adapter_.addClass(cssClasses$6.OPENING);
});
this.adapter_.saveFocus();
};
/**
* Closes the drawer from the open state.
*/
MDCDismissibleDrawerFoundation.prototype.close = function () {
if (!this.isOpen() || this.isOpening() || this.isClosing()) {
return;
}
this.adapter_.addClass(cssClasses$6.CLOSING);
};
/**
* Returns true if the drawer is in the open position.
* @return true if drawer is in open state.
*/
MDCDismissibleDrawerFoundation.prototype.isOpen = function () {
return this.adapter_.hasClass(cssClasses$6.OPEN);
};
/**
* Returns true if the drawer is animating open.
* @return true if drawer is animating open.
*/
MDCDismissibleDrawerFoundation.prototype.isOpening = function () {
return this.adapter_.hasClass(cssClasses$6.OPENING) || this.adapter_.hasClass(cssClasses$6.ANIMATE);
};
/**
* Returns true if the drawer is animating closed.
* @return true if drawer is animating closed.
*/
MDCDismissibleDrawerFoundation.prototype.isClosing = function () {
return this.adapter_.hasClass(cssClasses$6.CLOSING);
};
/**
* Keydown handler to close drawer when key is escape.
*/
MDCDismissibleDrawerFoundation.prototype.handleKeydown = function (evt) {
var keyCode = evt.keyCode, key = evt.key;
var isEscape = key === 'Escape' || keyCode === 27;
if (isEscape) {
this.close();
}
};
/**
* Handles the `transitionend` event when the drawer finishes opening/closing.
*/
MDCDismissibleDrawerFoundation.prototype.handleTransitionEnd = function (evt) {
var OPENING = cssClasses$6.OPENING, CLOSING = cssClasses$6.CLOSING, OPEN = cssClasses$6.OPEN, ANIMATE = cssClasses$6.ANIMATE, ROOT = cssClasses$6.ROOT;
// In Edge, transitionend on ripple pseudo-elements yields a target without classList, so check for Element first.
var isRootElement = this.isElement_(evt.target) && this.adapter_.elementHasClass(evt.target, ROOT);
if (!isRootElement) {
return;
}
if (this.isClosing()) {
this.adapter_.removeClass(OPEN);
this.closed_();
this.adapter_.restoreFocus();
this.adapter_.notifyClose();
}
else {
this.adapter_.focusActiveNavigationItem();
this.opened_();
this.adapter_.notifyOpen();
}
this.adapter_.removeClass(ANIMATE);
this.adapter_.removeClass(OPENING);
this.adapter_.removeClass(CLOSING);
};
/**
* Extension point for when drawer finishes open animation.
*/
MDCDismissibleDrawerFoundation.prototype.opened_ = function () { }; // tslint:disable-line:no-empty
/**
* Extension point for when drawer finishes close animation.
*/
MDCDismissibleDrawerFoundation.prototype.closed_ = function () { }; // tslint:disable-line:no-empty
/**
* Runs the given logic on the next animation frame, using setTimeout to factor in Firefox reflow behavior.
*/
MDCDismissibleDrawerFoundation.prototype.runNextAnimationFrame_ = function (callback) {
var _this = this;
cancelAnimationFrame(this.animationFrame_);
this.animationFrame_ = requestAnimationFrame(function () {
_this.animationFrame_ = 0;
clearTimeout(_this.animationTimer_);
_this.animationTimer_ = setTimeout(callback, 0);
});
};
MDCDismissibleDrawerFoundation.prototype.isElement_ = function (element) {
// In Edge, transitionend on ripple pseudo-elements yields a target without classList.
return Boolean(element.classList);
};
return MDCDismissibleDrawerFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* istanbul ignore next: subclass is not a branch statement */
var MDCModalDrawerFoundation = /** @class */ (function (_super) {
__extends(MDCModalDrawerFoundation, _super);
function MDCModalDrawerFoundation() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Handles click event on scrim.
*/
MDCModalDrawerFoundation.prototype.handleScrimClick = function () {
this.close();
};
/**
* Called when drawer finishes open animation.
*/
MDCModalDrawerFoundation.prototype.opened_ = function () {
this.adapter_.trapFocus();
};
/**
* Called when drawer finishes close animation.
*/
MDCModalDrawerFoundation.prototype.closed_ = function () {
this.adapter_.releaseFocus();
};
return MDCModalDrawerFoundation;
}(MDCDismissibleDrawerFoundation));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$7 = MDCDismissibleDrawerFoundation.cssClasses, strings$8 = MDCDismissibleDrawerFoundation.strings;
/**
* @events `MDCDrawer:closed {}` Emits when the navigation drawer has closed.
* @events `MDCDrawer:opened {}` Emits when the navigation drawer has opened.
*/
var MDCDrawer = /** @class */ (function (_super) {
__extends(MDCDrawer, _super);
function MDCDrawer() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCDrawer.attachTo = function (root) {
return new MDCDrawer(root);
};
Object.defineProperty(MDCDrawer.prototype, "open", {
/**
* @return boolean Proxies to the foundation's `open`/`close` methods.
* Also returns true if drawer is in the open position.
*/
get: function () {
return this.foundation_.isOpen();
},
/**
* Toggles the drawer open and closed.
*/
set: function (isOpen) {
if (isOpen) {
this.foundation_.open();
}
else {
this.foundation_.close();
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCDrawer.prototype, "list", {
get: function () {
return this.list_;
},
enumerable: true,
configurable: true
});
MDCDrawer.prototype.initialize = function (focusTrapFactory, listFactory) {
if (focusTrapFactory === void 0) { focusTrapFactory = focusTrap_1; }
if (listFactory === void 0) { listFactory = function (el) { return new MDCList(el); }; }
var listEl = this.root_.querySelector("." + MDCListFoundation.cssClasses.ROOT);
if (listEl) {
this.list_ = listFactory(listEl);
this.list_.wrapFocus = true;
}
this.focusTrapFactory_ = focusTrapFactory;
};
MDCDrawer.prototype.initialSyncWithDOM = function () {
var _this = this;
var MODAL = cssClasses$7.MODAL;
var SCRIM_SELECTOR = strings$8.SCRIM_SELECTOR;
this.scrim_ = this.root_.parentNode.querySelector(SCRIM_SELECTOR);
if (this.scrim_ && this.root_.classList.contains(MODAL)) {
this.handleScrimClick_ = function () { return _this.foundation_.handleScrimClick(); };
this.scrim_.addEventListener('click', this.handleScrimClick_);
this.focusTrap_ = createFocusTrapInstance$1(this.root_, this.focusTrapFactory_);
}
this.handleKeydown_ = function (evt) { return _this.foundation_.handleKeydown(evt); };
this.handleTransitionEnd_ = function (evt) { return _this.foundation_.handleTransitionEnd(evt); };
this.listen('keydown', this.handleKeydown_);
this.listen('transitionend', this.handleTransitionEnd_);
};
MDCDrawer.prototype.destroy = function () {
this.unlisten('keydown', this.handleKeydown_);
this.unlisten('transitionend', this.handleTransitionEnd_);
if (this.list_) {
this.list_.destroy();
}
var MODAL = cssClasses$7.MODAL;
if (this.scrim_ && this.handleScrimClick_ && this.root_.classList.contains(MODAL)) {
this.scrim_.removeEventListener('click', this.handleScrimClick_);
// Ensure drawer is closed to hide scrim and release focus
this.open = false;
}
};
MDCDrawer.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
hasClass: function (className) { return _this.root_.classList.contains(className); },
elementHasClass: function (element, className) { return element.classList.contains(className); },
saveFocus: function () { return _this.previousFocus_ = document.activeElement; },
restoreFocus: function () {
var previousFocus = _this.previousFocus_;
if (previousFocus && previousFocus.focus && _this.root_.contains(document.activeElement)) {
previousFocus.focus();
}
},
focusActiveNavigationItem: function () {
var activeNavItemEl = _this.root_.querySelector("." + MDCListFoundation.cssClasses.LIST_ITEM_ACTIVATED_CLASS);
if (activeNavItemEl) {
activeNavItemEl.focus();
}
},
notifyClose: function () { return _this.emit(strings$8.CLOSE_EVENT, {}, true /* shouldBubble */); },
notifyOpen: function () { return _this.emit(strings$8.OPEN_EVENT, {}, true /* shouldBubble */); },
trapFocus: function () { return _this.focusTrap_.activate(); },
releaseFocus: function () { return _this.focusTrap_.deactivate(); },
};
// tslint:enable:object-literal-sort-keys
var DISMISSIBLE = cssClasses$7.DISMISSIBLE, MODAL = cssClasses$7.MODAL;
if (this.root_.classList.contains(DISMISSIBLE)) {
return new MDCDismissibleDrawerFoundation(adapter);
}
else if (this.root_.classList.contains(MODAL)) {
return new MDCModalDrawerFoundation(adapter);
}
else {
throw new Error("MDCDrawer: Failed to instantiate component. Supported variants are " + DISMISSIBLE + " and " + MODAL + ".");
}
};
return MDCDrawer;
}(MDCComponent));
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$8 = {
ROOT: 'mdc-form-field',
};
var strings$9 = {
LABEL_SELECTOR: '.mdc-form-field > label',
};
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCFormFieldFoundation = /** @class */ (function (_super) {
__extends(MDCFormFieldFoundation, _super);
function MDCFormFieldFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCFormFieldFoundation.defaultAdapter, adapter)) || this;
_this.clickHandler_ = function () { return _this.handleClick_(); };
return _this;
}
Object.defineProperty(MDCFormFieldFoundation, "cssClasses", {
get: function () {
return cssClasses$8;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFormFieldFoundation, "strings", {
get: function () {
return strings$9;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFormFieldFoundation, "defaultAdapter", {
get: function () {
return {
activateInputRipple: function () { return undefined; },
deactivateInputRipple: function () { return undefined; },
deregisterInteractionHandler: function () { return undefined; },
registerInteractionHandler: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCFormFieldFoundation.prototype.init = function () {
this.adapter_.registerInteractionHandler('click', this.clickHandler_);
};
MDCFormFieldFoundation.prototype.destroy = function () {
this.adapter_.deregisterInteractionHandler('click', this.clickHandler_);
};
MDCFormFieldFoundation.prototype.handleClick_ = function () {
var _this = this;
this.adapter_.activateInputRipple();
requestAnimationFrame(function () { return _this.adapter_.deactivateInputRipple(); });
};
return MDCFormFieldFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCFormField = /** @class */ (function (_super) {
__extends(MDCFormField, _super);
function MDCFormField() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCFormField.attachTo = function (root) {
return new MDCFormField(root);
};
Object.defineProperty(MDCFormField.prototype, "input", {
get: function () {
return this.input_;
},
set: function (input) {
this.input_ = input;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFormField.prototype, "label_", {
get: function () {
var LABEL_SELECTOR = MDCFormFieldFoundation.strings.LABEL_SELECTOR;
return this.root_.querySelector(LABEL_SELECTOR);
},
enumerable: true,
configurable: true
});
MDCFormField.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = {
activateInputRipple: function () {
if (_this.input_ && _this.input_.ripple) {
_this.input_.ripple.activate();
}
},
deactivateInputRipple: function () {
if (_this.input_ && _this.input_.ripple) {
_this.input_.ripple.deactivate();
}
},
deregisterInteractionHandler: function (evtType, handler) {
if (_this.label_) {
_this.label_.removeEventListener(evtType, handler);
}
},
registerInteractionHandler: function (evtType, handler) {
if (_this.label_) {
_this.label_.addEventListener(evtType, handler);
}
},
};
return new MDCFormFieldFoundation(adapter);
};
return MDCFormField;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$9 = {
ICON_BUTTON_ON: 'mdc-icon-button--on',
ROOT: 'mdc-icon-button',
};
var strings$a = {
ARIA_PRESSED: 'aria-pressed',
CHANGE_EVENT: 'MDCIconButtonToggle:change',
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCIconButtonToggleFoundation = /** @class */ (function (_super) {
__extends(MDCIconButtonToggleFoundation, _super);
function MDCIconButtonToggleFoundation(adapter) {
return _super.call(this, __assign({}, MDCIconButtonToggleFoundation.defaultAdapter, adapter)) || this;
}
Object.defineProperty(MDCIconButtonToggleFoundation, "cssClasses", {
get: function () {
return cssClasses$9;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCIconButtonToggleFoundation, "strings", {
get: function () {
return strings$a;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCIconButtonToggleFoundation, "defaultAdapter", {
get: function () {
return {
addClass: function () { return undefined; },
hasClass: function () { return false; },
notifyChange: function () { return undefined; },
removeClass: function () { return undefined; },
setAttr: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCIconButtonToggleFoundation.prototype.init = function () {
this.adapter_.setAttr(strings$a.ARIA_PRESSED, "" + this.isOn());
};
MDCIconButtonToggleFoundation.prototype.handleClick = function () {
this.toggle();
this.adapter_.notifyChange({ isOn: this.isOn() });
};
MDCIconButtonToggleFoundation.prototype.isOn = function () {
return this.adapter_.hasClass(cssClasses$9.ICON_BUTTON_ON);
};
MDCIconButtonToggleFoundation.prototype.toggle = function (isOn) {
if (isOn === void 0) { isOn = !this.isOn(); }
if (isOn) {
this.adapter_.addClass(cssClasses$9.ICON_BUTTON_ON);
}
else {
this.adapter_.removeClass(cssClasses$9.ICON_BUTTON_ON);
}
this.adapter_.setAttr(strings$a.ARIA_PRESSED, "" + isOn);
};
return MDCIconButtonToggleFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var strings$b = MDCIconButtonToggleFoundation.strings;
var MDCIconButtonToggle = /** @class */ (function (_super) {
__extends(MDCIconButtonToggle, _super);
function MDCIconButtonToggle() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.ripple_ = _this.createRipple_();
return _this;
}
MDCIconButtonToggle.attachTo = function (root) {
return new MDCIconButtonToggle(root);
};
MDCIconButtonToggle.prototype.initialSyncWithDOM = function () {
var _this = this;
this.handleClick_ = function () { return _this.foundation_.handleClick(); };
this.listen('click', this.handleClick_);
};
MDCIconButtonToggle.prototype.destroy = function () {
this.unlisten('click', this.handleClick_);
this.ripple_.destroy();
_super.prototype.destroy.call(this);
};
MDCIconButtonToggle.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
hasClass: function (className) { return _this.root_.classList.contains(className); },
notifyChange: function (evtData) { return _this.emit(strings$b.CHANGE_EVENT, evtData); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
setAttr: function (attrName, attrValue) { return _this.root_.setAttribute(attrName, attrValue); },
};
return new MDCIconButtonToggleFoundation(adapter);
};
Object.defineProperty(MDCIconButtonToggle.prototype, "ripple", {
get: function () {
return this.ripple_;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCIconButtonToggle.prototype, "on", {
get: function () {
return this.foundation_.isOn();
},
set: function (isOn) {
this.foundation_.toggle(isOn);
},
enumerable: true,
configurable: true
});
MDCIconButtonToggle.prototype.createRipple_ = function () {
var ripple = new MDCRipple(this.root_);
ripple.unbounded = true;
return ripple;
};
return MDCIconButtonToggle;
}(MDCComponent));
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$a = {
CLOSED_CLASS: 'mdc-linear-progress--closed',
INDETERMINATE_CLASS: 'mdc-linear-progress--indeterminate',
REVERSED_CLASS: 'mdc-linear-progress--reversed',
};
var strings$c = {
BUFFER_SELECTOR: '.mdc-linear-progress__buffer',
PRIMARY_BAR_SELECTOR: '.mdc-linear-progress__primary-bar',
};
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCLinearProgressFoundation = /** @class */ (function (_super) {
__extends(MDCLinearProgressFoundation, _super);
function MDCLinearProgressFoundation(adapter) {
return _super.call(this, __assign({}, MDCLinearProgressFoundation.defaultAdapter, adapter)) || this;
}
Object.defineProperty(MDCLinearProgressFoundation, "cssClasses", {
get: function () {
return cssClasses$a;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCLinearProgressFoundation, "strings", {
get: function () {
return strings$c;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCLinearProgressFoundation, "defaultAdapter", {
get: function () {
return {
addClass: function () { return undefined; },
getBuffer: function () { return null; },
getPrimaryBar: function () { return null; },
hasClass: function () { return false; },
removeClass: function () { return undefined; },
setStyle: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCLinearProgressFoundation.prototype.init = function () {
this.isDeterminate_ = !this.adapter_.hasClass(cssClasses$a.INDETERMINATE_CLASS);
this.isReversed_ = this.adapter_.hasClass(cssClasses$a.REVERSED_CLASS);
this.progress_ = 0;
};
MDCLinearProgressFoundation.prototype.setDeterminate = function (isDeterminate) {
this.isDeterminate_ = isDeterminate;
if (this.isDeterminate_) {
this.adapter_.removeClass(cssClasses$a.INDETERMINATE_CLASS);
this.setScale_(this.adapter_.getPrimaryBar(), this.progress_);
}
else {
this.adapter_.addClass(cssClasses$a.INDETERMINATE_CLASS);
this.setScale_(this.adapter_.getPrimaryBar(), 1);
this.setScale_(this.adapter_.getBuffer(), 1);
}
};
MDCLinearProgressFoundation.prototype.setProgress = function (value) {
this.progress_ = value;
if (this.isDeterminate_) {
this.setScale_(this.adapter_.getPrimaryBar(), value);
}
};
MDCLinearProgressFoundation.prototype.setBuffer = function (value) {
if (this.isDeterminate_) {
this.setScale_(this.adapter_.getBuffer(), value);
}
};
MDCLinearProgressFoundation.prototype.setReverse = function (isReversed) {
this.isReversed_ = isReversed;
if (this.isReversed_) {
this.adapter_.addClass(cssClasses$a.REVERSED_CLASS);
}
else {
this.adapter_.removeClass(cssClasses$a.REVERSED_CLASS);
}
};
MDCLinearProgressFoundation.prototype.open = function () {
this.adapter_.removeClass(cssClasses$a.CLOSED_CLASS);
};
MDCLinearProgressFoundation.prototype.close = function () {
this.adapter_.addClass(cssClasses$a.CLOSED_CLASS);
};
MDCLinearProgressFoundation.prototype.setScale_ = function (el, scaleValue) {
if (!el) {
return;
}
var value = "scaleX(" + scaleValue + ")";
this.adapter_.setStyle(el, getCorrectPropertyName(window, 'transform'), value);
};
return MDCLinearProgressFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCLinearProgress = /** @class */ (function (_super) {
__extends(MDCLinearProgress, _super);
function MDCLinearProgress() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCLinearProgress.attachTo = function (root) {
return new MDCLinearProgress(root);
};
Object.defineProperty(MDCLinearProgress.prototype, "determinate", {
set: function (value) {
this.foundation_.setDeterminate(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCLinearProgress.prototype, "progress", {
set: function (value) {
this.foundation_.setProgress(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCLinearProgress.prototype, "buffer", {
set: function (value) {
this.foundation_.setBuffer(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCLinearProgress.prototype, "reverse", {
set: function (value) {
this.foundation_.setReverse(value);
},
enumerable: true,
configurable: true
});
MDCLinearProgress.prototype.open = function () {
this.foundation_.open();
};
MDCLinearProgress.prototype.close = function () {
this.foundation_.close();
};
MDCLinearProgress.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
getBuffer: function () { return _this.root_.querySelector(MDCLinearProgressFoundation.strings.BUFFER_SELECTOR); },
getPrimaryBar: function () { return _this.root_.querySelector(MDCLinearProgressFoundation.strings.PRIMARY_BAR_SELECTOR); },
hasClass: function (className) { return _this.root_.classList.contains(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
setStyle: function (el, styleProperty, value) { return el.style.setProperty(styleProperty, value); },
};
return new MDCLinearProgressFoundation(adapter);
};
return MDCLinearProgress;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$b = {
ANCHOR: 'mdc-menu-surface--anchor',
ANIMATING_CLOSED: 'mdc-menu-surface--animating-closed',
ANIMATING_OPEN: 'mdc-menu-surface--animating-open',
FIXED: 'mdc-menu-surface--fixed',
OPEN: 'mdc-menu-surface--open',
ROOT: 'mdc-menu-surface',
};
// tslint:disable:object-literal-sort-keys
var strings$d = {
CLOSED_EVENT: 'MDCMenuSurface:closed',
OPENED_EVENT: 'MDCMenuSurface:opened',
FOCUSABLE_ELEMENTS: [
'button:not(:disabled)', '[href]:not([aria-disabled="true"])', 'input:not(:disabled)',
'select:not(:disabled)', 'textarea:not(:disabled)', '[tabindex]:not([tabindex="-1"]):not([aria-disabled="true"])',
].join(', '),
};
// tslint:enable:object-literal-sort-keys
var numbers$4 = {
/** Total duration of menu-surface open animation. */
TRANSITION_OPEN_DURATION: 120,
/** Total duration of menu-surface close animation. */
TRANSITION_CLOSE_DURATION: 75,
/** Margin left to the edge of the viewport when menu-surface is at maximum possible height. */
MARGIN_TO_EDGE: 32,
/** Ratio of anchor width to menu-surface width for switching from corner positioning to center positioning. */
ANCHOR_TO_MENU_SURFACE_WIDTH_RATIO: 0.67,
};
/**
* Enum for bits in the {@see Corner) bitmap.
*/
var CornerBit;
(function (CornerBit) {
CornerBit[CornerBit["BOTTOM"] = 1] = "BOTTOM";
CornerBit[CornerBit["CENTER"] = 2] = "CENTER";
CornerBit[CornerBit["RIGHT"] = 4] = "RIGHT";
CornerBit[CornerBit["FLIP_RTL"] = 8] = "FLIP_RTL";
})(CornerBit || (CornerBit = {}));
/**
* Enum for representing an element corner for positioning the menu-surface.
*
* The START constants map to LEFT if element directionality is left
* to right and RIGHT if the directionality is right to left.
* Likewise END maps to RIGHT or LEFT depending on the directionality.
*/
(function (Corner) {
Corner[Corner["TOP_LEFT"] = 0] = "TOP_LEFT";
Corner[Corner["TOP_RIGHT"] = 4] = "TOP_RIGHT";
Corner[Corner["BOTTOM_LEFT"] = 1] = "BOTTOM_LEFT";
Corner[Corner["BOTTOM_RIGHT"] = 5] = "BOTTOM_RIGHT";
Corner[Corner["TOP_START"] = 8] = "TOP_START";
Corner[Corner["TOP_END"] = 12] = "TOP_END";
Corner[Corner["BOTTOM_START"] = 9] = "BOTTOM_START";
Corner[Corner["BOTTOM_END"] = 13] = "BOTTOM_END";
})(exports.Corner || (exports.Corner = {}));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCMenuSurfaceFoundation = /** @class */ (function (_super) {
__extends(MDCMenuSurfaceFoundation, _super);
function MDCMenuSurfaceFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCMenuSurfaceFoundation.defaultAdapter, adapter)) || this;
_this.isOpen_ = false;
_this.isQuickOpen_ = false;
_this.isHoistedElement_ = false;
_this.isFixedPosition_ = false;
_this.openAnimationEndTimerId_ = 0;
_this.closeAnimationEndTimerId_ = 0;
_this.animationRequestId_ = 0;
_this.anchorCorner_ = exports.Corner.TOP_START;
_this.anchorMargin_ = { top: 0, right: 0, bottom: 0, left: 0 };
_this.position_ = { x: 0, y: 0 };
return _this;
}
Object.defineProperty(MDCMenuSurfaceFoundation, "cssClasses", {
get: function () {
return cssClasses$b;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCMenuSurfaceFoundation, "strings", {
get: function () {
return strings$d;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCMenuSurfaceFoundation, "numbers", {
get: function () {
return numbers$4;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCMenuSurfaceFoundation, "Corner", {
get: function () {
return exports.Corner;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCMenuSurfaceFoundation, "defaultAdapter", {
/**
* @see {@link MDCMenuSurfaceAdapter} for typing information on parameters and return types.
*/
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
hasClass: function () { return false; },
hasAnchor: function () { return false; },
isElementInContainer: function () { return false; },
isFocused: function () { return false; },
isRtl: function () { return false; },
getInnerDimensions: function () { return ({ height: 0, width: 0 }); },
getAnchorDimensions: function () { return null; },
getWindowDimensions: function () { return ({ height: 0, width: 0 }); },
getBodyDimensions: function () { return ({ height: 0, width: 0 }); },
getWindowScroll: function () { return ({ x: 0, y: 0 }); },
setPosition: function () { return undefined; },
setMaxHeight: function () { return undefined; },
setTransformOrigin: function () { return undefined; },
saveFocus: function () { return undefined; },
restoreFocus: function () { return undefined; },
notifyClose: function () { return undefined; },
notifyOpen: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCMenuSurfaceFoundation.prototype.init = function () {
var _a = MDCMenuSurfaceFoundation.cssClasses, ROOT = _a.ROOT, OPEN = _a.OPEN;
if (!this.adapter_.hasClass(ROOT)) {
throw new Error(ROOT + " class required in root element.");
}
if (this.adapter_.hasClass(OPEN)) {
this.isOpen_ = true;
}
};
MDCMenuSurfaceFoundation.prototype.destroy = function () {
clearTimeout(this.openAnimationEndTimerId_);
clearTimeout(this.closeAnimationEndTimerId_);
// Cancel any currently running animations.
cancelAnimationFrame(this.animationRequestId_);
};
/**
* @param corner Default anchor corner alignment of top-left menu surface corner.
*/
MDCMenuSurfaceFoundation.prototype.setAnchorCorner = function (corner) {
this.anchorCorner_ = corner;
};
/**
* @param margin Set of margin values from anchor.
*/
MDCMenuSurfaceFoundation.prototype.setAnchorMargin = function (margin) {
this.anchorMargin_.top = margin.top || 0;
this.anchorMargin_.right = margin.right || 0;
this.anchorMargin_.bottom = margin.bottom || 0;
this.anchorMargin_.left = margin.left || 0;
};
/** Used to indicate if the menu-surface is hoisted to the body. */
MDCMenuSurfaceFoundation.prototype.setIsHoisted = function (isHoisted) {
this.isHoistedElement_ = isHoisted;
};
/** Used to set the menu-surface calculations based on a fixed position menu. */
MDCMenuSurfaceFoundation.prototype.setFixedPosition = function (isFixedPosition) {
this.isFixedPosition_ = isFixedPosition;
};
/** Sets the menu-surface position on the page. */
MDCMenuSurfaceFoundation.prototype.setAbsolutePosition = function (x, y) {
this.position_.x = this.isFinite_(x) ? x : 0;
this.position_.y = this.isFinite_(y) ? y : 0;
};
MDCMenuSurfaceFoundation.prototype.setQuickOpen = function (quickOpen) {
this.isQuickOpen_ = quickOpen;
};
MDCMenuSurfaceFoundation.prototype.isOpen = function () {
return this.isOpen_;
};
/**
* Open the menu surface.
*/
MDCMenuSurfaceFoundation.prototype.open = function () {
var _this = this;
this.adapter_.saveFocus();
if (!this.isQuickOpen_) {
this.adapter_.addClass(MDCMenuSurfaceFoundation.cssClasses.ANIMATING_OPEN);
}
this.animationRequestId_ = requestAnimationFrame(function () {
_this.adapter_.addClass(MDCMenuSurfaceFoundation.cssClasses.OPEN);
_this.dimensions_ = _this.adapter_.getInnerDimensions();
_this.autoPosition_();
if (_this.isQuickOpen_) {
_this.adapter_.notifyOpen();
}
else {
_this.openAnimationEndTimerId_ = setTimeout(function () {
_this.openAnimationEndTimerId_ = 0;
_this.adapter_.removeClass(MDCMenuSurfaceFoundation.cssClasses.ANIMATING_OPEN);
_this.adapter_.notifyOpen();
}, numbers$4.TRANSITION_OPEN_DURATION);
}
});
this.isOpen_ = true;
};
/**
* Closes the menu surface.
*/
MDCMenuSurfaceFoundation.prototype.close = function (skipRestoreFocus) {
var _this = this;
if (skipRestoreFocus === void 0) { skipRestoreFocus = false; }
if (!this.isQuickOpen_) {
this.adapter_.addClass(MDCMenuSurfaceFoundation.cssClasses.ANIMATING_CLOSED);
}
requestAnimationFrame(function () {
_this.adapter_.removeClass(MDCMenuSurfaceFoundation.cssClasses.OPEN);
if (_this.isQuickOpen_) {
_this.adapter_.notifyClose();
}
else {
_this.closeAnimationEndTimerId_ = setTimeout(function () {
_this.closeAnimationEndTimerId_ = 0;
_this.adapter_.removeClass(MDCMenuSurfaceFoundation.cssClasses.ANIMATING_CLOSED);
_this.adapter_.notifyClose();
}, numbers$4.TRANSITION_CLOSE_DURATION);
}
});
this.isOpen_ = false;
if (!skipRestoreFocus) {
this.maybeRestoreFocus_();
}
};
/** Handle clicks and close if not within menu-surface element. */
MDCMenuSurfaceFoundation.prototype.handleBodyClick = function (evt) {
var el = evt.target;
if (this.adapter_.isElementInContainer(el)) {
return;
}
this.close();
};
/** Handle keys that close the surface. */
MDCMenuSurfaceFoundation.prototype.handleKeydown = function (evt) {
var keyCode = evt.keyCode, key = evt.key;
var isEscape = key === 'Escape' || keyCode === 27;
if (isEscape) {
this.close();
}
};
MDCMenuSurfaceFoundation.prototype.autoPosition_ = function () {
var _a;
// Compute measurements for autoposition methods reuse.
this.measurements_ = this.getAutoLayoutMeasurements_();
var corner = this.getOriginCorner_();
var maxMenuSurfaceHeight = this.getMenuSurfaceMaxHeight_(corner);
var verticalAlignment = this.hasBit_(corner, CornerBit.BOTTOM) ? 'bottom' : 'top';
var horizontalAlignment = this.hasBit_(corner, CornerBit.RIGHT) ? 'right' : 'left';
var horizontalOffset = this.getHorizontalOriginOffset_(corner);
var verticalOffset = this.getVerticalOriginOffset_(corner);
var _b = this.measurements_, anchorSize = _b.anchorSize, surfaceSize = _b.surfaceSize;
var position = (_a = {},
_a[horizontalAlignment] = horizontalOffset,
_a[verticalAlignment] = verticalOffset,
_a);
// Center align when anchor width is comparable or greater than menu surface, otherwise keep corner.
if (anchorSize.width / surfaceSize.width > numbers$4.ANCHOR_TO_MENU_SURFACE_WIDTH_RATIO) {
horizontalAlignment = 'center';
}
// If the menu-surface has been hoisted to the body, it's no longer relative to the anchor element
if (this.isHoistedElement_ || this.isFixedPosition_) {
this.adjustPositionForHoistedElement_(position);
}
this.adapter_.setTransformOrigin(horizontalAlignment + " " + verticalAlignment);
this.adapter_.setPosition(position);
this.adapter_.setMaxHeight(maxMenuSurfaceHeight ? maxMenuSurfaceHeight + 'px' : '');
};
/**
* @return Measurements used to position menu surface popup.
*/
MDCMenuSurfaceFoundation.prototype.getAutoLayoutMeasurements_ = function () {
var anchorRect = this.adapter_.getAnchorDimensions();
var bodySize = this.adapter_.getBodyDimensions();
var viewportSize = this.adapter_.getWindowDimensions();
var windowScroll = this.adapter_.getWindowScroll();
if (!anchorRect) {
// tslint:disable:object-literal-sort-keys Positional properties are more readable when they're grouped together
anchorRect = {
top: this.position_.y,
right: this.position_.x,
bottom: this.position_.y,
left: this.position_.x,
width: 0,
height: 0,
};
// tslint:enable:object-literal-sort-keys
}
return {
anchorSize: anchorRect,
bodySize: bodySize,
surfaceSize: this.dimensions_,
viewportDistance: {
// tslint:disable:object-literal-sort-keys Positional properties are more readable when they're grouped together
top: anchorRect.top,
right: viewportSize.width - anchorRect.right,
bottom: viewportSize.height - anchorRect.bottom,
left: anchorRect.left,
},
viewportSize: viewportSize,
windowScroll: windowScroll,
};
};
/**
* Computes the corner of the anchor from which to animate and position the menu surface.
*/
MDCMenuSurfaceFoundation.prototype.getOriginCorner_ = function () {
// Defaults: open from the top left.
var corner = exports.Corner.TOP_LEFT;
var _a = this.measurements_, viewportDistance = _a.viewportDistance, anchorSize = _a.anchorSize, surfaceSize = _a.surfaceSize;
var isBottomAligned = this.hasBit_(this.anchorCorner_, CornerBit.BOTTOM);
var availableTop = isBottomAligned ? viewportDistance.top + anchorSize.height + this.anchorMargin_.bottom
: viewportDistance.top + this.anchorMargin_.top;
var availableBottom = isBottomAligned ? viewportDistance.bottom - this.anchorMargin_.bottom
: viewportDistance.bottom + anchorSize.height - this.anchorMargin_.top;
var topOverflow = surfaceSize.height - availableTop;
var bottomOverflow = surfaceSize.height - availableBottom;
if (bottomOverflow > 0 && topOverflow < bottomOverflow) {
corner = this.setBit_(corner, CornerBit.BOTTOM);
}
var isRtl = this.adapter_.isRtl();
var isFlipRtl = this.hasBit_(this.anchorCorner_, CornerBit.FLIP_RTL);
var avoidHorizontalOverlap = this.hasBit_(this.anchorCorner_, CornerBit.RIGHT);
var isAlignedRight = (avoidHorizontalOverlap && !isRtl) ||
(!avoidHorizontalOverlap && isFlipRtl && isRtl);
var availableLeft = isAlignedRight ? viewportDistance.left + anchorSize.width + this.anchorMargin_.right :
viewportDistance.left + this.anchorMargin_.left;
var availableRight = isAlignedRight ? viewportDistance.right - this.anchorMargin_.right :
viewportDistance.right + anchorSize.width - this.anchorMargin_.left;
var leftOverflow = surfaceSize.width - availableLeft;
var rightOverflow = surfaceSize.width - availableRight;
if ((leftOverflow < 0 && isAlignedRight && isRtl) ||
(avoidHorizontalOverlap && !isAlignedRight && leftOverflow < 0) ||
(rightOverflow > 0 && leftOverflow < rightOverflow)) {
corner = this.setBit_(corner, CornerBit.RIGHT);
}
return corner;
};
/**
* @param corner Origin corner of the menu surface.
* @return Maximum height of the menu surface, based on available space. 0 indicates should not be set.
*/
MDCMenuSurfaceFoundation.prototype.getMenuSurfaceMaxHeight_ = function (corner) {
var viewportDistance = this.measurements_.viewportDistance;
var maxHeight = 0;
var isBottomAligned = this.hasBit_(corner, CornerBit.BOTTOM);
var isBottomAnchored = this.hasBit_(this.anchorCorner_, CornerBit.BOTTOM);
var MARGIN_TO_EDGE = MDCMenuSurfaceFoundation.numbers.MARGIN_TO_EDGE;
// When maximum height is not specified, it is handled from CSS.
if (isBottomAligned) {
maxHeight = viewportDistance.top + this.anchorMargin_.top - MARGIN_TO_EDGE;
if (!isBottomAnchored) {
maxHeight += this.measurements_.anchorSize.height;
}
}
else {
maxHeight =
viewportDistance.bottom - this.anchorMargin_.bottom + this.measurements_.anchorSize.height - MARGIN_TO_EDGE;
if (isBottomAnchored) {
maxHeight -= this.measurements_.anchorSize.height;
}
}
return maxHeight;
};
/**
* @param corner Origin corner of the menu surface.
* @return Horizontal offset of menu surface origin corner from corresponding anchor corner.
*/
MDCMenuSurfaceFoundation.prototype.getHorizontalOriginOffset_ = function (corner) {
var anchorSize = this.measurements_.anchorSize;
// isRightAligned corresponds to using the 'right' property on the surface.
var isRightAligned = this.hasBit_(corner, CornerBit.RIGHT);
var avoidHorizontalOverlap = this.hasBit_(this.anchorCorner_, CornerBit.RIGHT);
if (isRightAligned) {
var rightOffset = avoidHorizontalOverlap ? anchorSize.width - this.anchorMargin_.left : this.anchorMargin_.right;
// For hoisted or fixed elements, adjust the offset by the difference between viewport width and body width so
// when we calculate the right value (`adjustPositionForHoistedElement_`) based on the element position,
// the right property is correct.
if (this.isHoistedElement_ || this.isFixedPosition_) {
return rightOffset - (this.measurements_.viewportSize.width - this.measurements_.bodySize.width);
}
return rightOffset;
}
return avoidHorizontalOverlap ? anchorSize.width - this.anchorMargin_.right : this.anchorMargin_.left;
};
/**
* @param corner Origin corner of the menu surface.
* @return Vertical offset of menu surface origin corner from corresponding anchor corner.
*/
MDCMenuSurfaceFoundation.prototype.getVerticalOriginOffset_ = function (corner) {
var anchorSize = this.measurements_.anchorSize;
var isBottomAligned = this.hasBit_(corner, CornerBit.BOTTOM);
var avoidVerticalOverlap = this.hasBit_(this.anchorCorner_, CornerBit.BOTTOM);
var y = 0;
if (isBottomAligned) {
y = avoidVerticalOverlap ? anchorSize.height - this.anchorMargin_.top : -this.anchorMargin_.bottom;
}
else {
y = avoidVerticalOverlap ? (anchorSize.height + this.anchorMargin_.bottom) : this.anchorMargin_.top;
}
return y;
};
/** Calculates the offsets for positioning the menu-surface when the menu-surface has been hoisted to the body. */
MDCMenuSurfaceFoundation.prototype.adjustPositionForHoistedElement_ = function (position) {
var e_1, _a;
var _b = this.measurements_, windowScroll = _b.windowScroll, viewportDistance = _b.viewportDistance;
var props = Object.keys(position);
try {
for (var props_1 = __values(props), props_1_1 = props_1.next(); !props_1_1.done; props_1_1 = props_1.next()) {
var prop = props_1_1.value;
var value = position[prop] || 0;
// Hoisted surfaces need to have the anchor elements location on the page added to the
// position properties for proper alignment on the body.
value += viewportDistance[prop];
// Surfaces that are absolutely positioned need to have additional calculations for scroll
// and bottom positioning.
if (!this.isFixedPosition_) {
if (prop === 'top') {
value += windowScroll.y;
}
else if (prop === 'bottom') {
value -= windowScroll.y;
}
else if (prop === 'left') {
value += windowScroll.x;
}
else { // prop === 'right'
value -= windowScroll.x;
}
}
position[prop] = value;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (props_1_1 && !props_1_1.done && (_a = props_1.return)) _a.call(props_1);
}
finally { if (e_1) throw e_1.error; }
}
};
/**
* The last focused element when the menu surface was opened should regain focus, if the user is
* focused on or within the menu surface when it is closed.
*/
MDCMenuSurfaceFoundation.prototype.maybeRestoreFocus_ = function () {
var isRootFocused = this.adapter_.isFocused();
var childHasFocus = document.activeElement && this.adapter_.isElementInContainer(document.activeElement);
if (isRootFocused || childHasFocus) {
this.adapter_.restoreFocus();
}
};
MDCMenuSurfaceFoundation.prototype.hasBit_ = function (corner, bit) {
return Boolean(corner & bit); // tslint:disable-line:no-bitwise
};
MDCMenuSurfaceFoundation.prototype.setBit_ = function (corner, bit) {
return corner | bit; // tslint:disable-line:no-bitwise
};
/**
* isFinite that doesn't force conversion to number type.
* Equivalent to Number.isFinite in ES2015, which is not supported in IE.
*/
MDCMenuSurfaceFoundation.prototype.isFinite_ = function (num) {
return typeof num === 'number' && isFinite(num);
};
return MDCMenuSurfaceFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cachedCssTransformPropertyName_;
/**
* Returns the name of the correct transform property to use on the current browser.
*/
function getTransformPropertyName(globalObj, forceRefresh) {
if (forceRefresh === void 0) { forceRefresh = false; }
if (cachedCssTransformPropertyName_ === undefined || forceRefresh) {
var el = globalObj.document.createElement('div');
cachedCssTransformPropertyName_ = 'transform' in el.style ? 'transform' : 'webkitTransform';
}
return cachedCssTransformPropertyName_;
}
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCMenuSurface = /** @class */ (function (_super) {
__extends(MDCMenuSurface, _super);
function MDCMenuSurface() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCMenuSurface.attachTo = function (root) {
return new MDCMenuSurface(root);
};
MDCMenuSurface.prototype.initialSyncWithDOM = function () {
var _this = this;
var parentEl = this.root_.parentElement;
this.anchorElement = parentEl && parentEl.classList.contains(cssClasses$b.ANCHOR) ? parentEl : null;
if (this.root_.classList.contains(cssClasses$b.FIXED)) {
this.setFixedPosition(true);
}
this.handleKeydown_ = function (evt) { return _this.foundation_.handleKeydown(evt); };
this.handleBodyClick_ = function (evt) { return _this.foundation_.handleBodyClick(evt); };
this.registerBodyClickListener_ = function () { return document.body.addEventListener('click', _this.handleBodyClick_); };
this.deregisterBodyClickListener_ = function () { return document.body.removeEventListener('click', _this.handleBodyClick_); };
this.listen('keydown', this.handleKeydown_);
this.listen(strings$d.OPENED_EVENT, this.registerBodyClickListener_);
this.listen(strings$d.CLOSED_EVENT, this.deregisterBodyClickListener_);
};
MDCMenuSurface.prototype.destroy = function () {
this.unlisten('keydown', this.handleKeydown_);
this.unlisten(strings$d.OPENED_EVENT, this.registerBodyClickListener_);
this.unlisten(strings$d.CLOSED_EVENT, this.deregisterBodyClickListener_);
_super.prototype.destroy.call(this);
};
MDCMenuSurface.prototype.isOpen = function () {
return this.foundation_.isOpen();
};
MDCMenuSurface.prototype.open = function () {
this.foundation_.open();
};
MDCMenuSurface.prototype.close = function (skipRestoreFocus) {
if (skipRestoreFocus === void 0) { skipRestoreFocus = false; }
this.foundation_.close(skipRestoreFocus);
};
Object.defineProperty(MDCMenuSurface.prototype, "quickOpen", {
set: function (quickOpen) {
this.foundation_.setQuickOpen(quickOpen);
},
enumerable: true,
configurable: true
});
/**
* Removes the menu-surface from it's current location and appends it to the
* body to overcome any overflow:hidden issues.
*/
MDCMenuSurface.prototype.hoistMenuToBody = function () {
document.body.appendChild(this.root_);
this.setIsHoisted(true);
};
/** Sets the foundation to use page offsets for an positioning when the menu is hoisted to the body. */
MDCMenuSurface.prototype.setIsHoisted = function (isHoisted) {
this.foundation_.setIsHoisted(isHoisted);
};
/** Sets the element that the menu-surface is anchored to. */
MDCMenuSurface.prototype.setMenuSurfaceAnchorElement = function (element) {
this.anchorElement = element;
};
/** Sets the menu-surface to position: fixed. */
MDCMenuSurface.prototype.setFixedPosition = function (isFixed) {
if (isFixed) {
this.root_.classList.add(cssClasses$b.FIXED);
}
else {
this.root_.classList.remove(cssClasses$b.FIXED);
}
this.foundation_.setFixedPosition(isFixed);
};
/** Sets the absolute x/y position to position based on. Requires the menu to be hoisted. */
MDCMenuSurface.prototype.setAbsolutePosition = function (x, y) {
this.foundation_.setAbsolutePosition(x, y);
this.setIsHoisted(true);
};
/**
* @param corner Default anchor corner alignment of top-left surface corner.
*/
MDCMenuSurface.prototype.setAnchorCorner = function (corner) {
this.foundation_.setAnchorCorner(corner);
};
MDCMenuSurface.prototype.setAnchorMargin = function (margin) {
this.foundation_.setAnchorMargin(margin);
};
MDCMenuSurface.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
hasClass: function (className) { return _this.root_.classList.contains(className); },
hasAnchor: function () { return !!_this.anchorElement; },
notifyClose: function () { return _this.emit(MDCMenuSurfaceFoundation.strings.CLOSED_EVENT, {}); },
notifyOpen: function () { return _this.emit(MDCMenuSurfaceFoundation.strings.OPENED_EVENT, {}); },
isElementInContainer: function (el) { return _this.root_.contains(el); },
isRtl: function () { return getComputedStyle(_this.root_).getPropertyValue('direction') === 'rtl'; },
setTransformOrigin: function (origin) {
var propertyName = getTransformPropertyName(window) + "-origin";
_this.root_.style.setProperty(propertyName, origin);
},
isFocused: function () { return document.activeElement === _this.root_; },
saveFocus: function () {
_this.previousFocus_ = document.activeElement;
},
restoreFocus: function () {
if (_this.root_.contains(document.activeElement)) {
if (_this.previousFocus_ && _this.previousFocus_.focus) {
_this.previousFocus_.focus();
}
}
},
getInnerDimensions: function () {
return { width: _this.root_.offsetWidth, height: _this.root_.offsetHeight };
},
getAnchorDimensions: function () { return _this.anchorElement ? _this.anchorElement.getBoundingClientRect() : null; },
getWindowDimensions: function () {
return { width: window.innerWidth, height: window.innerHeight };
},
getBodyDimensions: function () {
return { width: document.body.clientWidth, height: document.body.clientHeight };
},
getWindowScroll: function () {
return { x: window.pageXOffset, y: window.pageYOffset };
},
setPosition: function (position) {
_this.root_.style.left = 'left' in position ? position.left + "px" : '';
_this.root_.style.right = 'right' in position ? position.right + "px" : '';
_this.root_.style.top = 'top' in position ? position.top + "px" : '';
_this.root_.style.bottom = 'bottom' in position ? position.bottom + "px" : '';
},
setMaxHeight: function (height) {
_this.root_.style.maxHeight = height;
},
};
// tslint:enable:object-literal-sort-keys
return new MDCMenuSurfaceFoundation(adapter);
};
return MDCMenuSurface;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$c = {
MENU_SELECTED_LIST_ITEM: 'mdc-menu-item--selected',
MENU_SELECTION_GROUP: 'mdc-menu__selection-group',
ROOT: 'mdc-menu',
};
var strings$e = {
ARIA_CHECKED_ATTR: 'aria-checked',
ARIA_DISABLED_ATTR: 'aria-disabled',
CHECKBOX_SELECTOR: 'input[type="checkbox"]',
LIST_SELECTOR: '.mdc-list',
SELECTED_EVENT: 'MDCMenu:selected',
};
var numbers$5 = {
FOCUS_ROOT_INDEX: -1,
};
(function (DefaultFocusState) {
DefaultFocusState[DefaultFocusState["NONE"] = 0] = "NONE";
DefaultFocusState[DefaultFocusState["LIST_ROOT"] = 1] = "LIST_ROOT";
DefaultFocusState[DefaultFocusState["FIRST_ITEM"] = 2] = "FIRST_ITEM";
DefaultFocusState[DefaultFocusState["LAST_ITEM"] = 3] = "LAST_ITEM";
})(exports.DefaultFocusState || (exports.DefaultFocusState = {}));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCMenuFoundation = /** @class */ (function (_super) {
__extends(MDCMenuFoundation, _super);
function MDCMenuFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCMenuFoundation.defaultAdapter, adapter)) || this;
_this.closeAnimationEndTimerId_ = 0;
_this.defaultFocusState_ = exports.DefaultFocusState.LIST_ROOT;
return _this;
}
Object.defineProperty(MDCMenuFoundation, "cssClasses", {
get: function () {
return cssClasses$c;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCMenuFoundation, "strings", {
get: function () {
return strings$e;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCMenuFoundation, "numbers", {
get: function () {
return numbers$5;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCMenuFoundation, "defaultAdapter", {
/**
* @see {@link MDCMenuAdapter} for typing information on parameters and return types.
*/
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClassToElementAtIndex: function () { return undefined; },
removeClassFromElementAtIndex: function () { return undefined; },
addAttributeToElementAtIndex: function () { return undefined; },
removeAttributeFromElementAtIndex: function () { return undefined; },
elementContainsClass: function () { return false; },
closeSurface: function () { return undefined; },
getElementIndex: function () { return -1; },
notifySelected: function () { return undefined; },
getMenuItemCount: function () { return 0; },
focusItemAtIndex: function () { return undefined; },
focusListRoot: function () { return undefined; },
getSelectedSiblingOfItemAtIndex: function () { return -1; },
isSelectableItemAtIndex: function () { return false; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCMenuFoundation.prototype.destroy = function () {
if (this.closeAnimationEndTimerId_) {
clearTimeout(this.closeAnimationEndTimerId_);
}
this.adapter_.closeSurface();
};
MDCMenuFoundation.prototype.handleKeydown = function (evt) {
var key = evt.key, keyCode = evt.keyCode;
var isTab = key === 'Tab' || keyCode === 9;
if (isTab) {
this.adapter_.closeSurface(/** skipRestoreFocus */ true);
}
};
MDCMenuFoundation.prototype.handleItemAction = function (listItem) {
var _this = this;
var index = this.adapter_.getElementIndex(listItem);
if (index < 0) {
return;
}
this.adapter_.notifySelected({ index: index });
this.adapter_.closeSurface();
// Wait for the menu to close before adding/removing classes that affect styles.
this.closeAnimationEndTimerId_ = setTimeout(function () {
// Recompute the index in case the menu contents have changed.
var recomputedIndex = _this.adapter_.getElementIndex(listItem);
if (_this.adapter_.isSelectableItemAtIndex(recomputedIndex)) {
_this.setSelectedIndex(recomputedIndex);
}
}, MDCMenuSurfaceFoundation.numbers.TRANSITION_CLOSE_DURATION);
};
MDCMenuFoundation.prototype.handleMenuSurfaceOpened = function () {
switch (this.defaultFocusState_) {
case exports.DefaultFocusState.FIRST_ITEM:
this.adapter_.focusItemAtIndex(0);
break;
case exports.DefaultFocusState.LAST_ITEM:
this.adapter_.focusItemAtIndex(this.adapter_.getMenuItemCount() - 1);
break;
case exports.DefaultFocusState.NONE:
// Do nothing.
break;
default:
this.adapter_.focusListRoot();
break;
}
};
/**
* Sets default focus state where the menu should focus every time when menu
* is opened. Focuses the list root (`DefaultFocusState.LIST_ROOT`) element by
* default.
*/
MDCMenuFoundation.prototype.setDefaultFocusState = function (focusState) {
this.defaultFocusState_ = focusState;
};
/**
* Selects the list item at `index` within the menu.
* @param index Index of list item within the menu.
*/
MDCMenuFoundation.prototype.setSelectedIndex = function (index) {
this.validatedIndex_(index);
if (!this.adapter_.isSelectableItemAtIndex(index)) {
throw new Error('MDCMenuFoundation: No selection group at specified index.');
}
var prevSelectedIndex = this.adapter_.getSelectedSiblingOfItemAtIndex(index);
if (prevSelectedIndex >= 0) {
this.adapter_.removeAttributeFromElementAtIndex(prevSelectedIndex, strings$e.ARIA_CHECKED_ATTR);
this.adapter_.removeClassFromElementAtIndex(prevSelectedIndex, cssClasses$c.MENU_SELECTED_LIST_ITEM);
}
this.adapter_.addClassToElementAtIndex(index, cssClasses$c.MENU_SELECTED_LIST_ITEM);
this.adapter_.addAttributeToElementAtIndex(index, strings$e.ARIA_CHECKED_ATTR, 'true');
};
/**
* Sets the enabled state to isEnabled for the menu item at the given index.
* @param index Index of the menu item
* @param isEnabled The desired enabled state of the menu item.
*/
MDCMenuFoundation.prototype.setEnabled = function (index, isEnabled) {
this.validatedIndex_(index);
if (isEnabled) {
this.adapter_.removeClassFromElementAtIndex(index, cssClasses$5.LIST_ITEM_DISABLED_CLASS);
this.adapter_.addAttributeToElementAtIndex(index, strings$e.ARIA_DISABLED_ATTR, 'false');
}
else {
this.adapter_.addClassToElementAtIndex(index, cssClasses$5.LIST_ITEM_DISABLED_CLASS);
this.adapter_.addAttributeToElementAtIndex(index, strings$e.ARIA_DISABLED_ATTR, 'true');
}
};
MDCMenuFoundation.prototype.validatedIndex_ = function (index) {
var menuSize = this.adapter_.getMenuItemCount();
var isIndexInRange = index >= 0 && index < menuSize;
if (!isIndexInRange) {
throw new Error('MDCMenuFoundation: No list item at specified index.');
}
};
return MDCMenuFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCMenu = /** @class */ (function (_super) {
__extends(MDCMenu, _super);
function MDCMenu() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCMenu.attachTo = function (root) {
return new MDCMenu(root);
};
MDCMenu.prototype.initialize = function (menuSurfaceFactory, listFactory) {
if (menuSurfaceFactory === void 0) { menuSurfaceFactory = function (el) { return new MDCMenuSurface(el); }; }
if (listFactory === void 0) { listFactory = function (el) { return new MDCList(el); }; }
this.menuSurfaceFactory_ = menuSurfaceFactory;
this.listFactory_ = listFactory;
};
MDCMenu.prototype.initialSyncWithDOM = function () {
var _this = this;
this.menuSurface_ = this.menuSurfaceFactory_(this.root_);
var list = this.root_.querySelector(strings$e.LIST_SELECTOR);
if (list) {
this.list_ = this.listFactory_(list);
this.list_.wrapFocus = true;
}
else {
this.list_ = null;
}
this.handleKeydown_ = function (evt) { return _this.foundation_.handleKeydown(evt); };
this.handleItemAction_ = function (evt) { return _this.foundation_.handleItemAction(_this.items[evt.detail.index]); };
this.handleMenuSurfaceOpened_ = function () { return _this.foundation_.handleMenuSurfaceOpened(); };
this.menuSurface_.listen(MDCMenuSurfaceFoundation.strings.OPENED_EVENT, this.handleMenuSurfaceOpened_);
this.listen('keydown', this.handleKeydown_);
this.listen(MDCListFoundation.strings.ACTION_EVENT, this.handleItemAction_);
};
MDCMenu.prototype.destroy = function () {
if (this.list_) {
this.list_.destroy();
}
this.menuSurface_.destroy();
this.menuSurface_.unlisten(MDCMenuSurfaceFoundation.strings.OPENED_EVENT, this.handleMenuSurfaceOpened_);
this.unlisten('keydown', this.handleKeydown_);
this.unlisten(MDCListFoundation.strings.ACTION_EVENT, this.handleItemAction_);
_super.prototype.destroy.call(this);
};
Object.defineProperty(MDCMenu.prototype, "open", {
get: function () {
return this.menuSurface_.isOpen();
},
set: function (value) {
if (value) {
this.menuSurface_.open();
}
else {
this.menuSurface_.close();
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCMenu.prototype, "wrapFocus", {
get: function () {
return this.list_ ? this.list_.wrapFocus : false;
},
set: function (value) {
if (this.list_) {
this.list_.wrapFocus = value;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCMenu.prototype, "items", {
/**
* Return the items within the menu. Note that this only contains the set of elements within
* the items container that are proper list items, and not supplemental / presentational DOM
* elements.
*/
get: function () {
return this.list_ ? this.list_.listElements : [];
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCMenu.prototype, "quickOpen", {
set: function (quickOpen) {
this.menuSurface_.quickOpen = quickOpen;
},
enumerable: true,
configurable: true
});
/**
* Sets default focus state where the menu should focus every time when menu
* is opened. Focuses the list root (`DefaultFocusState.LIST_ROOT`) element by
* default.
* @param focusState Default focus state.
*/
MDCMenu.prototype.setDefaultFocusState = function (focusState) {
this.foundation_.setDefaultFocusState(focusState);
};
/**
* @param corner Default anchor corner alignment of top-left menu corner.
*/
MDCMenu.prototype.setAnchorCorner = function (corner) {
this.menuSurface_.setAnchorCorner(corner);
};
MDCMenu.prototype.setAnchorMargin = function (margin) {
this.menuSurface_.setAnchorMargin(margin);
};
/**
* Sets the list item as the selected row at the specified index.
* @param index Index of list item within menu.
*/
MDCMenu.prototype.setSelectedIndex = function (index) {
this.foundation_.setSelectedIndex(index);
};
/**
* Sets the enabled state to isEnabled for the menu item at the given index.
* @param index Index of the menu item
* @param isEnabled The desired enabled state of the menu item.
*/
MDCMenu.prototype.setEnabled = function (index, isEnabled) {
this.foundation_.setEnabled(index, isEnabled);
};
/**
* @return The item within the menu at the index specified.
*/
MDCMenu.prototype.getOptionByIndex = function (index) {
var items = this.items;
if (index < items.length) {
return this.items[index];
}
else {
return null;
}
};
MDCMenu.prototype.setFixedPosition = function (isFixed) {
this.menuSurface_.setFixedPosition(isFixed);
};
MDCMenu.prototype.hoistMenuToBody = function () {
this.menuSurface_.hoistMenuToBody();
};
MDCMenu.prototype.setIsHoisted = function (isHoisted) {
this.menuSurface_.setIsHoisted(isHoisted);
};
MDCMenu.prototype.setAbsolutePosition = function (x, y) {
this.menuSurface_.setAbsolutePosition(x, y);
};
/**
* Sets the element that the menu-surface is anchored to.
*/
MDCMenu.prototype.setAnchorElement = function (element) {
this.menuSurface_.anchorElement = element;
};
MDCMenu.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
addClassToElementAtIndex: function (index, className) {
var list = _this.items;
list[index].classList.add(className);
},
removeClassFromElementAtIndex: function (index, className) {
var list = _this.items;
list[index].classList.remove(className);
},
addAttributeToElementAtIndex: function (index, attr, value) {
var list = _this.items;
list[index].setAttribute(attr, value);
},
removeAttributeFromElementAtIndex: function (index, attr) {
var list = _this.items;
list[index].removeAttribute(attr);
},
elementContainsClass: function (element, className) { return element.classList.contains(className); },
closeSurface: function (skipRestoreFocus) { return _this.menuSurface_.close(skipRestoreFocus); },
getElementIndex: function (element) { return _this.items.indexOf(element); },
notifySelected: function (evtData) { return _this.emit(strings$e.SELECTED_EVENT, {
index: evtData.index,
item: _this.items[evtData.index],
}); },
getMenuItemCount: function () { return _this.items.length; },
focusItemAtIndex: function (index) { return _this.items[index].focus(); },
focusListRoot: function () { return _this.root_.querySelector(strings$e.LIST_SELECTOR).focus(); },
isSelectableItemAtIndex: function (index) { return !!closest(_this.items[index], "." + cssClasses$c.MENU_SELECTION_GROUP); },
getSelectedSiblingOfItemAtIndex: function (index) {
var selectionGroupEl = closest(_this.items[index], "." + cssClasses$c.MENU_SELECTION_GROUP);
var selectedItemEl = selectionGroupEl.querySelector("." + cssClasses$c.MENU_SELECTED_LIST_ITEM);
return selectedItemEl ? _this.items.indexOf(selectedItemEl) : -1;
},
};
// tslint:enable:object-literal-sort-keys
return new MDCMenuFoundation(adapter);
};
return MDCMenu;
}(MDCComponent));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var strings$f = {
NATIVE_CONTROL_SELECTOR: '.mdc-radio__native-control',
};
var cssClasses$d = {
DISABLED: 'mdc-radio--disabled',
ROOT: 'mdc-radio',
};
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCRadioFoundation = /** @class */ (function (_super) {
__extends(MDCRadioFoundation, _super);
function MDCRadioFoundation(adapter) {
return _super.call(this, __assign({}, MDCRadioFoundation.defaultAdapter, adapter)) || this;
}
Object.defineProperty(MDCRadioFoundation, "cssClasses", {
get: function () {
return cssClasses$d;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCRadioFoundation, "strings", {
get: function () {
return strings$f;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCRadioFoundation, "defaultAdapter", {
get: function () {
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
setNativeControlDisabled: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCRadioFoundation.prototype.setDisabled = function (disabled) {
var DISABLED = MDCRadioFoundation.cssClasses.DISABLED;
this.adapter_.setNativeControlDisabled(disabled);
if (disabled) {
this.adapter_.addClass(DISABLED);
}
else {
this.adapter_.removeClass(DISABLED);
}
};
return MDCRadioFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCRadio = /** @class */ (function (_super) {
__extends(MDCRadio, _super);
function MDCRadio() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.ripple_ = _this.createRipple_();
return _this;
}
MDCRadio.attachTo = function (root) {
return new MDCRadio(root);
};
Object.defineProperty(MDCRadio.prototype, "checked", {
get: function () {
return this.nativeControl_.checked;
},
set: function (checked) {
this.nativeControl_.checked = checked;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCRadio.prototype, "disabled", {
get: function () {
return this.nativeControl_.disabled;
},
set: function (disabled) {
this.foundation_.setDisabled(disabled);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCRadio.prototype, "value", {
get: function () {
return this.nativeControl_.value;
},
set: function (value) {
this.nativeControl_.value = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCRadio.prototype, "ripple", {
get: function () {
return this.ripple_;
},
enumerable: true,
configurable: true
});
MDCRadio.prototype.destroy = function () {
this.ripple_.destroy();
_super.prototype.destroy.call(this);
};
MDCRadio.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
setNativeControlDisabled: function (disabled) { return _this.nativeControl_.disabled = disabled; },
};
return new MDCRadioFoundation(adapter);
};
MDCRadio.prototype.createRipple_ = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = __assign({}, MDCRipple.createAdapter(this), { registerInteractionHandler: function (evtType, handler) { return _this.nativeControl_.addEventListener(evtType, handler, applyPassive()); }, deregisterInteractionHandler: function (evtType, handler) { return _this.nativeControl_.removeEventListener(evtType, handler, applyPassive()); },
// Radio buttons technically go "active" whenever there is *any* keyboard interaction.
// This is not the UI we desire.
isSurfaceActive: function () { return false; }, isUnbounded: function () { return true; } });
// tslint:enable:object-literal-sort-keys
return new MDCRipple(this.root_, new MDCRippleFoundation(adapter));
};
Object.defineProperty(MDCRadio.prototype, "nativeControl_", {
get: function () {
var NATIVE_CONTROL_SELECTOR = MDCRadioFoundation.strings.NATIVE_CONTROL_SELECTOR;
var el = this.root_.querySelector(NATIVE_CONTROL_SELECTOR);
if (!el) {
throw new Error("Radio component requires a " + NATIVE_CONTROL_SELECTOR + " element");
}
return el;
},
enumerable: true,
configurable: true
});
return MDCRadio;
}(MDCComponent));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$e = {
LABEL_FLOAT_ABOVE: 'mdc-floating-label--float-above',
LABEL_SHAKE: 'mdc-floating-label--shake',
ROOT: 'mdc-floating-label',
};
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCFloatingLabelFoundation = /** @class */ (function (_super) {
__extends(MDCFloatingLabelFoundation, _super);
function MDCFloatingLabelFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCFloatingLabelFoundation.defaultAdapter, adapter)) || this;
_this.shakeAnimationEndHandler_ = function () { return _this.handleShakeAnimationEnd_(); };
return _this;
}
Object.defineProperty(MDCFloatingLabelFoundation, "cssClasses", {
get: function () {
return cssClasses$e;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFloatingLabelFoundation, "defaultAdapter", {
/**
* See {@link MDCFloatingLabelAdapter} for typing information on parameters and return types.
*/
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
getWidth: function () { return 0; },
registerInteractionHandler: function () { return undefined; },
deregisterInteractionHandler: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCFloatingLabelFoundation.prototype.init = function () {
this.adapter_.registerInteractionHandler('animationend', this.shakeAnimationEndHandler_);
};
MDCFloatingLabelFoundation.prototype.destroy = function () {
this.adapter_.deregisterInteractionHandler('animationend', this.shakeAnimationEndHandler_);
};
/**
* Returns the width of the label element.
*/
MDCFloatingLabelFoundation.prototype.getWidth = function () {
return this.adapter_.getWidth();
};
/**
* Styles the label to produce a shake animation to indicate an error.
* @param shouldShake If true, adds the shake CSS class; otherwise, removes shake class.
*/
MDCFloatingLabelFoundation.prototype.shake = function (shouldShake) {
var LABEL_SHAKE = MDCFloatingLabelFoundation.cssClasses.LABEL_SHAKE;
if (shouldShake) {
this.adapter_.addClass(LABEL_SHAKE);
}
else {
this.adapter_.removeClass(LABEL_SHAKE);
}
};
/**
* Styles the label to float or dock.
* @param shouldFloat If true, adds the float CSS class; otherwise, removes float and shake classes to dock the label.
*/
MDCFloatingLabelFoundation.prototype.float = function (shouldFloat) {
var _a = MDCFloatingLabelFoundation.cssClasses, LABEL_FLOAT_ABOVE = _a.LABEL_FLOAT_ABOVE, LABEL_SHAKE = _a.LABEL_SHAKE;
if (shouldFloat) {
this.adapter_.addClass(LABEL_FLOAT_ABOVE);
}
else {
this.adapter_.removeClass(LABEL_FLOAT_ABOVE);
this.adapter_.removeClass(LABEL_SHAKE);
}
};
MDCFloatingLabelFoundation.prototype.handleShakeAnimationEnd_ = function () {
var LABEL_SHAKE = MDCFloatingLabelFoundation.cssClasses.LABEL_SHAKE;
this.adapter_.removeClass(LABEL_SHAKE);
};
return MDCFloatingLabelFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCFloatingLabel = /** @class */ (function (_super) {
__extends(MDCFloatingLabel, _super);
function MDCFloatingLabel() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCFloatingLabel.attachTo = function (root) {
return new MDCFloatingLabel(root);
};
/**
* Styles the label to produce the label shake for errors.
* @param shouldShake If true, shakes the label by adding a CSS class; otherwise, stops shaking by removing the class.
*/
MDCFloatingLabel.prototype.shake = function (shouldShake) {
this.foundation_.shake(shouldShake);
};
/**
* Styles the label to float/dock.
* @param shouldFloat If true, floats the label by adding a CSS class; otherwise, docks it by removing the class.
*/
MDCFloatingLabel.prototype.float = function (shouldFloat) {
this.foundation_.float(shouldFloat);
};
MDCFloatingLabel.prototype.getWidth = function () {
return this.foundation_.getWidth();
};
MDCFloatingLabel.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
getWidth: function () { return _this.root_.scrollWidth; },
registerInteractionHandler: function (evtType, handler) { return _this.listen(evtType, handler); },
deregisterInteractionHandler: function (evtType, handler) { return _this.unlisten(evtType, handler); },
};
// tslint:enable:object-literal-sort-keys
return new MDCFloatingLabelFoundation(adapter);
};
return MDCFloatingLabel;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$f = {
LINE_RIPPLE_ACTIVE: 'mdc-line-ripple--active',
LINE_RIPPLE_DEACTIVATING: 'mdc-line-ripple--deactivating',
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCLineRippleFoundation = /** @class */ (function (_super) {
__extends(MDCLineRippleFoundation, _super);
function MDCLineRippleFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCLineRippleFoundation.defaultAdapter, adapter)) || this;
_this.transitionEndHandler_ = function (evt) { return _this.handleTransitionEnd(evt); };
return _this;
}
Object.defineProperty(MDCLineRippleFoundation, "cssClasses", {
get: function () {
return cssClasses$f;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCLineRippleFoundation, "defaultAdapter", {
/**
* See {@link MDCLineRippleAdapter} for typing information on parameters and return types.
*/
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
hasClass: function () { return false; },
setStyle: function () { return undefined; },
registerEventHandler: function () { return undefined; },
deregisterEventHandler: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCLineRippleFoundation.prototype.init = function () {
this.adapter_.registerEventHandler('transitionend', this.transitionEndHandler_);
};
MDCLineRippleFoundation.prototype.destroy = function () {
this.adapter_.deregisterEventHandler('transitionend', this.transitionEndHandler_);
};
MDCLineRippleFoundation.prototype.activate = function () {
this.adapter_.removeClass(cssClasses$f.LINE_RIPPLE_DEACTIVATING);
this.adapter_.addClass(cssClasses$f.LINE_RIPPLE_ACTIVE);
};
MDCLineRippleFoundation.prototype.setRippleCenter = function (xCoordinate) {
this.adapter_.setStyle('transform-origin', xCoordinate + "px center");
};
MDCLineRippleFoundation.prototype.deactivate = function () {
this.adapter_.addClass(cssClasses$f.LINE_RIPPLE_DEACTIVATING);
};
MDCLineRippleFoundation.prototype.handleTransitionEnd = function (evt) {
// Wait for the line ripple to be either transparent or opaque
// before emitting the animation end event
var isDeactivating = this.adapter_.hasClass(cssClasses$f.LINE_RIPPLE_DEACTIVATING);
if (evt.propertyName === 'opacity') {
if (isDeactivating) {
this.adapter_.removeClass(cssClasses$f.LINE_RIPPLE_ACTIVE);
this.adapter_.removeClass(cssClasses$f.LINE_RIPPLE_DEACTIVATING);
}
}
};
return MDCLineRippleFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCLineRipple = /** @class */ (function (_super) {
__extends(MDCLineRipple, _super);
function MDCLineRipple() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCLineRipple.attachTo = function (root) {
return new MDCLineRipple(root);
};
/**
* Activates the line ripple
*/
MDCLineRipple.prototype.activate = function () {
this.foundation_.activate();
};
/**
* Deactivates the line ripple
*/
MDCLineRipple.prototype.deactivate = function () {
this.foundation_.deactivate();
};
/**
* Sets the transform origin given a user's click location.
* The `rippleCenter` is the x-coordinate of the middle of the ripple.
*/
MDCLineRipple.prototype.setRippleCenter = function (xCoordinate) {
this.foundation_.setRippleCenter(xCoordinate);
};
MDCLineRipple.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
hasClass: function (className) { return _this.root_.classList.contains(className); },
setStyle: function (propertyName, value) { return _this.root_.style.setProperty(propertyName, value); },
registerEventHandler: function (evtType, handler) { return _this.listen(evtType, handler); },
deregisterEventHandler: function (evtType, handler) { return _this.unlisten(evtType, handler); },
};
// tslint:enable:object-literal-sort-keys
return new MDCLineRippleFoundation(adapter);
};
return MDCLineRipple;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var strings$g = {
NOTCH_ELEMENT_SELECTOR: '.mdc-notched-outline__notch',
};
var numbers$6 = {
// This should stay in sync with $mdc-notched-outline-padding * 2.
NOTCH_ELEMENT_PADDING: 8,
};
var cssClasses$g = {
NO_LABEL: 'mdc-notched-outline--no-label',
OUTLINE_NOTCHED: 'mdc-notched-outline--notched',
OUTLINE_UPGRADED: 'mdc-notched-outline--upgraded',
};
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCNotchedOutlineFoundation = /** @class */ (function (_super) {
__extends(MDCNotchedOutlineFoundation, _super);
function MDCNotchedOutlineFoundation(adapter) {
return _super.call(this, __assign({}, MDCNotchedOutlineFoundation.defaultAdapter, adapter)) || this;
}
Object.defineProperty(MDCNotchedOutlineFoundation, "strings", {
get: function () {
return strings$g;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCNotchedOutlineFoundation, "cssClasses", {
get: function () {
return cssClasses$g;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCNotchedOutlineFoundation, "numbers", {
get: function () {
return numbers$6;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCNotchedOutlineFoundation, "defaultAdapter", {
/**
* See {@link MDCNotchedOutlineAdapter} for typing information on parameters and return types.
*/
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
setNotchWidthProperty: function () { return undefined; },
removeNotchWidthProperty: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
/**
* Adds the outline notched selector and updates the notch width calculated based off of notchWidth.
*/
MDCNotchedOutlineFoundation.prototype.notch = function (notchWidth) {
var OUTLINE_NOTCHED = MDCNotchedOutlineFoundation.cssClasses.OUTLINE_NOTCHED;
if (notchWidth > 0) {
notchWidth += numbers$6.NOTCH_ELEMENT_PADDING; // Add padding from left/right.
}
this.adapter_.setNotchWidthProperty(notchWidth);
this.adapter_.addClass(OUTLINE_NOTCHED);
};
/**
* Removes notched outline selector to close the notch in the outline.
*/
MDCNotchedOutlineFoundation.prototype.closeNotch = function () {
var OUTLINE_NOTCHED = MDCNotchedOutlineFoundation.cssClasses.OUTLINE_NOTCHED;
this.adapter_.removeClass(OUTLINE_NOTCHED);
this.adapter_.removeNotchWidthProperty();
};
return MDCNotchedOutlineFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCNotchedOutline = /** @class */ (function (_super) {
__extends(MDCNotchedOutline, _super);
function MDCNotchedOutline() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCNotchedOutline.attachTo = function (root) {
return new MDCNotchedOutline(root);
};
MDCNotchedOutline.prototype.initialSyncWithDOM = function () {
this.notchElement_ = this.root_.querySelector(strings$g.NOTCH_ELEMENT_SELECTOR);
var label = this.root_.querySelector('.' + MDCFloatingLabelFoundation.cssClasses.ROOT);
if (label) {
label.style.transitionDuration = '0s';
this.root_.classList.add(cssClasses$g.OUTLINE_UPGRADED);
requestAnimationFrame(function () {
label.style.transitionDuration = '';
});
}
else {
this.root_.classList.add(cssClasses$g.NO_LABEL);
}
};
/**
* Updates classes and styles to open the notch to the specified width.
* @param notchWidth The notch width in the outline.
*/
MDCNotchedOutline.prototype.notch = function (notchWidth) {
this.foundation_.notch(notchWidth);
};
/**
* Updates classes and styles to close the notch.
*/
MDCNotchedOutline.prototype.closeNotch = function () {
this.foundation_.closeNotch();
};
MDCNotchedOutline.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
setNotchWidthProperty: function (width) { return _this.notchElement_.style.setProperty('width', width + 'px'); },
removeNotchWidthProperty: function () { return _this.notchElement_.style.removeProperty('width'); },
};
// tslint:enable:object-literal-sort-keys
return new MDCNotchedOutlineFoundation(adapter);
};
return MDCNotchedOutline;
}(MDCComponent));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$h = {
ACTIVATED: 'mdc-select--activated',
DISABLED: 'mdc-select--disabled',
FOCUSED: 'mdc-select--focused',
INVALID: 'mdc-select--invalid',
OUTLINED: 'mdc-select--outlined',
REQUIRED: 'mdc-select--required',
ROOT: 'mdc-select',
SELECTED_ITEM_CLASS: 'mdc-list-item--selected',
WITH_LEADING_ICON: 'mdc-select--with-leading-icon',
};
var strings$h = {
ARIA_CONTROLS: 'aria-controls',
ARIA_SELECTED_ATTR: 'aria-selected',
CHANGE_EVENT: 'MDCSelect:change',
ENHANCED_VALUE_ATTR: 'data-value',
HIDDEN_INPUT_SELECTOR: 'input[type="hidden"]',
LABEL_SELECTOR: '.mdc-floating-label',
LEADING_ICON_SELECTOR: '.mdc-select__icon',
LINE_RIPPLE_SELECTOR: '.mdc-line-ripple',
MENU_SELECTOR: '.mdc-select__menu',
NATIVE_CONTROL_SELECTOR: '.mdc-select__native-control',
OUTLINE_SELECTOR: '.mdc-notched-outline',
SELECTED_ITEM_SELECTOR: "." + cssClasses$h.SELECTED_ITEM_CLASS,
SELECTED_TEXT_SELECTOR: '.mdc-select__selected-text',
};
var numbers$7 = {
LABEL_SCALE: 0.75,
};
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCSelectFoundation = /** @class */ (function (_super) {
__extends(MDCSelectFoundation, _super);
/* istanbul ignore next: optional argument is not a branch statement */
/**
* @param adapter
* @param foundationMap Map from subcomponent names to their subfoundations.
*/
function MDCSelectFoundation(adapter, foundationMap) {
if (foundationMap === void 0) { foundationMap = {}; }
var _this = _super.call(this, __assign({}, MDCSelectFoundation.defaultAdapter, adapter)) || this;
_this.leadingIcon_ = foundationMap.leadingIcon;
_this.helperText_ = foundationMap.helperText;
return _this;
}
Object.defineProperty(MDCSelectFoundation, "cssClasses", {
get: function () {
return cssClasses$h;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelectFoundation, "numbers", {
get: function () {
return numbers$7;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelectFoundation, "strings", {
get: function () {
return strings$h;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelectFoundation, "defaultAdapter", {
/**
* See {@link MDCSelectAdapter} for typing information on parameters and return types.
*/
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
hasClass: function () { return false; },
activateBottomLine: function () { return undefined; },
deactivateBottomLine: function () { return undefined; },
setValue: function () { return undefined; },
getValue: function () { return ''; },
floatLabel: function () { return undefined; },
getLabelWidth: function () { return 0; },
hasOutline: function () { return false; },
notchOutline: function () { return undefined; },
closeOutline: function () { return undefined; },
openMenu: function () { return undefined; },
closeMenu: function () { return undefined; },
isMenuOpen: function () { return false; },
setSelectedIndex: function () { return undefined; },
setDisabled: function () { return undefined; },
setRippleCenter: function () { return undefined; },
notifyChange: function () { return undefined; },
checkValidity: function () { return false; },
setValid: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCSelectFoundation.prototype.setSelectedIndex = function (index) {
this.adapter_.setSelectedIndex(index);
this.adapter_.closeMenu();
var didChange = true;
this.handleChange(didChange);
};
MDCSelectFoundation.prototype.setValue = function (value) {
this.adapter_.setValue(value);
var didChange = true;
this.handleChange(didChange);
};
MDCSelectFoundation.prototype.getValue = function () {
return this.adapter_.getValue();
};
MDCSelectFoundation.prototype.setDisabled = function (isDisabled) {
if (isDisabled) {
this.adapter_.addClass(cssClasses$h.DISABLED);
}
else {
this.adapter_.removeClass(cssClasses$h.DISABLED);
}
this.adapter_.setDisabled(isDisabled);
this.adapter_.closeMenu();
if (this.leadingIcon_) {
this.leadingIcon_.setDisabled(isDisabled);
}
};
/**
* @param content Sets the content of the helper text.
*/
MDCSelectFoundation.prototype.setHelperTextContent = function (content) {
if (this.helperText_) {
this.helperText_.setContent(content);
}
};
MDCSelectFoundation.prototype.layout = function () {
var openNotch = this.getValue().length > 0;
this.notchOutline(openNotch);
};
MDCSelectFoundation.prototype.handleMenuOpened = function () {
this.adapter_.addClass(cssClasses$h.ACTIVATED);
};
MDCSelectFoundation.prototype.handleMenuClosed = function () {
this.adapter_.removeClass(cssClasses$h.ACTIVATED);
};
/**
* Handles value changes, via change event or programmatic updates.
*/
MDCSelectFoundation.prototype.handleChange = function (didChange) {
if (didChange === void 0) { didChange = true; }
var value = this.getValue();
var optionHasValue = value.length > 0;
var isRequired = this.adapter_.hasClass(cssClasses$h.REQUIRED);
this.notchOutline(optionHasValue);
if (!this.adapter_.hasClass(cssClasses$h.FOCUSED)) {
this.adapter_.floatLabel(optionHasValue);
}
if (didChange) {
this.adapter_.notifyChange(value);
if (isRequired) {
this.setValid(this.isValid());
if (this.helperText_) {
this.helperText_.setValidity(this.isValid());
}
}
}
};
/**
* Handles focus events from select element.
*/
MDCSelectFoundation.prototype.handleFocus = function () {
this.adapter_.addClass(cssClasses$h.FOCUSED);
this.adapter_.floatLabel(true);
this.notchOutline(true);
this.adapter_.activateBottomLine();
if (this.helperText_) {
this.helperText_.showToScreenReader();
}
};
/**
* Handles blur events from select element.
*/
MDCSelectFoundation.prototype.handleBlur = function () {
if (this.adapter_.isMenuOpen()) {
return;
}
this.adapter_.removeClass(cssClasses$h.FOCUSED);
this.handleChange(false);
this.adapter_.deactivateBottomLine();
var isRequired = this.adapter_.hasClass(cssClasses$h.REQUIRED);
if (isRequired) {
this.setValid(this.isValid());
if (this.helperText_) {
this.helperText_.setValidity(this.isValid());
}
}
};
MDCSelectFoundation.prototype.handleClick = function (normalizedX) {
if (this.adapter_.isMenuOpen()) {
return;
}
this.adapter_.setRippleCenter(normalizedX);
this.adapter_.openMenu();
};
MDCSelectFoundation.prototype.handleKeydown = function (event) {
if (this.adapter_.isMenuOpen()) {
return;
}
var isEnter = event.key === 'Enter' || event.keyCode === 13;
var isSpace = event.key === 'Space' || event.keyCode === 32;
var arrowUp = event.key === 'ArrowUp' || event.keyCode === 38;
var arrowDown = event.key === 'ArrowDown' || event.keyCode === 40;
if (this.adapter_.hasClass(cssClasses$h.FOCUSED) && (isEnter || isSpace || arrowUp || arrowDown)) {
this.adapter_.openMenu();
event.preventDefault();
}
};
/**
* Opens/closes the notched outline.
*/
MDCSelectFoundation.prototype.notchOutline = function (openNotch) {
if (!this.adapter_.hasOutline()) {
return;
}
var isFocused = this.adapter_.hasClass(cssClasses$h.FOCUSED);
if (openNotch) {
var labelScale = numbers$7.LABEL_SCALE;
var labelWidth = this.adapter_.getLabelWidth() * labelScale;
this.adapter_.notchOutline(labelWidth);
}
else if (!isFocused) {
this.adapter_.closeOutline();
}
};
/**
* Sets the aria label of the leading icon.
*/
MDCSelectFoundation.prototype.setLeadingIconAriaLabel = function (label) {
if (this.leadingIcon_) {
this.leadingIcon_.setAriaLabel(label);
}
};
/**
* Sets the text content of the leading icon.
*/
MDCSelectFoundation.prototype.setLeadingIconContent = function (content) {
if (this.leadingIcon_) {
this.leadingIcon_.setContent(content);
}
};
MDCSelectFoundation.prototype.setValid = function (isValid) {
this.adapter_.setValid(isValid);
};
MDCSelectFoundation.prototype.isValid = function () {
return this.adapter_.checkValidity();
};
return MDCSelectFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var strings$i = {
ARIA_HIDDEN: 'aria-hidden',
ROLE: 'role',
};
var cssClasses$i = {
HELPER_TEXT_PERSISTENT: 'mdc-select-helper-text--persistent',
HELPER_TEXT_VALIDATION_MSG: 'mdc-select-helper-text--validation-msg',
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCSelectHelperTextFoundation = /** @class */ (function (_super) {
__extends(MDCSelectHelperTextFoundation, _super);
function MDCSelectHelperTextFoundation(adapter) {
return _super.call(this, __assign({}, MDCSelectHelperTextFoundation.defaultAdapter, adapter)) || this;
}
Object.defineProperty(MDCSelectHelperTextFoundation, "cssClasses", {
get: function () {
return cssClasses$i;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelectHelperTextFoundation, "strings", {
get: function () {
return strings$i;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelectHelperTextFoundation, "defaultAdapter", {
/**
* See {@link MDCSelectHelperTextAdapter} for typing information on parameters and return types.
*/
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
hasClass: function () { return false; },
setAttr: function () { return undefined; },
removeAttr: function () { return undefined; },
setContent: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
/**
* Sets the content of the helper text field.
*/
MDCSelectHelperTextFoundation.prototype.setContent = function (content) {
this.adapter_.setContent(content);
};
/**
* Sets the persistency of the helper text.
*/
MDCSelectHelperTextFoundation.prototype.setPersistent = function (isPersistent) {
if (isPersistent) {
this.adapter_.addClass(cssClasses$i.HELPER_TEXT_PERSISTENT);
}
else {
this.adapter_.removeClass(cssClasses$i.HELPER_TEXT_PERSISTENT);
}
};
/**
* @param isValidation True to make the helper text act as an error validation message.
*/
MDCSelectHelperTextFoundation.prototype.setValidation = function (isValidation) {
if (isValidation) {
this.adapter_.addClass(cssClasses$i.HELPER_TEXT_VALIDATION_MSG);
}
else {
this.adapter_.removeClass(cssClasses$i.HELPER_TEXT_VALIDATION_MSG);
}
};
/**
* Makes the helper text visible to screen readers.
*/
MDCSelectHelperTextFoundation.prototype.showToScreenReader = function () {
this.adapter_.removeAttr(strings$i.ARIA_HIDDEN);
};
/**
* Sets the validity of the helper text based on the select validity.
*/
MDCSelectHelperTextFoundation.prototype.setValidity = function (selectIsValid) {
var helperTextIsPersistent = this.adapter_.hasClass(cssClasses$i.HELPER_TEXT_PERSISTENT);
var helperTextIsValidationMsg = this.adapter_.hasClass(cssClasses$i.HELPER_TEXT_VALIDATION_MSG);
var validationMsgNeedsDisplay = helperTextIsValidationMsg && !selectIsValid;
if (validationMsgNeedsDisplay) {
this.adapter_.setAttr(strings$i.ROLE, 'alert');
}
else {
this.adapter_.removeAttr(strings$i.ROLE);
}
if (!helperTextIsPersistent && !validationMsgNeedsDisplay) {
this.hide_();
}
};
/**
* Hides the help text from screen readers.
*/
MDCSelectHelperTextFoundation.prototype.hide_ = function () {
this.adapter_.setAttr(strings$i.ARIA_HIDDEN, 'true');
};
return MDCSelectHelperTextFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCSelectHelperText = /** @class */ (function (_super) {
__extends(MDCSelectHelperText, _super);
function MDCSelectHelperText() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCSelectHelperText.attachTo = function (root) {
return new MDCSelectHelperText(root);
};
Object.defineProperty(MDCSelectHelperText.prototype, "foundation", {
get: function () {
return this.foundation_;
},
enumerable: true,
configurable: true
});
MDCSelectHelperText.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
hasClass: function (className) { return _this.root_.classList.contains(className); },
setAttr: function (attr, value) { return _this.root_.setAttribute(attr, value); },
removeAttr: function (attr) { return _this.root_.removeAttribute(attr); },
setContent: function (content) {
_this.root_.textContent = content;
},
};
// tslint:enable:object-literal-sort-keys
return new MDCSelectHelperTextFoundation(adapter);
};
return MDCSelectHelperText;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var strings$j = {
ICON_EVENT: 'MDCSelect:icon',
ICON_ROLE: 'button',
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var INTERACTION_EVENTS$1 = ['click', 'keydown'];
var MDCSelectIconFoundation = /** @class */ (function (_super) {
__extends(MDCSelectIconFoundation, _super);
function MDCSelectIconFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCSelectIconFoundation.defaultAdapter, adapter)) || this;
_this.savedTabIndex_ = null;
_this.interactionHandler_ = function (evt) { return _this.handleInteraction(evt); };
return _this;
}
Object.defineProperty(MDCSelectIconFoundation, "strings", {
get: function () {
return strings$j;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelectIconFoundation, "defaultAdapter", {
/**
* See {@link MDCSelectIconAdapter} for typing information on parameters and return types.
*/
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
getAttr: function () { return null; },
setAttr: function () { return undefined; },
removeAttr: function () { return undefined; },
setContent: function () { return undefined; },
registerInteractionHandler: function () { return undefined; },
deregisterInteractionHandler: function () { return undefined; },
notifyIconAction: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCSelectIconFoundation.prototype.init = function () {
var _this = this;
this.savedTabIndex_ = this.adapter_.getAttr('tabindex');
INTERACTION_EVENTS$1.forEach(function (evtType) {
_this.adapter_.registerInteractionHandler(evtType, _this.interactionHandler_);
});
};
MDCSelectIconFoundation.prototype.destroy = function () {
var _this = this;
INTERACTION_EVENTS$1.forEach(function (evtType) {
_this.adapter_.deregisterInteractionHandler(evtType, _this.interactionHandler_);
});
};
MDCSelectIconFoundation.prototype.setDisabled = function (disabled) {
if (!this.savedTabIndex_) {
return;
}
if (disabled) {
this.adapter_.setAttr('tabindex', '-1');
this.adapter_.removeAttr('role');
}
else {
this.adapter_.setAttr('tabindex', this.savedTabIndex_);
this.adapter_.setAttr('role', strings$j.ICON_ROLE);
}
};
MDCSelectIconFoundation.prototype.setAriaLabel = function (label) {
this.adapter_.setAttr('aria-label', label);
};
MDCSelectIconFoundation.prototype.setContent = function (content) {
this.adapter_.setContent(content);
};
MDCSelectIconFoundation.prototype.handleInteraction = function (evt) {
var isEnterKey = evt.key === 'Enter' || evt.keyCode === 13;
if (evt.type === 'click' || isEnterKey) {
this.adapter_.notifyIconAction();
}
};
return MDCSelectIconFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCSelectIcon = /** @class */ (function (_super) {
__extends(MDCSelectIcon, _super);
function MDCSelectIcon() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCSelectIcon.attachTo = function (root) {
return new MDCSelectIcon(root);
};
Object.defineProperty(MDCSelectIcon.prototype, "foundation", {
get: function () {
return this.foundation_;
},
enumerable: true,
configurable: true
});
MDCSelectIcon.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
getAttr: function (attr) { return _this.root_.getAttribute(attr); },
setAttr: function (attr, value) { return _this.root_.setAttribute(attr, value); },
removeAttr: function (attr) { return _this.root_.removeAttribute(attr); },
setContent: function (content) {
_this.root_.textContent = content;
},
registerInteractionHandler: function (evtType, handler) { return _this.listen(evtType, handler); },
deregisterInteractionHandler: function (evtType, handler) { return _this.unlisten(evtType, handler); },
notifyIconAction: function () { return _this.emit(MDCSelectIconFoundation.strings.ICON_EVENT, {} /* evtData */, true /* shouldBubble */); },
};
// tslint:enable:object-literal-sort-keys
return new MDCSelectIconFoundation(adapter);
};
return MDCSelectIcon;
}(MDCComponent));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var VALIDATION_ATTR_WHITELIST = ['required', 'aria-required'];
var MDCSelect = /** @class */ (function (_super) {
__extends(MDCSelect, _super);
function MDCSelect() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCSelect.attachTo = function (root) {
return new MDCSelect(root);
};
MDCSelect.prototype.initialize = function (labelFactory, lineRippleFactory, outlineFactory, menuFactory, iconFactory, helperTextFactory) {
if (labelFactory === void 0) { labelFactory = function (el) { return new MDCFloatingLabel(el); }; }
if (lineRippleFactory === void 0) { lineRippleFactory = function (el) { return new MDCLineRipple(el); }; }
if (outlineFactory === void 0) { outlineFactory = function (el) { return new MDCNotchedOutline(el); }; }
if (menuFactory === void 0) { menuFactory = function (el) { return new MDCMenu(el); }; }
if (iconFactory === void 0) { iconFactory = function (el) { return new MDCSelectIcon(el); }; }
if (helperTextFactory === void 0) { helperTextFactory = function (el) { return new MDCSelectHelperText(el); }; }
this.isMenuOpen_ = false;
this.nativeControl_ = this.root_.querySelector(strings$h.NATIVE_CONTROL_SELECTOR);
this.selectedText_ = this.root_.querySelector(strings$h.SELECTED_TEXT_SELECTOR);
var targetElement = this.nativeControl_ || this.selectedText_;
if (!targetElement) {
throw new Error('MDCSelect: Missing required element: Exactly one of the following selectors must be present: ' +
("'" + strings$h.NATIVE_CONTROL_SELECTOR + "' or '" + strings$h.SELECTED_TEXT_SELECTOR + "'"));
}
this.targetElement_ = targetElement;
if (this.targetElement_.hasAttribute(strings$h.ARIA_CONTROLS)) {
var helperTextElement = document.getElementById(this.targetElement_.getAttribute(strings$h.ARIA_CONTROLS));
if (helperTextElement) {
this.helperText_ = helperTextFactory(helperTextElement);
}
}
if (this.selectedText_) {
this.enhancedSelectSetup_(menuFactory);
}
var labelElement = this.root_.querySelector(strings$h.LABEL_SELECTOR);
this.label_ = labelElement ? labelFactory(labelElement) : null;
var lineRippleElement = this.root_.querySelector(strings$h.LINE_RIPPLE_SELECTOR);
this.lineRipple_ = lineRippleElement ? lineRippleFactory(lineRippleElement) : null;
var outlineElement = this.root_.querySelector(strings$h.OUTLINE_SELECTOR);
this.outline_ = outlineElement ? outlineFactory(outlineElement) : null;
var leadingIcon = this.root_.querySelector(strings$h.LEADING_ICON_SELECTOR);
if (leadingIcon) {
this.root_.classList.add(cssClasses$h.WITH_LEADING_ICON);
this.leadingIcon_ = iconFactory(leadingIcon);
if (this.menuElement_) {
this.menuElement_.classList.add(cssClasses$h.WITH_LEADING_ICON);
}
}
if (!this.root_.classList.contains(cssClasses$h.OUTLINED)) {
this.ripple = this.createRipple_();
}
// The required state needs to be sync'd before the mutation observer is added.
this.initialSyncRequiredState_();
this.addMutationObserverForRequired_();
};
/**
* Initializes the select's event listeners and internal state based
* on the environment's state.
*/
MDCSelect.prototype.initialSyncWithDOM = function () {
var _this = this;
this.handleChange_ = function () { return _this.foundation_.handleChange(/* didChange */ true); };
this.handleFocus_ = function () { return _this.foundation_.handleFocus(); };
this.handleBlur_ = function () { return _this.foundation_.handleBlur(); };
this.handleClick_ = function (evt) {
if (_this.selectedText_) {
_this.selectedText_.focus();
}
_this.foundation_.handleClick(_this.getNormalizedXCoordinate_(evt));
};
this.handleKeydown_ = function (evt) { return _this.foundation_.handleKeydown(evt); };
this.handleMenuSelected_ = function (evtData) { return _this.selectedIndex = evtData.detail.index; };
this.handleMenuOpened_ = function () {
_this.foundation_.handleMenuOpened();
if (_this.menu_.items.length === 0) {
return;
}
// Menu should open to the last selected element, should open to first menu item otherwise.
var focusItemIndex = _this.selectedIndex >= 0 ? _this.selectedIndex : 0;
var focusItemEl = _this.menu_.items[focusItemIndex];
focusItemEl.focus();
};
this.handleMenuClosed_ = function () {
_this.foundation_.handleMenuClosed();
// isMenuOpen_ is used to track the state of the menu opening or closing since the menu.open function
// will return false if the menu is still closing and this method listens to the closed event which
// occurs after the menu is already closed.
_this.isMenuOpen_ = false;
_this.selectedText_.removeAttribute('aria-expanded');
if (document.activeElement !== _this.selectedText_) {
_this.foundation_.handleBlur();
}
};
this.targetElement_.addEventListener('change', this.handleChange_);
this.targetElement_.addEventListener('focus', this.handleFocus_);
this.targetElement_.addEventListener('blur', this.handleBlur_);
this.targetElement_.addEventListener('click', this.handleClick_);
if (this.menuElement_) {
this.selectedText_.addEventListener('keydown', this.handleKeydown_);
this.menu_.listen(strings$d.CLOSED_EVENT, this.handleMenuClosed_);
this.menu_.listen(strings$d.OPENED_EVENT, this.handleMenuOpened_);
this.menu_.listen(strings$e.SELECTED_EVENT, this.handleMenuSelected_);
if (this.hiddenInput_ && this.hiddenInput_.value) {
// If the hidden input already has a value, use it to restore the select's value.
// This can happen e.g. if the user goes back or (in some browsers) refreshes the page.
var enhancedAdapterMethods = this.getEnhancedSelectAdapterMethods_();
enhancedAdapterMethods.setValue(this.hiddenInput_.value);
}
else if (this.menuElement_.querySelector(strings$h.SELECTED_ITEM_SELECTOR)) {
// If an element is selected, the select should set the initial selected text.
var enhancedAdapterMethods = this.getEnhancedSelectAdapterMethods_();
enhancedAdapterMethods.setValue(enhancedAdapterMethods.getValue());
}
}
// Initially sync floating label
this.foundation_.handleChange(/* didChange */ false);
if (this.root_.classList.contains(cssClasses$h.DISABLED)
|| (this.nativeControl_ && this.nativeControl_.disabled)) {
this.disabled = true;
}
};
MDCSelect.prototype.destroy = function () {
this.targetElement_.removeEventListener('change', this.handleChange_);
this.targetElement_.removeEventListener('focus', this.handleFocus_);
this.targetElement_.removeEventListener('blur', this.handleBlur_);
this.targetElement_.removeEventListener('keydown', this.handleKeydown_);
this.targetElement_.removeEventListener('click', this.handleClick_);
if (this.menu_) {
this.menu_.unlisten(strings$d.CLOSED_EVENT, this.handleMenuClosed_);
this.menu_.unlisten(strings$d.OPENED_EVENT, this.handleMenuOpened_);
this.menu_.unlisten(strings$e.SELECTED_EVENT, this.handleMenuSelected_);
this.menu_.destroy();
}
if (this.ripple) {
this.ripple.destroy();
}
if (this.outline_) {
this.outline_.destroy();
}
if (this.leadingIcon_) {
this.leadingIcon_.destroy();
}
if (this.helperText_) {
this.helperText_.destroy();
}
if (this.validationObserver_) {
this.validationObserver_.disconnect();
}
_super.prototype.destroy.call(this);
};
Object.defineProperty(MDCSelect.prototype, "value", {
get: function () {
return this.foundation_.getValue();
},
set: function (value) {
this.foundation_.setValue(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelect.prototype, "selectedIndex", {
get: function () {
var selectedIndex = -1;
if (this.menuElement_ && this.menu_) {
var selectedEl = this.menuElement_.querySelector(strings$h.SELECTED_ITEM_SELECTOR);
selectedIndex = this.menu_.items.indexOf(selectedEl);
}
else if (this.nativeControl_) {
selectedIndex = this.nativeControl_.selectedIndex;
}
return selectedIndex;
},
set: function (selectedIndex) {
this.foundation_.setSelectedIndex(selectedIndex);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelect.prototype, "disabled", {
get: function () {
return this.root_.classList.contains(cssClasses$h.DISABLED) ||
(this.nativeControl_ ? this.nativeControl_.disabled : false);
},
set: function (disabled) {
this.foundation_.setDisabled(disabled);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelect.prototype, "leadingIconAriaLabel", {
set: function (label) {
this.foundation_.setLeadingIconAriaLabel(label);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelect.prototype, "leadingIconContent", {
/**
* Sets the text content of the leading icon.
*/
set: function (content) {
this.foundation_.setLeadingIconContent(content);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelect.prototype, "helperTextContent", {
/**
* Sets the text content of the helper text.
*/
set: function (content) {
this.foundation_.setHelperTextContent(content);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelect.prototype, "valid", {
/**
* Checks if the select is in a valid state.
*/
get: function () {
return this.foundation_.isValid();
},
/**
* Sets the current invalid state of the select.
*/
set: function (isValid) {
this.foundation_.setValid(isValid);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSelect.prototype, "required", {
/**
* Returns whether the select is required.
*/
get: function () {
if (this.nativeControl_) {
return this.nativeControl_.required;
}
else {
return this.selectedText_.getAttribute('aria-required') === 'true';
}
},
/**
* Sets the control to the required state.
*/
set: function (isRequired) {
if (this.nativeControl_) {
this.nativeControl_.required = isRequired;
}
else {
if (isRequired) {
this.selectedText_.setAttribute('aria-required', isRequired.toString());
}
else {
this.selectedText_.removeAttribute('aria-required');
}
}
},
enumerable: true,
configurable: true
});
/**
* Recomputes the outline SVG path for the outline element.
*/
MDCSelect.prototype.layout = function () {
this.foundation_.layout();
};
MDCSelect.prototype.getDefaultFoundation = function () {
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = __assign({}, (this.nativeControl_ ? this.getNativeSelectAdapterMethods_() : this.getEnhancedSelectAdapterMethods_()), this.getCommonAdapterMethods_(), this.getOutlineAdapterMethods_(), this.getLabelAdapterMethods_());
return new MDCSelectFoundation(adapter, this.getFoundationMap_());
};
/**
* Handles setup for the enhanced menu.
*/
MDCSelect.prototype.enhancedSelectSetup_ = function (menuFactory) {
var isDisabled = this.root_.classList.contains(cssClasses$h.DISABLED);
this.selectedText_.setAttribute('tabindex', isDisabled ? '-1' : '0');
this.hiddenInput_ = this.root_.querySelector(strings$h.HIDDEN_INPUT_SELECTOR);
this.menuElement_ = this.root_.querySelector(strings$h.MENU_SELECTOR);
this.menu_ = menuFactory(this.menuElement_);
this.menu_.hoistMenuToBody();
this.menu_.setAnchorElement(this.root_);
this.menu_.setAnchorCorner(exports.Corner.BOTTOM_START);
this.menu_.wrapFocus = false;
};
MDCSelect.prototype.createRipple_ = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = __assign({}, MDCRipple.createAdapter(this), { registerInteractionHandler: function (evtType, handler) { return _this.targetElement_.addEventListener(evtType, handler); }, deregisterInteractionHandler: function (evtType, handler) { return _this.targetElement_.removeEventListener(evtType, handler); } });
// tslint:enable:object-literal-sort-keys
return new MDCRipple(this.root_, new MDCRippleFoundation(adapter));
};
MDCSelect.prototype.getNativeSelectAdapterMethods_ = function () {
var _this = this;
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
getValue: function () { return _this.nativeControl_.value; },
setValue: function (value) {
_this.nativeControl_.value = value;
},
openMenu: function () { return undefined; },
closeMenu: function () { return undefined; },
isMenuOpen: function () { return false; },
setSelectedIndex: function (index) {
_this.nativeControl_.selectedIndex = index;
},
setDisabled: function (isDisabled) {
_this.nativeControl_.disabled = isDisabled;
},
setValid: function (isValid) {
if (isValid) {
_this.root_.classList.remove(cssClasses$h.INVALID);
}
else {
_this.root_.classList.add(cssClasses$h.INVALID);
}
},
checkValidity: function () { return _this.nativeControl_.checkValidity(); },
};
// tslint:enable:object-literal-sort-keys
};
MDCSelect.prototype.getEnhancedSelectAdapterMethods_ = function () {
var _this = this;
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
getValue: function () {
var listItem = _this.menuElement_.querySelector(strings$h.SELECTED_ITEM_SELECTOR);
if (listItem && listItem.hasAttribute(strings$h.ENHANCED_VALUE_ATTR)) {
return listItem.getAttribute(strings$h.ENHANCED_VALUE_ATTR) || '';
}
return '';
},
setValue: function (value) {
var element = _this.menuElement_.querySelector("[" + strings$h.ENHANCED_VALUE_ATTR + "=\"" + value + "\"]");
_this.setEnhancedSelectedIndex_(element ? _this.menu_.items.indexOf(element) : -1);
},
openMenu: function () {
if (_this.menu_ && !_this.menu_.open) {
_this.menu_.open = true;
_this.isMenuOpen_ = true;
_this.selectedText_.setAttribute('aria-expanded', 'true');
}
},
closeMenu: function () {
if (_this.menu_ && _this.menu_.open) {
_this.menu_.open = false;
}
},
isMenuOpen: function () { return Boolean(_this.menu_) && _this.isMenuOpen_; },
setSelectedIndex: function (index) { return _this.setEnhancedSelectedIndex_(index); },
setDisabled: function (isDisabled) {
_this.selectedText_.setAttribute('tabindex', isDisabled ? '-1' : '0');
_this.selectedText_.setAttribute('aria-disabled', isDisabled.toString());
if (_this.hiddenInput_) {
_this.hiddenInput_.disabled = isDisabled;
}
},
checkValidity: function () {
var classList = _this.root_.classList;
if (classList.contains(cssClasses$h.REQUIRED) && !classList.contains(cssClasses$h.DISABLED)) {
// See notes for required attribute under https://www.w3.org/TR/html52/sec-forms.html#the-select-element
// TL;DR: Invalid if no index is selected, or if the first index is selected and has an empty value.
return _this.selectedIndex !== -1 && (_this.selectedIndex !== 0 || Boolean(_this.value));
}
else {
return true;
}
},
setValid: function (isValid) {
_this.selectedText_.setAttribute('aria-invalid', (!isValid).toString());
if (isValid) {
_this.root_.classList.remove(cssClasses$h.INVALID);
}
else {
_this.root_.classList.add(cssClasses$h.INVALID);
}
},
};
// tslint:enable:object-literal-sort-keys
};
MDCSelect.prototype.getCommonAdapterMethods_ = function () {
var _this = this;
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
hasClass: function (className) { return _this.root_.classList.contains(className); },
setRippleCenter: function (normalizedX) { return _this.lineRipple_ && _this.lineRipple_.setRippleCenter(normalizedX); },
activateBottomLine: function () { return _this.lineRipple_ && _this.lineRipple_.activate(); },
deactivateBottomLine: function () { return _this.lineRipple_ && _this.lineRipple_.deactivate(); },
notifyChange: function (value) {
var index = _this.selectedIndex;
_this.emit(strings$h.CHANGE_EVENT, { value: value, index: index }, true /* shouldBubble */);
},
};
// tslint:enable:object-literal-sort-keys
};
MDCSelect.prototype.getOutlineAdapterMethods_ = function () {
var _this = this;
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
hasOutline: function () { return Boolean(_this.outline_); },
notchOutline: function (labelWidth) { return _this.outline_ && _this.outline_.notch(labelWidth); },
closeOutline: function () { return _this.outline_ && _this.outline_.closeNotch(); },
};
// tslint:enable:object-literal-sort-keys
};
MDCSelect.prototype.getLabelAdapterMethods_ = function () {
var _this = this;
return {
floatLabel: function (shouldFloat) { return _this.label_ && _this.label_.float(shouldFloat); },
getLabelWidth: function () { return _this.label_ ? _this.label_.getWidth() : 0; },
};
};
/**
* Calculates where the line ripple should start based on the x coordinate within the component.
*/
MDCSelect.prototype.getNormalizedXCoordinate_ = function (evt) {
var targetClientRect = evt.target.getBoundingClientRect();
var xCoordinate = this.isTouchEvent_(evt) ? evt.touches[0].clientX : evt.clientX;
return xCoordinate - targetClientRect.left;
};
MDCSelect.prototype.isTouchEvent_ = function (evt) {
return Boolean(evt.touches);
};
/**
* Returns a map of all subcomponents to subfoundations.
*/
MDCSelect.prototype.getFoundationMap_ = function () {
return {
helperText: this.helperText_ ? this.helperText_.foundation : undefined,
leadingIcon: this.leadingIcon_ ? this.leadingIcon_.foundation : undefined,
};
};
MDCSelect.prototype.setEnhancedSelectedIndex_ = function (index) {
var selectedItem = this.menu_.items[index];
this.selectedText_.textContent = selectedItem ? selectedItem.textContent.trim() : '';
var previouslySelected = this.menuElement_.querySelector(strings$h.SELECTED_ITEM_SELECTOR);
if (previouslySelected) {
previouslySelected.classList.remove(cssClasses$h.SELECTED_ITEM_CLASS);
previouslySelected.removeAttribute(strings$h.ARIA_SELECTED_ATTR);
}
if (selectedItem) {
selectedItem.classList.add(cssClasses$h.SELECTED_ITEM_CLASS);
selectedItem.setAttribute(strings$h.ARIA_SELECTED_ATTR, 'true');
}
// Synchronize hidden input's value with data-value attribute of selected item.
// This code path is also followed when setting value directly, so this covers all cases.
if (this.hiddenInput_) {
this.hiddenInput_.value = selectedItem ? selectedItem.getAttribute(strings$h.ENHANCED_VALUE_ATTR) || '' : '';
}
this.layout();
};
MDCSelect.prototype.initialSyncRequiredState_ = function () {
var isRequired = this.targetElement_.required
|| this.targetElement_.getAttribute('aria-required') === 'true'
|| this.root_.classList.contains(cssClasses$h.REQUIRED);
if (isRequired) {
if (this.nativeControl_) {
this.nativeControl_.required = true;
}
else {
this.selectedText_.setAttribute('aria-required', 'true');
}
this.root_.classList.add(cssClasses$h.REQUIRED);
}
};
MDCSelect.prototype.addMutationObserverForRequired_ = function () {
var _this = this;
var observerHandler = function (attributesList) {
attributesList.some(function (attributeName) {
if (VALIDATION_ATTR_WHITELIST.indexOf(attributeName) === -1) {
return false;
}
if (_this.selectedText_) {
if (_this.selectedText_.getAttribute('aria-required') === 'true') {
_this.root_.classList.add(cssClasses$h.REQUIRED);
}
else {
_this.root_.classList.remove(cssClasses$h.REQUIRED);
}
}
else {
if (_this.nativeControl_.required) {
_this.root_.classList.add(cssClasses$h.REQUIRED);
}
else {
_this.root_.classList.remove(cssClasses$h.REQUIRED);
}
}
return true;
});
};
var getAttributesList = function (mutationsList) {
return mutationsList
.map(function (mutation) { return mutation.attributeName; })
.filter(function (attributeName) { return attributeName; });
};
var observer = new MutationObserver(function (mutationsList) { return observerHandler(getAttributesList(mutationsList)); });
observer.observe(this.targetElement_, { attributes: true });
this.validationObserver_ = observer;
};
return MDCSelect;
}(MDCComponent));
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$j = {
ACTIVE: 'mdc-slider--active',
DISABLED: 'mdc-slider--disabled',
DISCRETE: 'mdc-slider--discrete',
FOCUS: 'mdc-slider--focus',
HAS_TRACK_MARKER: 'mdc-slider--display-markers',
IN_TRANSIT: 'mdc-slider--in-transit',
IS_DISCRETE: 'mdc-slider--discrete',
};
var strings$k = {
ARIA_DISABLED: 'aria-disabled',
ARIA_VALUEMAX: 'aria-valuemax',
ARIA_VALUEMIN: 'aria-valuemin',
ARIA_VALUENOW: 'aria-valuenow',
CHANGE_EVENT: 'MDCSlider:change',
INPUT_EVENT: 'MDCSlider:input',
LAST_TRACK_MARKER_SELECTOR: '.mdc-slider__track-marker:last-child',
PIN_VALUE_MARKER_SELECTOR: '.mdc-slider__pin-value-marker',
STEP_DATA_ATTR: 'data-step',
THUMB_CONTAINER_SELECTOR: '.mdc-slider__thumb-container',
TRACK_MARKER_CONTAINER_SELECTOR: '.mdc-slider__track-marker-container',
TRACK_SELECTOR: '.mdc-slider__track',
};
var numbers$8 = {
PAGE_FACTOR: 4,
};
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var DOWN_EVENTS = ['mousedown', 'pointerdown', 'touchstart'];
var UP_EVENTS = ['mouseup', 'pointerup', 'touchend'];
var MOVE_EVENT_MAP = {
mousedown: 'mousemove',
pointerdown: 'pointermove',
touchstart: 'touchmove',
};
var KEY_IDS = {
ARROW_DOWN: 'ArrowDown',
ARROW_LEFT: 'ArrowLeft',
ARROW_RIGHT: 'ArrowRight',
ARROW_UP: 'ArrowUp',
END: 'End',
HOME: 'Home',
PAGE_DOWN: 'PageDown',
PAGE_UP: 'PageUp',
};
var MDCSliderFoundation = /** @class */ (function (_super) {
__extends(MDCSliderFoundation, _super);
function MDCSliderFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCSliderFoundation.defaultAdapter, adapter)) || this;
/**
* We set this to NaN since we want it to be a number, but we can't use '0' or '-1'
* because those could be valid tabindices set by the client code.
*/
_this.savedTabIndex_ = NaN;
_this.active_ = false;
_this.inTransit_ = false;
_this.isDiscrete_ = false;
_this.hasTrackMarker_ = false;
_this.handlingThumbTargetEvt_ = false;
_this.min_ = 0;
_this.max_ = 100;
_this.step_ = 0;
_this.value_ = 0;
_this.disabled_ = false;
_this.preventFocusState_ = false;
_this.thumbContainerPointerHandler_ = function () { return _this.handlingThumbTargetEvt_ = true; };
_this.interactionStartHandler_ = function (evt) { return _this.handleDown_(evt); };
_this.keydownHandler_ = function (evt) { return _this.handleKeydown_(evt); };
_this.focusHandler_ = function () { return _this.handleFocus_(); };
_this.blurHandler_ = function () { return _this.handleBlur_(); };
_this.resizeHandler_ = function () { return _this.layout(); };
return _this;
}
Object.defineProperty(MDCSliderFoundation, "cssClasses", {
get: function () {
return cssClasses$j;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSliderFoundation, "strings", {
get: function () {
return strings$k;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSliderFoundation, "numbers", {
get: function () {
return numbers$8;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSliderFoundation, "defaultAdapter", {
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
hasClass: function () { return false; },
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
getAttribute: function () { return null; },
setAttribute: function () { return undefined; },
removeAttribute: function () { return undefined; },
computeBoundingRect: function () { return ({ top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 }); },
getTabIndex: function () { return 0; },
registerInteractionHandler: function () { return undefined; },
deregisterInteractionHandler: function () { return undefined; },
registerThumbContainerInteractionHandler: function () { return undefined; },
deregisterThumbContainerInteractionHandler: function () { return undefined; },
registerBodyInteractionHandler: function () { return undefined; },
deregisterBodyInteractionHandler: function () { return undefined; },
registerResizeHandler: function () { return undefined; },
deregisterResizeHandler: function () { return undefined; },
notifyInput: function () { return undefined; },
notifyChange: function () { return undefined; },
setThumbContainerStyleProperty: function () { return undefined; },
setTrackStyleProperty: function () { return undefined; },
setMarkerValue: function () { return undefined; },
appendTrackMarkers: function () { return undefined; },
removeTrackMarkers: function () { return undefined; },
setLastTrackMarkersStyleProperty: function () { return undefined; },
isRTL: function () { return false; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCSliderFoundation.prototype.init = function () {
var _this = this;
this.isDiscrete_ = this.adapter_.hasClass(cssClasses$j.IS_DISCRETE);
this.hasTrackMarker_ = this.adapter_.hasClass(cssClasses$j.HAS_TRACK_MARKER);
DOWN_EVENTS.forEach(function (evtName) {
_this.adapter_.registerInteractionHandler(evtName, _this.interactionStartHandler_);
_this.adapter_.registerThumbContainerInteractionHandler(evtName, _this.thumbContainerPointerHandler_);
});
this.adapter_.registerInteractionHandler('keydown', this.keydownHandler_);
this.adapter_.registerInteractionHandler('focus', this.focusHandler_);
this.adapter_.registerInteractionHandler('blur', this.blurHandler_);
this.adapter_.registerResizeHandler(this.resizeHandler_);
this.layout();
// At last step, provide a reasonable default value to discrete slider
if (this.isDiscrete_ && this.getStep() === 0) {
this.step_ = 1;
}
};
MDCSliderFoundation.prototype.destroy = function () {
var _this = this;
DOWN_EVENTS.forEach(function (evtName) {
_this.adapter_.deregisterInteractionHandler(evtName, _this.interactionStartHandler_);
_this.adapter_.deregisterThumbContainerInteractionHandler(evtName, _this.thumbContainerPointerHandler_);
});
this.adapter_.deregisterInteractionHandler('keydown', this.keydownHandler_);
this.adapter_.deregisterInteractionHandler('focus', this.focusHandler_);
this.adapter_.deregisterInteractionHandler('blur', this.blurHandler_);
this.adapter_.deregisterResizeHandler(this.resizeHandler_);
};
MDCSliderFoundation.prototype.setupTrackMarker = function () {
if (this.isDiscrete_ && this.hasTrackMarker_ && this.getStep() !== 0) {
var min = this.getMin();
var max = this.getMax();
var step = this.getStep();
var numMarkers = (max - min) / step;
// In case distance between max & min is indivisible to step,
// we place the secondary to last marker proportionally at where thumb
// could reach and place the last marker at max value
var indivisible = Math.ceil(numMarkers) !== numMarkers;
if (indivisible) {
numMarkers = Math.ceil(numMarkers);
}
this.adapter_.removeTrackMarkers();
this.adapter_.appendTrackMarkers(numMarkers);
if (indivisible) {
var lastStepRatio = (max - numMarkers * step) / step + 1;
this.adapter_.setLastTrackMarkersStyleProperty('flex-grow', String(lastStepRatio));
}
}
};
MDCSliderFoundation.prototype.layout = function () {
this.rect_ = this.adapter_.computeBoundingRect();
this.updateUIForCurrentValue_();
};
MDCSliderFoundation.prototype.getValue = function () {
return this.value_;
};
MDCSliderFoundation.prototype.setValue = function (value) {
this.setValue_(value, false);
};
MDCSliderFoundation.prototype.getMax = function () {
return this.max_;
};
MDCSliderFoundation.prototype.setMax = function (max) {
if (max < this.min_) {
throw new Error('Cannot set max to be less than the slider\'s minimum value');
}
this.max_ = max;
this.setValue_(this.value_, false, true);
this.adapter_.setAttribute(strings$k.ARIA_VALUEMAX, String(this.max_));
this.setupTrackMarker();
};
MDCSliderFoundation.prototype.getMin = function () {
return this.min_;
};
MDCSliderFoundation.prototype.setMin = function (min) {
if (min > this.max_) {
throw new Error('Cannot set min to be greater than the slider\'s maximum value');
}
this.min_ = min;
this.setValue_(this.value_, false, true);
this.adapter_.setAttribute(strings$k.ARIA_VALUEMIN, String(this.min_));
this.setupTrackMarker();
};
MDCSliderFoundation.prototype.getStep = function () {
return this.step_;
};
MDCSliderFoundation.prototype.setStep = function (step) {
if (step < 0) {
throw new Error('Step cannot be set to a negative number');
}
if (this.isDiscrete_ && (typeof (step) !== 'number' || step < 1)) {
step = 1;
}
this.step_ = step;
this.setValue_(this.value_, false, true);
this.setupTrackMarker();
};
MDCSliderFoundation.prototype.isDisabled = function () {
return this.disabled_;
};
MDCSliderFoundation.prototype.setDisabled = function (disabled) {
this.disabled_ = disabled;
this.toggleClass_(cssClasses$j.DISABLED, this.disabled_);
if (this.disabled_) {
this.savedTabIndex_ = this.adapter_.getTabIndex();
this.adapter_.setAttribute(strings$k.ARIA_DISABLED, 'true');
this.adapter_.removeAttribute('tabindex');
}
else {
this.adapter_.removeAttribute(strings$k.ARIA_DISABLED);
if (!isNaN(this.savedTabIndex_)) {
this.adapter_.setAttribute('tabindex', String(this.savedTabIndex_));
}
}
};
/**
* Called when the user starts interacting with the slider
*/
MDCSliderFoundation.prototype.handleDown_ = function (downEvent) {
var _this = this;
if (this.disabled_) {
return;
}
this.preventFocusState_ = true;
this.setInTransit_(!this.handlingThumbTargetEvt_);
this.handlingThumbTargetEvt_ = false;
this.setActive_(true);
var moveHandler = function (moveEvent) {
_this.handleMove_(moveEvent);
};
var moveEventType = MOVE_EVENT_MAP[downEvent.type];
// Note: upHandler is [de]registered on ALL potential pointer-related release event types, since some browsers
// do not always fire these consistently in pairs.
// (See https://github.com/material-components/material-components-web/issues/1192)
var upHandler = function () {
_this.handleUp_();
_this.adapter_.deregisterBodyInteractionHandler(moveEventType, moveHandler);
UP_EVENTS.forEach(function (evtName) { return _this.adapter_.deregisterBodyInteractionHandler(evtName, upHandler); });
};
this.adapter_.registerBodyInteractionHandler(moveEventType, moveHandler);
UP_EVENTS.forEach(function (evtName) { return _this.adapter_.registerBodyInteractionHandler(evtName, upHandler); });
this.setValueFromEvt_(downEvent);
};
/**
* Called when the user moves the slider
*/
MDCSliderFoundation.prototype.handleMove_ = function (evt) {
evt.preventDefault();
this.setValueFromEvt_(evt);
};
/**
* Called when the user's interaction with the slider ends
*/
MDCSliderFoundation.prototype.handleUp_ = function () {
this.setActive_(false);
this.adapter_.notifyChange();
};
/**
* Returns the pageX of the event
*/
MDCSliderFoundation.prototype.getPageX_ = function (evt) {
if (evt.targetTouches && evt.targetTouches.length > 0) {
return evt.targetTouches[0].pageX;
}
return evt.pageX;
};
/**
* Sets the slider value from an event
*/
MDCSliderFoundation.prototype.setValueFromEvt_ = function (evt) {
var pageX = this.getPageX_(evt);
var value = this.computeValueFromPageX_(pageX);
this.setValue_(value, true);
};
/**
* Computes the new value from the pageX position
*/
MDCSliderFoundation.prototype.computeValueFromPageX_ = function (pageX) {
var _a = this, max = _a.max_, min = _a.min_;
var xPos = pageX - this.rect_.left;
var pctComplete = xPos / this.rect_.width;
if (this.adapter_.isRTL()) {
pctComplete = 1 - pctComplete;
}
// Fit the percentage complete between the range [min,max]
// by remapping from [0, 1] to [min, min+(max-min)].
return min + pctComplete * (max - min);
};
/**
* Handles keydown events
*/
MDCSliderFoundation.prototype.handleKeydown_ = function (evt) {
var keyId = this.getKeyId_(evt);
var value = this.getValueForKeyId_(keyId);
if (isNaN(value)) {
return;
}
// Prevent page from scrolling due to key presses that would normally scroll the page
evt.preventDefault();
this.adapter_.addClass(cssClasses$j.FOCUS);
this.setValue_(value, true);
this.adapter_.notifyChange();
};
/**
* Returns the computed name of the event
*/
MDCSliderFoundation.prototype.getKeyId_ = function (kbdEvt) {
if (kbdEvt.key === KEY_IDS.ARROW_LEFT || kbdEvt.keyCode === 37) {
return KEY_IDS.ARROW_LEFT;
}
if (kbdEvt.key === KEY_IDS.ARROW_RIGHT || kbdEvt.keyCode === 39) {
return KEY_IDS.ARROW_RIGHT;
}
if (kbdEvt.key === KEY_IDS.ARROW_UP || kbdEvt.keyCode === 38) {
return KEY_IDS.ARROW_UP;
}
if (kbdEvt.key === KEY_IDS.ARROW_DOWN || kbdEvt.keyCode === 40) {
return KEY_IDS.ARROW_DOWN;
}
if (kbdEvt.key === KEY_IDS.HOME || kbdEvt.keyCode === 36) {
return KEY_IDS.HOME;
}
if (kbdEvt.key === KEY_IDS.END || kbdEvt.keyCode === 35) {
return KEY_IDS.END;
}
if (kbdEvt.key === KEY_IDS.PAGE_UP || kbdEvt.keyCode === 33) {
return KEY_IDS.PAGE_UP;
}
if (kbdEvt.key === KEY_IDS.PAGE_DOWN || kbdEvt.keyCode === 34) {
return KEY_IDS.PAGE_DOWN;
}
return '';
};
/**
* Computes the value given a keyboard key ID
*/
MDCSliderFoundation.prototype.getValueForKeyId_ = function (keyId) {
var _a = this, max = _a.max_, min = _a.min_, step = _a.step_;
var delta = step || (max - min) / 100;
var valueNeedsToBeFlipped = this.adapter_.isRTL() && (keyId === KEY_IDS.ARROW_LEFT || keyId === KEY_IDS.ARROW_RIGHT);
if (valueNeedsToBeFlipped) {
delta = -delta;
}
switch (keyId) {
case KEY_IDS.ARROW_LEFT:
case KEY_IDS.ARROW_DOWN:
return this.value_ - delta;
case KEY_IDS.ARROW_RIGHT:
case KEY_IDS.ARROW_UP:
return this.value_ + delta;
case KEY_IDS.HOME:
return this.min_;
case KEY_IDS.END:
return this.max_;
case KEY_IDS.PAGE_UP:
return this.value_ + delta * numbers$8.PAGE_FACTOR;
case KEY_IDS.PAGE_DOWN:
return this.value_ - delta * numbers$8.PAGE_FACTOR;
default:
return NaN;
}
};
MDCSliderFoundation.prototype.handleFocus_ = function () {
if (this.preventFocusState_) {
return;
}
this.adapter_.addClass(cssClasses$j.FOCUS);
};
MDCSliderFoundation.prototype.handleBlur_ = function () {
this.preventFocusState_ = false;
this.adapter_.removeClass(cssClasses$j.FOCUS);
};
/**
* Sets the value of the slider
*/
MDCSliderFoundation.prototype.setValue_ = function (value, shouldFireInput, force) {
if (force === void 0) { force = false; }
if (value === this.value_ && !force) {
return;
}
var _a = this, min = _a.min_, max = _a.max_;
var valueSetToBoundary = value === min || value === max;
if (this.step_ && !valueSetToBoundary) {
value = this.quantize_(value);
}
if (value < min) {
value = min;
}
else if (value > max) {
value = max;
}
this.value_ = value;
this.adapter_.setAttribute(strings$k.ARIA_VALUENOW, String(this.value_));
this.updateUIForCurrentValue_();
if (shouldFireInput) {
this.adapter_.notifyInput();
if (this.isDiscrete_) {
this.adapter_.setMarkerValue(value);
}
}
};
/**
* Calculates the quantized value
*/
MDCSliderFoundation.prototype.quantize_ = function (value) {
var numSteps = Math.round(value / this.step_);
return numSteps * this.step_;
};
MDCSliderFoundation.prototype.updateUIForCurrentValue_ = function () {
var _this = this;
var _a = this, max = _a.max_, min = _a.min_, value = _a.value_;
var pctComplete = (value - min) / (max - min);
var translatePx = pctComplete * this.rect_.width;
if (this.adapter_.isRTL()) {
translatePx = this.rect_.width - translatePx;
}
var transformProp = getCorrectPropertyName(window, 'transform');
var transitionendEvtName = getCorrectEventName(window, 'transitionend');
if (this.inTransit_) {
var onTransitionEnd_1 = function () {
_this.setInTransit_(false);
_this.adapter_.deregisterThumbContainerInteractionHandler(transitionendEvtName, onTransitionEnd_1);
};
this.adapter_.registerThumbContainerInteractionHandler(transitionendEvtName, onTransitionEnd_1);
}
requestAnimationFrame(function () {
// NOTE(traviskaufman): It would be nice to use calc() here,
// but IE cannot handle calcs in transforms correctly.
// See: https://goo.gl/NC2itk
// Also note that the -50% offset is used to center the slider thumb.
_this.adapter_.setThumbContainerStyleProperty(transformProp, "translateX(" + translatePx + "px) translateX(-50%)");
_this.adapter_.setTrackStyleProperty(transformProp, "scaleX(" + pctComplete + ")");
});
};
/**
* Toggles the active state of the slider
*/
MDCSliderFoundation.prototype.setActive_ = function (active) {
this.active_ = active;
this.toggleClass_(cssClasses$j.ACTIVE, this.active_);
};
/**
* Toggles the inTransit state of the slider
*/
MDCSliderFoundation.prototype.setInTransit_ = function (inTransit) {
this.inTransit_ = inTransit;
this.toggleClass_(cssClasses$j.IN_TRANSIT, this.inTransit_);
};
/**
* Conditionally adds or removes a class based on shouldBePresent
*/
MDCSliderFoundation.prototype.toggleClass_ = function (className, shouldBePresent) {
if (shouldBePresent) {
this.adapter_.addClass(className);
}
else {
this.adapter_.removeClass(className);
}
};
return MDCSliderFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCSlider = /** @class */ (function (_super) {
__extends(MDCSlider, _super);
function MDCSlider() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCSlider.attachTo = function (root) {
return new MDCSlider(root);
};
Object.defineProperty(MDCSlider.prototype, "value", {
get: function () {
return this.foundation_.getValue();
},
set: function (value) {
this.foundation_.setValue(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSlider.prototype, "min", {
get: function () {
return this.foundation_.getMin();
},
set: function (min) {
this.foundation_.setMin(min);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSlider.prototype, "max", {
get: function () {
return this.foundation_.getMax();
},
set: function (max) {
this.foundation_.setMax(max);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSlider.prototype, "step", {
get: function () {
return this.foundation_.getStep();
},
set: function (step) {
this.foundation_.setStep(step);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSlider.prototype, "disabled", {
get: function () {
return this.foundation_.isDisabled();
},
set: function (disabled) {
this.foundation_.setDisabled(disabled);
},
enumerable: true,
configurable: true
});
MDCSlider.prototype.initialize = function () {
this.thumbContainer_ = this.root_.querySelector(strings$k.THUMB_CONTAINER_SELECTOR);
this.track_ = this.root_.querySelector(strings$k.TRACK_SELECTOR);
this.pinValueMarker_ = this.root_.querySelector(strings$k.PIN_VALUE_MARKER_SELECTOR);
this.trackMarkerContainer_ = this.root_.querySelector(strings$k.TRACK_MARKER_CONTAINER_SELECTOR);
};
MDCSlider.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
hasClass: function (className) { return _this.root_.classList.contains(className); },
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
getAttribute: function (name) { return _this.root_.getAttribute(name); },
setAttribute: function (name, value) { return _this.root_.setAttribute(name, value); },
removeAttribute: function (name) { return _this.root_.removeAttribute(name); },
computeBoundingRect: function () { return _this.root_.getBoundingClientRect(); },
getTabIndex: function () { return _this.root_.tabIndex; },
registerInteractionHandler: function (evtType, handler) { return _this.listen(evtType, handler, applyPassive()); },
deregisterInteractionHandler: function (evtType, handler) { return _this.unlisten(evtType, handler, applyPassive()); },
registerThumbContainerInteractionHandler: function (evtType, handler) {
_this.thumbContainer_.addEventListener(evtType, handler, applyPassive());
},
deregisterThumbContainerInteractionHandler: function (evtType, handler) {
_this.thumbContainer_.removeEventListener(evtType, handler, applyPassive());
},
registerBodyInteractionHandler: function (evtType, handler) { return document.body.addEventListener(evtType, handler); },
deregisterBodyInteractionHandler: function (evtType, handler) { return document.body.removeEventListener(evtType, handler); },
registerResizeHandler: function (handler) { return window.addEventListener('resize', handler); },
deregisterResizeHandler: function (handler) { return window.removeEventListener('resize', handler); },
notifyInput: function () { return _this.emit(strings$k.INPUT_EVENT, _this); },
notifyChange: function () { return _this.emit(strings$k.CHANGE_EVENT, _this); },
setThumbContainerStyleProperty: function (propertyName, value) {
_this.thumbContainer_.style.setProperty(propertyName, value);
},
setTrackStyleProperty: function (propertyName, value) { return _this.track_.style.setProperty(propertyName, value); },
setMarkerValue: function (value) { return _this.pinValueMarker_.innerText = value.toLocaleString(); },
appendTrackMarkers: function (numMarkers) {
var frag = document.createDocumentFragment();
for (var i = 0; i < numMarkers; i++) {
var marker = document.createElement('div');
marker.classList.add('mdc-slider__track-marker');
frag.appendChild(marker);
}
_this.trackMarkerContainer_.appendChild(frag);
},
removeTrackMarkers: function () {
while (_this.trackMarkerContainer_.firstChild) {
_this.trackMarkerContainer_.removeChild(_this.trackMarkerContainer_.firstChild);
}
},
setLastTrackMarkersStyleProperty: function (propertyName, value) {
// We remove and append new nodes, thus, the last track marker must be dynamically found.
var lastTrackMarker = _this.root_.querySelector(strings$k.LAST_TRACK_MARKER_SELECTOR);
lastTrackMarker.style.setProperty(propertyName, value);
},
isRTL: function () { return getComputedStyle(_this.root_).direction === 'rtl'; },
};
// tslint:enable:object-literal-sort-keys
return new MDCSliderFoundation(adapter);
};
MDCSlider.prototype.initialSyncWithDOM = function () {
var origValueNow = this.parseFloat_(this.root_.getAttribute(strings$k.ARIA_VALUENOW), this.value);
var min = this.parseFloat_(this.root_.getAttribute(strings$k.ARIA_VALUEMIN), this.min);
var max = this.parseFloat_(this.root_.getAttribute(strings$k.ARIA_VALUEMAX), this.max);
// min and max need to be set in the right order to avoid throwing an error
// when the new min is greater than the default max.
if (min >= this.max) {
this.max = max;
this.min = min;
}
else {
this.min = min;
this.max = max;
}
this.step = this.parseFloat_(this.root_.getAttribute(strings$k.STEP_DATA_ATTR), this.step);
this.value = origValueNow;
this.disabled = (this.root_.hasAttribute(strings$k.ARIA_DISABLED) &&
this.root_.getAttribute(strings$k.ARIA_DISABLED) !== 'false');
this.foundation_.setupTrackMarker();
};
MDCSlider.prototype.layout = function () {
this.foundation_.layout();
};
MDCSlider.prototype.stepUp = function (amount) {
if (amount === void 0) { amount = (this.step || 1); }
this.value += amount;
};
MDCSlider.prototype.stepDown = function (amount) {
if (amount === void 0) { amount = (this.step || 1); }
this.value -= amount;
};
MDCSlider.prototype.parseFloat_ = function (str, defaultValue) {
var num = parseFloat(str); // tslint:disable-line:ban
var isNumeric = typeof num === 'number' && isFinite(num);
return isNumeric ? num : defaultValue;
};
return MDCSlider;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$k = {
CLOSING: 'mdc-snackbar--closing',
OPEN: 'mdc-snackbar--open',
OPENING: 'mdc-snackbar--opening',
};
var strings$l = {
ACTION_SELECTOR: '.mdc-snackbar__action',
ARIA_LIVE_LABEL_TEXT_ATTR: 'data-mdc-snackbar-label-text',
CLOSED_EVENT: 'MDCSnackbar:closed',
CLOSING_EVENT: 'MDCSnackbar:closing',
DISMISS_SELECTOR: '.mdc-snackbar__dismiss',
LABEL_SELECTOR: '.mdc-snackbar__label',
OPENED_EVENT: 'MDCSnackbar:opened',
OPENING_EVENT: 'MDCSnackbar:opening',
REASON_ACTION: 'action',
REASON_DISMISS: 'dismiss',
SURFACE_SELECTOR: '.mdc-snackbar__surface',
};
var numbers$9 = {
DEFAULT_AUTO_DISMISS_TIMEOUT_MS: 5000,
MAX_AUTO_DISMISS_TIMEOUT_MS: 10000,
MIN_AUTO_DISMISS_TIMEOUT_MS: 4000,
// These variables need to be kept in sync with the values in _variables.scss.
SNACKBAR_ANIMATION_CLOSE_TIME_MS: 75,
SNACKBAR_ANIMATION_OPEN_TIME_MS: 150,
/**
* Number of milliseconds to wait between temporarily clearing the label text
* in the DOM and subsequently restoring it. This is necessary to force IE 11
* to pick up the `aria-live` content change and announce it to the user.
*/
ARIA_LIVE_DELAY_MS: 1000,
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var ARIA_LIVE_DELAY_MS = numbers$9.ARIA_LIVE_DELAY_MS;
var ARIA_LIVE_LABEL_TEXT_ATTR = strings$l.ARIA_LIVE_LABEL_TEXT_ATTR;
function announce(ariaEl, labelEl) {
if (labelEl === void 0) { labelEl = ariaEl; }
var priority = ariaEl.getAttribute('aria-live');
// Trim text to ignore `&nbsp;` (see below).
// textContent is only null if the node is a document, DOCTYPE, or notation.
var labelText = labelEl.textContent.trim();
if (!labelText || !priority) {
return;
}
// Temporarily disable `aria-live` to prevent JAWS+Firefox from announcing the message twice.
ariaEl.setAttribute('aria-live', 'off');
// Temporarily clear `textContent` to force a DOM mutation event that will be detected by screen readers.
// `aria-live` elements are only announced when the element's `textContent` *changes*, so snackbars
// sent to the browser in the initial HTML response won't be read unless we clear the element's `textContent` first.
// Similarly, displaying the same snackbar message twice in a row doesn't trigger a DOM mutation event,
// so screen readers won't announce the second message unless we first clear `textContent`.
//
// We have to clear the label text two different ways to make it work in all browsers and screen readers:
//
// 1. `textContent = ''` is required for IE11 + JAWS
// 2. `innerHTML = '&nbsp;'` is required for Chrome + JAWS and NVDA
//
// All other browser/screen reader combinations support both methods.
//
// The wrapper `<span>` visually hides the space character so that it doesn't cause jank when added/removed.
// N.B.: Setting `position: absolute`, `opacity: 0`, or `height: 0` prevents Chrome from detecting the DOM change.
//
// This technique has been tested in:
//
// * JAWS 2019:
// - Chrome 70
// - Firefox 60 (ESR)
// - IE 11
// * NVDA 2018:
// - Chrome 70
// - Firefox 60 (ESR)
// - IE 11
// * ChromeVox 53
labelEl.textContent = '';
labelEl.innerHTML = '<span style="display: inline-block; width: 0; height: 1px;">&nbsp;</span>';
// Prevent visual jank by temporarily displaying the label text in the ::before pseudo-element.
// CSS generated content is normally announced by screen readers
// (except in IE 11; see https://tink.uk/accessibility-support-for-css-generated-content/);
// however, `aria-live` is turned off, so this DOM update will be ignored by screen readers.
labelEl.setAttribute(ARIA_LIVE_LABEL_TEXT_ATTR, labelText);
setTimeout(function () {
// Allow screen readers to announce changes to the DOM again.
ariaEl.setAttribute('aria-live', priority);
// Remove the message from the ::before pseudo-element.
labelEl.removeAttribute(ARIA_LIVE_LABEL_TEXT_ATTR);
// Restore the original label text, which will be announced by screen readers.
labelEl.textContent = labelText;
}, ARIA_LIVE_DELAY_MS);
}
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var OPENING = cssClasses$k.OPENING, OPEN = cssClasses$k.OPEN, CLOSING = cssClasses$k.CLOSING;
var REASON_ACTION = strings$l.REASON_ACTION, REASON_DISMISS = strings$l.REASON_DISMISS;
var MDCSnackbarFoundation = /** @class */ (function (_super) {
__extends(MDCSnackbarFoundation, _super);
function MDCSnackbarFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCSnackbarFoundation.defaultAdapter, adapter)) || this;
_this.isOpen_ = false;
_this.animationFrame_ = 0;
_this.animationTimer_ = 0;
_this.autoDismissTimer_ = 0;
_this.autoDismissTimeoutMs_ = numbers$9.DEFAULT_AUTO_DISMISS_TIMEOUT_MS;
_this.closeOnEscape_ = true;
return _this;
}
Object.defineProperty(MDCSnackbarFoundation, "cssClasses", {
get: function () {
return cssClasses$k;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSnackbarFoundation, "strings", {
get: function () {
return strings$l;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSnackbarFoundation, "numbers", {
get: function () {
return numbers$9;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSnackbarFoundation, "defaultAdapter", {
get: function () {
return {
addClass: function () { return undefined; },
announce: function () { return undefined; },
notifyClosed: function () { return undefined; },
notifyClosing: function () { return undefined; },
notifyOpened: function () { return undefined; },
notifyOpening: function () { return undefined; },
removeClass: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCSnackbarFoundation.prototype.destroy = function () {
this.clearAutoDismissTimer_();
cancelAnimationFrame(this.animationFrame_);
this.animationFrame_ = 0;
clearTimeout(this.animationTimer_);
this.animationTimer_ = 0;
this.adapter_.removeClass(OPENING);
this.adapter_.removeClass(OPEN);
this.adapter_.removeClass(CLOSING);
};
MDCSnackbarFoundation.prototype.open = function () {
var _this = this;
this.clearAutoDismissTimer_();
this.isOpen_ = true;
this.adapter_.notifyOpening();
this.adapter_.removeClass(CLOSING);
this.adapter_.addClass(OPENING);
this.adapter_.announce();
// Wait a frame once display is no longer "none", to establish basis for animation
this.runNextAnimationFrame_(function () {
_this.adapter_.addClass(OPEN);
_this.animationTimer_ = setTimeout(function () {
_this.handleAnimationTimerEnd_();
_this.adapter_.notifyOpened();
_this.autoDismissTimer_ = setTimeout(function () {
_this.close(REASON_DISMISS);
}, _this.getTimeoutMs());
}, numbers$9.SNACKBAR_ANIMATION_OPEN_TIME_MS);
});
};
/**
* @param reason Why the snackbar was closed. Value will be passed to CLOSING_EVENT and CLOSED_EVENT via the
* `event.detail.reason` property. Standard values are REASON_ACTION and REASON_DISMISS, but custom
* client-specific values may also be used if desired.
*/
MDCSnackbarFoundation.prototype.close = function (reason) {
var _this = this;
if (reason === void 0) { reason = ''; }
if (!this.isOpen_) {
// Avoid redundant close calls (and events), e.g. repeated interactions as the snackbar is animating closed
return;
}
cancelAnimationFrame(this.animationFrame_);
this.animationFrame_ = 0;
this.clearAutoDismissTimer_();
this.isOpen_ = false;
this.adapter_.notifyClosing(reason);
this.adapter_.addClass(cssClasses$k.CLOSING);
this.adapter_.removeClass(cssClasses$k.OPEN);
this.adapter_.removeClass(cssClasses$k.OPENING);
clearTimeout(this.animationTimer_);
this.animationTimer_ = setTimeout(function () {
_this.handleAnimationTimerEnd_();
_this.adapter_.notifyClosed(reason);
}, numbers$9.SNACKBAR_ANIMATION_CLOSE_TIME_MS);
};
MDCSnackbarFoundation.prototype.isOpen = function () {
return this.isOpen_;
};
MDCSnackbarFoundation.prototype.getTimeoutMs = function () {
return this.autoDismissTimeoutMs_;
};
MDCSnackbarFoundation.prototype.setTimeoutMs = function (timeoutMs) {
// Use shorter variable names to make the code more readable
var minValue = numbers$9.MIN_AUTO_DISMISS_TIMEOUT_MS;
var maxValue = numbers$9.MAX_AUTO_DISMISS_TIMEOUT_MS;
if (timeoutMs <= maxValue && timeoutMs >= minValue) {
this.autoDismissTimeoutMs_ = timeoutMs;
}
else {
throw new Error("timeoutMs must be an integer in the range " + minValue + "\u2013" + maxValue + ", but got '" + timeoutMs + "'");
}
};
MDCSnackbarFoundation.prototype.getCloseOnEscape = function () {
return this.closeOnEscape_;
};
MDCSnackbarFoundation.prototype.setCloseOnEscape = function (closeOnEscape) {
this.closeOnEscape_ = closeOnEscape;
};
MDCSnackbarFoundation.prototype.handleKeyDown = function (evt) {
var isEscapeKey = evt.key === 'Escape' || evt.keyCode === 27;
if (isEscapeKey && this.getCloseOnEscape()) {
this.close(REASON_DISMISS);
}
};
MDCSnackbarFoundation.prototype.handleActionButtonClick = function (_evt) {
this.close(REASON_ACTION);
};
MDCSnackbarFoundation.prototype.handleActionIconClick = function (_evt) {
this.close(REASON_DISMISS);
};
MDCSnackbarFoundation.prototype.clearAutoDismissTimer_ = function () {
clearTimeout(this.autoDismissTimer_);
this.autoDismissTimer_ = 0;
};
MDCSnackbarFoundation.prototype.handleAnimationTimerEnd_ = function () {
this.animationTimer_ = 0;
this.adapter_.removeClass(cssClasses$k.OPENING);
this.adapter_.removeClass(cssClasses$k.CLOSING);
};
/**
* Runs the given logic on the next animation frame, using setTimeout to factor in Firefox reflow behavior.
*/
MDCSnackbarFoundation.prototype.runNextAnimationFrame_ = function (callback) {
var _this = this;
cancelAnimationFrame(this.animationFrame_);
this.animationFrame_ = requestAnimationFrame(function () {
_this.animationFrame_ = 0;
clearTimeout(_this.animationTimer_);
_this.animationTimer_ = setTimeout(callback, 0);
});
};
return MDCSnackbarFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var SURFACE_SELECTOR = strings$l.SURFACE_SELECTOR, LABEL_SELECTOR = strings$l.LABEL_SELECTOR, ACTION_SELECTOR = strings$l.ACTION_SELECTOR, DISMISS_SELECTOR = strings$l.DISMISS_SELECTOR, OPENING_EVENT = strings$l.OPENING_EVENT, OPENED_EVENT = strings$l.OPENED_EVENT, CLOSING_EVENT = strings$l.CLOSING_EVENT, CLOSED_EVENT = strings$l.CLOSED_EVENT;
var MDCSnackbar = /** @class */ (function (_super) {
__extends(MDCSnackbar, _super);
function MDCSnackbar() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCSnackbar.attachTo = function (root) {
return new MDCSnackbar(root);
};
MDCSnackbar.prototype.initialize = function (announcerFactory) {
if (announcerFactory === void 0) { announcerFactory = function () { return announce; }; }
this.announce_ = announcerFactory();
};
MDCSnackbar.prototype.initialSyncWithDOM = function () {
var _this = this;
this.surfaceEl_ = this.root_.querySelector(SURFACE_SELECTOR);
this.labelEl_ = this.root_.querySelector(LABEL_SELECTOR);
this.actionEl_ = this.root_.querySelector(ACTION_SELECTOR);
this.handleKeyDown_ = function (evt) { return _this.foundation_.handleKeyDown(evt); };
this.handleSurfaceClick_ = function (evt) {
var target = evt.target;
if (_this.isActionButton_(target)) {
_this.foundation_.handleActionButtonClick(evt);
}
else if (_this.isActionIcon_(target)) {
_this.foundation_.handleActionIconClick(evt);
}
};
this.registerKeyDownHandler_(this.handleKeyDown_);
this.registerSurfaceClickHandler_(this.handleSurfaceClick_);
};
MDCSnackbar.prototype.destroy = function () {
_super.prototype.destroy.call(this);
this.deregisterKeyDownHandler_(this.handleKeyDown_);
this.deregisterSurfaceClickHandler_(this.handleSurfaceClick_);
};
MDCSnackbar.prototype.open = function () {
this.foundation_.open();
};
/**
* @param reason Why the snackbar was closed. Value will be passed to CLOSING_EVENT and CLOSED_EVENT via the
* `event.detail.reason` property. Standard values are REASON_ACTION and REASON_DISMISS, but custom
* client-specific values may also be used if desired.
*/
MDCSnackbar.prototype.close = function (reason) {
if (reason === void 0) { reason = ''; }
this.foundation_.close(reason);
};
MDCSnackbar.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
announce: function () { return _this.announce_(_this.labelEl_); },
notifyClosed: function (reason) { return _this.emit(CLOSED_EVENT, reason ? { reason: reason } : {}); },
notifyClosing: function (reason) { return _this.emit(CLOSING_EVENT, reason ? { reason: reason } : {}); },
notifyOpened: function () { return _this.emit(OPENED_EVENT, {}); },
notifyOpening: function () { return _this.emit(OPENING_EVENT, {}); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
};
return new MDCSnackbarFoundation(adapter);
};
Object.defineProperty(MDCSnackbar.prototype, "timeoutMs", {
get: function () {
return this.foundation_.getTimeoutMs();
},
set: function (timeoutMs) {
this.foundation_.setTimeoutMs(timeoutMs);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSnackbar.prototype, "closeOnEscape", {
get: function () {
return this.foundation_.getCloseOnEscape();
},
set: function (closeOnEscape) {
this.foundation_.setCloseOnEscape(closeOnEscape);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSnackbar.prototype, "isOpen", {
get: function () {
return this.foundation_.isOpen();
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSnackbar.prototype, "labelText", {
get: function () {
// This property only returns null if the node is a document, DOCTYPE, or notation.
// On Element nodes, it always returns a string.
return this.labelEl_.textContent;
},
set: function (labelText) {
this.labelEl_.textContent = labelText;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSnackbar.prototype, "actionButtonText", {
get: function () {
return this.actionEl_.textContent;
},
set: function (actionButtonText) {
this.actionEl_.textContent = actionButtonText;
},
enumerable: true,
configurable: true
});
MDCSnackbar.prototype.registerKeyDownHandler_ = function (handler) {
this.listen('keydown', handler);
};
MDCSnackbar.prototype.deregisterKeyDownHandler_ = function (handler) {
this.unlisten('keydown', handler);
};
MDCSnackbar.prototype.registerSurfaceClickHandler_ = function (handler) {
this.surfaceEl_.addEventListener('click', handler);
};
MDCSnackbar.prototype.deregisterSurfaceClickHandler_ = function (handler) {
this.surfaceEl_.removeEventListener('click', handler);
};
MDCSnackbar.prototype.isActionButton_ = function (target) {
return Boolean(closest(target, ACTION_SELECTOR));
};
MDCSnackbar.prototype.isActionIcon_ = function (target) {
return Boolean(closest(target, DISMISS_SELECTOR));
};
return MDCSnackbar;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/** CSS classes used by the switch. */
var cssClasses$l = {
/** Class used for a switch that is in the "checked" (on) position. */
CHECKED: 'mdc-switch--checked',
/** Class used for a switch that is disabled. */
DISABLED: 'mdc-switch--disabled',
};
/** String constants used by the switch. */
var strings$m = {
/** A CSS selector used to locate the native HTML control for the switch. */
NATIVE_CONTROL_SELECTOR: '.mdc-switch__native-control',
/** A CSS selector used to locate the ripple surface element for the switch. */
RIPPLE_SURFACE_SELECTOR: '.mdc-switch__thumb-underlay',
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCSwitchFoundation = /** @class */ (function (_super) {
__extends(MDCSwitchFoundation, _super);
function MDCSwitchFoundation(adapter) {
return _super.call(this, __assign({}, MDCSwitchFoundation.defaultAdapter, adapter)) || this;
}
Object.defineProperty(MDCSwitchFoundation, "strings", {
/** The string constants used by the switch. */
get: function () {
return strings$m;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSwitchFoundation, "cssClasses", {
/** The CSS classes used by the switch. */
get: function () {
return cssClasses$l;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSwitchFoundation, "defaultAdapter", {
/** The default Adapter for the switch. */
get: function () {
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
setNativeControlChecked: function () { return undefined; },
setNativeControlDisabled: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
/** Sets the checked state of the switch. */
MDCSwitchFoundation.prototype.setChecked = function (checked) {
this.adapter_.setNativeControlChecked(checked);
this.updateCheckedStyling_(checked);
};
/** Sets the disabled state of the switch. */
MDCSwitchFoundation.prototype.setDisabled = function (disabled) {
this.adapter_.setNativeControlDisabled(disabled);
if (disabled) {
this.adapter_.addClass(cssClasses$l.DISABLED);
}
else {
this.adapter_.removeClass(cssClasses$l.DISABLED);
}
};
/** Handles the change event for the switch native control. */
MDCSwitchFoundation.prototype.handleChange = function (evt) {
var nativeControl = evt.target;
this.updateCheckedStyling_(nativeControl.checked);
};
/** Updates the styling of the switch based on its checked state. */
MDCSwitchFoundation.prototype.updateCheckedStyling_ = function (checked) {
if (checked) {
this.adapter_.addClass(cssClasses$l.CHECKED);
}
else {
this.adapter_.removeClass(cssClasses$l.CHECKED);
}
};
return MDCSwitchFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCSwitch = /** @class */ (function (_super) {
__extends(MDCSwitch, _super);
function MDCSwitch() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.ripple_ = _this.createRipple_();
return _this;
}
MDCSwitch.attachTo = function (root) {
return new MDCSwitch(root);
};
MDCSwitch.prototype.destroy = function () {
_super.prototype.destroy.call(this);
this.ripple_.destroy();
this.nativeControl_.removeEventListener('change', this.changeHandler_);
};
MDCSwitch.prototype.initialSyncWithDOM = function () {
var _this = this;
this.changeHandler_ = function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return (_a = _this.foundation_).handleChange.apply(_a, __spread(args));
};
this.nativeControl_.addEventListener('change', this.changeHandler_);
// Sometimes the checked state of the input element is saved in the history.
// The switch styling should match the checked state of the input element.
// Do an initial sync between the native control and the foundation.
this.checked = this.checked;
};
MDCSwitch.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
setNativeControlChecked: function (checked) { return _this.nativeControl_.checked = checked; },
setNativeControlDisabled: function (disabled) { return _this.nativeControl_.disabled = disabled; },
};
return new MDCSwitchFoundation(adapter);
};
Object.defineProperty(MDCSwitch.prototype, "ripple", {
get: function () {
return this.ripple_;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSwitch.prototype, "checked", {
get: function () {
return this.nativeControl_.checked;
},
set: function (checked) {
this.foundation_.setChecked(checked);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCSwitch.prototype, "disabled", {
get: function () {
return this.nativeControl_.disabled;
},
set: function (disabled) {
this.foundation_.setDisabled(disabled);
},
enumerable: true,
configurable: true
});
MDCSwitch.prototype.createRipple_ = function () {
var _this = this;
var RIPPLE_SURFACE_SELECTOR = MDCSwitchFoundation.strings.RIPPLE_SURFACE_SELECTOR;
var rippleSurface = this.root_.querySelector(RIPPLE_SURFACE_SELECTOR);
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = __assign({}, MDCRipple.createAdapter(this), { addClass: function (className) { return rippleSurface.classList.add(className); }, computeBoundingRect: function () { return rippleSurface.getBoundingClientRect(); }, deregisterInteractionHandler: function (evtType, handler) {
_this.nativeControl_.removeEventListener(evtType, handler, applyPassive());
}, isSurfaceActive: function () { return matches(_this.nativeControl_, ':active'); }, isUnbounded: function () { return true; }, registerInteractionHandler: function (evtType, handler) {
_this.nativeControl_.addEventListener(evtType, handler, applyPassive());
}, removeClass: function (className) { return rippleSurface.classList.remove(className); }, updateCssVariable: function (varName, value) {
rippleSurface.style.setProperty(varName, value);
} });
return new MDCRipple(this.root_, new MDCRippleFoundation(adapter));
};
Object.defineProperty(MDCSwitch.prototype, "nativeControl_", {
get: function () {
var NATIVE_CONTROL_SELECTOR = MDCSwitchFoundation.strings.NATIVE_CONTROL_SELECTOR;
return this.root_.querySelector(NATIVE_CONTROL_SELECTOR);
},
enumerable: true,
configurable: true
});
return MDCSwitch;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$m = {
ANIMATING: 'mdc-tab-scroller--animating',
SCROLL_AREA_SCROLL: 'mdc-tab-scroller__scroll-area--scroll',
SCROLL_TEST: 'mdc-tab-scroller__test',
};
var strings$n = {
AREA_SELECTOR: '.mdc-tab-scroller__scroll-area',
CONTENT_SELECTOR: '.mdc-tab-scroller__scroll-content',
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTabScrollerRTL = /** @class */ (function () {
function MDCTabScrollerRTL(adapter) {
this.adapter_ = adapter;
}
return MDCTabScrollerRTL;
}());
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTabScrollerRTLDefault = /** @class */ (function (_super) {
__extends(MDCTabScrollerRTLDefault, _super);
function MDCTabScrollerRTLDefault() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCTabScrollerRTLDefault.prototype.getScrollPositionRTL = function () {
var currentScrollLeft = this.adapter_.getScrollAreaScrollLeft();
var right = this.calculateScrollEdges_().right;
// Scroll values on most browsers are ints instead of floats so we round
return Math.round(right - currentScrollLeft);
};
MDCTabScrollerRTLDefault.prototype.scrollToRTL = function (scrollX) {
var edges = this.calculateScrollEdges_();
var currentScrollLeft = this.adapter_.getScrollAreaScrollLeft();
var clampedScrollLeft = this.clampScrollValue_(edges.right - scrollX);
return {
finalScrollPosition: clampedScrollLeft,
scrollDelta: clampedScrollLeft - currentScrollLeft,
};
};
MDCTabScrollerRTLDefault.prototype.incrementScrollRTL = function (scrollX) {
var currentScrollLeft = this.adapter_.getScrollAreaScrollLeft();
var clampedScrollLeft = this.clampScrollValue_(currentScrollLeft - scrollX);
return {
finalScrollPosition: clampedScrollLeft,
scrollDelta: clampedScrollLeft - currentScrollLeft,
};
};
MDCTabScrollerRTLDefault.prototype.getAnimatingScrollPosition = function (scrollX) {
return scrollX;
};
MDCTabScrollerRTLDefault.prototype.calculateScrollEdges_ = function () {
var contentWidth = this.adapter_.getScrollContentOffsetWidth();
var rootWidth = this.adapter_.getScrollAreaOffsetWidth();
return {
left: 0,
right: contentWidth - rootWidth,
};
};
MDCTabScrollerRTLDefault.prototype.clampScrollValue_ = function (scrollX) {
var edges = this.calculateScrollEdges_();
return Math.min(Math.max(edges.left, scrollX), edges.right);
};
return MDCTabScrollerRTLDefault;
}(MDCTabScrollerRTL));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTabScrollerRTLNegative = /** @class */ (function (_super) {
__extends(MDCTabScrollerRTLNegative, _super);
function MDCTabScrollerRTLNegative() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCTabScrollerRTLNegative.prototype.getScrollPositionRTL = function (translateX) {
var currentScrollLeft = this.adapter_.getScrollAreaScrollLeft();
return Math.round(translateX - currentScrollLeft);
};
MDCTabScrollerRTLNegative.prototype.scrollToRTL = function (scrollX) {
var currentScrollLeft = this.adapter_.getScrollAreaScrollLeft();
var clampedScrollLeft = this.clampScrollValue_(-scrollX);
return {
finalScrollPosition: clampedScrollLeft,
scrollDelta: clampedScrollLeft - currentScrollLeft,
};
};
MDCTabScrollerRTLNegative.prototype.incrementScrollRTL = function (scrollX) {
var currentScrollLeft = this.adapter_.getScrollAreaScrollLeft();
var clampedScrollLeft = this.clampScrollValue_(currentScrollLeft - scrollX);
return {
finalScrollPosition: clampedScrollLeft,
scrollDelta: clampedScrollLeft - currentScrollLeft,
};
};
MDCTabScrollerRTLNegative.prototype.getAnimatingScrollPosition = function (scrollX, translateX) {
return scrollX - translateX;
};
MDCTabScrollerRTLNegative.prototype.calculateScrollEdges_ = function () {
var contentWidth = this.adapter_.getScrollContentOffsetWidth();
var rootWidth = this.adapter_.getScrollAreaOffsetWidth();
return {
left: rootWidth - contentWidth,
right: 0,
};
};
MDCTabScrollerRTLNegative.prototype.clampScrollValue_ = function (scrollX) {
var edges = this.calculateScrollEdges_();
return Math.max(Math.min(edges.right, scrollX), edges.left);
};
return MDCTabScrollerRTLNegative;
}(MDCTabScrollerRTL));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTabScrollerRTLReverse = /** @class */ (function (_super) {
__extends(MDCTabScrollerRTLReverse, _super);
function MDCTabScrollerRTLReverse() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCTabScrollerRTLReverse.prototype.getScrollPositionRTL = function (translateX) {
var currentScrollLeft = this.adapter_.getScrollAreaScrollLeft();
// Scroll values on most browsers are ints instead of floats so we round
return Math.round(currentScrollLeft - translateX);
};
MDCTabScrollerRTLReverse.prototype.scrollToRTL = function (scrollX) {
var currentScrollLeft = this.adapter_.getScrollAreaScrollLeft();
var clampedScrollLeft = this.clampScrollValue_(scrollX);
return {
finalScrollPosition: clampedScrollLeft,
scrollDelta: currentScrollLeft - clampedScrollLeft,
};
};
MDCTabScrollerRTLReverse.prototype.incrementScrollRTL = function (scrollX) {
var currentScrollLeft = this.adapter_.getScrollAreaScrollLeft();
var clampedScrollLeft = this.clampScrollValue_(currentScrollLeft + scrollX);
return {
finalScrollPosition: clampedScrollLeft,
scrollDelta: currentScrollLeft - clampedScrollLeft,
};
};
MDCTabScrollerRTLReverse.prototype.getAnimatingScrollPosition = function (scrollX, translateX) {
return scrollX + translateX;
};
MDCTabScrollerRTLReverse.prototype.calculateScrollEdges_ = function () {
var contentWidth = this.adapter_.getScrollContentOffsetWidth();
var rootWidth = this.adapter_.getScrollAreaOffsetWidth();
return {
left: contentWidth - rootWidth,
right: 0,
};
};
MDCTabScrollerRTLReverse.prototype.clampScrollValue_ = function (scrollX) {
var edges = this.calculateScrollEdges_();
return Math.min(Math.max(edges.right, scrollX), edges.left);
};
return MDCTabScrollerRTLReverse;
}(MDCTabScrollerRTL));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTabScrollerFoundation = /** @class */ (function (_super) {
__extends(MDCTabScrollerFoundation, _super);
function MDCTabScrollerFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCTabScrollerFoundation.defaultAdapter, adapter)) || this;
/**
* Controls whether we should handle the transitionend and interaction events during the animation.
*/
_this.isAnimating_ = false;
return _this;
}
Object.defineProperty(MDCTabScrollerFoundation, "cssClasses", {
get: function () {
return cssClasses$m;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTabScrollerFoundation, "strings", {
get: function () {
return strings$n;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTabScrollerFoundation, "defaultAdapter", {
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
eventTargetMatchesSelector: function () { return false; },
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
addScrollAreaClass: function () { return undefined; },
setScrollAreaStyleProperty: function () { return undefined; },
setScrollContentStyleProperty: function () { return undefined; },
getScrollContentStyleValue: function () { return ''; },
setScrollAreaScrollLeft: function () { return undefined; },
getScrollAreaScrollLeft: function () { return 0; },
getScrollContentOffsetWidth: function () { return 0; },
getScrollAreaOffsetWidth: function () { return 0; },
computeScrollAreaClientRect: function () { return ({ top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 }); },
computeScrollContentClientRect: function () { return ({ top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 }); },
computeHorizontalScrollbarHeight: function () { return 0; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCTabScrollerFoundation.prototype.init = function () {
// Compute horizontal scrollbar height on scroller with overflow initially hidden, then update overflow to scroll
// and immediately adjust bottom margin to avoid the scrollbar initially appearing before JS runs.
var horizontalScrollbarHeight = this.adapter_.computeHorizontalScrollbarHeight();
this.adapter_.setScrollAreaStyleProperty('margin-bottom', -horizontalScrollbarHeight + 'px');
this.adapter_.addScrollAreaClass(MDCTabScrollerFoundation.cssClasses.SCROLL_AREA_SCROLL);
};
/**
* Computes the current visual scroll position
*/
MDCTabScrollerFoundation.prototype.getScrollPosition = function () {
if (this.isRTL_()) {
return this.computeCurrentScrollPositionRTL_();
}
var currentTranslateX = this.calculateCurrentTranslateX_();
var scrollLeft = this.adapter_.getScrollAreaScrollLeft();
return scrollLeft - currentTranslateX;
};
/**
* Handles interaction events that occur during transition
*/
MDCTabScrollerFoundation.prototype.handleInteraction = function () {
// Early exit if we aren't animating
if (!this.isAnimating_) {
return;
}
// Prevent other event listeners from handling this event
this.stopScrollAnimation_();
};
/**
* Handles the transitionend event
*/
MDCTabScrollerFoundation.prototype.handleTransitionEnd = function (evt) {
// Early exit if we aren't animating or the event was triggered by a different element.
var evtTarget = evt.target;
if (!this.isAnimating_ ||
!this.adapter_.eventTargetMatchesSelector(evtTarget, MDCTabScrollerFoundation.strings.CONTENT_SELECTOR)) {
return;
}
this.isAnimating_ = false;
this.adapter_.removeClass(MDCTabScrollerFoundation.cssClasses.ANIMATING);
};
/**
* Increment the scroll value by the scrollXIncrement
* @param scrollXIncrement The value by which to increment the scroll position
*/
MDCTabScrollerFoundation.prototype.incrementScroll = function (scrollXIncrement) {
// Early exit for non-operational increment values
if (scrollXIncrement === 0) {
return;
}
if (this.isRTL_()) {
return this.incrementScrollRTL_(scrollXIncrement);
}
this.incrementScroll_(scrollXIncrement);
};
/**
* Scrolls to the given scrollX value
*/
MDCTabScrollerFoundation.prototype.scrollTo = function (scrollX) {
if (this.isRTL_()) {
return this.scrollToRTL_(scrollX);
}
this.scrollTo_(scrollX);
};
/**
* @return Browser-specific {@link MDCTabScrollerRTL} instance.
*/
MDCTabScrollerFoundation.prototype.getRTLScroller = function () {
if (!this.rtlScrollerInstance_) {
this.rtlScrollerInstance_ = this.rtlScrollerFactory_();
}
return this.rtlScrollerInstance_;
};
/**
* @return translateX value from a CSS matrix transform function string.
*/
MDCTabScrollerFoundation.prototype.calculateCurrentTranslateX_ = function () {
var transformValue = this.adapter_.getScrollContentStyleValue('transform');
// Early exit if no transform is present
if (transformValue === 'none') {
return 0;
}
// The transform value comes back as a matrix transformation in the form
// of `matrix(a, b, c, d, tx, ty)`. We only care about tx (translateX) so
// we're going to grab all the parenthesized values, strip out tx, and
// parse it.
var match = /\((.+?)\)/.exec(transformValue);
if (!match) {
return 0;
}
var matrixParams = match[1];
// tslint:disable-next-line:ban-ts-ignore "Unused vars" should be a linter warning, not a compiler error.
// @ts-ignore These unused variables should retain their semantic names for clarity.
var _a = __read(matrixParams.split(','), 6), a = _a[0], b = _a[1], c = _a[2], d = _a[3], tx = _a[4], ty = _a[5];
return parseFloat(tx); // tslint:disable-line:ban
};
/**
* Calculates a safe scroll value that is > 0 and < the max scroll value
* @param scrollX The distance to scroll
*/
MDCTabScrollerFoundation.prototype.clampScrollValue_ = function (scrollX) {
var edges = this.calculateScrollEdges_();
return Math.min(Math.max(edges.left, scrollX), edges.right);
};
MDCTabScrollerFoundation.prototype.computeCurrentScrollPositionRTL_ = function () {
var translateX = this.calculateCurrentTranslateX_();
return this.getRTLScroller().getScrollPositionRTL(translateX);
};
MDCTabScrollerFoundation.prototype.calculateScrollEdges_ = function () {
var contentWidth = this.adapter_.getScrollContentOffsetWidth();
var rootWidth = this.adapter_.getScrollAreaOffsetWidth();
return {
left: 0,
right: contentWidth - rootWidth,
};
};
/**
* Internal scroll method
* @param scrollX The new scroll position
*/
MDCTabScrollerFoundation.prototype.scrollTo_ = function (scrollX) {
var currentScrollX = this.getScrollPosition();
var safeScrollX = this.clampScrollValue_(scrollX);
var scrollDelta = safeScrollX - currentScrollX;
this.animate_({
finalScrollPosition: safeScrollX,
scrollDelta: scrollDelta,
});
};
/**
* Internal RTL scroll method
* @param scrollX The new scroll position
*/
MDCTabScrollerFoundation.prototype.scrollToRTL_ = function (scrollX) {
var animation = this.getRTLScroller().scrollToRTL(scrollX);
this.animate_(animation);
};
/**
* Internal increment scroll method
* @param scrollX The new scroll position increment
*/
MDCTabScrollerFoundation.prototype.incrementScroll_ = function (scrollX) {
var currentScrollX = this.getScrollPosition();
var targetScrollX = scrollX + currentScrollX;
var safeScrollX = this.clampScrollValue_(targetScrollX);
var scrollDelta = safeScrollX - currentScrollX;
this.animate_({
finalScrollPosition: safeScrollX,
scrollDelta: scrollDelta,
});
};
/**
* Internal increment scroll RTL method
* @param scrollX The new scroll position RTL increment
*/
MDCTabScrollerFoundation.prototype.incrementScrollRTL_ = function (scrollX) {
var animation = this.getRTLScroller().incrementScrollRTL(scrollX);
this.animate_(animation);
};
/**
* Animates the tab scrolling
* @param animation The animation to apply
*/
MDCTabScrollerFoundation.prototype.animate_ = function (animation) {
var _this = this;
// Early exit if translateX is 0, which means there's no animation to perform
if (animation.scrollDelta === 0) {
return;
}
this.stopScrollAnimation_();
// This animation uses the FLIP approach.
// Read more here: https://aerotwist.com/blog/flip-your-animations/
this.adapter_.setScrollAreaScrollLeft(animation.finalScrollPosition);
this.adapter_.setScrollContentStyleProperty('transform', "translateX(" + animation.scrollDelta + "px)");
// Force repaint
this.adapter_.computeScrollAreaClientRect();
requestAnimationFrame(function () {
_this.adapter_.addClass(MDCTabScrollerFoundation.cssClasses.ANIMATING);
_this.adapter_.setScrollContentStyleProperty('transform', 'none');
});
this.isAnimating_ = true;
};
/**
* Stops scroll animation
*/
MDCTabScrollerFoundation.prototype.stopScrollAnimation_ = function () {
this.isAnimating_ = false;
var currentScrollPosition = this.getAnimatingScrollPosition_();
this.adapter_.removeClass(MDCTabScrollerFoundation.cssClasses.ANIMATING);
this.adapter_.setScrollContentStyleProperty('transform', 'translateX(0px)');
this.adapter_.setScrollAreaScrollLeft(currentScrollPosition);
};
/**
* Gets the current scroll position during animation
*/
MDCTabScrollerFoundation.prototype.getAnimatingScrollPosition_ = function () {
var currentTranslateX = this.calculateCurrentTranslateX_();
var scrollLeft = this.adapter_.getScrollAreaScrollLeft();
if (this.isRTL_()) {
return this.getRTLScroller().getAnimatingScrollPosition(scrollLeft, currentTranslateX);
}
return scrollLeft - currentTranslateX;
};
/**
* Determines the RTL Scroller to use
*/
MDCTabScrollerFoundation.prototype.rtlScrollerFactory_ = function () {
// Browsers have three different implementations of scrollLeft in RTL mode,
// dependent on the browser. The behavior is based off the max LTR
// scrollLeft value and 0.
//
// * Default scrolling in RTL *
// - Left-most value: 0
// - Right-most value: Max LTR scrollLeft value
//
// * Negative scrolling in RTL *
// - Left-most value: Negated max LTR scrollLeft value
// - Right-most value: 0
//
// * Reverse scrolling in RTL *
// - Left-most value: Max LTR scrollLeft value
// - Right-most value: 0
//
// We use those principles below to determine which RTL scrollLeft
// behavior is implemented in the current browser.
var initialScrollLeft = this.adapter_.getScrollAreaScrollLeft();
this.adapter_.setScrollAreaScrollLeft(initialScrollLeft - 1);
var newScrollLeft = this.adapter_.getScrollAreaScrollLeft();
// If the newScrollLeft value is negative,then we know that the browser has
// implemented negative RTL scrolling, since all other implementations have
// only positive values.
if (newScrollLeft < 0) {
// Undo the scrollLeft test check
this.adapter_.setScrollAreaScrollLeft(initialScrollLeft);
return new MDCTabScrollerRTLNegative(this.adapter_);
}
var rootClientRect = this.adapter_.computeScrollAreaClientRect();
var contentClientRect = this.adapter_.computeScrollContentClientRect();
var rightEdgeDelta = Math.round(contentClientRect.right - rootClientRect.right);
// Undo the scrollLeft test check
this.adapter_.setScrollAreaScrollLeft(initialScrollLeft);
// By calculating the clientRect of the root element and the clientRect of
// the content element, we can determine how much the scroll value changed
// when we performed the scrollLeft subtraction above.
if (rightEdgeDelta === newScrollLeft) {
return new MDCTabScrollerRTLReverse(this.adapter_);
}
return new MDCTabScrollerRTLDefault(this.adapter_);
};
MDCTabScrollerFoundation.prototype.isRTL_ = function () {
return this.adapter_.getScrollContentStyleValue('direction') === 'rtl';
};
return MDCTabScrollerFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* Stores result from computeHorizontalScrollbarHeight to avoid redundant processing.
*/
var horizontalScrollbarHeight_;
/**
* Computes the height of browser-rendered horizontal scrollbars using a self-created test element.
* May return 0 (e.g. on OS X browsers under default configuration).
*/
function computeHorizontalScrollbarHeight(documentObj, shouldCacheResult) {
if (shouldCacheResult === void 0) { shouldCacheResult = true; }
if (shouldCacheResult && typeof horizontalScrollbarHeight_ !== 'undefined') {
return horizontalScrollbarHeight_;
}
var el = documentObj.createElement('div');
el.classList.add(cssClasses$m.SCROLL_TEST);
documentObj.body.appendChild(el);
var horizontalScrollbarHeight = el.offsetHeight - el.clientHeight;
documentObj.body.removeChild(el);
if (shouldCacheResult) {
horizontalScrollbarHeight_ = horizontalScrollbarHeight;
}
return horizontalScrollbarHeight;
}
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTabScroller = /** @class */ (function (_super) {
__extends(MDCTabScroller, _super);
function MDCTabScroller() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCTabScroller.attachTo = function (root) {
return new MDCTabScroller(root);
};
MDCTabScroller.prototype.initialize = function () {
this.area_ = this.root_.querySelector(MDCTabScrollerFoundation.strings.AREA_SELECTOR);
this.content_ = this.root_.querySelector(MDCTabScrollerFoundation.strings.CONTENT_SELECTOR);
};
MDCTabScroller.prototype.initialSyncWithDOM = function () {
var _this = this;
this.handleInteraction_ = function () { return _this.foundation_.handleInteraction(); };
this.handleTransitionEnd_ = function (evt) { return _this.foundation_.handleTransitionEnd(evt); };
this.area_.addEventListener('wheel', this.handleInteraction_, applyPassive());
this.area_.addEventListener('touchstart', this.handleInteraction_, applyPassive());
this.area_.addEventListener('pointerdown', this.handleInteraction_, applyPassive());
this.area_.addEventListener('mousedown', this.handleInteraction_, applyPassive());
this.area_.addEventListener('keydown', this.handleInteraction_, applyPassive());
this.content_.addEventListener('transitionend', this.handleTransitionEnd_);
};
MDCTabScroller.prototype.destroy = function () {
_super.prototype.destroy.call(this);
this.area_.removeEventListener('wheel', this.handleInteraction_, applyPassive());
this.area_.removeEventListener('touchstart', this.handleInteraction_, applyPassive());
this.area_.removeEventListener('pointerdown', this.handleInteraction_, applyPassive());
this.area_.removeEventListener('mousedown', this.handleInteraction_, applyPassive());
this.area_.removeEventListener('keydown', this.handleInteraction_, applyPassive());
this.content_.removeEventListener('transitionend', this.handleTransitionEnd_);
};
MDCTabScroller.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
eventTargetMatchesSelector: function (evtTarget, selector) { return matches(evtTarget, selector); },
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
addScrollAreaClass: function (className) { return _this.area_.classList.add(className); },
setScrollAreaStyleProperty: function (prop, value) { return _this.area_.style.setProperty(prop, value); },
setScrollContentStyleProperty: function (prop, value) { return _this.content_.style.setProperty(prop, value); },
getScrollContentStyleValue: function (propName) { return window.getComputedStyle(_this.content_).getPropertyValue(propName); },
setScrollAreaScrollLeft: function (scrollX) { return _this.area_.scrollLeft = scrollX; },
getScrollAreaScrollLeft: function () { return _this.area_.scrollLeft; },
getScrollContentOffsetWidth: function () { return _this.content_.offsetWidth; },
getScrollAreaOffsetWidth: function () { return _this.area_.offsetWidth; },
computeScrollAreaClientRect: function () { return _this.area_.getBoundingClientRect(); },
computeScrollContentClientRect: function () { return _this.content_.getBoundingClientRect(); },
computeHorizontalScrollbarHeight: function () { return computeHorizontalScrollbarHeight(document); },
};
// tslint:enable:object-literal-sort-keys
return new MDCTabScrollerFoundation(adapter);
};
/**
* Returns the current visual scroll position
*/
MDCTabScroller.prototype.getScrollPosition = function () {
return this.foundation_.getScrollPosition();
};
/**
* Returns the width of the scroll content
*/
MDCTabScroller.prototype.getScrollContentWidth = function () {
return this.content_.offsetWidth;
};
/**
* Increments the scroll value by the given amount
* @param scrollXIncrement The pixel value by which to increment the scroll value
*/
MDCTabScroller.prototype.incrementScroll = function (scrollXIncrement) {
this.foundation_.incrementScroll(scrollXIncrement);
};
/**
* Scrolls to the given pixel position
* @param scrollX The pixel value to scroll to
*/
MDCTabScroller.prototype.scrollTo = function (scrollX) {
this.foundation_.scrollTo(scrollX);
};
return MDCTabScroller;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$n = {
ACTIVE: 'mdc-tab-indicator--active',
FADE: 'mdc-tab-indicator--fade',
NO_TRANSITION: 'mdc-tab-indicator--no-transition',
};
var strings$o = {
CONTENT_SELECTOR: '.mdc-tab-indicator__content',
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTabIndicatorFoundation = /** @class */ (function (_super) {
__extends(MDCTabIndicatorFoundation, _super);
function MDCTabIndicatorFoundation(adapter) {
return _super.call(this, __assign({}, MDCTabIndicatorFoundation.defaultAdapter, adapter)) || this;
}
Object.defineProperty(MDCTabIndicatorFoundation, "cssClasses", {
get: function () {
return cssClasses$n;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTabIndicatorFoundation, "strings", {
get: function () {
return strings$o;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTabIndicatorFoundation, "defaultAdapter", {
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
computeContentClientRect: function () { return ({ top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 }); },
setContentStyleProperty: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCTabIndicatorFoundation.prototype.computeContentClientRect = function () {
return this.adapter_.computeContentClientRect();
};
return MDCTabIndicatorFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* istanbul ignore next: subclass is not a branch statement */
var MDCFadingTabIndicatorFoundation = /** @class */ (function (_super) {
__extends(MDCFadingTabIndicatorFoundation, _super);
function MDCFadingTabIndicatorFoundation() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCFadingTabIndicatorFoundation.prototype.activate = function () {
this.adapter_.addClass(MDCTabIndicatorFoundation.cssClasses.ACTIVE);
};
MDCFadingTabIndicatorFoundation.prototype.deactivate = function () {
this.adapter_.removeClass(MDCTabIndicatorFoundation.cssClasses.ACTIVE);
};
return MDCFadingTabIndicatorFoundation;
}(MDCTabIndicatorFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* istanbul ignore next: subclass is not a branch statement */
var MDCSlidingTabIndicatorFoundation = /** @class */ (function (_super) {
__extends(MDCSlidingTabIndicatorFoundation, _super);
function MDCSlidingTabIndicatorFoundation() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCSlidingTabIndicatorFoundation.prototype.activate = function (previousIndicatorClientRect) {
// Early exit if no indicator is present to handle cases where an indicator
// may be activated without a prior indicator state
if (!previousIndicatorClientRect) {
this.adapter_.addClass(MDCTabIndicatorFoundation.cssClasses.ACTIVE);
return;
}
// This animation uses the FLIP approach. You can read more about it at the link below:
// https://aerotwist.com/blog/flip-your-animations/
// Calculate the dimensions based on the dimensions of the previous indicator
var currentClientRect = this.computeContentClientRect();
var widthDelta = previousIndicatorClientRect.width / currentClientRect.width;
var xPosition = previousIndicatorClientRect.left - currentClientRect.left;
this.adapter_.addClass(MDCTabIndicatorFoundation.cssClasses.NO_TRANSITION);
this.adapter_.setContentStyleProperty('transform', "translateX(" + xPosition + "px) scaleX(" + widthDelta + ")");
// Force repaint before updating classes and transform to ensure the transform properly takes effect
this.computeContentClientRect();
this.adapter_.removeClass(MDCTabIndicatorFoundation.cssClasses.NO_TRANSITION);
this.adapter_.addClass(MDCTabIndicatorFoundation.cssClasses.ACTIVE);
this.adapter_.setContentStyleProperty('transform', '');
};
MDCSlidingTabIndicatorFoundation.prototype.deactivate = function () {
this.adapter_.removeClass(MDCTabIndicatorFoundation.cssClasses.ACTIVE);
};
return MDCSlidingTabIndicatorFoundation;
}(MDCTabIndicatorFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTabIndicator = /** @class */ (function (_super) {
__extends(MDCTabIndicator, _super);
function MDCTabIndicator() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCTabIndicator.attachTo = function (root) {
return new MDCTabIndicator(root);
};
MDCTabIndicator.prototype.initialize = function () {
this.content_ = this.root_.querySelector(MDCTabIndicatorFoundation.strings.CONTENT_SELECTOR);
};
MDCTabIndicator.prototype.computeContentClientRect = function () {
return this.foundation_.computeContentClientRect();
};
MDCTabIndicator.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
computeContentClientRect: function () { return _this.content_.getBoundingClientRect(); },
setContentStyleProperty: function (prop, value) { return _this.content_.style.setProperty(prop, value); },
};
// tslint:enable:object-literal-sort-keys
if (this.root_.classList.contains(MDCTabIndicatorFoundation.cssClasses.FADE)) {
return new MDCFadingTabIndicatorFoundation(adapter);
}
// Default to the sliding indicator
return new MDCSlidingTabIndicatorFoundation(adapter);
};
MDCTabIndicator.prototype.activate = function (previousIndicatorClientRect) {
this.foundation_.activate(previousIndicatorClientRect);
};
MDCTabIndicator.prototype.deactivate = function () {
this.foundation_.deactivate();
};
return MDCTabIndicator;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$o = {
ACTIVE: 'mdc-tab--active',
};
var strings$p = {
ARIA_SELECTED: 'aria-selected',
CONTENT_SELECTOR: '.mdc-tab__content',
INTERACTED_EVENT: 'MDCTab:interacted',
RIPPLE_SELECTOR: '.mdc-tab__ripple',
TABINDEX: 'tabIndex',
TAB_INDICATOR_SELECTOR: '.mdc-tab-indicator',
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTabFoundation = /** @class */ (function (_super) {
__extends(MDCTabFoundation, _super);
function MDCTabFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCTabFoundation.defaultAdapter, adapter)) || this;
_this.focusOnActivate_ = true;
return _this;
}
Object.defineProperty(MDCTabFoundation, "cssClasses", {
get: function () {
return cssClasses$o;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTabFoundation, "strings", {
get: function () {
return strings$p;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTabFoundation, "defaultAdapter", {
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
hasClass: function () { return false; },
setAttr: function () { return undefined; },
activateIndicator: function () { return undefined; },
deactivateIndicator: function () { return undefined; },
notifyInteracted: function () { return undefined; },
getOffsetLeft: function () { return 0; },
getOffsetWidth: function () { return 0; },
getContentOffsetLeft: function () { return 0; },
getContentOffsetWidth: function () { return 0; },
focus: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCTabFoundation.prototype.handleClick = function () {
// It's up to the parent component to keep track of the active Tab and
// ensure we don't activate a Tab that's already active.
this.adapter_.notifyInteracted();
};
MDCTabFoundation.prototype.isActive = function () {
return this.adapter_.hasClass(cssClasses$o.ACTIVE);
};
/**
* Sets whether the tab should focus itself when activated
*/
MDCTabFoundation.prototype.setFocusOnActivate = function (focusOnActivate) {
this.focusOnActivate_ = focusOnActivate;
};
/**
* Activates the Tab
*/
MDCTabFoundation.prototype.activate = function (previousIndicatorClientRect) {
this.adapter_.addClass(cssClasses$o.ACTIVE);
this.adapter_.setAttr(strings$p.ARIA_SELECTED, 'true');
this.adapter_.setAttr(strings$p.TABINDEX, '0');
this.adapter_.activateIndicator(previousIndicatorClientRect);
if (this.focusOnActivate_) {
this.adapter_.focus();
}
};
/**
* Deactivates the Tab
*/
MDCTabFoundation.prototype.deactivate = function () {
// Early exit
if (!this.isActive()) {
return;
}
this.adapter_.removeClass(cssClasses$o.ACTIVE);
this.adapter_.setAttr(strings$p.ARIA_SELECTED, 'false');
this.adapter_.setAttr(strings$p.TABINDEX, '-1');
this.adapter_.deactivateIndicator();
};
/**
* Returns the dimensions of the Tab
*/
MDCTabFoundation.prototype.computeDimensions = function () {
var rootWidth = this.adapter_.getOffsetWidth();
var rootLeft = this.adapter_.getOffsetLeft();
var contentWidth = this.adapter_.getContentOffsetWidth();
var contentLeft = this.adapter_.getContentOffsetLeft();
return {
contentLeft: rootLeft + contentLeft,
contentRight: rootLeft + contentLeft + contentWidth,
rootLeft: rootLeft,
rootRight: rootLeft + rootWidth,
};
};
return MDCTabFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTab = /** @class */ (function (_super) {
__extends(MDCTab, _super);
function MDCTab() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCTab.attachTo = function (root) {
return new MDCTab(root);
};
MDCTab.prototype.initialize = function (rippleFactory, tabIndicatorFactory) {
if (rippleFactory === void 0) { rippleFactory = function (el, foundation) { return new MDCRipple(el, foundation); }; }
if (tabIndicatorFactory === void 0) { tabIndicatorFactory = function (el) { return new MDCTabIndicator(el); }; }
this.id = this.root_.id;
var rippleSurface = this.root_.querySelector(MDCTabFoundation.strings.RIPPLE_SELECTOR);
var rippleAdapter = __assign({}, MDCRipple.createAdapter(this), { addClass: function (className) { return rippleSurface.classList.add(className); }, removeClass: function (className) { return rippleSurface.classList.remove(className); }, updateCssVariable: function (varName, value) { return rippleSurface.style.setProperty(varName, value); } });
var rippleFoundation = new MDCRippleFoundation(rippleAdapter);
this.ripple_ = rippleFactory(this.root_, rippleFoundation);
var tabIndicatorElement = this.root_.querySelector(MDCTabFoundation.strings.TAB_INDICATOR_SELECTOR);
this.tabIndicator_ = tabIndicatorFactory(tabIndicatorElement);
this.content_ = this.root_.querySelector(MDCTabFoundation.strings.CONTENT_SELECTOR);
};
MDCTab.prototype.initialSyncWithDOM = function () {
var _this = this;
this.handleClick_ = function () { return _this.foundation_.handleClick(); };
this.listen('click', this.handleClick_);
};
MDCTab.prototype.destroy = function () {
this.unlisten('click', this.handleClick_);
this.ripple_.destroy();
_super.prototype.destroy.call(this);
};
MDCTab.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
setAttr: function (attr, value) { return _this.root_.setAttribute(attr, value); },
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
hasClass: function (className) { return _this.root_.classList.contains(className); },
activateIndicator: function (previousIndicatorClientRect) { return _this.tabIndicator_.activate(previousIndicatorClientRect); },
deactivateIndicator: function () { return _this.tabIndicator_.deactivate(); },
notifyInteracted: function () { return _this.emit(MDCTabFoundation.strings.INTERACTED_EVENT, { tabId: _this.id }, true /* bubble */); },
getOffsetLeft: function () { return _this.root_.offsetLeft; },
getOffsetWidth: function () { return _this.root_.offsetWidth; },
getContentOffsetLeft: function () { return _this.content_.offsetLeft; },
getContentOffsetWidth: function () { return _this.content_.offsetWidth; },
focus: function () { return _this.root_.focus(); },
};
// tslint:enable:object-literal-sort-keys
return new MDCTabFoundation(adapter);
};
Object.defineProperty(MDCTab.prototype, "active", {
/**
* Getter for the active state of the tab
*/
get: function () {
return this.foundation_.isActive();
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTab.prototype, "focusOnActivate", {
set: function (focusOnActivate) {
this.foundation_.setFocusOnActivate(focusOnActivate);
},
enumerable: true,
configurable: true
});
/**
* Activates the tab
*/
MDCTab.prototype.activate = function (computeIndicatorClientRect) {
this.foundation_.activate(computeIndicatorClientRect);
};
/**
* Deactivates the tab
*/
MDCTab.prototype.deactivate = function () {
this.foundation_.deactivate();
};
/**
* Returns the indicator's client rect
*/
MDCTab.prototype.computeIndicatorClientRect = function () {
return this.tabIndicator_.computeContentClientRect();
};
MDCTab.prototype.computeDimensions = function () {
return this.foundation_.computeDimensions();
};
/**
* Focuses the tab
*/
MDCTab.prototype.focus = function () {
this.root_.focus();
};
return MDCTab;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var strings$q = {
ARROW_LEFT_KEY: 'ArrowLeft',
ARROW_RIGHT_KEY: 'ArrowRight',
END_KEY: 'End',
ENTER_KEY: 'Enter',
HOME_KEY: 'Home',
SPACE_KEY: 'Space',
TAB_ACTIVATED_EVENT: 'MDCTabBar:activated',
TAB_SCROLLER_SELECTOR: '.mdc-tab-scroller',
TAB_SELECTOR: '.mdc-tab',
};
var numbers$a = {
ARROW_LEFT_KEYCODE: 37,
ARROW_RIGHT_KEYCODE: 39,
END_KEYCODE: 35,
ENTER_KEYCODE: 13,
EXTRA_SCROLL_AMOUNT: 20,
HOME_KEYCODE: 36,
SPACE_KEYCODE: 32,
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var ACCEPTABLE_KEYS = new Set();
// IE11 has no support for new Set with iterable so we need to initialize this by hand
ACCEPTABLE_KEYS.add(strings$q.ARROW_LEFT_KEY);
ACCEPTABLE_KEYS.add(strings$q.ARROW_RIGHT_KEY);
ACCEPTABLE_KEYS.add(strings$q.END_KEY);
ACCEPTABLE_KEYS.add(strings$q.HOME_KEY);
ACCEPTABLE_KEYS.add(strings$q.ENTER_KEY);
ACCEPTABLE_KEYS.add(strings$q.SPACE_KEY);
var KEYCODE_MAP = new Map();
// IE11 has no support for new Map with iterable so we need to initialize this by hand
KEYCODE_MAP.set(numbers$a.ARROW_LEFT_KEYCODE, strings$q.ARROW_LEFT_KEY);
KEYCODE_MAP.set(numbers$a.ARROW_RIGHT_KEYCODE, strings$q.ARROW_RIGHT_KEY);
KEYCODE_MAP.set(numbers$a.END_KEYCODE, strings$q.END_KEY);
KEYCODE_MAP.set(numbers$a.HOME_KEYCODE, strings$q.HOME_KEY);
KEYCODE_MAP.set(numbers$a.ENTER_KEYCODE, strings$q.ENTER_KEY);
KEYCODE_MAP.set(numbers$a.SPACE_KEYCODE, strings$q.SPACE_KEY);
var MDCTabBarFoundation = /** @class */ (function (_super) {
__extends(MDCTabBarFoundation, _super);
function MDCTabBarFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCTabBarFoundation.defaultAdapter, adapter)) || this;
_this.useAutomaticActivation_ = false;
return _this;
}
Object.defineProperty(MDCTabBarFoundation, "strings", {
get: function () {
return strings$q;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTabBarFoundation, "numbers", {
get: function () {
return numbers$a;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTabBarFoundation, "defaultAdapter", {
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
scrollTo: function () { return undefined; },
incrementScroll: function () { return undefined; },
getScrollPosition: function () { return 0; },
getScrollContentWidth: function () { return 0; },
getOffsetWidth: function () { return 0; },
isRTL: function () { return false; },
setActiveTab: function () { return undefined; },
activateTabAtIndex: function () { return undefined; },
deactivateTabAtIndex: function () { return undefined; },
focusTabAtIndex: function () { return undefined; },
getTabIndicatorClientRectAtIndex: function () { return ({ top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 }); },
getTabDimensionsAtIndex: function () { return ({ rootLeft: 0, rootRight: 0, contentLeft: 0, contentRight: 0 }); },
getPreviousActiveTabIndex: function () { return -1; },
getFocusedTabIndex: function () { return -1; },
getIndexOfTabById: function () { return -1; },
getTabListLength: function () { return 0; },
notifyTabActivated: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
/**
* Switches between automatic and manual activation modes.
* See https://www.w3.org/TR/wai-aria-practices/#tabpanel for examples.
*/
MDCTabBarFoundation.prototype.setUseAutomaticActivation = function (useAutomaticActivation) {
this.useAutomaticActivation_ = useAutomaticActivation;
};
MDCTabBarFoundation.prototype.activateTab = function (index) {
var previousActiveIndex = this.adapter_.getPreviousActiveTabIndex();
if (!this.indexIsInRange_(index) || index === previousActiveIndex) {
return;
}
var previousClientRect;
if (previousActiveIndex !== -1) {
this.adapter_.deactivateTabAtIndex(previousActiveIndex);
previousClientRect = this.adapter_.getTabIndicatorClientRectAtIndex(previousActiveIndex);
}
this.adapter_.activateTabAtIndex(index, previousClientRect);
this.scrollIntoView(index);
this.adapter_.notifyTabActivated(index);
};
MDCTabBarFoundation.prototype.handleKeyDown = function (evt) {
// Get the key from the event
var key = this.getKeyFromEvent_(evt);
// Early exit if the event key isn't one of the keyboard navigation keys
if (key === undefined) {
return;
}
// Prevent default behavior for movement keys, but not for activation keys, since :active is used to apply ripple
if (!this.isActivationKey_(key)) {
evt.preventDefault();
}
if (this.useAutomaticActivation_) {
if (this.isActivationKey_(key)) {
return;
}
var index = this.determineTargetFromKey_(this.adapter_.getPreviousActiveTabIndex(), key);
this.adapter_.setActiveTab(index);
this.scrollIntoView(index);
}
else {
var focusedTabIndex = this.adapter_.getFocusedTabIndex();
if (this.isActivationKey_(key)) {
this.adapter_.setActiveTab(focusedTabIndex);
}
else {
var index = this.determineTargetFromKey_(focusedTabIndex, key);
this.adapter_.focusTabAtIndex(index);
this.scrollIntoView(index);
}
}
};
/**
* Handles the MDCTab:interacted event
*/
MDCTabBarFoundation.prototype.handleTabInteraction = function (evt) {
this.adapter_.setActiveTab(this.adapter_.getIndexOfTabById(evt.detail.tabId));
};
/**
* Scrolls the tab at the given index into view
* @param index The tab index to make visible
*/
MDCTabBarFoundation.prototype.scrollIntoView = function (index) {
// Early exit if the index is out of range
if (!this.indexIsInRange_(index)) {
return;
}
// Always scroll to 0 if scrolling to the 0th index
if (index === 0) {
return this.adapter_.scrollTo(0);
}
// Always scroll to the max value if scrolling to the Nth index
// MDCTabScroller.scrollTo() will never scroll past the max possible value
if (index === this.adapter_.getTabListLength() - 1) {
return this.adapter_.scrollTo(this.adapter_.getScrollContentWidth());
}
if (this.isRTL_()) {
return this.scrollIntoViewRTL_(index);
}
this.scrollIntoView_(index);
};
/**
* Private method for determining the index of the destination tab based on what key was pressed
* @param origin The original index from which to determine the destination
* @param key The name of the key
*/
MDCTabBarFoundation.prototype.determineTargetFromKey_ = function (origin, key) {
var isRTL = this.isRTL_();
var maxIndex = this.adapter_.getTabListLength() - 1;
var shouldGoToEnd = key === strings$q.END_KEY;
var shouldDecrement = key === strings$q.ARROW_LEFT_KEY && !isRTL || key === strings$q.ARROW_RIGHT_KEY && isRTL;
var shouldIncrement = key === strings$q.ARROW_RIGHT_KEY && !isRTL || key === strings$q.ARROW_LEFT_KEY && isRTL;
var index = origin;
if (shouldGoToEnd) {
index = maxIndex;
}
else if (shouldDecrement) {
index -= 1;
}
else if (shouldIncrement) {
index += 1;
}
else {
index = 0;
}
if (index < 0) {
index = maxIndex;
}
else if (index > maxIndex) {
index = 0;
}
return index;
};
/**
* Calculates the scroll increment that will make the tab at the given index visible
* @param index The index of the tab
* @param nextIndex The index of the next tab
* @param scrollPosition The current scroll position
* @param barWidth The width of the Tab Bar
*/
MDCTabBarFoundation.prototype.calculateScrollIncrement_ = function (index, nextIndex, scrollPosition, barWidth) {
var nextTabDimensions = this.adapter_.getTabDimensionsAtIndex(nextIndex);
var relativeContentLeft = nextTabDimensions.contentLeft - scrollPosition - barWidth;
var relativeContentRight = nextTabDimensions.contentRight - scrollPosition;
var leftIncrement = relativeContentRight - numbers$a.EXTRA_SCROLL_AMOUNT;
var rightIncrement = relativeContentLeft + numbers$a.EXTRA_SCROLL_AMOUNT;
if (nextIndex < index) {
return Math.min(leftIncrement, 0);
}
return Math.max(rightIncrement, 0);
};
/**
* Calculates the scroll increment that will make the tab at the given index visible in RTL
* @param index The index of the tab
* @param nextIndex The index of the next tab
* @param scrollPosition The current scroll position
* @param barWidth The width of the Tab Bar
* @param scrollContentWidth The width of the scroll content
*/
MDCTabBarFoundation.prototype.calculateScrollIncrementRTL_ = function (index, nextIndex, scrollPosition, barWidth, scrollContentWidth) {
var nextTabDimensions = this.adapter_.getTabDimensionsAtIndex(nextIndex);
var relativeContentLeft = scrollContentWidth - nextTabDimensions.contentLeft - scrollPosition;
var relativeContentRight = scrollContentWidth - nextTabDimensions.contentRight - scrollPosition - barWidth;
var leftIncrement = relativeContentRight + numbers$a.EXTRA_SCROLL_AMOUNT;
var rightIncrement = relativeContentLeft - numbers$a.EXTRA_SCROLL_AMOUNT;
if (nextIndex > index) {
return Math.max(leftIncrement, 0);
}
return Math.min(rightIncrement, 0);
};
/**
* Determines the index of the adjacent tab closest to either edge of the Tab Bar
* @param index The index of the tab
* @param tabDimensions The dimensions of the tab
* @param scrollPosition The current scroll position
* @param barWidth The width of the tab bar
*/
MDCTabBarFoundation.prototype.findAdjacentTabIndexClosestToEdge_ = function (index, tabDimensions, scrollPosition, barWidth) {
/**
* Tabs are laid out in the Tab Scroller like this:
*
* Scroll Position
* +---+
* | | Bar Width
* | +-----------------------------------+
* | | |
* | V V
* | +-----------------------------------+
* V | Tab Scroller |
* +------------+--------------+-------------------+
* | Tab | Tab | Tab |
* +------------+--------------+-------------------+
* | |
* +-----------------------------------+
*
* To determine the next adjacent index, we look at the Tab root left and
* Tab root right, both relative to the scroll position. If the Tab root
* left is less than 0, then we know it's out of view to the left. If the
* Tab root right minus the bar width is greater than 0, we know the Tab is
* out of view to the right. From there, we either increment or decrement
* the index.
*/
var relativeRootLeft = tabDimensions.rootLeft - scrollPosition;
var relativeRootRight = tabDimensions.rootRight - scrollPosition - barWidth;
var relativeRootDelta = relativeRootLeft + relativeRootRight;
var leftEdgeIsCloser = relativeRootLeft < 0 || relativeRootDelta < 0;
var rightEdgeIsCloser = relativeRootRight > 0 || relativeRootDelta > 0;
if (leftEdgeIsCloser) {
return index - 1;
}
if (rightEdgeIsCloser) {
return index + 1;
}
return -1;
};
/**
* Determines the index of the adjacent tab closest to either edge of the Tab Bar in RTL
* @param index The index of the tab
* @param tabDimensions The dimensions of the tab
* @param scrollPosition The current scroll position
* @param barWidth The width of the tab bar
* @param scrollContentWidth The width of the scroller content
*/
MDCTabBarFoundation.prototype.findAdjacentTabIndexClosestToEdgeRTL_ = function (index, tabDimensions, scrollPosition, barWidth, scrollContentWidth) {
var rootLeft = scrollContentWidth - tabDimensions.rootLeft - barWidth - scrollPosition;
var rootRight = scrollContentWidth - tabDimensions.rootRight - scrollPosition;
var rootDelta = rootLeft + rootRight;
var leftEdgeIsCloser = rootLeft > 0 || rootDelta > 0;
var rightEdgeIsCloser = rootRight < 0 || rootDelta < 0;
if (leftEdgeIsCloser) {
return index + 1;
}
if (rightEdgeIsCloser) {
return index - 1;
}
return -1;
};
/**
* Returns the key associated with a keydown event
* @param evt The keydown event
*/
MDCTabBarFoundation.prototype.getKeyFromEvent_ = function (evt) {
if (ACCEPTABLE_KEYS.has(evt.key)) {
return evt.key;
}
return KEYCODE_MAP.get(evt.keyCode);
};
MDCTabBarFoundation.prototype.isActivationKey_ = function (key) {
return key === strings$q.SPACE_KEY || key === strings$q.ENTER_KEY;
};
/**
* Returns whether a given index is inclusively between the ends
* @param index The index to test
*/
MDCTabBarFoundation.prototype.indexIsInRange_ = function (index) {
return index >= 0 && index < this.adapter_.getTabListLength();
};
/**
* Returns the view's RTL property
*/
MDCTabBarFoundation.prototype.isRTL_ = function () {
return this.adapter_.isRTL();
};
/**
* Scrolls the tab at the given index into view for left-to-right user agents.
* @param index The index of the tab to scroll into view
*/
MDCTabBarFoundation.prototype.scrollIntoView_ = function (index) {
var scrollPosition = this.adapter_.getScrollPosition();
var barWidth = this.adapter_.getOffsetWidth();
var tabDimensions = this.adapter_.getTabDimensionsAtIndex(index);
var nextIndex = this.findAdjacentTabIndexClosestToEdge_(index, tabDimensions, scrollPosition, barWidth);
if (!this.indexIsInRange_(nextIndex)) {
return;
}
var scrollIncrement = this.calculateScrollIncrement_(index, nextIndex, scrollPosition, barWidth);
this.adapter_.incrementScroll(scrollIncrement);
};
/**
* Scrolls the tab at the given index into view in RTL
* @param index The tab index to make visible
*/
MDCTabBarFoundation.prototype.scrollIntoViewRTL_ = function (index) {
var scrollPosition = this.adapter_.getScrollPosition();
var barWidth = this.adapter_.getOffsetWidth();
var tabDimensions = this.adapter_.getTabDimensionsAtIndex(index);
var scrollWidth = this.adapter_.getScrollContentWidth();
var nextIndex = this.findAdjacentTabIndexClosestToEdgeRTL_(index, tabDimensions, scrollPosition, barWidth, scrollWidth);
if (!this.indexIsInRange_(nextIndex)) {
return;
}
var scrollIncrement = this.calculateScrollIncrementRTL_(index, nextIndex, scrollPosition, barWidth, scrollWidth);
this.adapter_.incrementScroll(scrollIncrement);
};
return MDCTabBarFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var strings$r = MDCTabBarFoundation.strings;
var tabIdCounter = 0;
var MDCTabBar = /** @class */ (function (_super) {
__extends(MDCTabBar, _super);
function MDCTabBar() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCTabBar.attachTo = function (root) {
return new MDCTabBar(root);
};
Object.defineProperty(MDCTabBar.prototype, "focusOnActivate", {
set: function (focusOnActivate) {
this.tabList_.forEach(function (tab) { return tab.focusOnActivate = focusOnActivate; });
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTabBar.prototype, "useAutomaticActivation", {
set: function (useAutomaticActivation) {
this.foundation_.setUseAutomaticActivation(useAutomaticActivation);
},
enumerable: true,
configurable: true
});
MDCTabBar.prototype.initialize = function (tabFactory, tabScrollerFactory) {
if (tabFactory === void 0) { tabFactory = function (el) { return new MDCTab(el); }; }
if (tabScrollerFactory === void 0) { tabScrollerFactory = function (el) { return new MDCTabScroller(el); }; }
this.tabList_ = this.instantiateTabs_(tabFactory);
this.tabScroller_ = this.instantiateTabScroller_(tabScrollerFactory);
};
MDCTabBar.prototype.initialSyncWithDOM = function () {
var _this = this;
this.handleTabInteraction_ = function (evt) { return _this.foundation_.handleTabInteraction(evt); };
this.handleKeyDown_ = function (evt) { return _this.foundation_.handleKeyDown(evt); };
this.listen(MDCTabFoundation.strings.INTERACTED_EVENT, this.handleTabInteraction_);
this.listen('keydown', this.handleKeyDown_);
for (var i = 0; i < this.tabList_.length; i++) {
if (this.tabList_[i].active) {
this.scrollIntoView(i);
break;
}
}
};
MDCTabBar.prototype.destroy = function () {
_super.prototype.destroy.call(this);
this.unlisten(MDCTabFoundation.strings.INTERACTED_EVENT, this.handleTabInteraction_);
this.unlisten('keydown', this.handleKeyDown_);
this.tabList_.forEach(function (tab) { return tab.destroy(); });
if (this.tabScroller_) {
this.tabScroller_.destroy();
}
};
MDCTabBar.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
scrollTo: function (scrollX) { return _this.tabScroller_.scrollTo(scrollX); },
incrementScroll: function (scrollXIncrement) { return _this.tabScroller_.incrementScroll(scrollXIncrement); },
getScrollPosition: function () { return _this.tabScroller_.getScrollPosition(); },
getScrollContentWidth: function () { return _this.tabScroller_.getScrollContentWidth(); },
getOffsetWidth: function () { return _this.root_.offsetWidth; },
isRTL: function () { return window.getComputedStyle(_this.root_).getPropertyValue('direction') === 'rtl'; },
setActiveTab: function (index) { return _this.foundation_.activateTab(index); },
activateTabAtIndex: function (index, clientRect) { return _this.tabList_[index].activate(clientRect); },
deactivateTabAtIndex: function (index) { return _this.tabList_[index].deactivate(); },
focusTabAtIndex: function (index) { return _this.tabList_[index].focus(); },
getTabIndicatorClientRectAtIndex: function (index) { return _this.tabList_[index].computeIndicatorClientRect(); },
getTabDimensionsAtIndex: function (index) { return _this.tabList_[index].computeDimensions(); },
getPreviousActiveTabIndex: function () {
for (var i = 0; i < _this.tabList_.length; i++) {
if (_this.tabList_[i].active) {
return i;
}
}
return -1;
},
getFocusedTabIndex: function () {
var tabElements = _this.getTabElements_();
var activeElement = document.activeElement;
return tabElements.indexOf(activeElement);
},
getIndexOfTabById: function (id) {
for (var i = 0; i < _this.tabList_.length; i++) {
if (_this.tabList_[i].id === id) {
return i;
}
}
return -1;
},
getTabListLength: function () { return _this.tabList_.length; },
notifyTabActivated: function (index) {
return _this.emit(strings$r.TAB_ACTIVATED_EVENT, { index: index }, true);
},
};
// tslint:enable:object-literal-sort-keys
return new MDCTabBarFoundation(adapter);
};
/**
* Activates the tab at the given index
* @param index The index of the tab
*/
MDCTabBar.prototype.activateTab = function (index) {
this.foundation_.activateTab(index);
};
/**
* Scrolls the tab at the given index into view
* @param index THe index of the tab
*/
MDCTabBar.prototype.scrollIntoView = function (index) {
this.foundation_.scrollIntoView(index);
};
/**
* Returns all the tab elements in a nice clean array
*/
MDCTabBar.prototype.getTabElements_ = function () {
return [].slice.call(this.root_.querySelectorAll(strings$r.TAB_SELECTOR));
};
/**
* Instantiates tab components on all child tab elements
*/
MDCTabBar.prototype.instantiateTabs_ = function (tabFactory) {
return this.getTabElements_().map(function (el) {
el.id = el.id || "mdc-tab-" + ++tabIdCounter;
return tabFactory(el);
});
};
/**
* Instantiates tab scroller component on the child tab scroller element
*/
MDCTabBar.prototype.instantiateTabScroller_ = function (tabScrollerFactory) {
var tabScrollerElement = this.root_.querySelector(strings$r.TAB_SCROLLER_SELECTOR);
if (tabScrollerElement) {
return tabScrollerFactory(tabScrollerElement);
}
return null;
};
return MDCTabBar;
}(MDCComponent));
/**
* @license
* Copyright 2019 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$p = {
ROOT: 'mdc-text-field-character-counter',
};
var strings$s = {
ROOT_SELECTOR: "." + cssClasses$p.ROOT,
};
/**
* @license
* Copyright 2019 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTextFieldCharacterCounterFoundation = /** @class */ (function (_super) {
__extends(MDCTextFieldCharacterCounterFoundation, _super);
function MDCTextFieldCharacterCounterFoundation(adapter) {
return _super.call(this, __assign({}, MDCTextFieldCharacterCounterFoundation.defaultAdapter, adapter)) || this;
}
Object.defineProperty(MDCTextFieldCharacterCounterFoundation, "cssClasses", {
get: function () {
return cssClasses$p;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextFieldCharacterCounterFoundation, "strings", {
get: function () {
return strings$s;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextFieldCharacterCounterFoundation, "defaultAdapter", {
/**
* See {@link MDCTextFieldCharacterCounterAdapter} for typing information on parameters and return types.
*/
get: function () {
return {
setContent: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCTextFieldCharacterCounterFoundation.prototype.setCounterValue = function (currentLength, maxLength) {
currentLength = Math.min(currentLength, maxLength);
this.adapter_.setContent(currentLength + " / " + maxLength);
};
return MDCTextFieldCharacterCounterFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2019 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTextFieldCharacterCounter = /** @class */ (function (_super) {
__extends(MDCTextFieldCharacterCounter, _super);
function MDCTextFieldCharacterCounter() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCTextFieldCharacterCounter.attachTo = function (root) {
return new MDCTextFieldCharacterCounter(root);
};
Object.defineProperty(MDCTextFieldCharacterCounter.prototype, "foundation", {
get: function () {
return this.foundation_;
},
enumerable: true,
configurable: true
});
MDCTextFieldCharacterCounter.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
var adapter = {
setContent: function (content) {
_this.root_.textContent = content;
},
};
return new MDCTextFieldCharacterCounterFoundation(adapter);
};
return MDCTextFieldCharacterCounter;
}(MDCComponent));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var strings$t = {
ARIA_CONTROLS: 'aria-controls',
ICON_SELECTOR: '.mdc-text-field__icon',
INPUT_SELECTOR: '.mdc-text-field__input',
LABEL_SELECTOR: '.mdc-floating-label',
LINE_RIPPLE_SELECTOR: '.mdc-line-ripple',
OUTLINE_SELECTOR: '.mdc-notched-outline',
};
var cssClasses$q = {
DENSE: 'mdc-text-field--dense',
DISABLED: 'mdc-text-field--disabled',
FOCUSED: 'mdc-text-field--focused',
FULLWIDTH: 'mdc-text-field--fullwidth',
HELPER_LINE: 'mdc-text-field-helper-line',
INVALID: 'mdc-text-field--invalid',
NO_LABEL: 'mdc-text-field--no-label',
OUTLINED: 'mdc-text-field--outlined',
ROOT: 'mdc-text-field',
TEXTAREA: 'mdc-text-field--textarea',
WITH_LEADING_ICON: 'mdc-text-field--with-leading-icon',
WITH_TRAILING_ICON: 'mdc-text-field--with-trailing-icon',
};
var numbers$b = {
DENSE_LABEL_SCALE: 0.923,
LABEL_SCALE: 0.75,
};
/**
* Whitelist based off of https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation
* under the "Validation-related attributes" section.
*/
var VALIDATION_ATTR_WHITELIST$1 = [
'pattern', 'min', 'max', 'required', 'step', 'minlength', 'maxlength',
];
/**
* Label should always float for these types as they show some UI even if value is empty.
*/
var ALWAYS_FLOAT_TYPES = [
'color', 'date', 'datetime-local', 'month', 'range', 'time', 'week',
];
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var POINTERDOWN_EVENTS = ['mousedown', 'touchstart'];
var INTERACTION_EVENTS$2 = ['click', 'keydown'];
var MDCTextFieldFoundation = /** @class */ (function (_super) {
__extends(MDCTextFieldFoundation, _super);
/**
* @param adapter
* @param foundationMap Map from subcomponent names to their subfoundations.
*/
function MDCTextFieldFoundation(adapter, foundationMap) {
if (foundationMap === void 0) { foundationMap = {}; }
var _this = _super.call(this, __assign({}, MDCTextFieldFoundation.defaultAdapter, adapter)) || this;
_this.isFocused_ = false;
_this.receivedUserInput_ = false;
_this.isValid_ = true;
_this.useNativeValidation_ = true;
_this.helperText_ = foundationMap.helperText;
_this.characterCounter_ = foundationMap.characterCounter;
_this.leadingIcon_ = foundationMap.leadingIcon;
_this.trailingIcon_ = foundationMap.trailingIcon;
_this.inputFocusHandler_ = function () { return _this.activateFocus(); };
_this.inputBlurHandler_ = function () { return _this.deactivateFocus(); };
_this.inputInputHandler_ = function () { return _this.handleInput(); };
_this.setPointerXOffset_ = function (evt) { return _this.setTransformOrigin(evt); };
_this.textFieldInteractionHandler_ = function () { return _this.handleTextFieldInteraction(); };
_this.validationAttributeChangeHandler_ = function (attributesList) { return _this.handleValidationAttributeChange(attributesList); };
return _this;
}
Object.defineProperty(MDCTextFieldFoundation, "cssClasses", {
get: function () {
return cssClasses$q;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextFieldFoundation, "strings", {
get: function () {
return strings$t;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextFieldFoundation, "numbers", {
get: function () {
return numbers$b;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextFieldFoundation.prototype, "shouldAlwaysFloat_", {
get: function () {
var type = this.getNativeInput_().type;
return ALWAYS_FLOAT_TYPES.indexOf(type) >= 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextFieldFoundation.prototype, "shouldFloat", {
get: function () {
return this.shouldAlwaysFloat_ || this.isFocused_ || Boolean(this.getValue()) || this.isBadInput_();
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextFieldFoundation.prototype, "shouldShake", {
get: function () {
return !this.isFocused_ && !this.isValid() && Boolean(this.getValue());
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextFieldFoundation, "defaultAdapter", {
/**
* See {@link MDCTextFieldAdapter} for typing information on parameters and return types.
*/
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
hasClass: function () { return true; },
registerTextFieldInteractionHandler: function () { return undefined; },
deregisterTextFieldInteractionHandler: function () { return undefined; },
registerInputInteractionHandler: function () { return undefined; },
deregisterInputInteractionHandler: function () { return undefined; },
registerValidationAttributeChangeHandler: function () { return new MutationObserver(function () { return undefined; }); },
deregisterValidationAttributeChangeHandler: function () { return undefined; },
getNativeInput: function () { return null; },
isFocused: function () { return false; },
activateLineRipple: function () { return undefined; },
deactivateLineRipple: function () { return undefined; },
setLineRippleTransformOrigin: function () { return undefined; },
shakeLabel: function () { return undefined; },
floatLabel: function () { return undefined; },
hasLabel: function () { return false; },
getLabelWidth: function () { return 0; },
hasOutline: function () { return false; },
notchOutline: function () { return undefined; },
closeOutline: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCTextFieldFoundation.prototype.init = function () {
var _this = this;
if (this.adapter_.isFocused()) {
this.inputFocusHandler_();
}
else if (this.adapter_.hasLabel() && this.shouldFloat) {
this.notchOutline(true);
this.adapter_.floatLabel(true);
}
this.adapter_.registerInputInteractionHandler('focus', this.inputFocusHandler_);
this.adapter_.registerInputInteractionHandler('blur', this.inputBlurHandler_);
this.adapter_.registerInputInteractionHandler('input', this.inputInputHandler_);
POINTERDOWN_EVENTS.forEach(function (evtType) {
_this.adapter_.registerInputInteractionHandler(evtType, _this.setPointerXOffset_);
});
INTERACTION_EVENTS$2.forEach(function (evtType) {
_this.adapter_.registerTextFieldInteractionHandler(evtType, _this.textFieldInteractionHandler_);
});
this.validationObserver_ =
this.adapter_.registerValidationAttributeChangeHandler(this.validationAttributeChangeHandler_);
this.setCharacterCounter_(this.getValue().length);
};
MDCTextFieldFoundation.prototype.destroy = function () {
var _this = this;
this.adapter_.deregisterInputInteractionHandler('focus', this.inputFocusHandler_);
this.adapter_.deregisterInputInteractionHandler('blur', this.inputBlurHandler_);
this.adapter_.deregisterInputInteractionHandler('input', this.inputInputHandler_);
POINTERDOWN_EVENTS.forEach(function (evtType) {
_this.adapter_.deregisterInputInteractionHandler(evtType, _this.setPointerXOffset_);
});
INTERACTION_EVENTS$2.forEach(function (evtType) {
_this.adapter_.deregisterTextFieldInteractionHandler(evtType, _this.textFieldInteractionHandler_);
});
this.adapter_.deregisterValidationAttributeChangeHandler(this.validationObserver_);
};
/**
* Handles user interactions with the Text Field.
*/
MDCTextFieldFoundation.prototype.handleTextFieldInteraction = function () {
var nativeInput = this.adapter_.getNativeInput();
if (nativeInput && nativeInput.disabled) {
return;
}
this.receivedUserInput_ = true;
};
/**
* Handles validation attribute changes
*/
MDCTextFieldFoundation.prototype.handleValidationAttributeChange = function (attributesList) {
var _this = this;
attributesList.some(function (attributeName) {
if (VALIDATION_ATTR_WHITELIST$1.indexOf(attributeName) > -1) {
_this.styleValidity_(true);
return true;
}
return false;
});
if (attributesList.indexOf('maxlength') > -1) {
this.setCharacterCounter_(this.getValue().length);
}
};
/**
* Opens/closes the notched outline.
*/
MDCTextFieldFoundation.prototype.notchOutline = function (openNotch) {
if (!this.adapter_.hasOutline()) {
return;
}
if (openNotch) {
var isDense = this.adapter_.hasClass(cssClasses$q.DENSE);
var labelScale = isDense ? numbers$b.DENSE_LABEL_SCALE : numbers$b.LABEL_SCALE;
var labelWidth = this.adapter_.getLabelWidth() * labelScale;
this.adapter_.notchOutline(labelWidth);
}
else {
this.adapter_.closeOutline();
}
};
/**
* Activates the text field focus state.
*/
MDCTextFieldFoundation.prototype.activateFocus = function () {
this.isFocused_ = true;
this.styleFocused_(this.isFocused_);
this.adapter_.activateLineRipple();
if (this.adapter_.hasLabel()) {
this.notchOutline(this.shouldFloat);
this.adapter_.floatLabel(this.shouldFloat);
this.adapter_.shakeLabel(this.shouldShake);
}
if (this.helperText_) {
this.helperText_.showToScreenReader();
}
};
/**
* Sets the line ripple's transform origin, so that the line ripple activate
* animation will animate out from the user's click location.
*/
MDCTextFieldFoundation.prototype.setTransformOrigin = function (evt) {
var touches = evt.touches;
var targetEvent = touches ? touches[0] : evt;
var targetClientRect = targetEvent.target.getBoundingClientRect();
var normalizedX = targetEvent.clientX - targetClientRect.left;
this.adapter_.setLineRippleTransformOrigin(normalizedX);
};
/**
* Handles input change of text input and text area.
*/
MDCTextFieldFoundation.prototype.handleInput = function () {
this.autoCompleteFocus();
this.setCharacterCounter_(this.getValue().length);
};
/**
* Activates the Text Field's focus state in cases when the input value
* changes without user input (e.g. programmatically).
*/
MDCTextFieldFoundation.prototype.autoCompleteFocus = function () {
if (!this.receivedUserInput_) {
this.activateFocus();
}
};
/**
* Deactivates the Text Field's focus state.
*/
MDCTextFieldFoundation.prototype.deactivateFocus = function () {
this.isFocused_ = false;
this.adapter_.deactivateLineRipple();
var isValid = this.isValid();
this.styleValidity_(isValid);
this.styleFocused_(this.isFocused_);
if (this.adapter_.hasLabel()) {
this.notchOutline(this.shouldFloat);
this.adapter_.floatLabel(this.shouldFloat);
this.adapter_.shakeLabel(this.shouldShake);
}
if (!this.shouldFloat) {
this.receivedUserInput_ = false;
}
};
MDCTextFieldFoundation.prototype.getValue = function () {
return this.getNativeInput_().value;
};
/**
* @param value The value to set on the input Element.
*/
MDCTextFieldFoundation.prototype.setValue = function (value) {
// Prevent Safari from moving the caret to the end of the input when the value has not changed.
if (this.getValue() !== value) {
this.getNativeInput_().value = value;
}
this.setCharacterCounter_(value.length);
var isValid = this.isValid();
this.styleValidity_(isValid);
if (this.adapter_.hasLabel()) {
this.notchOutline(this.shouldFloat);
this.adapter_.floatLabel(this.shouldFloat);
this.adapter_.shakeLabel(this.shouldShake);
}
};
/**
* @return The custom validity state, if set; otherwise, the result of a native validity check.
*/
MDCTextFieldFoundation.prototype.isValid = function () {
return this.useNativeValidation_
? this.isNativeInputValid_() : this.isValid_;
};
/**
* @param isValid Sets the custom validity state of the Text Field.
*/
MDCTextFieldFoundation.prototype.setValid = function (isValid) {
this.isValid_ = isValid;
this.styleValidity_(isValid);
var shouldShake = !isValid && !this.isFocused_;
if (this.adapter_.hasLabel()) {
this.adapter_.shakeLabel(shouldShake);
}
};
/**
* Enables or disables the use of native validation. Use this for custom validation.
* @param useNativeValidation Set this to false to ignore native input validation.
*/
MDCTextFieldFoundation.prototype.setUseNativeValidation = function (useNativeValidation) {
this.useNativeValidation_ = useNativeValidation;
};
MDCTextFieldFoundation.prototype.isDisabled = function () {
return this.getNativeInput_().disabled;
};
/**
* @param disabled Sets the text-field disabled or enabled.
*/
MDCTextFieldFoundation.prototype.setDisabled = function (disabled) {
this.getNativeInput_().disabled = disabled;
this.styleDisabled_(disabled);
};
/**
* @param content Sets the content of the helper text.
*/
MDCTextFieldFoundation.prototype.setHelperTextContent = function (content) {
if (this.helperText_) {
this.helperText_.setContent(content);
}
};
/**
* Sets the aria label of the leading icon.
*/
MDCTextFieldFoundation.prototype.setLeadingIconAriaLabel = function (label) {
if (this.leadingIcon_) {
this.leadingIcon_.setAriaLabel(label);
}
};
/**
* Sets the text content of the leading icon.
*/
MDCTextFieldFoundation.prototype.setLeadingIconContent = function (content) {
if (this.leadingIcon_) {
this.leadingIcon_.setContent(content);
}
};
/**
* Sets the aria label of the trailing icon.
*/
MDCTextFieldFoundation.prototype.setTrailingIconAriaLabel = function (label) {
if (this.trailingIcon_) {
this.trailingIcon_.setAriaLabel(label);
}
};
/**
* Sets the text content of the trailing icon.
*/
MDCTextFieldFoundation.prototype.setTrailingIconContent = function (content) {
if (this.trailingIcon_) {
this.trailingIcon_.setContent(content);
}
};
/**
* Sets character counter values that shows characters used and the total character limit.
*/
MDCTextFieldFoundation.prototype.setCharacterCounter_ = function (currentLength) {
if (!this.characterCounter_) {
return;
}
var maxLength = this.getNativeInput_().maxLength;
if (maxLength === -1) {
throw new Error('MDCTextFieldFoundation: Expected maxlength html property on text input or textarea.');
}
this.characterCounter_.setCounterValue(currentLength, maxLength);
};
/**
* @return True if the Text Field input fails in converting the user-supplied value.
*/
MDCTextFieldFoundation.prototype.isBadInput_ = function () {
// The badInput property is not supported in IE 11 💩.
return this.getNativeInput_().validity.badInput || false;
};
/**
* @return The result of native validity checking (ValidityState.valid).
*/
MDCTextFieldFoundation.prototype.isNativeInputValid_ = function () {
return this.getNativeInput_().validity.valid;
};
/**
* Styles the component based on the validity state.
*/
MDCTextFieldFoundation.prototype.styleValidity_ = function (isValid) {
var INVALID = MDCTextFieldFoundation.cssClasses.INVALID;
if (isValid) {
this.adapter_.removeClass(INVALID);
}
else {
this.adapter_.addClass(INVALID);
}
if (this.helperText_) {
this.helperText_.setValidity(isValid);
}
};
/**
* Styles the component based on the focused state.
*/
MDCTextFieldFoundation.prototype.styleFocused_ = function (isFocused) {
var FOCUSED = MDCTextFieldFoundation.cssClasses.FOCUSED;
if (isFocused) {
this.adapter_.addClass(FOCUSED);
}
else {
this.adapter_.removeClass(FOCUSED);
}
};
/**
* Styles the component based on the disabled state.
*/
MDCTextFieldFoundation.prototype.styleDisabled_ = function (isDisabled) {
var _a = MDCTextFieldFoundation.cssClasses, DISABLED = _a.DISABLED, INVALID = _a.INVALID;
if (isDisabled) {
this.adapter_.addClass(DISABLED);
this.adapter_.removeClass(INVALID);
}
else {
this.adapter_.removeClass(DISABLED);
}
if (this.leadingIcon_) {
this.leadingIcon_.setDisabled(isDisabled);
}
if (this.trailingIcon_) {
this.trailingIcon_.setDisabled(isDisabled);
}
};
/**
* @return The native text input element from the host environment, or an object with the same shape for unit tests.
*/
MDCTextFieldFoundation.prototype.getNativeInput_ = function () {
// this.adapter_ may be undefined in foundation unit tests. This happens when testdouble is creating a mock object
// and invokes the shouldShake/shouldFloat getters (which in turn call getValue(), which calls this method) before
// init() has been called from the MDCTextField constructor. To work around that issue, we return a dummy object.
var nativeInput = this.adapter_ ? this.adapter_.getNativeInput() : null;
return nativeInput || {
disabled: false,
maxLength: -1,
type: 'input',
validity: {
badInput: false,
valid: true,
},
value: '',
};
};
return MDCTextFieldFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$r = {
HELPER_TEXT_PERSISTENT: 'mdc-text-field-helper-text--persistent',
HELPER_TEXT_VALIDATION_MSG: 'mdc-text-field-helper-text--validation-msg',
ROOT: 'mdc-text-field-helper-text',
};
var strings$u = {
ARIA_HIDDEN: 'aria-hidden',
ROLE: 'role',
ROOT_SELECTOR: "." + cssClasses$r.ROOT,
};
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTextFieldHelperTextFoundation = /** @class */ (function (_super) {
__extends(MDCTextFieldHelperTextFoundation, _super);
function MDCTextFieldHelperTextFoundation(adapter) {
return _super.call(this, __assign({}, MDCTextFieldHelperTextFoundation.defaultAdapter, adapter)) || this;
}
Object.defineProperty(MDCTextFieldHelperTextFoundation, "cssClasses", {
get: function () {
return cssClasses$r;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextFieldHelperTextFoundation, "strings", {
get: function () {
return strings$u;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextFieldHelperTextFoundation, "defaultAdapter", {
/**
* See {@link MDCTextFieldHelperTextAdapter} for typing information on parameters and return types.
*/
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
hasClass: function () { return false; },
setAttr: function () { return undefined; },
removeAttr: function () { return undefined; },
setContent: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
/**
* Sets the content of the helper text field.
*/
MDCTextFieldHelperTextFoundation.prototype.setContent = function (content) {
this.adapter_.setContent(content);
};
/**
* @param isPersistent Sets the persistency of the helper text.
*/
MDCTextFieldHelperTextFoundation.prototype.setPersistent = function (isPersistent) {
if (isPersistent) {
this.adapter_.addClass(cssClasses$r.HELPER_TEXT_PERSISTENT);
}
else {
this.adapter_.removeClass(cssClasses$r.HELPER_TEXT_PERSISTENT);
}
};
/**
* @param isValidation True to make the helper text act as an error validation message.
*/
MDCTextFieldHelperTextFoundation.prototype.setValidation = function (isValidation) {
if (isValidation) {
this.adapter_.addClass(cssClasses$r.HELPER_TEXT_VALIDATION_MSG);
}
else {
this.adapter_.removeClass(cssClasses$r.HELPER_TEXT_VALIDATION_MSG);
}
};
/**
* Makes the helper text visible to the screen reader.
*/
MDCTextFieldHelperTextFoundation.prototype.showToScreenReader = function () {
this.adapter_.removeAttr(strings$u.ARIA_HIDDEN);
};
/**
* Sets the validity of the helper text based on the input validity.
*/
MDCTextFieldHelperTextFoundation.prototype.setValidity = function (inputIsValid) {
var helperTextIsPersistent = this.adapter_.hasClass(cssClasses$r.HELPER_TEXT_PERSISTENT);
var helperTextIsValidationMsg = this.adapter_.hasClass(cssClasses$r.HELPER_TEXT_VALIDATION_MSG);
var validationMsgNeedsDisplay = helperTextIsValidationMsg && !inputIsValid;
if (validationMsgNeedsDisplay) {
this.adapter_.setAttr(strings$u.ROLE, 'alert');
}
else {
this.adapter_.removeAttr(strings$u.ROLE);
}
if (!helperTextIsPersistent && !validationMsgNeedsDisplay) {
this.hide_();
}
};
/**
* Hides the help text from screen readers.
*/
MDCTextFieldHelperTextFoundation.prototype.hide_ = function () {
this.adapter_.setAttr(strings$u.ARIA_HIDDEN, 'true');
};
return MDCTextFieldHelperTextFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTextFieldHelperText = /** @class */ (function (_super) {
__extends(MDCTextFieldHelperText, _super);
function MDCTextFieldHelperText() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCTextFieldHelperText.attachTo = function (root) {
return new MDCTextFieldHelperText(root);
};
Object.defineProperty(MDCTextFieldHelperText.prototype, "foundation", {
get: function () {
return this.foundation_;
},
enumerable: true,
configurable: true
});
MDCTextFieldHelperText.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
hasClass: function (className) { return _this.root_.classList.contains(className); },
setAttr: function (attr, value) { return _this.root_.setAttribute(attr, value); },
removeAttr: function (attr) { return _this.root_.removeAttribute(attr); },
setContent: function (content) {
_this.root_.textContent = content;
},
};
// tslint:enable:object-literal-sort-keys
return new MDCTextFieldHelperTextFoundation(adapter);
};
return MDCTextFieldHelperText;
}(MDCComponent));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var strings$v = {
ICON_EVENT: 'MDCTextField:icon',
ICON_ROLE: 'button',
};
var cssClasses$s = {
ROOT: 'mdc-text-field__icon',
};
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var INTERACTION_EVENTS$3 = ['click', 'keydown'];
var MDCTextFieldIconFoundation = /** @class */ (function (_super) {
__extends(MDCTextFieldIconFoundation, _super);
function MDCTextFieldIconFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCTextFieldIconFoundation.defaultAdapter, adapter)) || this;
_this.savedTabIndex_ = null;
_this.interactionHandler_ = function (evt) { return _this.handleInteraction(evt); };
return _this;
}
Object.defineProperty(MDCTextFieldIconFoundation, "strings", {
get: function () {
return strings$v;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextFieldIconFoundation, "cssClasses", {
get: function () {
return cssClasses$s;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextFieldIconFoundation, "defaultAdapter", {
/**
* See {@link MDCTextFieldIconAdapter} for typing information on parameters and return types.
*/
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
getAttr: function () { return null; },
setAttr: function () { return undefined; },
removeAttr: function () { return undefined; },
setContent: function () { return undefined; },
registerInteractionHandler: function () { return undefined; },
deregisterInteractionHandler: function () { return undefined; },
notifyIconAction: function () { return undefined; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
MDCTextFieldIconFoundation.prototype.init = function () {
var _this = this;
this.savedTabIndex_ = this.adapter_.getAttr('tabindex');
INTERACTION_EVENTS$3.forEach(function (evtType) {
_this.adapter_.registerInteractionHandler(evtType, _this.interactionHandler_);
});
};
MDCTextFieldIconFoundation.prototype.destroy = function () {
var _this = this;
INTERACTION_EVENTS$3.forEach(function (evtType) {
_this.adapter_.deregisterInteractionHandler(evtType, _this.interactionHandler_);
});
};
MDCTextFieldIconFoundation.prototype.setDisabled = function (disabled) {
if (!this.savedTabIndex_) {
return;
}
if (disabled) {
this.adapter_.setAttr('tabindex', '-1');
this.adapter_.removeAttr('role');
}
else {
this.adapter_.setAttr('tabindex', this.savedTabIndex_);
this.adapter_.setAttr('role', strings$v.ICON_ROLE);
}
};
MDCTextFieldIconFoundation.prototype.setAriaLabel = function (label) {
this.adapter_.setAttr('aria-label', label);
};
MDCTextFieldIconFoundation.prototype.setContent = function (content) {
this.adapter_.setContent(content);
};
MDCTextFieldIconFoundation.prototype.handleInteraction = function (evt) {
var isEnterKey = evt.key === 'Enter' || evt.keyCode === 13;
if (evt.type === 'click' || isEnterKey) {
this.adapter_.notifyIconAction();
}
};
return MDCTextFieldIconFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTextFieldIcon = /** @class */ (function (_super) {
__extends(MDCTextFieldIcon, _super);
function MDCTextFieldIcon() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCTextFieldIcon.attachTo = function (root) {
return new MDCTextFieldIcon(root);
};
Object.defineProperty(MDCTextFieldIcon.prototype, "foundation", {
get: function () {
return this.foundation_;
},
enumerable: true,
configurable: true
});
MDCTextFieldIcon.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
getAttr: function (attr) { return _this.root_.getAttribute(attr); },
setAttr: function (attr, value) { return _this.root_.setAttribute(attr, value); },
removeAttr: function (attr) { return _this.root_.removeAttribute(attr); },
setContent: function (content) {
_this.root_.textContent = content;
},
registerInteractionHandler: function (evtType, handler) { return _this.listen(evtType, handler); },
deregisterInteractionHandler: function (evtType, handler) { return _this.unlisten(evtType, handler); },
notifyIconAction: function () { return _this.emit(MDCTextFieldIconFoundation.strings.ICON_EVENT, {} /* evtData */, true /* shouldBubble */); },
};
// tslint:enable:object-literal-sort-keys
return new MDCTextFieldIconFoundation(adapter);
};
return MDCTextFieldIcon;
}(MDCComponent));
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTextField = /** @class */ (function (_super) {
__extends(MDCTextField, _super);
function MDCTextField() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCTextField.attachTo = function (root) {
return new MDCTextField(root);
};
MDCTextField.prototype.initialize = function (rippleFactory, lineRippleFactory, helperTextFactory, characterCounterFactory, iconFactory, labelFactory, outlineFactory) {
if (rippleFactory === void 0) { rippleFactory = function (el, foundation) { return new MDCRipple(el, foundation); }; }
if (lineRippleFactory === void 0) { lineRippleFactory = function (el) { return new MDCLineRipple(el); }; }
if (helperTextFactory === void 0) { helperTextFactory = function (el) { return new MDCTextFieldHelperText(el); }; }
if (characterCounterFactory === void 0) { characterCounterFactory = function (el) { return new MDCTextFieldCharacterCounter(el); }; }
if (iconFactory === void 0) { iconFactory = function (el) { return new MDCTextFieldIcon(el); }; }
if (labelFactory === void 0) { labelFactory = function (el) { return new MDCFloatingLabel(el); }; }
if (outlineFactory === void 0) { outlineFactory = function (el) { return new MDCNotchedOutline(el); }; }
this.input_ = this.root_.querySelector(strings$t.INPUT_SELECTOR);
var labelElement = this.root_.querySelector(strings$t.LABEL_SELECTOR);
this.label_ = labelElement ? labelFactory(labelElement) : null;
var lineRippleElement = this.root_.querySelector(strings$t.LINE_RIPPLE_SELECTOR);
this.lineRipple_ = lineRippleElement ? lineRippleFactory(lineRippleElement) : null;
var outlineElement = this.root_.querySelector(strings$t.OUTLINE_SELECTOR);
this.outline_ = outlineElement ? outlineFactory(outlineElement) : null;
// Helper text
var helperTextStrings = MDCTextFieldHelperTextFoundation.strings;
var nextElementSibling = this.root_.nextElementSibling;
var hasHelperLine = (nextElementSibling && nextElementSibling.classList.contains(cssClasses$q.HELPER_LINE));
var helperTextEl = hasHelperLine && nextElementSibling && nextElementSibling.querySelector(helperTextStrings.ROOT_SELECTOR);
this.helperText_ = helperTextEl ? helperTextFactory(helperTextEl) : null;
// Character counter
var characterCounterStrings = MDCTextFieldCharacterCounterFoundation.strings;
var characterCounterEl = this.root_.querySelector(characterCounterStrings.ROOT_SELECTOR);
// If character counter is not found in root element search in sibling element.
if (!characterCounterEl && hasHelperLine && nextElementSibling) {
characterCounterEl = nextElementSibling.querySelector(characterCounterStrings.ROOT_SELECTOR);
}
this.characterCounter_ = characterCounterEl ? characterCounterFactory(characterCounterEl) : null;
this.leadingIcon_ = null;
this.trailingIcon_ = null;
var iconElements = this.root_.querySelectorAll(strings$t.ICON_SELECTOR);
if (iconElements.length > 0) {
if (iconElements.length > 1) { // Has both icons.
this.leadingIcon_ = iconFactory(iconElements[0]);
this.trailingIcon_ = iconFactory(iconElements[1]);
}
else {
if (this.root_.classList.contains(cssClasses$q.WITH_LEADING_ICON)) {
this.leadingIcon_ = iconFactory(iconElements[0]);
}
else {
this.trailingIcon_ = iconFactory(iconElements[0]);
}
}
}
this.ripple = this.createRipple_(rippleFactory);
};
MDCTextField.prototype.destroy = function () {
if (this.ripple) {
this.ripple.destroy();
}
if (this.lineRipple_) {
this.lineRipple_.destroy();
}
if (this.helperText_) {
this.helperText_.destroy();
}
if (this.characterCounter_) {
this.characterCounter_.destroy();
}
if (this.leadingIcon_) {
this.leadingIcon_.destroy();
}
if (this.trailingIcon_) {
this.trailingIcon_.destroy();
}
if (this.label_) {
this.label_.destroy();
}
if (this.outline_) {
this.outline_.destroy();
}
_super.prototype.destroy.call(this);
};
/**
* Initializes the Text Field's internal state based on the environment's
* state.
*/
MDCTextField.prototype.initialSyncWithDOM = function () {
this.disabled = this.input_.disabled;
};
Object.defineProperty(MDCTextField.prototype, "value", {
get: function () {
return this.foundation_.getValue();
},
/**
* @param value The value to set on the input.
*/
set: function (value) {
this.foundation_.setValue(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "disabled", {
get: function () {
return this.foundation_.isDisabled();
},
/**
* @param disabled Sets the Text Field disabled or enabled.
*/
set: function (disabled) {
this.foundation_.setDisabled(disabled);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "valid", {
get: function () {
return this.foundation_.isValid();
},
/**
* @param valid Sets the Text Field valid or invalid.
*/
set: function (valid) {
this.foundation_.setValid(valid);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "required", {
get: function () {
return this.input_.required;
},
/**
* @param required Sets the Text Field to required.
*/
set: function (required) {
this.input_.required = required;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "pattern", {
get: function () {
return this.input_.pattern;
},
/**
* @param pattern Sets the input element's validation pattern.
*/
set: function (pattern) {
this.input_.pattern = pattern;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "minLength", {
get: function () {
return this.input_.minLength;
},
/**
* @param minLength Sets the input element's minLength.
*/
set: function (minLength) {
this.input_.minLength = minLength;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "maxLength", {
get: function () {
return this.input_.maxLength;
},
/**
* @param maxLength Sets the input element's maxLength.
*/
set: function (maxLength) {
// Chrome throws exception if maxLength is set to a value less than zero
if (maxLength < 0) {
this.input_.removeAttribute('maxLength');
}
else {
this.input_.maxLength = maxLength;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "min", {
get: function () {
return this.input_.min;
},
/**
* @param min Sets the input element's min.
*/
set: function (min) {
this.input_.min = min;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "max", {
get: function () {
return this.input_.max;
},
/**
* @param max Sets the input element's max.
*/
set: function (max) {
this.input_.max = max;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "step", {
get: function () {
return this.input_.step;
},
/**
* @param step Sets the input element's step.
*/
set: function (step) {
this.input_.step = step;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "helperTextContent", {
/**
* Sets the helper text element content.
*/
set: function (content) {
this.foundation_.setHelperTextContent(content);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "leadingIconAriaLabel", {
/**
* Sets the aria label of the leading icon.
*/
set: function (label) {
this.foundation_.setLeadingIconAriaLabel(label);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "leadingIconContent", {
/**
* Sets the text content of the leading icon.
*/
set: function (content) {
this.foundation_.setLeadingIconContent(content);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "trailingIconAriaLabel", {
/**
* Sets the aria label of the trailing icon.
*/
set: function (label) {
this.foundation_.setTrailingIconAriaLabel(label);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "trailingIconContent", {
/**
* Sets the text content of the trailing icon.
*/
set: function (content) {
this.foundation_.setTrailingIconContent(content);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTextField.prototype, "useNativeValidation", {
/**
* Enables or disables the use of native validation. Use this for custom validation.
* @param useNativeValidation Set this to false to ignore native input validation.
*/
set: function (useNativeValidation) {
this.foundation_.setUseNativeValidation(useNativeValidation);
},
enumerable: true,
configurable: true
});
/**
* Focuses the input element.
*/
MDCTextField.prototype.focus = function () {
this.input_.focus();
};
/**
* Recomputes the outline SVG path for the outline element.
*/
MDCTextField.prototype.layout = function () {
var openNotch = this.foundation_.shouldFloat;
this.foundation_.notchOutline(openNotch);
};
MDCTextField.prototype.getDefaultFoundation = function () {
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = __assign({}, this.getRootAdapterMethods_(), this.getInputAdapterMethods_(), this.getLabelAdapterMethods_(), this.getLineRippleAdapterMethods_(), this.getOutlineAdapterMethods_());
// tslint:enable:object-literal-sort-keys
return new MDCTextFieldFoundation(adapter, this.getFoundationMap_());
};
MDCTextField.prototype.getRootAdapterMethods_ = function () {
var _this = this;
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
hasClass: function (className) { return _this.root_.classList.contains(className); },
registerTextFieldInteractionHandler: function (evtType, handler) { return _this.listen(evtType, handler); },
deregisterTextFieldInteractionHandler: function (evtType, handler) { return _this.unlisten(evtType, handler); },
registerValidationAttributeChangeHandler: function (handler) {
var getAttributesList = function (mutationsList) {
return mutationsList
.map(function (mutation) { return mutation.attributeName; })
.filter(function (attributeName) { return attributeName; });
};
var observer = new MutationObserver(function (mutationsList) { return handler(getAttributesList(mutationsList)); });
var config = { attributes: true };
observer.observe(_this.input_, config);
return observer;
},
deregisterValidationAttributeChangeHandler: function (observer) { return observer.disconnect(); },
};
// tslint:enable:object-literal-sort-keys
};
MDCTextField.prototype.getInputAdapterMethods_ = function () {
var _this = this;
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
getNativeInput: function () { return _this.input_; },
isFocused: function () { return document.activeElement === _this.input_; },
registerInputInteractionHandler: function (evtType, handler) {
return _this.input_.addEventListener(evtType, handler, applyPassive());
},
deregisterInputInteractionHandler: function (evtType, handler) {
return _this.input_.removeEventListener(evtType, handler, applyPassive());
},
};
// tslint:enable:object-literal-sort-keys
};
MDCTextField.prototype.getLabelAdapterMethods_ = function () {
var _this = this;
return {
floatLabel: function (shouldFloat) { return _this.label_ && _this.label_.float(shouldFloat); },
getLabelWidth: function () { return _this.label_ ? _this.label_.getWidth() : 0; },
hasLabel: function () { return Boolean(_this.label_); },
shakeLabel: function (shouldShake) { return _this.label_ && _this.label_.shake(shouldShake); },
};
};
MDCTextField.prototype.getLineRippleAdapterMethods_ = function () {
var _this = this;
return {
activateLineRipple: function () {
if (_this.lineRipple_) {
_this.lineRipple_.activate();
}
},
deactivateLineRipple: function () {
if (_this.lineRipple_) {
_this.lineRipple_.deactivate();
}
},
setLineRippleTransformOrigin: function (normalizedX) {
if (_this.lineRipple_) {
_this.lineRipple_.setRippleCenter(normalizedX);
}
},
};
};
MDCTextField.prototype.getOutlineAdapterMethods_ = function () {
var _this = this;
return {
closeOutline: function () { return _this.outline_ && _this.outline_.closeNotch(); },
hasOutline: function () { return Boolean(_this.outline_); },
notchOutline: function (labelWidth) { return _this.outline_ && _this.outline_.notch(labelWidth); },
};
};
/**
* @return A map of all subcomponents to subfoundations.
*/
MDCTextField.prototype.getFoundationMap_ = function () {
return {
characterCounter: this.characterCounter_ ? this.characterCounter_.foundation : undefined,
helperText: this.helperText_ ? this.helperText_.foundation : undefined,
leadingIcon: this.leadingIcon_ ? this.leadingIcon_.foundation : undefined,
trailingIcon: this.trailingIcon_ ? this.trailingIcon_.foundation : undefined,
};
};
MDCTextField.prototype.createRipple_ = function (rippleFactory) {
var _this = this;
var isTextArea = this.root_.classList.contains(cssClasses$q.TEXTAREA);
var isOutlined = this.root_.classList.contains(cssClasses$q.OUTLINED);
if (isTextArea || isOutlined) {
return null;
}
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = __assign({}, MDCRipple.createAdapter(this), { isSurfaceActive: function () { return matches(_this.input_, ':active'); }, registerInteractionHandler: function (evtType, handler) { return _this.input_.addEventListener(evtType, handler, applyPassive()); }, deregisterInteractionHandler: function (evtType, handler) {
return _this.input_.removeEventListener(evtType, handler, applyPassive());
} });
// tslint:enable:object-literal-sort-keys
return rippleFactory(this.root_, new MDCRippleFoundation(adapter));
};
return MDCTextField;
}(MDCComponent));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$t = {
FIXED_CLASS: 'mdc-top-app-bar--fixed',
FIXED_SCROLLED_CLASS: 'mdc-top-app-bar--fixed-scrolled',
SHORT_CLASS: 'mdc-top-app-bar--short',
SHORT_COLLAPSED_CLASS: 'mdc-top-app-bar--short-collapsed',
SHORT_HAS_ACTION_ITEM_CLASS: 'mdc-top-app-bar--short-has-action-item',
};
var numbers$c = {
DEBOUNCE_THROTTLE_RESIZE_TIME_MS: 100,
MAX_TOP_APP_BAR_HEIGHT: 128,
};
var strings$w = {
ACTION_ITEM_SELECTOR: '.mdc-top-app-bar__action-item',
NAVIGATION_EVENT: 'MDCTopAppBar:nav',
NAVIGATION_ICON_SELECTOR: '.mdc-top-app-bar__navigation-icon',
ROOT_SELECTOR: '.mdc-top-app-bar',
TITLE_SELECTOR: '.mdc-top-app-bar__title',
};
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTopAppBarBaseFoundation = /** @class */ (function (_super) {
__extends(MDCTopAppBarBaseFoundation, _super);
/* istanbul ignore next: optional argument is not a branch statement */
function MDCTopAppBarBaseFoundation(adapter) {
return _super.call(this, __assign({}, MDCTopAppBarBaseFoundation.defaultAdapter, adapter)) || this;
}
Object.defineProperty(MDCTopAppBarBaseFoundation, "strings", {
get: function () {
return strings$w;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTopAppBarBaseFoundation, "cssClasses", {
get: function () {
return cssClasses$t;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTopAppBarBaseFoundation, "numbers", {
get: function () {
return numbers$c;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCTopAppBarBaseFoundation, "defaultAdapter", {
/**
* See {@link MDCTopAppBarAdapter} for typing information on parameters and return types.
*/
get: function () {
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
return {
addClass: function () { return undefined; },
removeClass: function () { return undefined; },
hasClass: function () { return false; },
setStyle: function () { return undefined; },
getTopAppBarHeight: function () { return 0; },
notifyNavigationIconClicked: function () { return undefined; },
getViewportScrollY: function () { return 0; },
getTotalActionItems: function () { return 0; },
};
// tslint:enable:object-literal-sort-keys
},
enumerable: true,
configurable: true
});
/** Other variants of TopAppBar foundation overrides this method */
MDCTopAppBarBaseFoundation.prototype.handleTargetScroll = function () { }; // tslint:disable-line:no-empty
/** Other variants of TopAppBar foundation overrides this method */
MDCTopAppBarBaseFoundation.prototype.handleWindowResize = function () { }; // tslint:disable-line:no-empty
MDCTopAppBarBaseFoundation.prototype.handleNavigationClick = function () {
this.adapter_.notifyNavigationIconClicked();
};
return MDCTopAppBarBaseFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var INITIAL_VALUE = 0;
var MDCTopAppBarFoundation = /** @class */ (function (_super) {
__extends(MDCTopAppBarFoundation, _super);
/* istanbul ignore next: optional argument is not a branch statement */
function MDCTopAppBarFoundation(adapter) {
var _this = _super.call(this, adapter) || this;
/**
* Indicates if the top app bar was docked in the previous scroll handler iteration.
*/
_this.wasDocked_ = true;
/**
* Indicates if the top app bar is docked in the fully shown position.
*/
_this.isDockedShowing_ = true;
/**
* Variable for current scroll position of the top app bar
*/
_this.currentAppBarOffsetTop_ = 0;
/**
* Used to prevent the top app bar from being scrolled out of view during resize events
*/
_this.isCurrentlyBeingResized_ = false;
/**
* The timeout that's used to throttle the resize events
*/
_this.resizeThrottleId_ = INITIAL_VALUE;
/**
* The timeout that's used to debounce toggling the isCurrentlyBeingResized_ variable after a resize
*/
_this.resizeDebounceId_ = INITIAL_VALUE;
_this.lastScrollPosition_ = _this.adapter_.getViewportScrollY();
_this.topAppBarHeight_ = _this.adapter_.getTopAppBarHeight();
return _this;
}
MDCTopAppBarFoundation.prototype.destroy = function () {
_super.prototype.destroy.call(this);
this.adapter_.setStyle('top', '');
};
/**
* Scroll handler for the default scroll behavior of the top app bar.
* @override
*/
MDCTopAppBarFoundation.prototype.handleTargetScroll = function () {
var currentScrollPosition = Math.max(this.adapter_.getViewportScrollY(), 0);
var diff = currentScrollPosition - this.lastScrollPosition_;
this.lastScrollPosition_ = currentScrollPosition;
// If the window is being resized the lastScrollPosition_ needs to be updated but the
// current scroll of the top app bar should stay in the same position.
if (!this.isCurrentlyBeingResized_) {
this.currentAppBarOffsetTop_ -= diff;
if (this.currentAppBarOffsetTop_ > 0) {
this.currentAppBarOffsetTop_ = 0;
}
else if (Math.abs(this.currentAppBarOffsetTop_) > this.topAppBarHeight_) {
this.currentAppBarOffsetTop_ = -this.topAppBarHeight_;
}
this.moveTopAppBar_();
}
};
/**
* Top app bar resize handler that throttle/debounce functions that execute updates.
* @override
*/
MDCTopAppBarFoundation.prototype.handleWindowResize = function () {
var _this = this;
// Throttle resize events 10 p/s
if (!this.resizeThrottleId_) {
this.resizeThrottleId_ = setTimeout(function () {
_this.resizeThrottleId_ = INITIAL_VALUE;
_this.throttledResizeHandler_();
}, numbers$c.DEBOUNCE_THROTTLE_RESIZE_TIME_MS);
}
this.isCurrentlyBeingResized_ = true;
if (this.resizeDebounceId_) {
clearTimeout(this.resizeDebounceId_);
}
this.resizeDebounceId_ = setTimeout(function () {
_this.handleTargetScroll();
_this.isCurrentlyBeingResized_ = false;
_this.resizeDebounceId_ = INITIAL_VALUE;
}, numbers$c.DEBOUNCE_THROTTLE_RESIZE_TIME_MS);
};
/**
* Function to determine if the DOM needs to update.
*/
MDCTopAppBarFoundation.prototype.checkForUpdate_ = function () {
var offscreenBoundaryTop = -this.topAppBarHeight_;
var hasAnyPixelsOffscreen = this.currentAppBarOffsetTop_ < 0;
var hasAnyPixelsOnscreen = this.currentAppBarOffsetTop_ > offscreenBoundaryTop;
var partiallyShowing = hasAnyPixelsOffscreen && hasAnyPixelsOnscreen;
// If it's partially showing, it can't be docked.
if (partiallyShowing) {
this.wasDocked_ = false;
}
else {
// Not previously docked and not partially showing, it's now docked.
if (!this.wasDocked_) {
this.wasDocked_ = true;
return true;
}
else if (this.isDockedShowing_ !== hasAnyPixelsOnscreen) {
this.isDockedShowing_ = hasAnyPixelsOnscreen;
return true;
}
}
return partiallyShowing;
};
/**
* Function to move the top app bar if needed.
*/
MDCTopAppBarFoundation.prototype.moveTopAppBar_ = function () {
if (this.checkForUpdate_()) {
// Once the top app bar is fully hidden we use the max potential top app bar height as our offset
// so the top app bar doesn't show if the window resizes and the new height > the old height.
var offset = this.currentAppBarOffsetTop_;
if (Math.abs(offset) >= this.topAppBarHeight_) {
offset = -numbers$c.MAX_TOP_APP_BAR_HEIGHT;
}
this.adapter_.setStyle('top', offset + 'px');
}
};
/**
* Throttled function that updates the top app bar scrolled values if the
* top app bar height changes.
*/
MDCTopAppBarFoundation.prototype.throttledResizeHandler_ = function () {
var currentHeight = this.adapter_.getTopAppBarHeight();
if (this.topAppBarHeight_ !== currentHeight) {
this.wasDocked_ = false;
// Since the top app bar has a different height depending on the screen width, this
// will ensure that the top app bar remains in the correct location if
// completely hidden and a resize makes the top app bar a different height.
this.currentAppBarOffsetTop_ -= this.topAppBarHeight_ - currentHeight;
this.topAppBarHeight_ = currentHeight;
}
this.handleTargetScroll();
};
return MDCTopAppBarFoundation;
}(MDCTopAppBarBaseFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCFixedTopAppBarFoundation = /** @class */ (function (_super) {
__extends(MDCFixedTopAppBarFoundation, _super);
function MDCFixedTopAppBarFoundation() {
var _this = _super !== null && _super.apply(this, arguments) || this;
/**
* State variable for the previous scroll iteration top app bar state
*/
_this.wasScrolled_ = false;
return _this;
}
/**
* Scroll handler for applying/removing the modifier class on the fixed top app bar.
* @override
*/
MDCFixedTopAppBarFoundation.prototype.handleTargetScroll = function () {
var currentScroll = this.adapter_.getViewportScrollY();
if (currentScroll <= 0) {
if (this.wasScrolled_) {
this.adapter_.removeClass(cssClasses$t.FIXED_SCROLLED_CLASS);
this.wasScrolled_ = false;
}
}
else {
if (!this.wasScrolled_) {
this.adapter_.addClass(cssClasses$t.FIXED_SCROLLED_CLASS);
this.wasScrolled_ = true;
}
}
};
return MDCFixedTopAppBarFoundation;
}(MDCTopAppBarFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCShortTopAppBarFoundation = /** @class */ (function (_super) {
__extends(MDCShortTopAppBarFoundation, _super);
/* istanbul ignore next: optional argument is not a branch statement */
function MDCShortTopAppBarFoundation(adapter) {
var _this = _super.call(this, adapter) || this;
_this.isCollapsed_ = false;
_this.isAlwaysCollapsed_ = false;
return _this;
}
Object.defineProperty(MDCShortTopAppBarFoundation.prototype, "isCollapsed", {
// Public visibility for backward compatibility.
get: function () {
return this.isCollapsed_;
},
enumerable: true,
configurable: true
});
MDCShortTopAppBarFoundation.prototype.init = function () {
_super.prototype.init.call(this);
if (this.adapter_.getTotalActionItems() > 0) {
this.adapter_.addClass(cssClasses$t.SHORT_HAS_ACTION_ITEM_CLASS);
}
// If initialized with SHORT_COLLAPSED_CLASS, the bar should always be collapsed
this.setAlwaysCollapsed(this.adapter_.hasClass(cssClasses$t.SHORT_COLLAPSED_CLASS));
};
/**
* Set if the short top app bar should always be collapsed.
*
* @param value When `true`, bar will always be collapsed. When `false`, bar may collapse or expand based on scroll.
*/
MDCShortTopAppBarFoundation.prototype.setAlwaysCollapsed = function (value) {
this.isAlwaysCollapsed_ = !!value;
if (this.isAlwaysCollapsed_) {
this.collapse_();
}
else {
// let maybeCollapseBar_ determine if the bar should be collapsed
this.maybeCollapseBar_();
}
};
MDCShortTopAppBarFoundation.prototype.getAlwaysCollapsed = function () {
return this.isAlwaysCollapsed_;
};
/**
* Scroll handler for applying/removing the collapsed modifier class on the short top app bar.
* @override
*/
MDCShortTopAppBarFoundation.prototype.handleTargetScroll = function () {
this.maybeCollapseBar_();
};
MDCShortTopAppBarFoundation.prototype.maybeCollapseBar_ = function () {
if (this.isAlwaysCollapsed_) {
return;
}
var currentScroll = this.adapter_.getViewportScrollY();
if (currentScroll <= 0) {
if (this.isCollapsed_) {
this.uncollapse_();
}
}
else {
if (!this.isCollapsed_) {
this.collapse_();
}
}
};
MDCShortTopAppBarFoundation.prototype.uncollapse_ = function () {
this.adapter_.removeClass(cssClasses$t.SHORT_COLLAPSED_CLASS);
this.isCollapsed_ = false;
};
MDCShortTopAppBarFoundation.prototype.collapse_ = function () {
this.adapter_.addClass(cssClasses$t.SHORT_COLLAPSED_CLASS);
this.isCollapsed_ = true;
};
return MDCShortTopAppBarFoundation;
}(MDCTopAppBarBaseFoundation));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCTopAppBar = /** @class */ (function (_super) {
__extends(MDCTopAppBar, _super);
function MDCTopAppBar() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCTopAppBar.attachTo = function (root) {
return new MDCTopAppBar(root);
};
MDCTopAppBar.prototype.initialize = function (rippleFactory) {
if (rippleFactory === void 0) { rippleFactory = function (el) { return MDCRipple.attachTo(el); }; }
this.navIcon_ = this.root_.querySelector(strings$w.NAVIGATION_ICON_SELECTOR);
// Get all icons in the toolbar and instantiate the ripples
var icons = [].slice.call(this.root_.querySelectorAll(strings$w.ACTION_ITEM_SELECTOR));
if (this.navIcon_) {
icons.push(this.navIcon_);
}
this.iconRipples_ = icons.map(function (icon) {
var ripple = rippleFactory(icon);
ripple.unbounded = true;
return ripple;
});
this.scrollTarget_ = window;
};
MDCTopAppBar.prototype.initialSyncWithDOM = function () {
this.handleNavigationClick_ = this.foundation_.handleNavigationClick.bind(this.foundation_);
this.handleWindowResize_ = this.foundation_.handleWindowResize.bind(this.foundation_);
this.handleTargetScroll_ = this.foundation_.handleTargetScroll.bind(this.foundation_);
this.scrollTarget_.addEventListener('scroll', this.handleTargetScroll_);
if (this.navIcon_) {
this.navIcon_.addEventListener('click', this.handleNavigationClick_);
}
var isFixed = this.root_.classList.contains(cssClasses$t.FIXED_CLASS);
var isShort = this.root_.classList.contains(cssClasses$t.SHORT_CLASS);
if (!isShort && !isFixed) {
window.addEventListener('resize', this.handleWindowResize_);
}
};
MDCTopAppBar.prototype.destroy = function () {
this.iconRipples_.forEach(function (iconRipple) { return iconRipple.destroy(); });
this.scrollTarget_.removeEventListener('scroll', this.handleTargetScroll_);
if (this.navIcon_) {
this.navIcon_.removeEventListener('click', this.handleNavigationClick_);
}
var isFixed = this.root_.classList.contains(cssClasses$t.FIXED_CLASS);
var isShort = this.root_.classList.contains(cssClasses$t.SHORT_CLASS);
if (!isShort && !isFixed) {
window.removeEventListener('resize', this.handleWindowResize_);
}
_super.prototype.destroy.call(this);
};
MDCTopAppBar.prototype.setScrollTarget = function (target) {
// Remove scroll handler from the previous scroll target
this.scrollTarget_.removeEventListener('scroll', this.handleTargetScroll_);
this.scrollTarget_ = target;
// Initialize scroll handler on the new scroll target
this.handleTargetScroll_ =
this.foundation_.handleTargetScroll.bind(this.foundation_);
this.scrollTarget_.addEventListener('scroll', this.handleTargetScroll_);
};
MDCTopAppBar.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
hasClass: function (className) { return _this.root_.classList.contains(className); },
addClass: function (className) { return _this.root_.classList.add(className); },
removeClass: function (className) { return _this.root_.classList.remove(className); },
setStyle: function (property, value) { return _this.root_.style.setProperty(property, value); },
getTopAppBarHeight: function () { return _this.root_.clientHeight; },
notifyNavigationIconClicked: function () { return _this.emit(strings$w.NAVIGATION_EVENT, {}); },
getViewportScrollY: function () {
var win = _this.scrollTarget_;
var el = _this.scrollTarget_;
return win.pageYOffset !== undefined ? win.pageYOffset : el.scrollTop;
},
getTotalActionItems: function () { return _this.root_.querySelectorAll(strings$w.ACTION_ITEM_SELECTOR).length; },
};
// tslint:enable:object-literal-sort-keys
var foundation;
if (this.root_.classList.contains(cssClasses$t.SHORT_CLASS)) {
foundation = new MDCShortTopAppBarFoundation(adapter);
}
else if (this.root_.classList.contains(cssClasses$t.FIXED_CLASS)) {
foundation = new MDCFixedTopAppBarFoundation(adapter);
}
else {
foundation = new MDCTopAppBarFoundation(adapter);
}
return foundation;
};
return MDCTopAppBar;
}(MDCComponent));
/**
* @license
* Copyright 2019 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$u = {
CELL: 'mdc-data-table__cell',
CELL_NUMERIC: 'mdc-data-table__cell--numeric',
CONTENT: 'mdc-data-table__content',
HEADER_ROW: 'mdc-data-table__header-row',
HEADER_ROW_CHECKBOX: 'mdc-data-table__header-row-checkbox',
ROOT: 'mdc-data-table',
ROW: 'mdc-data-table__row',
ROW_CHECKBOX: 'mdc-data-table__row-checkbox',
ROW_SELECTED: 'mdc-data-table__row--selected',
};
var strings$x = {
ARIA_SELECTED: 'aria-selected',
DATA_ROW_ID_ATTR: 'data-row-id',
HEADER_ROW_CHECKBOX_SELECTOR: "." + cssClasses$u.HEADER_ROW_CHECKBOX,
ROW_CHECKBOX_SELECTOR: "." + cssClasses$u.ROW_CHECKBOX,
ROW_SELECTED_SELECTOR: "." + cssClasses$u.ROW_SELECTED,
ROW_SELECTOR: "." + cssClasses$u.ROW,
};
var events = {
ROW_SELECTION_CHANGED: 'MDCDataTable:rowSelectionChanged',
SELECTED_ALL: 'MDCDataTable:selectedAll',
UNSELECTED_ALL: 'MDCDataTable:unselectedAll',
};
/**
* @license
* Copyright 2019 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCDataTableFoundation = /** @class */ (function (_super) {
__extends(MDCDataTableFoundation, _super);
function MDCDataTableFoundation(adapter) {
return _super.call(this, __assign({}, MDCDataTableFoundation.defaultAdapter, adapter)) || this;
}
Object.defineProperty(MDCDataTableFoundation, "defaultAdapter", {
get: function () {
return {
addClassAtRowIndex: function () { return undefined; },
getRowCount: function () { return 0; },
getRowElements: function () { return []; },
getRowIdAtIndex: function () { return ''; },
getRowIndexByChildElement: function () { return 0; },
getSelectedRowCount: function () { return 0; },
isCheckboxAtRowIndexChecked: function () { return false; },
isHeaderRowCheckboxChecked: function () { return false; },
isRowsSelectable: function () { return false; },
notifyRowSelectionChanged: function () { return undefined; },
notifySelectedAll: function () { return undefined; },
notifyUnselectedAll: function () { return undefined; },
registerHeaderRowCheckbox: function () { return undefined; },
registerRowCheckboxes: function () { return undefined; },
removeClassAtRowIndex: function () { return undefined; },
setAttributeAtRowIndex: function () { return undefined; },
setHeaderRowCheckboxChecked: function () { return undefined; },
setHeaderRowCheckboxIndeterminate: function () { return undefined; },
setRowCheckboxCheckedAtIndex: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
/**
* Re-initializes header row checkbox and row checkboxes when selectable rows are added or removed from table.
* Use this if registering checkbox is synchronous.
*/
MDCDataTableFoundation.prototype.layout = function () {
if (this.adapter_.isRowsSelectable()) {
this.adapter_.registerHeaderRowCheckbox();
this.adapter_.registerRowCheckboxes();
this.setHeaderRowCheckboxState_();
}
};
/**
* Re-initializes header row checkbox and row checkboxes when selectable rows are added or removed from table.
* Use this if registering checkbox is asynchronous.
*/
MDCDataTableFoundation.prototype.layoutAsync = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.adapter_.isRowsSelectable()) return [3 /*break*/, 3];
return [4 /*yield*/, this.adapter_.registerHeaderRowCheckbox()];
case 1:
_a.sent();
return [4 /*yield*/, this.adapter_.registerRowCheckboxes()];
case 2:
_a.sent();
this.setHeaderRowCheckboxState_();
_a.label = 3;
case 3: return [2 /*return*/];
}
});
});
};
/**
* @return Returns array of row elements.
*/
MDCDataTableFoundation.prototype.getRows = function () {
return this.adapter_.getRowElements();
};
/**
* Sets selected row ids. Overwrites previously selected rows.
* @param rowIds Array of row ids that needs to be selected.
*/
MDCDataTableFoundation.prototype.setSelectedRowIds = function (rowIds) {
for (var rowIndex = 0; rowIndex < this.adapter_.getRowCount(); rowIndex++) {
var rowId = this.adapter_.getRowIdAtIndex(rowIndex);
var isSelected = false;
if (rowId && rowIds.indexOf(rowId) >= 0) {
isSelected = true;
}
this.adapter_.setRowCheckboxCheckedAtIndex(rowIndex, isSelected);
this.selectRowAtIndex_(rowIndex, isSelected);
}
this.setHeaderRowCheckboxState_();
};
/**
* @return Returns array of selected row ids.
*/
MDCDataTableFoundation.prototype.getSelectedRowIds = function () {
var selectedRowIds = [];
for (var rowIndex = 0; rowIndex < this.adapter_.getRowCount(); rowIndex++) {
if (this.adapter_.isCheckboxAtRowIndexChecked(rowIndex)) {
selectedRowIds.push(this.adapter_.getRowIdAtIndex(rowIndex));
}
}
return selectedRowIds;
};
/**
* Handles header row checkbox change event.
*/
MDCDataTableFoundation.prototype.handleHeaderRowCheckboxChange = function () {
var isHeaderChecked = this.adapter_.isHeaderRowCheckboxChecked();
for (var rowIndex = 0; rowIndex < this.adapter_.getRowCount(); rowIndex++) {
this.adapter_.setRowCheckboxCheckedAtIndex(rowIndex, isHeaderChecked);
this.selectRowAtIndex_(rowIndex, isHeaderChecked);
}
if (isHeaderChecked) {
this.adapter_.notifySelectedAll();
}
else {
this.adapter_.notifyUnselectedAll();
}
};
/**
* Handles change event originated from row checkboxes.
*/
MDCDataTableFoundation.prototype.handleRowCheckboxChange = function (event) {
var rowIndex = this.adapter_.getRowIndexByChildElement(event.target);
if (rowIndex === -1) {
return;
}
var selected = this.adapter_.isCheckboxAtRowIndexChecked(rowIndex);
this.selectRowAtIndex_(rowIndex, selected);
this.setHeaderRowCheckboxState_();
var rowId = this.adapter_.getRowIdAtIndex(rowIndex);
this.adapter_.notifyRowSelectionChanged({ rowId: rowId, rowIndex: rowIndex, selected: selected });
};
/**
* Updates header row checkbox state based on number of rows selected.
*/
MDCDataTableFoundation.prototype.setHeaderRowCheckboxState_ = function () {
if (this.adapter_.getSelectedRowCount() === this.adapter_.getRowCount()) {
this.adapter_.setHeaderRowCheckboxChecked(true);
this.adapter_.setHeaderRowCheckboxIndeterminate(false);
}
else if (this.adapter_.getSelectedRowCount() === 0) {
this.adapter_.setHeaderRowCheckboxIndeterminate(false);
this.adapter_.setHeaderRowCheckboxChecked(false);
}
else {
this.adapter_.setHeaderRowCheckboxIndeterminate(true);
this.adapter_.setHeaderRowCheckboxChecked(false);
}
};
/**
* Sets the attributes of row element based on selection state.
*/
MDCDataTableFoundation.prototype.selectRowAtIndex_ = function (rowIndex, selected) {
if (selected) {
this.adapter_.addClassAtRowIndex(rowIndex, cssClasses$u.ROW_SELECTED);
this.adapter_.setAttributeAtRowIndex(rowIndex, strings$x.ARIA_SELECTED, 'true');
}
else {
this.adapter_.removeClassAtRowIndex(rowIndex, cssClasses$u.ROW_SELECTED);
this.adapter_.setAttributeAtRowIndex(rowIndex, strings$x.ARIA_SELECTED, 'false');
}
};
return MDCDataTableFoundation;
}(MDCFoundation));
/**
* @license
* Copyright 2019 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCDataTable = /** @class */ (function (_super) {
__extends(MDCDataTable, _super);
function MDCDataTable() {
return _super !== null && _super.apply(this, arguments) || this;
}
MDCDataTable.attachTo = function (root) {
return new MDCDataTable(root);
};
MDCDataTable.prototype.initialize = function (checkboxFactory) {
if (checkboxFactory === void 0) { checkboxFactory = function (el) { return new MDCCheckbox(el); }; }
this.checkboxFactory_ = checkboxFactory;
};
MDCDataTable.prototype.initialSyncWithDOM = function () {
var _this = this;
this.headerRow_ = this.root_.querySelector("." + cssClasses$u.HEADER_ROW);
this.handleHeaderRowCheckboxChange_ = function () { return _this.foundation_.handleHeaderRowCheckboxChange(); };
this.headerRow_.addEventListener('change', this.handleHeaderRowCheckboxChange_);
this.content_ = this.root_.querySelector("." + cssClasses$u.CONTENT);
this.handleRowCheckboxChange_ = function (event) { return _this.foundation_.handleRowCheckboxChange(event); };
this.content_.addEventListener('change', this.handleRowCheckboxChange_);
this.layout();
};
/**
* Re-initializes header row checkbox and row checkboxes when selectable rows are added or removed from table.
*/
MDCDataTable.prototype.layout = function () {
this.foundation_.layout();
};
/**
* @return Returns array of row elements.
*/
MDCDataTable.prototype.getRows = function () {
return this.foundation_.getRows();
};
/**
* @return Returns array of selected row ids.
*/
MDCDataTable.prototype.getSelectedRowIds = function () {
return this.foundation_.getSelectedRowIds();
};
/**
* Sets selected row ids. Overwrites previously selected rows.
* @param rowIds Array of row ids that needs to be selected.
*/
MDCDataTable.prototype.setSelectedRowIds = function (rowIds) {
this.foundation_.setSelectedRowIds(rowIds);
};
MDCDataTable.prototype.destroy = function () {
this.headerRow_.removeEventListener('change', this.handleHeaderRowCheckboxChange_);
this.content_.removeEventListener('change', this.handleRowCheckboxChange_);
this.headerRowCheckbox_.destroy();
this.rowCheckboxList_.forEach(function (checkbox) { return checkbox.destroy(); });
};
MDCDataTable.prototype.getDefaultFoundation = function () {
var _this = this;
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
// tslint:disable:object-literal-sort-keys Methods should be in the same order as the adapter interface.
var adapter = {
addClassAtRowIndex: function (rowIndex, className) { return _this.getRows()[rowIndex].classList.add(className); },
getRowCount: function () { return _this.getRows().length; },
getRowElements: function () { return [].slice.call(_this.root_.querySelectorAll(strings$x.ROW_SELECTOR)); },
getRowIdAtIndex: function (rowIndex) { return _this.getRows()[rowIndex].getAttribute(strings$x.DATA_ROW_ID_ATTR); },
getRowIndexByChildElement: function (el) {
return _this.getRows().indexOf(closest(el, strings$x.ROW_SELECTOR));
},
getSelectedRowCount: function () { return _this.root_.querySelectorAll(strings$x.ROW_SELECTED_SELECTOR).length; },
isCheckboxAtRowIndexChecked: function (rowIndex) { return _this.rowCheckboxList_[rowIndex].checked; },
isHeaderRowCheckboxChecked: function () { return _this.headerRowCheckbox_.checked; },
isRowsSelectable: function () { return !!_this.root_.querySelector(strings$x.ROW_CHECKBOX_SELECTOR); },
notifyRowSelectionChanged: function (data) {
_this.emit(events.ROW_SELECTION_CHANGED, {
row: _this.getRowByIndex_(data.rowIndex),
rowId: _this.getRowIdByIndex_(data.rowIndex),
rowIndex: data.rowIndex,
selected: data.selected,
},
/** shouldBubble */ true);
},
notifySelectedAll: function () { return _this.emit(events.SELECTED_ALL, {}, /** shouldBubble */ true); },
notifyUnselectedAll: function () { return _this.emit(events.UNSELECTED_ALL, {}, /** shouldBubble */ true); },
registerHeaderRowCheckbox: function () {
if (_this.headerRowCheckbox_) {
_this.headerRowCheckbox_.destroy();
}
var checkboxEl = _this.root_.querySelector(strings$x.HEADER_ROW_CHECKBOX_SELECTOR);
_this.headerRowCheckbox_ = _this.checkboxFactory_(checkboxEl);
},
registerRowCheckboxes: function () {
if (_this.rowCheckboxList_) {
_this.rowCheckboxList_.forEach(function (checkbox) { return checkbox.destroy(); });
}
_this.rowCheckboxList_ = [];
_this.getRows().forEach(function (rowEl) {
var checkbox = _this.checkboxFactory_(rowEl.querySelector(strings$x.ROW_CHECKBOX_SELECTOR));
_this.rowCheckboxList_.push(checkbox);
});
},
removeClassAtRowIndex: function (rowIndex, className) {
_this.getRows()[rowIndex].classList.remove(className);
},
setAttributeAtRowIndex: function (rowIndex, attr, value) {
_this.getRows()[rowIndex].setAttribute(attr, value);
},
setHeaderRowCheckboxChecked: function (checked) {
_this.headerRowCheckbox_.checked = checked;
},
setHeaderRowCheckboxIndeterminate: function (indeterminate) {
_this.headerRowCheckbox_.indeterminate = indeterminate;
},
setRowCheckboxCheckedAtIndex: function (rowIndex, checked) {
_this.rowCheckboxList_[rowIndex].checked = checked;
},
};
return new MDCDataTableFoundation(adapter);
};
MDCDataTable.prototype.getRowByIndex_ = function (index) {
return this.getRows()[index];
};
MDCDataTable.prototype.getRowIdByIndex_ = function (index) {
return this.getRowByIndex_(index).getAttribute(strings$x.DATA_ROW_ID_ATTR);
};
return MDCDataTable;
}(MDCComponent));
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
/**
* True if the custom elements polyfill is in use.
*/
const isCEPolyfill = typeof window !== 'undefined' &&
window.customElements != null &&
window.customElements.polyfillWrapFlushCallback !==
undefined;
/**
* Reparents nodes, starting from `start` (inclusive) to `end` (exclusive),
* into another container (could be the same container), before `before`. If
* `before` is null, it appends the nodes to the container.
*/
const reparentNodes = (container, start, end = null, before = null) => {
while (start !== end) {
const n = start.nextSibling;
container.insertBefore(start, before);
start = n;
}
};
/**
* Removes nodes, starting from `start` (inclusive) to `end` (exclusive), from
* `container`.
*/
const removeNodes = (container, start, end = null) => {
while (start !== end) {
const n = start.nextSibling;
container.removeChild(start);
start = n;
}
};
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
/**
* An expression marker with embedded unique key to avoid collision with
* possible text in templates.
*/
const marker = `{{lit-${String(Math.random()).slice(2)}}}`;
/**
* An expression marker used text-positions, multi-binding attributes, and
* attributes with markup-like text values.
*/
const nodeMarker = `<!--${marker}-->`;
const markerRegex = new RegExp(`${marker}|${nodeMarker}`);
/**
* Suffix appended to all bound attribute names.
*/
const boundAttributeSuffix = '$lit$';
/**
* An updatable Template that tracks the location of dynamic parts.
*/
class Template {
constructor(result, element) {
this.parts = [];
this.element = element;
const nodesToRemove = [];
const stack = [];
// Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null
const walker = document.createTreeWalker(element.content, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false);
// Keeps track of the last index associated with a part. We try to delete
// unnecessary nodes, but we never want to associate two different parts
// to the same index. They must have a constant node between.
let lastPartIndex = 0;
let index = -1;
let partIndex = 0;
const { strings, values: { length } } = result;
while (partIndex < length) {
const node = walker.nextNode();
if (node === null) {
// We've exhausted the content inside a nested template element.
// Because we still have parts (the outer for-loop), we know:
// - There is a template in the stack
// - The walker will find a nextNode outside the template
walker.currentNode = stack.pop();
continue;
}
index++;
if (node.nodeType === 1 /* Node.ELEMENT_NODE */) {
if (node.hasAttributes()) {
const attributes = node.attributes;
const { length } = attributes;
// Per
// https://developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap,
// attributes are not guaranteed to be returned in document order.
// In particular, Edge/IE can return them out of order, so we cannot
// assume a correspondence between part index and attribute index.
let count = 0;
for (let i = 0; i < length; i++) {
if (endsWith(attributes[i].name, boundAttributeSuffix)) {
count++;
}
}
while (count-- > 0) {
// Get the template literal section leading up to the first
// expression in this attribute
const stringForPart = strings[partIndex];
// Find the attribute name
const name = lastAttributeNameRegex.exec(stringForPart)[2];
// Find the corresponding attribute
// All bound attributes have had a suffix added in
// TemplateResult#getHTML to opt out of special attribute
// handling. To look up the attribute value we also need to add
// the suffix.
const attributeLookupName = name.toLowerCase() + boundAttributeSuffix;
const attributeValue = node.getAttribute(attributeLookupName);
node.removeAttribute(attributeLookupName);
const statics = attributeValue.split(markerRegex);
this.parts.push({ type: 'attribute', index, name, strings: statics });
partIndex += statics.length - 1;
}
}
if (node.tagName === 'TEMPLATE') {
stack.push(node);
walker.currentNode = node.content;
}
}
else if (node.nodeType === 3 /* Node.TEXT_NODE */) {
const data = node.data;
if (data.indexOf(marker) >= 0) {
const parent = node.parentNode;
const strings = data.split(markerRegex);
const lastIndex = strings.length - 1;
// Generate a new text node for each literal section
// These nodes are also used as the markers for node parts
for (let i = 0; i < lastIndex; i++) {
let insert;
let s = strings[i];
if (s === '') {
insert = createMarker();
}
else {
const match = lastAttributeNameRegex.exec(s);
if (match !== null && endsWith(match[2], boundAttributeSuffix)) {
s = s.slice(0, match.index) + match[1] +
match[2].slice(0, -boundAttributeSuffix.length) + match[3];
}
insert = document.createTextNode(s);
}
parent.insertBefore(insert, node);
this.parts.push({ type: 'node', index: ++index });
}
// If there's no text, we must insert a comment to mark our place.
// Else, we can trust it will stick around after cloning.
if (strings[lastIndex] === '') {
parent.insertBefore(createMarker(), node);
nodesToRemove.push(node);
}
else {
node.data = strings[lastIndex];
}
// We have a part for each match found
partIndex += lastIndex;
}
}
else if (node.nodeType === 8 /* Node.COMMENT_NODE */) {
if (node.data === marker) {
const parent = node.parentNode;
// Add a new marker node to be the startNode of the Part if any of
// the following are true:
// * We don't have a previousSibling
// * The previousSibling is already the start of a previous part
if (node.previousSibling === null || index === lastPartIndex) {
index++;
parent.insertBefore(createMarker(), node);
}
lastPartIndex = index;
this.parts.push({ type: 'node', index });
// If we don't have a nextSibling, keep this node so we have an end.
// Else, we can remove it to save future costs.
if (node.nextSibling === null) {
node.data = '';
}
else {
nodesToRemove.push(node);
index--;
}
partIndex++;
}
else {
let i = -1;
while ((i = node.data.indexOf(marker, i + 1)) !== -1) {
// Comment node has a binding marker inside, make an inactive part
// The binding won't work, but subsequent bindings will
// TODO (justinfagnani): consider whether it's even worth it to
// make bindings in comments work
this.parts.push({ type: 'node', index: -1 });
partIndex++;
}
}
}
}
// Remove text binding nodes after the walk to not disturb the TreeWalker
for (const n of nodesToRemove) {
n.parentNode.removeChild(n);
}
}
}
const endsWith = (str, suffix) => {
const index = str.length - suffix.length;
return index >= 0 && str.slice(index) === suffix;
};
const isTemplatePartActive = (part) => part.index !== -1;
// Allows `document.createComment('')` to be renamed for a
// small manual size-savings.
const createMarker = () => document.createComment('');
/**
* This regex extracts the attribute name preceding an attribute-position
* expression. It does this by matching the syntax allowed for attributes
* against the string literal directly preceding the expression, assuming that
* the expression is in an attribute-value position.
*
* See attributes in the HTML spec:
* https://www.w3.org/TR/html5/syntax.html#elements-attributes
*
* " \x09\x0a\x0c\x0d" are HTML space characters:
* https://www.w3.org/TR/html5/infrastructure.html#space-characters
*
* "\0-\x1F\x7F-\x9F" are Unicode control characters, which includes every
* space character except " ".
*
* So an attribute is:
* * The name: any character except a control character, space character, ('),
* ("), ">", "=", or "/"
* * Followed by zero or more space characters
* * Followed by "="
* * Followed by zero or more space characters
* * Followed by:
* * Any character except space, ('), ("), "<", ">", "=", (`), or
* * (") then any non-("), or
* * (') then any non-(')
*/
const lastAttributeNameRegex =
// eslint-disable-next-line no-control-regex
/([ \x09\x0a\x0c\x0d])([^\0-\x1F\x7F-\x9F "'>=/]+)([ \x09\x0a\x0c\x0d]*=[ \x09\x0a\x0c\x0d]*(?:[^ \x09\x0a\x0c\x0d"'`<>=]*|"[^"]*|'[^']*))$/;
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
const walkerNodeFilter = 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */;
/**
* Removes the list of nodes from a Template safely. In addition to removing
* nodes from the Template, the Template part indices are updated to match
* the mutated Template DOM.
*
* As the template is walked the removal state is tracked and
* part indices are adjusted as needed.
*
* div
* div#1 (remove) <-- start removing (removing node is div#1)
* div
* div#2 (remove) <-- continue removing (removing node is still div#1)
* div
* div <-- stop removing since previous sibling is the removing node (div#1,
* removed 4 nodes)
*/
function removeNodesFromTemplate(template, nodesToRemove) {
const { element: { content }, parts } = template;
const walker = document.createTreeWalker(content, walkerNodeFilter, null, false);
let partIndex = nextActiveIndexInTemplateParts(parts);
let part = parts[partIndex];
let nodeIndex = -1;
let removeCount = 0;
const nodesToRemoveInTemplate = [];
let currentRemovingNode = null;
while (walker.nextNode()) {
nodeIndex++;
const node = walker.currentNode;
// End removal if stepped past the removing node
if (node.previousSibling === currentRemovingNode) {
currentRemovingNode = null;
}
// A node to remove was found in the template
if (nodesToRemove.has(node)) {
nodesToRemoveInTemplate.push(node);
// Track node we're removing
if (currentRemovingNode === null) {
currentRemovingNode = node;
}
}
// When removing, increment count by which to adjust subsequent part indices
if (currentRemovingNode !== null) {
removeCount++;
}
while (part !== undefined && part.index === nodeIndex) {
// If part is in a removed node deactivate it by setting index to -1 or
// adjust the index as needed.
part.index = currentRemovingNode !== null ? -1 : part.index - removeCount;
// go to the next active part.
partIndex = nextActiveIndexInTemplateParts(parts, partIndex);
part = parts[partIndex];
}
}
nodesToRemoveInTemplate.forEach((n) => n.parentNode.removeChild(n));
}
const countNodes = (node) => {
let count = (node.nodeType === 11 /* Node.DOCUMENT_FRAGMENT_NODE */) ? 0 : 1;
const walker = document.createTreeWalker(node, walkerNodeFilter, null, false);
while (walker.nextNode()) {
count++;
}
return count;
};
const nextActiveIndexInTemplateParts = (parts, startIndex = -1) => {
for (let i = startIndex + 1; i < parts.length; i++) {
const part = parts[i];
if (isTemplatePartActive(part)) {
return i;
}
}
return -1;
};
/**
* Inserts the given node into the Template, optionally before the given
* refNode. In addition to inserting the node into the Template, the Template
* part indices are updated to match the mutated Template DOM.
*/
function insertNodeIntoTemplate(template, node, refNode = null) {
const { element: { content }, parts } = template;
// If there's no refNode, then put node at end of template.
// No part indices need to be shifted in this case.
if (refNode === null || refNode === undefined) {
content.appendChild(node);
return;
}
const walker = document.createTreeWalker(content, walkerNodeFilter, null, false);
let partIndex = nextActiveIndexInTemplateParts(parts);
let insertCount = 0;
let walkerIndex = -1;
while (walker.nextNode()) {
walkerIndex++;
const walkerNode = walker.currentNode;
if (walkerNode === refNode) {
insertCount = countNodes(node);
refNode.parentNode.insertBefore(node, refNode);
}
while (partIndex !== -1 && parts[partIndex].index === walkerIndex) {
// If we've inserted the node, simply adjust all subsequent parts
if (insertCount > 0) {
while (partIndex !== -1) {
parts[partIndex].index += insertCount;
partIndex = nextActiveIndexInTemplateParts(parts, partIndex);
}
return;
}
partIndex = nextActiveIndexInTemplateParts(parts, partIndex);
}
}
}
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
const directives = new WeakMap();
/**
* Brands a function as a directive factory function so that lit-html will call
* the function during template rendering, rather than passing as a value.
*
* A _directive_ is a function that takes a Part as an argument. It has the
* signature: `(part: Part) => void`.
*
* A directive _factory_ is a function that takes arguments for data and
* configuration and returns a directive. Users of directive usually refer to
* the directive factory as the directive. For example, "The repeat directive".
*
* Usually a template author will invoke a directive factory in their template
* with relevant arguments, which will then return a directive function.
*
* Here's an example of using the `repeat()` directive factory that takes an
* array and a function to render an item:
*
* ```js
* html`<ul><${repeat(items, (item) => html`<li>${item}</li>`)}</ul>`
* ```
*
* When `repeat` is invoked, it returns a directive function that closes over
* `items` and the template function. When the outer template is rendered, the
* return directive function is called with the Part for the expression.
* `repeat` then performs it's custom logic to render multiple items.
*
* @param f The directive factory function. Must be a function that returns a
* function of the signature `(part: Part) => void`. The returned function will
* be called with the part object.
*
* @example
*
* import {directive, html} from 'lit-html';
*
* const immutable = directive((v) => (part) => {
* if (part.value !== v) {
* part.setValue(v)
* }
* });
*/
const directive = (f) => ((...args) => {
const d = f(...args);
directives.set(d, true);
return d;
});
const isDirective = (o) => {
return typeof o === 'function' && directives.has(o);
};
/**
* @license
* Copyright (c) 2018 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
/**
* A sentinel value that signals that a value was handled by a directive and
* should not be written to the DOM.
*/
const noChange = {};
/**
* A sentinel value that signals a NodePart to fully clear its content.
*/
const nothing = {};
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
/**
* An instance of a `Template` that can be attached to the DOM and updated
* with new values.
*/
class TemplateInstance {
constructor(template, processor, options) {
this.__parts = [];
this.template = template;
this.processor = processor;
this.options = options;
}
update(values) {
let i = 0;
for (const part of this.__parts) {
if (part !== undefined) {
part.setValue(values[i]);
}
i++;
}
for (const part of this.__parts) {
if (part !== undefined) {
part.commit();
}
}
}
_clone() {
// There are a number of steps in the lifecycle of a template instance's
// DOM fragment:
// 1. Clone - create the instance fragment
// 2. Adopt - adopt into the main document
// 3. Process - find part markers and create parts
// 4. Upgrade - upgrade custom elements
// 5. Update - set node, attribute, property, etc., values
// 6. Connect - connect to the document. Optional and outside of this
// method.
//
// We have a few constraints on the ordering of these steps:
// * We need to upgrade before updating, so that property values will pass
// through any property setters.
// * We would like to process before upgrading so that we're sure that the
// cloned fragment is inert and not disturbed by self-modifying DOM.
// * We want custom elements to upgrade even in disconnected fragments.
//
// Given these constraints, with full custom elements support we would
// prefer the order: Clone, Process, Adopt, Upgrade, Update, Connect
//
// But Safari does not implement CustomElementRegistry#upgrade, so we
// can not implement that order and still have upgrade-before-update and
// upgrade disconnected fragments. So we instead sacrifice the
// process-before-upgrade constraint, since in Custom Elements v1 elements
// must not modify their light DOM in the constructor. We still have issues
// when co-existing with CEv0 elements like Polymer 1, and with polyfills
// that don't strictly adhere to the no-modification rule because shadow
// DOM, which may be created in the constructor, is emulated by being placed
// in the light DOM.
//
// The resulting order is on native is: Clone, Adopt, Upgrade, Process,
// Update, Connect. document.importNode() performs Clone, Adopt, and Upgrade
// in one step.
//
// The Custom Elements v1 polyfill supports upgrade(), so the order when
// polyfilled is the more ideal: Clone, Process, Adopt, Upgrade, Update,
// Connect.
const fragment = isCEPolyfill ?
this.template.element.content.cloneNode(true) :
document.importNode(this.template.element.content, true);
const stack = [];
const parts = this.template.parts;
// Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null
const walker = document.createTreeWalker(fragment, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false);
let partIndex = 0;
let nodeIndex = 0;
let part;
let node = walker.nextNode();
// Loop through all the nodes and parts of a template
while (partIndex < parts.length) {
part = parts[partIndex];
if (!isTemplatePartActive(part)) {
this.__parts.push(undefined);
partIndex++;
continue;
}
// Progress the tree walker until we find our next part's node.
// Note that multiple parts may share the same node (attribute parts
// on a single element), so this loop may not run at all.
while (nodeIndex < part.index) {
nodeIndex++;
if (node.nodeName === 'TEMPLATE') {
stack.push(node);
walker.currentNode = node.content;
}
if ((node = walker.nextNode()) === null) {
// We've exhausted the content inside a nested template element.
// Because we still have parts (the outer for-loop), we know:
// - There is a template in the stack
// - The walker will find a nextNode outside the template
walker.currentNode = stack.pop();
node = walker.nextNode();
}
}
// We've arrived at our part's node.
if (part.type === 'node') {
const part = this.processor.handleTextExpression(this.options);
part.insertAfterNode(node.previousSibling);
this.__parts.push(part);
}
else {
this.__parts.push(...this.processor.handleAttributeExpressions(node, part.name, part.strings, this.options));
}
partIndex++;
}
if (isCEPolyfill) {
document.adoptNode(fragment);
customElements.upgrade(fragment);
}
return fragment;
}
}
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
const commentMarker = ` ${marker} `;
/**
* The return type of `html`, which holds a Template and the values from
* interpolated expressions.
*/
class TemplateResult {
constructor(strings, values, type, processor) {
this.strings = strings;
this.values = values;
this.type = type;
this.processor = processor;
}
/**
* Returns a string of HTML used to create a `<template>` element.
*/
getHTML() {
const l = this.strings.length - 1;
let html = '';
let isCommentBinding = false;
for (let i = 0; i < l; i++) {
const s = this.strings[i];
// For each binding we want to determine the kind of marker to insert
// into the template source before it's parsed by the browser's HTML
// parser. The marker type is based on whether the expression is in an
// attribute, text, or comment position.
// * For node-position bindings we insert a comment with the marker
// sentinel as its text content, like <!--{{lit-guid}}-->.
// * For attribute bindings we insert just the marker sentinel for the
// first binding, so that we support unquoted attribute bindings.
// Subsequent bindings can use a comment marker because multi-binding
// attributes must be quoted.
// * For comment bindings we insert just the marker sentinel so we don't
// close the comment.
//
// The following code scans the template source, but is *not* an HTML
// parser. We don't need to track the tree structure of the HTML, only
// whether a binding is inside a comment, and if not, if it appears to be
// the first binding in an attribute.
const commentOpen = s.lastIndexOf('<!--');
// We're in comment position if we have a comment open with no following
// comment close. Because <-- can appear in an attribute value there can
// be false positives.
isCommentBinding = (commentOpen > -1 || isCommentBinding) &&
s.indexOf('-->', commentOpen + 1) === -1;
// Check to see if we have an attribute-like sequence preceding the
// expression. This can match "name=value" like structures in text,
// comments, and attribute values, so there can be false-positives.
const attributeMatch = lastAttributeNameRegex.exec(s);
if (attributeMatch === null) {
// We're only in this branch if we don't have a attribute-like
// preceding sequence. For comments, this guards against unusual
// attribute values like <div foo="<!--${'bar'}">. Cases like
// <!-- foo=${'bar'}--> are handled correctly in the attribute branch
// below.
html += s + (isCommentBinding ? commentMarker : nodeMarker);
}
else {
// For attributes we use just a marker sentinel, and also append a
// $lit$ suffix to the name to opt-out of attribute-specific parsing
// that IE and Edge do for style and certain SVG attributes.
html += s.substr(0, attributeMatch.index) + attributeMatch[1] +
attributeMatch[2] + boundAttributeSuffix + attributeMatch[3] +
marker;
}
}
html += this.strings[l];
return html;
}
getTemplateElement() {
const template = document.createElement('template');
template.innerHTML = this.getHTML();
return template;
}
}
/**
* A TemplateResult for SVG fragments.
*
* This class wraps HTML in an `<svg>` tag in order to parse its contents in the
* SVG namespace, then modifies the template to remove the `<svg>` tag so that
* clones only container the original fragment.
*/
class SVGTemplateResult extends TemplateResult {
getHTML() {
return `<svg>${super.getHTML()}</svg>`;
}
getTemplateElement() {
const template = super.getTemplateElement();
const content = template.content;
const svgElement = content.firstChild;
content.removeChild(svgElement);
reparentNodes(content, svgElement.firstChild);
return template;
}
}
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
const isPrimitive = (value) => {
return (value === null ||
!(typeof value === 'object' || typeof value === 'function'));
};
const isIterable = (value) => {
return Array.isArray(value) ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
!!(value && value[Symbol.iterator]);
};
/**
* Writes attribute values to the DOM for a group of AttributeParts bound to a
* single attribute. The value is only set once even if there are multiple parts
* for an attribute.
*/
class AttributeCommitter {
constructor(element, name, strings) {
this.dirty = true;
this.element = element;
this.name = name;
this.strings = strings;
this.parts = [];
for (let i = 0; i < strings.length - 1; i++) {
this.parts[i] = this._createPart();
}
}
/**
* Creates a single part. Override this to create a differnt type of part.
*/
_createPart() {
return new AttributePart(this);
}
_getValue() {
const strings = this.strings;
const l = strings.length - 1;
let text = '';
for (let i = 0; i < l; i++) {
text += strings[i];
const part = this.parts[i];
if (part !== undefined) {
const v = part.value;
if (isPrimitive(v) || !isIterable(v)) {
text += typeof v === 'string' ? v : String(v);
}
else {
for (const t of v) {
text += typeof t === 'string' ? t : String(t);
}
}
}
}
text += strings[l];
return text;
}
commit() {
if (this.dirty) {
this.dirty = false;
this.element.setAttribute(this.name, this._getValue());
}
}
}
/**
* A Part that controls all or part of an attribute value.
*/
class AttributePart {
constructor(committer) {
this.value = undefined;
this.committer = committer;
}
setValue(value) {
if (value !== noChange && (!isPrimitive(value) || value !== this.value)) {
this.value = value;
// If the value is a not a directive, dirty the committer so that it'll
// call setAttribute. If the value is a directive, it'll dirty the
// committer if it calls setValue().
if (!isDirective(value)) {
this.committer.dirty = true;
}
}
}
commit() {
while (isDirective(this.value)) {
const directive = this.value;
this.value = noChange;
directive(this);
}
if (this.value === noChange) {
return;
}
this.committer.commit();
}
}
/**
* A Part that controls a location within a Node tree. Like a Range, NodePart
* has start and end locations and can set and update the Nodes between those
* locations.
*
* NodeParts support several value types: primitives, Nodes, TemplateResults,
* as well as arrays and iterables of those types.
*/
class NodePart {
constructor(options) {
this.value = undefined;
this.__pendingValue = undefined;
this.options = options;
}
/**
* Appends this part into a container.
*
* This part must be empty, as its contents are not automatically moved.
*/
appendInto(container) {
this.startNode = container.appendChild(createMarker());
this.endNode = container.appendChild(createMarker());
}
/**
* Inserts this part after the `ref` node (between `ref` and `ref`'s next
* sibling). Both `ref` and its next sibling must be static, unchanging nodes
* such as those that appear in a literal section of a template.
*
* This part must be empty, as its contents are not automatically moved.
*/
insertAfterNode(ref) {
this.startNode = ref;
this.endNode = ref.nextSibling;
}
/**
* Appends this part into a parent part.
*
* This part must be empty, as its contents are not automatically moved.
*/
appendIntoPart(part) {
part.__insert(this.startNode = createMarker());
part.__insert(this.endNode = createMarker());
}
/**
* Inserts this part after the `ref` part.
*
* This part must be empty, as its contents are not automatically moved.
*/
insertAfterPart(ref) {
ref.__insert(this.startNode = createMarker());
this.endNode = ref.endNode;
ref.endNode = this.startNode;
}
setValue(value) {
this.__pendingValue = value;
}
commit() {
if (this.startNode.parentNode === null) {
return;
}
while (isDirective(this.__pendingValue)) {
const directive = this.__pendingValue;
this.__pendingValue = noChange;
directive(this);
}
const value = this.__pendingValue;
if (value === noChange) {
return;
}
if (isPrimitive(value)) {
if (value !== this.value) {
this.__commitText(value);
}
}
else if (value instanceof TemplateResult) {
this.__commitTemplateResult(value);
}
else if (value instanceof Node) {
this.__commitNode(value);
}
else if (isIterable(value)) {
this.__commitIterable(value);
}
else if (value === nothing) {
this.value = nothing;
this.clear();
}
else {
// Fallback, will render the string representation
this.__commitText(value);
}
}
__insert(node) {
this.endNode.parentNode.insertBefore(node, this.endNode);
}
__commitNode(value) {
if (this.value === value) {
return;
}
this.clear();
this.__insert(value);
this.value = value;
}
__commitText(value) {
const node = this.startNode.nextSibling;
value = value == null ? '' : value;
// If `value` isn't already a string, we explicitly convert it here in case
// it can't be implicitly converted - i.e. it's a symbol.
const valueAsString = typeof value === 'string' ? value : String(value);
if (node === this.endNode.previousSibling &&
node.nodeType === 3 /* Node.TEXT_NODE */) {
// If we only have a single text node between the markers, we can just
// set its value, rather than replacing it.
// TODO(justinfagnani): Can we just check if this.value is primitive?
node.data = valueAsString;
}
else {
this.__commitNode(document.createTextNode(valueAsString));
}
this.value = value;
}
__commitTemplateResult(value) {
const template = this.options.templateFactory(value);
if (this.value instanceof TemplateInstance &&
this.value.template === template) {
this.value.update(value.values);
}
else {
// Make sure we propagate the template processor from the TemplateResult
// so that we use its syntax extension, etc. The template factory comes
// from the render function options so that it can control template
// caching and preprocessing.
const instance = new TemplateInstance(template, value.processor, this.options);
const fragment = instance._clone();
instance.update(value.values);
this.__commitNode(fragment);
this.value = instance;
}
}
__commitIterable(value) {
// For an Iterable, we create a new InstancePart per item, then set its
// value to the item. This is a little bit of overhead for every item in
// an Iterable, but it lets us recurse easily and efficiently update Arrays
// of TemplateResults that will be commonly returned from expressions like:
// array.map((i) => html`${i}`), by reusing existing TemplateInstances.
// If _value is an array, then the previous render was of an
// iterable and _value will contain the NodeParts from the previous
// render. If _value is not an array, clear this part and make a new
// array for NodeParts.
if (!Array.isArray(this.value)) {
this.value = [];
this.clear();
}
// Lets us keep track of how many items we stamped so we can clear leftover
// items from a previous render
const itemParts = this.value;
let partIndex = 0;
let itemPart;
for (const item of value) {
// Try to reuse an existing part
itemPart = itemParts[partIndex];
// If no existing part, create a new one
if (itemPart === undefined) {
itemPart = new NodePart(this.options);
itemParts.push(itemPart);
if (partIndex === 0) {
itemPart.appendIntoPart(this);
}
else {
itemPart.insertAfterPart(itemParts[partIndex - 1]);
}
}
itemPart.setValue(item);
itemPart.commit();
partIndex++;
}
if (partIndex < itemParts.length) {
// Truncate the parts array so _value reflects the current state
itemParts.length = partIndex;
this.clear(itemPart && itemPart.endNode);
}
}
clear(startNode = this.startNode) {
removeNodes(this.startNode.parentNode, startNode.nextSibling, this.endNode);
}
}
/**
* Implements a boolean attribute, roughly as defined in the HTML
* specification.
*
* If the value is truthy, then the attribute is present with a value of
* ''. If the value is falsey, the attribute is removed.
*/
class BooleanAttributePart {
constructor(element, name, strings) {
this.value = undefined;
this.__pendingValue = undefined;
if (strings.length !== 2 || strings[0] !== '' || strings[1] !== '') {
throw new Error('Boolean attributes can only contain a single expression');
}
this.element = element;
this.name = name;
this.strings = strings;
}
setValue(value) {
this.__pendingValue = value;
}
commit() {
while (isDirective(this.__pendingValue)) {
const directive = this.__pendingValue;
this.__pendingValue = noChange;
directive(this);
}
if (this.__pendingValue === noChange) {
return;
}
const value = !!this.__pendingValue;
if (this.value !== value) {
if (value) {
this.element.setAttribute(this.name, '');
}
else {
this.element.removeAttribute(this.name);
}
this.value = value;
}
this.__pendingValue = noChange;
}
}
/**
* Sets attribute values for PropertyParts, so that the value is only set once
* even if there are multiple parts for a property.
*
* If an expression controls the whole property value, then the value is simply
* assigned to the property under control. If there are string literals or
* multiple expressions, then the strings are expressions are interpolated into
* a string first.
*/
class PropertyCommitter extends AttributeCommitter {
constructor(element, name, strings) {
super(element, name, strings);
this.single =
(strings.length === 2 && strings[0] === '' && strings[1] === '');
}
_createPart() {
return new PropertyPart(this);
}
_getValue() {
if (this.single) {
return this.parts[0].value;
}
return super._getValue();
}
commit() {
if (this.dirty) {
this.dirty = false;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.element[this.name] = this._getValue();
}
}
}
class PropertyPart extends AttributePart {
}
// Detect event listener options support. If the `capture` property is read
// from the options object, then options are supported. If not, then the third
// argument to add/removeEventListener is interpreted as the boolean capture
// value so we should only pass the `capture` property.
let eventOptionsSupported = false;
// Wrap into an IIFE because MS Edge <= v41 does not support having try/catch
// blocks right into the body of a module
(() => {
try {
const options = {
get capture() {
eventOptionsSupported = true;
return false;
}
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
window.addEventListener('test', options, options);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
window.removeEventListener('test', options, options);
}
catch (_e) {
// event options not supported
}
})();
class EventPart {
constructor(element, eventName, eventContext) {
this.value = undefined;
this.__pendingValue = undefined;
this.element = element;
this.eventName = eventName;
this.eventContext = eventContext;
this.__boundHandleEvent = (e) => this.handleEvent(e);
}
setValue(value) {
this.__pendingValue = value;
}
commit() {
while (isDirective(this.__pendingValue)) {
const directive = this.__pendingValue;
this.__pendingValue = noChange;
directive(this);
}
if (this.__pendingValue === noChange) {
return;
}
const newListener = this.__pendingValue;
const oldListener = this.value;
const shouldRemoveListener = newListener == null ||
oldListener != null &&
(newListener.capture !== oldListener.capture ||
newListener.once !== oldListener.once ||
newListener.passive !== oldListener.passive);
const shouldAddListener = newListener != null && (oldListener == null || shouldRemoveListener);
if (shouldRemoveListener) {
this.element.removeEventListener(this.eventName, this.__boundHandleEvent, this.__options);
}
if (shouldAddListener) {
this.__options = getOptions(newListener);
this.element.addEventListener(this.eventName, this.__boundHandleEvent, this.__options);
}
this.value = newListener;
this.__pendingValue = noChange;
}
handleEvent(event) {
if (typeof this.value === 'function') {
this.value.call(this.eventContext || this.element, event);
}
else {
this.value.handleEvent(event);
}
}
}
// We copy options because of the inconsistent behavior of browsers when reading
// the third argument of add/removeEventListener. IE11 doesn't support options
// at all. Chrome 41 only reads `capture` if the argument is an object.
const getOptions = (o) => o &&
(eventOptionsSupported ?
{ capture: o.capture, passive: o.passive, once: o.once } :
o.capture);
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
/**
* The default TemplateFactory which caches Templates keyed on
* result.type and result.strings.
*/
function templateFactory(result) {
let templateCache = templateCaches.get(result.type);
if (templateCache === undefined) {
templateCache = {
stringsArray: new WeakMap(),
keyString: new Map()
};
templateCaches.set(result.type, templateCache);
}
let template = templateCache.stringsArray.get(result.strings);
if (template !== undefined) {
return template;
}
// If the TemplateStringsArray is new, generate a key from the strings
// This key is shared between all templates with identical content
const key = result.strings.join(marker);
// Check if we already have a Template for this key
template = templateCache.keyString.get(key);
if (template === undefined) {
// If we have not seen this key before, create a new Template
template = new Template(result, result.getTemplateElement());
// Cache the Template for this key
templateCache.keyString.set(key, template);
}
// Cache all future queries for this TemplateStringsArray
templateCache.stringsArray.set(result.strings, template);
return template;
}
const templateCaches = new Map();
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
const parts = new WeakMap();
/**
* Renders a template result or other value to a container.
*
* To update a container with new values, reevaluate the template literal and
* call `render` with the new result.
*
* @param result Any value renderable by NodePart - typically a TemplateResult
* created by evaluating a template tag like `html` or `svg`.
* @param container A DOM parent to render to. The entire contents are either
* replaced, or efficiently updated if the same result type was previous
* rendered there.
* @param options RenderOptions for the entire render tree rendered to this
* container. Render options must *not* change between renders to the same
* container, as those changes will not effect previously rendered DOM.
*/
const render = (result, container, options) => {
let part = parts.get(container);
if (part === undefined) {
removeNodes(container, container.firstChild);
parts.set(container, part = new NodePart(Object.assign({ templateFactory }, options)));
part.appendInto(container);
}
part.setValue(result);
part.commit();
};
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
/**
* Creates Parts when a template is instantiated.
*/
class DefaultTemplateProcessor {
/**
* Create parts for an attribute-position binding, given the event, attribute
* name, and string literals.
*
* @param element The element containing the binding
* @param name The attribute name
* @param strings The string literals. There are always at least two strings,
* event for fully-controlled bindings with a single expression.
*/
handleAttributeExpressions(element, name, strings, options) {
const prefix = name[0];
if (prefix === '.') {
const committer = new PropertyCommitter(element, name.slice(1), strings);
return committer.parts;
}
if (prefix === '@') {
return [new EventPart(element, name.slice(1), options.eventContext)];
}
if (prefix === '?') {
return [new BooleanAttributePart(element, name.slice(1), strings)];
}
const committer = new AttributeCommitter(element, name, strings);
return committer.parts;
}
/**
* Create parts for a text-position binding.
* @param templateFactory
*/
handleTextExpression(options) {
return new NodePart(options);
}
}
const defaultTemplateProcessor = new DefaultTemplateProcessor();
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
// IMPORTANT: do not change the property name or the assignment expression.
// This line will be used in regexes to search for lit-html usage.
// TODO(justinfagnani): inject version number at build time
if (typeof window !== 'undefined') {
(window['litHtmlVersions'] || (window['litHtmlVersions'] = [])).push('1.2.1');
}
/**
* Interprets a template literal as an HTML template that can efficiently
* render to and update a container.
*/
const html = (strings, ...values) => new TemplateResult(strings, values, 'html', defaultTemplateProcessor);
/**
* Interprets a template literal as an SVG template that can efficiently
* render to and update a container.
*/
const svg = (strings, ...values) => new SVGTemplateResult(strings, values, 'svg', defaultTemplateProcessor);
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
// Get a key to lookup in `templateCaches`.
const getTemplateCacheKey = (type, scopeName) => `${type}--${scopeName}`;
let compatibleShadyCSSVersion = true;
if (typeof window.ShadyCSS === 'undefined') {
compatibleShadyCSSVersion = false;
}
else if (typeof window.ShadyCSS.prepareTemplateDom === 'undefined') {
console.warn(`Incompatible ShadyCSS version detected. ` +
`Please update to at least @webcomponents/webcomponentsjs@2.0.2 and ` +
`@webcomponents/shadycss@1.3.1.`);
compatibleShadyCSSVersion = false;
}
/**
* Template factory which scopes template DOM using ShadyCSS.
* @param scopeName {string}
*/
const shadyTemplateFactory = (scopeName) => (result) => {
const cacheKey = getTemplateCacheKey(result.type, scopeName);
let templateCache = templateCaches.get(cacheKey);
if (templateCache === undefined) {
templateCache = {
stringsArray: new WeakMap(),
keyString: new Map()
};
templateCaches.set(cacheKey, templateCache);
}
let template = templateCache.stringsArray.get(result.strings);
if (template !== undefined) {
return template;
}
const key = result.strings.join(marker);
template = templateCache.keyString.get(key);
if (template === undefined) {
const element = result.getTemplateElement();
if (compatibleShadyCSSVersion) {
window.ShadyCSS.prepareTemplateDom(element, scopeName);
}
template = new Template(result, element);
templateCache.keyString.set(key, template);
}
templateCache.stringsArray.set(result.strings, template);
return template;
};
const TEMPLATE_TYPES = ['html', 'svg'];
/**
* Removes all style elements from Templates for the given scopeName.
*/
const removeStylesFromLitTemplates = (scopeName) => {
TEMPLATE_TYPES.forEach((type) => {
const templates = templateCaches.get(getTemplateCacheKey(type, scopeName));
if (templates !== undefined) {
templates.keyString.forEach((template) => {
const { element: { content } } = template;
// IE 11 doesn't support the iterable param Set constructor
const styles = new Set();
Array.from(content.querySelectorAll('style')).forEach((s) => {
styles.add(s);
});
removeNodesFromTemplate(template, styles);
});
}
});
};
const shadyRenderSet = new Set();
/**
* For the given scope name, ensures that ShadyCSS style scoping is performed.
* This is done just once per scope name so the fragment and template cannot
* be modified.
* (1) extracts styles from the rendered fragment and hands them to ShadyCSS
* to be scoped and appended to the document
* (2) removes style elements from all lit-html Templates for this scope name.
*
* Note, <style> elements can only be placed into templates for the
* initial rendering of the scope. If <style> elements are included in templates
* dynamically rendered to the scope (after the first scope render), they will
* not be scoped and the <style> will be left in the template and rendered
* output.
*/
const prepareTemplateStyles = (scopeName, renderedDOM, template) => {
shadyRenderSet.add(scopeName);
// If `renderedDOM` is stamped from a Template, then we need to edit that
// Template's underlying template element. Otherwise, we create one here
// to give to ShadyCSS, which still requires one while scoping.
const templateElement = !!template ? template.element : document.createElement('template');
// Move styles out of rendered DOM and store.
const styles = renderedDOM.querySelectorAll('style');
const { length } = styles;
// If there are no styles, skip unnecessary work
if (length === 0) {
// Ensure prepareTemplateStyles is called to support adding
// styles via `prepareAdoptedCssText` since that requires that
// `prepareTemplateStyles` is called.
//
// ShadyCSS will only update styles containing @apply in the template
// given to `prepareTemplateStyles`. If no lit Template was given,
// ShadyCSS will not be able to update uses of @apply in any relevant
// template. However, this is not a problem because we only create the
// template for the purpose of supporting `prepareAdoptedCssText`,
// which doesn't support @apply at all.
window.ShadyCSS.prepareTemplateStyles(templateElement, scopeName);
return;
}
const condensedStyle = document.createElement('style');
// Collect styles into a single style. This helps us make sure ShadyCSS
// manipulations will not prevent us from being able to fix up template
// part indices.
// NOTE: collecting styles is inefficient for browsers but ShadyCSS
// currently does this anyway. When it does not, this should be changed.
for (let i = 0; i < length; i++) {
const style = styles[i];
style.parentNode.removeChild(style);
condensedStyle.textContent += style.textContent;
}
// Remove styles from nested templates in this scope.
removeStylesFromLitTemplates(scopeName);
// And then put the condensed style into the "root" template passed in as
// `template`.
const content = templateElement.content;
if (!!template) {
insertNodeIntoTemplate(template, condensedStyle, content.firstChild);
}
else {
content.insertBefore(condensedStyle, content.firstChild);
}
// Note, it's important that ShadyCSS gets the template that `lit-html`
// will actually render so that it can update the style inside when
// needed (e.g. @apply native Shadow DOM case).
window.ShadyCSS.prepareTemplateStyles(templateElement, scopeName);
const style = content.querySelector('style');
if (window.ShadyCSS.nativeShadow && style !== null) {
// When in native Shadow DOM, ensure the style created by ShadyCSS is
// included in initially rendered output (`renderedDOM`).
renderedDOM.insertBefore(style.cloneNode(true), renderedDOM.firstChild);
}
else if (!!template) {
// When no style is left in the template, parts will be broken as a
// result. To fix this, we put back the style node ShadyCSS removed
// and then tell lit to remove that node from the template.
// There can be no style in the template in 2 cases (1) when Shady DOM
// is in use, ShadyCSS removes all styles, (2) when native Shadow DOM
// is in use ShadyCSS removes the style if it contains no content.
// NOTE, ShadyCSS creates its own style so we can safely add/remove
// `condensedStyle` here.
content.insertBefore(condensedStyle, content.firstChild);
const removes = new Set();
removes.add(condensedStyle);
removeNodesFromTemplate(template, removes);
}
};
/**
* Extension to the standard `render` method which supports rendering
* to ShadowRoots when the ShadyDOM (https://github.com/webcomponents/shadydom)
* and ShadyCSS (https://github.com/webcomponents/shadycss) polyfills are used
* or when the webcomponentsjs
* (https://github.com/webcomponents/webcomponentsjs) polyfill is used.
*
* Adds a `scopeName` option which is used to scope element DOM and stylesheets
* when native ShadowDOM is unavailable. The `scopeName` will be added to
* the class attribute of all rendered DOM. In addition, any style elements will
* be automatically re-written with this `scopeName` selector and moved out
* of the rendered DOM and into the document `<head>`.
*
* It is common to use this render method in conjunction with a custom element
* which renders a shadowRoot. When this is done, typically the element's
* `localName` should be used as the `scopeName`.
*
* In addition to DOM scoping, ShadyCSS also supports a basic shim for css
* custom properties (needed only on older browsers like IE11) and a shim for
* a deprecated feature called `@apply` that supports applying a set of css
* custom properties to a given location.
*
* Usage considerations:
*
* * Part values in `<style>` elements are only applied the first time a given
* `scopeName` renders. Subsequent changes to parts in style elements will have
* no effect. Because of this, parts in style elements should only be used for
* values that will never change, for example parts that set scope-wide theme
* values or parts which render shared style elements.
*
* * Note, due to a limitation of the ShadyDOM polyfill, rendering in a
* custom element's `constructor` is not supported. Instead rendering should
* either done asynchronously, for example at microtask timing (for example
* `Promise.resolve()`), or be deferred until the first time the element's
* `connectedCallback` runs.
*
* Usage considerations when using shimmed custom properties or `@apply`:
*
* * Whenever any dynamic changes are made which affect
* css custom properties, `ShadyCSS.styleElement(element)` must be called
* to update the element. There are two cases when this is needed:
* (1) the element is connected to a new parent, (2) a class is added to the
* element that causes it to match different custom properties.
* To address the first case when rendering a custom element, `styleElement`
* should be called in the element's `connectedCallback`.
*
* * Shimmed custom properties may only be defined either for an entire
* shadowRoot (for example, in a `:host` rule) or via a rule that directly
* matches an element with a shadowRoot. In other words, instead of flowing from
* parent to child as do native css custom properties, shimmed custom properties
* flow only from shadowRoots to nested shadowRoots.
*
* * When using `@apply` mixing css shorthand property names with
* non-shorthand names (for example `border` and `border-width`) is not
* supported.
*/
const render$1 = (result, container, options) => {
if (!options || typeof options !== 'object' || !options.scopeName) {
throw new Error('The `scopeName` option is required.');
}
const scopeName = options.scopeName;
const hasRendered = parts.has(container);
const needsScoping = compatibleShadyCSSVersion &&
container.nodeType === 11 /* Node.DOCUMENT_FRAGMENT_NODE */ &&
!!container.host;
// Handle first render to a scope specially...
const firstScopeRender = needsScoping && !shadyRenderSet.has(scopeName);
// On first scope render, render into a fragment; this cannot be a single
// fragment that is reused since nested renders can occur synchronously.
const renderContainer = firstScopeRender ? document.createDocumentFragment() : container;
render(result, renderContainer, Object.assign({ templateFactory: shadyTemplateFactory(scopeName) }, options));
// When performing first scope render,
// (1) We've rendered into a fragment so that there's a chance to
// `prepareTemplateStyles` before sub-elements hit the DOM
// (which might cause them to render based on a common pattern of
// rendering in a custom element's `connectedCallback`);
// (2) Scope the template with ShadyCSS one time only for this scope.
// (3) Render the fragment into the container and make sure the
// container knows its `part` is the one we just rendered. This ensures
// DOM will be re-used on subsequent renders.
if (firstScopeRender) {
const part = parts.get(renderContainer);
parts.delete(renderContainer);
// ShadyCSS might have style sheets (e.g. from `prepareAdoptedCssText`)
// that should apply to `renderContainer` even if the rendered value is
// not a TemplateInstance. However, it will only insert scoped styles
// into the document if `prepareTemplateStyles` has already been called
// for the given scope name.
const template = part.value instanceof TemplateInstance ?
part.value.template :
undefined;
prepareTemplateStyles(scopeName, renderContainer, template);
removeNodes(container, container.firstChild);
container.appendChild(renderContainer);
parts.set(container, part);
}
// After elements have hit the DOM, update styling if this is the
// initial render to this container.
// This is needed whenever dynamic changes are made so it would be
// safest to do every render; however, this would regress performance
// so we leave it up to the user to call `ShadyCSS.styleElement`
// for dynamic changes.
if (!hasRendered && needsScoping) {
window.ShadyCSS.styleElement(container.host);
}
};
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
var _a$1;
/**
* When using Closure Compiler, JSCompiler_renameProperty(property, object) is
* replaced at compile time by the munged name for object[property]. We cannot
* alias this function, so we have to use a small shim that has the same
* behavior when not compiling.
*/
window.JSCompiler_renameProperty =
(prop, _obj) => prop;
const defaultConverter = {
toAttribute(value, type) {
switch (type) {
case Boolean:
return value ? '' : null;
case Object:
case Array:
// if the value is `null` or `undefined` pass this through
// to allow removing/no change behavior.
return value == null ? value : JSON.stringify(value);
}
return value;
},
fromAttribute(value, type) {
switch (type) {
case Boolean:
return value !== null;
case Number:
return value === null ? null : Number(value);
case Object:
case Array:
return JSON.parse(value);
}
return value;
}
};
/**
* Change function that returns true if `value` is different from `oldValue`.
* This method is used as the default for a property's `hasChanged` function.
*/
const notEqual = (value, old) => {
// This ensures (old==NaN, value==NaN) always returns false
return old !== value && (old === old || value === value);
};
const defaultPropertyDeclaration = {
attribute: true,
type: String,
converter: defaultConverter,
reflect: false,
hasChanged: notEqual
};
const STATE_HAS_UPDATED = 1;
const STATE_UPDATE_REQUESTED = 1 << 2;
const STATE_IS_REFLECTING_TO_ATTRIBUTE = 1 << 3;
const STATE_IS_REFLECTING_TO_PROPERTY = 1 << 4;
/**
* The Closure JS Compiler doesn't currently have good support for static
* property semantics where "this" is dynamic (e.g.
* https://github.com/google/closure-compiler/issues/3177 and others) so we use
* this hack to bypass any rewriting by the compiler.
*/
const finalized = 'finalized';
/**
* Base element class which manages element properties and attributes. When
* properties change, the `update` method is asynchronously called. This method
* should be supplied by subclassers to render updates as desired.
*/
class UpdatingElement extends HTMLElement {
constructor() {
super();
this._updateState = 0;
this._instanceProperties = undefined;
// Initialize to an unresolved Promise so we can make sure the element has
// connected before first update.
this._updatePromise = new Promise((res) => this._enableUpdatingResolver = res);
/**
* Map with keys for any properties that have changed since the last
* update cycle with previous values.
*/
this._changedProperties = new Map();
/**
* Map with keys of properties that should be reflected when updated.
*/
this._reflectingProperties = undefined;
this.initialize();
}
/**
* Returns a list of attributes corresponding to the registered properties.
* @nocollapse
*/
static get observedAttributes() {
// note: piggy backing on this to ensure we're finalized.
this.finalize();
const attributes = [];
// Use forEach so this works even if for/of loops are compiled to for loops
// expecting arrays
this._classProperties.forEach((v, p) => {
const attr = this._attributeNameForProperty(p, v);
if (attr !== undefined) {
this._attributeToPropertyMap.set(attr, p);
attributes.push(attr);
}
});
return attributes;
}
/**
* Ensures the private `_classProperties` property metadata is created.
* In addition to `finalize` this is also called in `createProperty` to
* ensure the `@property` decorator can add property metadata.
*/
/** @nocollapse */
static _ensureClassProperties() {
// ensure private storage for property declarations.
if (!this.hasOwnProperty(JSCompiler_renameProperty('_classProperties', this))) {
this._classProperties = new Map();
// NOTE: Workaround IE11 not supporting Map constructor argument.
const superProperties = Object.getPrototypeOf(this)._classProperties;
if (superProperties !== undefined) {
superProperties.forEach((v, k) => this._classProperties.set(k, v));
}
}
}
/**
* Creates a property accessor on the element prototype if one does not exist
* and stores a PropertyDeclaration for the property with the given options.
* The property setter calls the property's `hasChanged` property option
* or uses a strict identity check to determine whether or not to request
* an update.
*
* This method may be overridden to customize properties; however,
* when doing so, it's important to call `super.createProperty` to ensure
* the property is setup correctly. This method calls
* `getPropertyDescriptor` internally to get a descriptor to install.
* To customize what properties do when they are get or set, override
* `getPropertyDescriptor`. To customize the options for a property,
* implement `createProperty` like this:
*
* static createProperty(name, options) {
* options = Object.assign(options, {myOption: true});
* super.createProperty(name, options);
* }
*
* @nocollapse
*/
static createProperty(name, options = defaultPropertyDeclaration) {
// Note, since this can be called by the `@property` decorator which
// is called before `finalize`, we ensure storage exists for property
// metadata.
this._ensureClassProperties();
this._classProperties.set(name, options);
// Do not generate an accessor if the prototype already has one, since
// it would be lost otherwise and that would never be the user's intention;
// Instead, we expect users to call `requestUpdate` themselves from
// user-defined accessors. Note that if the super has an accessor we will
// still overwrite it
if (options.noAccessor || this.prototype.hasOwnProperty(name)) {
return;
}
const key = typeof name === 'symbol' ? Symbol() : `__${name}`;
const descriptor = this.getPropertyDescriptor(name, key, options);
if (descriptor !== undefined) {
Object.defineProperty(this.prototype, name, descriptor);
}
}
/**
* Returns a property descriptor to be defined on the given named property.
* If no descriptor is returned, the property will not become an accessor.
* For example,
*
* class MyElement extends LitElement {
* static getPropertyDescriptor(name, key, options) {
* const defaultDescriptor =
* super.getPropertyDescriptor(name, key, options);
* const setter = defaultDescriptor.set;
* return {
* get: defaultDescriptor.get,
* set(value) {
* setter.call(this, value);
* // custom action.
* },
* configurable: true,
* enumerable: true
* }
* }
* }
*
* @nocollapse
*/
static getPropertyDescriptor(name, key, _options) {
return {
// tslint:disable-next-line:no-any no symbol in index
get() {
return this[key];
},
set(value) {
const oldValue = this[name];
this[key] = value;
this._requestUpdate(name, oldValue);
},
configurable: true,
enumerable: true
};
}
/**
* Returns the property options associated with the given property.
* These options are defined with a PropertyDeclaration via the `properties`
* object or the `@property` decorator and are registered in
* `createProperty(...)`.
*
* Note, this method should be considered "final" and not overridden. To
* customize the options for a given property, override `createProperty`.
*
* @nocollapse
* @final
*/
static getPropertyOptions(name) {
return this._classProperties && this._classProperties.get(name) ||
defaultPropertyDeclaration;
}
/**
* Creates property accessors for registered properties and ensures
* any superclasses are also finalized.
* @nocollapse
*/
static finalize() {
// finalize any superclasses
const superCtor = Object.getPrototypeOf(this);
if (!superCtor.hasOwnProperty(finalized)) {
superCtor.finalize();
}
this[finalized] = true;
this._ensureClassProperties();
// initialize Map populated in observedAttributes
this._attributeToPropertyMap = new Map();
// make any properties
// Note, only process "own" properties since this element will inherit
// any properties defined on the superClass, and finalization ensures
// the entire prototype chain is finalized.
if (this.hasOwnProperty(JSCompiler_renameProperty('properties', this))) {
const props = this.properties;
// support symbols in properties (IE11 does not support this)
const propKeys = [
...Object.getOwnPropertyNames(props),
...(typeof Object.getOwnPropertySymbols === 'function') ?
Object.getOwnPropertySymbols(props) :
[]
];
// This for/of is ok because propKeys is an array
for (const p of propKeys) {
// note, use of `any` is due to TypeSript lack of support for symbol in
// index types
// tslint:disable-next-line:no-any no symbol in index
this.createProperty(p, props[p]);
}
}
}
/**
* Returns the property name for the given attribute `name`.
* @nocollapse
*/
static _attributeNameForProperty(name, options) {
const attribute = options.attribute;
return attribute === false ?
undefined :
(typeof attribute === 'string' ?
attribute :
(typeof name === 'string' ? name.toLowerCase() : undefined));
}
/**
* Returns true if a property should request an update.
* Called when a property value is set and uses the `hasChanged`
* option for the property if present or a strict identity check.
* @nocollapse
*/
static _valueHasChanged(value, old, hasChanged = notEqual) {
return hasChanged(value, old);
}
/**
* Returns the property value for the given attribute value.
* Called via the `attributeChangedCallback` and uses the property's
* `converter` or `converter.fromAttribute` property option.
* @nocollapse
*/
static _propertyValueFromAttribute(value, options) {
const type = options.type;
const converter = options.converter || defaultConverter;
const fromAttribute = (typeof converter === 'function' ? converter : converter.fromAttribute);
return fromAttribute ? fromAttribute(value, type) : value;
}
/**
* Returns the attribute value for the given property value. If this
* returns undefined, the property will *not* be reflected to an attribute.
* If this returns null, the attribute will be removed, otherwise the
* attribute will be set to the value.
* This uses the property's `reflect` and `type.toAttribute` property options.
* @nocollapse
*/
static _propertyValueToAttribute(value, options) {
if (options.reflect === undefined) {
return;
}
const type = options.type;
const converter = options.converter;
const toAttribute = converter && converter.toAttribute ||
defaultConverter.toAttribute;
return toAttribute(value, type);
}
/**
* Performs element initialization. By default captures any pre-set values for
* registered properties.
*/
initialize() {
this._saveInstanceProperties();
// ensures first update will be caught by an early access of
// `updateComplete`
this._requestUpdate();
}
/**
* Fixes any properties set on the instance before upgrade time.
* Otherwise these would shadow the accessor and break these properties.
* The properties are stored in a Map which is played back after the
* constructor runs. Note, on very old versions of Safari (<=9) or Chrome
* (<=41), properties created for native platform properties like (`id` or
* `name`) may not have default values set in the element constructor. On
* these browsers native properties appear on instances and therefore their
* default value will overwrite any element default (e.g. if the element sets
* this.id = 'id' in the constructor, the 'id' will become '' since this is
* the native platform default).
*/
_saveInstanceProperties() {
// Use forEach so this works even if for/of loops are compiled to for loops
// expecting arrays
this.constructor
._classProperties.forEach((_v, p) => {
if (this.hasOwnProperty(p)) {
const value = this[p];
delete this[p];
if (!this._instanceProperties) {
this._instanceProperties = new Map();
}
this._instanceProperties.set(p, value);
}
});
}
/**
* Applies previously saved instance properties.
*/
_applyInstanceProperties() {
// Use forEach so this works even if for/of loops are compiled to for loops
// expecting arrays
// tslint:disable-next-line:no-any
this._instanceProperties.forEach((v, p) => this[p] = v);
this._instanceProperties = undefined;
}
connectedCallback() {
// Ensure first connection completes an update. Updates cannot complete
// before connection.
this.enableUpdating();
}
enableUpdating() {
if (this._enableUpdatingResolver !== undefined) {
this._enableUpdatingResolver();
this._enableUpdatingResolver = undefined;
}
}
/**
* Allows for `super.disconnectedCallback()` in extensions while
* reserving the possibility of making non-breaking feature additions
* when disconnecting at some point in the future.
*/
disconnectedCallback() {
}
/**
* Synchronizes property values when attributes change.
*/
attributeChangedCallback(name, old, value) {
if (old !== value) {
this._attributeToProperty(name, value);
}
}
_propertyToAttribute(name, value, options = defaultPropertyDeclaration) {
const ctor = this.constructor;
const attr = ctor._attributeNameForProperty(name, options);
if (attr !== undefined) {
const attrValue = ctor._propertyValueToAttribute(value, options);
// an undefined value does not change the attribute.
if (attrValue === undefined) {
return;
}
// Track if the property is being reflected to avoid
// setting the property again via `attributeChangedCallback`. Note:
// 1. this takes advantage of the fact that the callback is synchronous.
// 2. will behave incorrectly if multiple attributes are in the reaction
// stack at time of calling. However, since we process attributes
// in `update` this should not be possible (or an extreme corner case
// that we'd like to discover).
// mark state reflecting
this._updateState = this._updateState | STATE_IS_REFLECTING_TO_ATTRIBUTE;
if (attrValue == null) {
this.removeAttribute(attr);
}
else {
this.setAttribute(attr, attrValue);
}
// mark state not reflecting
this._updateState = this._updateState & ~STATE_IS_REFLECTING_TO_ATTRIBUTE;
}
}
_attributeToProperty(name, value) {
// Use tracking info to avoid deserializing attribute value if it was
// just set from a property setter.
if (this._updateState & STATE_IS_REFLECTING_TO_ATTRIBUTE) {
return;
}
const ctor = this.constructor;
// Note, hint this as an `AttributeMap` so closure clearly understands
// the type; it has issues with tracking types through statics
// tslint:disable-next-line:no-unnecessary-type-assertion
const propName = ctor._attributeToPropertyMap.get(name);
if (propName !== undefined) {
const options = ctor.getPropertyOptions(propName);
// mark state reflecting
this._updateState = this._updateState | STATE_IS_REFLECTING_TO_PROPERTY;
this[propName] =
// tslint:disable-next-line:no-any
ctor._propertyValueFromAttribute(value, options);
// mark state not reflecting
this._updateState = this._updateState & ~STATE_IS_REFLECTING_TO_PROPERTY;
}
}
/**
* This private version of `requestUpdate` does not access or return the
* `updateComplete` promise. This promise can be overridden and is therefore
* not free to access.
*/
_requestUpdate(name, oldValue) {
let shouldRequestUpdate = true;
// If we have a property key, perform property update steps.
if (name !== undefined) {
const ctor = this.constructor;
const options = ctor.getPropertyOptions(name);
if (ctor._valueHasChanged(this[name], oldValue, options.hasChanged)) {
if (!this._changedProperties.has(name)) {
this._changedProperties.set(name, oldValue);
}
// Add to reflecting properties set.
// Note, it's important that every change has a chance to add the
// property to `_reflectingProperties`. This ensures setting
// attribute + property reflects correctly.
if (options.reflect === true &&
!(this._updateState & STATE_IS_REFLECTING_TO_PROPERTY)) {
if (this._reflectingProperties === undefined) {
this._reflectingProperties = new Map();
}
this._reflectingProperties.set(name, options);
}
}
else {
// Abort the request if the property should not be considered changed.
shouldRequestUpdate = false;
}
}
if (!this._hasRequestedUpdate && shouldRequestUpdate) {
this._updatePromise = this._enqueueUpdate();
}
}
/**
* Requests an update which is processed asynchronously. This should
* be called when an element should update based on some state not triggered
* by setting a property. In this case, pass no arguments. It should also be
* called when manually implementing a property setter. In this case, pass the
* property `name` and `oldValue` to ensure that any configured property
* options are honored. Returns the `updateComplete` Promise which is resolved
* when the update completes.
*
* @param name {PropertyKey} (optional) name of requesting property
* @param oldValue {any} (optional) old value of requesting property
* @returns {Promise} A Promise that is resolved when the update completes.
*/
requestUpdate(name, oldValue) {
this._requestUpdate(name, oldValue);
return this.updateComplete;
}
/**
* Sets up the element to asynchronously update.
*/
async _enqueueUpdate() {
this._updateState = this._updateState | STATE_UPDATE_REQUESTED;
try {
// Ensure any previous update has resolved before updating.
// This `await` also ensures that property changes are batched.
await this._updatePromise;
}
catch (e) {
// Ignore any previous errors. We only care that the previous cycle is
// done. Any error should have been handled in the previous update.
}
const result = this.performUpdate();
// If `performUpdate` returns a Promise, we await it. This is done to
// enable coordinating updates with a scheduler. Note, the result is
// checked to avoid delaying an additional microtask unless we need to.
if (result != null) {
await result;
}
return !this._hasRequestedUpdate;
}
get _hasRequestedUpdate() {
return (this._updateState & STATE_UPDATE_REQUESTED);
}
get hasUpdated() {
return (this._updateState & STATE_HAS_UPDATED);
}
/**
* Performs an element update. Note, if an exception is thrown during the
* update, `firstUpdated` and `updated` will not be called.
*
* You can override this method to change the timing of updates. If this
* method is overridden, `super.performUpdate()` must be called.
*
* For instance, to schedule updates to occur just before the next frame:
*
* ```
* protected async performUpdate(): Promise<unknown> {
* await new Promise((resolve) => requestAnimationFrame(() => resolve()));
* super.performUpdate();
* }
* ```
*/
performUpdate() {
// Mixin instance properties once, if they exist.
if (this._instanceProperties) {
this._applyInstanceProperties();
}
let shouldUpdate = false;
const changedProperties = this._changedProperties;
try {
shouldUpdate = this.shouldUpdate(changedProperties);
if (shouldUpdate) {
this.update(changedProperties);
}
else {
this._markUpdated();
}
}
catch (e) {
// Prevent `firstUpdated` and `updated` from running when there's an
// update exception.
shouldUpdate = false;
// Ensure element can accept additional updates after an exception.
this._markUpdated();
throw e;
}
if (shouldUpdate) {
if (!(this._updateState & STATE_HAS_UPDATED)) {
this._updateState = this._updateState | STATE_HAS_UPDATED;
this.firstUpdated(changedProperties);
}
this.updated(changedProperties);
}
}
_markUpdated() {
this._changedProperties = new Map();
this._updateState = this._updateState & ~STATE_UPDATE_REQUESTED;
}
/**
* Returns a Promise that resolves when the element has completed updating.
* The Promise value is a boolean that is `true` if the element completed the
* update without triggering another update. The Promise result is `false` if
* a property was set inside `updated()`. If the Promise is rejected, an
* exception was thrown during the update.
*
* To await additional asynchronous work, override the `_getUpdateComplete`
* method. For example, it is sometimes useful to await a rendered element
* before fulfilling this Promise. To do this, first await
* `super._getUpdateComplete()`, then any subsequent state.
*
* @returns {Promise} The Promise returns a boolean that indicates if the
* update resolved without triggering another update.
*/
get updateComplete() {
return this._getUpdateComplete();
}
/**
* Override point for the `updateComplete` promise.
*
* It is not safe to override the `updateComplete` getter directly due to a
* limitation in TypeScript which means it is not possible to call a
* superclass getter (e.g. `super.updateComplete.then(...)`) when the target
* language is ES5 (https://github.com/microsoft/TypeScript/issues/338).
* This method should be overridden instead. For example:
*
* class MyElement extends LitElement {
* async _getUpdateComplete() {
* await super._getUpdateComplete();
* await this._myChild.updateComplete;
* }
* }
*/
_getUpdateComplete() {
return this._updatePromise;
}
/**
* Controls whether or not `update` should be called when the element requests
* an update. By default, this method always returns `true`, but this can be
* customized to control when to update.
*
* @param _changedProperties Map of changed properties with old values
*/
shouldUpdate(_changedProperties) {
return true;
}
/**
* Updates the element. This method reflects property values to attributes.
* It can be overridden to render and keep updated element DOM.
* Setting properties inside this method will *not* trigger
* another update.
*
* @param _changedProperties Map of changed properties with old values
*/
update(_changedProperties) {
if (this._reflectingProperties !== undefined &&
this._reflectingProperties.size > 0) {
// Use forEach so this works even if for/of loops are compiled to for
// loops expecting arrays
this._reflectingProperties.forEach((v, k) => this._propertyToAttribute(k, this[k], v));
this._reflectingProperties = undefined;
}
this._markUpdated();
}
/**
* Invoked whenever the element is updated. Implement to perform
* post-updating tasks via DOM APIs, for example, focusing an element.
*
* Setting properties inside this method will trigger the element to update
* again after this update cycle completes.
*
* @param _changedProperties Map of changed properties with old values
*/
updated(_changedProperties) {
}
/**
* Invoked when the element is first updated. Implement to perform one time
* work on the element after update.
*
* Setting properties inside this method will trigger the element to update
* again after this update cycle completes.
*
* @param _changedProperties Map of changed properties with old values
*/
firstUpdated(_changedProperties) {
}
}
_a$1 = finalized;
/**
* Marks class as having finished creating properties.
*/
UpdatingElement[_a$1] = true;
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
const legacyCustomElement = (tagName, clazz) => {
window.customElements.define(tagName, clazz);
// Cast as any because TS doesn't recognize the return type as being a
// subtype of the decorated class when clazz is typed as
// `Constructor<HTMLElement>` for some reason.
// `Constructor<HTMLElement>` is helpful to make sure the decorator is
// applied to elements however.
// tslint:disable-next-line:no-any
return clazz;
};
const standardCustomElement = (tagName, descriptor) => {
const { kind, elements } = descriptor;
return {
kind,
elements,
// This callback is called once the class is otherwise fully defined
finisher(clazz) {
window.customElements.define(tagName, clazz);
}
};
};
/**
* Class decorator factory that defines the decorated class as a custom element.
*
* ```
* @customElement('my-element')
* class MyElement {
* render() {
* return html``;
* }
* }
* ```
*
* @param tagName The name of the custom element to define.
*/
const customElement = (tagName) => (classOrDescriptor) => (typeof classOrDescriptor === 'function') ?
legacyCustomElement(tagName, classOrDescriptor) :
standardCustomElement(tagName, classOrDescriptor);
const standardProperty = (options, element) => {
// When decorating an accessor, pass it through and add property metadata.
// Note, the `hasOwnProperty` check in `createProperty` ensures we don't
// stomp over the user's accessor.
if (element.kind === 'method' && element.descriptor &&
!('value' in element.descriptor)) {
return Object.assign(Object.assign({}, element), { finisher(clazz) {
clazz.createProperty(element.key, options);
} });
}
else {
// createProperty() takes care of defining the property, but we still
// must return some kind of descriptor, so return a descriptor for an
// unused prototype field. The finisher calls createProperty().
return {
kind: 'field',
key: Symbol(),
placement: 'own',
descriptor: {},
// When @babel/plugin-proposal-decorators implements initializers,
// do this instead of the initializer below. See:
// https://github.com/babel/babel/issues/9260 extras: [
// {
// kind: 'initializer',
// placement: 'own',
// initializer: descriptor.initializer,
// }
// ],
initializer() {
if (typeof element.initializer === 'function') {
this[element.key] = element.initializer.call(this);
}
},
finisher(clazz) {
clazz.createProperty(element.key, options);
}
};
}
};
const legacyProperty = (options, proto, name) => {
proto.constructor
.createProperty(name, options);
};
/**
* A property decorator which creates a LitElement property which reflects a
* corresponding attribute value. A `PropertyDeclaration` may optionally be
* supplied to configure property features.
*
* This decorator should only be used for public fields. Private or protected
* fields should use the internalProperty decorator.
*
* @example
*
* class MyElement {
* @property({ type: Boolean })
* clicked = false;
* }
*
* @ExportDecoratedItems
*/
function property(options) {
// tslint:disable-next-line:no-any decorator
return (protoOrDescriptor, name) => (name !== undefined) ?
legacyProperty(options, protoOrDescriptor, name) :
standardProperty(options, protoOrDescriptor);
}
/**
* Declares a private or protected property that still triggers updates to the
* element when it changes.
*
* Properties declared this way must not be used from HTML or HTML templating
* systems, they're solely for properties internal to the element. These
* properties may be renamed by optimization tools like closure compiler.
*/
function internalProperty(options) {
return property({ attribute: false, hasChanged: options === null || options === void 0 ? void 0 : options.hasChanged });
}
/**
* A property decorator that converts a class property into a getter that
* executes a querySelector on the element's renderRoot.
*
* @param selector A DOMString containing one or more selectors to match.
*
* See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
*
* @example
*
* class MyElement {
* @query('#first')
* first;
*
* render() {
* return html`
* <div id="first"></div>
* <div id="second"></div>
* `;
* }
* }
*
*/
function query(selector) {
return (protoOrDescriptor,
// tslint:disable-next-line:no-any decorator
name) => {
const descriptor = {
get() {
return this.renderRoot.querySelector(selector);
},
enumerable: true,
configurable: true,
};
return (name !== undefined) ?
legacyQuery(descriptor, protoOrDescriptor, name) :
standardQuery(descriptor, protoOrDescriptor);
};
}
// Note, in the future, we may extend this decorator to support the use case
// where the queried element may need to do work to become ready to interact
// with (e.g. load some implementation code). If so, we might elect to
// add a second argument defining a function that can be run to make the
// queried element loaded/updated/ready.
/**
* A property decorator that converts a class property into a getter that
* returns a promise that resolves to the result of a querySelector on the
* element's renderRoot done after the element's `updateComplete` promise
* resolves. When the queried property may change with element state, this
* decorator can be used instead of requiring users to await the
* `updateComplete` before accessing the property.
*
* @param selector A DOMString containing one or more selectors to match.
*
* See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
*
* @example
*
* class MyElement {
* @queryAsync('#first')
* first;
*
* render() {
* return html`
* <div id="first"></div>
* <div id="second"></div>
* `;
* }
* }
*
* // external usage
* async doSomethingWithFirst() {
* (await aMyElement.first).doSomething();
* }
*/
function queryAsync(selector) {
return (protoOrDescriptor,
// tslint:disable-next-line:no-any decorator
name) => {
const descriptor = {
async get() {
await this.updateComplete;
return this.renderRoot.querySelector(selector);
},
enumerable: true,
configurable: true,
};
return (name !== undefined) ?
legacyQuery(descriptor, protoOrDescriptor, name) :
standardQuery(descriptor, protoOrDescriptor);
};
}
/**
* A property decorator that converts a class property into a getter
* that executes a querySelectorAll on the element's renderRoot.
*
* @param selector A DOMString containing one or more selectors to match.
*
* See:
* https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
*
* @example
*
* class MyElement {
* @queryAll('div')
* divs;
*
* render() {
* return html`
* <div id="first"></div>
* <div id="second"></div>
* `;
* }
* }
*/
function queryAll(selector) {
return (protoOrDescriptor,
// tslint:disable-next-line:no-any decorator
name) => {
const descriptor = {
get() {
return this.renderRoot.querySelectorAll(selector);
},
enumerable: true,
configurable: true,
};
return (name !== undefined) ?
legacyQuery(descriptor, protoOrDescriptor, name) :
standardQuery(descriptor, protoOrDescriptor);
};
}
const legacyQuery = (descriptor, proto, name) => {
Object.defineProperty(proto, name, descriptor);
};
const standardQuery = (descriptor, element) => ({
kind: 'method',
placement: 'prototype',
key: element.key,
descriptor,
});
const standardEventOptions = (options, element) => {
return Object.assign(Object.assign({}, element), { finisher(clazz) {
Object.assign(clazz.prototype[element.key], options);
} });
};
const legacyEventOptions =
// tslint:disable-next-line:no-any legacy decorator
(options, proto, name) => {
Object.assign(proto[name], options);
};
/**
* Adds event listener options to a method used as an event listener in a
* lit-html template.
*
* @param options An object that specifies event listener options as accepted by
* `EventTarget#addEventListener` and `EventTarget#removeEventListener`.
*
* Current browsers support the `capture`, `passive`, and `once` options. See:
* https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters
*
* @example
*
* class MyElement {
* clicked = false;
*
* render() {
* return html`
* <div @click=${this._onClick}`>
* <button></button>
* </div>
* `;
* }
*
* @eventOptions({capture: true})
* _onClick(e) {
* this.clicked = true;
* }
* }
*/
function eventOptions(options) {
// Return value typed as any to prevent TypeScript from complaining that
// standard decorator function signature does not match TypeScript decorator
// signature
// TODO(kschaaf): unclear why it was only failing on this decorator and not
// the others
return ((protoOrDescriptor, name) => (name !== undefined) ?
legacyEventOptions(options, protoOrDescriptor, name) :
standardEventOptions(options, protoOrDescriptor));
}
/**
* A property decorator that converts a class property into a getter that
* returns the `assignedNodes` of the given named `slot`. Note, the type of
* this property should be annotated as `NodeListOf<HTMLElement>`.
*
*/
function queryAssignedNodes(slotName = '', flatten = false) {
return (protoOrDescriptor,
// tslint:disable-next-line:no-any decorator
name) => {
const descriptor = {
get() {
const selector = `slot${slotName ? `[name=${slotName}]` : ''}`;
const slot = this.renderRoot.querySelector(selector);
return slot && slot.assignedNodes({ flatten });
},
enumerable: true,
configurable: true,
};
return (name !== undefined) ?
legacyQuery(descriptor, protoOrDescriptor, name) :
standardQuery(descriptor, protoOrDescriptor);
};
}
/**
@license
Copyright (c) 2019 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at
http://polymer.github.io/LICENSE.txt The complete set of authors may be found at
http://polymer.github.io/AUTHORS.txt The complete set of contributors may be
found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as
part of the polymer project is also subject to an additional IP rights grant
found at http://polymer.github.io/PATENTS.txt
*/
const supportsAdoptingStyleSheets = ('adoptedStyleSheets' in Document.prototype) &&
('replace' in CSSStyleSheet.prototype);
const constructionToken = Symbol();
class CSSResult {
constructor(cssText, safeToken) {
if (safeToken !== constructionToken) {
throw new Error('CSSResult is not constructable. Use `unsafeCSS` or `css` instead.');
}
this.cssText = cssText;
}
// Note, this is a getter so that it's lazy. In practice, this means
// stylesheets are not created until the first element instance is made.
get styleSheet() {
if (this._styleSheet === undefined) {
// Note, if `adoptedStyleSheets` is supported then we assume CSSStyleSheet
// is constructable.
if (supportsAdoptingStyleSheets) {
this._styleSheet = new CSSStyleSheet();
this._styleSheet.replaceSync(this.cssText);
}
else {
this._styleSheet = null;
}
}
return this._styleSheet;
}
toString() {
return this.cssText;
}
}
/**
* Wrap a value for interpolation in a css tagged template literal.
*
* This is unsafe because untrusted CSS text can be used to phone home
* or exfiltrate data to an attacker controlled site. Take care to only use
* this with trusted input.
*/
const unsafeCSS = (value) => {
return new CSSResult(String(value), constructionToken);
};
const textFromCSSResult = (value) => {
if (value instanceof CSSResult) {
return value.cssText;
}
else if (typeof value === 'number') {
return value;
}
else {
throw new Error(`Value passed to 'css' function must be a 'css' function result: ${value}. Use 'unsafeCSS' to pass non-literal values, but
take care to ensure page security.`);
}
};
/**
* Template tag which which can be used with LitElement's `style` property to
* set element styles. For security reasons, only literal string values may be
* used. To incorporate non-literal values `unsafeCSS` may be used inside a
* template string part.
*/
const css = (strings, ...values) => {
const cssText = values.reduce((acc, v, idx) => acc + textFromCSSResult(v) + strings[idx + 1], strings[0]);
return new CSSResult(cssText, constructionToken);
};
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
// IMPORTANT: do not change the property name or the assignment expression.
// This line will be used in regexes to search for LitElement usage.
// TODO(justinfagnani): inject version number at build time
(window['litElementVersions'] || (window['litElementVersions'] = []))
.push('2.3.1');
/**
* Sentinal value used to avoid calling lit-html's render function when
* subclasses do not implement `render`
*/
const renderNotImplemented = {};
class LitElement extends UpdatingElement {
/**
* Return the array of styles to apply to the element.
* Override this method to integrate into a style management system.
*
* @nocollapse
*/
static getStyles() {
return this.styles;
}
/** @nocollapse */
static _getUniqueStyles() {
// Only gather styles once per class
if (this.hasOwnProperty(JSCompiler_renameProperty('_styles', this))) {
return;
}
// Take care not to call `this.getStyles()` multiple times since this
// generates new CSSResults each time.
// TODO(sorvell): Since we do not cache CSSResults by input, any
// shared styles will generate new stylesheet objects, which is wasteful.
// This should be addressed when a browser ships constructable
// stylesheets.
const userStyles = this.getStyles();
if (userStyles === undefined) {
this._styles = [];
}
else if (Array.isArray(userStyles)) {
// De-duplicate styles preserving the _last_ instance in the set.
// This is a performance optimization to avoid duplicated styles that can
// occur especially when composing via subclassing.
// The last item is kept to try to preserve the cascade order with the
// assumption that it's most important that last added styles override
// previous styles.
const addStyles = (styles, set) => styles.reduceRight((set, s) =>
// Note: On IE set.add() does not return the set
Array.isArray(s) ? addStyles(s, set) : (set.add(s), set), set);
// Array.from does not work on Set in IE, otherwise return
// Array.from(addStyles(userStyles, new Set<CSSResult>())).reverse()
const set = addStyles(userStyles, new Set());
const styles = [];
set.forEach((v) => styles.unshift(v));
this._styles = styles;
}
else {
this._styles = [userStyles];
}
}
/**
* Performs element initialization. By default this calls `createRenderRoot`
* to create the element `renderRoot` node and captures any pre-set values for
* registered properties.
*/
initialize() {
super.initialize();
this.constructor._getUniqueStyles();
this.renderRoot =
this.createRenderRoot();
// Note, if renderRoot is not a shadowRoot, styles would/could apply to the
// element's getRootNode(). While this could be done, we're choosing not to
// support this now since it would require different logic around de-duping.
if (window.ShadowRoot && this.renderRoot instanceof window.ShadowRoot) {
this.adoptStyles();
}
}
/**
* Returns the node into which the element should render and by default
* creates and returns an open shadowRoot. Implement to customize where the
* element's DOM is rendered. For example, to render into the element's
* childNodes, return `this`.
* @returns {Element|DocumentFragment} Returns a node into which to render.
*/
createRenderRoot() {
return this.attachShadow({ mode: 'open' });
}
/**
* Applies styling to the element shadowRoot using the `static get styles`
* property. Styling will apply using `shadowRoot.adoptedStyleSheets` where
* available and will fallback otherwise. When Shadow DOM is polyfilled,
* ShadyCSS scopes styles and adds them to the document. When Shadow DOM
* is available but `adoptedStyleSheets` is not, styles are appended to the
* end of the `shadowRoot` to [mimic spec
* behavior](https://wicg.github.io/construct-stylesheets/#using-constructed-stylesheets).
*/
adoptStyles() {
const styles = this.constructor._styles;
if (styles.length === 0) {
return;
}
// There are three separate cases here based on Shadow DOM support.
// (1) shadowRoot polyfilled: use ShadyCSS
// (2) shadowRoot.adoptedStyleSheets available: use it.
// (3) shadowRoot.adoptedStyleSheets polyfilled: append styles after
// rendering
if (window.ShadyCSS !== undefined && !window.ShadyCSS.nativeShadow) {
window.ShadyCSS.ScopingShim.prepareAdoptedCssText(styles.map((s) => s.cssText), this.localName);
}
else if (supportsAdoptingStyleSheets) {
this.renderRoot.adoptedStyleSheets =
styles.map((s) => s.styleSheet);
}
else {
// This must be done after rendering so the actual style insertion is done
// in `update`.
this._needsShimAdoptedStyleSheets = true;
}
}
connectedCallback() {
super.connectedCallback();
// Note, first update/render handles styleElement so we only call this if
// connected after first update.
if (this.hasUpdated && window.ShadyCSS !== undefined) {
window.ShadyCSS.styleElement(this);
}
}
/**
* Updates the element. This method reflects property values to attributes
* and calls `render` to render DOM via lit-html. Setting properties inside
* this method will *not* trigger another update.
* @param _changedProperties Map of changed properties with old values
*/
update(changedProperties) {
// Setting properties in `render` should not trigger an update. Since
// updates are allowed after super.update, it's important to call `render`
// before that.
const templateResult = this.render();
super.update(changedProperties);
// If render is not implemented by the component, don't call lit-html render
if (templateResult !== renderNotImplemented) {
this.constructor
.render(templateResult, this.renderRoot, { scopeName: this.localName, eventContext: this });
}
// When native Shadow DOM is used but adoptedStyles are not supported,
// insert styling after rendering to ensure adoptedStyles have highest
// priority.
if (this._needsShimAdoptedStyleSheets) {
this._needsShimAdoptedStyleSheets = false;
this.constructor._styles.forEach((s) => {
const style = document.createElement('style');
style.textContent = s.cssText;
this.renderRoot.appendChild(style);
});
}
}
/**
* Invoked on each update to perform rendering tasks. This method may return
* any value renderable by lit-html's NodePart - typically a TemplateResult.
* Setting properties inside this method will *not* trigger the element to
* update.
*/
render() {
return renderNotImplemented;
}
}
/**
* Ensure this class is marked as `finalized` as an optimization ensuring
* it will not needlessly try to `finalize`.
*
* Note this property name is a string to prevent breaking Closure JS Compiler
* optimizations. See updating-element.ts for more information.
*/
LitElement['finalized'] = true;
/**
* Render method used to render the value to the element's DOM.
* @param result The value to render.
* @param container Node into which to render.
* @param options Element name.
* @nocollapse
*/
LitElement.render = render$1;
/**
* @license
* Copyright (c) 2018 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
// IE11 doesn't support classList on SVG elements, so we emulate it with a Set
class ClassList {
constructor(element) {
this.classes = new Set();
this.changed = false;
this.element = element;
const classList = (element.getAttribute('class') || '').split(/\s+/);
for (const cls of classList) {
this.classes.add(cls);
}
}
add(cls) {
this.classes.add(cls);
this.changed = true;
}
remove(cls) {
this.classes.delete(cls);
this.changed = true;
}
commit() {
if (this.changed) {
let classString = '';
this.classes.forEach((cls) => classString += cls + ' ');
this.element.setAttribute('class', classString);
}
}
}
/**
* Stores the ClassInfo object applied to a given AttributePart.
* Used to unset existing values when a new ClassInfo object is applied.
*/
const previousClassesCache = new WeakMap();
/**
* A directive that applies CSS classes. This must be used in the `class`
* attribute and must be the only part used in the attribute. It takes each
* property in the `classInfo` argument and adds the property name to the
* element's `class` if the property value is truthy; if the property value is
* falsey, the property name is removed from the element's `class`. For example
* `{foo: bar}` applies the class `foo` if the value of `bar` is truthy.
* @param classInfo {ClassInfo}
*/
const classMap = directive((classInfo) => (part) => {
if (!(part instanceof AttributePart) || (part instanceof PropertyPart) ||
part.committer.name !== 'class' || part.committer.parts.length > 1) {
throw new Error('The `classMap` directive must be used in the `class` attribute ' +
'and must be the only part in the attribute.');
}
const { committer } = part;
const { element } = committer;
let previousClasses = previousClassesCache.get(part);
if (previousClasses === undefined) {
// Write static classes once
// Use setAttribute() because className isn't a string on SVG elements
element.setAttribute('class', committer.strings.join(' '));
previousClassesCache.set(part, previousClasses = new Set());
}
const classList = (element.classList || new ClassList(element));
// Remove old classes that no longer apply
// We use forEach() instead of for-of so that re don't require down-level
// iteration.
previousClasses.forEach((name) => {
if (!(name in classInfo)) {
classList.remove(name);
previousClasses.delete(name);
}
});
// Add or remove classes based on their classMap value
for (const name in classInfo) {
const value = classInfo[name];
if (value != previousClasses.has(name)) {
// We explicitly want a loose truthy check of `value` because it seems
// more convenient that '' and 0 are skipped.
if (value) {
classList.add(name);
previousClasses.add(name);
}
else {
classList.remove(name);
previousClasses.delete(name);
}
}
}
if (typeof classList.commit === 'function') {
classList.commit();
}
});
/**
* @license
* Copyright (c) 2018 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
const previousValues = new WeakMap();
/**
* For AttributeParts, sets the attribute if the value is defined and removes
* the attribute if the value is undefined.
*
* For other part types, this directive is a no-op.
*/
const ifDefined = directive((value) => (part) => {
const previousValue = previousValues.get(part);
if (value === undefined && part instanceof AttributePart) {
// If the value is undefined, remove the attribute, but only if the value
// was previously defined.
if (previousValue !== undefined || !previousValues.has(part)) {
const name = part.committer.name;
part.committer.element.removeAttribute(name);
}
}
else if (value !== previousValue) {
part.setValue(value);
}
previousValues.set(part, value);
});
/**
* @license
* Copyright (c) 2018 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
/**
* Stores the StyleInfo object applied to a given AttributePart.
* Used to unset existing values when a new StyleInfo object is applied.
*/
const previousStylePropertyCache = new WeakMap();
/**
* A directive that applies CSS properties to an element.
*
* `styleMap` can only be used in the `style` attribute and must be the only
* expression in the attribute. It takes the property names in the `styleInfo`
* object and adds the property values as CSS properties. Property names with
* dashes (`-`) are assumed to be valid CSS property names and set on the
* element's style object using `setProperty()`. Names without dashes are
* assumed to be camelCased JavaScript property names and set on the element's
* style object using property assignment, allowing the style object to
* translate JavaScript-style names to CSS property names.
*
* For example `styleMap({backgroundColor: 'red', 'border-top': '5px', '--size':
* '0'})` sets the `background-color`, `border-top` and `--size` properties.
*
* @param styleInfo {StyleInfo}
*/
const styleMap = directive((styleInfo) => (part) => {
if (!(part instanceof AttributePart) || (part instanceof PropertyPart) ||
part.committer.name !== 'style' || part.committer.parts.length > 1) {
throw new Error('The `styleMap` directive must be used in the style attribute ' +
'and must be the only part in the attribute.');
}
const { committer } = part;
const { style } = committer.element;
let previousStyleProperties = previousStylePropertyCache.get(part);
if (previousStyleProperties === undefined) {
// Write static styles once
style.cssText = committer.strings.join(' ');
previousStylePropertyCache.set(part, previousStyleProperties = new Set());
}
// Remove old properties that no longer exist in styleInfo
// We use forEach() instead of for-of so that re don't require down-level
// iteration.
previousStyleProperties.forEach((name) => {
if (!(name in styleInfo)) {
previousStyleProperties.delete(name);
if (name.indexOf('-') === -1) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
style[name] = null;
}
else {
style.removeProperty(name);
}
}
});
// Add or update properties
for (const name in styleInfo) {
previousStyleProperties.add(name);
if (name.indexOf('-') === -1) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
style[name] = styleInfo[name];
}
else {
style.setProperty(name, styleInfo[name]);
}
}
});
/** @soyCompatible */
class CircularProgressBase extends LitElement {
constructor() {
super(...arguments);
this.indeterminate = false;
this.progress = 0;
this.density = 0;
this.closed = false;
this.ariaLabel = '';
this.containerSideLength = 0;
this.circleRadius = 0;
this.determinateStrokeDashOffset = 0;
this.strokeWidth = 0;
}
open() {
this.closed = false;
}
close() {
this.closed = true;
}
/**
* @soyCompatible
*/
render() {
/** @classMap */
const classes = {
'mdc-circular-progress--closed': this.closed,
'mdc-circular-progress--indeterminate': this.indeterminate,
};
const styles = {
'width': `${this.containerSideLength}px`,
'height': `${this.containerSideLength}px`,
};
return html `
<div
class="mdc-circular-progress ${classMap(classes)}"
style="${styleMap(styles)}"
role="progressbar"
aria-label="${this.ariaLabel}"
aria-valuemin="0"
aria-valuemax="1"
aria-valuenow="${ifDefined(this.indeterminate ? undefined : this.progress)}">
${this.renderDeterminateContainer()}
${this.renderIndeterminateContainer()}
</div>`;
}
/**
* @soyCompatible
*/
renderDeterminateContainer() {
const center = this.containerSideLength / 2;
return html `
<div class="mdc-circular-progress__determinate-container">
<svg class="mdc-circular-progress__determinate-circle-graphic"
viewBox="0 0 ${this.containerSideLength} ${this.containerSideLength}">
<circle class="mdc-circular-progress__determinate-circle"
cx="${center}" cy="${center}" r="${this.circleRadius}"
stroke-dasharray="${2 * 3.1415926 * this.circleRadius}"
stroke-dashoffset="${this.determinateStrokeDashOffset}"
stroke-width="${this.strokeWidth}"></circle>
</svg>
</div>`;
}
/**
* @soyCompatible
*/
renderIndeterminateContainer() {
return html `
<div class="mdc-circular-progress__indeterminate-container">
${this.renderIndeterminateSpinnerLayer()}
</div>`;
}
/**
* @soyCompatible
*/
renderIndeterminateSpinnerLayer(classes = '') {
const center = this.containerSideLength / 2;
const circumference = 2 * 3.1415926 * this.circleRadius;
const halfCircumference = 0.5 * circumference;
return html `
<div class="mdc-circular-progress__spinner-layer ${classes}">
<div class="mdc-circular-progress__circle-clipper mdc-circular-progress__circle-left">
<svg class="mdc-circular-progress__indeterminate-circle-graphic"
viewBox="0 0 ${this.containerSideLength} ${this.containerSideLength}">
<circle cx="${center}" cy="${center}" r="${this.circleRadius}"
stroke-dasharray="${circumference}"
stroke-dashoffset="${halfCircumference}"
stroke-width="${this.strokeWidth}"></circle>
</svg>
</div><div class="mdc-circular-progress__gap-patch">
<svg class="mdc-circular-progress__indeterminate-circle-graphic"
viewBox="0 0 ${this.containerSideLength} ${this.containerSideLength}">
<circle cx="${center}" cy="${center}" r="${this.circleRadius}"
stroke-dasharray="${circumference}"
stroke-dashoffset="${halfCircumference}"
stroke-width="${this.strokeWidth * 0.8}"></circle>
</svg>
</div><div class="mdc-circular-progress__circle-clipper mdc-circular-progress__circle-right">
<svg class="mdc-circular-progress__indeterminate-circle-graphic"
viewBox="0 0 ${this.containerSideLength} ${this.containerSideLength}">
<circle cx="${center}" cy="${center}" r="${this.circleRadius}"
stroke-dasharray="${circumference}"
stroke-dashoffset="${halfCircumference}"
stroke-width="${this.strokeWidth}"></circle>
</svg>
</div>
</div>`;
}
update(changedProperties) {
super.update(changedProperties);
this.containerSideLength = this.getContainerSideLength();
this.circleRadius = this.getCircleRadius();
this.determinateStrokeDashOffset = this.getDeterminateStrokeDashOffset();
this.strokeWidth = this.getStrokeWidth();
// Bound progress value in interval [0, 1].
if (changedProperties.has('progress')) {
if (this.progress > 1) {
this.progress = 1;
}
if (this.progress < 0) {
this.progress = 0;
}
}
}
getContainerSideLength() {
return 48 + this.density * 4;
}
getDeterminateStrokeDashOffset() {
const circleRadius = this.getCircleRadius();
const circumference = 2 * 3.1415926 * circleRadius;
return (1 - this.progress) * circumference;
}
getCircleRadius() {
return this.density >= -3 ? 18 + this.density * 11 / 6 :
12.5 + (this.density + 3) * 5 / 4;
}
getStrokeWidth() {
return this.density >= -3 ? 4 + this.density * (1 / 3) :
3 + (this.density + 3) * (1 / 6);
}
}
__decorate([
property({ type: Boolean, reflect: true })
], CircularProgressBase.prototype, "indeterminate", void 0);
__decorate([
property({ type: Number, reflect: true })
], CircularProgressBase.prototype, "progress", void 0);
__decorate([
property({ type: Number, reflect: true })
], CircularProgressBase.prototype, "density", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], CircularProgressBase.prototype, "closed", void 0);
__decorate([
property({ type: String })
], CircularProgressBase.prototype, "ariaLabel", void 0);
__decorate([
internalProperty()
], CircularProgressBase.prototype, "containerSideLength", void 0);
__decorate([
internalProperty()
], CircularProgressBase.prototype, "circleRadius", void 0);
__decorate([
internalProperty()
], CircularProgressBase.prototype, "determinateStrokeDashOffset", void 0);
__decorate([
internalProperty()
], CircularProgressBase.prototype, "strokeWidth", void 0);
/**
@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.
*/
const style = css `.mdc-circular-progress__determinate-circle,.mdc-circular-progress__indeterminate-circle-graphic{stroke:#6200ee;stroke:var(--mdc-theme-primary, #6200ee)}@keyframes mdc-circular-progress-container-rotate{to{transform:rotate(360deg)}}@keyframes mdc-circular-progress-spinner-layer-rotate{12.5%{transform:rotate(135deg)}25%{transform:rotate(270deg)}37.5%{transform:rotate(405deg)}50%{transform:rotate(540deg)}62.5%{transform:rotate(675deg)}75%{transform:rotate(810deg)}87.5%{transform:rotate(945deg)}100%{transform:rotate(1080deg)}}@keyframes mdc-circular-progress-color-1-fade-in-out{from{opacity:.99}25%{opacity:.99}26%{opacity:0}89%{opacity:0}90%{opacity:.99}to{opacity:.99}}@keyframes mdc-circular-progress-color-2-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:.99}50%{opacity:.99}51%{opacity:0}to{opacity:0}}@keyframes mdc-circular-progress-color-3-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:.99}75%{opacity:.99}76%{opacity:0}to{opacity:0}}@keyframes mdc-circular-progress-color-4-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:.99}90%{opacity:.99}to{opacity:0}}@keyframes mdc-circular-progress-left-spin{from{transform:rotate(265deg)}50%{transform:rotate(130deg)}to{transform:rotate(265deg)}}@keyframes mdc-circular-progress-right-spin{from{transform:rotate(-265deg)}50%{transform:rotate(-130deg)}to{transform:rotate(-265deg)}}.mdc-circular-progress{display:inline-block;position:relative;direction:ltr;transition:opacity 250ms 0ms cubic-bezier(0.4, 0, 0.6, 1)}.mdc-circular-progress__determinate-container,.mdc-circular-progress__indeterminate-circle-graphic,.mdc-circular-progress__indeterminate-container,.mdc-circular-progress__spinner-layer{position:absolute;width:100%;height:100%}.mdc-circular-progress__determinate-container{transform:rotate(-90deg)}.mdc-circular-progress__indeterminate-container{opacity:0}.mdc-circular-progress__determinate-circle-graphic,.mdc-circular-progress__indeterminate-circle-graphic{fill:transparent}.mdc-circular-progress__determinate-circle{transition:stroke-dashoffset 500ms 0ms cubic-bezier(0, 0, 0.2, 1)}.mdc-circular-progress__gap-patch{position:absolute;top:0;left:47.5%;box-sizing:border-box;width:5%;height:100%;overflow:hidden}.mdc-circular-progress__gap-patch .mdc-circular-progress__indeterminate-circle-graphic{left:-900%;width:2000%;transform:rotate(180deg)}.mdc-circular-progress__circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden}.mdc-circular-progress__circle-clipper .mdc-circular-progress__indeterminate-circle-graphic{width:200%}.mdc-circular-progress__circle-right .mdc-circular-progress__indeterminate-circle-graphic{left:-100%}.mdc-circular-progress--indeterminate .mdc-circular-progress__determinate-container{opacity:0}.mdc-circular-progress--indeterminate .mdc-circular-progress__indeterminate-container{opacity:1}.mdc-circular-progress--indeterminate .mdc-circular-progress__indeterminate-container{animation:mdc-circular-progress-container-rotate 1568.2352941176ms linear infinite}.mdc-circular-progress--indeterminate .mdc-circular-progress__spinner-layer{animation:mdc-circular-progress-spinner-layer-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--indeterminate .mdc-circular-progress__color-1{animation:mdc-circular-progress-spinner-layer-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,mdc-circular-progress-color-1-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--indeterminate .mdc-circular-progress__color-2{animation:mdc-circular-progress-spinner-layer-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,mdc-circular-progress-color-2-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--indeterminate .mdc-circular-progress__color-3{animation:mdc-circular-progress-spinner-layer-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,mdc-circular-progress-color-3-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--indeterminate .mdc-circular-progress__color-4{animation:mdc-circular-progress-spinner-layer-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,mdc-circular-progress-color-4-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--indeterminate .mdc-circular-progress__circle-left .mdc-circular-progress__indeterminate-circle-graphic{animation:mdc-circular-progress-left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--indeterminate .mdc-circular-progress__circle-right .mdc-circular-progress__indeterminate-circle-graphic{animation:mdc-circular-progress-right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--closed{opacity:0}:host{display:inline-flex}`;
/** @soyCompatible */
exports.CircularProgress = class CircularProgress extends CircularProgressBase {
};
exports.CircularProgress.styles = style;
exports.CircularProgress = __decorate([
customElement('mwc-circular-progress')
], exports.CircularProgress);
/**
@license
Copyright 2020 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.
*/
/** @soyCompatible */
class CircularProgressFourColorBase extends CircularProgressBase {
renderIndeterminateContainer() {
return html `
<div class="mdc-circular-progress__indeterminate-container">
${this.renderIndeterminateSpinnerLayer('mdc-circular-progress__color-1')}
${this.renderIndeterminateSpinnerLayer('mdc-circular-progress__color-2')}
${this.renderIndeterminateSpinnerLayer('mdc-circular-progress__color-3')}
${this.renderIndeterminateSpinnerLayer('mdc-circular-progress__color-4')}
</div>`;
}
}
/**
@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.
*/
const style$1 = css `.mdc-circular-progress__determinate-circle,.mdc-circular-progress__indeterminate-circle-graphic{stroke:#6200ee;stroke:var(--mdc-theme-primary, #6200ee)}@keyframes mdc-circular-progress-container-rotate{to{transform:rotate(360deg)}}@keyframes mdc-circular-progress-spinner-layer-rotate{12.5%{transform:rotate(135deg)}25%{transform:rotate(270deg)}37.5%{transform:rotate(405deg)}50%{transform:rotate(540deg)}62.5%{transform:rotate(675deg)}75%{transform:rotate(810deg)}87.5%{transform:rotate(945deg)}100%{transform:rotate(1080deg)}}@keyframes mdc-circular-progress-color-1-fade-in-out{from{opacity:.99}25%{opacity:.99}26%{opacity:0}89%{opacity:0}90%{opacity:.99}to{opacity:.99}}@keyframes mdc-circular-progress-color-2-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:.99}50%{opacity:.99}51%{opacity:0}to{opacity:0}}@keyframes mdc-circular-progress-color-3-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:.99}75%{opacity:.99}76%{opacity:0}to{opacity:0}}@keyframes mdc-circular-progress-color-4-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:.99}90%{opacity:.99}to{opacity:0}}@keyframes mdc-circular-progress-left-spin{from{transform:rotate(265deg)}50%{transform:rotate(130deg)}to{transform:rotate(265deg)}}@keyframes mdc-circular-progress-right-spin{from{transform:rotate(-265deg)}50%{transform:rotate(-130deg)}to{transform:rotate(-265deg)}}.mdc-circular-progress{display:inline-block;position:relative;direction:ltr;transition:opacity 250ms 0ms cubic-bezier(0.4, 0, 0.6, 1)}.mdc-circular-progress__determinate-container,.mdc-circular-progress__indeterminate-circle-graphic,.mdc-circular-progress__indeterminate-container,.mdc-circular-progress__spinner-layer{position:absolute;width:100%;height:100%}.mdc-circular-progress__determinate-container{transform:rotate(-90deg)}.mdc-circular-progress__indeterminate-container{opacity:0}.mdc-circular-progress__determinate-circle-graphic,.mdc-circular-progress__indeterminate-circle-graphic{fill:transparent}.mdc-circular-progress__determinate-circle{transition:stroke-dashoffset 500ms 0ms cubic-bezier(0, 0, 0.2, 1)}.mdc-circular-progress__gap-patch{position:absolute;top:0;left:47.5%;box-sizing:border-box;width:5%;height:100%;overflow:hidden}.mdc-circular-progress__gap-patch .mdc-circular-progress__indeterminate-circle-graphic{left:-900%;width:2000%;transform:rotate(180deg)}.mdc-circular-progress__circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden}.mdc-circular-progress__circle-clipper .mdc-circular-progress__indeterminate-circle-graphic{width:200%}.mdc-circular-progress__circle-right .mdc-circular-progress__indeterminate-circle-graphic{left:-100%}.mdc-circular-progress--indeterminate .mdc-circular-progress__determinate-container{opacity:0}.mdc-circular-progress--indeterminate .mdc-circular-progress__indeterminate-container{opacity:1}.mdc-circular-progress--indeterminate .mdc-circular-progress__indeterminate-container{animation:mdc-circular-progress-container-rotate 1568.2352941176ms linear infinite}.mdc-circular-progress--indeterminate .mdc-circular-progress__spinner-layer{animation:mdc-circular-progress-spinner-layer-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--indeterminate .mdc-circular-progress__color-1{animation:mdc-circular-progress-spinner-layer-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,mdc-circular-progress-color-1-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--indeterminate .mdc-circular-progress__color-2{animation:mdc-circular-progress-spinner-layer-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,mdc-circular-progress-color-2-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--indeterminate .mdc-circular-progress__color-3{animation:mdc-circular-progress-spinner-layer-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,mdc-circular-progress-color-3-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--indeterminate .mdc-circular-progress__color-4{animation:mdc-circular-progress-spinner-layer-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,mdc-circular-progress-color-4-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--indeterminate .mdc-circular-progress__circle-left .mdc-circular-progress__indeterminate-circle-graphic{animation:mdc-circular-progress-left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--indeterminate .mdc-circular-progress__circle-right .mdc-circular-progress__indeterminate-circle-graphic{animation:mdc-circular-progress-right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.mdc-circular-progress--closed{opacity:0}.mdc-circular-progress__color-1 .mdc-circular-progress__indeterminate-circle-graphic{stroke:#6200ee;stroke:var(--mdc-circular-progress-bar-color-1, var(--mdc-theme-primary, #6200ee))}.mdc-circular-progress__color-2 .mdc-circular-progress__indeterminate-circle-graphic{stroke:#6200ee;stroke:var(--mdc-circular-progress-bar-color-2, var(--mdc-theme-primary, #6200ee))}.mdc-circular-progress__color-3 .mdc-circular-progress__indeterminate-circle-graphic{stroke:#6200ee;stroke:var(--mdc-circular-progress-bar-color-3, var(--mdc-theme-primary, #6200ee))}.mdc-circular-progress__color-4 .mdc-circular-progress__indeterminate-circle-graphic{stroke:#6200ee;stroke:var(--mdc-circular-progress-bar-color-4, var(--mdc-theme-primary, #6200ee))}:host{display:inline-flex}`;
/** @soyCompatible */
exports.CircularProgressFourColor = class CircularProgressFourColor extends CircularProgressFourColorBase {
};
exports.CircularProgressFourColor.styles = style$1;
exports.CircularProgressFourColor = __decorate([
customElement('mwc-circular-progress-four-color')
], exports.CircularProgressFourColor);
/**
@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.
*/
const style$2 = css `:host{font-family:var(--mdc-icon-font, "Material Icons");font-weight:normal;font-style:normal;font-size:var(--mdc-icon-size, 24px);line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:"liga"}`;
exports.Icon = class Icon extends LitElement {
render() {
return html `<slot></slot>`;
}
};
exports.Icon.styles = style$2;
exports.Icon = __decorate([
customElement('mwc-icon')
], exports.Icon);
/**
* @license
* Copyright 2019 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* Determine whether the current browser supports passive event listeners, and
* if so, use them.
*/
function applyPassive$1(globalObj) {
if (globalObj === void 0) { globalObj = window; }
return supportsPassiveOption(globalObj) ?
{ passive: true } :
false;
}
function supportsPassiveOption(globalObj) {
if (globalObj === void 0) { globalObj = window; }
// See
// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
var passiveSupported = false;
try {
var options = {
// This function will be called when the browser
// attempts to access the passive property.
get passive() {
passiveSupported = true;
return false;
}
};
var handler = function () { };
globalObj.document.addEventListener('test', handler, options);
globalObj.document.removeEventListener('test', handler, options);
}
catch (err) {
passiveSupported = false;
}
return passiveSupported;
}
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
function matches$2(element, selector) {
var nativeMatches = element.matches
|| element.webkitMatchesSelector
|| element.msMatchesSelector;
return nativeMatches.call(element, selector);
}
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCFoundation$1 = /** @class */ (function () {
function MDCFoundation(adapter) {
if (adapter === void 0) { adapter = {}; }
this.adapter_ = adapter;
}
Object.defineProperty(MDCFoundation, "cssClasses", {
get: function () {
// Classes extending MDCFoundation should implement this method to return an object which exports every
// CSS class the foundation class needs as a property. e.g. {ACTIVE: 'mdc-component--active'}
return {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFoundation, "strings", {
get: function () {
// Classes extending MDCFoundation should implement this method to return an object which exports all
// semantic strings as constants. e.g. {ARIA_ROLE: 'tablist'}
return {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFoundation, "numbers", {
get: function () {
// Classes extending MDCFoundation should implement this method to return an object which exports all
// of its semantic numbers as constants. e.g. {ANIMATION_DELAY_MS: 350}
return {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFoundation, "defaultAdapter", {
get: function () {
// Classes extending MDCFoundation may choose to implement this getter in order to provide a convenient
// way of viewing the necessary methods of an adapter. In the future, this could also be used for adapter
// validation.
return {};
},
enumerable: true,
configurable: true
});
MDCFoundation.prototype.init = function () {
// Subclasses should override this method to perform initialization routines (registering events, etc.)
};
MDCFoundation.prototype.destroy = function () {
// Subclasses should override this method to perform de-initialization routines (de-registering events, etc.)
};
return MDCFoundation;
}());
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$v = {
// Ripple is a special case where the "root" component is really a "mixin" of sorts,
// given that it's an 'upgrade' to an existing component. That being said it is the root
// CSS class that all other CSS classes derive from.
BG_FOCUSED: 'mdc-ripple-upgraded--background-focused',
FG_ACTIVATION: 'mdc-ripple-upgraded--foreground-activation',
FG_DEACTIVATION: 'mdc-ripple-upgraded--foreground-deactivation',
ROOT: 'mdc-ripple-upgraded',
UNBOUNDED: 'mdc-ripple-upgraded--unbounded',
};
var strings$y = {
VAR_FG_SCALE: '--mdc-ripple-fg-scale',
VAR_FG_SIZE: '--mdc-ripple-fg-size',
VAR_FG_TRANSLATE_END: '--mdc-ripple-fg-translate-end',
VAR_FG_TRANSLATE_START: '--mdc-ripple-fg-translate-start',
VAR_LEFT: '--mdc-ripple-left',
VAR_TOP: '--mdc-ripple-top',
};
var numbers$d = {
DEACTIVATION_TIMEOUT_MS: 225,
FG_DEACTIVATION_MS: 150,
INITIAL_ORIGIN_SCALE: 0.6,
PADDING: 10,
TAP_DELAY_MS: 300,
};
/**
* Stores result from supportsCssVariables to avoid redundant processing to
* detect CSS custom variable support.
*/
var supportsCssVariables_$1;
function supportsCssVariables$1(windowObj, forceRefresh) {
if (forceRefresh === void 0) { forceRefresh = false; }
var CSS = windowObj.CSS;
var supportsCssVars = supportsCssVariables_$1;
if (typeof supportsCssVariables_$1 === 'boolean' && !forceRefresh) {
return supportsCssVariables_$1;
}
var supportsFunctionPresent = CSS && typeof CSS.supports === 'function';
if (!supportsFunctionPresent) {
return false;
}
var explicitlySupportsCssVars = CSS.supports('--css-vars', 'yes');
// See: https://bugs.webkit.org/show_bug.cgi?id=154669
// See: README section on Safari
var weAreFeatureDetectingSafari10plus = (CSS.supports('(--css-vars: yes)') &&
CSS.supports('color', '#00000000'));
supportsCssVars =
explicitlySupportsCssVars || weAreFeatureDetectingSafari10plus;
if (!forceRefresh) {
supportsCssVariables_$1 = supportsCssVars;
}
return supportsCssVars;
}
function getNormalizedEventCoords$1(evt, pageOffset, clientRect) {
if (!evt) {
return { x: 0, y: 0 };
}
var x = pageOffset.x, y = pageOffset.y;
var documentX = x + clientRect.left;
var documentY = y + clientRect.top;
var normalizedX;
var normalizedY;
// Determine touch point relative to the ripple container.
if (evt.type === 'touchstart') {
var touchEvent = evt;
normalizedX = touchEvent.changedTouches[0].pageX - documentX;
normalizedY = touchEvent.changedTouches[0].pageY - documentY;
}
else {
var mouseEvent = evt;
normalizedX = mouseEvent.pageX - documentX;
normalizedY = mouseEvent.pageY - documentY;
}
return { x: normalizedX, y: normalizedY };
}
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Activation events registered on the root element of each instance for activation
var ACTIVATION_EVENT_TYPES$1 = [
'touchstart', 'pointerdown', 'mousedown', 'keydown',
];
// Deactivation events registered on documentElement when a pointer-related down event occurs
var POINTER_DEACTIVATION_EVENT_TYPES$1 = [
'touchend', 'pointerup', 'mouseup', 'contextmenu',
];
// simultaneous nested activations
var activatedTargets$1 = [];
var MDCRippleFoundation$1 = /** @class */ (function (_super) {
__extends(MDCRippleFoundation, _super);
function MDCRippleFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCRippleFoundation.defaultAdapter, adapter)) || this;
_this.activationAnimationHasEnded_ = false;
_this.activationTimer_ = 0;
_this.fgDeactivationRemovalTimer_ = 0;
_this.fgScale_ = '0';
_this.frame_ = { width: 0, height: 0 };
_this.initialSize_ = 0;
_this.layoutFrame_ = 0;
_this.maxRadius_ = 0;
_this.unboundedCoords_ = { left: 0, top: 0 };
_this.activationState_ = _this.defaultActivationState_();
_this.activationTimerCallback_ = function () {
_this.activationAnimationHasEnded_ = true;
_this.runDeactivationUXLogicIfReady_();
};
_this.activateHandler_ = function (e) { return _this.activate_(e); };
_this.deactivateHandler_ = function () { return _this.deactivate_(); };
_this.focusHandler_ = function () { return _this.handleFocus(); };
_this.blurHandler_ = function () { return _this.handleBlur(); };
_this.resizeHandler_ = function () { return _this.layout(); };
return _this;
}
Object.defineProperty(MDCRippleFoundation, "cssClasses", {
get: function () {
return cssClasses$v;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCRippleFoundation, "strings", {
get: function () {
return strings$y;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCRippleFoundation, "numbers", {
get: function () {
return numbers$d;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCRippleFoundation, "defaultAdapter", {
get: function () {
return {
addClass: function () { return undefined; },
browserSupportsCssVars: function () { return true; },
computeBoundingRect: function () { return ({ top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 }); },
containsEventTarget: function () { return true; },
deregisterDocumentInteractionHandler: function () { return undefined; },
deregisterInteractionHandler: function () { return undefined; },
deregisterResizeHandler: function () { return undefined; },
getWindowPageOffset: function () { return ({ x: 0, y: 0 }); },
isSurfaceActive: function () { return true; },
isSurfaceDisabled: function () { return true; },
isUnbounded: function () { return true; },
registerDocumentInteractionHandler: function () { return undefined; },
registerInteractionHandler: function () { return undefined; },
registerResizeHandler: function () { return undefined; },
removeClass: function () { return undefined; },
updateCssVariable: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCRippleFoundation.prototype.init = function () {
var _this = this;
var supportsPressRipple = this.supportsPressRipple_();
this.registerRootHandlers_(supportsPressRipple);
if (supportsPressRipple) {
var _a = MDCRippleFoundation.cssClasses, ROOT_1 = _a.ROOT, UNBOUNDED_1 = _a.UNBOUNDED;
requestAnimationFrame(function () {
_this.adapter_.addClass(ROOT_1);
if (_this.adapter_.isUnbounded()) {
_this.adapter_.addClass(UNBOUNDED_1);
// Unbounded ripples need layout logic applied immediately to set coordinates for both shade and ripple
_this.layoutInternal_();
}
});
}
};
MDCRippleFoundation.prototype.destroy = function () {
var _this = this;
if (this.supportsPressRipple_()) {
if (this.activationTimer_) {
clearTimeout(this.activationTimer_);
this.activationTimer_ = 0;
this.adapter_.removeClass(MDCRippleFoundation.cssClasses.FG_ACTIVATION);
}
if (this.fgDeactivationRemovalTimer_) {
clearTimeout(this.fgDeactivationRemovalTimer_);
this.fgDeactivationRemovalTimer_ = 0;
this.adapter_.removeClass(MDCRippleFoundation.cssClasses.FG_DEACTIVATION);
}
var _a = MDCRippleFoundation.cssClasses, ROOT_2 = _a.ROOT, UNBOUNDED_2 = _a.UNBOUNDED;
requestAnimationFrame(function () {
_this.adapter_.removeClass(ROOT_2);
_this.adapter_.removeClass(UNBOUNDED_2);
_this.removeCssVars_();
});
}
this.deregisterRootHandlers_();
this.deregisterDeactivationHandlers_();
};
/**
* @param evt Optional event containing position information.
*/
MDCRippleFoundation.prototype.activate = function (evt) {
this.activate_(evt);
};
MDCRippleFoundation.prototype.deactivate = function () {
this.deactivate_();
};
MDCRippleFoundation.prototype.layout = function () {
var _this = this;
if (this.layoutFrame_) {
cancelAnimationFrame(this.layoutFrame_);
}
this.layoutFrame_ = requestAnimationFrame(function () {
_this.layoutInternal_();
_this.layoutFrame_ = 0;
});
};
MDCRippleFoundation.prototype.setUnbounded = function (unbounded) {
var UNBOUNDED = MDCRippleFoundation.cssClasses.UNBOUNDED;
if (unbounded) {
this.adapter_.addClass(UNBOUNDED);
}
else {
this.adapter_.removeClass(UNBOUNDED);
}
};
MDCRippleFoundation.prototype.handleFocus = function () {
var _this = this;
requestAnimationFrame(function () {
return _this.adapter_.addClass(MDCRippleFoundation.cssClasses.BG_FOCUSED);
});
};
MDCRippleFoundation.prototype.handleBlur = function () {
var _this = this;
requestAnimationFrame(function () {
return _this.adapter_.removeClass(MDCRippleFoundation.cssClasses.BG_FOCUSED);
});
};
/**
* We compute this property so that we are not querying information about the client
* until the point in time where the foundation requests it. This prevents scenarios where
* client-side feature-detection may happen too early, such as when components are rendered on the server
* and then initialized at mount time on the client.
*/
MDCRippleFoundation.prototype.supportsPressRipple_ = function () {
return this.adapter_.browserSupportsCssVars();
};
MDCRippleFoundation.prototype.defaultActivationState_ = function () {
return {
activationEvent: undefined,
hasDeactivationUXRun: false,
isActivated: false,
isProgrammatic: false,
wasActivatedByPointer: false,
wasElementMadeActive: false,
};
};
/**
* supportsPressRipple Passed from init to save a redundant function call
*/
MDCRippleFoundation.prototype.registerRootHandlers_ = function (supportsPressRipple) {
var _this = this;
if (supportsPressRipple) {
ACTIVATION_EVENT_TYPES$1.forEach(function (evtType) {
_this.adapter_.registerInteractionHandler(evtType, _this.activateHandler_);
});
if (this.adapter_.isUnbounded()) {
this.adapter_.registerResizeHandler(this.resizeHandler_);
}
}
this.adapter_.registerInteractionHandler('focus', this.focusHandler_);
this.adapter_.registerInteractionHandler('blur', this.blurHandler_);
};
MDCRippleFoundation.prototype.registerDeactivationHandlers_ = function (evt) {
var _this = this;
if (evt.type === 'keydown') {
this.adapter_.registerInteractionHandler('keyup', this.deactivateHandler_);
}
else {
POINTER_DEACTIVATION_EVENT_TYPES$1.forEach(function (evtType) {
_this.adapter_.registerDocumentInteractionHandler(evtType, _this.deactivateHandler_);
});
}
};
MDCRippleFoundation.prototype.deregisterRootHandlers_ = function () {
var _this = this;
ACTIVATION_EVENT_TYPES$1.forEach(function (evtType) {
_this.adapter_.deregisterInteractionHandler(evtType, _this.activateHandler_);
});
this.adapter_.deregisterInteractionHandler('focus', this.focusHandler_);
this.adapter_.deregisterInteractionHandler('blur', this.blurHandler_);
if (this.adapter_.isUnbounded()) {
this.adapter_.deregisterResizeHandler(this.resizeHandler_);
}
};
MDCRippleFoundation.prototype.deregisterDeactivationHandlers_ = function () {
var _this = this;
this.adapter_.deregisterInteractionHandler('keyup', this.deactivateHandler_);
POINTER_DEACTIVATION_EVENT_TYPES$1.forEach(function (evtType) {
_this.adapter_.deregisterDocumentInteractionHandler(evtType, _this.deactivateHandler_);
});
};
MDCRippleFoundation.prototype.removeCssVars_ = function () {
var _this = this;
var rippleStrings = MDCRippleFoundation.strings;
var keys = Object.keys(rippleStrings);
keys.forEach(function (key) {
if (key.indexOf('VAR_') === 0) {
_this.adapter_.updateCssVariable(rippleStrings[key], null);
}
});
};
MDCRippleFoundation.prototype.activate_ = function (evt) {
var _this = this;
if (this.adapter_.isSurfaceDisabled()) {
return;
}
var activationState = this.activationState_;
if (activationState.isActivated) {
return;
}
// Avoid reacting to follow-on events fired by touch device after an already-processed user interaction
var previousActivationEvent = this.previousActivationEvent_;
var isSameInteraction = previousActivationEvent && evt !== undefined && previousActivationEvent.type !== evt.type;
if (isSameInteraction) {
return;
}
activationState.isActivated = true;
activationState.isProgrammatic = evt === undefined;
activationState.activationEvent = evt;
activationState.wasActivatedByPointer = activationState.isProgrammatic ? false : evt !== undefined && (evt.type === 'mousedown' || evt.type === 'touchstart' || evt.type === 'pointerdown');
var hasActivatedChild = evt !== undefined && activatedTargets$1.length > 0 && activatedTargets$1.some(function (target) { return _this.adapter_.containsEventTarget(target); });
if (hasActivatedChild) {
// Immediately reset activation state, while preserving logic that prevents touch follow-on events
this.resetActivationState_();
return;
}
if (evt !== undefined) {
activatedTargets$1.push(evt.target);
this.registerDeactivationHandlers_(evt);
}
activationState.wasElementMadeActive = this.checkElementMadeActive_(evt);
if (activationState.wasElementMadeActive) {
this.animateActivation_();
}
requestAnimationFrame(function () {
// Reset array on next frame after the current event has had a chance to bubble to prevent ancestor ripples
activatedTargets$1 = [];
if (!activationState.wasElementMadeActive
&& evt !== undefined
&& (evt.key === ' ' || evt.keyCode === 32)) {
// If space was pressed, try again within an rAF call to detect :active, because different UAs report
// active states inconsistently when they're called within event handling code:
// - https://bugs.chromium.org/p/chromium/issues/detail?id=635971
// - https://bugzilla.mozilla.org/show_bug.cgi?id=1293741
// We try first outside rAF to support Edge, which does not exhibit this problem, but will crash if a CSS
// variable is set within a rAF callback for a submit button interaction (#2241).
activationState.wasElementMadeActive = _this.checkElementMadeActive_(evt);
if (activationState.wasElementMadeActive) {
_this.animateActivation_();
}
}
if (!activationState.wasElementMadeActive) {
// Reset activation state immediately if element was not made active.
_this.activationState_ = _this.defaultActivationState_();
}
});
};
MDCRippleFoundation.prototype.checkElementMadeActive_ = function (evt) {
return (evt !== undefined && evt.type === 'keydown') ? this.adapter_.isSurfaceActive() : true;
};
MDCRippleFoundation.prototype.animateActivation_ = function () {
var _this = this;
var _a = MDCRippleFoundation.strings, VAR_FG_TRANSLATE_START = _a.VAR_FG_TRANSLATE_START, VAR_FG_TRANSLATE_END = _a.VAR_FG_TRANSLATE_END;
var _b = MDCRippleFoundation.cssClasses, FG_DEACTIVATION = _b.FG_DEACTIVATION, FG_ACTIVATION = _b.FG_ACTIVATION;
var DEACTIVATION_TIMEOUT_MS = MDCRippleFoundation.numbers.DEACTIVATION_TIMEOUT_MS;
this.layoutInternal_();
var translateStart = '';
var translateEnd = '';
if (!this.adapter_.isUnbounded()) {
var _c = this.getFgTranslationCoordinates_(), startPoint = _c.startPoint, endPoint = _c.endPoint;
translateStart = startPoint.x + "px, " + startPoint.y + "px";
translateEnd = endPoint.x + "px, " + endPoint.y + "px";
}
this.adapter_.updateCssVariable(VAR_FG_TRANSLATE_START, translateStart);
this.adapter_.updateCssVariable(VAR_FG_TRANSLATE_END, translateEnd);
// Cancel any ongoing activation/deactivation animations
clearTimeout(this.activationTimer_);
clearTimeout(this.fgDeactivationRemovalTimer_);
this.rmBoundedActivationClasses_();
this.adapter_.removeClass(FG_DEACTIVATION);
// Force layout in order to re-trigger the animation.
this.adapter_.computeBoundingRect();
this.adapter_.addClass(FG_ACTIVATION);
this.activationTimer_ = setTimeout(function () { return _this.activationTimerCallback_(); }, DEACTIVATION_TIMEOUT_MS);
};
MDCRippleFoundation.prototype.getFgTranslationCoordinates_ = function () {
var _a = this.activationState_, activationEvent = _a.activationEvent, wasActivatedByPointer = _a.wasActivatedByPointer;
var startPoint;
if (wasActivatedByPointer) {
startPoint = getNormalizedEventCoords$1(activationEvent, this.adapter_.getWindowPageOffset(), this.adapter_.computeBoundingRect());
}
else {
startPoint = {
x: this.frame_.width / 2,
y: this.frame_.height / 2,
};
}
// Center the element around the start point.
startPoint = {
x: startPoint.x - (this.initialSize_ / 2),
y: startPoint.y - (this.initialSize_ / 2),
};
var endPoint = {
x: (this.frame_.width / 2) - (this.initialSize_ / 2),
y: (this.frame_.height / 2) - (this.initialSize_ / 2),
};
return { startPoint: startPoint, endPoint: endPoint };
};
MDCRippleFoundation.prototype.runDeactivationUXLogicIfReady_ = function () {
var _this = this;
// This method is called both when a pointing device is released, and when the activation animation ends.
// The deactivation animation should only run after both of those occur.
var FG_DEACTIVATION = MDCRippleFoundation.cssClasses.FG_DEACTIVATION;
var _a = this.activationState_, hasDeactivationUXRun = _a.hasDeactivationUXRun, isActivated = _a.isActivated;
var activationHasEnded = hasDeactivationUXRun || !isActivated;
if (activationHasEnded && this.activationAnimationHasEnded_) {
this.rmBoundedActivationClasses_();
this.adapter_.addClass(FG_DEACTIVATION);
this.fgDeactivationRemovalTimer_ = setTimeout(function () {
_this.adapter_.removeClass(FG_DEACTIVATION);
}, numbers$d.FG_DEACTIVATION_MS);
}
};
MDCRippleFoundation.prototype.rmBoundedActivationClasses_ = function () {
var FG_ACTIVATION = MDCRippleFoundation.cssClasses.FG_ACTIVATION;
this.adapter_.removeClass(FG_ACTIVATION);
this.activationAnimationHasEnded_ = false;
this.adapter_.computeBoundingRect();
};
MDCRippleFoundation.prototype.resetActivationState_ = function () {
var _this = this;
this.previousActivationEvent_ = this.activationState_.activationEvent;
this.activationState_ = this.defaultActivationState_();
// Touch devices may fire additional events for the same interaction within a short time.
// Store the previous event until it's safe to assume that subsequent events are for new interactions.
setTimeout(function () { return _this.previousActivationEvent_ = undefined; }, MDCRippleFoundation.numbers.TAP_DELAY_MS);
};
MDCRippleFoundation.prototype.deactivate_ = function () {
var _this = this;
var activationState = this.activationState_;
// This can happen in scenarios such as when you have a keyup event that blurs the element.
if (!activationState.isActivated) {
return;
}
var state = __assign({}, activationState);
if (activationState.isProgrammatic) {
requestAnimationFrame(function () { return _this.animateDeactivation_(state); });
this.resetActivationState_();
}
else {
this.deregisterDeactivationHandlers_();
requestAnimationFrame(function () {
_this.activationState_.hasDeactivationUXRun = true;
_this.animateDeactivation_(state);
_this.resetActivationState_();
});
}
};
MDCRippleFoundation.prototype.animateDeactivation_ = function (_a) {
var wasActivatedByPointer = _a.wasActivatedByPointer, wasElementMadeActive = _a.wasElementMadeActive;
if (wasActivatedByPointer || wasElementMadeActive) {
this.runDeactivationUXLogicIfReady_();
}
};
MDCRippleFoundation.prototype.layoutInternal_ = function () {
var _this = this;
this.frame_ = this.adapter_.computeBoundingRect();
var maxDim = Math.max(this.frame_.height, this.frame_.width);
// Surface diameter is treated differently for unbounded vs. bounded ripples.
// Unbounded ripple diameter is calculated smaller since the surface is expected to already be padded appropriately
// to extend the hitbox, and the ripple is expected to meet the edges of the padded hitbox (which is typically
// square). Bounded ripples, on the other hand, are fully expected to expand beyond the surface's longest diameter
// (calculated based on the diagonal plus a constant padding), and are clipped at the surface's border via
// `overflow: hidden`.
var getBoundedRadius = function () {
var hypotenuse = Math.sqrt(Math.pow(_this.frame_.width, 2) + Math.pow(_this.frame_.height, 2));
return hypotenuse + MDCRippleFoundation.numbers.PADDING;
};
this.maxRadius_ = this.adapter_.isUnbounded() ? maxDim : getBoundedRadius();
// Ripple is sized as a fraction of the largest dimension of the surface, then scales up using a CSS scale transform
var initialSize = Math.floor(maxDim * MDCRippleFoundation.numbers.INITIAL_ORIGIN_SCALE);
// Unbounded ripple size should always be even number to equally center align.
if (this.adapter_.isUnbounded() && initialSize % 2 !== 0) {
this.initialSize_ = initialSize - 1;
}
else {
this.initialSize_ = initialSize;
}
this.fgScale_ = "" + this.maxRadius_ / this.initialSize_;
this.updateLayoutCssVars_();
};
MDCRippleFoundation.prototype.updateLayoutCssVars_ = function () {
var _a = MDCRippleFoundation.strings, VAR_FG_SIZE = _a.VAR_FG_SIZE, VAR_LEFT = _a.VAR_LEFT, VAR_TOP = _a.VAR_TOP, VAR_FG_SCALE = _a.VAR_FG_SCALE;
this.adapter_.updateCssVariable(VAR_FG_SIZE, this.initialSize_ + "px");
this.adapter_.updateCssVariable(VAR_FG_SCALE, this.fgScale_);
if (this.adapter_.isUnbounded()) {
this.unboundedCoords_ = {
left: Math.round((this.frame_.width / 2) - (this.initialSize_ / 2)),
top: Math.round((this.frame_.height / 2) - (this.initialSize_ / 2)),
};
this.adapter_.updateCssVariable(VAR_LEFT, this.unboundedCoords_.left + "px");
this.adapter_.updateCssVariable(VAR_TOP, this.unboundedCoords_.top + "px");
}
};
return MDCRippleFoundation;
}(MDCFoundation$1));
/**
@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.
*/
const style$3 = css `@keyframes mdc-ripple-fg-radius-in{from{animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transform:translate(var(--mdc-ripple-fg-translate-start, 0)) scale(1)}to{transform:translate(var(--mdc-ripple-fg-translate-end, 0)) scale(var(--mdc-ripple-fg-scale, 1))}}@keyframes mdc-ripple-fg-opacity-in{from{animation-timing-function:linear;opacity:0}to{opacity:var(--mdc-ripple-fg-opacity, 0)}}@keyframes mdc-ripple-fg-opacity-out{from{animation-timing-function:linear;opacity:var(--mdc-ripple-fg-opacity, 0)}to{opacity:0}}`;
/**
@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.
*/
const supportsCssVariablesWin = supportsCssVariables$1(window);
// NOTE: This is a workaround for
// https://bugs.webkit.org/show_bug.cgi?id=173027. Since keyframes on
// pseudo-elements (:after) are not supported in Shadow DOM, we put the keyframe
// style into the <head> element.
const isSafari = navigator.userAgent.match(/Safari/);
let didApplyRippleStyle = false;
const applyRippleStyle = () => {
didApplyRippleStyle = true;
const styleElement = document.createElement('style');
const part = new NodePart({ templateFactory });
part.appendInto(styleElement);
part.setValue(style$3);
part.commit();
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
document.head.appendChild(styleElement);
};
/**
* Applied a ripple to the node specified by {surfaceNode}.
* @param options {RippleNodeOptions}
*/
const rippleNode = (options) => {
if (isSafari && !didApplyRippleStyle) {
applyRippleStyle();
}
// TODO(sorvell): This directive requires bringing css yourself. We probably
// need to do this because of ShadyCSS, but on Safari, the keyframes styling
// must be global. Perhaps this directive could fix that.
const surfaceNode = options.surfaceNode;
const interactionNode = options.interactionNode || surfaceNode;
// only style interaction node if not in the same root
if (interactionNode.getRootNode() !== surfaceNode.getRootNode()) {
if (interactionNode.style.position === '') {
interactionNode.style.position = 'relative';
}
}
const adapter = {
browserSupportsCssVars: () => supportsCssVariablesWin,
isUnbounded: () => options.unbounded === undefined ? true : options.unbounded,
isSurfaceActive: () => matches$2(interactionNode, ':active'),
isSurfaceDisabled: () => Boolean(interactionNode.hasAttribute('disabled')),
addClass: (className) => surfaceNode.classList.add(className),
removeClass: (className) => surfaceNode.classList.remove(className),
containsEventTarget: (target) => interactionNode.contains(target),
registerInteractionHandler: (type, handler) => interactionNode.addEventListener(type, handler, applyPassive$1()),
deregisterInteractionHandler: (type, handler) => interactionNode.removeEventListener(type, handler, applyPassive$1()),
registerDocumentInteractionHandler: (evtType, handler) =>
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
document.documentElement.addEventListener(evtType, handler, applyPassive$1()),
deregisterDocumentInteractionHandler: (evtType, handler) =>
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
document.documentElement.removeEventListener(evtType, handler, applyPassive$1()),
registerResizeHandler: (handler) => window.addEventListener('resize', handler),
deregisterResizeHandler: (handler) => window.removeEventListener('resize', handler),
updateCssVariable: (varName, value) => surfaceNode.style.setProperty(varName, value),
computeBoundingRect: () => surfaceNode.getBoundingClientRect(),
getWindowPageOffset: () => ({ x: window.pageXOffset, y: window.pageYOffset }),
};
const rippleFoundation = new MDCRippleFoundation$1(adapter);
rippleFoundation.init();
return rippleFoundation;
};
const rippleInteractionNodes = new WeakMap();
/**
* A directive that applies a Material ripple to a part node. The directive
* should be applied to a PropertyPart.
* @param options {RippleOptions}
*/
const ripple = directive((options = {}) => (part) => {
const surfaceNode = part.committer.element;
const interactionNode = options.interactionNode || surfaceNode;
let rippleFoundation = part.value;
// if the interaction node changes, destroy and invalidate the foundation.
const existingInteractionNode = rippleInteractionNodes.get(rippleFoundation);
if (existingInteractionNode !== undefined &&
existingInteractionNode !== interactionNode) {
rippleFoundation.destroy();
rippleFoundation = noChange;
}
// make the ripple, if needed
if (rippleFoundation === noChange) {
rippleFoundation =
rippleNode(Object.assign({}, options, { surfaceNode }));
rippleInteractionNodes.set(rippleFoundation, interactionNode);
part.setValue(rippleFoundation);
// otherwise update settings as needed.
}
else {
if (options.unbounded !== undefined) {
rippleFoundation
.setUnbounded(options.unbounded);
}
if (options.disabled !== undefined) {
rippleFoundation
.setUnbounded(options.disabled);
}
}
if (options.active === true) {
rippleFoundation.activate();
}
else if (options.active === false) {
rippleFoundation.deactivate();
}
});
class ButtonBase extends LitElement {
constructor() {
super(...arguments);
this.raised = false;
this.unelevated = false;
this.outlined = false;
this.dense = false;
this.disabled = false;
this.trailingIcon = false;
this.fullwidth = false;
this.icon = '';
this.label = '';
}
createRenderRoot() {
return this.attachShadow({ mode: 'open', delegatesFocus: true });
}
focus() {
const buttonElement = this.buttonElement;
if (buttonElement) {
const ripple = buttonElement.ripple;
if (ripple) {
ripple.handleFocus();
}
buttonElement.focus();
}
}
blur() {
const buttonElement = this.buttonElement;
if (buttonElement) {
const ripple = buttonElement.ripple;
if (ripple) {
ripple.handleBlur();
}
buttonElement.blur();
}
}
render() {
const classes = {
'mdc-button--raised': this.raised,
'mdc-button--unelevated': this.unelevated,
'mdc-button--outlined': this.outlined,
'mdc-button--dense': this.dense,
};
return html `
<button
id="button"
class="mdc-button ${classMap(classes)}"
?disabled="${this.disabled}"
aria-label="${this.label || this.icon}">
<div class="mdc-button__ripple"></div>
<span class="leading-icon">
<slot name="icon">
${this.icon && !this.trailingIcon ? this.renderIcon(this.icon) : ''}
</slot>
</span>
<span class="mdc-button__label">${this.label}</span>
<slot></slot>
<span class="trailing-icon">
<slot name="trailingIcon">
${this.icon && this.trailingIcon ? this.renderIcon(this.icon) : ''}
</slot>
</span>
</button>`;
}
renderIcon(icon) {
return html `
<mwc-icon class="mdc-button__icon">
${icon}
</mwc-icon>`;
}
firstUpdated() {
this.buttonElement.ripple =
rippleNode({ surfaceNode: this.buttonElement, unbounded: false });
}
}
__decorate([
property({ type: Boolean })
], ButtonBase.prototype, "raised", void 0);
__decorate([
property({ type: Boolean })
], ButtonBase.prototype, "unelevated", void 0);
__decorate([
property({ type: Boolean })
], ButtonBase.prototype, "outlined", void 0);
__decorate([
property({ type: Boolean })
], ButtonBase.prototype, "dense", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], ButtonBase.prototype, "disabled", void 0);
__decorate([
property({ type: Boolean })
], ButtonBase.prototype, "trailingIcon", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], ButtonBase.prototype, "fullwidth", void 0);
__decorate([
property({ type: String })
], ButtonBase.prototype, "icon", void 0);
__decorate([
property({ type: String })
], ButtonBase.prototype, "label", void 0);
__decorate([
query('#button')
], ButtonBase.prototype, "buttonElement", void 0);
/**
@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.
*/
const style$4 = css `.mdc-touch-target-wrapper{display:inline}.mdc-elevation-overlay{position:absolute;border-radius:inherit;opacity:0;pointer-events:none;transition:opacity 280ms cubic-bezier(0.4, 0, 0.2, 1);background-color:#fff}.mdc-button{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:Roboto, sans-serif;font-family:var(--mdc-typography-button-font-family, var(--mdc-typography-font-family, Roboto, sans-serif));font-size:.875rem;font-size:var(--mdc-typography-button-font-size, 0.875rem);line-height:2.25rem;line-height:var(--mdc-typography-button-line-height, 2.25rem);font-weight:500;font-weight:var(--mdc-typography-button-font-weight, 500);letter-spacing:.0892857143em;letter-spacing:var(--mdc-typography-button-letter-spacing, 0.0892857143em);text-decoration:none;text-decoration:var(--mdc-typography-button-text-decoration, none);text-transform:uppercase;text-transform:var(--mdc-typography-button-text-transform, uppercase);padding:0 8px 0 8px;position:relative;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;min-width:64px;border:none;outline:none;line-height:inherit;user-select:none;-webkit-appearance:none;overflow:visible;vertical-align:middle;border-radius:4px}.mdc-button .mdc-elevation-overlay{width:100%;height:100%;top:0;left:0}.mdc-button::-moz-focus-inner{padding:0;border:0}.mdc-button:active{outline:none}.mdc-button:hover{cursor:pointer}.mdc-button:disabled{cursor:default;pointer-events:none}.mdc-button .mdc-button__ripple{border-radius:4px}.mdc-button:not(:disabled){background-color:transparent}.mdc-button:disabled{background-color:transparent}.mdc-button .mdc-button__icon{margin-left:0;margin-right:8px;display:inline-block;width:18px;height:18px;font-size:18px;vertical-align:top}[dir=rtl] .mdc-button .mdc-button__icon,.mdc-button .mdc-button__icon[dir=rtl]{margin-left:8px;margin-right:0}.mdc-button .mdc-button__touch{position:absolute;top:50%;right:0;height:48px;left:0;transform:translateY(-50%)}.mdc-button:not(:disabled){color:#6200ee;color:var(--mdc-theme-primary, #6200ee)}.mdc-button:disabled{color:rgba(0,0,0,.38)}.mdc-button__label+.mdc-button__icon{margin-left:8px;margin-right:0}[dir=rtl] .mdc-button__label+.mdc-button__icon,.mdc-button__label+.mdc-button__icon[dir=rtl]{margin-left:0;margin-right:8px}svg.mdc-button__icon{fill:currentColor}.mdc-button--raised .mdc-button__icon,.mdc-button--unelevated .mdc-button__icon,.mdc-button--outlined .mdc-button__icon{margin-left:-4px;margin-right:8px}[dir=rtl] .mdc-button--raised .mdc-button__icon,.mdc-button--raised .mdc-button__icon[dir=rtl],[dir=rtl] .mdc-button--unelevated .mdc-button__icon,.mdc-button--unelevated .mdc-button__icon[dir=rtl],[dir=rtl] .mdc-button--outlined .mdc-button__icon,.mdc-button--outlined .mdc-button__icon[dir=rtl]{margin-left:8px;margin-right:-4px}.mdc-button--raised .mdc-button__label+.mdc-button__icon,.mdc-button--unelevated .mdc-button__label+.mdc-button__icon,.mdc-button--outlined .mdc-button__label+.mdc-button__icon{margin-left:8px;margin-right:-4px}[dir=rtl] .mdc-button--raised .mdc-button__label+.mdc-button__icon,.mdc-button--raised .mdc-button__label+.mdc-button__icon[dir=rtl],[dir=rtl] .mdc-button--unelevated .mdc-button__label+.mdc-button__icon,.mdc-button--unelevated .mdc-button__label+.mdc-button__icon[dir=rtl],[dir=rtl] .mdc-button--outlined .mdc-button__label+.mdc-button__icon,.mdc-button--outlined .mdc-button__label+.mdc-button__icon[dir=rtl]{margin-left:-4px;margin-right:8px}.mdc-button--raised,.mdc-button--unelevated{padding:0 16px 0 16px}.mdc-button--raised:not(:disabled),.mdc-button--unelevated:not(:disabled){background-color:#6200ee;background-color:var(--mdc-theme-primary, #6200ee)}.mdc-button--raised:not(:disabled),.mdc-button--unelevated:not(:disabled){color:#fff;color:var(--mdc-theme-on-primary, #fff)}.mdc-button--raised:disabled,.mdc-button--unelevated:disabled{background-color:rgba(0,0,0,.12)}.mdc-button--raised:disabled,.mdc-button--unelevated:disabled{color:rgba(0,0,0,.38)}.mdc-button--raised{box-shadow:0px 3px 1px -2px rgba(0, 0, 0, 0.2),0px 2px 2px 0px rgba(0, 0, 0, 0.14),0px 1px 5px 0px rgba(0,0,0,.12);transition:box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1)}.mdc-button--raised:hover,.mdc-button--raised:focus{box-shadow:0px 2px 4px -1px rgba(0, 0, 0, 0.2),0px 4px 5px 0px rgba(0, 0, 0, 0.14),0px 1px 10px 0px rgba(0,0,0,.12)}.mdc-button--raised:active{box-shadow:0px 5px 5px -3px rgba(0, 0, 0, 0.2),0px 8px 10px 1px rgba(0, 0, 0, 0.14),0px 3px 14px 2px rgba(0,0,0,.12)}.mdc-button--raised:disabled{box-shadow:0px 0px 0px 0px rgba(0, 0, 0, 0.2),0px 0px 0px 0px rgba(0, 0, 0, 0.14),0px 0px 0px 0px rgba(0,0,0,.12)}.mdc-button--outlined{padding:0 15px 0 15px;border-width:1px;border-style:solid}.mdc-button--outlined .mdc-button__ripple{top:-1px;left:-1px;border:1px solid transparent}.mdc-button--outlined:not(:disabled){border-color:rgba(0,0,0,.12)}.mdc-button--outlined:disabled{border-color:rgba(0,0,0,.12)}.mdc-button--touch{margin-top:6px;margin-bottom:6px}@keyframes mdc-ripple-fg-radius-in{from{animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transform:translate(var(--mdc-ripple-fg-translate-start, 0)) scale(1)}to{transform:translate(var(--mdc-ripple-fg-translate-end, 0)) scale(var(--mdc-ripple-fg-scale, 1))}}@keyframes mdc-ripple-fg-opacity-in{from{animation-timing-function:linear;opacity:0}to{opacity:var(--mdc-ripple-fg-opacity, 0)}}@keyframes mdc-ripple-fg-opacity-out{from{animation-timing-function:linear;opacity:var(--mdc-ripple-fg-opacity, 0)}to{opacity:0}}.mdc-button{--mdc-ripple-fg-size: 0;--mdc-ripple-left: 0;--mdc-ripple-top: 0;--mdc-ripple-fg-scale: 1;--mdc-ripple-fg-translate-end: 0;--mdc-ripple-fg-translate-start: 0;-webkit-tap-highlight-color:rgba(0,0,0,0)}.mdc-button .mdc-button__ripple::before,.mdc-button .mdc-button__ripple::after{position:absolute;border-radius:50%;opacity:0;pointer-events:none;content:""}.mdc-button .mdc-button__ripple::before{transition:opacity 15ms linear,background-color 15ms linear;z-index:1}.mdc-button.mdc-ripple-upgraded .mdc-button__ripple::before{transform:scale(var(--mdc-ripple-fg-scale, 1))}.mdc-button.mdc-ripple-upgraded .mdc-button__ripple::after{top:0;left:0;transform:scale(0);transform-origin:center center}.mdc-button.mdc-ripple-upgraded--unbounded .mdc-button__ripple::after{top:var(--mdc-ripple-top, 0);left:var(--mdc-ripple-left, 0)}.mdc-button.mdc-ripple-upgraded--foreground-activation .mdc-button__ripple::after{animation:mdc-ripple-fg-radius-in 225ms forwards,mdc-ripple-fg-opacity-in 75ms forwards}.mdc-button.mdc-ripple-upgraded--foreground-deactivation .mdc-button__ripple::after{animation:mdc-ripple-fg-opacity-out 150ms;transform:translate(var(--mdc-ripple-fg-translate-end, 0)) scale(var(--mdc-ripple-fg-scale, 1))}.mdc-button .mdc-button__ripple::before,.mdc-button .mdc-button__ripple::after{top:calc(50% - 100%);left:calc(50% - 100%);width:200%;height:200%}.mdc-button.mdc-ripple-upgraded .mdc-button__ripple::after{width:var(--mdc-ripple-fg-size, 100%);height:var(--mdc-ripple-fg-size, 100%)}.mdc-button .mdc-button__ripple::before,.mdc-button .mdc-button__ripple::after{background-color:#6200ee;background-color:var(--mdc-theme-primary, #6200ee)}.mdc-button:hover .mdc-button__ripple::before{opacity:.04}.mdc-button.mdc-ripple-upgraded--background-focused .mdc-button__ripple::before,.mdc-button:not(.mdc-ripple-upgraded):focus .mdc-button__ripple::before{transition-duration:75ms;opacity:.12}.mdc-button:not(.mdc-ripple-upgraded) .mdc-button__ripple::after{transition:opacity 150ms linear}.mdc-button:not(.mdc-ripple-upgraded):active .mdc-button__ripple::after{transition-duration:75ms;opacity:.12}.mdc-button.mdc-ripple-upgraded{--mdc-ripple-fg-opacity: 0.12}.mdc-button .mdc-button__ripple{position:absolute;box-sizing:content-box;width:100%;height:100%;overflow:hidden}.mdc-button:not(.mdc-button--outlined) .mdc-button__ripple{top:0;left:0}.mdc-button--raised .mdc-button__ripple::before,.mdc-button--raised .mdc-button__ripple::after,.mdc-button--unelevated .mdc-button__ripple::before,.mdc-button--unelevated .mdc-button__ripple::after{background-color:#fff;background-color:var(--mdc-theme-on-primary, #fff)}.mdc-button--raised:hover .mdc-button__ripple::before,.mdc-button--unelevated:hover .mdc-button__ripple::before{opacity:.08}.mdc-button--raised.mdc-ripple-upgraded--background-focused .mdc-button__ripple::before,.mdc-button--raised:not(.mdc-ripple-upgraded):focus .mdc-button__ripple::before,.mdc-button--unelevated.mdc-ripple-upgraded--background-focused .mdc-button__ripple::before,.mdc-button--unelevated:not(.mdc-ripple-upgraded):focus .mdc-button__ripple::before{transition-duration:75ms;opacity:.24}.mdc-button--raised:not(.mdc-ripple-upgraded) .mdc-button__ripple::after,.mdc-button--unelevated:not(.mdc-ripple-upgraded) .mdc-button__ripple::after{transition:opacity 150ms linear}.mdc-button--raised:not(.mdc-ripple-upgraded):active .mdc-button__ripple::after,.mdc-button--unelevated:not(.mdc-ripple-upgraded):active .mdc-button__ripple::after{transition-duration:75ms;opacity:.24}.mdc-button--raised.mdc-ripple-upgraded,.mdc-button--unelevated.mdc-ripple-upgraded{--mdc-ripple-fg-opacity: 0.24}.mdc-button{height:36px}.trailing-icon ::slotted(*),.trailing-icon .mdc-button__icon,.leading-icon ::slotted(*),.leading-icon .mdc-button__icon{margin-left:0;margin-right:8px;display:inline-block;width:18px;height:18px;font-size:18px;vertical-align:top}[dir=rtl] .trailing-icon ::slotted(*),.trailing-icon ::slotted(*)[dir=rtl],[dir=rtl] .trailing-icon .mdc-button__icon,.trailing-icon .mdc-button__icon[dir=rtl],[dir=rtl] .leading-icon ::slotted(*),.leading-icon ::slotted(*)[dir=rtl],[dir=rtl] .leading-icon .mdc-button__icon,.leading-icon .mdc-button__icon[dir=rtl]{margin-left:8px;margin-right:0}.trailing-icon ::slotted(*),.trailing-icon .mdc-button__icon{margin-left:8px;margin-right:0}[dir=rtl] .trailing-icon ::slotted(*),.trailing-icon ::slotted(*)[dir=rtl],[dir=rtl] .trailing-icon .mdc-button__icon,.trailing-icon .mdc-button__icon[dir=rtl]{margin-left:0;margin-right:8px}.mdc-button--raised{box-shadow:var(--mdc-button-raised-box-shadow, 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12))}.mdc-button--raised:hover,.mdc-button--raised:focus{box-shadow:var(--mdc-button-raised-box-shadow-hover, 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12))}.mdc-button--raised:active{box-shadow:var(--mdc-button-raised-box-shadow-active, 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12))}.mdc-button--raised:disabled{box-shadow:var(--mdc-button-raised-box-shadow-disabled, 0px 0px 0px 0px rgba(0, 0, 0, 0.2), 0px 0px 0px 0px rgba(0, 0, 0, 0.14), 0px 0px 0px 0px rgba(0, 0, 0, 0.12))}:host{display:inline-flex;outline:none;vertical-align:top}:host([disabled]){pointer-events:none}:host([fullwidth]){width:100%}.mdc-button{flex:auto;overflow:hidden;padding:0 var(--mdc-button-horizontal-padding, 8px) 0 var(--mdc-button-horizontal-padding, 8px)}.mdc-button.mdc-button--raised,.mdc-button.mdc-button--unelevated{padding:0 var(--mdc-button-horizontal-padding, 16px) 0 var(--mdc-button-horizontal-padding, 16px)}.mdc-button.mdc-button--outlined{padding:0 calc(var(--mdc-button-horizontal-padding, 16px) - var(--mdc-button-outline-width, 1px)) 0 calc(var(--mdc-button-horizontal-padding, 16px) - var(--mdc-button-outline-width, 1px));border-width:var(--mdc-button-outline-width, 1px);border-color:var(--mdc-button-outline-color, var(--mdc-theme-primary, #6200ee))}.mdc-button.mdc-button--dense{height:28px;margin-top:0;margin-bottom:0}.mdc-button.mdc-button--dense .mdc-button__touch{display:none}.mdc-button .mdc-button__ripple{border-radius:0}:host([disabled]) .mdc-button.mdc-button--raised,:host([disabled]) .mdc-button.mdc-button--unelevated{background-color:var(--mdc-button-disabled-fill-color, rgba(0, 0, 0, 0.12));color:var(--mdc-button-disabled-ink-color, rgba(0, 0, 0, 0.38))}:host([disabled]) .mdc-button:not(.mdc-button--raised):not(.mdc-button--unelevated){color:var(--mdc-button-disabled-ink-color, rgba(0, 0, 0, 0.38))}:host([disabled]) .mdc-button.mdc-button--outlined{border-color:var(--mdc-button-disabled-ink-color, rgba(0, 0, 0, 0.38));border-color:var(--mdc-button-disabled-outline-color, var(--mdc-button-disabled-ink-color, rgba(0, 0, 0, 0.38)))}`;
exports.Button = class Button extends ButtonBase {
};
exports.Button.styles = style$4;
exports.Button = __decorate([
customElement('mwc-button')
], exports.Button);
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCFoundation$2 = /** @class */ (function () {
function MDCFoundation(adapter) {
if (adapter === void 0) { adapter = {}; }
this.adapter_ = adapter;
}
Object.defineProperty(MDCFoundation, "cssClasses", {
get: function () {
// Classes extending MDCFoundation should implement this method to return an object which exports every
// CSS class the foundation class needs as a property. e.g. {ACTIVE: 'mdc-component--active'}
return {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFoundation, "strings", {
get: function () {
// Classes extending MDCFoundation should implement this method to return an object which exports all
// semantic strings as constants. e.g. {ARIA_ROLE: 'tablist'}
return {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFoundation, "numbers", {
get: function () {
// Classes extending MDCFoundation should implement this method to return an object which exports all
// of its semantic numbers as constants. e.g. {ANIMATION_DELAY_MS: 350}
return {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFoundation, "defaultAdapter", {
get: function () {
// Classes extending MDCFoundation may choose to implement this getter in order to provide a convenient
// way of viewing the necessary methods of an adapter. In the future, this could also be used for adapter
// validation.
return {};
},
enumerable: true,
configurable: true
});
MDCFoundation.prototype.init = function () {
// Subclasses should override this method to perform initialization routines (registering events, etc.)
};
MDCFoundation.prototype.destroy = function () {
// Subclasses should override this method to perform de-initialization routines (de-registering events, etc.)
};
return MDCFoundation;
}());
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$w = {
ANIM_CHECKED_INDETERMINATE: 'mdc-checkbox--anim-checked-indeterminate',
ANIM_CHECKED_UNCHECKED: 'mdc-checkbox--anim-checked-unchecked',
ANIM_INDETERMINATE_CHECKED: 'mdc-checkbox--anim-indeterminate-checked',
ANIM_INDETERMINATE_UNCHECKED: 'mdc-checkbox--anim-indeterminate-unchecked',
ANIM_UNCHECKED_CHECKED: 'mdc-checkbox--anim-unchecked-checked',
ANIM_UNCHECKED_INDETERMINATE: 'mdc-checkbox--anim-unchecked-indeterminate',
BACKGROUND: 'mdc-checkbox__background',
CHECKED: 'mdc-checkbox--checked',
CHECKMARK: 'mdc-checkbox__checkmark',
CHECKMARK_PATH: 'mdc-checkbox__checkmark-path',
DISABLED: 'mdc-checkbox--disabled',
INDETERMINATE: 'mdc-checkbox--indeterminate',
MIXEDMARK: 'mdc-checkbox__mixedmark',
NATIVE_CONTROL: 'mdc-checkbox__native-control',
ROOT: 'mdc-checkbox',
SELECTED: 'mdc-checkbox--selected',
UPGRADED: 'mdc-checkbox--upgraded',
};
var strings$z = {
ARIA_CHECKED_ATTR: 'aria-checked',
ARIA_CHECKED_INDETERMINATE_VALUE: 'mixed',
NATIVE_CONTROL_SELECTOR: '.mdc-checkbox__native-control',
TRANSITION_STATE_CHECKED: 'checked',
TRANSITION_STATE_INDETERMINATE: 'indeterminate',
TRANSITION_STATE_INIT: 'init',
TRANSITION_STATE_UNCHECKED: 'unchecked',
};
var numbers$e = {
ANIM_END_LATCH_MS: 250,
};
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCCheckboxFoundation$1 = /** @class */ (function (_super) {
__extends(MDCCheckboxFoundation, _super);
function MDCCheckboxFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCCheckboxFoundation.defaultAdapter, adapter)) || this;
_this.currentCheckState_ = strings$z.TRANSITION_STATE_INIT;
_this.currentAnimationClass_ = '';
_this.animEndLatchTimer_ = 0;
_this.enableAnimationEndHandler_ = false;
return _this;
}
Object.defineProperty(MDCCheckboxFoundation, "cssClasses", {
get: function () {
return cssClasses$w;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCCheckboxFoundation, "strings", {
get: function () {
return strings$z;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCCheckboxFoundation, "numbers", {
get: function () {
return numbers$e;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCCheckboxFoundation, "defaultAdapter", {
get: function () {
return {
addClass: function () { return undefined; },
forceLayout: function () { return undefined; },
hasNativeControl: function () { return false; },
isAttachedToDOM: function () { return false; },
isChecked: function () { return false; },
isIndeterminate: function () { return false; },
removeClass: function () { return undefined; },
removeNativeControlAttr: function () { return undefined; },
setNativeControlAttr: function () { return undefined; },
setNativeControlDisabled: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCCheckboxFoundation.prototype.init = function () {
this.currentCheckState_ = this.determineCheckState_();
this.updateAriaChecked_();
this.adapter_.addClass(cssClasses$w.UPGRADED);
};
MDCCheckboxFoundation.prototype.destroy = function () {
clearTimeout(this.animEndLatchTimer_);
};
MDCCheckboxFoundation.prototype.setDisabled = function (disabled) {
this.adapter_.setNativeControlDisabled(disabled);
if (disabled) {
this.adapter_.addClass(cssClasses$w.DISABLED);
}
else {
this.adapter_.removeClass(cssClasses$w.DISABLED);
}
};
/**
* Handles the animationend event for the checkbox
*/
MDCCheckboxFoundation.prototype.handleAnimationEnd = function () {
var _this = this;
if (!this.enableAnimationEndHandler_) {
return;
}
clearTimeout(this.animEndLatchTimer_);
this.animEndLatchTimer_ = setTimeout(function () {
_this.adapter_.removeClass(_this.currentAnimationClass_);
_this.enableAnimationEndHandler_ = false;
}, numbers$e.ANIM_END_LATCH_MS);
};
/**
* Handles the change event for the checkbox
*/
MDCCheckboxFoundation.prototype.handleChange = function () {
this.transitionCheckState_();
};
MDCCheckboxFoundation.prototype.transitionCheckState_ = function () {
if (!this.adapter_.hasNativeControl()) {
return;
}
var oldState = this.currentCheckState_;
var newState = this.determineCheckState_();
if (oldState === newState) {
return;
}
this.updateAriaChecked_();
var TRANSITION_STATE_UNCHECKED = strings$z.TRANSITION_STATE_UNCHECKED;
var SELECTED = cssClasses$w.SELECTED;
if (newState === TRANSITION_STATE_UNCHECKED) {
this.adapter_.removeClass(SELECTED);
}
else {
this.adapter_.addClass(SELECTED);
}
// Check to ensure that there isn't a previously existing animation class, in case for example
// the user interacted with the checkbox before the animation was finished.
if (this.currentAnimationClass_.length > 0) {
clearTimeout(this.animEndLatchTimer_);
this.adapter_.forceLayout();
this.adapter_.removeClass(this.currentAnimationClass_);
}
this.currentAnimationClass_ = this.getTransitionAnimationClass_(oldState, newState);
this.currentCheckState_ = newState;
// Check for parentNode so that animations are only run when the element is attached
// to the DOM.
if (this.adapter_.isAttachedToDOM() && this.currentAnimationClass_.length > 0) {
this.adapter_.addClass(this.currentAnimationClass_);
this.enableAnimationEndHandler_ = true;
}
};
MDCCheckboxFoundation.prototype.determineCheckState_ = function () {
var TRANSITION_STATE_INDETERMINATE = strings$z.TRANSITION_STATE_INDETERMINATE, TRANSITION_STATE_CHECKED = strings$z.TRANSITION_STATE_CHECKED, TRANSITION_STATE_UNCHECKED = strings$z.TRANSITION_STATE_UNCHECKED;
if (this.adapter_.isIndeterminate()) {
return TRANSITION_STATE_INDETERMINATE;
}
return this.adapter_.isChecked() ? TRANSITION_STATE_CHECKED : TRANSITION_STATE_UNCHECKED;
};
MDCCheckboxFoundation.prototype.getTransitionAnimationClass_ = function (oldState, newState) {
var TRANSITION_STATE_INIT = strings$z.TRANSITION_STATE_INIT, TRANSITION_STATE_CHECKED = strings$z.TRANSITION_STATE_CHECKED, TRANSITION_STATE_UNCHECKED = strings$z.TRANSITION_STATE_UNCHECKED;
var _a = MDCCheckboxFoundation.cssClasses, ANIM_UNCHECKED_CHECKED = _a.ANIM_UNCHECKED_CHECKED, ANIM_UNCHECKED_INDETERMINATE = _a.ANIM_UNCHECKED_INDETERMINATE, ANIM_CHECKED_UNCHECKED = _a.ANIM_CHECKED_UNCHECKED, ANIM_CHECKED_INDETERMINATE = _a.ANIM_CHECKED_INDETERMINATE, ANIM_INDETERMINATE_CHECKED = _a.ANIM_INDETERMINATE_CHECKED, ANIM_INDETERMINATE_UNCHECKED = _a.ANIM_INDETERMINATE_UNCHECKED;
switch (oldState) {
case TRANSITION_STATE_INIT:
if (newState === TRANSITION_STATE_UNCHECKED) {
return '';
}
return newState === TRANSITION_STATE_CHECKED ? ANIM_INDETERMINATE_CHECKED : ANIM_INDETERMINATE_UNCHECKED;
case TRANSITION_STATE_UNCHECKED:
return newState === TRANSITION_STATE_CHECKED ? ANIM_UNCHECKED_CHECKED : ANIM_UNCHECKED_INDETERMINATE;
case TRANSITION_STATE_CHECKED:
return newState === TRANSITION_STATE_UNCHECKED ? ANIM_CHECKED_UNCHECKED : ANIM_CHECKED_INDETERMINATE;
default: // TRANSITION_STATE_INDETERMINATE
return newState === TRANSITION_STATE_CHECKED ? ANIM_INDETERMINATE_CHECKED : ANIM_INDETERMINATE_UNCHECKED;
}
};
MDCCheckboxFoundation.prototype.updateAriaChecked_ = function () {
// Ensure aria-checked is set to mixed if checkbox is in indeterminate state.
if (this.adapter_.isIndeterminate()) {
this.adapter_.setNativeControlAttr(strings$z.ARIA_CHECKED_ATTR, strings$z.ARIA_CHECKED_INDETERMINATE_VALUE);
}
else {
// The on/off state does not need to keep track of aria-checked, since
// the screenreader uses the checked property on the checkbox element.
this.adapter_.removeNativeControlAttr(strings$z.ARIA_CHECKED_ATTR);
}
};
return MDCCheckboxFoundation;
}(MDCFoundation$2));
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
function matches$3(element, selector) {
var nativeMatches = element.matches
|| element.webkitMatchesSelector
|| element.msMatchesSelector;
return nativeMatches.call(element, selector);
}
/**
@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.
*/
/**
* Determines whether a node is an element.
*
* @param node Node to check
*/
const isNodeElement = (node) => {
return node.nodeType === Node.ELEMENT_NODE;
};
function findAssignedElement(slot, selector) {
for (const node of slot.assignedNodes({ flatten: true })) {
if (isNodeElement(node)) {
const el = node;
if (matches$3(el, selector)) {
return el;
}
}
}
return null;
}
function addHasRemoveClass(element) {
return {
addClass: (className) => {
element.classList.add(className);
},
removeClass: (className) => {
element.classList.remove(className);
},
hasClass: (className) => element.classList.contains(className),
};
}
let supportsPassive = false;
const fn = () => { };
const optionsBlock = {
get passive() {
supportsPassive = true;
return false;
}
};
document.addEventListener('x', fn, optionsBlock);
document.removeEventListener('x', fn);
/**
* Do event listeners suport the `passive` option?
*/
const supportsPassiveEventListener = supportsPassive;
const deepActiveElementPath = (doc = window.document) => {
let activeElement = doc.activeElement;
const path = [];
if (!activeElement) {
return path;
}
while (activeElement) {
path.push(activeElement);
if (activeElement.shadowRoot) {
activeElement = activeElement.shadowRoot.activeElement;
}
else {
break;
}
}
return path;
};
const doesElementContainFocus = (element) => {
const activePath = deepActiveElementPath();
if (!activePath.length) {
return false;
}
const deepActiveElement = activePath[activePath.length - 1];
const focusEv = new Event('check-if-focused', { bubbles: true, composed: true });
let composedPath = [];
const listener = (ev) => {
composedPath = ev.composedPath();
};
document.body.addEventListener('check-if-focused', listener);
deepActiveElement.dispatchEvent(focusEv);
document.body.removeEventListener('check-if-focused', listener);
return composedPath.indexOf(element) !== -1;
};
/**
@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.
*/
class BaseElement extends LitElement {
/**
* Create and attach the MDC Foundation to the instance
*/
createFoundation() {
if (this.mdcFoundation !== undefined) {
this.mdcFoundation.destroy();
}
if (this.mdcFoundationClass) {
this.mdcFoundation = new this.mdcFoundationClass(this.createAdapter());
this.mdcFoundation.init();
}
}
firstUpdated() {
this.createFoundation();
}
}
/**
@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.
*/
class FormElement extends BaseElement {
createRenderRoot() {
return this.attachShadow({ mode: 'open', delegatesFocus: true });
}
click() {
if (this.formElement) {
this.formElement.focus();
this.formElement.click();
}
}
setAriaLabel(label) {
if (this.formElement) {
this.formElement.setAttribute('aria-label', label);
}
}
firstUpdated() {
super.firstUpdated();
this.mdcRoot.addEventListener('change', (e) => {
this.dispatchEvent(new Event('change', e));
});
}
}
const observer = (observer) =>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(proto, propName) => {
// if we haven't wrapped `updated` in this class, do so
if (!proto.constructor._observers) {
proto.constructor._observers = new Map();
const userUpdated = proto.updated;
proto.updated = function (changedProperties) {
userUpdated.call(this, changedProperties);
changedProperties.forEach((v, k) => {
const observer = this.constructor._observers.get(k);
if (observer !== undefined) {
observer.call(this, this[k], v);
}
});
};
// clone any existing observers (superclasses)
}
else if (!proto.constructor.hasOwnProperty('_observers')) {
const observers = proto.constructor._observers;
proto.constructor._observers = new Map();
observers.forEach(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(v, k) => proto.constructor._observers.set(k, v));
}
// set this method
proto.constructor._observers.set(propName, observer);
};
class CheckboxBase extends FormElement {
constructor() {
super(...arguments);
this.checked = false;
this.indeterminate = false;
this.disabled = false;
this.value = '';
this.mdcFoundationClass = MDCCheckboxFoundation$1;
}
get ripple() {
return this.mdcRoot.ripple;
}
createAdapter() {
return Object.assign(Object.assign({}, addHasRemoveClass(this.mdcRoot)), { forceLayout: () => {
this.mdcRoot.offsetWidth;
}, isAttachedToDOM: () => this.isConnected, isIndeterminate: () => this.indeterminate, isChecked: () => this.checked, hasNativeControl: () => Boolean(this.formElement), setNativeControlDisabled: (disabled) => {
this.formElement.disabled = disabled;
}, setNativeControlAttr: (attr, value) => {
this.formElement.setAttribute(attr, value);
}, removeNativeControlAttr: (attr) => {
this.formElement.removeAttribute(attr);
} });
}
render() {
return html `
<div class="mdc-checkbox"
@animationend="${this._animationEndHandler}">
<input type="checkbox"
class="mdc-checkbox__native-control"
@change="${this._changeHandler}"
.indeterminate="${this.indeterminate}"
.checked="${this.checked}"
.value="${this.value}">
<div class="mdc-checkbox__background">
<svg class="mdc-checkbox__checkmark"
viewBox="0 0 24 24">
<path class="mdc-checkbox__checkmark-path"
fill="none"
d="M1.73,12.91 8.1,19.28 22.79,4.59"></path>
</svg>
<div class="mdc-checkbox__mixedmark"></div>
</div>
<div class="mdc-checkbox__ripple"></div>
</div>`;
}
firstUpdated() {
super.firstUpdated();
this.mdcRoot.ripple = rippleNode({ surfaceNode: this.mdcRoot, interactionNode: this.formElement });
}
_changeHandler() {
this.checked = this.formElement.checked;
this.indeterminate = this.formElement.indeterminate;
this.mdcFoundation.handleChange();
}
_animationEndHandler() {
this.mdcFoundation.handleAnimationEnd();
}
}
__decorate([
query('.mdc-checkbox')
], CheckboxBase.prototype, "mdcRoot", void 0);
__decorate([
query('input')
], CheckboxBase.prototype, "formElement", void 0);
__decorate([
property({ type: Boolean })
], CheckboxBase.prototype, "checked", void 0);
__decorate([
property({ type: Boolean })
], CheckboxBase.prototype, "indeterminate", void 0);
__decorate([
property({ type: Boolean }),
observer(function (value) {
this.mdcFoundation.setDisabled(value);
})
], CheckboxBase.prototype, "disabled", void 0);
__decorate([
property({ type: String })
], CheckboxBase.prototype, "value", void 0);
/**
@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.
*/
const style$5 = css `.mdc-touch-target-wrapper{display:inline}@keyframes mdc-checkbox-unchecked-checked-checkmark-path{0%,50%{stroke-dashoffset:29.7833385}50%{animation-timing-function:cubic-bezier(0, 0, 0.2, 1)}100%{stroke-dashoffset:0}}@keyframes mdc-checkbox-unchecked-indeterminate-mixedmark{0%,68.2%{transform:scaleX(0)}68.2%{animation-timing-function:cubic-bezier(0, 0, 0, 1)}100%{transform:scaleX(1)}}@keyframes mdc-checkbox-checked-unchecked-checkmark-path{from{animation-timing-function:cubic-bezier(0.4, 0, 1, 1);opacity:1;stroke-dashoffset:0}to{opacity:0;stroke-dashoffset:-29.7833385}}@keyframes mdc-checkbox-checked-indeterminate-checkmark{from{animation-timing-function:cubic-bezier(0, 0, 0.2, 1);transform:rotate(0deg);opacity:1}to{transform:rotate(45deg);opacity:0}}@keyframes mdc-checkbox-indeterminate-checked-checkmark{from{animation-timing-function:cubic-bezier(0.14, 0, 0, 1);transform:rotate(45deg);opacity:0}to{transform:rotate(360deg);opacity:1}}@keyframes mdc-checkbox-checked-indeterminate-mixedmark{from{animation-timing-function:mdc-animation-deceleration-curve-timing-function;transform:rotate(-45deg);opacity:0}to{transform:rotate(0deg);opacity:1}}@keyframes mdc-checkbox-indeterminate-checked-mixedmark{from{animation-timing-function:cubic-bezier(0.14, 0, 0, 1);transform:rotate(0deg);opacity:1}to{transform:rotate(315deg);opacity:0}}@keyframes mdc-checkbox-indeterminate-unchecked-mixedmark{0%{animation-timing-function:linear;transform:scaleX(1);opacity:1}32.8%,100%{transform:scaleX(0);opacity:0}}.mdc-checkbox{display:inline-block;position:relative;flex:0 0 18px;box-sizing:content-box;width:18px;height:18px;line-height:0;white-space:nowrap;cursor:pointer;vertical-align:bottom;padding:11px}.mdc-checkbox .mdc-checkbox__native-control:checked~.mdc-checkbox__background::before,.mdc-checkbox .mdc-checkbox__native-control:indeterminate~.mdc-checkbox__background::before{background-color:#018786;background-color:var(--mdc-theme-secondary, #018786)}.mdc-checkbox.mdc-checkbox--selected .mdc-checkbox__ripple::before,.mdc-checkbox.mdc-checkbox--selected .mdc-checkbox__ripple::after{background-color:#018786;background-color:var(--mdc-theme-secondary, #018786)}.mdc-checkbox.mdc-checkbox--selected:hover .mdc-checkbox__ripple::before{opacity:.04}.mdc-checkbox.mdc-checkbox--selected.mdc-ripple-upgraded--background-focused .mdc-checkbox__ripple::before,.mdc-checkbox.mdc-checkbox--selected:not(.mdc-ripple-upgraded):focus .mdc-checkbox__ripple::before{transition-duration:75ms;opacity:.12}.mdc-checkbox.mdc-checkbox--selected:not(.mdc-ripple-upgraded) .mdc-checkbox__ripple::after{transition:opacity 150ms linear}.mdc-checkbox.mdc-checkbox--selected:not(.mdc-ripple-upgraded):active .mdc-checkbox__ripple::after{transition-duration:75ms;opacity:.12}.mdc-checkbox.mdc-checkbox--selected.mdc-ripple-upgraded{--mdc-ripple-fg-opacity: 0.12}.mdc-checkbox.mdc-ripple-upgraded--background-focused.mdc-checkbox--selected .mdc-checkbox__ripple::before,.mdc-checkbox.mdc-ripple-upgraded--background-focused.mdc-checkbox--selected .mdc-checkbox__ripple::after{background-color:#018786;background-color:var(--mdc-theme-secondary, #018786)}.mdc-checkbox .mdc-checkbox__background{top:11px;left:11px}.mdc-checkbox .mdc-checkbox__background::before{top:-13px;left:-13px;width:40px;height:40px}.mdc-checkbox .mdc-checkbox__native-control{top:0px;right:0px;left:0px;width:40px;height:40px}.mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate)~.mdc-checkbox__background{border-color:rgba(0,0,0,.54);background-color:transparent}.mdc-checkbox__native-control:enabled:checked~.mdc-checkbox__background,.mdc-checkbox__native-control:enabled:indeterminate~.mdc-checkbox__background{border-color:#018786;border-color:var(--mdc-theme-secondary, #018786);background-color:#018786;background-color:var(--mdc-theme-secondary, #018786)}@keyframes mdc-checkbox-fade-in-background-8A000000secondary00000000secondary{0%{border-color:rgba(0,0,0,.54);background-color:transparent}50%{border-color:#018786;border-color:var(--mdc-theme-secondary, #018786);background-color:#018786;background-color:var(--mdc-theme-secondary, #018786)}}@keyframes mdc-checkbox-fade-out-background-8A000000secondary00000000secondary{0%,80%{border-color:#018786;border-color:var(--mdc-theme-secondary, #018786);background-color:#018786;background-color:var(--mdc-theme-secondary, #018786)}100%{border-color:rgba(0,0,0,.54);background-color:transparent}}.mdc-checkbox--anim-unchecked-checked .mdc-checkbox__native-control:enabled~.mdc-checkbox__background,.mdc-checkbox--anim-unchecked-indeterminate .mdc-checkbox__native-control:enabled~.mdc-checkbox__background{animation-name:mdc-checkbox-fade-in-background-8A000000secondary00000000secondary}.mdc-checkbox--anim-checked-unchecked .mdc-checkbox__native-control:enabled~.mdc-checkbox__background,.mdc-checkbox--anim-indeterminate-unchecked .mdc-checkbox__native-control:enabled~.mdc-checkbox__background{animation-name:mdc-checkbox-fade-out-background-8A000000secondary00000000secondary}.mdc-checkbox__native-control[disabled]:not(:checked):not(:indeterminate)~.mdc-checkbox__background{border-color:rgba(0,0,0,.38);background-color:transparent}.mdc-checkbox__native-control[disabled]:checked~.mdc-checkbox__background,.mdc-checkbox__native-control[disabled]:indeterminate~.mdc-checkbox__background{border-color:transparent;background-color:rgba(0,0,0,.38)}.mdc-checkbox__native-control:enabled~.mdc-checkbox__background .mdc-checkbox__checkmark{color:#fff}.mdc-checkbox__native-control:enabled~.mdc-checkbox__background .mdc-checkbox__mixedmark{border-color:#fff}.mdc-checkbox__native-control:disabled~.mdc-checkbox__background .mdc-checkbox__checkmark{color:#fff}.mdc-checkbox__native-control:disabled~.mdc-checkbox__background .mdc-checkbox__mixedmark{border-color:#fff}@media screen and (-ms-high-contrast: active){.mdc-checkbox__native-control[disabled]:not(:checked):not(:indeterminate)~.mdc-checkbox__background{border-color:GrayText;background-color:transparent}.mdc-checkbox__native-control[disabled]:checked~.mdc-checkbox__background,.mdc-checkbox__native-control[disabled]:indeterminate~.mdc-checkbox__background{border-color:GrayText;background-color:transparent}.mdc-checkbox__native-control:disabled~.mdc-checkbox__background .mdc-checkbox__checkmark{color:GrayText}.mdc-checkbox__native-control:disabled~.mdc-checkbox__background .mdc-checkbox__mixedmark{border-color:GrayText}.mdc-checkbox__mixedmark{margin:0 1px}}.mdc-checkbox--disabled{cursor:default;pointer-events:none}.mdc-checkbox__background{display:inline-flex;position:absolute;align-items:center;justify-content:center;box-sizing:border-box;width:18px;height:18px;border:2px solid currentColor;border-radius:2px;background-color:transparent;pointer-events:none;will-change:background-color,border-color;transition:background-color 90ms 0ms cubic-bezier(0.4, 0, 0.6, 1),border-color 90ms 0ms cubic-bezier(0.4, 0, 0.6, 1)}.mdc-checkbox__background .mdc-checkbox__background::before{background-color:#000;background-color:var(--mdc-theme-on-surface, #000)}.mdc-checkbox__checkmark{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;opacity:0;transition:opacity 180ms 0ms cubic-bezier(0.4, 0, 0.6, 1)}.mdc-checkbox--upgraded .mdc-checkbox__checkmark{opacity:1}.mdc-checkbox__checkmark-path{transition:stroke-dashoffset 180ms 0ms cubic-bezier(0.4, 0, 0.6, 1);stroke:currentColor;stroke-width:3.12px;stroke-dashoffset:29.7833385;stroke-dasharray:29.7833385}.mdc-checkbox__mixedmark{width:100%;height:0;transform:scaleX(0) rotate(0deg);border-width:1px;border-style:solid;opacity:0;transition:opacity 90ms 0ms cubic-bezier(0.4, 0, 0.6, 1),transform 90ms 0ms cubic-bezier(0.4, 0, 0.6, 1)}.mdc-checkbox--upgraded .mdc-checkbox__background,.mdc-checkbox--upgraded .mdc-checkbox__checkmark,.mdc-checkbox--upgraded .mdc-checkbox__checkmark-path,.mdc-checkbox--upgraded .mdc-checkbox__mixedmark{transition:none !important}.mdc-checkbox--anim-unchecked-checked .mdc-checkbox__background,.mdc-checkbox--anim-unchecked-indeterminate .mdc-checkbox__background,.mdc-checkbox--anim-checked-unchecked .mdc-checkbox__background,.mdc-checkbox--anim-indeterminate-unchecked .mdc-checkbox__background{animation-duration:180ms;animation-timing-function:linear}.mdc-checkbox--anim-unchecked-checked .mdc-checkbox__checkmark-path{animation:mdc-checkbox-unchecked-checked-checkmark-path 180ms linear 0s;transition:none}.mdc-checkbox--anim-unchecked-indeterminate .mdc-checkbox__mixedmark{animation:mdc-checkbox-unchecked-indeterminate-mixedmark 90ms linear 0s;transition:none}.mdc-checkbox--anim-checked-unchecked .mdc-checkbox__checkmark-path{animation:mdc-checkbox-checked-unchecked-checkmark-path 90ms linear 0s;transition:none}.mdc-checkbox--anim-checked-indeterminate .mdc-checkbox__checkmark{animation:mdc-checkbox-checked-indeterminate-checkmark 90ms linear 0s;transition:none}.mdc-checkbox--anim-checked-indeterminate .mdc-checkbox__mixedmark{animation:mdc-checkbox-checked-indeterminate-mixedmark 90ms linear 0s;transition:none}.mdc-checkbox--anim-indeterminate-checked .mdc-checkbox__checkmark{animation:mdc-checkbox-indeterminate-checked-checkmark 500ms linear 0s;transition:none}.mdc-checkbox--anim-indeterminate-checked .mdc-checkbox__mixedmark{animation:mdc-checkbox-indeterminate-checked-mixedmark 500ms linear 0s;transition:none}.mdc-checkbox--anim-indeterminate-unchecked .mdc-checkbox__mixedmark{animation:mdc-checkbox-indeterminate-unchecked-mixedmark 300ms linear 0s;transition:none}.mdc-checkbox__native-control:checked~.mdc-checkbox__background,.mdc-checkbox__native-control:indeterminate~.mdc-checkbox__background{transition:border-color 90ms 0ms cubic-bezier(0, 0, 0.2, 1),background-color 90ms 0ms cubic-bezier(0, 0, 0.2, 1)}.mdc-checkbox__native-control:checked~.mdc-checkbox__background .mdc-checkbox__checkmark-path,.mdc-checkbox__native-control:indeterminate~.mdc-checkbox__background .mdc-checkbox__checkmark-path{stroke-dashoffset:0}.mdc-checkbox__background::before{position:absolute;transform:scale(0, 0);border-radius:50%;opacity:0;pointer-events:none;content:"";will-change:opacity,transform;transition:opacity 90ms 0ms cubic-bezier(0.4, 0, 0.6, 1),transform 90ms 0ms cubic-bezier(0.4, 0, 0.6, 1)}.mdc-checkbox__native-control:focus~.mdc-checkbox__background::before{transform:scale(1);opacity:.12;transition:opacity 80ms 0ms cubic-bezier(0, 0, 0.2, 1),transform 80ms 0ms cubic-bezier(0, 0, 0.2, 1)}.mdc-checkbox__native-control{position:absolute;margin:0;padding:0;opacity:0;cursor:inherit}.mdc-checkbox__native-control:disabled{cursor:default;pointer-events:none}.mdc-checkbox--touch{margin-top:4px;margin-bottom:4px;margin-right:4px;margin-left:4px}.mdc-checkbox--touch .mdc-checkbox__native-control{top:-4px;right:-4px;left:-4px;width:48px;height:48px}.mdc-checkbox__native-control:checked~.mdc-checkbox__background .mdc-checkbox__checkmark{transition:opacity 180ms 0ms cubic-bezier(0, 0, 0.2, 1),transform 180ms 0ms cubic-bezier(0, 0, 0.2, 1);opacity:1}.mdc-checkbox__native-control:checked~.mdc-checkbox__background .mdc-checkbox__mixedmark{transform:scaleX(1) rotate(-45deg)}.mdc-checkbox__native-control:indeterminate~.mdc-checkbox__background .mdc-checkbox__checkmark{transform:rotate(45deg);opacity:0;transition:opacity 90ms 0ms cubic-bezier(0.4, 0, 0.6, 1),transform 90ms 0ms cubic-bezier(0.4, 0, 0.6, 1)}.mdc-checkbox__native-control:indeterminate~.mdc-checkbox__background .mdc-checkbox__mixedmark{transform:scaleX(1) rotate(0deg);opacity:1}@keyframes mdc-ripple-fg-radius-in{from{animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transform:translate(var(--mdc-ripple-fg-translate-start, 0)) scale(1)}to{transform:translate(var(--mdc-ripple-fg-translate-end, 0)) scale(var(--mdc-ripple-fg-scale, 1))}}@keyframes mdc-ripple-fg-opacity-in{from{animation-timing-function:linear;opacity:0}to{opacity:var(--mdc-ripple-fg-opacity, 0)}}@keyframes mdc-ripple-fg-opacity-out{from{animation-timing-function:linear;opacity:var(--mdc-ripple-fg-opacity, 0)}to{opacity:0}}.mdc-checkbox{--mdc-ripple-fg-size: 0;--mdc-ripple-left: 0;--mdc-ripple-top: 0;--mdc-ripple-fg-scale: 1;--mdc-ripple-fg-translate-end: 0;--mdc-ripple-fg-translate-start: 0;-webkit-tap-highlight-color:rgba(0,0,0,0)}.mdc-checkbox .mdc-checkbox__ripple::before,.mdc-checkbox .mdc-checkbox__ripple::after{position:absolute;border-radius:50%;opacity:0;pointer-events:none;content:""}.mdc-checkbox .mdc-checkbox__ripple::before{transition:opacity 15ms linear,background-color 15ms linear;z-index:1}.mdc-checkbox.mdc-ripple-upgraded .mdc-checkbox__ripple::before{transform:scale(var(--mdc-ripple-fg-scale, 1))}.mdc-checkbox.mdc-ripple-upgraded .mdc-checkbox__ripple::after{top:0;left:0;transform:scale(0);transform-origin:center center}.mdc-checkbox.mdc-ripple-upgraded--unbounded .mdc-checkbox__ripple::after{top:var(--mdc-ripple-top, 0);left:var(--mdc-ripple-left, 0)}.mdc-checkbox.mdc-ripple-upgraded--foreground-activation .mdc-checkbox__ripple::after{animation:mdc-ripple-fg-radius-in 225ms forwards,mdc-ripple-fg-opacity-in 75ms forwards}.mdc-checkbox.mdc-ripple-upgraded--foreground-deactivation .mdc-checkbox__ripple::after{animation:mdc-ripple-fg-opacity-out 150ms;transform:translate(var(--mdc-ripple-fg-translate-end, 0)) scale(var(--mdc-ripple-fg-scale, 1))}.mdc-checkbox .mdc-checkbox__ripple::before,.mdc-checkbox .mdc-checkbox__ripple::after{background-color:#000;background-color:var(--mdc-theme-on-surface, #000)}.mdc-checkbox:hover .mdc-checkbox__ripple::before{opacity:.04}.mdc-checkbox.mdc-ripple-upgraded--background-focused .mdc-checkbox__ripple::before,.mdc-checkbox:not(.mdc-ripple-upgraded):focus .mdc-checkbox__ripple::before{transition-duration:75ms;opacity:.12}.mdc-checkbox:not(.mdc-ripple-upgraded) .mdc-checkbox__ripple::after{transition:opacity 150ms linear}.mdc-checkbox:not(.mdc-ripple-upgraded):active .mdc-checkbox__ripple::after{transition-duration:75ms;opacity:.12}.mdc-checkbox.mdc-ripple-upgraded{--mdc-ripple-fg-opacity: 0.12}.mdc-checkbox .mdc-checkbox__ripple::before,.mdc-checkbox .mdc-checkbox__ripple::after{top:calc(50% - 50%);left:calc(50% - 50%);width:100%;height:100%}.mdc-checkbox.mdc-ripple-upgraded .mdc-checkbox__ripple::before,.mdc-checkbox.mdc-ripple-upgraded .mdc-checkbox__ripple::after{top:var(--mdc-ripple-top, calc(50% - 50%));left:var(--mdc-ripple-left, calc(50% - 50%));width:var(--mdc-ripple-fg-size, 100%);height:var(--mdc-ripple-fg-size, 100%)}.mdc-checkbox.mdc-ripple-upgraded .mdc-checkbox__ripple::after{width:var(--mdc-ripple-fg-size, 100%);height:var(--mdc-ripple-fg-size, 100%)}.mdc-checkbox__ripple{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none}.mdc-ripple-upgraded--background-focused .mdc-checkbox__background::before{content:none}:host{outline:none;display:inline-block}.mdc-checkbox .mdc-checkbox__native-control:focus~.mdc-checkbox__background::before{background-color:var(--mdc-checkbox-unchecked-color, rgba(0, 0, 0, 0.54))}.mdc-checkbox__native-control[disabled]:not(:checked):not(:indeterminate)~.mdc-checkbox__background{border-color:var(--mdc-checkbox-disabled-color, rgba(0, 0, 0, 0.38));background-color:transparent}.mdc-checkbox__native-control[disabled]:checked~.mdc-checkbox__background,.mdc-checkbox__native-control[disabled]:indeterminate~.mdc-checkbox__background{border-color:transparent;background-color:var(--mdc-checkbox-disabled-color, rgba(0, 0, 0, 0.38))}.mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate)~.mdc-checkbox__background{border-color:var(--mdc-checkbox-unchecked-color, rgba(0, 0, 0, 0.54));background-color:transparent}.mdc-checkbox__native-control:enabled:checked~.mdc-checkbox__background,.mdc-checkbox__native-control:enabled:indeterminate~.mdc-checkbox__background{border-color:#018786;border-color:var(--mdc-theme-secondary, #018786);background-color:#018786;background-color:var(--mdc-theme-secondary, #018786)}@keyframes mdc-checkbox-fade-in-background---mdc-checkbox-unchecked-colorsecondary00000000secondary{0%{border-color:var(--mdc-checkbox-unchecked-color, rgba(0, 0, 0, 0.54));background-color:transparent}50%{border-color:#018786;border-color:var(--mdc-theme-secondary, #018786);background-color:#018786;background-color:var(--mdc-theme-secondary, #018786)}}@keyframes mdc-checkbox-fade-out-background---mdc-checkbox-unchecked-colorsecondary00000000secondary{0%,80%{border-color:#018786;border-color:var(--mdc-theme-secondary, #018786);background-color:#018786;background-color:var(--mdc-theme-secondary, #018786)}100%{border-color:var(--mdc-checkbox-unchecked-color, rgba(0, 0, 0, 0.54));background-color:transparent}}.mdc-checkbox--anim-unchecked-checked .mdc-checkbox__native-control:enabled~.mdc-checkbox__background,.mdc-checkbox--anim-unchecked-indeterminate .mdc-checkbox__native-control:enabled~.mdc-checkbox__background{animation-name:mdc-checkbox-fade-in-background---mdc-checkbox-unchecked-colorsecondary00000000secondary}.mdc-checkbox--anim-checked-unchecked .mdc-checkbox__native-control:enabled~.mdc-checkbox__background,.mdc-checkbox--anim-indeterminate-unchecked .mdc-checkbox__native-control:enabled~.mdc-checkbox__background{animation-name:mdc-checkbox-fade-out-background---mdc-checkbox-unchecked-colorsecondary00000000secondary}.mdc-checkbox__native-control:enabled~.mdc-checkbox__background .mdc-checkbox__checkmark{color:var(--mdc-checkbox-mark-color, #fff)}.mdc-checkbox__native-control:enabled~.mdc-checkbox__background .mdc-checkbox__mixedmark{border-color:var(--mdc-checkbox-mark-color, #fff)}.mdc-checkbox__native-control:disabled~.mdc-checkbox__background .mdc-checkbox__checkmark{color:var(--mdc-checkbox-mark-color, #fff)}.mdc-checkbox__native-control:disabled~.mdc-checkbox__background .mdc-checkbox__mixedmark{border-color:var(--mdc-checkbox-mark-color, #fff)}`;
exports.Checkbox = class Checkbox extends CheckboxBase {
};
exports.Checkbox.styles = style$5;
exports.Checkbox = __decorate([
customElement('mwc-checkbox')
], exports.Checkbox);
/**
* @license
* Copyright 2016 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.
*/
(() => {
var _a, _b, _c;
/* Symbols for private properties */
const _blockingElements = Symbol();
const _alreadyInertElements = Symbol();
const _topElParents = Symbol();
const _siblingsToRestore = Symbol();
const _parentMO = Symbol();
/* Symbols for private static methods */
const _topChanged = Symbol();
const _swapInertedSibling = Symbol();
const _inertSiblings = Symbol();
const _restoreInertedSiblings = Symbol();
const _getParents = Symbol();
const _getDistributedChildren = Symbol();
const _isInertable = Symbol();
const _handleMutations = Symbol();
class BlockingElementsImpl {
constructor() {
/**
* The blocking elements.
*/
this[_a] = [];
/**
* Used to keep track of the parents of the top element, from the element
* itself up to body. When top changes, the old top might have been removed
* from the document, so we need to memoize the inerted parents' siblings
* in order to restore their inerteness when top changes.
*/
this[_b] = [];
/**
* Elements that are already inert before the first blocking element is
* pushed.
*/
this[_c] = new Set();
}
destructor() {
// Restore original inertness.
this[_restoreInertedSiblings](this[_topElParents]);
// Note we don't want to make these properties nullable on the class,
// since then we'd need non-null casts in many places. Calling a method on
// a BlockingElements instance after calling destructor will result in an
// exception.
const nullable = this;
nullable[_blockingElements] = null;
nullable[_topElParents] = null;
nullable[_alreadyInertElements] = null;
}
get top() {
const elems = this[_blockingElements];
return elems[elems.length - 1] || null;
}
push(element) {
if (!element || element === this.top) {
return;
}
// Remove it from the stack, we'll bring it to the top.
this.remove(element);
this[_topChanged](element);
this[_blockingElements].push(element);
}
remove(element) {
const i = this[_blockingElements].indexOf(element);
if (i === -1) {
return false;
}
this[_blockingElements].splice(i, 1);
// Top changed only if the removed element was the top element.
if (i === this[_blockingElements].length) {
this[_topChanged](this.top);
}
return true;
}
pop() {
const top = this.top;
top && this.remove(top);
return top;
}
has(element) {
return this[_blockingElements].indexOf(element) !== -1;
}
/**
* Sets `inert` to all document elements except the new top element, its
* parents, and its distributed content.
*/
[(_a = _blockingElements, _b = _topElParents, _c = _alreadyInertElements, _topChanged)](newTop) {
const toKeepInert = this[_alreadyInertElements];
const oldParents = this[_topElParents];
// No new top, reset old top if any.
if (!newTop) {
this[_restoreInertedSiblings](oldParents);
toKeepInert.clear();
this[_topElParents] = [];
return;
}
const newParents = this[_getParents](newTop);
// New top is not contained in the main document!
if (newParents[newParents.length - 1].parentNode !== document.body) {
throw Error('Non-connected element cannot be a blocking element');
}
// Cast here because we know we'll call _inertSiblings on newParents
// below.
this[_topElParents] = newParents;
const toSkip = this[_getDistributedChildren](newTop);
// No previous top element.
if (!oldParents.length) {
this[_inertSiblings](newParents, toSkip, toKeepInert);
return;
}
let i = oldParents.length - 1;
let j = newParents.length - 1;
// Find common parent. Index 0 is the element itself (so stop before it).
while (i > 0 && j > 0 && oldParents[i] === newParents[j]) {
i--;
j--;
}
// If up the parents tree there are 2 elements that are siblings, swap
// the inerted sibling.
if (oldParents[i] !== newParents[j]) {
this[_swapInertedSibling](oldParents[i], newParents[j]);
}
// Restore old parents siblings inertness.
i > 0 && this[_restoreInertedSiblings](oldParents.slice(0, i));
// Make new parents siblings inert.
j > 0 && this[_inertSiblings](newParents.slice(0, j), toSkip, null);
}
/**
* Swaps inertness between two sibling elements.
* Sets the property `inert` over the attribute since the inert spec
* doesn't specify if it should be reflected.
* https://html.spec.whatwg.org/multipage/interaction.html#inert
*/
[_swapInertedSibling](oldInert, newInert) {
const siblingsToRestore = oldInert[_siblingsToRestore];
// oldInert is not contained in siblings to restore, so we have to check
// if it's inertable and if already inert.
if (this[_isInertable](oldInert) && !oldInert.inert) {
oldInert.inert = true;
siblingsToRestore.add(oldInert);
}
// If newInert was already between the siblings to restore, it means it is
// inertable and must be restored.
if (siblingsToRestore.has(newInert)) {
newInert.inert = false;
siblingsToRestore.delete(newInert);
}
newInert[_parentMO] = oldInert[_parentMO];
newInert[_siblingsToRestore] = siblingsToRestore;
oldInert[_parentMO] = undefined;
oldInert[_siblingsToRestore] = undefined;
}
/**
* Restores original inertness to the siblings of the elements.
* Sets the property `inert` over the attribute since the inert spec
* doesn't specify if it should be reflected.
* https://html.spec.whatwg.org/multipage/interaction.html#inert
*/
[_restoreInertedSiblings](elements) {
for (const element of elements) {
const mo = element[_parentMO];
mo.disconnect();
element[_parentMO] = undefined;
const siblings = element[_siblingsToRestore];
for (const sibling of siblings) {
sibling.inert = false;
}
element[_siblingsToRestore] = undefined;
}
}
/**
* Inerts the siblings of the elements except the elements to skip. Stores
* the inerted siblings into the element's symbol `_siblingsToRestore`.
* Pass `toKeepInert` to collect the already inert elements.
* Sets the property `inert` over the attribute since the inert spec
* doesn't specify if it should be reflected.
* https://html.spec.whatwg.org/multipage/interaction.html#inert
*/
[_inertSiblings](elements, toSkip, toKeepInert) {
for (const element of elements) {
// Assume element is not a Document, so it must have a parentNode.
const parent = element.parentNode;
const children = parent.children;
const inertedSiblings = new Set();
for (let j = 0; j < children.length; j++) {
const sibling = children[j];
// Skip the input element, if not inertable or to be skipped.
if (sibling === element || !this[_isInertable](sibling) ||
(toSkip && toSkip.has(sibling))) {
continue;
}
// Should be collected since already inerted.
if (toKeepInert && sibling.inert) {
toKeepInert.add(sibling);
}
else {
sibling.inert = true;
inertedSiblings.add(sibling);
}
}
// Store the siblings that were inerted.
element[_siblingsToRestore] = inertedSiblings;
// Observe only immediate children mutations on the parent.
const mo = new MutationObserver(this[_handleMutations].bind(this));
element[_parentMO] = mo;
let parentToObserve = parent;
// If we're using the ShadyDOM polyfill, then our parent could be a
// shady root, which is an object that acts like a ShadowRoot, but isn't
// actually a node in the real DOM. Observe the real DOM parent instead.
const maybeShadyRoot = parentToObserve;
if (maybeShadyRoot.__shady && maybeShadyRoot.host) {
parentToObserve = maybeShadyRoot.host;
}
mo.observe(parentToObserve, {
childList: true,
});
}
}
/**
* Handles newly added/removed nodes by toggling their inertness.
* It also checks if the current top Blocking Element has been removed,
* notifying and removing it.
*/
[_handleMutations](mutations) {
const parents = this[_topElParents];
const toKeepInert = this[_alreadyInertElements];
for (const mutation of mutations) {
// If the target is a shadowRoot, get its host as we skip shadowRoots when
// computing _topElParents.
const target = mutation.target.host || mutation.target;
const idx = target === document.body ?
parents.length :
parents.indexOf(target);
const inertedChild = parents[idx - 1];
const inertedSiblings = inertedChild[_siblingsToRestore];
// To restore.
for (let i = 0; i < mutation.removedNodes.length; i++) {
const sibling = mutation.removedNodes[i];
if (sibling === inertedChild) {
console.info('Detected removal of the top Blocking Element.');
this.pop();
return;
}
if (inertedSiblings.has(sibling)) {
sibling.inert = false;
inertedSiblings.delete(sibling);
}
}
// To inert.
for (let i = 0; i < mutation.addedNodes.length; i++) {
const sibling = mutation.addedNodes[i];
if (!this[_isInertable](sibling)) {
continue;
}
if (toKeepInert && sibling.inert) {
toKeepInert.add(sibling);
}
else {
sibling.inert = true;
inertedSiblings.add(sibling);
}
}
}
}
/**
* Returns if the element is inertable.
*/
[_isInertable](element) {
return false === /^(style|template|script)$/.test(element.localName);
}
/**
* Returns the list of newParents of an element, starting from element
* (included) up to `document.body` (excluded).
*/
[_getParents](element) {
const parents = [];
let current = element;
// Stop to body.
while (current && current !== document.body) {
// Skip shadow roots.
if (current.nodeType === Node.ELEMENT_NODE) {
parents.push(current);
}
// ShadowDom v1
if (current.assignedSlot) {
// Collect slots from deepest slot to top.
while (current = current.assignedSlot) {
parents.push(current);
}
// Continue the search on the top slot.
current = parents.pop();
continue;
}
current = current.parentNode ||
current.host;
}
return parents;
}
/**
* Returns the distributed children of the element's shadow root.
* Returns null if the element doesn't have a shadow root.
*/
[_getDistributedChildren](element) {
const shadowRoot = element.shadowRoot;
if (!shadowRoot) {
return null;
}
const result = new Set();
let i;
let j;
let nodes;
const slots = shadowRoot.querySelectorAll('slot');
if (slots.length && slots[0].assignedNodes) {
for (i = 0; i < slots.length; i++) {
nodes = slots[i].assignedNodes({
flatten: true,
});
for (j = 0; j < nodes.length; j++) {
if (nodes[j].nodeType === Node.ELEMENT_NODE) {
result.add(nodes[j]);
}
}
}
// No need to search for <content>.
}
return result;
}
}
document.$blockingElements =
new BlockingElementsImpl();
})();
/**
* This work is licensed under the W3C Software and Document License
* (http://www.w3.org/Consortium/Legal/2015/copyright-software-and-document).
*/
(function() {
// Return early if we're not running inside of the browser.
if (typeof window === 'undefined') {
return;
}
// Convenience function for converting NodeLists.
/** @type {typeof Array.prototype.slice} */
const slice = Array.prototype.slice;
/**
* IE has a non-standard name for "matches".
* @type {typeof Element.prototype.matches}
*/
const matches =
Element.prototype.matches || Element.prototype.msMatchesSelector;
/** @type {string} */
const _focusableElementsString = ['a[href]',
'area[href]',
'input:not([disabled])',
'select:not([disabled])',
'textarea:not([disabled])',
'button:not([disabled])',
'details',
'summary',
'iframe',
'object',
'embed',
'[contenteditable]'].join(',');
/**
* `InertRoot` manages a single inert subtree, i.e. a DOM subtree whose root element has an `inert`
* attribute.
*
* Its main functions are:
*
* - to create and maintain a set of managed `InertNode`s, including when mutations occur in the
* subtree. The `makeSubtreeUnfocusable()` method handles collecting `InertNode`s via registering
* each focusable node in the subtree with the singleton `InertManager` which manages all known
* focusable nodes within inert subtrees. `InertManager` ensures that a single `InertNode`
* instance exists for each focusable node which has at least one inert root as an ancestor.
*
* - to notify all managed `InertNode`s when this subtree stops being inert (i.e. when the `inert`
* attribute is removed from the root node). This is handled in the destructor, which calls the
* `deregister` method on `InertManager` for each managed inert node.
*/
class InertRoot {
/**
* @param {!Element} rootElement The Element at the root of the inert subtree.
* @param {!InertManager} inertManager The global singleton InertManager object.
*/
constructor(rootElement, inertManager) {
/** @type {!InertManager} */
this._inertManager = inertManager;
/** @type {!Element} */
this._rootElement = rootElement;
/**
* @type {!Set<!InertNode>}
* All managed focusable nodes in this InertRoot's subtree.
*/
this._managedNodes = new Set();
// Make the subtree hidden from assistive technology
if (this._rootElement.hasAttribute('aria-hidden')) {
/** @type {?string} */
this._savedAriaHidden = this._rootElement.getAttribute('aria-hidden');
} else {
this._savedAriaHidden = null;
}
this._rootElement.setAttribute('aria-hidden', 'true');
// Make all focusable elements in the subtree unfocusable and add them to _managedNodes
this._makeSubtreeUnfocusable(this._rootElement);
// Watch for:
// - any additions in the subtree: make them unfocusable too
// - any removals from the subtree: remove them from this inert root's managed nodes
// - attribute changes: if `tabindex` is added, or removed from an intrinsically focusable
// element, make that node a managed node.
this._observer = new MutationObserver(this._onMutation.bind(this));
this._observer.observe(this._rootElement, {attributes: true, childList: true, subtree: true});
}
/**
* Call this whenever this object is about to become obsolete. This unwinds all of the state
* stored in this object and updates the state of all of the managed nodes.
*/
destructor() {
this._observer.disconnect();
if (this._rootElement) {
if (this._savedAriaHidden !== null) {
this._rootElement.setAttribute('aria-hidden', this._savedAriaHidden);
} else {
this._rootElement.removeAttribute('aria-hidden');
}
}
this._managedNodes.forEach(function(inertNode) {
this._unmanageNode(inertNode.node);
}, this);
// Note we cast the nulls to the ANY type here because:
// 1) We want the class properties to be declared as non-null, or else we
// need even more casts throughout this code. All bets are off if an
// instance has been destroyed and a method is called.
// 2) We don't want to cast "this", because we want type-aware optimizations
// to know which properties we're setting.
this._observer = /** @type {?} */ (null);
this._rootElement = /** @type {?} */ (null);
this._managedNodes = /** @type {?} */ (null);
this._inertManager = /** @type {?} */ (null);
}
/**
* @return {!Set<!InertNode>} A copy of this InertRoot's managed nodes set.
*/
get managedNodes() {
return new Set(this._managedNodes);
}
/** @return {boolean} */
get hasSavedAriaHidden() {
return this._savedAriaHidden !== null;
}
/** @param {?string} ariaHidden */
set savedAriaHidden(ariaHidden) {
this._savedAriaHidden = ariaHidden;
}
/** @return {?string} */
get savedAriaHidden() {
return this._savedAriaHidden;
}
/**
* @param {!Node} startNode
*/
_makeSubtreeUnfocusable(startNode) {
composedTreeWalk(startNode, (node) => this._visitNode(node));
let activeElement = document.activeElement;
if (!document.body.contains(startNode)) {
// startNode may be in shadow DOM, so find its nearest shadowRoot to get the activeElement.
let node = startNode;
/** @type {!ShadowRoot|undefined} */
let root = undefined;
while (node) {
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
root = /** @type {!ShadowRoot} */ (node);
break;
}
node = node.parentNode;
}
if (root) {
activeElement = root.activeElement;
}
}
if (startNode.contains(activeElement)) {
activeElement.blur();
// In IE11, if an element is already focused, and then set to tabindex=-1
// calling blur() will not actually move the focus.
// To work around this we call focus() on the body instead.
if (activeElement === document.activeElement) {
document.body.focus();
}
}
}
/**
* @param {!Node} node
*/
_visitNode(node) {
if (node.nodeType !== Node.ELEMENT_NODE) {
return;
}
const element = /** @type {!Element} */ (node);
// If a descendant inert root becomes un-inert, its descendants will still be inert because of
// this inert root, so all of its managed nodes need to be adopted by this InertRoot.
if (element !== this._rootElement && element.hasAttribute('inert')) {
this._adoptInertRoot(element);
}
if (matches.call(element, _focusableElementsString) || element.hasAttribute('tabindex')) {
this._manageNode(element);
}
}
/**
* Register the given node with this InertRoot and with InertManager.
* @param {!Node} node
*/
_manageNode(node) {
const inertNode = this._inertManager.register(node, this);
this._managedNodes.add(inertNode);
}
/**
* Unregister the given node with this InertRoot and with InertManager.
* @param {!Node} node
*/
_unmanageNode(node) {
const inertNode = this._inertManager.deregister(node, this);
if (inertNode) {
this._managedNodes.delete(inertNode);
}
}
/**
* Unregister the entire subtree starting at `startNode`.
* @param {!Node} startNode
*/
_unmanageSubtree(startNode) {
composedTreeWalk(startNode, (node) => this._unmanageNode(node));
}
/**
* If a descendant node is found with an `inert` attribute, adopt its managed nodes.
* @param {!Element} node
*/
_adoptInertRoot(node) {
let inertSubroot = this._inertManager.getInertRoot(node);
// During initialisation this inert root may not have been registered yet,
// so register it now if need be.
if (!inertSubroot) {
this._inertManager.setInert(node, true);
inertSubroot = this._inertManager.getInertRoot(node);
}
inertSubroot.managedNodes.forEach(function(savedInertNode) {
this._manageNode(savedInertNode.node);
}, this);
}
/**
* Callback used when mutation observer detects subtree additions, removals, or attribute changes.
* @param {!Array<!MutationRecord>} records
* @param {!MutationObserver} self
*/
_onMutation(records, self) {
records.forEach(function(record) {
const target = /** @type {!Element} */ (record.target);
if (record.type === 'childList') {
// Manage added nodes
slice.call(record.addedNodes).forEach(function(node) {
this._makeSubtreeUnfocusable(node);
}, this);
// Un-manage removed nodes
slice.call(record.removedNodes).forEach(function(node) {
this._unmanageSubtree(node);
}, this);
} else if (record.type === 'attributes') {
if (record.attributeName === 'tabindex') {
// Re-initialise inert node if tabindex changes
this._manageNode(target);
} else if (target !== this._rootElement &&
record.attributeName === 'inert' &&
target.hasAttribute('inert')) {
// If a new inert root is added, adopt its managed nodes and make sure it knows about the
// already managed nodes from this inert subroot.
this._adoptInertRoot(target);
const inertSubroot = this._inertManager.getInertRoot(target);
this._managedNodes.forEach(function(managedNode) {
if (target.contains(managedNode.node)) {
inertSubroot._manageNode(managedNode.node);
}
});
}
}
}, this);
}
}
/**
* `InertNode` initialises and manages a single inert node.
* A node is inert if it is a descendant of one or more inert root elements.
*
* On construction, `InertNode` saves the existing `tabindex` value for the node, if any, and
* either removes the `tabindex` attribute or sets it to `-1`, depending on whether the element
* is intrinsically focusable or not.
*
* `InertNode` maintains a set of `InertRoot`s which are descendants of this `InertNode`. When an
* `InertRoot` is destroyed, and calls `InertManager.deregister()`, the `InertManager` notifies the
* `InertNode` via `removeInertRoot()`, which in turn destroys the `InertNode` if no `InertRoot`s
* remain in the set. On destruction, `InertNode` reinstates the stored `tabindex` if one exists,
* or removes the `tabindex` attribute if the element is intrinsically focusable.
*/
class InertNode {
/**
* @param {!Node} node A focusable element to be made inert.
* @param {!InertRoot} inertRoot The inert root element associated with this inert node.
*/
constructor(node, inertRoot) {
/** @type {!Node} */
this._node = node;
/** @type {boolean} */
this._overrodeFocusMethod = false;
/**
* @type {!Set<!InertRoot>} The set of descendant inert roots.
* If and only if this set becomes empty, this node is no longer inert.
*/
this._inertRoots = new Set([inertRoot]);
/** @type {?number} */
this._savedTabIndex = null;
/** @type {boolean} */
this._destroyed = false;
// Save any prior tabindex info and make this node untabbable
this.ensureUntabbable();
}
/**
* Call this whenever this object is about to become obsolete.
* This makes the managed node focusable again and deletes all of the previously stored state.
*/
destructor() {
this._throwIfDestroyed();
if (this._node && this._node.nodeType === Node.ELEMENT_NODE) {
const element = /** @type {!Element} */ (this._node);
if (this._savedTabIndex !== null) {
element.setAttribute('tabindex', this._savedTabIndex);
} else {
element.removeAttribute('tabindex');
}
// Use `delete` to restore native focus method.
if (this._overrodeFocusMethod) {
delete element.focus;
}
}
// See note in InertRoot.destructor for why we cast these nulls to ANY.
this._node = /** @type {?} */ (null);
this._inertRoots = /** @type {?} */ (null);
this._destroyed = true;
}
/**
* @type {boolean} Whether this object is obsolete because the managed node is no longer inert.
* If the object has been destroyed, any attempt to access it will cause an exception.
*/
get destroyed() {
return /** @type {!InertNode} */ (this)._destroyed;
}
/**
* Throw if user tries to access destroyed InertNode.
*/
_throwIfDestroyed() {
if (this.destroyed) {
throw new Error('Trying to access destroyed InertNode');
}
}
/** @return {boolean} */
get hasSavedTabIndex() {
return this._savedTabIndex !== null;
}
/** @return {!Node} */
get node() {
this._throwIfDestroyed();
return this._node;
}
/** @param {?number} tabIndex */
set savedTabIndex(tabIndex) {
this._throwIfDestroyed();
this._savedTabIndex = tabIndex;
}
/** @return {?number} */
get savedTabIndex() {
this._throwIfDestroyed();
return this._savedTabIndex;
}
/** Save the existing tabindex value and make the node untabbable and unfocusable */
ensureUntabbable() {
if (this.node.nodeType !== Node.ELEMENT_NODE) {
return;
}
const element = /** @type {!Element} */ (this.node);
if (matches.call(element, _focusableElementsString)) {
if (/** @type {!HTMLElement} */ (element).tabIndex === -1 &&
this.hasSavedTabIndex) {
return;
}
if (element.hasAttribute('tabindex')) {
this._savedTabIndex = /** @type {!HTMLElement} */ (element).tabIndex;
}
element.setAttribute('tabindex', '-1');
if (element.nodeType === Node.ELEMENT_NODE) {
element.focus = function() {};
this._overrodeFocusMethod = true;
}
} else if (element.hasAttribute('tabindex')) {
this._savedTabIndex = /** @type {!HTMLElement} */ (element).tabIndex;
element.removeAttribute('tabindex');
}
}
/**
* Add another inert root to this inert node's set of managing inert roots.
* @param {!InertRoot} inertRoot
*/
addInertRoot(inertRoot) {
this._throwIfDestroyed();
this._inertRoots.add(inertRoot);
}
/**
* Remove the given inert root from this inert node's set of managing inert roots.
* If the set of managing inert roots becomes empty, this node is no longer inert,
* so the object should be destroyed.
* @param {!InertRoot} inertRoot
*/
removeInertRoot(inertRoot) {
this._throwIfDestroyed();
this._inertRoots.delete(inertRoot);
if (this._inertRoots.size === 0) {
this.destructor();
}
}
}
/**
* InertManager is a per-document singleton object which manages all inert roots and nodes.
*
* When an element becomes an inert root by having an `inert` attribute set and/or its `inert`
* property set to `true`, the `setInert` method creates an `InertRoot` object for the element.
* The `InertRoot` in turn registers itself as managing all of the element's focusable descendant
* nodes via the `register()` method. The `InertManager` ensures that a single `InertNode` instance
* is created for each such node, via the `_managedNodes` map.
*/
class InertManager {
/**
* @param {!Document} document
*/
constructor(document) {
if (!document) {
throw new Error('Missing required argument; InertManager needs to wrap a document.');
}
/** @type {!Document} */
this._document = document;
/**
* All managed nodes known to this InertManager. In a map to allow looking up by Node.
* @type {!Map<!Node, !InertNode>}
*/
this._managedNodes = new Map();
/**
* All inert roots known to this InertManager. In a map to allow looking up by Node.
* @type {!Map<!Node, !InertRoot>}
*/
this._inertRoots = new Map();
/**
* Observer for mutations on `document.body`.
* @type {!MutationObserver}
*/
this._observer = new MutationObserver(this._watchForInert.bind(this));
// Add inert style.
addInertStyle(document.head || document.body || document.documentElement);
// Wait for document to be loaded.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', this._onDocumentLoaded.bind(this));
} else {
this._onDocumentLoaded();
}
}
/**
* Set whether the given element should be an inert root or not.
* @param {!Element} root
* @param {boolean} inert
*/
setInert(root, inert) {
if (inert) {
if (this._inertRoots.has(root)) { // element is already inert
return;
}
const inertRoot = new InertRoot(root, this);
root.setAttribute('inert', '');
this._inertRoots.set(root, inertRoot);
// If not contained in the document, it must be in a shadowRoot.
// Ensure inert styles are added there.
if (!this._document.body.contains(root)) {
let parent = root.parentNode;
while (parent) {
if (parent.nodeType === 11) {
addInertStyle(parent);
}
parent = parent.parentNode;
}
}
} else {
if (!this._inertRoots.has(root)) { // element is already non-inert
return;
}
const inertRoot = this._inertRoots.get(root);
inertRoot.destructor();
this._inertRoots.delete(root);
root.removeAttribute('inert');
}
}
/**
* Get the InertRoot object corresponding to the given inert root element, if any.
* @param {!Node} element
* @return {!InertRoot|undefined}
*/
getInertRoot(element) {
return this._inertRoots.get(element);
}
/**
* Register the given InertRoot as managing the given node.
* In the case where the node has a previously existing inert root, this inert root will
* be added to its set of inert roots.
* @param {!Node} node
* @param {!InertRoot} inertRoot
* @return {!InertNode} inertNode
*/
register(node, inertRoot) {
let inertNode = this._managedNodes.get(node);
if (inertNode !== undefined) { // node was already in an inert subtree
inertNode.addInertRoot(inertRoot);
} else {
inertNode = new InertNode(node, inertRoot);
}
this._managedNodes.set(node, inertNode);
return inertNode;
}
/**
* De-register the given InertRoot as managing the given inert node.
* Removes the inert root from the InertNode's set of managing inert roots, and remove the inert
* node from the InertManager's set of managed nodes if it is destroyed.
* If the node is not currently managed, this is essentially a no-op.
* @param {!Node} node
* @param {!InertRoot} inertRoot
* @return {?InertNode} The potentially destroyed InertNode associated with this node, if any.
*/
deregister(node, inertRoot) {
const inertNode = this._managedNodes.get(node);
if (!inertNode) {
return null;
}
inertNode.removeInertRoot(inertRoot);
if (inertNode.destroyed) {
this._managedNodes.delete(node);
}
return inertNode;
}
/**
* Callback used when document has finished loading.
*/
_onDocumentLoaded() {
// Find all inert roots in document and make them actually inert.
const inertElements = slice.call(this._document.querySelectorAll('[inert]'));
inertElements.forEach(function(inertElement) {
this.setInert(inertElement, true);
}, this);
// Comment this out to use programmatic API only.
this._observer.observe(this._document.body || this._document.documentElement, {attributes: true, subtree: true, childList: true});
}
/**
* Callback used when mutation observer detects attribute changes.
* @param {!Array<!MutationRecord>} records
* @param {!MutationObserver} self
*/
_watchForInert(records, self) {
const _this = this;
records.forEach(function(record) {
switch (record.type) {
case 'childList':
slice.call(record.addedNodes).forEach(function(node) {
if (node.nodeType !== Node.ELEMENT_NODE) {
return;
}
const inertElements = slice.call(node.querySelectorAll('[inert]'));
if (matches.call(node, '[inert]')) {
inertElements.unshift(node);
}
inertElements.forEach(function(inertElement) {
this.setInert(inertElement, true);
}, _this);
}, _this);
break;
case 'attributes':
if (record.attributeName !== 'inert') {
return;
}
const target = /** @type {!Element} */ (record.target);
const inert = target.hasAttribute('inert');
_this.setInert(target, inert);
break;
}
}, this);
}
}
/**
* Recursively walk the composed tree from |node|.
* @param {!Node} node
* @param {(function (!Element))=} callback Callback to be called for each element traversed,
* before descending into child nodes.
* @param {?ShadowRoot=} shadowRootAncestor The nearest ShadowRoot ancestor, if any.
*/
function composedTreeWalk(node, callback, shadowRootAncestor) {
if (node.nodeType == Node.ELEMENT_NODE) {
const element = /** @type {!Element} */ (node);
if (callback) {
callback(element);
}
// Descend into node:
// If it has a ShadowRoot, ignore all child elements - these will be picked
// up by the <content> or <shadow> elements. Descend straight into the
// ShadowRoot.
const shadowRoot = /** @type {!HTMLElement} */ (element).shadowRoot;
if (shadowRoot) {
composedTreeWalk(shadowRoot, callback);
return;
}
// If it is a <content> element, descend into distributed elements - these
// are elements from outside the shadow root which are rendered inside the
// shadow DOM.
if (element.localName == 'content') {
const content = /** @type {!HTMLContentElement} */ (element);
// Verifies if ShadowDom v0 is supported.
const distributedNodes = content.getDistributedNodes ?
content.getDistributedNodes() : [];
for (let i = 0; i < distributedNodes.length; i++) {
composedTreeWalk(distributedNodes[i], callback);
}
return;
}
// If it is a <slot> element, descend into assigned nodes - these
// are elements from outside the shadow root which are rendered inside the
// shadow DOM.
if (element.localName == 'slot') {
const slot = /** @type {!HTMLSlotElement} */ (element);
// Verify if ShadowDom v1 is supported.
const distributedNodes = slot.assignedNodes ?
slot.assignedNodes({flatten: true}) : [];
for (let i = 0; i < distributedNodes.length; i++) {
composedTreeWalk(distributedNodes[i], callback);
}
return;
}
}
// If it is neither the parent of a ShadowRoot, a <content> element, a <slot>
// element, nor a <shadow> element recurse normally.
let child = node.firstChild;
while (child != null) {
composedTreeWalk(child, callback);
child = child.nextSibling;
}
}
/**
* Adds a style element to the node containing the inert specific styles
* @param {!Node} node
*/
function addInertStyle(node) {
if (node.querySelector('style#inert-style, link#inert-style')) {
return;
}
const style = document.createElement('style');
style.setAttribute('id', 'inert-style');
style.textContent = '\n'+
'[inert] {\n' +
' pointer-events: none;\n' +
' cursor: default;\n' +
'}\n' +
'\n' +
'[inert], [inert] * {\n' +
' -webkit-user-select: none;\n' +
' -moz-user-select: none;\n' +
' -ms-user-select: none;\n' +
' user-select: none;\n' +
'}\n';
node.appendChild(style);
}
/** @type {!InertManager} */
const inertManager = new InertManager(document);
if (!Element.prototype.hasOwnProperty('inert')) {
Object.defineProperty(Element.prototype, 'inert', {
enumerable: true,
/** @this {!Element} */
get: function() {
return this.hasAttribute('inert');
},
/** @this {!Element} */
set: function(inert) {
inertManager.setInert(this, inert);
},
});
}
})();
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var cssClasses$x = {
CLOSING: 'mdc-dialog--closing',
OPEN: 'mdc-dialog--open',
OPENING: 'mdc-dialog--opening',
SCROLLABLE: 'mdc-dialog--scrollable',
SCROLL_LOCK: 'mdc-dialog-scroll-lock',
STACKED: 'mdc-dialog--stacked',
};
var strings$A = {
ACTION_ATTRIBUTE: 'data-mdc-dialog-action',
BUTTON_DEFAULT_ATTRIBUTE: 'data-mdc-dialog-button-default',
BUTTON_SELECTOR: '.mdc-dialog__button',
CLOSED_EVENT: 'MDCDialog:closed',
CLOSE_ACTION: 'close',
CLOSING_EVENT: 'MDCDialog:closing',
CONTAINER_SELECTOR: '.mdc-dialog__container',
CONTENT_SELECTOR: '.mdc-dialog__content',
DESTROY_ACTION: 'destroy',
INITIAL_FOCUS_ATTRIBUTE: 'data-mdc-dialog-initial-focus',
OPENED_EVENT: 'MDCDialog:opened',
OPENING_EVENT: 'MDCDialog:opening',
SCRIM_SELECTOR: '.mdc-dialog__scrim',
SUPPRESS_DEFAULT_PRESS_SELECTOR: [
'textarea',
'.mdc-menu .mdc-list-item',
].join(', '),
SURFACE_SELECTOR: '.mdc-dialog__surface',
};
var numbers$f = {
DIALOG_ANIMATION_CLOSE_TIME_MS: 75,
DIALOG_ANIMATION_OPEN_TIME_MS: 150,
};
/**
* @license
* Copyright 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCFoundation$3 = /** @class */ (function () {
function MDCFoundation(adapter) {
if (adapter === void 0) { adapter = {}; }
this.adapter_ = adapter;
}
Object.defineProperty(MDCFoundation, "cssClasses", {
get: function () {
// Classes extending MDCFoundation should implement this method to return an object which exports every
// CSS class the foundation class needs as a property. e.g. {ACTIVE: 'mdc-component--active'}
return {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFoundation, "strings", {
get: function () {
// Classes extending MDCFoundation should implement this method to return an object which exports all
// semantic strings as constants. e.g. {ARIA_ROLE: 'tablist'}
return {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFoundation, "numbers", {
get: function () {
// Classes extending MDCFoundation should implement this method to return an object which exports all
// of its semantic numbers as constants. e.g. {ANIMATION_DELAY_MS: 350}
return {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCFoundation, "defaultAdapter", {
get: function () {
// Classes extending MDCFoundation may choose to implement this getter in order to provide a convenient
// way of viewing the necessary methods of an adapter. In the future, this could also be used for adapter
// validation.
return {};
},
enumerable: true,
configurable: true
});
MDCFoundation.prototype.init = function () {
// Subclasses should override this method to perform initialization routines (registering events, etc.)
};
MDCFoundation.prototype.destroy = function () {
// Subclasses should override this method to perform de-initialization routines (de-registering events, etc.)
};
return MDCFoundation;
}());
/**
* @license
* Copyright 2017 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var MDCDialogFoundation$1 = /** @class */ (function (_super) {
__extends(MDCDialogFoundation, _super);
function MDCDialogFoundation(adapter) {
var _this = _super.call(this, __assign({}, MDCDialogFoundation.defaultAdapter, adapter)) || this;
_this.isOpen_ = false;
_this.animationFrame_ = 0;
_this.animationTimer_ = 0;
_this.layoutFrame_ = 0;
_this.escapeKeyAction_ = strings$A.CLOSE_ACTION;
_this.scrimClickAction_ = strings$A.CLOSE_ACTION;
_this.autoStackButtons_ = true;
_this.areButtonsStacked_ = false;
return _this;
}
Object.defineProperty(MDCDialogFoundation, "cssClasses", {
get: function () {
return cssClasses$x;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCDialogFoundation, "strings", {
get: function () {
return strings$A;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCDialogFoundation, "numbers", {
get: function () {
return numbers$f;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MDCDialogFoundation, "defaultAdapter", {
get: function () {
return {
addBodyClass: function () { return undefined; },
addClass: function () { return undefined; },
areButtonsStacked: function () { return false; },
clickDefaultButton: function () { return undefined; },
eventTargetMatches: function () { return false; },
getActionFromEvent: function () { return ''; },
getInitialFocusEl: function () { return null; },
hasClass: function () { return false; },
isContentScrollable: function () { return false; },
notifyClosed: function () { return undefined; },
notifyClosing: function () { return undefined; },
notifyOpened: function () { return undefined; },
notifyOpening: function () { return undefined; },
releaseFocus: function () { return undefined; },
removeBodyClass: function () { return undefined; },
removeClass: function () { return undefined; },
reverseButtons: function () { return undefined; },
trapFocus: function () { return undefined; },
};
},
enumerable: true,
configurable: true
});
MDCDialogFoundation.prototype.init = function () {
if (this.adapter_.hasClass(cssClasses$x.STACKED)) {
this.setAutoStackButtons(false);
}
};
MDCDialogFoundation.prototype.destroy = function () {
if (this.isOpen_) {
this.close(strings$A.DESTROY_ACTION);
}
if (this.animationTimer_) {
clearTimeout(this.animationTimer_);
this.handleAnimationTimerEnd_();
}
if (this.layoutFrame_) {
cancelAnimationFrame(this.layoutFrame_);
this.layoutFrame_ = 0;
}
};
MDCDialogFoundation.prototype.open = function () {
var _this = this;
this.isOpen_ = true;
this.adapter_.notifyOpening();
this.adapter_.addClass(cssClasses$x.OPENING);
// Wait a frame once display is no longer "none", to establish basis for animation
this.runNextAnimationFrame_(function () {
_this.adapter_.addClass(cssClasses$x.OPEN);
_this.adapter_.addBodyClass(cssClasses$x.SCROLL_LOCK);
_this.layout();
_this.animationTimer_ = setTimeout(function () {
_this.handleAnimationTimerEnd_();
_this.adapter_.trapFocus(_this.adapter_.getInitialFocusEl());
_this.adapter_.notifyOpened();
}, numbers$f.DIALOG_ANIMATION_OPEN_TIME_MS);
});
};
MDCDialogFoundation.prototype.close = function (action) {
var _this = this;
if (action === void 0) { action = ''; }
if (!this.isOpen_) {
// Avoid redundant close calls (and events), e.g. from keydown on elements that inherently emit click
return;
}
this.isOpen_ = false;
this.adapter_.notifyClosing(action);
this.adapter_.addClass(cssClasses$x.CLOSING);
t
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment