Browse Source

Task/improve copy-to-clipboard feedback in value component (#7338)

* Improve copy-to-clipboard feedback

* Update changelog

---------

Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
pull/7366/head
Chanhyo Jung 2 days ago
committed by GitHub
parent
commit
74914d973c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 9
      libs/ui/src/lib/value/value.component.html
  3. 35
      libs/ui/src/lib/value/value.component.ts

1
CHANGELOG.md

@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Improved the copy-to-clipboard functionality in the value component by providing a visual confirmation
- Improved the language localization for German (`de`)
- Upgraded `stripe` from version `22.2.3` to `22.3.2`

9
libs/ui/src/lib/value/value.component.html

@ -13,13 +13,16 @@
@if (enableCopyToClipboardButton) {
<button
class="ml-1 no-height no-min-width p-1"
i18n-title
mat-button
title="Copy to clipboard"
type="button"
[title]="isCopied ? copiedTitle : copyToClipboardTitle"
(click)="onCopyValueToClipboard()"
(mousedown)="$event.preventDefault()"
>
<ion-icon class="text-muted" name="copy-outline" />
<ion-icon
class="text-muted"
[name]="isCopied ? 'checkmark-outline' : 'copy-outline'"
/>
</button>
}
</ng-template>

35
libs/ui/src/lib/value/value.component.ts

@ -13,13 +13,14 @@ import {
input,
Input,
OnChanges,
OnDestroy,
ViewChild
} from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatSnackBar } from '@angular/material/snack-bar';
import { IonIcon } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons';
import { copyOutline } from 'ionicons/icons';
import { checkmarkOutline, copyOutline } from 'ionicons/icons';
import { isNumber } from 'lodash';
import ms from 'ms';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
@ -32,7 +33,7 @@ import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
styleUrls: ['./value.component.scss'],
templateUrl: './value.component.html'
})
export class GfValueComponent implements AfterViewInit, OnChanges {
export class GfValueComponent implements AfterViewInit, OnChanges, OnDestroy {
@Input() colorizeSign = false;
@Input() deviceType: string;
@Input() enableCopyToClipboardButton = false;
@ -54,22 +55,29 @@ export class GfValueComponent implements AfterViewInit, OnChanges {
public absoluteValue = 0;
public formattedValue = '';
public hasLabel = false;
public isCopied = false;
public isNumber = false;
public isString = false;
public useAbsoluteValue = false;
public readonly copiedTitle = $localize`The value has been copied to the clipboard`;
public readonly copyToClipboardTitle = $localize`Copy to clipboard`;
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private clipboard: Clipboard,
private snackBar: MatSnackBar
) {
addIcons({
checkmarkOutline,
copyOutline
});
}
public readonly precision = input<number>();
private copyToClipboardTimeout: ReturnType<typeof setTimeout>;
private readonly formatOptions = computed<Intl.NumberFormatOptions>(() => {
const digits = this.hasPrecision ? this.precision() : 2;
@ -178,6 +186,18 @@ export class GfValueComponent implements AfterViewInit, OnChanges {
public onCopyValueToClipboard() {
this.clipboard.copy(String(this.value));
this.isCopied = true;
if (this.copyToClipboardTimeout) {
clearTimeout(this.copyToClipboardTimeout);
}
this.copyToClipboardTimeout = setTimeout(() => {
this.isCopied = false;
this.changeDetectorRef.markForCheck();
}, ms('3 seconds'));
this.snackBar.open(
'✅ ' + $localize`${this.value} has been copied to the clipboard`,
undefined,
@ -187,12 +207,23 @@ export class GfValueComponent implements AfterViewInit, OnChanges {
);
}
public ngOnDestroy() {
if (this.copyToClipboardTimeout) {
clearTimeout(this.copyToClipboardTimeout);
}
}
private initializeVariables() {
this.absoluteValue = 0;
this.formattedValue = '';
this.isCopied = false;
this.isNumber = false;
this.isString = false;
this.locale = this.locale || getLocale();
this.useAbsoluteValue = false;
if (this.copyToClipboardTimeout) {
clearTimeout(this.copyToClipboardTimeout);
}
}
}

Loading…
Cancel
Save