feat: Use clipboardjs library in copy-button component
This commit is contained in:
6 files changed
+108
-20
No files matched your search
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
@@ -28,3 +28,4 @@ add-hosts: Add Hosts
|
||||
set-password: Set Password
|
||||
change-password: Change Password
|
||||
edit-form: Edit Form
|
||||
copy: Copy
|
||||
@@ -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==
|
||||
|
||||
Reference in new issue
Block a user