Project import generated by Copybara.

GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/static_src/elements/chops/chops-toggle/chops-toggle.js b/static_src/elements/chops/chops-toggle/chops-toggle.js
new file mode 100644
index 0000000..52868bd
--- /dev/null
+++ b/static_src/elements/chops/chops-toggle/chops-toggle.js
@@ -0,0 +1,124 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {LitElement, html, css} from 'lit-element';
+
+/**
+ * `<chops-toggle>`
+ *
+ * A toggle button component. This component is primarily a wrapper
+ * around a native checkbox to allow easy sharing of styles.
+ *
+ */
+export class ChopsToggle extends LitElement {
+  /** @override */
+  static get styles() {
+    return css`
+      :host {
+        --chops-toggle-bg: none;
+        --chops-toggle-color: var(--chops-primary-font-color);
+        --chops-toggle-hover-bg: rgba(0, 0, 0, 0.3);
+        --chops-toggle-focus-border: hsl(193, 82%, 63%);
+        --chops-toggle-checked-bg: rgba(0, 0, 0, 0.6);
+        --chops-toggle-checked-color: var(--chops-white);
+      }
+      label {
+        background: var(--chops-toggle-bg);
+        color: var(--chops-toggle-color);
+        cursor: pointer;
+        align-items: center;
+        padding: 2px 4px;
+        border: var(--chops-normal-border);
+        border-radius: var(--chops-button-radius);
+      }
+      input[type="checkbox"] {
+        /* We need the checkbox to be hidden but still accessible. */
+        opacity: 0;
+        width: 0;
+        height: 0;
+        position: absolute;
+        top: -9999;
+        left: -9999;
+      }
+      input[type="checkbox"]:focus + label {
+        /* Make sure an outline shows around this element for
+        * accessibility.
+        */
+        box-shadow: 0 0 5px 1px var(--chops-toggle-focus-border);
+      }
+      input[type="checkbox"]:hover + label {
+        background: var(--chops-toggle-hover-bg);
+      }
+      input[type="checkbox"]:checked + label {
+        background: var(--chops-toggle-checked-bg);
+        color: var(--chops-toggle-checked-color);
+      }
+      input[type="checkbox"]:disabled + label {
+        opacity: 0.8;
+        cursor: default;
+        pointer-events: none;
+      }
+    `;
+  }
+
+  /** @override */
+  render() {
+    return html`
+      <input id="checkbox"
+        type="checkbox"
+        ?checked=${this.checked}
+        ?disabled=${this.disabled}
+        @change=${this._checkedChangeHandler}
+      >
+      <label for="checkbox">
+        <slot></slot>
+      </label>
+    `;
+  }
+
+  /** @override */
+  static get properties() {
+    return {
+      /**
+       * Note: At the moment, this component does not manage its own
+       * internal checked state. It expects its checked state to come
+       * from its parent, and its parent is expected to update the
+       * chops-checkbox's checked state on a change event.
+       *
+       * This can be generalized in the future to support multiple
+       * ways of managing checked state if needed.
+       **/
+      checked: {type: Boolean},
+      /**
+       * Whether the element currently allows checking or not.
+       */
+      disabled: {type: Boolean},
+    };
+  }
+
+  click() {
+    super.click();
+    this.shadowRoot.querySelector('#checkbox').click();
+  }
+
+  _checkedChangeHandler(evt) {
+    this._checkedChange(evt.target.checked);
+  }
+
+  /**
+   * @param {boolean} checked
+   * @fires CustomEvent#checked-change
+   * @private
+   */
+  _checkedChange(checked) {
+    if (checked === this.checked) return;
+    const customEvent = new CustomEvent('checked-change', {
+      detail: {
+        checked: checked,
+      },
+    });
+    this.dispatchEvent(customEvent);
+  }
+}
+customElements.define('chops-toggle', ChopsToggle);