Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { IconComponent } from 'flowbite-angular';

import { CommonModule } from '@angular/common';
import { Component, ElementRef, ViewChild } from '@angular/core';

@Component({
selector: 'flowbite-copy-package-input',
standalone: true,
imports: [CommonModule, IconComponent],
template: `
<div class="relative">
<input
#inputElement
[value]="value"
readonly
disabled
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm w-80 h-12 rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-gray-400" />
<span
(click)="copyToClipboard()"
class="absolute right-3 top-1/2 -translate-y-1/2 cursor-pointer"
[ngClass]="{ 'text-gray-500': !isJustCopied, 'text-primary-700': isJustCopied }">
@if (!isJustCopied) {
<flowbite-icon
svgIcon="solid:clipboard"
class="h-5 w-5 block text-primary-700" />
} @else {
<flowbite-icon
svgIcon="outline:check"
class="h-5 w-5 block text-primary-700" />
}
<div
class="absolute left-1/2 -translate-x-1/2 -top-8 bg-gray-800 text-white px-2 py-1 rounded text-xs"
[ngClass]="{ 'opacity-0': !isJustCopied, 'opacity-100': isJustCopied }">
{{ isJustCopied ? 'Copied!' : 'Copy to clipboard' }}
</div>
</span>
</div>
`,
})
export class CopyPackageInputComponent {
value: string = 'npm i flowbite flowbite-angular';
@ViewChild('inputElement') inputElement!: ElementRef<HTMLInputElement>;
isJustCopied: boolean = false;

copyToClipboard(): void {
const textToCopy = this.inputElement.nativeElement.value;

// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(textToCopy).then(() => {
this.showCopiedFeedback();
});
} else {
const textArea = document.createElement('textarea');
textArea.value = textToCopy;
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand('copy');
this.showCopiedFeedback();
} catch (err) {
console.error('Unable to copy to clipboard', err);
}
document.body.removeChild(textArea);
}
}

private showCopiedFeedback(): void {
this.isJustCopied = true;
setTimeout(() => (this.isJustCopied = false), 2000);
}
}
11 changes: 10 additions & 1 deletion apps/docs/src/app/ui/features/home/home.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@ <h1 class="leading-7 text-4xl xl:text-6xl font-extrabold text-gray-900 dark:text
</p>
</div>
<div class="flex flex-row items-start gap-4 md:gap-6">
<p class="text-xl font-normal">copy component</p>
<flowbite-copy-package-input />
<flowbite-button
color="primary"
size="xl">
<span class="leading-5 text-sm font-medium">Get started</span>
<flowbite-icon
svgIcon="outline:arrow-right"
class="block w-5 h-5 ms-2"
alt="arrow right" />
</flowbite-button>
</div>
</div>
<div class="hidden xl:block size-full">
Expand Down
3 changes: 3 additions & 0 deletions apps/docs/src/app/ui/features/home/home.component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { CopyPackageInputComponent } from './copy-package-input/copy-package-input.component';

import type { ThemeState } from 'flowbite-angular';
import {
BreadcrumbComponent,
Expand All @@ -23,6 +25,7 @@ import { RouterLink } from '@angular/router';
InputDirective,
RouterLink,
IconComponent,
CopyPackageInputComponent,
],
templateUrl: './home.component.html',
})
Expand Down