@taiga-ui/kit
Version:
Taiga UI Angular main components kit
197 lines (188 loc) • 17.4 kB
JavaScript
import * as i1$1 from '@angular/cdk/clipboard';
import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard';
import * as i0 from '@angular/core';
import { inject, signal, computed, Component, ViewEncapsulation, ChangeDetectionStrategy, Input, Directive } from '@angular/core';
import { tuiInjectElement } from '@taiga-ui/cdk/utils/dom';
import { tuiIsString, tuiDirectiveBinding } from '@taiga-ui/cdk/utils/miscellaneous';
import * as i1 from '@taiga-ui/core/components/button';
import { tuiButtonOptionsProvider, TuiButton } from '@taiga-ui/core/components/button';
import { TUI_NOTIFICATION_OPTIONS } from '@taiga-ui/core/components/notification';
import * as i2 from '@taiga-ui/core/directives/hint';
import { TuiHintDirective, TuiHint } from '@taiga-ui/core/directives/hint';
import { TUI_DARK_MODE } from '@taiga-ui/core/tokens';
import { TuiIcons } from '@taiga-ui/core/directives/icons';
import { TUI_COPY_TEXTS } from '@taiga-ui/kit/tokens';
import { toSignal } from '@angular/core/rxjs-interop';
import { NgIf, DOCUMENT } from '@angular/common';
import { tuiCreateOptions } from '@taiga-ui/cdk/utils/di';
import { TUI_FALSE_HANDLER } from '@taiga-ui/cdk/constants';
import { TuiCopyProcessor } from '@taiga-ui/cdk/directives/copy-processor';
import { TuiIcon } from '@taiga-ui/core/components/icon';
import { BehaviorSubject, switchMap, timer, map, startWith, Subject } from 'rxjs';
import { TuiTextfieldComponent } from '@taiga-ui/core/components/textfield';
import * as i1$2 from '@taiga-ui/core/directives/appearance';
import { TUI_APPEARANCE_OPTIONS, TuiWithAppearance } from '@taiga-ui/core/directives/appearance';
const [TUI_COPY_OPTIONS, tuiCopyOptionsProvider] = tuiCreateOptions({ icon: '@tui.copy' });
class TuiButtonCopyComponent {
constructor() {
this.el = tuiInjectElement();
this.clipboard = inject(Clipboard);
this.options = inject(TUI_COPY_OPTIONS);
this.copyTexts = toSignal(inject(TUI_COPY_TEXTS));
this.notification = inject(TUI_NOTIFICATION_OPTIONS);
this.hint = inject(TuiHintDirective);
this.check = tuiIsString(this.notification.icon)
? this.notification.icon
: this.notification.icon('positive');
this.appearance = this.hint.appearance ||
this.hint.el.closest('[tuiTheme]')?.getAttribute('tuiTheme');
this.darkMode = inject(TUI_DARK_MODE);
this.copied = signal(false);
this.copiedText = computed(() => this.copyTexts()?.[1] ?? '');
this.icon = tuiDirectiveBinding(TuiIcons, 'iconStart', computed(() => {
if (this.copied()) {
return this.check;
}
return typeof this.options.icon === 'string'
? this.options.icon
: this.options.icon('s');
}));
this.tuiButtonCopy = '';
}
copy(target) {
const copied = this.el === target;
if (copied) {
this.clipboard.copy(this.tuiButtonCopy);
}
this.copied.set(copied);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiButtonCopyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TuiButtonCopyComponent, isStandalone: true, selector: "[tuiButtonCopy]", inputs: { tuiButtonCopy: "tuiButtonCopy" }, host: { attributes: { "tuiButton": "", "type": "button" }, listeners: { "document:click.capture": "copy($event.target)" }, properties: { "attr.tuiTheme": "appearance === \"dark\" ? \"light\" : darkMode() ? \"light\" : \"dark\"" } }, providers: [tuiButtonOptionsProvider({ appearance: 'flat-grayscale', size: 's' })], hostDirectives: [{ directive: i1.TuiButton }], ngImport: i0, template: `
<ng-container *ngIf="copied(); else notCopied">
{{ copiedText() }}
</ng-container>
<ng-template #notCopied>
<ng-content />
</ng-template>
`, isInline: true, styles: ["tui-hint:has([tuiButtonCopy]){display:flex;padding:.375rem;max-inline-size:none}[tuiButtonCopy]:not(:first-of-type){margin-inline-start:calc(.75rem - 1px);border-image:linear-gradient(transparent .375rem,var(--tui-border-normal) .375rem,var(--tui-border-normal) calc(100% - .375rem),transparent calc(100% - .375rem)) 0 0 0 1 / 0 1px / 0 .375rem}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiButtonCopyComponent, decorators: [{
type: Component,
args: [{ standalone: true, selector: '[tuiButtonCopy]', imports: [NgIf], template: `
<ng-container *ngIf="copied(); else notCopied">
{{ copiedText() }}
</ng-container>
<ng-template #notCopied>
<ng-content />
</ng-template>
`, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [tuiButtonOptionsProvider({ appearance: 'flat-grayscale', size: 's' })], hostDirectives: [TuiButton], host: {
tuiButton: '',
type: 'button',
'[attr.tuiTheme]': 'appearance === "dark" ? "light" : darkMode() ? "light" : "dark"',
'(document:click.capture)': 'copy($event.target)',
}, styles: ["tui-hint:has([tuiButtonCopy]){display:flex;padding:.375rem;max-inline-size:none}[tuiButtonCopy]:not(:first-of-type){margin-inline-start:calc(.75rem - 1px);border-image:linear-gradient(transparent .375rem,var(--tui-border-normal) .375rem,var(--tui-border-normal) calc(100% - .375rem),transparent calc(100% - .375rem)) 0 0 0 1 / 0 1px / 0 .375rem}\n"] }]
}], propDecorators: { tuiButtonCopy: [{
type: Input
}] } });
class TuiCopyComponent {
constructor() {
this.processor = inject(TuiCopyProcessor, { optional: true });
this.notification = inject(TUI_NOTIFICATION_OPTIONS);
this.options = inject(TUI_COPY_OPTIONS);
this.copied$ = new BehaviorSubject(false);
this.texts = toSignal(inject(TUI_COPY_TEXTS));
this.hint = toSignal(this.copied$.pipe(switchMap((copied) => timer(2000).pipe(map(TUI_FALSE_HANDLER), startWith(copied)))));
this.size = 'm';
}
get icon() {
return tuiIsString(this.options.icon)
? this.options.icon
: this.options.icon(this.size);
}
get check() {
return tuiIsString(this.notification.icon)
? this.notification.icon
: this.notification.icon('positive');
}
process(value) {
const source = value ?? '';
return this.processor?.tuiCopyProcessor(source) ?? source.trim();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiCopyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TuiCopyComponent, isStandalone: true, selector: "tui-copy", inputs: { size: "size" }, host: { listeners: { "pointerdown": "copied$.next(false)" }, properties: { "attr.data-size": "size" } }, ngImport: i0, template: "<span\n #content\n tuiHintAppearance=\"dark\"\n tuiHintDirection=\"top\"\n class=\"t-content\"\n [cdkCopyToClipboard]=\"process(content.textContent)\"\n [tuiHint]=\"template\"\n [tuiHintManual]=\"!!hint()\"\n (cdkCopyToClipboardCopied)=\"copied$.next($event)\"\n>\n <ng-content />\n</span>\n<button\n appearance=\"icon\"\n size=\"xs\"\n tuiIconButton\n type=\"button\"\n class=\"t-button\"\n [attr.aria-label]=\"texts()?.[0]\"\n [cdkCopyToClipboard]=\"process(content.textContent)\"\n [iconStart]=\"icon\"\n (cdkCopyToClipboardCopied)=\"copied$.next($event)\"\n></button>\n<ng-template #template>\n <tui-icon\n class=\"t-icon\"\n [icon]=\"check\"\n />\n {{ texts()?.[1] }}\n</ng-template>\n", styles: [":host{cursor:pointer}:host[data-size=m]{--t-size: min( calc(1em + 1px) , 1rem)}:host[data-size=l]{--t-size: max(calc(1em / 1.57), min(max(calc(1em / 1.18), 1.25rem), 1.5rem))}@media (hover: hover) and (pointer: fine){:host:hover .t-content{opacity:var(--tui-disabled-opacity);-webkit-mask-position:0;mask-position:0}:host:hover .t-button{opacity:1}}:host:has(.t-button:focus-visible) .t-content{opacity:var(--tui-disabled-opacity);-webkit-mask-position:0;mask-position:0}.t-content{transition-property:opacity,-webkit-mask;transition-property:opacity,mask;transition-property:opacity,mask,-webkit-mask;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;-webkit-mask:linear-gradient(to var(--tui-inline-start),transparent calc(1.25 * var(--t-size)),black calc(2 * var(--t-size))) no-repeat,linear-gradient(to var(--tui-inline-end),black,black calc(2 * var(--t-size)),transparent calc(2 * var(--t-size))) no-repeat;mask:linear-gradient(to var(--tui-inline-start),transparent calc(1.25 * var(--t-size)),black calc(2 * var(--t-size))) no-repeat,linear-gradient(to var(--tui-inline-end),black,black calc(2 * var(--t-size)),transparent calc(2 * var(--t-size))) no-repeat;-webkit-mask-position:calc(var(--tui-inline) * 2 * var(--t-size)),0;mask-position:calc(var(--tui-inline) * 2 * var(--t-size)),0}.t-button{opacity:0;border-radius:0;font-size:inherit!important;margin-inline-start:calc(-1 * var(--t-size));--t-size: inherit}.t-button:before{font-size:var(--t-size)}.t-button:focus-visible{opacity:1}.t-icon{font-size:1rem;margin-inline-end:.25rem;vertical-align:sub;color:var(--tui-text-positive)}\n"], dependencies: [{ kind: "ngmodule", type: ClipboardModule }, { kind: "directive", type: i1$1.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "directive", type: i2.TuiHintDirective, selector: "[tuiHint]:not(ng-container):not(ng-template)", inputs: ["tuiHintContext", "tuiHintAppearance", "tuiHint"], outputs: ["tuiHintVisible"] }, { kind: "directive", type: i2.TuiHintManual, selector: "[tuiHint][tuiHintManual]", inputs: ["tuiHintManual"] }, { kind: "component", type: TuiIcon, selector: "tui-icon", inputs: ["icon", "background"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiCopyComponent, decorators: [{
type: Component,
args: [{ standalone: true, selector: 'tui-copy', imports: [ClipboardModule, TuiButton, TuiHint, TuiIcon], changeDetection: ChangeDetectionStrategy.OnPush, host: {
'[attr.data-size]': 'size',
'(pointerdown)': 'copied$.next(false)',
}, template: "<span\n #content\n tuiHintAppearance=\"dark\"\n tuiHintDirection=\"top\"\n class=\"t-content\"\n [cdkCopyToClipboard]=\"process(content.textContent)\"\n [tuiHint]=\"template\"\n [tuiHintManual]=\"!!hint()\"\n (cdkCopyToClipboardCopied)=\"copied$.next($event)\"\n>\n <ng-content />\n</span>\n<button\n appearance=\"icon\"\n size=\"xs\"\n tuiIconButton\n type=\"button\"\n class=\"t-button\"\n [attr.aria-label]=\"texts()?.[0]\"\n [cdkCopyToClipboard]=\"process(content.textContent)\"\n [iconStart]=\"icon\"\n (cdkCopyToClipboardCopied)=\"copied$.next($event)\"\n></button>\n<ng-template #template>\n <tui-icon\n class=\"t-icon\"\n [icon]=\"check\"\n />\n {{ texts()?.[1] }}\n</ng-template>\n", styles: [":host{cursor:pointer}:host[data-size=m]{--t-size: min( calc(1em + 1px) , 1rem)}:host[data-size=l]{--t-size: max(calc(1em / 1.57), min(max(calc(1em / 1.18), 1.25rem), 1.5rem))}@media (hover: hover) and (pointer: fine){:host:hover .t-content{opacity:var(--tui-disabled-opacity);-webkit-mask-position:0;mask-position:0}:host:hover .t-button{opacity:1}}:host:has(.t-button:focus-visible) .t-content{opacity:var(--tui-disabled-opacity);-webkit-mask-position:0;mask-position:0}.t-content{transition-property:opacity,-webkit-mask;transition-property:opacity,mask;transition-property:opacity,mask,-webkit-mask;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;-webkit-mask:linear-gradient(to var(--tui-inline-start),transparent calc(1.25 * var(--t-size)),black calc(2 * var(--t-size))) no-repeat,linear-gradient(to var(--tui-inline-end),black,black calc(2 * var(--t-size)),transparent calc(2 * var(--t-size))) no-repeat;mask:linear-gradient(to var(--tui-inline-start),transparent calc(1.25 * var(--t-size)),black calc(2 * var(--t-size))) no-repeat,linear-gradient(to var(--tui-inline-end),black,black calc(2 * var(--t-size)),transparent calc(2 * var(--t-size))) no-repeat;-webkit-mask-position:calc(var(--tui-inline) * 2 * var(--t-size)),0;mask-position:calc(var(--tui-inline) * 2 * var(--t-size)),0}.t-button{opacity:0;border-radius:0;font-size:inherit!important;margin-inline-start:calc(-1 * var(--t-size));--t-size: inherit}.t-button:before{font-size:var(--t-size)}.t-button:focus-visible{opacity:1}.t-icon{font-size:1rem;margin-inline-end:.25rem;vertical-align:sub;color:var(--tui-text-positive)}\n"] }]
}], propDecorators: { size: [{
type: Input
}] } });
class TuiCopyDirective {
constructor() {
this.options = inject(TUI_COPY_OPTIONS);
this.copied$ = new Subject();
this.doc = inject(DOCUMENT);
this.textfield = inject(TuiTextfieldComponent);
this.hint = tuiDirectiveBinding(TuiHintDirective, 'tuiHint', toSignal(inject(TUI_COPY_TEXTS).pipe(switchMap(([copy, copied]) => this.copied$.pipe(switchMap(() => timer(3000).pipe(map(() => copy), startWith(copied))), startWith(copy)))), { initialValue: '' }));
this.icons = tuiDirectiveBinding(TuiIcon, 'icon', computed((size = this.textfield.options.size()) => tuiIsString(this.options.icon) ? this.options.icon : this.options.icon(size)));
this.tuiCopy = '';
}
get disabled() {
return !this.textfield.input?.nativeElement.value;
}
copy() {
this.textfield.input?.nativeElement.select();
this.doc.execCommand('copy');
this.copied$.next();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiCopyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: TuiCopyDirective, isStandalone: true, selector: "tui-icon[tuiCopy]", inputs: { tuiCopy: "tuiCopy" }, host: { listeners: { "click": "copy()" }, properties: { "style.pointer-events": "disabled ? \"none\" : null", "style.opacity": "disabled ? \"var(--tui-disabled-opacity)\" : null", "style.border-width.rem": "textfield.options.size() === \"l\" ? null : 0.25" }, styleAttribute: "cursor: pointer" }, providers: [
{
provide: TUI_APPEARANCE_OPTIONS,
useValue: { appearance: 'icon' },
},
], hostDirectives: [{ directive: i1$2.TuiWithAppearance }, { directive: i2.TuiHintDirective, inputs: ["tuiHintAppearance", "tuiHintAppearance", "tuiHintContext", "tuiHintContext"] }], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiCopyDirective, decorators: [{
type: Directive,
args: [{
standalone: true,
selector: 'tui-icon[tuiCopy]',
providers: [
{
provide: TUI_APPEARANCE_OPTIONS,
useValue: { appearance: 'icon' },
},
],
hostDirectives: [
TuiWithAppearance,
{
directive: TuiHintDirective,
inputs: ['tuiHintAppearance', 'tuiHintContext'],
},
],
host: {
style: 'cursor: pointer',
'(click)': 'copy()',
'[style.pointer-events]': 'disabled ? "none" : null',
'[style.opacity]': 'disabled ? "var(--tui-disabled-opacity)" : null',
'[style.border-width.rem]': 'textfield.options.size() === "l" ? null : 0.25',
},
}]
}], propDecorators: { tuiCopy: [{
type: Input
}] } });
const TuiCopy = [
TuiCopyComponent,
TuiCopyDirective,
TuiButtonCopyComponent,
];
// TODO: Move to components in v5
/**
* Generated bundle index. Do not edit.
*/
export { TUI_COPY_OPTIONS, TuiButtonCopyComponent, TuiCopy, TuiCopyComponent, TuiCopyDirective, tuiCopyOptionsProvider };
//# sourceMappingURL=taiga-ui-kit-directives-copy.mjs.map