Project import generated by Copybara.
GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
diff --git a/node_modules/material-design-lite/src/snackbar/README.md b/node_modules/material-design-lite/src/snackbar/README.md
new file mode 100644
index 0000000..4bace84
--- /dev/null
+++ b/node_modules/material-design-lite/src/snackbar/README.md
@@ -0,0 +1,102 @@
+## Introduction
+
+The Material Design Lite (MDL) **snackbar** component is a container used to notify a user of an operation's status.
+It displays at the bottom of the screen.
+A snackbar may contain an action button to execute a command for the user.
+Actions should undo the committed action or retry it if it failed for example.
+Actions should not be to close the snackbar.
+By not providing an action, the snackbar becomes a **toast** component.
+
+## Basic Usage:
+
+Start a snackbar with a container div element.
+On that container define the `mdl-js-snackbar` and `mdl-snackbar` classes.
+It is also beneficial to add the aria live and atomic values to this container.
+
+Within the container create a container element for the message.
+This element should have the class `mdl-snackbar__text`.
+Leave this element empty!
+Text is added when the snackbar is called to be shown.
+
+Second in the container, add a button element.
+This element should have the class `mdl-snackbar__action`.
+It is recommended to set the type to button to make sure no forms get submitted by accident.
+Leave the text content empty here as well!
+Do not directly apply any event handlers.
+
+You now have complete markup for the snackbar to function.
+All that is left is within your JavaScript to call the `showSnackbar` method on the snackbar container.
+This takes a [plain object](#data-object) to configure the snackbar content appropriately.
+You may call it multiple consecutive times and messages will stack.
+
+## Examples
+
+All snackbars should be shown through the same element.
+
+#### Markup:
+
+```html
+<div aria-live="assertive" aria-atomic="true" aria-relevant="text" class="mdl-snackbar mdl-js-snackbar">
+ <div class="mdl-snackbar__text"></div>
+ <button type="button" class="mdl-snackbar__action"></button>
+</div>
+```
+
+> Note: In this example there are a few aria attributes for accessibility. Please modify these as-needed for your site.
+
+### Snackbar
+
+```javascript
+var notification = document.querySelector('.mdl-js-snackbar');
+var data = {
+ message: 'Message Sent',
+ actionHandler: function(event) {},
+ actionText: 'Undo',
+ timeout: 10000
+};
+notification.MaterialSnackbar.showSnackbar(data);
+```
+
+### Toast
+
+```javascript
+var notification = document.querySelector('.mdl-js-snackbar');
+notification.MaterialSnackbar.showSnackbar(
+ {
+ message: 'Image Uploaded'
+ }
+);
+```
+
+## CSS Classes
+
+### Blocks
+
+| MDL Class | Effect | Remarks |
+|-----------|--------|---------|
+| `mdl-snackbar` | Defines the container of the snackbar component. | Required on snackbar container |
+
+### Elements
+
+| MDL Class | Effect | Remarks |
+|-----------|--------|---------|
+| `mdl-snackbar__text` | Defines the element containing the text of the snackbar. | Required |
+| `mdl-snackbar__action` | Defines the element that triggers the action of a snackbar. | Required |
+
+### Modifiers
+
+| MDL Class | Effect | Remarks |
+|-----------|--------|---------|
+| `mdl-snackbar--active` | Marks the snackbar as active which causes it to display. | Required when active. Controlled in JavaScript |
+
+## Data Object
+
+The Snackbar components `showSnackbar` method takes an object for snackbar data.
+The table below shows the properties and their usage.
+
+| Property | Effect | Remarks | Type |
+|-----------|--------|---------|---------|
+| message | The text message to display. | Required | String |
+| timeout | The amount of time in milliseconds to show the snackbar. | Optional (default 2750) | Integer |
+| actionHandler | The function to execute when the action is clicked. | Optional | Function |
+| actionText | The text to display for the action button. | Required if actionHandler is set | String. |
diff --git a/node_modules/material-design-lite/src/snackbar/_snackbar.scss b/node_modules/material-design-lite/src/snackbar/_snackbar.scss
new file mode 100644
index 0000000..ac97598
--- /dev/null
+++ b/node_modules/material-design-lite/src/snackbar/_snackbar.scss
@@ -0,0 +1,89 @@
+/**
+ * Copyright 2015 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.
+ */
+
+@import "../variables";
+@import "../mixins";
+
+.mdl-snackbar {
+ position: fixed;
+ bottom: 0;
+ left: 50%;
+ cursor: default;
+ background-color: $snackbar-background-color;
+ z-index: 3;
+ display: block;
+ display: flex;
+ justify-content: space-between;
+ font-family: $preferred_font;
+ will-change: transform;
+ transform: translate(0, 80px);
+ transition: transform 0.25s $animation-curve-fast-out-linear-in;
+ pointer-events: none;
+ @media(max-width: $snackbar-tablet-breakpoint - 1) {
+ width: 100%;
+ left: 0;
+ min-height: 48px;
+ max-height: 80px;
+ }
+ @media(min-width: $snackbar-tablet-breakpoint) {
+ min-width: 288px;
+ max-width: 568px;
+ border-radius: 2px;
+ transform: translate(-50%, 80px);
+ }
+ &--active {
+ transform: translate(0, 0);
+ pointer-events: auto;
+ transition: transform 0.25s $animation-curve-linear-out-slow-in;
+
+ @media(min-width: $snackbar-tablet-breakpoint) {
+ transform: translate(-50%, 0);
+ }
+ }
+
+ &__text {
+ padding: 14px 12px 14px 24px;
+ vertical-align: middle;
+ color: white;
+ float: left;
+ }
+
+ &__action {
+ background: transparent;
+ border: none;
+ color: $snackbar-action-color;
+ float: right;
+ text-transform: uppercase;
+ padding: 14px 24px 14px 12px;
+ @include typo-button();
+ overflow: hidden;
+ outline: none;
+ opacity: 0;
+ pointer-events: none;
+ cursor: pointer;
+ text-decoration: none;
+ text-align: center;
+ align-self: center;
+
+ &::-moz-focus-inner {
+ border: 0;
+ }
+ &:not([aria-hidden]) {
+ opacity: 1;
+ pointer-events: auto;
+ }
+ }
+}
diff --git a/node_modules/material-design-lite/src/snackbar/snackbar.js b/node_modules/material-design-lite/src/snackbar/snackbar.js
new file mode 100644
index 0000000..7a855ab
--- /dev/null
+++ b/node_modules/material-design-lite/src/snackbar/snackbar.js
@@ -0,0 +1,189 @@
+/**
+ * Copyright 2015 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.
+ */
+(function() {
+ 'use strict';
+
+ /**
+ * Class constructor for Snackbar MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialSnackbar = function MaterialSnackbar(element) {
+ this.element_ = element;
+ this.textElement_ = this.element_.querySelector('.' + this.cssClasses_.MESSAGE);
+ this.actionElement_ = this.element_.querySelector('.' + this.cssClasses_.ACTION);
+ if (!this.textElement_) {
+ throw new Error('There must be a message element for a snackbar.');
+ }
+ if (!this.actionElement_) {
+ throw new Error('There must be an action element for a snackbar.');
+ }
+ this.active = false;
+ this.actionHandler_ = undefined;
+ this.message_ = undefined;
+ this.actionText_ = undefined;
+ this.queuedNotifications_ = [];
+ this.setActionHidden_(true);
+ };
+ window['MaterialSnackbar'] = MaterialSnackbar;
+
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialSnackbar.prototype.Constant_ = {
+ // The duration of the snackbar show/hide animation, in ms.
+ ANIMATION_LENGTH: 250
+ };
+
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialSnackbar.prototype.cssClasses_ = {
+ SNACKBAR: 'mdl-snackbar',
+ MESSAGE: 'mdl-snackbar__text',
+ ACTION: 'mdl-snackbar__action',
+ ACTIVE: 'mdl-snackbar--active'
+ };
+
+ /**
+ * Display the snackbar.
+ *
+ * @private
+ */
+ MaterialSnackbar.prototype.displaySnackbar_ = function() {
+ this.element_.setAttribute('aria-hidden', 'true');
+
+ if (this.actionHandler_) {
+ this.actionElement_.textContent = this.actionText_;
+ this.actionElement_.addEventListener('click', this.actionHandler_);
+ this.setActionHidden_(false);
+ }
+
+ this.textElement_.textContent = this.message_;
+ this.element_.classList.add(this.cssClasses_.ACTIVE);
+ this.element_.setAttribute('aria-hidden', 'false');
+ setTimeout(this.cleanup_.bind(this), this.timeout_);
+
+ };
+
+ /**
+ * Show the snackbar.
+ *
+ * @param {Object} data The data for the notification.
+ * @public
+ */
+ MaterialSnackbar.prototype.showSnackbar = function(data) {
+ if (data === undefined) {
+ throw new Error(
+ 'Please provide a data object with at least a message to display.');
+ }
+ if (data['message'] === undefined) {
+ throw new Error('Please provide a message to be displayed.');
+ }
+ if (data['actionHandler'] && !data['actionText']) {
+ throw new Error('Please provide action text with the handler.');
+ }
+ if (this.active) {
+ this.queuedNotifications_.push(data);
+ } else {
+ this.active = true;
+ this.message_ = data['message'];
+ if (data['timeout']) {
+ this.timeout_ = data['timeout'];
+ } else {
+ this.timeout_ = 2750;
+ }
+ if (data['actionHandler']) {
+ this.actionHandler_ = data['actionHandler'];
+ }
+ if (data['actionText']) {
+ this.actionText_ = data['actionText'];
+ }
+ this.displaySnackbar_();
+ }
+ };
+ MaterialSnackbar.prototype['showSnackbar'] = MaterialSnackbar.prototype.showSnackbar;
+
+ /**
+ * Check if the queue has items within it.
+ * If it does, display the next entry.
+ *
+ * @private
+ */
+ MaterialSnackbar.prototype.checkQueue_ = function() {
+ if (this.queuedNotifications_.length > 0) {
+ this.showSnackbar(this.queuedNotifications_.shift());
+ }
+ };
+
+ /**
+ * Cleanup the snackbar event listeners and accessiblity attributes.
+ *
+ * @private
+ */
+ MaterialSnackbar.prototype.cleanup_ = function() {
+ this.element_.classList.remove(this.cssClasses_.ACTIVE);
+ setTimeout(function() {
+ this.element_.setAttribute('aria-hidden', 'true');
+ this.textElement_.textContent = '';
+ if (!Boolean(this.actionElement_.getAttribute('aria-hidden'))) {
+ this.setActionHidden_(true);
+ this.actionElement_.textContent = '';
+ this.actionElement_.removeEventListener('click', this.actionHandler_);
+ }
+ this.actionHandler_ = undefined;
+ this.message_ = undefined;
+ this.actionText_ = undefined;
+ this.active = false;
+ this.checkQueue_();
+ }.bind(this), /** @type {number} */ (this.Constant_.ANIMATION_LENGTH));
+ };
+
+ /**
+ * Set the action handler hidden state.
+ *
+ * @param {boolean} value
+ * @private
+ */
+ MaterialSnackbar.prototype.setActionHidden_ = function(value) {
+ if (value) {
+ this.actionElement_.setAttribute('aria-hidden', 'true');
+ } else {
+ this.actionElement_.removeAttribute('aria-hidden');
+ }
+ };
+
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialSnackbar,
+ classAsString: 'MaterialSnackbar',
+ cssClass: 'mdl-js-snackbar',
+ widget: true
+ });
+
+})();
diff --git a/node_modules/material-design-lite/src/snackbar/snippets/snackbar.html b/node_modules/material-design-lite/src/snackbar/snippets/snackbar.html
new file mode 100644
index 0000000..6e07fee
--- /dev/null
+++ b/node_modules/material-design-lite/src/snackbar/snippets/snackbar.html
@@ -0,0 +1,27 @@
+<button id="demo-show-snackbar" class="mdl-button mdl-js-button mdl-button--raised" type="button">Show Snackbar</button>
+<div id="demo-snackbar-example" class="mdl-js-snackbar mdl-snackbar">
+ <div class="mdl-snackbar__text"></div>
+ <button class="mdl-snackbar__action" type="button"></button>
+</div>
+<script>
+(function() {
+ 'use strict';
+ var snackbarContainer = document.querySelector('#demo-snackbar-example');
+ var showSnackbarButton = document.querySelector('#demo-show-snackbar');
+ var handler = function(event) {
+ showSnackbarButton.style.backgroundColor = '';
+ };
+ showSnackbarButton.addEventListener('click', function() {
+ 'use strict';
+ showSnackbarButton.style.backgroundColor = '#' +
+ Math.floor(Math.random() * 0xFFFFFF).toString(16);
+ var data = {
+ message: 'Button color changed.',
+ timeout: 2000,
+ actionHandler: handler,
+ actionText: 'Undo'
+ };
+ snackbarContainer.MaterialSnackbar.showSnackbar(data);
+ });
+}());
+</script>
diff --git a/node_modules/material-design-lite/src/snackbar/snippets/toast.html b/node_modules/material-design-lite/src/snackbar/snippets/toast.html
new file mode 100644
index 0000000..6505692
--- /dev/null
+++ b/node_modules/material-design-lite/src/snackbar/snippets/toast.html
@@ -0,0 +1,18 @@
+<button id="demo-show-toast" class="mdl-button mdl-js-button mdl-button--raised" type="button">Show Toast</button>
+<div id="demo-toast-example" class="mdl-js-snackbar mdl-snackbar">
+ <div class="mdl-snackbar__text"></div>
+ <button class="mdl-snackbar__action" type="button"></button>
+</div>
+<script>
+(function() {
+ 'use strict';
+ window['counter'] = 0;
+ var snackbarContainer = document.querySelector('#demo-toast-example');
+ var showToastButton = document.querySelector('#demo-show-toast');
+ showToastButton.addEventListener('click', function() {
+ 'use strict';
+ var data = {message: 'Example Message # ' + ++counter};
+ snackbarContainer.MaterialSnackbar.showSnackbar(data);
+ });
+}());
+</script>