@frame-kit/ui-ng 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENTS.md +683 -0
- package/DEVELOPMENT_GUIDE.md +1102 -0
- package/LICENSE +21 -0
- package/README.md +69 -0
- package/THEMING.md +130 -0
- package/core/headline/README.md +121 -0
- package/core/icon/README.md +173 -0
- package/core/image/README.md +210 -0
- package/core/link/README.md +297 -0
- package/core/separator/README.md +145 -0
- package/core/text/README.md +240 -0
- package/directives/infinite-scroll/README.md +102 -0
- package/directives/spotlight/README.md +154 -0
- package/directives/tooltip/README.md +147 -0
- package/docs/endpoint-link/README.md +142 -0
- package/docs/method-badge/README.md +154 -0
- package/fesm2022/frame-kit-ui-ng-core-headline.mjs +122 -0
- package/fesm2022/frame-kit-ui-ng-core-headline.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-icon.mjs +189 -0
- package/fesm2022/frame-kit-ui-ng-core-icon.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-image.mjs +123 -0
- package/fesm2022/frame-kit-ui-ng-core-image.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-link.mjs +369 -0
- package/fesm2022/frame-kit-ui-ng-core-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-separator.mjs +59 -0
- package/fesm2022/frame-kit-ui-ng-core-separator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-text.mjs +204 -0
- package/fesm2022/frame-kit-ui-ng-core-text.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs +74 -0
- package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs +76 -0
- package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs +425 -0
- package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs +63 -0
- package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs +43 -0
- package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-forms.mjs +3632 -0
- package/fesm2022/frame-kit-ui-ng-forms.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs +239 -0
- package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs +132 -0
- package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs +133 -0
- package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs +60 -0
- package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-toast.mjs +166 -0
- package/fesm2022/frame-kit-ui-ng-services-toast.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs +214 -0
- package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-alert.mjs +82 -0
- package/fesm2022/frame-kit-ui-ng-ui-alert.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs +76 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-badge.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs +68 -0
- package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-button.mjs +108 -0
- package/fesm2022/frame-kit-ui-ng-ui-button.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-callout.mjs +58 -0
- package/fesm2022/frame-kit-ui-ng-ui-callout.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-card.mjs +70 -0
- package/fesm2022/frame-kit-ui-ng-ui-card.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs +113 -0
- package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs +1288 -0
- package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs +456 -0
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs +398 -0
- package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs +398 -0
- package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs +125 -0
- package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs +113 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs +111 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs +103 -0
- package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs +135 -0
- package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-loader.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-loader.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs +79 -0
- package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs +40 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs +110 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs +91 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs +86 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs +443 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-note.mjs +56 -0
- package/fesm2022/frame-kit-ui-ng-ui-note.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs +105 -0
- package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs +110 -0
- package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs +129 -0
- package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs +42 -0
- package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs +894 -0
- package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-toast.mjs +179 -0
- package/fesm2022/frame-kit-ui-ng-ui-toast.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs +143 -0
- package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs +191 -0
- package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng.mjs +58 -0
- package/fesm2022/frame-kit-ui-ng.mjs.map +1 -0
- package/layouts/app-shell/README.md +357 -0
- package/layouts/content-split/README.md +180 -0
- package/package.json +253 -0
- package/services/overlay-orchestrator/README.md +184 -0
- package/services/spotlight/README.md +61 -0
- package/services/toast/README.md +118 -0
- package/types/frame-kit-ui-ng-core-headline.d.ts +38 -0
- package/types/frame-kit-ui-ng-core-icon.d.ts +74 -0
- package/types/frame-kit-ui-ng-core-image.d.ts +93 -0
- package/types/frame-kit-ui-ng-core-link.d.ts +251 -0
- package/types/frame-kit-ui-ng-core-separator.d.ts +28 -0
- package/types/frame-kit-ui-ng-core-text.d.ts +186 -0
- package/types/frame-kit-ui-ng-directives-infinite-scroll.d.ts +42 -0
- package/types/frame-kit-ui-ng-directives-spotlight.d.ts +51 -0
- package/types/frame-kit-ui-ng-directives-tooltip.d.ts +70 -0
- package/types/frame-kit-ui-ng-docs-endpoint-link.d.ts +43 -0
- package/types/frame-kit-ui-ng-docs-method-badge.d.ts +30 -0
- package/types/frame-kit-ui-ng-forms.d.ts +1674 -0
- package/types/frame-kit-ui-ng-layouts-app-shell.d.ts +75 -0
- package/types/frame-kit-ui-ng-layouts-content-split.d.ts +43 -0
- package/types/frame-kit-ui-ng-services-overlay-orchestrator.d.ts +96 -0
- package/types/frame-kit-ui-ng-services-spotlight.d.ts +32 -0
- package/types/frame-kit-ui-ng-services-toast.d.ts +100 -0
- package/types/frame-kit-ui-ng-ui-accordion.d.ts +86 -0
- package/types/frame-kit-ui-ng-ui-alert.d.ts +34 -0
- package/types/frame-kit-ui-ng-ui-avatar-stack.d.ts +38 -0
- package/types/frame-kit-ui-ng-ui-avatar.d.ts +36 -0
- package/types/frame-kit-ui-ng-ui-badge.d.ts +33 -0
- package/types/frame-kit-ui-ng-ui-breadcrumb.d.ts +45 -0
- package/types/frame-kit-ui-ng-ui-button.d.ts +48 -0
- package/types/frame-kit-ui-ng-ui-callout.d.ts +26 -0
- package/types/frame-kit-ui-ng-ui-card.d.ts +30 -0
- package/types/frame-kit-ui-ng-ui-copyable-field.d.ts +62 -0
- package/types/frame-kit-ui-ng-ui-data-table.d.ts +482 -0
- package/types/frame-kit-ui-ng-ui-dialog.d.ts +166 -0
- package/types/frame-kit-ui-ng-ui-drawer.d.ts +130 -0
- package/types/frame-kit-ui-ng-ui-dropdown-menu.d.ts +77 -0
- package/types/frame-kit-ui-ng-ui-editable-field.d.ts +65 -0
- package/types/frame-kit-ui-ng-ui-icon-badge.d.ts +45 -0
- package/types/frame-kit-ui-ng-ui-icon-list.d.ts +67 -0
- package/types/frame-kit-ui-ng-ui-inline-edit.d.ts +44 -0
- package/types/frame-kit-ui-ng-ui-list-editor.d.ts +56 -0
- package/types/frame-kit-ui-ng-ui-loader.d.ts +32 -0
- package/types/frame-kit-ui-ng-ui-menu-item.d.ts +27 -0
- package/types/frame-kit-ui-ng-ui-nav-brand.d.ts +25 -0
- package/types/frame-kit-ui-ng-ui-nav-group.d.ts +60 -0
- package/types/frame-kit-ui-ng-ui-nav-separator.d.ts +33 -0
- package/types/frame-kit-ui-ng-ui-node-tree-breadcrumb.d.ts +35 -0
- package/types/frame-kit-ui-ng-ui-node-tree.d.ts +135 -0
- package/types/frame-kit-ui-ng-ui-note.d.ts +22 -0
- package/types/frame-kit-ui-ng-ui-numbered-list.d.ts +52 -0
- package/types/frame-kit-ui-ng-ui-pagination.d.ts +49 -0
- package/types/frame-kit-ui-ng-ui-progress-bar.d.ts +50 -0
- package/types/frame-kit-ui-ng-ui-sidenav-link.d.ts +24 -0
- package/types/frame-kit-ui-ng-ui-tabs.d.ts +266 -0
- package/types/frame-kit-ui-ng-ui-timeline.d.ts +42 -0
- package/types/frame-kit-ui-ng-ui-toast.d.ts +56 -0
- package/types/frame-kit-ui-ng-ui-user-menu.d.ts +87 -0
- package/types/frame-kit-ui-ng-ui-wizard-dialog.d.ts +116 -0
- package/types/frame-kit-ui-ng.d.ts +53 -0
- package/ui/accordion/README.md +261 -0
- package/ui/alert/README.md +211 -0
- package/ui/avatar/README.md +167 -0
- package/ui/avatar-stack/README.md +164 -0
- package/ui/badge/README.md +162 -0
- package/ui/breadcrumb/README.md +240 -0
- package/ui/button/README.md +184 -0
- package/ui/callout/README.md +159 -0
- package/ui/card/README.md +174 -0
- package/ui/copyable-field/README.md +235 -0
- package/ui/data-table/README.md +408 -0
- package/ui/dialog/README.md +222 -0
- package/ui/drawer/README.md +274 -0
- package/ui/dropdown-menu/README.md +336 -0
- package/ui/editable-field/README.md +171 -0
- package/ui/icon-badge/README.md +131 -0
- package/ui/icon-list/README.md +205 -0
- package/ui/inline-edit/README.md +135 -0
- package/ui/list-editor/README.md +162 -0
- package/ui/loader/README.md +160 -0
- package/ui/menu-item/README.md +204 -0
- package/ui/nav-brand/README.md +111 -0
- package/ui/nav-group/README.md +145 -0
- package/ui/nav-separator/README.md +44 -0
- package/ui/node-tree/README.md +278 -0
- package/ui/node-tree-breadcrumb/README.md +164 -0
- package/ui/note/README.md +146 -0
- package/ui/numbered-list/README.md +187 -0
- package/ui/pagination/README.md +174 -0
- package/ui/progress-bar/README.md +223 -0
- package/ui/sidenav-link/README.md +214 -0
- package/ui/tabs/README.md +204 -0
- package/ui/timeline/README.md +285 -0
- package/ui/toast/README.md +243 -0
- package/ui/user-menu/README.md +260 -0
- package/ui/wizard-dialog/README.md +283 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, Directive, input, contentChild, computed, HostBinding, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { LoaderComponent } from '@frame-kit/ui-ng/ui/loader';
|
|
4
|
+
|
|
5
|
+
const FK_BUTTON_ICON_START = new InjectionToken('FK_BUTTON_ICON_START');
|
|
6
|
+
const FK_BUTTON_ICON_END = new InjectionToken('FK_BUTTON_ICON_END');
|
|
7
|
+
class FkButtonIconStartDirective {
|
|
8
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkButtonIconStartDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
9
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: FkButtonIconStartDirective, isStandalone: true, selector: "[fkButtonIconStart]", host: { attributes: { "aria-hidden": "true" } }, providers: [
|
|
10
|
+
{ provide: FK_BUTTON_ICON_START, useExisting: FkButtonIconStartDirective },
|
|
11
|
+
], ngImport: i0 });
|
|
12
|
+
}
|
|
13
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkButtonIconStartDirective, decorators: [{
|
|
14
|
+
type: Directive,
|
|
15
|
+
args: [{
|
|
16
|
+
selector: '[fkButtonIconStart]',
|
|
17
|
+
standalone: true,
|
|
18
|
+
providers: [
|
|
19
|
+
{ provide: FK_BUTTON_ICON_START, useExisting: FkButtonIconStartDirective },
|
|
20
|
+
],
|
|
21
|
+
host: {
|
|
22
|
+
'aria-hidden': 'true',
|
|
23
|
+
},
|
|
24
|
+
}]
|
|
25
|
+
}] });
|
|
26
|
+
class FkButtonIconEndDirective {
|
|
27
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkButtonIconEndDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
28
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: FkButtonIconEndDirective, isStandalone: true, selector: "[fkButtonIconEnd]", host: { attributes: { "aria-hidden": "true" } }, providers: [
|
|
29
|
+
{ provide: FK_BUTTON_ICON_END, useExisting: FkButtonIconEndDirective },
|
|
30
|
+
], ngImport: i0 });
|
|
31
|
+
}
|
|
32
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkButtonIconEndDirective, decorators: [{
|
|
33
|
+
type: Directive,
|
|
34
|
+
args: [{
|
|
35
|
+
selector: '[fkButtonIconEnd]',
|
|
36
|
+
standalone: true,
|
|
37
|
+
providers: [
|
|
38
|
+
{ provide: FK_BUTTON_ICON_END, useExisting: FkButtonIconEndDirective },
|
|
39
|
+
],
|
|
40
|
+
host: {
|
|
41
|
+
'aria-hidden': 'true',
|
|
42
|
+
},
|
|
43
|
+
}]
|
|
44
|
+
}] });
|
|
45
|
+
|
|
46
|
+
class ButtonComponent {
|
|
47
|
+
// ===== BEHAVIOR =====
|
|
48
|
+
/** Visual style variant of the button (primary, secondary, ghost, etc.). */
|
|
49
|
+
variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
50
|
+
/** Size of the button, affecting padding and font size. */
|
|
51
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
52
|
+
/** When true, shows a spinner and disables interaction. */
|
|
53
|
+
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
54
|
+
/** When true, prevents interaction and applies disabled styling. */
|
|
55
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
56
|
+
/** HTML type attribute forwarded to the inner `<button>` element. */
|
|
57
|
+
type = input('button', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
58
|
+
/** When true, the button stretches to fill its container width. */
|
|
59
|
+
fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : /* istanbul ignore next */ []));
|
|
60
|
+
// ===== CONTENT CHILDREN =====
|
|
61
|
+
iconStartRef = contentChild(FK_BUTTON_ICON_START, ...(ngDevMode ? [{ debugName: "iconStartRef" }] : /* istanbul ignore next */ []));
|
|
62
|
+
iconEndRef = contentChild(FK_BUTTON_ICON_END, ...(ngDevMode ? [{ debugName: "iconEndRef" }] : /* istanbul ignore next */ []));
|
|
63
|
+
// ===== BASE PROPS =====
|
|
64
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
65
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
66
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
67
|
+
ariaDescribedBy = input(null, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : /* istanbul ignore next */ []));
|
|
68
|
+
// ===== COMPUTED =====
|
|
69
|
+
isDisabled = computed(() => this.disabled() || this.loading(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
70
|
+
classes = computed(() => {
|
|
71
|
+
return [
|
|
72
|
+
'fk-button',
|
|
73
|
+
`fk-button--${this.variant()}`,
|
|
74
|
+
`fk-button--${this.size()}`,
|
|
75
|
+
this.isDisabled() ? 'fk-button--disabled' : '',
|
|
76
|
+
this.loading() ? 'fk-button--loading' : '',
|
|
77
|
+
this.fullWidth() ? 'fk-button--full-width' : '',
|
|
78
|
+
this.className(),
|
|
79
|
+
]
|
|
80
|
+
.filter(Boolean)
|
|
81
|
+
.join(' ');
|
|
82
|
+
}, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
83
|
+
get hostClass() {
|
|
84
|
+
return this.classes();
|
|
85
|
+
}
|
|
86
|
+
get ariaDisabledAttr() {
|
|
87
|
+
return this.isDisabled() ? 'true' : null;
|
|
88
|
+
}
|
|
89
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
90
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ButtonComponent, isStandalone: true, selector: "fk-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClass", "attr.aria-disabled": "this.ariaDisabledAttr" } }, queries: [{ propertyName: "iconStartRef", first: true, predicate: FK_BUTTON_ICON_START, descendants: true, isSignal: true }, { propertyName: "iconEndRef", first: true, predicate: FK_BUTTON_ICON_END, descendants: true, isSignal: true }], ngImport: i0, template: "<button\n class=\"fk-button__native\"\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [id]=\"id()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n>\n @if (loading()) {\n <fk-loader\n className=\"fk-button__loader\"\n size=\"sm\"\n color=\"inherit\"\n ariaLabel=\"Loading\"\n ></fk-loader>\n }\n <span\n class=\"fk-button__content\"\n [class.fk-button__content--hidden]=\"loading()\"\n >\n <ng-content select=\"[fkButtonIconStart]\" />\n <ng-content />\n <ng-content select=\"[fkButtonIconEnd]\" />\n </span>\n</button>\n", styles: [":host{display:inline-block}:host.fk-button--full-width{display:block;width:100%}.fk-button__native{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:var(--fk-button-icon-gap, .5rem);border:var(--fk-button-border-width, 1px) solid transparent;border-radius:var(--fk-button-border-radius, .5rem);font-weight:var(--fk-button-font-weight, var(--fk-typography-button-font-weight, 400));line-height:var(--fk-button-line-height, var(--fk-typography-button-line-height, 1.5));cursor:var(--fk-button-cursor, pointer);transition:var(--fk-button-transition, background-color .15s ease, border-color .15s ease, color .15s ease);text-decoration:none;white-space:nowrap;width:100%}.fk-button__native:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}.fk-button__content{display:inline-flex;align-items:center;gap:var(--fk-button-icon-gap, .5rem)}.fk-button__content--hidden{visibility:hidden}.fk-button__loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}:host.fk-button--sm .fk-button__native{padding:var(--fk-button-padding-sm, .375rem .75rem);font-size:var(--fk-button-font-size-sm, .875rem)}:host.fk-button--md .fk-button__native{padding:var(--fk-button-padding-md, .5rem 1rem);font-size:var(--fk-button-font-size-md, 1rem)}:host.fk-button--lg .fk-button__native{padding:var(--fk-button-padding-lg, .625rem 1.25rem);font-size:var(--fk-button-font-size-lg, 1.125rem)}:host.fk-button--primary .fk-button__native{background-color:var(--fk-button-primary-bg, var(--fk-color-primary, #0a84ff));color:var(--fk-button-primary-color, var(--fk-color-surface, #ffffff));border-color:var(--fk-button-primary-border-color, transparent)}:host.fk-button--primary:not(.fk-button--disabled) .fk-button__native:hover{background-color:var(--fk-button-primary-bg-hover, var(--fk-color-primary-hover, #0670e0))}:host.fk-button--primary:not(.fk-button--disabled) .fk-button__native:active{background-color:var(--fk-button-primary-bg-active, var(--fk-color-primary-active, #055fc3))}:host.fk-button--secondary .fk-button__native{background-color:var(--fk-button-secondary-bg, transparent);color:var(--fk-button-secondary-color, var(--fk-color-primary, #0a84ff));border-color:var(--fk-button-secondary-border-color, var(--fk-color-border, #d9e2ee))}:host.fk-button--secondary:not(.fk-button--disabled) .fk-button__native:hover{background-color:var(--fk-button-secondary-bg-hover, var(--fk-color-surface-muted, #f7f9fb))}:host.fk-button--secondary:not(.fk-button--disabled) .fk-button__native:active{background-color:var(--fk-button-secondary-bg-active, var(--fk-color-border, #d9e2ee))}:host.fk-button--outline .fk-button__native{background-color:var(--fk-button-outline-bg, transparent);color:var(--fk-button-outline-color, var(--fk-color-primary, #0a84ff));border-color:var(--fk-button-outline-border-color, var(--fk-color-border, #d9e2ee))}:host.fk-button--outline:not(.fk-button--disabled) .fk-button__native:hover{background-color:var(--fk-button-outline-bg-hover, var(--fk-color-surface-muted, #f7f9fb))}:host.fk-button--outline:not(.fk-button--disabled) .fk-button__native:active{background-color:var(--fk-button-outline-bg-active, var(--fk-color-border, #d9e2ee))}:host.fk-button--danger .fk-button__native{background-color:var(--fk-button-danger-bg, var(--fk-color-danger, #e02424));color:var(--fk-button-danger-color, var(--fk-color-surface, #ffffff));border-color:var(--fk-button-danger-border-color, transparent)}:host.fk-button--danger:not(.fk-button--disabled) .fk-button__native:hover{background-color:var(--fk-button-danger-bg-hover, #b91c1c)}:host.fk-button--danger:not(.fk-button--disabled) .fk-button__native:active{background-color:var(--fk-button-danger-bg-active, #991b1b)}:host.fk-button--disabled .fk-button__native{opacity:var(--fk-button-opacity-disabled, .6);cursor:var(--fk-button-cursor-disabled, not-allowed)}\n"], dependencies: [{ kind: "component", type: LoaderComponent, selector: "fk-loader", inputs: ["size", "color", "className", "id", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
91
|
+
}
|
|
92
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
93
|
+
type: Component,
|
|
94
|
+
args: [{ selector: 'fk-button', standalone: true, imports: [LoaderComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n class=\"fk-button__native\"\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [id]=\"id()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n>\n @if (loading()) {\n <fk-loader\n className=\"fk-button__loader\"\n size=\"sm\"\n color=\"inherit\"\n ariaLabel=\"Loading\"\n ></fk-loader>\n }\n <span\n class=\"fk-button__content\"\n [class.fk-button__content--hidden]=\"loading()\"\n >\n <ng-content select=\"[fkButtonIconStart]\" />\n <ng-content />\n <ng-content select=\"[fkButtonIconEnd]\" />\n </span>\n</button>\n", styles: [":host{display:inline-block}:host.fk-button--full-width{display:block;width:100%}.fk-button__native{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:var(--fk-button-icon-gap, .5rem);border:var(--fk-button-border-width, 1px) solid transparent;border-radius:var(--fk-button-border-radius, .5rem);font-weight:var(--fk-button-font-weight, var(--fk-typography-button-font-weight, 400));line-height:var(--fk-button-line-height, var(--fk-typography-button-line-height, 1.5));cursor:var(--fk-button-cursor, pointer);transition:var(--fk-button-transition, background-color .15s ease, border-color .15s ease, color .15s ease);text-decoration:none;white-space:nowrap;width:100%}.fk-button__native:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}.fk-button__content{display:inline-flex;align-items:center;gap:var(--fk-button-icon-gap, .5rem)}.fk-button__content--hidden{visibility:hidden}.fk-button__loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}:host.fk-button--sm .fk-button__native{padding:var(--fk-button-padding-sm, .375rem .75rem);font-size:var(--fk-button-font-size-sm, .875rem)}:host.fk-button--md .fk-button__native{padding:var(--fk-button-padding-md, .5rem 1rem);font-size:var(--fk-button-font-size-md, 1rem)}:host.fk-button--lg .fk-button__native{padding:var(--fk-button-padding-lg, .625rem 1.25rem);font-size:var(--fk-button-font-size-lg, 1.125rem)}:host.fk-button--primary .fk-button__native{background-color:var(--fk-button-primary-bg, var(--fk-color-primary, #0a84ff));color:var(--fk-button-primary-color, var(--fk-color-surface, #ffffff));border-color:var(--fk-button-primary-border-color, transparent)}:host.fk-button--primary:not(.fk-button--disabled) .fk-button__native:hover{background-color:var(--fk-button-primary-bg-hover, var(--fk-color-primary-hover, #0670e0))}:host.fk-button--primary:not(.fk-button--disabled) .fk-button__native:active{background-color:var(--fk-button-primary-bg-active, var(--fk-color-primary-active, #055fc3))}:host.fk-button--secondary .fk-button__native{background-color:var(--fk-button-secondary-bg, transparent);color:var(--fk-button-secondary-color, var(--fk-color-primary, #0a84ff));border-color:var(--fk-button-secondary-border-color, var(--fk-color-border, #d9e2ee))}:host.fk-button--secondary:not(.fk-button--disabled) .fk-button__native:hover{background-color:var(--fk-button-secondary-bg-hover, var(--fk-color-surface-muted, #f7f9fb))}:host.fk-button--secondary:not(.fk-button--disabled) .fk-button__native:active{background-color:var(--fk-button-secondary-bg-active, var(--fk-color-border, #d9e2ee))}:host.fk-button--outline .fk-button__native{background-color:var(--fk-button-outline-bg, transparent);color:var(--fk-button-outline-color, var(--fk-color-primary, #0a84ff));border-color:var(--fk-button-outline-border-color, var(--fk-color-border, #d9e2ee))}:host.fk-button--outline:not(.fk-button--disabled) .fk-button__native:hover{background-color:var(--fk-button-outline-bg-hover, var(--fk-color-surface-muted, #f7f9fb))}:host.fk-button--outline:not(.fk-button--disabled) .fk-button__native:active{background-color:var(--fk-button-outline-bg-active, var(--fk-color-border, #d9e2ee))}:host.fk-button--danger .fk-button__native{background-color:var(--fk-button-danger-bg, var(--fk-color-danger, #e02424));color:var(--fk-button-danger-color, var(--fk-color-surface, #ffffff));border-color:var(--fk-button-danger-border-color, transparent)}:host.fk-button--danger:not(.fk-button--disabled) .fk-button__native:hover{background-color:var(--fk-button-danger-bg-hover, #b91c1c)}:host.fk-button--danger:not(.fk-button--disabled) .fk-button__native:active{background-color:var(--fk-button-danger-bg-active, #991b1b)}:host.fk-button--disabled .fk-button__native{opacity:var(--fk-button-opacity-disabled, .6);cursor:var(--fk-button-cursor-disabled, not-allowed)}\n"] }]
|
|
95
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], iconStartRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FK_BUTTON_ICON_START), { isSignal: true }] }], iconEndRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FK_BUTTON_ICON_END), { isSignal: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }], hostClass: [{
|
|
96
|
+
type: HostBinding,
|
|
97
|
+
args: ['class']
|
|
98
|
+
}], ariaDisabledAttr: [{
|
|
99
|
+
type: HostBinding,
|
|
100
|
+
args: ['attr.aria-disabled']
|
|
101
|
+
}] } });
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Generated bundle index. Do not edit.
|
|
105
|
+
*/
|
|
106
|
+
|
|
107
|
+
export { ButtonComponent, FK_BUTTON_ICON_END, FK_BUTTON_ICON_START, FkButtonIconEndDirective, FkButtonIconStartDirective };
|
|
108
|
+
//# sourceMappingURL=frame-kit-ui-ng-ui-button.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-button.mjs","sources":["../../../../packages/ui-ng/ui/button/button-icon.directive.ts","../../../../packages/ui-ng/ui/button/button.component.ts","../../../../packages/ui-ng/ui/button/button.component.html","../../../../packages/ui-ng/ui/button/frame-kit-ui-ng-ui-button.ts"],"sourcesContent":["import { Directive, InjectionToken } from '@angular/core';\n\nexport const FK_BUTTON_ICON_START =\n new InjectionToken<FkButtonIconStartDirective>('FK_BUTTON_ICON_START');\n\nexport const FK_BUTTON_ICON_END = new InjectionToken<FkButtonIconEndDirective>(\n 'FK_BUTTON_ICON_END',\n);\n\n@Directive({\n selector: '[fkButtonIconStart]',\n standalone: true,\n providers: [\n { provide: FK_BUTTON_ICON_START, useExisting: FkButtonIconStartDirective },\n ],\n host: {\n 'aria-hidden': 'true',\n },\n})\nexport class FkButtonIconStartDirective {}\n\n@Directive({\n selector: '[fkButtonIconEnd]',\n standalone: true,\n providers: [\n { provide: FK_BUTTON_ICON_END, useExisting: FkButtonIconEndDirective },\n ],\n host: {\n 'aria-hidden': 'true',\n },\n})\nexport class FkButtonIconEndDirective {}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n HostBinding,\n input,\n} from '@angular/core';\n\nimport { LoaderComponent } from '@frame-kit/ui-ng/ui/loader';\nimport type { ButtonSize, ButtonType, ButtonVariant } from './button.types';\nimport {\n FK_BUTTON_ICON_END,\n FK_BUTTON_ICON_START,\n} from './button-icon.directive';\n\n@Component({\n selector: 'fk-button',\n standalone: true,\n imports: [LoaderComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './button.component.html',\n styleUrl: './button.component.scss',\n})\nexport class ButtonComponent {\n // ===== BEHAVIOR =====\n /** Visual style variant of the button (primary, secondary, ghost, etc.). */\n readonly variant = input<ButtonVariant>('primary');\n /** Size of the button, affecting padding and font size. */\n readonly size = input<ButtonSize>('md');\n /** When true, shows a spinner and disables interaction. */\n readonly loading = input<boolean>(false);\n /** When true, prevents interaction and applies disabled styling. */\n readonly disabled = input<boolean>(false);\n /** HTML type attribute forwarded to the inner `<button>` element. */\n readonly type = input<ButtonType>('button');\n /** When true, the button stretches to fill its container width. */\n readonly fullWidth = input<boolean>(false);\n\n // ===== CONTENT CHILDREN =====\n readonly iconStartRef = contentChild(FK_BUTTON_ICON_START);\n readonly iconEndRef = contentChild(FK_BUTTON_ICON_END);\n\n // ===== BASE PROPS =====\n readonly id = input<string | null>(null);\n readonly className = input<string>('');\n readonly ariaLabel = input<string | null>(null);\n readonly ariaDescribedBy = input<string | null>(null);\n\n // ===== COMPUTED =====\n readonly isDisabled = computed(() => this.disabled() || this.loading());\n\n readonly classes = computed(() => {\n return [\n 'fk-button',\n `fk-button--${this.variant()}`,\n `fk-button--${this.size()}`,\n this.isDisabled() ? 'fk-button--disabled' : '',\n this.loading() ? 'fk-button--loading' : '',\n this.fullWidth() ? 'fk-button--full-width' : '',\n this.className(),\n ]\n .filter(Boolean)\n .join(' ');\n });\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n @HostBinding('attr.aria-disabled')\n get ariaDisabledAttr(): string | null {\n return this.isDisabled() ? 'true' : null;\n }\n}\n","<button\n class=\"fk-button__native\"\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [id]=\"id()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n>\n @if (loading()) {\n <fk-loader\n className=\"fk-button__loader\"\n size=\"sm\"\n color=\"inherit\"\n ariaLabel=\"Loading\"\n ></fk-loader>\n }\n <span\n class=\"fk-button__content\"\n [class.fk-button__content--hidden]=\"loading()\"\n >\n <ng-content select=\"[fkButtonIconStart]\" />\n <ng-content />\n <ng-content select=\"[fkButtonIconEnd]\" />\n </span>\n</button>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, computed, HostBinding, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { HeadlineComponent } from '@frame-kit/ui-ng/core/headline';
|
|
4
|
+
|
|
5
|
+
class CalloutComponent {
|
|
6
|
+
// ===== INPUTS =====
|
|
7
|
+
/** Optional title rendered as a headline above the projected content. */
|
|
8
|
+
title = input(null, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
9
|
+
/** Text alignment applied to the callout body. */
|
|
10
|
+
align = input('start', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
11
|
+
/** Custom background color applied via a CSS custom property. */
|
|
12
|
+
backgroundColor = input(null, ...(ngDevMode ? [{ debugName: "backgroundColor" }] : /* istanbul ignore next */ []));
|
|
13
|
+
/** Custom border color applied via a CSS custom property. */
|
|
14
|
+
borderColor = input(null, ...(ngDevMode ? [{ debugName: "borderColor" }] : /* istanbul ignore next */ []));
|
|
15
|
+
// ===== BASE PROPS =====
|
|
16
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
17
|
+
// ===== COMPUTED =====
|
|
18
|
+
classes = computed(() => {
|
|
19
|
+
return ['fk-callout', this.className()].filter(Boolean).join(' ');
|
|
20
|
+
}, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
21
|
+
get hostClass() {
|
|
22
|
+
return this.classes();
|
|
23
|
+
}
|
|
24
|
+
get hostBg() {
|
|
25
|
+
return this.backgroundColor();
|
|
26
|
+
}
|
|
27
|
+
get hostBorderColor() {
|
|
28
|
+
return this.borderColor();
|
|
29
|
+
}
|
|
30
|
+
get hostTextAlign() {
|
|
31
|
+
return this.align() === 'start' ? null : this.align();
|
|
32
|
+
}
|
|
33
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CalloutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
34
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: CalloutComponent, isStandalone: true, selector: "fk-callout", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, backgroundColor: { classPropertyName: "backgroundColor", publicName: "backgroundColor", isSignal: true, isRequired: false, transformFunction: null }, borderColor: { classPropertyName: "borderColor", publicName: "borderColor", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClass", "style.--fk-callout-bg": "this.hostBg", "style.--fk-callout-border-color": "this.hostBorderColor", "style.text-align": "this.hostTextAlign" } }, ngImport: i0, template: "@if (title()) {\n <fk-headline [level]=\"6\">{{ title() }}</fk-headline>\n}\n\n<p class=\"fk-callout__description\">\n <ng-content />\n</p>\n", styles: [":host{display:block;padding:var(--fk-callout-padding, var(--fk-rhythm-4, 1rem));background-color:var(--fk-callout-bg, var(--fk-color-surface-muted, #f7f9fb));border:1px solid var(--fk-callout-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-callout-border-radius, var(--fk-radius-md, .375rem));font-size:var(--fk-callout-font-size, var(--fk-typography-small-font-size, .8125rem));--fk-typography-h6-font-size: var(--fk-callout-title-font-size, inherit)}fk-headline+.fk-callout__description{margin-block-start:var(--fk-callout-title-gap, var(--fk-rhythm-2, .5rem))}.fk-callout__description{margin:0;color:var(--fk-text-color-muted, #6b7280);line-height:var(--fk-typography-small-line-height, 1.4);letter-spacing:var(--fk-typography-small-letter-spacing, .01em)}\n"], dependencies: [{ kind: "component", type: HeadlineComponent, selector: "fk-headline", inputs: ["ariaLabel", "className", "fontSize", "id", "level", "variant", "visuallyHidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
35
|
+
}
|
|
36
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CalloutComponent, decorators: [{
|
|
37
|
+
type: Component,
|
|
38
|
+
args: [{ selector: 'fk-callout', standalone: true, imports: [HeadlineComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (title()) {\n <fk-headline [level]=\"6\">{{ title() }}</fk-headline>\n}\n\n<p class=\"fk-callout__description\">\n <ng-content />\n</p>\n", styles: [":host{display:block;padding:var(--fk-callout-padding, var(--fk-rhythm-4, 1rem));background-color:var(--fk-callout-bg, var(--fk-color-surface-muted, #f7f9fb));border:1px solid var(--fk-callout-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-callout-border-radius, var(--fk-radius-md, .375rem));font-size:var(--fk-callout-font-size, var(--fk-typography-small-font-size, .8125rem));--fk-typography-h6-font-size: var(--fk-callout-title-font-size, inherit)}fk-headline+.fk-callout__description{margin-block-start:var(--fk-callout-title-gap, var(--fk-rhythm-2, .5rem))}.fk-callout__description{margin:0;color:var(--fk-text-color-muted, #6b7280);line-height:var(--fk-typography-small-line-height, 1.4);letter-spacing:var(--fk-typography-small-letter-spacing, .01em)}\n"] }]
|
|
39
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], backgroundColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "backgroundColor", required: false }] }], borderColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "borderColor", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], hostClass: [{
|
|
40
|
+
type: HostBinding,
|
|
41
|
+
args: ['class']
|
|
42
|
+
}], hostBg: [{
|
|
43
|
+
type: HostBinding,
|
|
44
|
+
args: ['style.--fk-callout-bg']
|
|
45
|
+
}], hostBorderColor: [{
|
|
46
|
+
type: HostBinding,
|
|
47
|
+
args: ['style.--fk-callout-border-color']
|
|
48
|
+
}], hostTextAlign: [{
|
|
49
|
+
type: HostBinding,
|
|
50
|
+
args: ['style.text-align']
|
|
51
|
+
}] } });
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Generated bundle index. Do not edit.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
export { CalloutComponent };
|
|
58
|
+
//# sourceMappingURL=frame-kit-ui-ng-ui-callout.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-callout.mjs","sources":["../../../../packages/ui-ng/ui/callout/callout.component.ts","../../../../packages/ui-ng/ui/callout/callout.component.html","../../../../packages/ui-ng/ui/callout/frame-kit-ui-ng-ui-callout.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n HostBinding,\n input,\n} from '@angular/core';\n\nimport { HeadlineComponent } from '@frame-kit/ui-ng/core/headline';\nimport type { TextAlign } from '@frame-kit/ui-ng/core/text';\n\n@Component({\n selector: 'fk-callout',\n standalone: true,\n imports: [HeadlineComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './callout.component.html',\n styleUrl: './callout.component.scss',\n})\nexport class CalloutComponent {\n // ===== INPUTS =====\n /** Optional title rendered as a headline above the projected content. */\n readonly title = input<string | null>(null);\n /** Text alignment applied to the callout body. */\n readonly align = input<TextAlign>('start');\n /** Custom background color applied via a CSS custom property. */\n readonly backgroundColor = input<string | null>(null);\n /** Custom border color applied via a CSS custom property. */\n readonly borderColor = input<string | null>(null);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n\n // ===== COMPUTED =====\n readonly classes = computed(() => {\n return ['fk-callout', this.className()].filter(Boolean).join(' ');\n });\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n @HostBinding('style.--fk-callout-bg')\n get hostBg() {\n return this.backgroundColor();\n }\n\n @HostBinding('style.--fk-callout-border-color')\n get hostBorderColor() {\n return this.borderColor();\n }\n\n @HostBinding('style.text-align')\n get hostTextAlign() {\n return this.align() === 'start' ? null : this.align();\n }\n}\n","@if (title()) {\n <fk-headline [level]=\"6\">{{ title() }}</fk-headline>\n}\n\n<p class=\"fk-callout__description\">\n <ng-content />\n</p>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, computed, HostBinding, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
class CardComponent {
|
|
5
|
+
// ===== INPUTS =====
|
|
6
|
+
/** Preset size that controls the card's internal padding; also accepts any valid CSS padding string for a custom size. */
|
|
7
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
8
|
+
/** Alignment of the card's content along the cross axis. */
|
|
9
|
+
align = input('stretch', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
10
|
+
/** When true, the card has no background fill. */
|
|
11
|
+
transparent = input(false, ...(ngDevMode ? [{ debugName: "transparent" }] : /* istanbul ignore next */ []));
|
|
12
|
+
/** When true, the card has no border or shadow. */
|
|
13
|
+
borderless = input(false, ...(ngDevMode ? [{ debugName: "borderless" }] : /* istanbul ignore next */ []));
|
|
14
|
+
// ===== BASE PROPS =====
|
|
15
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
16
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
17
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
18
|
+
// ===== COMPUTED =====
|
|
19
|
+
sizePresets = ['sm', 'md', 'lg'];
|
|
20
|
+
isCustomSize = computed(() => !this.sizePresets.includes(this.size()), ...(ngDevMode ? [{ debugName: "isCustomSize" }] : /* istanbul ignore next */ []));
|
|
21
|
+
classes = computed(() => {
|
|
22
|
+
return [
|
|
23
|
+
'fk-card',
|
|
24
|
+
this.isCustomSize() ? '' : `fk-card--${this.size()}`,
|
|
25
|
+
`fk-card--align-${this.align()}`,
|
|
26
|
+
this.transparent() ? 'fk-card--transparent' : '',
|
|
27
|
+
this.borderless() ? 'fk-card--borderless' : '',
|
|
28
|
+
this.className(),
|
|
29
|
+
]
|
|
30
|
+
.filter(Boolean)
|
|
31
|
+
.join(' ');
|
|
32
|
+
}, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
33
|
+
get hostClass() {
|
|
34
|
+
return this.classes();
|
|
35
|
+
}
|
|
36
|
+
get hostPadding() {
|
|
37
|
+
return this.isCustomSize() ? this.size() : null;
|
|
38
|
+
}
|
|
39
|
+
get hostId() {
|
|
40
|
+
return this.id();
|
|
41
|
+
}
|
|
42
|
+
get hostAriaLabel() {
|
|
43
|
+
return this.ariaLabel();
|
|
44
|
+
}
|
|
45
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
46
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: CardComponent, isStandalone: true, selector: "fk-card", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, transparent: { classPropertyName: "transparent", publicName: "transparent", isSignal: true, isRequired: false, transformFunction: null }, borderless: { classPropertyName: "borderless", publicName: "borderless", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClass", "style.padding": "this.hostPadding", "attr.id": "this.hostId", "attr.aria-label": "this.hostAriaLabel" } }, ngImport: i0, template: "<ng-content />\n", styles: [":host{display:flex;flex-direction:column;background-color:var(--fk-card-bg, var(--fk-color-surface, #ffffff));border:1px solid var(--fk-card-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-card-border-radius, var(--fk-radius-lg, .75rem))}:host.fk-card--transparent{background-color:transparent}:host.fk-card--borderless{border-color:transparent}:host.fk-card--align-start{align-items:flex-start}:host.fk-card--align-center{align-items:center}:host.fk-card--align-end{align-items:flex-end}:host.fk-card--align-stretch{align-items:stretch}:host.fk-card--sm{padding:var(--fk-card-padding-sm, var(--fk-rhythm-4, 1rem))}:host.fk-card--md{padding:var(--fk-card-padding-md, var(--fk-rhythm-6, 1.5rem))}:host.fk-card--lg{padding:var(--fk-card-padding-lg, var(--fk-rhythm-8, 2rem))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
47
|
+
}
|
|
48
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CardComponent, decorators: [{
|
|
49
|
+
type: Component,
|
|
50
|
+
args: [{ selector: 'fk-card', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content />\n", styles: [":host{display:flex;flex-direction:column;background-color:var(--fk-card-bg, var(--fk-color-surface, #ffffff));border:1px solid var(--fk-card-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-card-border-radius, var(--fk-radius-lg, .75rem))}:host.fk-card--transparent{background-color:transparent}:host.fk-card--borderless{border-color:transparent}:host.fk-card--align-start{align-items:flex-start}:host.fk-card--align-center{align-items:center}:host.fk-card--align-end{align-items:flex-end}:host.fk-card--align-stretch{align-items:stretch}:host.fk-card--sm{padding:var(--fk-card-padding-sm, var(--fk-rhythm-4, 1rem))}:host.fk-card--md{padding:var(--fk-card-padding-md, var(--fk-rhythm-6, 1.5rem))}:host.fk-card--lg{padding:var(--fk-card-padding-lg, var(--fk-rhythm-8, 2rem))}\n"] }]
|
|
51
|
+
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], transparent: [{ type: i0.Input, args: [{ isSignal: true, alias: "transparent", required: false }] }], borderless: [{ type: i0.Input, args: [{ isSignal: true, alias: "borderless", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hostClass: [{
|
|
52
|
+
type: HostBinding,
|
|
53
|
+
args: ['class']
|
|
54
|
+
}], hostPadding: [{
|
|
55
|
+
type: HostBinding,
|
|
56
|
+
args: ['style.padding']
|
|
57
|
+
}], hostId: [{
|
|
58
|
+
type: HostBinding,
|
|
59
|
+
args: ['attr.id']
|
|
60
|
+
}], hostAriaLabel: [{
|
|
61
|
+
type: HostBinding,
|
|
62
|
+
args: ['attr.aria-label']
|
|
63
|
+
}] } });
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Generated bundle index. Do not edit.
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
export { CardComponent };
|
|
70
|
+
//# sourceMappingURL=frame-kit-ui-ng-ui-card.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-card.mjs","sources":["../../../../packages/ui-ng/ui/card/card.component.ts","../../../../packages/ui-ng/ui/card/card.component.html","../../../../packages/ui-ng/ui/card/frame-kit-ui-ng-ui-card.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n HostBinding,\n input,\n} from '@angular/core';\n\nimport type { CardAlign, CardSize } from './card.types';\n\n@Component({\n selector: 'fk-card',\n standalone: true,\n imports: [],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './card.component.html',\n styleUrl: './card.component.scss',\n})\nexport class CardComponent {\n // ===== INPUTS =====\n /** Preset size that controls the card's internal padding; also accepts any valid CSS padding string for a custom size. */\n readonly size = input<CardSize>('md');\n /** Alignment of the card's content along the cross axis. */\n readonly align = input<CardAlign>('stretch');\n /** When true, the card has no background fill. */\n readonly transparent = input<boolean>(false);\n /** When true, the card has no border or shadow. */\n readonly borderless = input<boolean>(false);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n\n // ===== COMPUTED =====\n private readonly sizePresets = ['sm', 'md', 'lg'];\n\n readonly isCustomSize = computed(\n () => !this.sizePresets.includes(this.size()),\n );\n\n readonly classes = computed(() => {\n return [\n 'fk-card',\n this.isCustomSize() ? '' : `fk-card--${this.size()}`,\n `fk-card--align-${this.align()}`,\n this.transparent() ? 'fk-card--transparent' : '',\n this.borderless() ? 'fk-card--borderless' : '',\n this.className(),\n ]\n .filter(Boolean)\n .join(' ');\n });\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n @HostBinding('style.padding')\n get hostPadding(): string | null {\n return this.isCustomSize() ? this.size() : null;\n }\n\n @HostBinding('attr.id')\n get hostId() {\n return this.id();\n }\n\n @HostBinding('attr.aria-label')\n get hostAriaLabel() {\n return this.ariaLabel();\n }\n}\n","<ng-content />\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;MAkBa,aAAa,CAAA;;;AAGf,IAAA,IAAI,GAAG,KAAK,CAAW,IAAI,2EAAC;;AAE5B,IAAA,KAAK,GAAG,KAAK,CAAY,SAAS,4EAAC;;AAEnC,IAAA,WAAW,GAAG,KAAK,CAAU,KAAK,kFAAC;;AAEnC,IAAA,UAAU,GAAG,KAAK,CAAU,KAAK,iFAAC;;AAGlC,IAAA,SAAS,GAAG,KAAK,CAAS,EAAE,gFAAC;AAC7B,IAAA,EAAE,GAAG,KAAK,CAAgB,IAAI,yEAAC;AAC/B,IAAA,SAAS,GAAG,KAAK,CAAgB,IAAI,gFAAC;;IAG9B,WAAW,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;AAExC,IAAA,YAAY,GAAG,QAAQ,CAC9B,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,mFAC9C;AAEQ,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;QAC/B,OAAO;YACL,SAAS;AACT,YAAA,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,GAAG,CAAA,SAAA,EAAY,IAAI,CAAC,IAAI,EAAE,CAAA,CAAE;AACpD,YAAA,CAAA,eAAA,EAAkB,IAAI,CAAC,KAAK,EAAE,CAAA,CAAE;YAChC,IAAI,CAAC,WAAW,EAAE,GAAG,sBAAsB,GAAG,EAAE;YAChD,IAAI,CAAC,UAAU,EAAE,GAAG,qBAAqB,GAAG,EAAE;YAC9C,IAAI,CAAC,SAAS,EAAE;AACjB;aACE,MAAM,CAAC,OAAO;aACd,IAAI,CAAC,GAAG,CAAC;AACd,IAAA,CAAC,8EAAC;AAEF,IAAA,IACI,SAAS,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,OAAO,EAAE;IACvB;AAEA,IAAA,IACI,WAAW,GAAA;AACb,QAAA,OAAO,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI;IACjD;AAEA,IAAA,IACI,MAAM,GAAA;AACR,QAAA,OAAO,IAAI,CAAC,EAAE,EAAE;IAClB;AAEA,IAAA,IACI,aAAa,GAAA;AACf,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE;IACzB;uGAtDW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,aAAa,imCClB1B,kBACA,EAAA,MAAA,EAAA,CAAA,+xBAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FDiBa,aAAa,EAAA,UAAA,EAAA,CAAA;kBARzB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,SAAS,cACP,IAAI,EAAA,OAAA,EACP,EAAE,EAAA,eAAA,EACM,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,+xBAAA,CAAA,EAAA;;sBAwC9C,WAAW;uBAAC,OAAO;;sBAKnB,WAAW;uBAAC,eAAe;;sBAK3B,WAAW;uBAAC,SAAS;;sBAKrB,WAAW;uBAAC,iBAAiB;;;AErEhC;;AAEG;;;;"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, output, signal, computed, inject, DestroyRef, HostBinding, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Displays a read-only value next to a copy-to-clipboard button.
|
|
6
|
+
*
|
|
7
|
+
* Use for showing secrets (API keys, tokens), IDs, URLs, and any value the
|
|
8
|
+
* user will want to copy rather than re-type. After a successful copy the
|
|
9
|
+
* copy-button icon swaps to a confirmation for `copiedDuration` ms and a
|
|
10
|
+
* screen-reader announcement fires.
|
|
11
|
+
*
|
|
12
|
+
* The copy button ships with inline SVG icons for both states so the
|
|
13
|
+
* component works standalone. Consumers can override either icon by
|
|
14
|
+
* projecting their own element with the `fkCopyIcon` or `fkCopiedIcon`
|
|
15
|
+
* attribute selector — for example an `fk-icon` wired to their own icon
|
|
16
|
+
* registry:
|
|
17
|
+
*
|
|
18
|
+
* ```html
|
|
19
|
+
* <fk-copyable-field [value]="apiKey">
|
|
20
|
+
* <fk-icon fkCopyIcon name="clipboard-outline" size="sm" />
|
|
21
|
+
* <fk-icon fkCopiedIcon name="check-outline" size="sm" />
|
|
22
|
+
* </fk-copyable-field>
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
class CopyableFieldComponent {
|
|
26
|
+
// ===== INPUTS =====
|
|
27
|
+
/** The string value displayed and written to the clipboard when the user copies. */
|
|
28
|
+
value = input.required(...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
29
|
+
/** Optional visible label rendered above the value field. */
|
|
30
|
+
label = input(null, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
31
|
+
/** Controls the size variant of the field. */
|
|
32
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
33
|
+
/** When true, the value is rendered in a monospace font. */
|
|
34
|
+
mono = input(true, ...(ngDevMode ? [{ debugName: "mono" }] : /* istanbul ignore next */ []));
|
|
35
|
+
/** Accessible label for the copy button read by screen readers. */
|
|
36
|
+
copyAriaLabel = input('Copy to clipboard', ...(ngDevMode ? [{ debugName: "copyAriaLabel" }] : /* istanbul ignore next */ []));
|
|
37
|
+
/** Screen-reader announcement text emitted after a successful copy. */
|
|
38
|
+
copiedAnnouncement = input('Copied to clipboard', ...(ngDevMode ? [{ debugName: "copiedAnnouncement" }] : /* istanbul ignore next */ []));
|
|
39
|
+
/** How long in milliseconds the "copied" confirmation state is shown. */
|
|
40
|
+
copiedDuration = input(2000, ...(ngDevMode ? [{ debugName: "copiedDuration" }] : /* istanbul ignore next */ []));
|
|
41
|
+
// ===== BASE PROPS =====
|
|
42
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
43
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
44
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
45
|
+
// ===== OUTPUTS =====
|
|
46
|
+
/** Fires after a successful clipboard write, emitting the copied value. */
|
|
47
|
+
copied = output();
|
|
48
|
+
/** Fires when the clipboard write fails, emitting the underlying error. */
|
|
49
|
+
copyFailed = output();
|
|
50
|
+
// ===== STATE =====
|
|
51
|
+
_isCopied = signal(false, ...(ngDevMode ? [{ debugName: "_isCopied" }] : /* istanbul ignore next */ []));
|
|
52
|
+
copyTimer = null;
|
|
53
|
+
isCopied = this._isCopied.asReadonly();
|
|
54
|
+
// ===== COMPUTED =====
|
|
55
|
+
classes = computed(() => {
|
|
56
|
+
return [
|
|
57
|
+
'fk-copyable-field',
|
|
58
|
+
`fk-copyable-field--${this.size()}`,
|
|
59
|
+
this.mono() ? 'fk-copyable-field--mono' : '',
|
|
60
|
+
this.className(),
|
|
61
|
+
]
|
|
62
|
+
.filter(Boolean)
|
|
63
|
+
.join(' ');
|
|
64
|
+
}, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
65
|
+
get hostClass() {
|
|
66
|
+
return this.classes();
|
|
67
|
+
}
|
|
68
|
+
constructor() {
|
|
69
|
+
const destroyRef = inject(DestroyRef);
|
|
70
|
+
destroyRef.onDestroy(() => {
|
|
71
|
+
this.clearCopyTimer();
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/** Writes the current value to the clipboard and shows the copied confirmation state. */
|
|
75
|
+
async copy() {
|
|
76
|
+
try {
|
|
77
|
+
await navigator.clipboard.writeText(this.value());
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
this.copyFailed.emit(error);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
this._isCopied.set(true);
|
|
84
|
+
this.copied.emit(this.value());
|
|
85
|
+
this.clearCopyTimer();
|
|
86
|
+
this.copyTimer = setTimeout(() => {
|
|
87
|
+
this._isCopied.set(false);
|
|
88
|
+
this.copyTimer = null;
|
|
89
|
+
}, this.copiedDuration());
|
|
90
|
+
}
|
|
91
|
+
clearCopyTimer() {
|
|
92
|
+
if (this.copyTimer) {
|
|
93
|
+
clearTimeout(this.copyTimer);
|
|
94
|
+
this.copyTimer = null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CopyableFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
98
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: CopyableFieldComponent, isStandalone: true, selector: "fk-copyable-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, mono: { classPropertyName: "mono", publicName: "mono", isSignal: true, isRequired: false, transformFunction: null }, copyAriaLabel: { classPropertyName: "copyAriaLabel", publicName: "copyAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, copiedAnnouncement: { classPropertyName: "copiedAnnouncement", publicName: "copiedAnnouncement", isSignal: true, isRequired: false, transformFunction: null }, copiedDuration: { classPropertyName: "copiedDuration", publicName: "copiedDuration", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { copied: "copied", copyFailed: "copyFailed" }, host: { properties: { "class": "this.hostClass" } }, ngImport: i0, template: "@if (label()) {\n <span class=\"fk-copyable-field__label\">{{ label() }}</span>\n}\n\n<div class=\"fk-copyable-field__row\">\n <span\n class=\"fk-copyable-field__value\"\n [id]=\"id() ?? undefined\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n {{ value() }}\n </span>\n\n <button\n type=\"button\"\n class=\"fk-copyable-field__action\"\n [attr.aria-label]=\"copyAriaLabel()\"\n (click)=\"copy()\"\n >\n @if (isCopied()) {\n <ng-content select=\"[fkCopiedIcon]\">\n <svg\n class=\"fk-copyable-field__icon\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3 8.5l3 3L13 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </ng-content>\n } @else {\n <ng-content select=\"[fkCopyIcon]\">\n <svg\n class=\"fk-copyable-field__icon\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <rect\n x=\"5.25\"\n y=\"5.25\"\n width=\"8.5\"\n height=\"8.5\"\n rx=\"1.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n />\n <path\n d=\"M10 5.25V3.75A1.5 1.5 0 0 0 8.5 2.25h-5A1.5 1.5 0 0 0 2 3.75v5A1.5 1.5 0 0 0 3.5 10.25H5\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n />\n </svg>\n </ng-content>\n }\n </button>\n</div>\n\n<span class=\"fk-copyable-field__sr-only\" role=\"status\" aria-live=\"polite\">\n @if (isCopied()) {\n {{ copiedAnnouncement() }}\n }\n</span>\n", styles: [":host{display:block}.fk-copyable-field__label{display:block;margin-bottom:var(--fk-copyable-field-label-gap, var(--fk-rhythm-1, .25rem));font-size:var(--fk-copyable-field-label-font-size, var(--fk-typography-small-font-size, .8125rem));font-weight:var(--fk-copyable-field-label-font-weight, var(--fk-font-weight-medium, 500));color:var(--fk-copyable-field-label-color, var(--fk-color-muted, #8a98a8))}.fk-copyable-field__row{display:flex;align-items:center;gap:var(--fk-copyable-field-gap, var(--fk-rhythm-2, .5rem));background:var(--fk-copyable-field-bg, var(--fk-color-surface-muted, #f7f9fb));border:1px solid var(--fk-copyable-field-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-copyable-field-radius, var(--fk-radius-md, .5rem))}.fk-copyable-field__value{flex:1;min-width:0;color:var(--fk-copyable-field-value-color, var(--fk-color-text, #1f2d3d));word-break:break-all}.fk-copyable-field__action{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;padding:var(--fk-copyable-field-action-padding, var(--fk-rhythm-1, .25rem));color:var(--fk-copyable-field-action-color, var(--fk-color-muted, #8a98a8));background:transparent;border:none;border-radius:var(--fk-copyable-field-action-radius, var(--fk-radius-sm, .25rem));cursor:pointer;transition:color .15s,background-color .15s}.fk-copyable-field__action:hover{color:var(--fk-copyable-field-action-color-hover, var(--fk-color-text, #1f2d3d));background:var(--fk-copyable-field-action-bg-hover, var(--fk-color-surface-dim, #f1f4f8))}.fk-copyable-field__action:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}.fk-copyable-field__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host.fk-copyable-field--sm .fk-copyable-field__row{padding:var(--fk-copyable-field-padding-sm, var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem))}:host.fk-copyable-field--sm .fk-copyable-field__value{font-size:var(--fk-copyable-field-font-size-sm, var(--fk-typography-caption-font-size, .75rem))}:host.fk-copyable-field--md .fk-copyable-field__row{padding:var(--fk-copyable-field-padding-md, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem))}:host.fk-copyable-field--md .fk-copyable-field__value{font-size:var(--fk-copyable-field-font-size-md, var(--fk-typography-small-font-size, .8125rem))}:host.fk-copyable-field--lg .fk-copyable-field__row{padding:var(--fk-copyable-field-padding-lg, var(--fk-rhythm-3, .75rem) var(--fk-rhythm-4, 1rem))}:host.fk-copyable-field--lg .fk-copyable-field__value{font-size:var(--fk-copyable-field-font-size-lg, var(--fk-typography-body-font-size, .9375rem))}:host.fk-copyable-field--mono .fk-copyable-field__value{font-family:var(--fk-copyable-field-mono-font-family, var(--fk-font-family-mono, ui-monospace, SFMono-Regular, Menlo, monospace))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
99
|
+
}
|
|
100
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CopyableFieldComponent, decorators: [{
|
|
101
|
+
type: Component,
|
|
102
|
+
args: [{ selector: 'fk-copyable-field', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (label()) {\n <span class=\"fk-copyable-field__label\">{{ label() }}</span>\n}\n\n<div class=\"fk-copyable-field__row\">\n <span\n class=\"fk-copyable-field__value\"\n [id]=\"id() ?? undefined\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n {{ value() }}\n </span>\n\n <button\n type=\"button\"\n class=\"fk-copyable-field__action\"\n [attr.aria-label]=\"copyAriaLabel()\"\n (click)=\"copy()\"\n >\n @if (isCopied()) {\n <ng-content select=\"[fkCopiedIcon]\">\n <svg\n class=\"fk-copyable-field__icon\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3 8.5l3 3L13 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </ng-content>\n } @else {\n <ng-content select=\"[fkCopyIcon]\">\n <svg\n class=\"fk-copyable-field__icon\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <rect\n x=\"5.25\"\n y=\"5.25\"\n width=\"8.5\"\n height=\"8.5\"\n rx=\"1.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n />\n <path\n d=\"M10 5.25V3.75A1.5 1.5 0 0 0 8.5 2.25h-5A1.5 1.5 0 0 0 2 3.75v5A1.5 1.5 0 0 0 3.5 10.25H5\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n />\n </svg>\n </ng-content>\n }\n </button>\n</div>\n\n<span class=\"fk-copyable-field__sr-only\" role=\"status\" aria-live=\"polite\">\n @if (isCopied()) {\n {{ copiedAnnouncement() }}\n }\n</span>\n", styles: [":host{display:block}.fk-copyable-field__label{display:block;margin-bottom:var(--fk-copyable-field-label-gap, var(--fk-rhythm-1, .25rem));font-size:var(--fk-copyable-field-label-font-size, var(--fk-typography-small-font-size, .8125rem));font-weight:var(--fk-copyable-field-label-font-weight, var(--fk-font-weight-medium, 500));color:var(--fk-copyable-field-label-color, var(--fk-color-muted, #8a98a8))}.fk-copyable-field__row{display:flex;align-items:center;gap:var(--fk-copyable-field-gap, var(--fk-rhythm-2, .5rem));background:var(--fk-copyable-field-bg, var(--fk-color-surface-muted, #f7f9fb));border:1px solid var(--fk-copyable-field-border-color, var(--fk-color-border, #d9e2ee));border-radius:var(--fk-copyable-field-radius, var(--fk-radius-md, .5rem))}.fk-copyable-field__value{flex:1;min-width:0;color:var(--fk-copyable-field-value-color, var(--fk-color-text, #1f2d3d));word-break:break-all}.fk-copyable-field__action{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;padding:var(--fk-copyable-field-action-padding, var(--fk-rhythm-1, .25rem));color:var(--fk-copyable-field-action-color, var(--fk-color-muted, #8a98a8));background:transparent;border:none;border-radius:var(--fk-copyable-field-action-radius, var(--fk-radius-sm, .25rem));cursor:pointer;transition:color .15s,background-color .15s}.fk-copyable-field__action:hover{color:var(--fk-copyable-field-action-color-hover, var(--fk-color-text, #1f2d3d));background:var(--fk-copyable-field-action-bg-hover, var(--fk-color-surface-dim, #f1f4f8))}.fk-copyable-field__action:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}.fk-copyable-field__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host.fk-copyable-field--sm .fk-copyable-field__row{padding:var(--fk-copyable-field-padding-sm, var(--fk-rhythm-1, .25rem) var(--fk-rhythm-2, .5rem))}:host.fk-copyable-field--sm .fk-copyable-field__value{font-size:var(--fk-copyable-field-font-size-sm, var(--fk-typography-caption-font-size, .75rem))}:host.fk-copyable-field--md .fk-copyable-field__row{padding:var(--fk-copyable-field-padding-md, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem))}:host.fk-copyable-field--md .fk-copyable-field__value{font-size:var(--fk-copyable-field-font-size-md, var(--fk-typography-small-font-size, .8125rem))}:host.fk-copyable-field--lg .fk-copyable-field__row{padding:var(--fk-copyable-field-padding-lg, var(--fk-rhythm-3, .75rem) var(--fk-rhythm-4, 1rem))}:host.fk-copyable-field--lg .fk-copyable-field__value{font-size:var(--fk-copyable-field-font-size-lg, var(--fk-typography-body-font-size, .9375rem))}:host.fk-copyable-field--mono .fk-copyable-field__value{font-family:var(--fk-copyable-field-mono-font-family, var(--fk-font-family-mono, ui-monospace, SFMono-Regular, Menlo, monospace))}\n"] }]
|
|
103
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], mono: [{ type: i0.Input, args: [{ isSignal: true, alias: "mono", required: false }] }], copyAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "copyAriaLabel", required: false }] }], copiedAnnouncement: [{ type: i0.Input, args: [{ isSignal: true, alias: "copiedAnnouncement", required: false }] }], copiedDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "copiedDuration", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], copied: [{ type: i0.Output, args: ["copied"] }], copyFailed: [{ type: i0.Output, args: ["copyFailed"] }], hostClass: [{
|
|
104
|
+
type: HostBinding,
|
|
105
|
+
args: ['class']
|
|
106
|
+
}] } });
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Generated bundle index. Do not edit.
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
export { CopyableFieldComponent };
|
|
113
|
+
//# sourceMappingURL=frame-kit-ui-ng-ui-copyable-field.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-copyable-field.mjs","sources":["../../../../packages/ui-ng/ui/copyable-field/copyable-field.component.ts","../../../../packages/ui-ng/ui/copyable-field/copyable-field.component.html","../../../../packages/ui-ng/ui/copyable-field/frame-kit-ui-ng-ui-copyable-field.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n HostBinding,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\n\nimport type { CopyableFieldSize } from './copyable-field.types';\n\n/**\n * Displays a read-only value next to a copy-to-clipboard button.\n *\n * Use for showing secrets (API keys, tokens), IDs, URLs, and any value the\n * user will want to copy rather than re-type. After a successful copy the\n * copy-button icon swaps to a confirmation for `copiedDuration` ms and a\n * screen-reader announcement fires.\n *\n * The copy button ships with inline SVG icons for both states so the\n * component works standalone. Consumers can override either icon by\n * projecting their own element with the `fkCopyIcon` or `fkCopiedIcon`\n * attribute selector — for example an `fk-icon` wired to their own icon\n * registry:\n *\n * ```html\n * <fk-copyable-field [value]=\"apiKey\">\n * <fk-icon fkCopyIcon name=\"clipboard-outline\" size=\"sm\" />\n * <fk-icon fkCopiedIcon name=\"check-outline\" size=\"sm\" />\n * </fk-copyable-field>\n * ```\n */\n@Component({\n selector: 'fk-copyable-field',\n standalone: true,\n imports: [],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './copyable-field.component.html',\n styleUrl: './copyable-field.component.scss',\n})\nexport class CopyableFieldComponent {\n // ===== INPUTS =====\n /** The string value displayed and written to the clipboard when the user copies. */\n readonly value = input.required<string>();\n /** Optional visible label rendered above the value field. */\n readonly label = input<string | null>(null);\n /** Controls the size variant of the field. */\n readonly size = input<CopyableFieldSize>('md');\n /** When true, the value is rendered in a monospace font. */\n readonly mono = input<boolean>(true);\n /** Accessible label for the copy button read by screen readers. */\n readonly copyAriaLabel = input<string>('Copy to clipboard');\n /** Screen-reader announcement text emitted after a successful copy. */\n readonly copiedAnnouncement = input<string>('Copied to clipboard');\n /** How long in milliseconds the \"copied\" confirmation state is shown. */\n readonly copiedDuration = input<number>(2000);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n\n // ===== OUTPUTS =====\n /** Fires after a successful clipboard write, emitting the copied value. */\n readonly copied = output<string>();\n /** Fires when the clipboard write fails, emitting the underlying error. */\n readonly copyFailed = output<unknown>();\n\n // ===== STATE =====\n private readonly _isCopied = signal(false);\n private copyTimer: ReturnType<typeof setTimeout> | null = null;\n\n readonly isCopied = this._isCopied.asReadonly();\n\n // ===== COMPUTED =====\n readonly classes = computed(() => {\n return [\n 'fk-copyable-field',\n `fk-copyable-field--${this.size()}`,\n this.mono() ? 'fk-copyable-field--mono' : '',\n this.className(),\n ]\n .filter(Boolean)\n .join(' ');\n });\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n constructor() {\n const destroyRef = inject(DestroyRef);\n\n destroyRef.onDestroy(() => {\n this.clearCopyTimer();\n });\n }\n\n /** Writes the current value to the clipboard and shows the copied confirmation state. */\n async copy(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.value());\n } catch (error) {\n this.copyFailed.emit(error);\n\n return;\n }\n\n this._isCopied.set(true);\n this.copied.emit(this.value());\n\n this.clearCopyTimer();\n\n this.copyTimer = setTimeout(() => {\n this._isCopied.set(false);\n this.copyTimer = null;\n }, this.copiedDuration());\n }\n\n private clearCopyTimer(): void {\n if (this.copyTimer) {\n clearTimeout(this.copyTimer);\n this.copyTimer = null;\n }\n }\n}\n","@if (label()) {\n <span class=\"fk-copyable-field__label\">{{ label() }}</span>\n}\n\n<div class=\"fk-copyable-field__row\">\n <span\n class=\"fk-copyable-field__value\"\n [id]=\"id() ?? undefined\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n {{ value() }}\n </span>\n\n <button\n type=\"button\"\n class=\"fk-copyable-field__action\"\n [attr.aria-label]=\"copyAriaLabel()\"\n (click)=\"copy()\"\n >\n @if (isCopied()) {\n <ng-content select=\"[fkCopiedIcon]\">\n <svg\n class=\"fk-copyable-field__icon\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3 8.5l3 3L13 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </ng-content>\n } @else {\n <ng-content select=\"[fkCopyIcon]\">\n <svg\n class=\"fk-copyable-field__icon\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <rect\n x=\"5.25\"\n y=\"5.25\"\n width=\"8.5\"\n height=\"8.5\"\n rx=\"1.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n />\n <path\n d=\"M10 5.25V3.75A1.5 1.5 0 0 0 8.5 2.25h-5A1.5 1.5 0 0 0 2 3.75v5A1.5 1.5 0 0 0 3.5 10.25H5\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n />\n </svg>\n </ng-content>\n }\n </button>\n</div>\n\n<span class=\"fk-copyable-field__sr-only\" role=\"status\" aria-live=\"polite\">\n @if (isCopied()) {\n {{ copiedAnnouncement() }}\n }\n</span>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|