feat: Use clipboardjs library in copy-button component

This commit is contained in:
Susmitha Girumala committed 2020-09-29 11:14:07 -04:00
1 parent c7b49920f6
commit c937d94822
6 files changed
+108 -20

No files matched your search

+19 -1
View File
@@ -1 +1,19 @@
{{yield}}
{{#if this.isClipboardLibrarySupported}}
<span
{{did-insert this.register}}
{{will-destroy this.destroy}}
>
<span id={{this.targetId}} class="copy-target">
{{yield}}
</span>
<Rose::Button
class="copy-button"
@iconRight={{this.icon}}
aria-label={{t "resources.actions.copy"}}
data-clipboard-target={{concat "#" this.targetId}}
/>
</span>
{{else}}
{{yield}}
{{/if}}
@@ -1,4 +1,76 @@
import Component from '@glimmer/component';
import ClipboardJS from 'clipboard';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { generateComponentID } from 'rose/utilities/component-auto-id';
import { task, timeout } from 'ember-concurrency';
import { set } from '@ember/object';
import { bind } from '@ember/runloop';
export default class CopyButtonComponent extends Component {
// =attributes
id = generateComponentID();
targetId = `copy-target-${this.id}`;
icon = 'copy-action';
@tracked clipboard;
/**
* A Ember Concurrency-based task that updates copy icon to a success state
* and back after 1 second. This icon flash indicates success on
* copy to clipboard action.
*
* NOTE: tasks are sort of attributes and sort of methods, but they are not
* language-level constructs. Thus we annotate this task as if it
* is an attribute.
* @type {Task}
*/
@task(function * () {
set(this, 'icon', 'copy-success');
yield timeout(1000);
set(this, 'icon', 'copy-action');
}).drop() successIconTimer;
// =methods
/**
* Checks for ClipboardJS support.
* @return {boolean}
*/
get isClipboardLibrarySupported() {
return ClipboardJS?.isSupported();
}
/**
* When copy to clipboard is successful, begin timer to show success icon.
*/
onCopySuccess(clipboardEvent) {
clipboardEvent.clearSelection();
this.successIconTimer.perform();
}
// =actions
/**
* Initialize ClipboardJS library and register for it's events.
*/
@action
register() {
if(!this.clipboard) {
this.clipboard = new ClipboardJS('.copy-button');
this.clipboard.on('success', bind(this, this.onCopySuccess));
}
}
/**
* Destroy ClipboardJS library instance and cancel icon timer.
*/
@action
destroy() {
this.clipboard?.destroy();
this.successIconTimer.cancelAll();
}
}
+3 -2
View File
@@ -29,6 +29,7 @@
"devDependencies": {
"@babel/core": "^7.9.6",
"@ember/optional-features": "^1.3.0",
"@ember/render-modifiers": "^1.0.2",
"@glimmer/component": "^1.0.0",
"@glimmer/tracking": "^1.0.0",
"api": "*",
@@ -36,6 +37,7 @@
"babel-eslint": "^10.0.3",
"babel-loader": "^8.1.0",
"broccoli-asset-rev": "^3.0.0",
"clipboard": "^2.0.6",
"doctoc": "^1.4.0",
"ember-a11y-testing": "^3.0.0",
"ember-auto-import": "^1.5.3",
@@ -84,8 +86,7 @@
"qunit-dom": "^1.0.0",
"rose": "*",
"sass": "^1.26.5",
"sass-lint": "^1.13.1",
"clipboard": "^2.0.6"
"sass-lint": "^1.13.1"
},
"engines": {
"node": "10.* || >= 12"
@@ -1,26 +1,14 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { render, find } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | copy-button', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function(assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });
await render(hbs`<CopyButton />`);
assert.equal(this.element.textContent.trim(), '');
// Template block usage:
await render(hbs`
<CopyButton>
template block text
</CopyButton>
`);
assert.equal(this.element.textContent.trim(), 'template block text');
await render(hbs`<CopyButton>text</CopyButton>`);
assert.ok(find('.copy-button'));
assert.equal(find('.copy-target').textContent.trim(), 'text');
});
});
+1
View File
@@ -28,3 +28,4 @@ add-hosts: Add Hosts
set-password: Set Password
change-password: Change Password
edit-form: Edit Form
copy: Copy
+9 -1
View File
@@ -2543,6 +2543,14 @@
ember-cli-babel "^6.16.0"
ember-compatibility-helpers "^1.1.1"
"@ember/render-modifiers@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@ember/render-modifiers/-/render-modifiers-1.0.2.tgz#2e87c48db49d922ce4850d707215caaac60d8444"
integrity sha512-6tEnHl5+62NTSAG2mwhGMFPhUrJQjoVqV+slsn+rlTknm2Zik+iwxBQEbwaiQOU1FUYxkS8RWcieovRNMR8inQ==
dependencies:
ember-cli-babel "^7.10.0"
ember-modifier-manager-polyfill "^1.1.0"
"@ember/test-helpers@^1.7.0", "@ember/test-helpers@^1.7.1":
version "1.7.1"
resolved "https://registry.yarnpkg.com/@ember/test-helpers/-/test-helpers-1.7.1.tgz#cc22a954b3b46856518f034bd492a74e0482389f"
@@ -9601,7 +9609,7 @@ ember-maybe-import-regenerator@^0.1.5, ember-maybe-import-regenerator@^0.1.6:
ember-cli-babel "^6.0.0-beta.4"
regenerator-runtime "^0.9.5"
ember-modifier-manager-polyfill@^1.2.0:
ember-modifier-manager-polyfill@^1.1.0, ember-modifier-manager-polyfill@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/ember-modifier-manager-polyfill/-/ember-modifier-manager-polyfill-1.2.0.tgz#cf4444e11a42ac84f5c8badd85e635df57565dda"
integrity sha512-bnaKF1LLKMkBNeDoetvIJ4vhwRPKIIumWr6dbVuW6W6p4QV8ZiO+GdF8J7mxDNlog9CeL9Z/7wam4YS86G8BYA==