mirror of
https://github.com/bitwarden/browser
synced 2026-01-21 11:53:34 +00:00
PM-21800 calling copyToClipboard function from PlatformUtilsService in order to trim copied string (#17510)
* PM-21800 applied tw-whitespace-break-spaces in order to manage contents of clipboard * PM-21800 implemented host listener to decorate clipboard value * PM-21800 revert earlier tailwind change * PM21800 resolved pr comment re shared clipboard function * chore: rerun UI tests * PM-21800 resolved failling chromatic tests * PM-21800 resolved failing chromatic tests * PM-21800 reverted from shared clipboard component * PM-21800 resolved clipboard issue * PM-21800 resolved clipboard issue * PM-21800 resolved pr comment * PM-21800 reverted storybook change * PM-21800 removed css tailwind way to restrict clipboard copied text * PM-21800 refactored hostlistener in color password component * PM-21800 resolved pr comment to replace class with data attribute
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
import { Component, computed, HostBinding, input } from "@angular/core";
|
||||
import {
|
||||
Component,
|
||||
computed,
|
||||
ElementRef,
|
||||
HostBinding,
|
||||
HostListener,
|
||||
inject,
|
||||
input,
|
||||
} from "@angular/core";
|
||||
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
|
||||
type CharacterType = "letter" | "emoji" | "special" | "number";
|
||||
@@ -14,7 +23,7 @@ type CharacterType = "letter" | "emoji" | "special" | "number";
|
||||
@Component({
|
||||
selector: "bit-color-password",
|
||||
template: `@for (character of passwordCharArray(); track $index; let i = $index) {
|
||||
<span [class]="getCharacterClass(character)" class="tw-font-mono">
|
||||
<span [class]="getCharacterClass(character)" class="tw-font-mono" data-password-character>
|
||||
<span>{{ character }}</span>
|
||||
@if (showCount()) {
|
||||
<span class="tw-whitespace-nowrap tw-text-xs tw-leading-5 tw-text-main">{{ i + 1 }}</span>
|
||||
@@ -31,6 +40,9 @@ export class ColorPasswordComponent {
|
||||
return Array.from(this.password() ?? "");
|
||||
});
|
||||
|
||||
private platformUtilsService = inject(PlatformUtilsService);
|
||||
private elementRef = inject(ElementRef);
|
||||
|
||||
characterStyles: Record<CharacterType, string[]> = {
|
||||
emoji: [],
|
||||
letter: ["tw-text-main"],
|
||||
@@ -78,4 +90,28 @@ export class ColorPasswordComponent {
|
||||
|
||||
return "letter";
|
||||
}
|
||||
|
||||
@HostListener("copy", ["$event"])
|
||||
onCopy(event: ClipboardEvent) {
|
||||
event.preventDefault();
|
||||
const selection = window.getSelection();
|
||||
if (!selection || selection.rangeCount === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const spanElements = this.elementRef.nativeElement.querySelectorAll(
|
||||
"span[data-password-character]",
|
||||
);
|
||||
let copiedText = "";
|
||||
|
||||
spanElements.forEach((span: HTMLElement, index: number) => {
|
||||
if (selection.containsNode(span, true)) {
|
||||
copiedText += this.passwordCharArray()[index];
|
||||
}
|
||||
});
|
||||
|
||||
if (copiedText) {
|
||||
this.platformUtilsService.copyToClipboard(copiedText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { Meta, StoryObj } from "@storybook/angular";
|
||||
import { applicationConfig, Meta, StoryObj } from "@storybook/angular";
|
||||
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
|
||||
import { formatArgsForCodeSnippet } from "../../../../.storybook/format-args-for-code-snippet";
|
||||
|
||||
@@ -9,6 +11,19 @@ const examplePassword = "Wq$Jk😀7jlI DX#rS5Sdi!z0O ";
|
||||
export default {
|
||||
title: "Component Library/Color Password",
|
||||
component: ColorPasswordComponent,
|
||||
decorators: [
|
||||
applicationConfig({
|
||||
providers: [
|
||||
{
|
||||
provide: PlatformUtilsService,
|
||||
useValue: {
|
||||
// eslint-disable-next-line
|
||||
copyToClipboard: (text: string) => console.log(`${text} copied to clipboard`),
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
args: {
|
||||
password: examplePassword,
|
||||
showCount: false,
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
|
||||
import { PasswordManagerLogo } from "@bitwarden/assets/svg";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { GlobalStateProvider } from "@bitwarden/state";
|
||||
|
||||
import { LayoutComponent } from "../../layout";
|
||||
@@ -71,6 +72,13 @@ export default {
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: PlatformUtilsService,
|
||||
useValue: {
|
||||
// eslint-disable-next-line
|
||||
copyToClipboard: (text: string) => console.log(`${text} copied to clipboard`),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: GlobalStateProvider,
|
||||
useClass: StorybookGlobalStateProvider,
|
||||
|
||||
Reference in New Issue
Block a user