gr-key-binding-display to lit element

Change-Id: Ib3364cd31108aa329719799345fa7a9eaf37f1f0
diff --git a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.css.ts b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.css.ts
new file mode 100644
index 0000000..ccba289
--- /dev/null
+++ b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.css.ts
@@ -0,0 +1,30 @@
+/**
+ * @license
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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 {css} from 'lit-element';
+
+export const cssTemplate = css`
+  .key {
+    background-color: var(--chip-background-color);
+    color: var(--primary-text-color);
+    border: 1px solid var(--border-color);
+    border-radius: var(--border-radius);
+    display: inline-block;
+    font-weight: var(--font-weight-bold);
+    padding: var(--spacing-xxs) var(--spacing-m);
+    text-align: center;
+  }
+`;
diff --git a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.ts b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.ts
index 796a167..091684f 100644
--- a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.ts
+++ b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.ts
@@ -14,12 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import '../../../styles/shared-styles';
-import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
-import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
-import {PolymerElement} from '@polymer/polymer/polymer-element';
-import {htmlTemplate} from './gr-key-binding-display_html';
-import {customElement, property} from '@polymer/decorators';
+import {html} from 'lit-html';
+import {GrLitElement} from '../../lit/gr-lit-element';
+import {customElement, property} from 'lit-element';
+import {cssTemplate} from './gr-key-binding-display.css';
+import {sharedStyles} from '../../../styles/shared-styles';
 
 declare global {
   interface HTMLElementTagNameMap {
@@ -28,21 +27,30 @@
 }
 
 @customElement('gr-key-binding-display')
-export class GrKeyBindingDisplay extends GestureEventListeners(
-  LegacyElementMixin(PolymerElement)
-) {
-  static get template() {
-    return htmlTemplate;
+export class GrKeyBindingDisplay extends GrLitElement {
+  static get styles() {
+    return [sharedStyles, cssTemplate];
+  }
+
+  render() {
+    const items = this.binding.map((binding, index) => [
+      index > 0 ? html` or ` : html``,
+      this._computeModifiers(binding).map(
+        modifier => html`<span class="key modifier">${modifier}</span> `
+      ),
+      html`<span class="key">${this._computeKey(binding)}</span>`,
+    ]);
+    return html`${items}`;
   }
 
   @property({type: Array})
   binding: string[][] = [];
 
-  _computeModifiers(binding: string[][]) {
+  _computeModifiers(binding: string[]) {
     return binding.slice(0, binding.length - 1);
   }
 
-  _computeKey(binding: string[][]) {
+  _computeKey(binding: string[]) {
     return binding[binding.length - 1];
   }
 }
diff --git a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_html.ts b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_html.ts
deleted file mode 100644
index 251e30f..0000000
--- a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_html.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @license
- * Copyright (C) 2020 The Android Open Source Project
- *
- * 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 {html} from '@polymer/polymer/lib/utils/html-tag';
-
-export const htmlTemplate = html`
-  <style include="shared-styles">
-    .key {
-      background-color: var(--chip-background-color);
-      color: var(--primary-text-color);
-      border: 1px solid var(--border-color);
-      border-radius: var(--border-radius);
-      display: inline-block;
-      font-weight: var(--font-weight-bold);
-      padding: var(--spacing-xxs) var(--spacing-m);
-      text-align: center;
-    }
-  </style>
-  <template is="dom-repeat" items="[[binding]]">
-    <template is="dom-if" if="[[index]]">
-      or
-    </template>
-    <template is="dom-repeat" items="[[_computeModifiers(item)]]" as="modifier">
-      <span class="key modifier">[[modifier]]</span>
-    </template>
-    <span class="key">[[_computeKey(item)]]</span>
-  </template>
-`;
diff --git a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.js b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.ts
similarity index 86%
rename from polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.js
rename to polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.ts
index 0c25e6e..875cde8 100644
--- a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.js
+++ b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.ts
@@ -17,11 +17,12 @@
 
 import '../../../test/common-test-setup-karma.js';
 import './gr-key-binding-display.js';
+import {GrKeyBindingDisplay} from './gr-key-binding-display.js';
 
 const basicFixture = fixtureFromElement('gr-key-binding-display');
 
 suite('gr-key-binding-display tests', () => {
-  let element;
+  let element: GrKeyBindingDisplay;
 
   setup(() => {
     element = basicFixture.instantiate();
@@ -45,10 +46,10 @@
 
     test('key with modifiers', () => {
       assert.deepEqual(element._computeModifiers(['Ctrl', 'x']), ['Ctrl']);
-      assert.deepEqual(
-          element._computeModifiers(['Shift', 'Meta', 'x']),
-          ['Shift', 'Meta']);
+      assert.deepEqual(element._computeModifiers(['Shift', 'Meta', 'x']), [
+        'Shift',
+        'Meta',
+      ]);
     });
   });
 });
-
diff --git a/polygerrit-ui/app/styles/shared-styles.ts b/polygerrit-ui/app/styles/shared-styles.ts
index 695ae24..c2baaa9 100644
--- a/polygerrit-ui/app/styles/shared-styles.ts
+++ b/polygerrit-ui/app/styles/shared-styles.ts
@@ -15,6 +15,8 @@
  * limitations under the License.
  */
 
