diff --git a/src/components/component-names.ts b/src/components/component-names.ts
index a6dc3a639..eeaea1851 100644
--- a/src/components/component-names.ts
+++ b/src/components/component-names.ts
@@ -14,6 +14,7 @@ export const CHIP_NAME: string = 'm-chip';
export const CHIP_ADD_NAME: string = 'm-chip-add';
export const CHIP_DELETE_NAME: string = 'm-chip-delete';
export const COPY_TO_CLIPBOARD_NAME: string = 'm-copy-to-clipboard';
+export const COPY_TO_CLIPBOARD_FEEDBACK_NAME: string = 'm-copy-to-clipboard-feedback';
export const DATEFIELDS_NAME: string = 'm-datefields';
export const DATEPICKER_NAME: string = 'm-datepicker';
export const DATERANGEPICKER_NAME: string = 'm-daterangepicker';
diff --git a/src/components/copy-to-clipboard/__snapshots__/copy-to-clipboard.stories.ts.snap b/src/components/copy-to-clipboard/__snapshots__/copy-to-clipboard.stories.ts.snap
index 5ebe7be1e..61fb4a87b 100644
--- a/src/components/copy-to-clipboard/__snapshots__/copy-to-clipboard.stories.ts.snap
+++ b/src/components/copy-to-clipboard/__snapshots__/copy-to-clipboard.stories.ts.snap
@@ -88,6 +88,103 @@ exports[`Storyshots components|m-copy-to-clipboard custom 1`] = `
`;
+exports[`Storyshots components|m-copy-to-clipboard custom user feedback 1`] = `
+
+`;
+
exports[`Storyshots components|m-copy-to-clipboard default 1`] = `
`;
+
+exports[`Storyshots components|m-copy-to-clipboard user feedback 1`] = `
+
+`;
diff --git a/src/components/copy-to-clipboard/copy-to-clipboard-feedback.ts b/src/components/copy-to-clipboard/copy-to-clipboard-feedback.ts
new file mode 100644
index 000000000..ba34ce975
--- /dev/null
+++ b/src/components/copy-to-clipboard/copy-to-clipboard-feedback.ts
@@ -0,0 +1,53 @@
+import { PluginObject, VNode } from 'vue';
+import Component from 'vue-class-component';
+import { Prop } from 'vue-property-decorator';
+import { ModulVue } from '../../utils/vue/vue';
+import { COPY_TO_CLIPBOARD_FEEDBACK_NAME } from '../component-names';
+import I18nPlugin from '../i18n/i18n';
+import TextfieldPlugin from '../textfield/textfield';
+import ToastPlugin, { MToastPosition, MToastTimeout } from '../toast/toast';
+
+@Component
+export class MCopyToClipboardFeedback extends ModulVue {
+ @Prop()
+ message: string;
+
+ @Prop({
+ default: MToastPosition.BottomRight
+ })
+ position: MToastPosition;
+
+ @Prop({
+ default: MToastTimeout.xshort
+ })
+ timeout: MToastTimeout;
+
+ render(): VNode {
+ if (this.$scopedSlots && this.$scopedSlots.default) {
+ return this.$scopedSlots.default({
+ showToast: () => this.showToast()
+ }) as any;
+ } else {
+ throw new Error('copy-to-clipboard expects a default scoped slot.');
+ }
+ }
+
+ showToast(): void {
+ this.$toast.show({
+ text: this.message ? this.message : this.$i18n.translate('m-copy-to-clipboard:copied'),
+ position: this.position,
+ timeout: this.timeout
+ });
+ }
+}
+
+const CopyToClipboardFeedbackPlugin: PluginObject = {
+ install(v): void {
+ v.component(COPY_TO_CLIPBOARD_FEEDBACK_NAME, MCopyToClipboardFeedback);
+ v.use(I18nPlugin);
+ v.use(TextfieldPlugin);
+ v.use(ToastPlugin);
+ }
+};
+
+export default CopyToClipboardFeedbackPlugin;
diff --git a/src/components/copy-to-clipboard/copy-to-clipboard.html b/src/components/copy-to-clipboard/copy-to-clipboard.html
index da4e12ae9..182ab8a60 100644
--- a/src/components/copy-to-clipboard/copy-to-clipboard.html
+++ b/src/components/copy-to-clipboard/copy-to-clipboard.html
@@ -4,7 +4,6 @@
:handlers="inputHandlers">
-
diff --git a/src/components/copy-to-clipboard/copy-to-clipboard.stories.ts b/src/components/copy-to-clipboard/copy-to-clipboard.stories.ts
index c705e9387..a33fa9097 100644
--- a/src/components/copy-to-clipboard/copy-to-clipboard.stories.ts
+++ b/src/components/copy-to-clipboard/copy-to-clipboard.stories.ts
@@ -5,10 +5,12 @@ import { componentsHierarchyRootSeparator } from '../../../conf/storybook/utils'
import { MButton } from '../button/button';
import { COPY_TO_CLIPBOARD_NAME } from '../component-names';
import { MTextfield } from '../textfield/textfield';
+import { COPY_TO_CLIPBOARD_FEEDBACK_NAME } from './../component-names';
import CopyToClipboardPlugin from './copy-to-clipboard';
Vue.use(CopyToClipboardPlugin);
const componentName: string = COPY_TO_CLIPBOARD_NAME;
+const feedbackComponentName: string = COPY_TO_CLIPBOARD_FEEDBACK_NAME;
storiesOf(`${componentsHierarchyRootSeparator}${COPY_TO_CLIPBOARD_NAME}`, module)
.addDecorator(withA11y)
@@ -18,6 +20,22 @@ storiesOf(`${componentsHierarchyRootSeparator}${COPY_TO_CLIPBOARD_NAME}`, module
.add('default with value', () => ({
template: `<${componentName} :value="'some value'" />`
}))
+ .add('user feedback', () => ({
+ template: `
+ <${feedbackComponentName}>
+
+ <${componentName} :value="'some value'" @copy="showToast" />
+
+ ${feedbackComponentName}>`
+ }))
+ .add('custom user feedback', () => ({
+ template: `
+ <${feedbackComponentName} :message="'some message'" :position="'top-center'" :timeout="'none'">
+
+ <${componentName} :value="'some value'" @copy="showToast" />
+
+ ${feedbackComponentName}>`
+ }))
.add('custom', () => ({
template: `
<${componentName} :value="value">
diff --git a/src/components/copy-to-clipboard/copy-to-clipboard.ts b/src/components/copy-to-clipboard/copy-to-clipboard.ts
index 3df9af397..b03eaeb8d 100644
--- a/src/components/copy-to-clipboard/copy-to-clipboard.ts
+++ b/src/components/copy-to-clipboard/copy-to-clipboard.ts
@@ -3,10 +3,9 @@ import { PluginObject } from 'vue';
import { Component, Prop } from 'vue-property-decorator';
import { ModulVue } from '../../utils/vue/vue';
import { COPY_TO_CLIPBOARD_NAME } from '../component-names';
-import I18nPlugin from '../i18n/i18n';
import LinkPlugin from '../link/link';
import TextfieldPlugin from '../textfield/textfield';
-import ToastPlugin, { MToastPosition, MToastTimeout } from '../toast/toast';
+import CopyToClipboardFeedbackPlugin from './copy-to-clipboard-feedback';
import WithRender from './copy-to-clipboard.html';
import './copy-to-clipboard.scss';
@@ -82,21 +81,16 @@ export class MCopyToClipboard extends ModulVue {
copyText(): void {
copyToClipboard(this.value);
this.selectText();
- this.$toast.show({
- text: this.$i18n.translate('m-copy-to-clipboard:copied'),
- position: MToastPosition.BottomLeft,
- timeout: MToastTimeout.xshort
- });
+ this.$emit('copy');
}
}
const CopyToClipboardPlugin: PluginObject = {
install(v): void {
v.component(COPY_TO_CLIPBOARD_NAME, MCopyToClipboard);
- v.use(I18nPlugin);
v.use(TextfieldPlugin);
v.use(LinkPlugin);
- v.use(ToastPlugin);
+ v.use(CopyToClipboardFeedbackPlugin);
}
};
diff --git a/src/components/link/link.html b/src/components/link/link.html
index 7e8c89232..c5b2ba10d 100644
--- a/src/components/link/link.html
+++ b/src/components/link/link.html
@@ -39,6 +39,7 @@
:href="propUrl"
:target="target"
@click="onClick"
+ @mousedown="onMousedown"
v-if="!isRouterLink"
@keyup="onKeyup"
:tabindex="disabled ? '-1' : tabindex"
diff --git a/src/components/link/link.ts b/src/components/link/link.ts
index b8094da70..e373ed470 100644
--- a/src/components/link/link.ts
+++ b/src/components/link/link.ts
@@ -1,6 +1,6 @@
import { PluginObject } from 'vue';
import Component from 'vue-class-component';
-import { Prop, Watch } from 'vue-property-decorator';
+import { Emit, Prop, Watch } from 'vue-property-decorator';
import { Location } from 'vue-router';
import { KeyCode } from '../../utils/keycode/keycode';
import { ModulVue } from '../../utils/vue/vue';
@@ -112,6 +112,9 @@ export class MLink extends ModulVue {
}
}
+ @Emit('mousedown')
+ private onMousedown(): void { }
+
private get isRouterLink(): boolean {
return this.mode === MLinkMode.RouterLink;
}
diff --git a/src/components/toast/toast.ts b/src/components/toast/toast.ts
index 7108eb2b7..18f754984 100644
--- a/src/components/toast/toast.ts
+++ b/src/components/toast/toast.ts
@@ -77,6 +77,7 @@ export class MToast extends ModulVue implements PortalMixinImpl {
default: MToastTimeout.none,
validator: value =>
value === MToastTimeout.none ||
+ value === MToastTimeout.xshort ||
value === MToastTimeout.short ||
value === MToastTimeout.long
})