Project import generated by Copybara.

GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/static_src/elements/chops/chops-checkbox/chops-checkbox.js b/static_src/elements/chops/chops-checkbox/chops-checkbox.js
new file mode 100644
index 0000000..d752347
--- /dev/null
+++ b/static_src/elements/chops/chops-checkbox/chops-checkbox.js
@@ -0,0 +1,135 @@
+// 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-checkbox>`
+ *
+ * A checkbox component. This component is primarily a wrapper
+ * around a native checkbox to allow easy sharing of styles.
+ *
+ */
+export class ChopsCheckbox extends LitElement {
+  /** @override */
+  static get styles() {
+    return css`
+      :host {
+        --chops-checkbox-color: var(--chops-primary-accent-color);
+        /* A bit brighter than Chrome's default focus color to
+        * avoid blending into the checkbox's blue. */
+        --chops-checkbox-focus-color: hsl(193, 82%, 63%);
+        --chops-checkbox-size: 16px;
+        --chops-checkbox-check-size: 18px;
+      }
+      label {
+        cursor: pointer;
+        display: inline-flex;
+        align-items: center;
+      }
+      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;
+      }
+      label::before {
+        width: var(--chops-checkbox-size);
+        height: var(--chops-checkbox-size);
+        margin-right: 8px;
+        box-sizing: border-box;
+        content: "\\2713";
+        display: inline-flex;
+        align-items: center;
+        justify-content: center;
+        border: 2px solid #222;
+        border-radius: 2px;
+        background: #fff;
+        font-size: var(--chops-checkbox-check-size);
+        padding: 0;
+        color: transparent;
+      }
+      input[type="checkbox"]:focus + label::before {
+        /* Make sure an outline shows around this element for
+        * accessibility.
+        */
+        box-shadow: 0 0 5px 1px var(--chops-checkbox-focus-color);
+      }
+      input[type="checkbox"]:checked + label::before {
+        background: var(--chops-checkbox-color);
+        border-color: var(--chops-checkbox-color);
+        color: #fff;
+      }
+    `;
+  }
+
+  /** @override */
+  render() {
+    return html`
+      <!-- Note: Avoiding 2-way data binding to futureproof this code
+        for LitElement. -->
+      <input id="checkbox" type="checkbox"
+        .checked=${this.checked} @change=${this._checkedChangeHandler}>
+      <label for="checkbox">
+        <slot></slot>
+      </label>
+    `;
+  }
+
+  /** @override */
+  static get properties() {
+    return {
+      label: {type: String},
+
+      /**
+       * 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},
+    };
+  }
+
+  /**
+   * Clicks the checkbox. Helpful for automated testing.
+   */
+  click() {
+    super.click();
+    /** @type {HTMLInputElement} */ (
+      this.shadowRoot.querySelector('#checkbox')).click();
+  }
+
+  /**
+   * Listens to the native checkbox's change event and runs internal
+   * logic based on changes.
+   * @param {Event} evt
+   * @private
+   */
+  _checkedChangeHandler(evt) {
+    this._checkedChange(evt.target.checked);
+  }
+
+  /**
+   * @param {boolean} checked Whether the box was checked or unchecked.
+   * @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-checkbox', ChopsCheckbox);