+import {css} from 'lit-element';
+
 // Mark the file as a module. Otherwise typescript assumes this is a script
 // and $_documentContainer is a global variable.
 // See: https://www.typescriptlang.org/docs/handbook/modules.html
@@ -22,189 +24,276 @@
 
 const $_documentContainer = document.createElement('template');
 
+export const sharedStyles = css`
+  /* CSS reset */
+
+  html,
+  body,
+  button,
+  div,
+  span,
+  applet,
+  object,
+  iframe,
+  h1,
+  h2,
+  h3,
+  h4,
+  h5,
+  h6,
+  p,
+  blockquote,
+  pre,
+  a,
+  abbr,
+  acronym,
+  address,
+  big,
+  cite,
+  code,
+  del,
+  dfn,
+  em,
+  img,
+  ins,
+  kbd,
+  q,
+  s,
+  samp,
+  small,
+  strike,
+  strong,
+  sub,
+  sup,
+  tt,
+  var,
+  b,
+  u,
+  i,
+  center,
+  dl,
+  dt,
+  dd,
+  ol,
+  ul,
+  li,
+  fieldset,
+  form,
+  label,
+  legend,
+  table,
+  caption,
+  tbody,
+  tfoot,
+  thead,
+  tr,
+  th,
+  td,
+  article,
+  aside,
+  canvas,
+  details,
+  embed,
+  figure,
+  figcaption,
+  footer,
+  header,
+  hgroup,
+  main,
+  menu,
+  nav,
+  output,
+  ruby,
+  section,
+  summary,
+  time,
+  mark,
+  audio,
+  video {
+    border: 0;
+    box-sizing: border-box;
+    font-size: 100%;
+    font: inherit;
+    margin: 0;
+    padding: 0;
+    vertical-align: baseline;
+  }
+  *::after,
+  *::before {
+    box-sizing: border-box;
+  }
+  input {
+    background-color: var(--background-color-primary);
+    border: 1px solid var(--border-color);
+    border-radius: var(--border-radius);
+    box-sizing: border-box;
+    color: var(--primary-text-color);
+    margin: 0;
+    padding: var(--spacing-s);
+  }
+  iron-autogrow-textarea {
+    background-color: inherit;
+    color: var(--primary-text-color);
+    border: 1px solid var(--border-color);
+    border-radius: var(--border-radius);
+    padding: 0;
+    box-sizing: border-box;
+    /* iron-autogrow-textarea has a "-webkit-appearance: textarea" :host
+        css rule, which prevents overriding the border color. Clear that. */
+    -webkit-appearance: none;
+
+    --iron-autogrow-textarea: {
+      box-sizing: border-box;
+      padding: var(--spacing-s);
+    }
+  }
+  a {
+    color: var(--link-color);
+  }
+  input,
+  textarea,
+  select,
+  button {
+    font: inherit;
+  }
+  ol,
+  ul {
+    list-style: none;
+  }
+  blockquote,
+  q {
+    quotes: none;
+  }
+  blockquote:before,
+  blockquote:after,
+  q:before,
+  q:after {
+    content: '';
+    content: none;
+  }
+  table {
+    border-collapse: collapse;
+    border-spacing: 0;
+  }
+
+  /* Fonts */
+
+  .font-normal {
+    font-size: var(--font-size-normal);
+    font-weight: var(--font-weight-normal);
+    line-height: var(--line-height-normal);
+  }
+  .font-small {
+    font-size: var(--font-size-small);
+    font-weight: var(--font-weight-normal);
+    line-height: var(--line-height-small);
+  }
+  .heading-1 {
+    font-family: var(--header-font-family);
+    font-size: var(--font-size-h1);
+    font-weight: var(--font-weight-h1);
+    line-height: var(--line-height-h1);
+  }
+  .heading-2 {
+    font-family: var(--header-font-family);
+    font-size: var(--font-size-h2);
+    font-weight: var(--font-weight-h2);
+    line-height: var(--line-height-h2);
+  }
+  .heading-3 {
+    font-family: var(--header-font-family);
+    font-size: var(--font-size-h3);
+    font-weight: var(--font-weight-h3);
+    line-height: var(--line-height-h3);
+  }
+  iron-icon {
+    color: var(--deemphasized-text-color);
+    --iron-icon-height: 20px;
+    --iron-icon-width: 20px;
+  }
+
+  /* Stopgap solution until we remove hidden$ attributes. */
+
+  :host([hidden]),
+  [hidden] {
+    display: none !important;
+  }
+  .separator {
+    border-left: 1px solid var(--border-color);
+    height: 20px;
+    margin: 0 8px;
+  }
+  .separator.transparent {
+    border-color: transparent;
+  }
+  paper-toggle-button {
+    --paper-toggle-button-checked-bar-color: var(--link-color);
+    --paper-toggle-button-checked-button-color: var(--link-color);
+  }
+  paper-tabs {
+    font-size: var(--font-size-h3);
+    font-weight: var(--font-weight-h3);
+    line-height: var(--line-height-h3);
+    --paper-font-common-base: {
+      font-family: var(--header-font-family);
+      -webkit-font-smoothing: initial;
+    }
+    --paper-tab-content-focused: {
+      /* paper-tabs uses 700 here, which can look awkward */
+      font-weight: var(--font-weight-h3);
+    }
+    --paper-tab-content-unselected: {
+      /* paper-tabs uses 0.8 here, but we want to control the color directly */
+      opacity: 1;
+      color: var(--deemphasized-text-color);
+    }
+  }
+  iron-autogrow-textarea {
+    /** This is needed for firefox */
+    --iron-autogrow-textarea_-_white-space: pre-wrap;
+  }
+  strong {
+    font-weight: var(--font-weight-bold);
+  }
+
+  .assistive-tech-only {
+    user-select: none;
+    clip: rect(1px, 1px, 1px, 1px);
+    height: 1px;
+    margin: 0;
+    overflow: hidden;
+    padding: 0;
+    position: absolute;
+    white-space: nowrap;
+    width: 1px;
+    z-index: -1000;
+  }
+
+  /** BEGIN: loading spiner */
+  .loadingSpin {
+    border: 2px solid var(--disabled-button-background-color);
+    border-top: 2px solid var(--primary-button-background-color);
+    border-radius: 50%;
+    width: 10px;
+    height: 10px;
+    animation: spin 2s linear infinite;
+    margin-right: var(--spacing-s);
+  }
+  @keyframes spin {
+    0% {
+      transform: rotate(0deg);
+    }
+    100% {
+      transform: rotate(360deg);
+    }
+  }
+  /** END: loading spiner */
+`;
+
 $_documentContainer.innerHTML = `<dom-module id="shared-styles">
   <template>
     <style>
-
-      /* CSS reset */
-
-      html, body, button, div, span, applet, object, iframe, h1, h2, h3,
-      h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite,
-      code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub,
-      sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form,
-      label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article,
-      aside, canvas, details, embed, figure, figcaption, footer, header, hgroup,
-      main, menu, nav, output, ruby, section, summary, time, mark, audio, video {
-        border: 0;
-        box-sizing: border-box;
-        font-size: 100%;
-        font: inherit;
-        margin: 0;
-        padding: 0;
-        vertical-align: baseline;
-      }
-      *::after,
-      *::before {
-        box-sizing: border-box;
-      }
-      input {
-        background-color: var(--background-color-primary);
-        border: 1px solid var(--border-color);
-        border-radius: var(--border-radius);
-        box-sizing: border-box;
-        color: var(--primary-text-color);
-        margin: 0;
-        padding: var(--spacing-s);
-      }
-      iron-autogrow-textarea {
-        background-color: inherit;
-        color: var(--primary-text-color);
-        border: 1px solid var(--border-color);
-        border-radius: var(--border-radius);
-        padding: 0;
-        box-sizing: border-box;
-        /* iron-autogrow-textarea has a "-webkit-appearance: textarea" :host
-           css rule, which prevents overriding the border color. Clear that. */
-        -webkit-appearance: none;
-
-        --iron-autogrow-textarea: {
-          box-sizing: border-box;
-          padding: var(--spacing-s);
-        };
-      }
-      a {
-        color: var(--link-color);
-      }
-      input,
-      textarea,
-      select,
-      button {
-        font: inherit;
-      }
-      ol, ul {
-        list-style: none;
-      }
-      blockquote, q {
-        quotes: none;
-      }
-      blockquote:before, blockquote:after,
-      q:before, q:after {
-        content: '';
-        content: none;
-      }
-      table {
-        border-collapse: collapse;
-        border-spacing: 0;
-      }
-
-      /* Fonts */
-
-      .font-normal {
-        font-size: var(--font-size-normal);
-        font-weight: var(--font-weight-normal);
-        line-height: var(--line-height-normal);
-      }
-      .font-small {
-        font-size: var(--font-size-small);
-        font-weight: var(--font-weight-normal);
-        line-height: var(--line-height-small);
-      }
-      .heading-1 {
-        font-family: var(--header-font-family);
-        font-size: var(--font-size-h1);
-        font-weight: var(--font-weight-h1);
-        line-height: var(--line-height-h1);
-      }
-      .heading-2 {
-        font-family: var(--header-font-family);
-        font-size: var(--font-size-h2);
-        font-weight: var(--font-weight-h2);
-        line-height: var(--line-height-h2);
-      }
-      .heading-3 {
-        font-family: var(--header-font-family);
-        font-size: var(--font-size-h3);
-        font-weight: var(--font-weight-h3);
-        line-height: var(--line-height-h3);
-      }
-      iron-icon {
-        color: var(--deemphasized-text-color);
-        --iron-icon-height: 20px;
-        --iron-icon-width: 20px;
-      }
-
-      /* Stopgap solution until we remove hidden$ attributes. */
-
-      :host([hidden]),
-      [hidden] {
-        display: none !important;
-      }
-      .separator {
-        border-left: 1px solid var(--border-color);
-        height: 20px;
-        margin: 0 8px;
-      }
-      .separator.transparent {
-        border-color: transparent;
-      }
-      paper-toggle-button {
-        --paper-toggle-button-checked-bar-color: var(--link-color);
-        --paper-toggle-button-checked-button-color: var(--link-color);
-      }
-      paper-tabs {
-        font-size: var(--font-size-h3);
-        font-weight: var(--font-weight-h3);
-        line-height: var(--line-height-h3);
-        --paper-font-common-base: {
-          font-family: var(--header-font-family);
-          -webkit-font-smoothing: initial;
-        };
-        --paper-tab-content-focused: {
-          /* paper-tabs uses 700 here, which can look awkward */
-          font-weight: var(--font-weight-h3);
-        };
-        --paper-tab-content-unselected: {
-          /* paper-tabs uses 0.8 here, but we want to control the color directly */
-          opacity: 1;
-          color: var(--deemphasized-text-color);
-        };
-      }
-      iron-autogrow-textarea {
-        /** This is needed for firefox */
-        --iron-autogrow-textarea_-_white-space: pre-wrap;
-      }
-      strong {
-        font-weight: var(--font-weight-bold);
-      }
-
-      .assistive-tech-only {
-        user-select: none;
-        clip: rect(1px, 1px, 1px, 1px);
-        height: 1px;
-        margin: 0;
-        overflow: hidden;
-        padding: 0;
-        position: absolute;
-        white-space: nowrap;
-        width: 1px;
-        z-index: -1000;
-      }
-
-      /** BEGIN: loading spiner */
-      .loadingSpin {
-        border: 2px solid var(--disabled-button-background-color);
-        border-top: 2px solid var(--primary-button-background-color);
-        border-radius: 50%;
-        width: 10px;
-        height: 10px;
-        animation: spin 2s linear infinite;
-        margin-right: var(--spacing-s);
-      }
-      @keyframes spin {
-        0% { transform: rotate(0deg); }
-        100% { transform: rotate(360deg); }
-      }
-      /** END: loading spiner */
+    ${sharedStyles.cssText}
     </style>
   </template>
 </dom-module>`;