gr-copy-clipboard to lit
Change-Id: I59cb4cfdc5ea091ba6e22fc28124501c24009544
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_html.ts b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_html.ts
index 8823377..2e9a3fd 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_html.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_html.ts
@@ -344,7 +344,7 @@
<span class="headerSubject">[[_change.subject]]</span>
<gr-copy-clipboard
class="changeCopyClipboard"
- hide-input=""
+ hideInput=""
text="[[_computeCopyTextForTitle(_change)]]"
>
</gr-copy-clipboard>
diff --git a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_html.ts b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_html.ts
index 65ca8b5..02fa090 100644
--- a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_html.ts
+++ b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_html.ts
@@ -31,9 +31,9 @@
>[[_computeShortHash(change, commitInfo, serverConfig)]]</a
>
<gr-copy-clipboard
- has-tooltip=""
- button-title="Copy full SHA to clipboard"
- hide-input=""
+ hasTooltip=""
+ buttonTitle="Copy full SHA to clipboard"
+ hideInput=""
text="[[commitInfo.commit]]"
>
</gr-copy-clipboard>
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_html.ts b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_html.ts
index 3b2cacf..4d04744 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_html.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_html.ts
@@ -410,7 +410,7 @@
</span>
<gr-file-status-chip file="[[file]]"></gr-file-status-chip>
<gr-copy-clipboard
- hide-input=""
+ hideInput=""
text="[[file.__path]]"
></gr-copy-clipboard>
</a>
@@ -418,7 +418,7 @@
<div class="oldPath" title$="[[file.old_path]]">
[[file.old_path]]
<gr-copy-clipboard
- hide-input=""
+ hideInput=""
text="[[file.old_path]]"
></gr-copy-clipboard>
</div>
diff --git a/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor_html.ts b/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor_html.ts
index ab24168..f4641c2 100644
--- a/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor_html.ts
+++ b/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor_html.ts
@@ -70,9 +70,9 @@
</td>
<td>
<gr-copy-clipboard
- has-tooltip=""
- button-title="Copy GPG public key to clipboard"
- hide-input=""
+ hasTooltip=""
+ buttonTitle="Copy GPG public key to clipboard"
+ hideInput=""
text="[[key.key]]"
>
</gr-copy-clipboard>
diff --git a/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password_html.ts b/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password_html.ts
index 549fc93..811b85c 100644
--- a/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password_html.ts
+++ b/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password_html.ts
@@ -78,9 +78,9 @@
<span class="title">New Password:</span>
<span class="value">[[_generatedPassword]]</span>
<gr-copy-clipboard
- has-tooltip=""
- button-title="Copy password to clipboard"
- hide-input=""
+ hasTooltip=""
+ buttonTitle="Copy password to clipboard"
+ hideInput=""
text="[[_generatedPassword]]"
>
</gr-copy-clipboard>
diff --git a/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor_html.ts b/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor_html.ts
index 0bee1d3..e853b58 100644
--- a/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor_html.ts
+++ b/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor_html.ts
@@ -76,9 +76,9 @@
</td>
<td>
<gr-copy-clipboard
- has-tooltip=""
- button-title="Copy SSH public key to clipboard"
- hide-input=""
+ hasTooltip=""
+ buttonTitle="Copy SSH public key to clipboard"
+ hideInput=""
text="[[key.ssh_public_key]]"
>
</gr-copy-clipboard>
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.ts b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.ts
index 2fe6fed..4a2bcee 100644
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.ts
+++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.ts
@@ -15,16 +15,14 @@
* limitations under the License.
*/
import '@polymer/iron-input/iron-input';
-import '../../../styles/shared-styles';
import '../gr-button/gr-button';
import '../gr-icons/gr-icons';
-import {dom, EventApi} from '@polymer/polymer/lib/legacy/polymer.dom';
-import {PolymerElement} from '@polymer/polymer/polymer-element';
-import {htmlTemplate} from './gr-copy-clipboard_html';
-import {GrButton} from '../gr-button/gr-button';
-import {customElement, property} from '@polymer/decorators';
import {IronIconElement} from '@polymer/iron-icon';
-import {assertIsDefined} from '../../../utils/common-util';
+import {assertIsDefined, queryAndAssert} from '../../../utils/common-util';
+import {classMap} from 'lit-html/directives/class-map';
+import {css, customElement, html, property} from 'lit-element';
+import {GrLitElement} from '../../lit/gr-lit-element';
+import {GrButton} from '../gr-button/gr-button';
const COPY_TIMEOUT_MS = 1000;
@@ -33,17 +31,8 @@
'gr-copy-clipboard': GrCopyClipboard;
}
}
-
-export interface GrCopyClipboard {
- $: {button: GrButton; icon: IronIconElement; input: HTMLInputElement};
-}
-
@customElement('gr-copy-clipboard')
-export class GrCopyClipboard extends PolymerElement {
- static get template() {
- return htmlTemplate;
- }
-
+export class GrCopyClipboard extends GrLitElement {
@property({type: String})
text: string | undefined;
@@ -56,29 +45,121 @@
@property({type: Boolean})
hideInput = false;
- focusOnCopy() {
- this.$.button.focus();
+ static get styles() {
+ return [
+ css`
+ .text {
+ align-items: center;
+ display: flex;
+ flex-wrap: wrap;
+ }
+ .copyText {
+ flex-grow: 1;
+ margin-right: var(--spacing-s);
+ }
+ .hideInput {
+ display: none;
+ }
+ input#input {
+ font-family: var(--monospace-font-family);
+ font-size: var(--font-size-mono);
+ line-height: var(--line-height-mono);
+ width: 100%;
+ }
+ /*
+ * Typically icons are 20px, which is the normal line-height.
+ * The copy icon is too prominent at 20px, so we choose 16px
+ * here, but add 2x2px padding below, so the entire
+ * component should still fit nicely into a normal inline
+ * layout flow.
+ */
+ #icon {
+ height: 16px;
+ width: 16px;
+ }
+ iron-icon {
+ color: var(--deemphasized-text-color);
+ vertical-align: top;
+ }
+ `,
+ ];
}
- _computeInputClass(hideInput: boolean) {
- return hideInput ? 'hideInput' : '';
+ render() {
+ // To pass CSS mixins for @apply to Polymer components, they need to appear
+ // in <style> inside the template.
+ const customStyle = html`
+ <style>
+ iron-icon {
+ --iron-icon-height: 20px;
+ --iron-icon-width: 20px;
+ }
+ gr-button {
+ --gr-button: {
+ padding: 2px;
+ }
+ }
+ </style>
+ `;
+ return html`${customStyle}
+ <div class="text">
+ <iron-input
+ class="copyText"
+ type="text"
+ @click="${this._handleInputClick}"
+ readonly=""
+ bind-value=${this.text}
+ >
+ <input
+ id="input"
+ is="iron-input"
+ class="${classMap({hideInput: this.hideInput})}"
+ type="text"
+ @click="${this._handleInputClick}"
+ readonly=""
+ .value=${this.text}
+ part="text-container-style"
+ />
+ </iron-input>
+ <gr-button
+ id="copy-clipboard-button"
+ link=""
+ ?has-tooltip=${this.hasTooltip}
+ class="copyToClipboard"
+ title="${this.buttonTitle}"
+ @click="${this._copyToClipboard}"
+ aria-label="Click to copy to clipboard"
+ >
+ <iron-icon id="icon" icon="gr-icons:content-copy"></iron-icon>
+ </gr-button>
+ </div> `;
+ }
+
+ focusOnCopy() {
+ queryAndAssert<GrButton>(this, '#copy-clipboard-button').focus();
}
_handleInputClick(e: MouseEvent) {
e.preventDefault();
- ((dom(e) as EventApi).rootTarget as HTMLInputElement).select();
+ const rootTarget = e.composedPath()[0];
+ (rootTarget as HTMLInputElement).select();
}
_copyToClipboard(e: MouseEvent) {
e.preventDefault();
e.stopPropagation();
+ this.text = queryAndAssert<HTMLInputElement>(this, '#input').value;
assertIsDefined(this.text, 'text');
- this.$.icon.icon = 'gr-icons:check';
+ this.iconEl.icon = 'gr-icons:check';
navigator.clipboard.writeText(this.text);
setTimeout(
- () => (this.$.icon.icon = 'gr-icons:content-copy'),
+ () => (this.iconEl.icon = 'gr-icons:content-copy'),
COPY_TIMEOUT_MS
);
}
+
+ private get iconEl(): IronIconElement {
+ return queryAndAssert<IronIconElement>(this, '#icon');
+ }
}
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_html.ts b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_html.ts
deleted file mode 100644
index 3ccc46f..0000000
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_html.ts
+++ /dev/null
@@ -1,93 +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>
- .text {
- align-items: center;
- display: flex;
- flex-wrap: wrap;
- }
- .copyText {
- flex-grow: 1;
- margin-right: var(--spacing-s);
- }
- .hideInput {
- display: none;
- }
- input#input {
- font-family: var(--monospace-font-family);
- font-size: var(--font-size-mono);
- line-height: var(--line-height-mono);
- @apply --text-container-style;
- width: 100%;
- }
- /*
- * Typically icons are 20px, which is the normal line-height.
- * The copy icon is too prominent at 20px, so we choose 16px
- * here, but add 2x2px padding below, so the entire
- * component should still fit nicely into a normal inline
- * layout flow.
- */
- #icon {
- height: 16px;
- width: 16px;
- }
- iron-icon {
- color: var(--deemphasized-text-color);
- vertical-align: top;
- --iron-icon-height: 20px;
- --iron-icon-width: 20px;
- }
- gr-button {
- --gr-button: {
- padding: 2px;
- }
- }
- </style>
- <div class="text">
- <iron-input
- class="copyText"
- type="text"
- bind-value="[[text]]"
- on-click="_handleInputClick"
- readonly=""
- >
- <input
- id="input"
- is="iron-input"
- class$="[[_computeInputClass(hideInput)]]"
- type="text"
- bind-value="[[text]]"
- on-click="_handleInputClick"
- readonly=""
- />
- </iron-input>
- <gr-button
- id="button"
- link=""
- has-tooltip="[[hasTooltip]]"
- class="copyToClipboard"
- title="[[buttonTitle]]"
- on-click="_copyToClipboard"
- aria-label="Click to copy to clipboard"
- >
- <iron-icon id="icon" icon="gr-icons:content-copy"></iron-icon>
- </gr-button>
- </div>
-`;
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.js b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.js
index 55b2483..45847d7 100644
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.js
@@ -17,7 +17,7 @@
import '../../../test/common-test-setup-karma.js';
import './gr-copy-clipboard.js';
-import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+import {queryAndAssert} from '../../../test/test-utils.js';
const basicFixture = fixtureFromElement('gr-copy-clipboard');
@@ -32,18 +32,18 @@
});
test('copy to clipboard', () => {
- const clipboardSpy = sinon.spy(element, '_copyToClipboard');
+ const clipboardSpy = sinon.spy(navigator.clipboard, 'writeText');
const copyBtn = element.shadowRoot
.querySelector('.copyToClipboard');
- MockInteractions.tap(copyBtn);
+ MockInteractions.click(copyBtn);
assert.isTrue(clipboardSpy.called);
});
test('focusOnCopy', () => {
element.focusOnCopy();
- assert.deepEqual(dom(element.root).activeElement,
- element.shadowRoot
- .querySelector('.copyToClipboard'));
+ const activeElement = element.shadowRoot.activeElement;
+ const button = element.shadowRoot.querySelector('.copyToClipboard');
+ assert.deepEqual(activeElement, button);
});
test('_handleInputClick', () => {
@@ -58,16 +58,17 @@
assert.equal(inputElement.selectionEnd, element.text.length - 1);
});
- test('hideInput', () => {
+ test('hideInput', async () => {
// iron-input as parent should never be hidden as copy won't work
// on nested hidden elements
const ironInputElement = element.shadowRoot.querySelector('iron-input');
assert.notEqual(getComputedStyle(ironInputElement).display, 'none');
- assert.notEqual(getComputedStyle(element.$.input).display, 'none');
+ const input = queryAndAssert(element, 'input');
+ assert.notEqual(getComputedStyle(input).display, 'none');
element.hideInput = true;
- flush();
- assert.equal(getComputedStyle(element.$.input).display, 'none');
+ await flush();
+ assert.equal(getComputedStyle(input).display, 'none');
});
test('stop events propagation', () => {
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_html.ts b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_html.ts
index c163924..18a46a0 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_html.ts
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_html.ts
@@ -127,7 +127,7 @@
<span id="triggerText">[[text]]</span>
<gr-copy-clipboard
hidden="[[!showCopyForTriggerText]]"
- hide-input=""
+ hideInput=""
text="[[text]]"
></gr-copy-clipboard>
</gr-button>
diff --git a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_html.ts b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_html.ts
index 6c7f0d8..e43460d 100644
--- a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_html.ts
+++ b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_html.ts
@@ -45,17 +45,15 @@
/* Should roughly match the height of .commandContainer without padding. */
line-height: 26px;
}
- .commandContainer gr-copy-clipboard {
- --text-container-style: {
- border: none;
- }
+ .commandContainer gr-copy-clipboard::part(text-container-style) {
+ border: none;
}
</style>
<label>[[label]]</label>
<div class="commandContainer">
<gr-copy-clipboard
text="[[command]]"
- has-tooltip
+ hasTooltip
button-title="[[tooltip]]"
></gr-copy-clipboard>
</div>