Skip to content

Instantly share code, notes, and snippets.

@sagrawal31
Created June 18, 2022 10:30
Show Gist options
  • Save sagrawal31/db6f2e7546523c3032259e69133dd8d6 to your computer and use it in GitHub Desktop.
Save sagrawal31/db6f2e7546523c3032259e69133dd8d6 to your computer and use it in GitHub Desktop.
My first Angular v14 Standalone Component - Click to Copy

Click to Copy - An Angular v14 Standalone Component

Two dependencies- Angular Material & Tailwind are used in this example that you can always remove and replace with your own.

Usage

Importing in your existing module

@NgModule({
    declarations: [
        // ... your declarations
    ],
    imports: [
        // ... your imports
        ClickToCopyComponent,
    ],
    exports: [
        // ... your exports
    ],
})
export class MyExistingModule {
}

Using in your HTML

<click-to-copy [text]="app.mySecretKeyToCopy">
    {{ app.mySecretKeyToCopy }}
</click-to-copy>

If [text] is not provided that the component will copy the text part of the element.

<span class="bg-gray-200 hover:bg-gray-300 cursor-pointer p-1 text-black rounded"
[matTooltip]="tooltipMessage"
<!-- Disable the auto hover by default so that we can control it from the component -->
[matTooltipDisabled]="tooltipDisabled"
[matTooltipHideDelay]="2000">
<!-- Put the content here -->
<ng-content></ng-content>
</span>
:host {
display: inline-block;
> span {
display: inline-block;
}
}
import {Component, ElementRef, HostListener, Input, NgZone, OnInit, ViewChild} from '@angular/core';
import {MatTooltip, MatTooltipModule} from '@angular/material/tooltip';
import {UntilDestroy, untilDestroyed} from '@ngneat/until-destroy';
import {fromEvent, switchMap} from 'rxjs';
@Component({
// This is required to make this a standalone component
standalone: true,
selector: 'click-to-copy',
// Importing Angular Material Tooltip as a dependency
imports: [MatTooltipModule],
templateUrl: './click-to-copy.component.html',
styleUrls: ['./click-to-copy.component.scss'],
})
@UntilDestroy()
export class ClickToCopyComponent implements OnInit {
@Input() text: string;
@ViewChild(MatTooltip) tooltip: MatTooltip;
tooltipMessage = 'Click to copy';
tooltipDisabled = true;
constructor(
private readonly zone: NgZone,
private readonly host: ElementRef<HTMLElement>,
) {
}
@HostListener('mouseout')
onMouseOut(): void {
// Manually hide the trigger when mouse is out of the component
this.tooltip.hide();
this.tooltipDisabled = true;
// Give tooltip some time to hide
setTimeout(() => {
this.tooltipMessage = 'Click to copy';
}, 100);
}
@HostListener('mouseover')
onMouseOver(): void {
this.tooltipDisabled = false;
// Manually show the trigger when mouse is over the component
this.tooltip.show();
}
ngOnInit(): void {
this.zone.runOutsideAngular(() => {
fromEvent(this.host.nativeElement, 'click').pipe(
switchMap(() => navigator.clipboard.writeText(this.getTextToCopy())),
untilDestroyed(this),
).subscribe(() => {
this.copied();
});
});
}
private copied(): void {
this.zone.run(() => {
// Change the text as the text is copied in the clipboard
this.tooltipMessage = 'Copied!';
this.tooltip.show();
});
}
private getTextToCopy(): string {
return this.text || this.host.nativeElement.textContent;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment