@frame-kit/ui-ng-patterns 0.1.6 → 0.1.8
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.
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input,
|
|
2
|
+
import { input, computed, HostBinding, ChangeDetectionStrategy, ViewEncapsulation, Component, inject, TemplateRef, Directive, ViewContainerRef, DestroyRef, Injector, viewChild, contentChild, signal, effect, afterNextRender, output, ElementRef, linkedSignal } from '@angular/core';
|
|
3
3
|
import { HeadlineComponent } from '@frame-kit/ui-ng/core/headline';
|
|
4
4
|
import { TextComponent } from '@frame-kit/ui-ng/core/text';
|
|
5
5
|
import { IconComponent } from '@frame-kit/ui-ng/core/icon';
|
|
6
6
|
import { Overlay } from '@angular/cdk/overlay';
|
|
7
7
|
import { TemplatePortal } from '@angular/cdk/portal';
|
|
8
8
|
import { NgTemplateOutlet } from '@angular/common';
|
|
9
|
-
import { toSignal } from '@angular/core/rxjs-interop';
|
|
9
|
+
import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
10
10
|
import { Router, ActivatedRoute, NavigationEnd, RouterLink } from '@angular/router';
|
|
11
11
|
import { filter, map, Subscription } from 'rxjs';
|
|
12
12
|
import { TooltipDirective } from '@frame-kit/ui-ng/directives/tooltip';
|
|
13
13
|
import { AppShellComponent } from '@frame-kit/ui-ng/layouts/app-shell';
|
|
14
14
|
import { ButtonComponent } from '@frame-kit/ui-ng/ui/button';
|
|
15
15
|
import { IconBadgeComponent } from '@frame-kit/ui-ng/ui/icon-badge';
|
|
16
|
+
import * as i1 from '@angular/cdk/drag-drop';
|
|
17
|
+
import { CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop';
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* Page-level dashboard header: title + optional description on the left, up to
|
|
@@ -47,16 +49,35 @@ import { IconBadgeComponent } from '@frame-kit/ui-ng/ui/icon-badge';
|
|
|
47
49
|
* </fk-page-header>
|
|
48
50
|
*/
|
|
49
51
|
class PageHeaderComponent {
|
|
52
|
+
// ===== INPUTS =====
|
|
50
53
|
title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
51
54
|
description = input(null, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
52
55
|
headingLevel = input(1, ...(ngDevMode ? [{ debugName: "headingLevel" }] : /* istanbul ignore next */ []));
|
|
56
|
+
// ===== BASE PROPS =====
|
|
57
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
58
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
59
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
60
|
+
// ===== COMPUTED =====
|
|
61
|
+
classes = computed(() => ['fk-page-header', this.className()].filter(Boolean).join(' '), ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
62
|
+
get hostClass() {
|
|
63
|
+
return this.classes();
|
|
64
|
+
}
|
|
65
|
+
get hostId() {
|
|
66
|
+
return this.id();
|
|
67
|
+
}
|
|
53
68
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: PageHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
54
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: PageHeaderComponent, isStandalone: true, selector: "fk-page-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, headingLevel: { classPropertyName: "headingLevel", publicName: "headingLevel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<header class=\"fk-page-
|
|
69
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: PageHeaderComponent, isStandalone: true, selector: "fk-page-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, headingLevel: { classPropertyName: "headingLevel", publicName: "headingLevel", 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", "attr.id": "this.hostId" } }, ngImport: i0, template: "<header class=\"fk-page-header__bar\" [attr.aria-label]=\"ariaLabel()\">\n <div class=\"fk-page-header__text\">\n <div class=\"fk-page-header__title-row\">\n <ng-content select=\"[pageHeaderLeading]\" />\n\n <fk-headline [level]=\"headingLevel()\">{{ title() }}</fk-headline>\n\n <ng-content select=\"[pageHeaderTrailing]\" />\n </div>\n\n @if (description()) {\n <fk-text class=\"fk-page-header__description\" tone=\"muted\">{{\n description()\n }}</fk-text>\n }\n </div>\n\n <div class=\"fk-page-header__actions\">\n <ng-content select=\"[pageHeaderActions]\" />\n </div>\n</header>\n", styles: [":host{display:block;container-type:inline-size}.fk-page-header__bar{display:flex;flex-direction:column;gap:var(--fk-rhythm-4, 1rem)}.fk-page-header__text{min-width:0}.fk-page-header__title-row{display:flex;align-items:center;gap:var(--fk-rhythm-2, .5rem)}.fk-page-header__title-row fk-headline{margin-block:0}.fk-page-header__description{display:block;margin-top:var(--fk-rhythm-2, .5rem);max-width:60ch;line-height:1.5}.fk-page-header__actions{display:flex;flex-direction:column;gap:var(--fk-rhythm-3, .75rem)}@container (min-width: 40rem){.fk-page-header__bar{flex-direction:row;align-items:flex-start;justify-content:space-between}.fk-page-header__actions{flex-direction:row;flex-shrink:0;align-items:center}}\n"], dependencies: [{ kind: "component", type: HeadlineComponent, selector: "fk-headline", inputs: ["ariaLabel", "className", "fontSize", "id", "level", "variant", "visuallyHidden"] }, { kind: "component", type: TextComponent, selector: "fk-text", inputs: ["as", "variant", "tone", "align", "weight", "truncate", "maxLines", "gutterBottom", "italic", "visuallyHidden", "className", "id", "ariaLabel", "ariaDescribedBy", "role", "htmlFor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
55
70
|
}
|
|
56
71
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: PageHeaderComponent, decorators: [{
|
|
57
72
|
type: Component,
|
|
58
|
-
args: [{ selector: 'fk-page-header', standalone: true, imports: [HeadlineComponent, TextComponent], encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"fk-page-
|
|
59
|
-
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], headingLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingLevel", required: false }] }] } }
|
|
73
|
+
args: [{ selector: 'fk-page-header', standalone: true, imports: [HeadlineComponent, TextComponent], encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"fk-page-header__bar\" [attr.aria-label]=\"ariaLabel()\">\n <div class=\"fk-page-header__text\">\n <div class=\"fk-page-header__title-row\">\n <ng-content select=\"[pageHeaderLeading]\" />\n\n <fk-headline [level]=\"headingLevel()\">{{ title() }}</fk-headline>\n\n <ng-content select=\"[pageHeaderTrailing]\" />\n </div>\n\n @if (description()) {\n <fk-text class=\"fk-page-header__description\" tone=\"muted\">{{\n description()\n }}</fk-text>\n }\n </div>\n\n <div class=\"fk-page-header__actions\">\n <ng-content select=\"[pageHeaderActions]\" />\n </div>\n</header>\n", styles: [":host{display:block;container-type:inline-size}.fk-page-header__bar{display:flex;flex-direction:column;gap:var(--fk-rhythm-4, 1rem)}.fk-page-header__text{min-width:0}.fk-page-header__title-row{display:flex;align-items:center;gap:var(--fk-rhythm-2, .5rem)}.fk-page-header__title-row fk-headline{margin-block:0}.fk-page-header__description{display:block;margin-top:var(--fk-rhythm-2, .5rem);max-width:60ch;line-height:1.5}.fk-page-header__actions{display:flex;flex-direction:column;gap:var(--fk-rhythm-3, .75rem)}@container (min-width: 40rem){.fk-page-header__bar{flex-direction:row;align-items:flex-start;justify-content:space-between}.fk-page-header__actions{flex-direction:row;flex-shrink:0;align-items:center}}\n"] }]
|
|
74
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], headingLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingLevel", 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: [{
|
|
75
|
+
type: HostBinding,
|
|
76
|
+
args: ['class']
|
|
77
|
+
}], hostId: [{
|
|
78
|
+
type: HostBinding,
|
|
79
|
+
args: ['attr.id']
|
|
80
|
+
}] } });
|
|
60
81
|
|
|
61
82
|
/**
|
|
62
83
|
* Empty-state panel for dashboard tables and lists: a centered icon, a title,
|
|
@@ -125,18 +146,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
125
146
|
* A standalone layout primitive for custom dashboard rows.
|
|
126
147
|
*/
|
|
127
148
|
class ContentSplitLayoutComponent {
|
|
149
|
+
// ===== INPUTS =====
|
|
128
150
|
endWidth = input(null, ...(ngDevMode ? [{ debugName: "endWidth" }] : /* istanbul ignore next */ []));
|
|
129
151
|
gap = input('var(--fk-rhythm-4, 1rem)', ...(ngDevMode ? [{ debugName: "gap" }] : /* istanbul ignore next */ []));
|
|
130
|
-
|
|
152
|
+
// ===== BASE PROPS =====
|
|
153
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
154
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
155
|
+
// ===== COMPUTED =====
|
|
156
|
+
classes = computed(() => ['fk-content-split-layout', this.className()].filter(Boolean).join(' '), ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
157
|
+
get hostClass() {
|
|
158
|
+
return this.classes();
|
|
159
|
+
}
|
|
160
|
+
get hostId() {
|
|
161
|
+
return this.id();
|
|
162
|
+
}
|
|
131
163
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContentSplitLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
132
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: ContentSplitLayoutComponent, isStandalone: true, selector: "fk-content-split-layout", inputs: { endWidth: { classPropertyName: "endWidth", publicName: "endWidth", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClass" } }, ngImport: i0, template: "<div\n class=\"fk-content-split-layout__row\"\n [style.--fk-content-split-gap]=\"gap()\"\n>\n <div class=\"fk-content-split-layout__start\">\n <ng-content select=\"[start]\" />\n </div>\n\n <div\n class=\"fk-content-split-layout__end\"\n [class.fk-content-split-layout__end--fixed]=\"endWidth()\"\n [style.--fk-content-split-end-width]=\"endWidth()\"\n >\n <ng-content select=\"[end]\" />\n </div>\n</div>\n", styles: [":host{display:block;container-type:inline-size}.fk-content-split-layout__row{display:flex;flex-direction:column;gap:var(--fk-content-split-gap, var(--fk-rhythm-4, 1rem))}@container (min-width: 700px){.fk-content-split-layout__row{flex-direction:row;align-items:flex-start}}.fk-content-split-layout__start{display:flex;flex-direction:column;padding-top:var(--fk-rhythm-4, 1rem);width:100%}.fk-content-split-layout__start>*+*{margin-top:var(--fk-content-split-gap, var(--fk-rhythm-4, 1rem))}@container (min-width: 700px){.fk-content-split-layout__start{flex:1;min-width:0}}.fk-content-split-layout__end{width:100%}@container (min-width: 700px){.fk-content-split-layout__end{flex:0 0 auto}}@container (min-width: 700px){.fk-content-split-layout__end--fixed{flex:0 0 var(--fk-content-split-end-width)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
164
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: ContentSplitLayoutComponent, isStandalone: true, selector: "fk-content-split-layout", inputs: { endWidth: { classPropertyName: "endWidth", publicName: "endWidth", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", 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 } }, host: { properties: { "class": "this.hostClass", "attr.id": "this.hostId" } }, ngImport: i0, template: "<div\n class=\"fk-content-split-layout__row\"\n [style.--fk-content-split-gap]=\"gap()\"\n>\n <div class=\"fk-content-split-layout__start\">\n <ng-content select=\"[start]\" />\n </div>\n\n <div\n class=\"fk-content-split-layout__end\"\n [class.fk-content-split-layout__end--fixed]=\"endWidth()\"\n [style.--fk-content-split-end-width]=\"endWidth()\"\n >\n <ng-content select=\"[end]\" />\n </div>\n</div>\n", styles: [":host{display:block;container-type:inline-size}.fk-content-split-layout__row{display:flex;flex-direction:column;gap:var(--fk-content-split-gap, var(--fk-rhythm-4, 1rem))}@container (min-width: 700px){.fk-content-split-layout__row{flex-direction:row;align-items:flex-start}}.fk-content-split-layout__start{display:flex;flex-direction:column;padding-top:var(--fk-rhythm-4, 1rem);width:100%}.fk-content-split-layout__start>*+*{margin-top:var(--fk-content-split-gap, var(--fk-rhythm-4, 1rem))}@container (min-width: 700px){.fk-content-split-layout__start{flex:1;min-width:0}}.fk-content-split-layout__end{width:100%}@container (min-width: 700px){.fk-content-split-layout__end{flex:0 0 auto}}@container (min-width: 700px){.fk-content-split-layout__end--fixed{flex:0 0 var(--fk-content-split-end-width)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
133
165
|
}
|
|
134
166
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContentSplitLayoutComponent, decorators: [{
|
|
135
167
|
type: Component,
|
|
136
168
|
args: [{ selector: 'fk-content-split-layout', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"fk-content-split-layout__row\"\n [style.--fk-content-split-gap]=\"gap()\"\n>\n <div class=\"fk-content-split-layout__start\">\n <ng-content select=\"[start]\" />\n </div>\n\n <div\n class=\"fk-content-split-layout__end\"\n [class.fk-content-split-layout__end--fixed]=\"endWidth()\"\n [style.--fk-content-split-end-width]=\"endWidth()\"\n >\n <ng-content select=\"[end]\" />\n </div>\n</div>\n", styles: [":host{display:block;container-type:inline-size}.fk-content-split-layout__row{display:flex;flex-direction:column;gap:var(--fk-content-split-gap, var(--fk-rhythm-4, 1rem))}@container (min-width: 700px){.fk-content-split-layout__row{flex-direction:row;align-items:flex-start}}.fk-content-split-layout__start{display:flex;flex-direction:column;padding-top:var(--fk-rhythm-4, 1rem);width:100%}.fk-content-split-layout__start>*+*{margin-top:var(--fk-content-split-gap, var(--fk-rhythm-4, 1rem))}@container (min-width: 700px){.fk-content-split-layout__start{flex:1;min-width:0}}.fk-content-split-layout__end{width:100%}@container (min-width: 700px){.fk-content-split-layout__end{flex:0 0 auto}}@container (min-width: 700px){.fk-content-split-layout__end--fixed{flex:0 0 var(--fk-content-split-end-width)}}\n"] }]
|
|
137
|
-
}], propDecorators: { endWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "endWidth", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], hostClass: [{
|
|
169
|
+
}], propDecorators: { endWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "endWidth", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], hostClass: [{
|
|
138
170
|
type: HostBinding,
|
|
139
171
|
args: ['class']
|
|
172
|
+
}], hostId: [{
|
|
173
|
+
type: HostBinding,
|
|
174
|
+
args: ['attr.id']
|
|
140
175
|
}] } });
|
|
141
176
|
|
|
142
177
|
/**
|
|
@@ -924,9 +959,593 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
924
959
|
args: ['attr.id']
|
|
925
960
|
}] } });
|
|
926
961
|
|
|
962
|
+
const VIEWPORT_MARGIN = 24;
|
|
963
|
+
/**
|
|
964
|
+
* A floating, draggable onboarding-progress widget. It presents a checklist of
|
|
965
|
+
* steps with a progress bar, collapses to a compact pill with a progress ring,
|
|
966
|
+
* and can be dragged anywhere on screen (CDK drag). It renders over the app in
|
|
967
|
+
* a fixed layer — drop it once near the app root.
|
|
968
|
+
*
|
|
969
|
+
* **Controlled model, no domain data.** The `steps` model is a required,
|
|
970
|
+
* reactive input: the widget is a pure view of it and emits events when the
|
|
971
|
+
* user acts (`stepAction`, `stepMarkDone`, `substepToggle`, `goLive`). The
|
|
972
|
+
* consumer owns the step state — so if it is keyed by, say, the active account
|
|
973
|
+
* or environment, swapping the input re-renders the widget instantly. The
|
|
974
|
+
* widget never persists step state.
|
|
975
|
+
*
|
|
976
|
+
* **Presentation state is internal + persisted.** Collapsed and drag position
|
|
977
|
+
* live in the widget and persist to `localStorage` under `storageKey` — these
|
|
978
|
+
* are UI preferences, not part of the model.
|
|
979
|
+
*
|
|
980
|
+
* **Opinionated but themeable.** It ships a house look out of the box; all
|
|
981
|
+
* colour flows through `--fk-onboarding-guide-*` tokens, so overriding those
|
|
982
|
+
* (e.g. pointing them at a brand scale) retints it without touching the markup.
|
|
983
|
+
*
|
|
984
|
+
* ```html
|
|
985
|
+
* <fk-onboarding-guide
|
|
986
|
+
* [steps]="steps()"
|
|
987
|
+
* title="Setup guide"
|
|
988
|
+
* (stepAction)="onStart($event)"
|
|
989
|
+
* (substepToggle)="onToggle($event)"
|
|
990
|
+
* (goLive)="onGoLive()"
|
|
991
|
+
* (dismiss)="onDismiss()"
|
|
992
|
+
* />
|
|
993
|
+
* ```
|
|
994
|
+
*/
|
|
995
|
+
class OnboardingGuideComponent {
|
|
996
|
+
host = inject(ElementRef);
|
|
997
|
+
drag = inject(CdkDrag);
|
|
998
|
+
destroyRef = inject(DestroyRef);
|
|
999
|
+
// ===== INPUTS =====
|
|
1000
|
+
/** The step model. Controlled by the consumer; the widget is a view of it. */
|
|
1001
|
+
steps = input.required(...(ngDevMode ? [{ debugName: "steps" }] : /* istanbul ignore next */ []));
|
|
1002
|
+
/** Widget title. */
|
|
1003
|
+
title = input('Setup guide', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
1004
|
+
/** `localStorage` key for the collapsed + drag-position preferences. */
|
|
1005
|
+
storageKey = input('fk-onboarding-guide', ...(ngDevMode ? [{ debugName: "storageKey" }] : /* istanbul ignore next */ []));
|
|
1006
|
+
/** Initial collapsed state, used only when nothing is persisted yet. */
|
|
1007
|
+
startCollapsed = input(false, ...(ngDevMode ? [{ debugName: "startCollapsed" }] : /* istanbul ignore next */ []));
|
|
1008
|
+
// --- Text (English defaults; pass translated strings as needed) ---
|
|
1009
|
+
/** Default CTA label when a step doesn't supply its own `actionLabel`. */
|
|
1010
|
+
startLabel = input('Start', ...(ngDevMode ? [{ debugName: "startLabel" }] : /* istanbul ignore next */ []));
|
|
1011
|
+
/** Secondary "mark this step done" action label. */
|
|
1012
|
+
markDoneLabel = input('Mark done', ...(ngDevMode ? [{ debugName: "markDoneLabel" }] : /* istanbul ignore next */ []));
|
|
1013
|
+
/** Footer / final go-live action label. */
|
|
1014
|
+
goLiveLabel = input('Go live', ...(ngDevMode ? [{ debugName: "goLiveLabel" }] : /* istanbul ignore next */ []));
|
|
1015
|
+
/** Footer noun for the "{done} of {total} {stepsWord} {doneWord}" summary. */
|
|
1016
|
+
stepsWord = input('steps', ...(ngDevMode ? [{ debugName: "stepsWord" }] : /* istanbul ignore next */ []));
|
|
1017
|
+
/** Footer verb for the summary. */
|
|
1018
|
+
doneWord = input('done', ...(ngDevMode ? [{ debugName: "doneWord" }] : /* istanbul ignore next */ []));
|
|
1019
|
+
/** Collapsed-pill suffix, e.g. "3 steps left". */
|
|
1020
|
+
stepsLeftWord = input('left', ...(ngDevMode ? [{ debugName: "stepsLeftWord" }] : /* istanbul ignore next */ []));
|
|
1021
|
+
/** Collapsed-pill copy shown when everything is complete. */
|
|
1022
|
+
allDoneLabel = input('All set', ...(ngDevMode ? [{ debugName: "allDoneLabel" }] : /* istanbul ignore next */ []));
|
|
1023
|
+
/** ARIA labels for the icon-only header controls. */
|
|
1024
|
+
renameLabel = input('Rename', ...(ngDevMode ? [{ debugName: "renameLabel" }] : /* istanbul ignore next */ []));
|
|
1025
|
+
collapseLabel = input('Collapse', ...(ngDevMode ? [{ debugName: "collapseLabel" }] : /* istanbul ignore next */ []));
|
|
1026
|
+
dismissLabel = input('Dismiss', ...(ngDevMode ? [{ debugName: "dismissLabel" }] : /* istanbul ignore next */ []));
|
|
1027
|
+
expandLabel = input('Expand', ...(ngDevMode ? [{ debugName: "expandLabel" }] : /* istanbul ignore next */ []));
|
|
1028
|
+
// --- Icon glyph names (resolved by the app's icon registry) ---
|
|
1029
|
+
checkIcon = input('check', ...(ngDevMode ? [{ debugName: "checkIcon" }] : /* istanbul ignore next */ []));
|
|
1030
|
+
caretIcon = input('chevron-down', ...(ngDevMode ? [{ debugName: "caretIcon" }] : /* istanbul ignore next */ []));
|
|
1031
|
+
editIcon = input('pen', ...(ngDevMode ? [{ debugName: "editIcon" }] : /* istanbul ignore next */ []));
|
|
1032
|
+
collapseIcon = input('collapse', ...(ngDevMode ? [{ debugName: "collapseIcon" }] : /* istanbul ignore next */ []));
|
|
1033
|
+
dismissIcon = input('close', ...(ngDevMode ? [{ debugName: "dismissIcon" }] : /* istanbul ignore next */ []));
|
|
1034
|
+
expandIcon = input('expand', ...(ngDevMode ? [{ debugName: "expandIcon" }] : /* istanbul ignore next */ []));
|
|
1035
|
+
actionIcon = input('arrow-right', ...(ngDevMode ? [{ debugName: "actionIcon" }] : /* istanbul ignore next */ []));
|
|
1036
|
+
// ===== OUTPUTS =====
|
|
1037
|
+
/** A step's primary CTA was clicked. Emits the step id. */
|
|
1038
|
+
stepAction = output();
|
|
1039
|
+
/** A step's "mark done" was clicked. Emits the step id. */
|
|
1040
|
+
stepMarkDone = output();
|
|
1041
|
+
/** A substep checkbox was toggled. */
|
|
1042
|
+
substepToggle = output();
|
|
1043
|
+
/** The final go-live action was invoked (footer or the go-live step CTA). */
|
|
1044
|
+
goLive = output();
|
|
1045
|
+
/** The rename (edit) affordance was clicked; the consumer owns renaming. */
|
|
1046
|
+
renameClick = output();
|
|
1047
|
+
/** The dismiss control was clicked; the consumer decides whether to hide it. */
|
|
1048
|
+
dismiss = output();
|
|
1049
|
+
/** Fires when the collapsed state changes. */
|
|
1050
|
+
collapsedChange = output();
|
|
1051
|
+
// ===== BASE PROPS =====
|
|
1052
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
1053
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
1054
|
+
// ===== PRESENTATION STATE =====
|
|
1055
|
+
collapsed = signal(false, ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
|
|
1056
|
+
dragPosition = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "dragPosition" }] : /* istanbul ignore next */ []));
|
|
1057
|
+
/** True immediately after a real drag, so the drag-handle's click (e.g. the
|
|
1058
|
+
* pill's expand) is suppressed rather than firing at the drop point. */
|
|
1059
|
+
justDragged = false;
|
|
1060
|
+
/**
|
|
1061
|
+
* The expanded step. A `linkedSignal` over `steps` so that whenever the model
|
|
1062
|
+
* changes (e.g. the consumer swaps in another account/environment's steps) it
|
|
1063
|
+
* resets to the first incomplete step; user toggles override until the next
|
|
1064
|
+
* model change.
|
|
1065
|
+
*/
|
|
1066
|
+
openStepId = linkedSignal({ ...(ngDevMode ? { debugName: "openStepId" } : /* istanbul ignore next */ {}), source: this.steps,
|
|
1067
|
+
computation: (steps) => steps.find((s) => !this.isComplete(s))?.id ?? null });
|
|
1068
|
+
// ===== DERIVED =====
|
|
1069
|
+
total = computed(() => this.steps().length, ...(ngDevMode ? [{ debugName: "total" }] : /* istanbul ignore next */ []));
|
|
1070
|
+
doneCount = computed(() => this.steps().filter((s) => this.isComplete(s)).length, ...(ngDevMode ? [{ debugName: "doneCount" }] : /* istanbul ignore next */ []));
|
|
1071
|
+
percent = computed(() => {
|
|
1072
|
+
const total = this.total();
|
|
1073
|
+
return total === 0 ? 0 : Math.round((this.doneCount() / total) * 100);
|
|
1074
|
+
}, ...(ngDevMode ? [{ debugName: "percent" }] : /* istanbul ignore next */ []));
|
|
1075
|
+
stepsLeft = computed(() => this.total() - this.doneCount(), ...(ngDevMode ? [{ debugName: "stepsLeft" }] : /* istanbul ignore next */ []));
|
|
1076
|
+
complete = computed(() => this.total() > 0 && this.stepsLeft() === 0, ...(ngDevMode ? [{ debugName: "complete" }] : /* istanbul ignore next */ []));
|
|
1077
|
+
/** Circumference for the pill's progress ring (r = 16). */
|
|
1078
|
+
ringCircumference = 2 * Math.PI * 16;
|
|
1079
|
+
ringOffset = computed(() => {
|
|
1080
|
+
const total = this.total();
|
|
1081
|
+
const fraction = total === 0 ? 0 : this.doneCount() / total;
|
|
1082
|
+
return this.ringCircumference * (1 - fraction);
|
|
1083
|
+
}, ...(ngDevMode ? [{ debugName: "ringOffset" }] : /* istanbul ignore next */ []));
|
|
1084
|
+
classes = computed(() => [
|
|
1085
|
+
'fk-onboarding-guide',
|
|
1086
|
+
this.collapsed() ? 'fk-onboarding-guide--collapsed' : '',
|
|
1087
|
+
this.complete() ? 'fk-onboarding-guide--complete' : '',
|
|
1088
|
+
this.className(),
|
|
1089
|
+
]
|
|
1090
|
+
.filter(Boolean)
|
|
1091
|
+
.join(' '), ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
1092
|
+
get hostClass() {
|
|
1093
|
+
return this.classes();
|
|
1094
|
+
}
|
|
1095
|
+
get hostId() {
|
|
1096
|
+
return this.id();
|
|
1097
|
+
}
|
|
1098
|
+
constructor() {
|
|
1099
|
+
this.drag.ended
|
|
1100
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
1101
|
+
.subscribe((event) => this.onDragEnded(event));
|
|
1102
|
+
afterNextRender(() => this.hydrate());
|
|
1103
|
+
}
|
|
1104
|
+
// ===== COMPLETION LOGIC =====
|
|
1105
|
+
isComplete(step) {
|
|
1106
|
+
if (step.substeps && step.substeps.length > 0) {
|
|
1107
|
+
return step.substeps.every((sub) => sub.done);
|
|
1108
|
+
}
|
|
1109
|
+
return step.done;
|
|
1110
|
+
}
|
|
1111
|
+
isActive(step) {
|
|
1112
|
+
return !this.isComplete(step) && this.openStepId() === step.id;
|
|
1113
|
+
}
|
|
1114
|
+
actionLabelFor(step) {
|
|
1115
|
+
return step.actionLabel || this.startLabel();
|
|
1116
|
+
}
|
|
1117
|
+
// ===== INTERACTIONS =====
|
|
1118
|
+
toggleStep(stepId) {
|
|
1119
|
+
this.openStepId.update((cur) => (cur === stepId ? null : stepId));
|
|
1120
|
+
}
|
|
1121
|
+
onAction(step) {
|
|
1122
|
+
this.stepAction.emit(step.id);
|
|
1123
|
+
}
|
|
1124
|
+
onMarkDone(step) {
|
|
1125
|
+
this.stepMarkDone.emit(step.id);
|
|
1126
|
+
}
|
|
1127
|
+
onSubstep(step, substep) {
|
|
1128
|
+
this.substepToggle.emit({ stepId: step.id, substepId: substep.id });
|
|
1129
|
+
}
|
|
1130
|
+
onCollapse() {
|
|
1131
|
+
this.setCollapsed(true);
|
|
1132
|
+
}
|
|
1133
|
+
onExpand() {
|
|
1134
|
+
if (this.justDragged) {
|
|
1135
|
+
return;
|
|
1136
|
+
}
|
|
1137
|
+
this.setCollapsed(false);
|
|
1138
|
+
}
|
|
1139
|
+
onRename() {
|
|
1140
|
+
this.renameClick.emit();
|
|
1141
|
+
}
|
|
1142
|
+
onDismiss() {
|
|
1143
|
+
this.dismiss.emit();
|
|
1144
|
+
}
|
|
1145
|
+
onGoLive() {
|
|
1146
|
+
this.goLive.emit();
|
|
1147
|
+
}
|
|
1148
|
+
setCollapsed(value) {
|
|
1149
|
+
this.collapsed.set(value);
|
|
1150
|
+
this.collapsedChange.emit(value);
|
|
1151
|
+
this.persist();
|
|
1152
|
+
}
|
|
1153
|
+
// ===== DRAG =====
|
|
1154
|
+
onDragEnded(event) {
|
|
1155
|
+
const clamped = this.clamp(this.drag.getFreeDragPosition());
|
|
1156
|
+
this.dragPosition.set(clamped);
|
|
1157
|
+
this.drag.setFreeDragPosition(clamped);
|
|
1158
|
+
this.persist();
|
|
1159
|
+
const moved = Math.abs(event.distance.x) > 3 || Math.abs(event.distance.y) > 3;
|
|
1160
|
+
if (moved) {
|
|
1161
|
+
this.justDragged = true;
|
|
1162
|
+
setTimeout(() => (this.justDragged = false));
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
clamp(point) {
|
|
1166
|
+
if (typeof window === 'undefined') {
|
|
1167
|
+
return point;
|
|
1168
|
+
}
|
|
1169
|
+
const rect = this.host.nativeElement.getBoundingClientRect();
|
|
1170
|
+
const maxX = window.innerWidth - rect.width - VIEWPORT_MARGIN;
|
|
1171
|
+
const maxY = window.innerHeight - rect.height - VIEWPORT_MARGIN;
|
|
1172
|
+
return {
|
|
1173
|
+
x: Math.max(VIEWPORT_MARGIN, Math.min(point.x, maxX)),
|
|
1174
|
+
y: Math.max(VIEWPORT_MARGIN, Math.min(point.y, maxY)),
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1177
|
+
// ===== PERSISTENCE =====
|
|
1178
|
+
hydrate() {
|
|
1179
|
+
const saved = this.read();
|
|
1180
|
+
this.collapsed.set(saved.collapsed ?? this.startCollapsed());
|
|
1181
|
+
const pos = saved.pos ? this.clamp(saved.pos) : this.defaultBottomRight();
|
|
1182
|
+
this.dragPosition.set(pos);
|
|
1183
|
+
this.drag.setFreeDragPosition(pos);
|
|
1184
|
+
}
|
|
1185
|
+
defaultBottomRight() {
|
|
1186
|
+
if (typeof window === 'undefined') {
|
|
1187
|
+
return { x: 0, y: 0 };
|
|
1188
|
+
}
|
|
1189
|
+
const rect = this.host.nativeElement.getBoundingClientRect();
|
|
1190
|
+
return {
|
|
1191
|
+
x: Math.max(VIEWPORT_MARGIN, window.innerWidth - rect.width - VIEWPORT_MARGIN),
|
|
1192
|
+
y: Math.max(VIEWPORT_MARGIN, window.innerHeight - rect.height - VIEWPORT_MARGIN),
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1195
|
+
read() {
|
|
1196
|
+
const store = this.storage();
|
|
1197
|
+
if (!store) {
|
|
1198
|
+
return {};
|
|
1199
|
+
}
|
|
1200
|
+
try {
|
|
1201
|
+
return JSON.parse(store.getItem(this.storageKey()) || '{}');
|
|
1202
|
+
}
|
|
1203
|
+
catch {
|
|
1204
|
+
return {};
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
persist() {
|
|
1208
|
+
const store = this.storage();
|
|
1209
|
+
if (!store) {
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
const state = {
|
|
1213
|
+
collapsed: this.collapsed(),
|
|
1214
|
+
pos: this.dragPosition(),
|
|
1215
|
+
};
|
|
1216
|
+
try {
|
|
1217
|
+
store.setItem(this.storageKey(), JSON.stringify(state));
|
|
1218
|
+
}
|
|
1219
|
+
catch {
|
|
1220
|
+
// Storage unavailable (private mode / quota) — preferences just don't stick.
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
storage() {
|
|
1224
|
+
try {
|
|
1225
|
+
return typeof window === 'undefined' ? null : window.localStorage;
|
|
1226
|
+
}
|
|
1227
|
+
catch {
|
|
1228
|
+
return null;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OnboardingGuideComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1232
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: OnboardingGuideComponent, isStandalone: true, selector: "fk-onboarding-guide", inputs: { steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, storageKey: { classPropertyName: "storageKey", publicName: "storageKey", isSignal: true, isRequired: false, transformFunction: null }, startCollapsed: { classPropertyName: "startCollapsed", publicName: "startCollapsed", isSignal: true, isRequired: false, transformFunction: null }, startLabel: { classPropertyName: "startLabel", publicName: "startLabel", isSignal: true, isRequired: false, transformFunction: null }, markDoneLabel: { classPropertyName: "markDoneLabel", publicName: "markDoneLabel", isSignal: true, isRequired: false, transformFunction: null }, goLiveLabel: { classPropertyName: "goLiveLabel", publicName: "goLiveLabel", isSignal: true, isRequired: false, transformFunction: null }, stepsWord: { classPropertyName: "stepsWord", publicName: "stepsWord", isSignal: true, isRequired: false, transformFunction: null }, doneWord: { classPropertyName: "doneWord", publicName: "doneWord", isSignal: true, isRequired: false, transformFunction: null }, stepsLeftWord: { classPropertyName: "stepsLeftWord", publicName: "stepsLeftWord", isSignal: true, isRequired: false, transformFunction: null }, allDoneLabel: { classPropertyName: "allDoneLabel", publicName: "allDoneLabel", isSignal: true, isRequired: false, transformFunction: null }, renameLabel: { classPropertyName: "renameLabel", publicName: "renameLabel", isSignal: true, isRequired: false, transformFunction: null }, collapseLabel: { classPropertyName: "collapseLabel", publicName: "collapseLabel", isSignal: true, isRequired: false, transformFunction: null }, dismissLabel: { classPropertyName: "dismissLabel", publicName: "dismissLabel", isSignal: true, isRequired: false, transformFunction: null }, expandLabel: { classPropertyName: "expandLabel", publicName: "expandLabel", isSignal: true, isRequired: false, transformFunction: null }, checkIcon: { classPropertyName: "checkIcon", publicName: "checkIcon", isSignal: true, isRequired: false, transformFunction: null }, caretIcon: { classPropertyName: "caretIcon", publicName: "caretIcon", isSignal: true, isRequired: false, transformFunction: null }, editIcon: { classPropertyName: "editIcon", publicName: "editIcon", isSignal: true, isRequired: false, transformFunction: null }, collapseIcon: { classPropertyName: "collapseIcon", publicName: "collapseIcon", isSignal: true, isRequired: false, transformFunction: null }, dismissIcon: { classPropertyName: "dismissIcon", publicName: "dismissIcon", isSignal: true, isRequired: false, transformFunction: null }, expandIcon: { classPropertyName: "expandIcon", publicName: "expandIcon", isSignal: true, isRequired: false, transformFunction: null }, actionIcon: { classPropertyName: "actionIcon", publicName: "actionIcon", 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 } }, outputs: { stepAction: "stepAction", stepMarkDone: "stepMarkDone", substepToggle: "substepToggle", goLive: "goLive", renameClick: "renameClick", dismiss: "dismiss", collapsedChange: "collapsedChange" }, host: { properties: { "class": "this.hostClass", "attr.id": "this.hostId" } }, hostDirectives: [{ directive: i1.CdkDrag }], ngImport: i0, template: "<!-- ===================== EXPANDED CARD ===================== -->\n<div class=\"fk-onboarding-guide__card\">\n <div class=\"fk-onboarding-guide__head\">\n <div class=\"fk-onboarding-guide__head-top\">\n <span class=\"fk-onboarding-guide__grip\" cdkDragHandle aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"9\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n </svg>\n </span>\n\n <span class=\"fk-onboarding-guide__title\" cdkDragHandle>{{\n title()\n }}</span>\n\n <button\n type=\"button\"\n class=\"fk-onboarding-guide__icon-btn fk-onboarding-guide__edit\"\n [attr.aria-label]=\"renameLabel()\"\n (click)=\"onRename()\"\n >\n <fk-icon [name]=\"editIcon()\" size=\"sm\" />\n </button>\n\n <div class=\"fk-onboarding-guide__head-actions\">\n <button\n type=\"button\"\n class=\"fk-onboarding-guide__icon-btn\"\n [attr.aria-label]=\"collapseLabel()\"\n (click)=\"onCollapse()\"\n >\n <fk-icon [name]=\"collapseIcon()\" size=\"sm\" />\n </button>\n <button\n type=\"button\"\n class=\"fk-onboarding-guide__icon-btn\"\n [attr.aria-label]=\"dismissLabel()\"\n (click)=\"onDismiss()\"\n >\n <fk-icon [name]=\"dismissIcon()\" size=\"sm\" />\n </button>\n </div>\n </div>\n\n <div class=\"fk-onboarding-guide__progress\">\n <div\n class=\"fk-onboarding-guide__track\"\n role=\"progressbar\"\n [attr.aria-valuenow]=\"percent()\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n >\n <div\n class=\"fk-onboarding-guide__fill\"\n [style.width.%]=\"percent()\"\n ></div>\n </div>\n <span class=\"fk-onboarding-guide__pct\">{{ percent() }}%</span>\n </div>\n </div>\n\n <div class=\"fk-onboarding-guide__steps\" role=\"list\">\n @for (step of steps(); track step.id) {\n @let done = isComplete(step);\n @let open = openStepId() === step.id;\n @let active = isActive(step);\n\n <div\n class=\"fk-onboarding-guide__step\"\n role=\"listitem\"\n [class.fk-onboarding-guide__step--done]=\"done\"\n [class.fk-onboarding-guide__step--open]=\"open\"\n >\n <button\n type=\"button\"\n class=\"fk-onboarding-guide__step-row\"\n [attr.aria-expanded]=\"open\"\n (click)=\"toggleStep(step.id)\"\n >\n <span\n class=\"fk-onboarding-guide__check\"\n [class.fk-onboarding-guide__check--done]=\"done\"\n [class.fk-onboarding-guide__check--active]=\"active\"\n [class.fk-onboarding-guide__check--todo]=\"!done && !active\"\n aria-hidden=\"true\"\n >\n @if (done) {\n <fk-icon [name]=\"checkIcon()\" size=\"xs\" />\n } @else if (active) {\n <i class=\"fk-onboarding-guide__dot\"></i>\n }\n </span>\n\n <span class=\"fk-onboarding-guide__step-label\">{{ step.label }}</span>\n\n <span class=\"fk-onboarding-guide__caret\" aria-hidden=\"true\">\n <fk-icon [name]=\"caretIcon()\" size=\"sm\" />\n </span>\n </button>\n\n @if (open) {\n <div class=\"fk-onboarding-guide__step-body\">\n @if (step.substeps && step.substeps.length > 0) {\n @for (sub of step.substeps; track sub.id) {\n <button\n type=\"button\"\n class=\"fk-onboarding-guide__sub\"\n [class.fk-onboarding-guide__sub--done]=\"sub.done\"\n (click)=\"onSubstep(step, sub)\"\n >\n <span\n class=\"fk-onboarding-guide__sub-check\"\n aria-hidden=\"true\"\n >\n @if (sub.done) {\n <fk-icon [name]=\"checkIcon()\" size=\"xs\" />\n }\n </span>\n <span class=\"fk-onboarding-guide__sub-label\">{{\n sub.label\n }}</span>\n </button>\n }\n } @else {\n @if (step.description) {\n <p class=\"fk-onboarding-guide__desc\">{{ step.description }}</p>\n }\n\n @if (!done) {\n <div class=\"fk-onboarding-guide__actions\">\n <fk-button\n variant=\"primary\"\n size=\"sm\"\n (click)=\"onAction(step)\"\n >\n {{ actionLabelFor(step) }}\n <fk-icon fkButtonIconEnd [name]=\"actionIcon()\" size=\"xs\" />\n </fk-button>\n <button\n type=\"button\"\n class=\"fk-onboarding-guide__skip\"\n (click)=\"onMarkDone(step)\"\n >\n {{ markDoneLabel() }}\n </button>\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"fk-onboarding-guide__foot\">\n <span class=\"fk-onboarding-guide__foot-text\">\n <b>{{ doneCount() }}</b> / {{ total() }} {{ stepsWord() }}\n {{ doneWord() }}\n </span>\n <button type=\"button\" class=\"fk-onboarding-guide__go\" (click)=\"onGoLive()\">\n {{ goLiveLabel() }}\n <fk-icon [name]=\"actionIcon()\" size=\"xs\" />\n </button>\n </div>\n</div>\n\n<!-- ===================== COLLAPSED PILL ===================== -->\n<button\n type=\"button\"\n class=\"fk-onboarding-guide__pill\"\n cdkDragHandle\n [attr.aria-label]=\"expandLabel()\"\n (click)=\"onExpand()\"\n>\n <span class=\"fk-onboarding-guide__ring\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 38 38\">\n <circle class=\"fk-onboarding-guide__ring-track\" cx=\"19\" cy=\"19\" r=\"16\" />\n <circle\n class=\"fk-onboarding-guide__ring-prog\"\n cx=\"19\"\n cy=\"19\"\n r=\"16\"\n [style.stroke-dasharray]=\"ringCircumference\"\n [style.stroke-dashoffset]=\"ringOffset()\"\n />\n </svg>\n <span class=\"fk-onboarding-guide__ring-num\">{{ percent() }}%</span>\n </span>\n\n <span class=\"fk-onboarding-guide__pill-meta\">\n <span class=\"fk-onboarding-guide__pill-title\">{{ title() }}</span>\n <span class=\"fk-onboarding-guide__pill-sub\">\n @if (complete()) {\n {{ allDoneLabel() }}\n } @else {\n <b>{{ stepsLeft() }}</b> {{ stepsWord() }} {{ stepsLeftWord() }}\n }\n </span>\n </span>\n\n <span class=\"fk-onboarding-guide__pill-expand\" aria-hidden=\"true\">\n <fk-icon [name]=\"expandIcon()\" size=\"sm\" />\n </span>\n</button>\n", styles: ["@keyframes fk-onboarding-guide-pop{0%{opacity:0;transform:translateY(8px) scale(.97)}to{opacity:1;transform:none}}:host{position:fixed;top:0;left:0;z-index:var(--fk-onboarding-guide-z, 60);font-family:var(--fk-onboarding-guide-font-body, var(--fk-font-family-body, system-ui, sans-serif));color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b));touch-action:none}.fk-onboarding-guide__card,.fk-onboarding-guide__pill{--fk-button-primary-bg: var( --fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a) );--fk-button-primary-bg-hover: color-mix( in srgb, var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a)) 88%, #000 );--fk-button-primary-color: var( --fk-onboarding-guide-accent-contrast, var(--fk-color-surface, #fff) )}.fk-onboarding-guide__card{width:var(--fk-onboarding-guide-width, 360px);max-width:calc(100vw - 2 * var(--fk-rhythm-4, 1rem));background:var(--fk-onboarding-guide-surface, var(--fk-color-surface, #fff));border:1px solid var(--fk-onboarding-guide-border, var(--fk-color-border, #e2e8f0));border-radius:var(--fk-onboarding-guide-radius, var(--fk-radius-lg, 16px));box-shadow:var(--fk-onboarding-guide-shadow, 0 24px 54px -18px rgba(15, 23, 42, .28));overflow:hidden;transform-origin:bottom right;animation:fk-onboarding-guide-pop .24s cubic-bezier(.2,.9,.3,1.1)}.fk-onboarding-guide__head{padding:16px 18px 14px}.fk-onboarding-guide__head-top{display:flex;align-items:center;gap:9px}.fk-onboarding-guide__grip,.fk-onboarding-guide__title{cursor:grab}.fk-onboarding-guide__grip:active,.fk-onboarding-guide__title:active{cursor:grabbing}.fk-onboarding-guide__grip{display:inline-flex;flex:none;margin-left:-3px;color:var(--fk-onboarding-guide-text-faint, var(--fk-color-muted, #94a3b8))}.fk-onboarding-guide__grip svg{width:15px;height:15px}.fk-onboarding-guide__title{font-family:var(--fk-onboarding-guide-font-display, var(--fk-font-family-display, inherit));font-size:16px;font-weight:700;color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b))}.fk-onboarding-guide__head-actions{margin-left:auto;display:flex;gap:4px}.fk-onboarding-guide__icon-btn{display:grid;place-items:center;width:28px;height:28px;border:1px solid transparent;border-radius:7px;background:none;color:var(--fk-onboarding-guide-text-faint, var(--fk-color-muted, #94a3b8));cursor:pointer;transition:.14s}.fk-onboarding-guide__icon-btn:hover{background:var(--fk-onboarding-guide-surface-muted, var(--fk-color-surface-muted, #f8fafc));border-color:var(--fk-onboarding-guide-border, var(--fk-color-border, #e2e8f0));color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b))}.fk-onboarding-guide__edit{width:24px;height:24px;border-radius:6px}.fk-onboarding-guide__progress{display:flex;align-items:center;gap:11px;margin-top:13px}.fk-onboarding-guide__track{flex:1;height:7px;border-radius:5px;background:var(--fk-onboarding-guide-surface-muted, var(--fk-color-surface-muted, #f1f5f9));overflow:hidden}.fk-onboarding-guide__fill{height:100%;border-radius:5px;background:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a));transition:width .5s cubic-bezier(.4,0,.2,1)}.fk-onboarding-guide__pct{flex:none;font-family:var(--fk-onboarding-guide-font-mono, var(--fk-font-family-mono, ui-monospace, monospace));font-size:11px;font-weight:600;color:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a))}.fk-onboarding-guide__steps{padding:6px 8px 10px;max-height:400px;overflow-y:auto}.fk-onboarding-guide__step{border-radius:12px;overflow:hidden}.fk-onboarding-guide__step--open{background:var(--fk-onboarding-guide-surface-muted, var(--fk-color-surface-muted, #f8fafc))}.fk-onboarding-guide__step-row{display:flex;align-items:center;gap:12px;width:100%;padding:13px 12px;border:none;border-radius:12px;background:none;text-align:left;cursor:pointer;transition:.14s}.fk-onboarding-guide__step-row:hover{background:var(--fk-onboarding-guide-surface-muted, var(--fk-color-surface-muted, #f8fafc))}.fk-onboarding-guide__step--open .fk-onboarding-guide__step-row:hover{background:transparent}.fk-onboarding-guide__check{display:grid;place-items:center;flex:none;width:20px;height:20px;border-radius:50%;transition:.16s;color:var(--fk-onboarding-guide-accent-contrast, #fff)}.fk-onboarding-guide__check--done{background:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a))}.fk-onboarding-guide__check--todo{border:2px solid color-mix(in srgb,var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b)) 45%,transparent)}.fk-onboarding-guide__check--active{border:2px solid var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a));background:color-mix(in srgb,var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a)) 10%,transparent)}.fk-onboarding-guide__dot{width:7px;height:7px;border-radius:50%;background:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a))}.fk-onboarding-guide__step-label{flex:1;min-width:0;font-size:14.5px;font-weight:600;color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b))}.fk-onboarding-guide__step--done .fk-onboarding-guide__step-label{color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b));font-weight:500;text-decoration:line-through;text-decoration-color:color-mix(in srgb,var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b)) 55%,transparent)}.fk-onboarding-guide__caret{display:grid;place-items:center;flex:none;color:var(--fk-onboarding-guide-text-faint, var(--fk-color-muted, #b6bfce));transition:transform .18s}.fk-onboarding-guide__step--open .fk-onboarding-guide__caret{transform:rotate(180deg);color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b))}.fk-onboarding-guide__step-body{padding:0 14px 14px 44px}.fk-onboarding-guide__desc{font-size:13px;line-height:1.55;color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b));margin-bottom:12px}.fk-onboarding-guide__actions{display:flex;align-items:center;gap:8px}.fk-onboarding-guide__skip{font-size:13px;font-weight:600;color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b));background:none;border:none;padding:6px;cursor:pointer}.fk-onboarding-guide__skip:hover{color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b))}.fk-onboarding-guide__sub{display:flex;align-items:center;gap:11px;width:100%;padding:8px 0;border:none;background:none;text-align:left;cursor:pointer}.fk-onboarding-guide__sub-check{display:grid;place-items:center;flex:none;width:18px;height:18px;border-radius:50%;color:var(--fk-onboarding-guide-accent-contrast, #fff);background:color-mix(in srgb,var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b)) 22%,transparent)}.fk-onboarding-guide__sub--done .fk-onboarding-guide__sub-check{background:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a))}.fk-onboarding-guide__sub-label{font-size:14px;color:var(--fk-onboarding-guide-text, var(--fk-color-text, #36405a))}.fk-onboarding-guide__sub--done .fk-onboarding-guide__sub-label{color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b))}.fk-onboarding-guide__foot{display:flex;align-items:center;gap:10px;padding:12px 18px 16px;border-top:1px solid var(--fk-onboarding-guide-divider, var(--fk-color-surface-dim, #f1f5f9))}.fk-onboarding-guide__foot-text{font-size:12.5px;color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b))}.fk-onboarding-guide__foot-text b{color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b));font-weight:600}.fk-onboarding-guide__go{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;background:none;border:none;cursor:pointer;color:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a))}.fk-onboarding-guide__pill{display:none;align-items:center;gap:12px;padding:9px 15px 9px 10px;border:1px solid var(--fk-onboarding-guide-border, var(--fk-color-border, #e2e8f0));border-radius:999px;background:var(--fk-onboarding-guide-surface, var(--fk-color-surface, #fff));box-shadow:var(--fk-onboarding-guide-shadow, 0 24px 54px -18px rgba(15, 23, 42, .28));cursor:grab;animation:fk-onboarding-guide-pop .22s cubic-bezier(.2,.9,.3,1.1)}.fk-onboarding-guide__pill:active{cursor:grabbing}.fk-onboarding-guide__ring{position:relative;width:38px;height:38px;flex:none}.fk-onboarding-guide__ring svg{width:38px;height:38px;transform:rotate(-90deg)}.fk-onboarding-guide__ring-track{fill:none;stroke:var(--fk-onboarding-guide-surface-muted, var(--fk-color-surface-muted, #f1f5f9));stroke-width:4}.fk-onboarding-guide__ring-prog{fill:none;stroke:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a));stroke-width:4;stroke-linecap:round;transition:stroke-dashoffset .5s cubic-bezier(.4,0,.2,1)}.fk-onboarding-guide__ring-num{position:absolute;inset:0;display:grid;place-items:center;font-family:var(--fk-onboarding-guide-font-mono, var(--fk-font-family-mono, ui-monospace, monospace));font-size:10.5px;font-weight:600;color:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a))}.fk-onboarding-guide__pill-meta{display:flex;flex-direction:column;line-height:1.2;text-align:left}.fk-onboarding-guide__pill-title{font-family:var(--fk-onboarding-guide-font-display, var(--fk-font-family-display, inherit));font-size:13.5px;font-weight:700;white-space:nowrap;color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b))}.fk-onboarding-guide__pill-sub{margin-top:2px;font-size:11.5px;white-space:nowrap;color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b))}.fk-onboarding-guide__pill-sub b{color:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a));font-weight:600}.fk-onboarding-guide__pill-expand{display:grid;place-items:center;width:28px;height:28px;flex:none;margin-left:2px;border-radius:50%;background:var(--fk-onboarding-guide-surface-muted, var(--fk-color-surface-muted, #f8fafc));color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b))}.fk-onboarding-guide--complete .fk-onboarding-guide__ring-prog{stroke:var(--fk-onboarding-guide-complete, var(--fk-color-success, #16a34a))}.fk-onboarding-guide--complete .fk-onboarding-guide__ring-num{color:var(--fk-onboarding-guide-complete, var(--fk-color-success, #16a34a))}:host(.fk-onboarding-guide--collapsed) .fk-onboarding-guide__card{display:none}:host(.fk-onboarding-guide--collapsed) .fk-onboarding-guide__pill{display:flex}\n"], dependencies: [{ kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: ButtonComponent, selector: "fk-button", inputs: ["variant", "size", "loading", "disabled", "type", "fullWidth", "id", "className", "ariaLabel", "ariaDescribedBy"] }, { kind: "component", type: IconComponent, selector: "fk-icon", inputs: ["name", "size", "color", "className", "id", "ariaLabel", "ariaHidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1233
|
+
}
|
|
1234
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OnboardingGuideComponent, decorators: [{
|
|
1235
|
+
type: Component,
|
|
1236
|
+
args: [{ selector: 'fk-onboarding-guide', standalone: true, imports: [CdkDragHandle, ButtonComponent, IconComponent], hostDirectives: [CdkDrag], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- ===================== EXPANDED CARD ===================== -->\n<div class=\"fk-onboarding-guide__card\">\n <div class=\"fk-onboarding-guide__head\">\n <div class=\"fk-onboarding-guide__head-top\">\n <span class=\"fk-onboarding-guide__grip\" cdkDragHandle aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"9\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" />\n </svg>\n </span>\n\n <span class=\"fk-onboarding-guide__title\" cdkDragHandle>{{\n title()\n }}</span>\n\n <button\n type=\"button\"\n class=\"fk-onboarding-guide__icon-btn fk-onboarding-guide__edit\"\n [attr.aria-label]=\"renameLabel()\"\n (click)=\"onRename()\"\n >\n <fk-icon [name]=\"editIcon()\" size=\"sm\" />\n </button>\n\n <div class=\"fk-onboarding-guide__head-actions\">\n <button\n type=\"button\"\n class=\"fk-onboarding-guide__icon-btn\"\n [attr.aria-label]=\"collapseLabel()\"\n (click)=\"onCollapse()\"\n >\n <fk-icon [name]=\"collapseIcon()\" size=\"sm\" />\n </button>\n <button\n type=\"button\"\n class=\"fk-onboarding-guide__icon-btn\"\n [attr.aria-label]=\"dismissLabel()\"\n (click)=\"onDismiss()\"\n >\n <fk-icon [name]=\"dismissIcon()\" size=\"sm\" />\n </button>\n </div>\n </div>\n\n <div class=\"fk-onboarding-guide__progress\">\n <div\n class=\"fk-onboarding-guide__track\"\n role=\"progressbar\"\n [attr.aria-valuenow]=\"percent()\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n >\n <div\n class=\"fk-onboarding-guide__fill\"\n [style.width.%]=\"percent()\"\n ></div>\n </div>\n <span class=\"fk-onboarding-guide__pct\">{{ percent() }}%</span>\n </div>\n </div>\n\n <div class=\"fk-onboarding-guide__steps\" role=\"list\">\n @for (step of steps(); track step.id) {\n @let done = isComplete(step);\n @let open = openStepId() === step.id;\n @let active = isActive(step);\n\n <div\n class=\"fk-onboarding-guide__step\"\n role=\"listitem\"\n [class.fk-onboarding-guide__step--done]=\"done\"\n [class.fk-onboarding-guide__step--open]=\"open\"\n >\n <button\n type=\"button\"\n class=\"fk-onboarding-guide__step-row\"\n [attr.aria-expanded]=\"open\"\n (click)=\"toggleStep(step.id)\"\n >\n <span\n class=\"fk-onboarding-guide__check\"\n [class.fk-onboarding-guide__check--done]=\"done\"\n [class.fk-onboarding-guide__check--active]=\"active\"\n [class.fk-onboarding-guide__check--todo]=\"!done && !active\"\n aria-hidden=\"true\"\n >\n @if (done) {\n <fk-icon [name]=\"checkIcon()\" size=\"xs\" />\n } @else if (active) {\n <i class=\"fk-onboarding-guide__dot\"></i>\n }\n </span>\n\n <span class=\"fk-onboarding-guide__step-label\">{{ step.label }}</span>\n\n <span class=\"fk-onboarding-guide__caret\" aria-hidden=\"true\">\n <fk-icon [name]=\"caretIcon()\" size=\"sm\" />\n </span>\n </button>\n\n @if (open) {\n <div class=\"fk-onboarding-guide__step-body\">\n @if (step.substeps && step.substeps.length > 0) {\n @for (sub of step.substeps; track sub.id) {\n <button\n type=\"button\"\n class=\"fk-onboarding-guide__sub\"\n [class.fk-onboarding-guide__sub--done]=\"sub.done\"\n (click)=\"onSubstep(step, sub)\"\n >\n <span\n class=\"fk-onboarding-guide__sub-check\"\n aria-hidden=\"true\"\n >\n @if (sub.done) {\n <fk-icon [name]=\"checkIcon()\" size=\"xs\" />\n }\n </span>\n <span class=\"fk-onboarding-guide__sub-label\">{{\n sub.label\n }}</span>\n </button>\n }\n } @else {\n @if (step.description) {\n <p class=\"fk-onboarding-guide__desc\">{{ step.description }}</p>\n }\n\n @if (!done) {\n <div class=\"fk-onboarding-guide__actions\">\n <fk-button\n variant=\"primary\"\n size=\"sm\"\n (click)=\"onAction(step)\"\n >\n {{ actionLabelFor(step) }}\n <fk-icon fkButtonIconEnd [name]=\"actionIcon()\" size=\"xs\" />\n </fk-button>\n <button\n type=\"button\"\n class=\"fk-onboarding-guide__skip\"\n (click)=\"onMarkDone(step)\"\n >\n {{ markDoneLabel() }}\n </button>\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"fk-onboarding-guide__foot\">\n <span class=\"fk-onboarding-guide__foot-text\">\n <b>{{ doneCount() }}</b> / {{ total() }} {{ stepsWord() }}\n {{ doneWord() }}\n </span>\n <button type=\"button\" class=\"fk-onboarding-guide__go\" (click)=\"onGoLive()\">\n {{ goLiveLabel() }}\n <fk-icon [name]=\"actionIcon()\" size=\"xs\" />\n </button>\n </div>\n</div>\n\n<!-- ===================== COLLAPSED PILL ===================== -->\n<button\n type=\"button\"\n class=\"fk-onboarding-guide__pill\"\n cdkDragHandle\n [attr.aria-label]=\"expandLabel()\"\n (click)=\"onExpand()\"\n>\n <span class=\"fk-onboarding-guide__ring\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 38 38\">\n <circle class=\"fk-onboarding-guide__ring-track\" cx=\"19\" cy=\"19\" r=\"16\" />\n <circle\n class=\"fk-onboarding-guide__ring-prog\"\n cx=\"19\"\n cy=\"19\"\n r=\"16\"\n [style.stroke-dasharray]=\"ringCircumference\"\n [style.stroke-dashoffset]=\"ringOffset()\"\n />\n </svg>\n <span class=\"fk-onboarding-guide__ring-num\">{{ percent() }}%</span>\n </span>\n\n <span class=\"fk-onboarding-guide__pill-meta\">\n <span class=\"fk-onboarding-guide__pill-title\">{{ title() }}</span>\n <span class=\"fk-onboarding-guide__pill-sub\">\n @if (complete()) {\n {{ allDoneLabel() }}\n } @else {\n <b>{{ stepsLeft() }}</b> {{ stepsWord() }} {{ stepsLeftWord() }}\n }\n </span>\n </span>\n\n <span class=\"fk-onboarding-guide__pill-expand\" aria-hidden=\"true\">\n <fk-icon [name]=\"expandIcon()\" size=\"sm\" />\n </span>\n</button>\n", styles: ["@keyframes fk-onboarding-guide-pop{0%{opacity:0;transform:translateY(8px) scale(.97)}to{opacity:1;transform:none}}:host{position:fixed;top:0;left:0;z-index:var(--fk-onboarding-guide-z, 60);font-family:var(--fk-onboarding-guide-font-body, var(--fk-font-family-body, system-ui, sans-serif));color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b));touch-action:none}.fk-onboarding-guide__card,.fk-onboarding-guide__pill{--fk-button-primary-bg: var( --fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a) );--fk-button-primary-bg-hover: color-mix( in srgb, var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a)) 88%, #000 );--fk-button-primary-color: var( --fk-onboarding-guide-accent-contrast, var(--fk-color-surface, #fff) )}.fk-onboarding-guide__card{width:var(--fk-onboarding-guide-width, 360px);max-width:calc(100vw - 2 * var(--fk-rhythm-4, 1rem));background:var(--fk-onboarding-guide-surface, var(--fk-color-surface, #fff));border:1px solid var(--fk-onboarding-guide-border, var(--fk-color-border, #e2e8f0));border-radius:var(--fk-onboarding-guide-radius, var(--fk-radius-lg, 16px));box-shadow:var(--fk-onboarding-guide-shadow, 0 24px 54px -18px rgba(15, 23, 42, .28));overflow:hidden;transform-origin:bottom right;animation:fk-onboarding-guide-pop .24s cubic-bezier(.2,.9,.3,1.1)}.fk-onboarding-guide__head{padding:16px 18px 14px}.fk-onboarding-guide__head-top{display:flex;align-items:center;gap:9px}.fk-onboarding-guide__grip,.fk-onboarding-guide__title{cursor:grab}.fk-onboarding-guide__grip:active,.fk-onboarding-guide__title:active{cursor:grabbing}.fk-onboarding-guide__grip{display:inline-flex;flex:none;margin-left:-3px;color:var(--fk-onboarding-guide-text-faint, var(--fk-color-muted, #94a3b8))}.fk-onboarding-guide__grip svg{width:15px;height:15px}.fk-onboarding-guide__title{font-family:var(--fk-onboarding-guide-font-display, var(--fk-font-family-display, inherit));font-size:16px;font-weight:700;color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b))}.fk-onboarding-guide__head-actions{margin-left:auto;display:flex;gap:4px}.fk-onboarding-guide__icon-btn{display:grid;place-items:center;width:28px;height:28px;border:1px solid transparent;border-radius:7px;background:none;color:var(--fk-onboarding-guide-text-faint, var(--fk-color-muted, #94a3b8));cursor:pointer;transition:.14s}.fk-onboarding-guide__icon-btn:hover{background:var(--fk-onboarding-guide-surface-muted, var(--fk-color-surface-muted, #f8fafc));border-color:var(--fk-onboarding-guide-border, var(--fk-color-border, #e2e8f0));color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b))}.fk-onboarding-guide__edit{width:24px;height:24px;border-radius:6px}.fk-onboarding-guide__progress{display:flex;align-items:center;gap:11px;margin-top:13px}.fk-onboarding-guide__track{flex:1;height:7px;border-radius:5px;background:var(--fk-onboarding-guide-surface-muted, var(--fk-color-surface-muted, #f1f5f9));overflow:hidden}.fk-onboarding-guide__fill{height:100%;border-radius:5px;background:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a));transition:width .5s cubic-bezier(.4,0,.2,1)}.fk-onboarding-guide__pct{flex:none;font-family:var(--fk-onboarding-guide-font-mono, var(--fk-font-family-mono, ui-monospace, monospace));font-size:11px;font-weight:600;color:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a))}.fk-onboarding-guide__steps{padding:6px 8px 10px;max-height:400px;overflow-y:auto}.fk-onboarding-guide__step{border-radius:12px;overflow:hidden}.fk-onboarding-guide__step--open{background:var(--fk-onboarding-guide-surface-muted, var(--fk-color-surface-muted, #f8fafc))}.fk-onboarding-guide__step-row{display:flex;align-items:center;gap:12px;width:100%;padding:13px 12px;border:none;border-radius:12px;background:none;text-align:left;cursor:pointer;transition:.14s}.fk-onboarding-guide__step-row:hover{background:var(--fk-onboarding-guide-surface-muted, var(--fk-color-surface-muted, #f8fafc))}.fk-onboarding-guide__step--open .fk-onboarding-guide__step-row:hover{background:transparent}.fk-onboarding-guide__check{display:grid;place-items:center;flex:none;width:20px;height:20px;border-radius:50%;transition:.16s;color:var(--fk-onboarding-guide-accent-contrast, #fff)}.fk-onboarding-guide__check--done{background:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a))}.fk-onboarding-guide__check--todo{border:2px solid color-mix(in srgb,var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b)) 45%,transparent)}.fk-onboarding-guide__check--active{border:2px solid var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a));background:color-mix(in srgb,var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a)) 10%,transparent)}.fk-onboarding-guide__dot{width:7px;height:7px;border-radius:50%;background:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a))}.fk-onboarding-guide__step-label{flex:1;min-width:0;font-size:14.5px;font-weight:600;color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b))}.fk-onboarding-guide__step--done .fk-onboarding-guide__step-label{color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b));font-weight:500;text-decoration:line-through;text-decoration-color:color-mix(in srgb,var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b)) 55%,transparent)}.fk-onboarding-guide__caret{display:grid;place-items:center;flex:none;color:var(--fk-onboarding-guide-text-faint, var(--fk-color-muted, #b6bfce));transition:transform .18s}.fk-onboarding-guide__step--open .fk-onboarding-guide__caret{transform:rotate(180deg);color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b))}.fk-onboarding-guide__step-body{padding:0 14px 14px 44px}.fk-onboarding-guide__desc{font-size:13px;line-height:1.55;color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b));margin-bottom:12px}.fk-onboarding-guide__actions{display:flex;align-items:center;gap:8px}.fk-onboarding-guide__skip{font-size:13px;font-weight:600;color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b));background:none;border:none;padding:6px;cursor:pointer}.fk-onboarding-guide__skip:hover{color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b))}.fk-onboarding-guide__sub{display:flex;align-items:center;gap:11px;width:100%;padding:8px 0;border:none;background:none;text-align:left;cursor:pointer}.fk-onboarding-guide__sub-check{display:grid;place-items:center;flex:none;width:18px;height:18px;border-radius:50%;color:var(--fk-onboarding-guide-accent-contrast, #fff);background:color-mix(in srgb,var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b)) 22%,transparent)}.fk-onboarding-guide__sub--done .fk-onboarding-guide__sub-check{background:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a))}.fk-onboarding-guide__sub-label{font-size:14px;color:var(--fk-onboarding-guide-text, var(--fk-color-text, #36405a))}.fk-onboarding-guide__sub--done .fk-onboarding-guide__sub-label{color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b))}.fk-onboarding-guide__foot{display:flex;align-items:center;gap:10px;padding:12px 18px 16px;border-top:1px solid var(--fk-onboarding-guide-divider, var(--fk-color-surface-dim, #f1f5f9))}.fk-onboarding-guide__foot-text{font-size:12.5px;color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b))}.fk-onboarding-guide__foot-text b{color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b));font-weight:600}.fk-onboarding-guide__go{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;background:none;border:none;cursor:pointer;color:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a))}.fk-onboarding-guide__pill{display:none;align-items:center;gap:12px;padding:9px 15px 9px 10px;border:1px solid var(--fk-onboarding-guide-border, var(--fk-color-border, #e2e8f0));border-radius:999px;background:var(--fk-onboarding-guide-surface, var(--fk-color-surface, #fff));box-shadow:var(--fk-onboarding-guide-shadow, 0 24px 54px -18px rgba(15, 23, 42, .28));cursor:grab;animation:fk-onboarding-guide-pop .22s cubic-bezier(.2,.9,.3,1.1)}.fk-onboarding-guide__pill:active{cursor:grabbing}.fk-onboarding-guide__ring{position:relative;width:38px;height:38px;flex:none}.fk-onboarding-guide__ring svg{width:38px;height:38px;transform:rotate(-90deg)}.fk-onboarding-guide__ring-track{fill:none;stroke:var(--fk-onboarding-guide-surface-muted, var(--fk-color-surface-muted, #f1f5f9));stroke-width:4}.fk-onboarding-guide__ring-prog{fill:none;stroke:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a));stroke-width:4;stroke-linecap:round;transition:stroke-dashoffset .5s cubic-bezier(.4,0,.2,1)}.fk-onboarding-guide__ring-num{position:absolute;inset:0;display:grid;place-items:center;font-family:var(--fk-onboarding-guide-font-mono, var(--fk-font-family-mono, ui-monospace, monospace));font-size:10.5px;font-weight:600;color:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a))}.fk-onboarding-guide__pill-meta{display:flex;flex-direction:column;line-height:1.2;text-align:left}.fk-onboarding-guide__pill-title{font-family:var(--fk-onboarding-guide-font-display, var(--fk-font-family-display, inherit));font-size:13.5px;font-weight:700;white-space:nowrap;color:var(--fk-onboarding-guide-text, var(--fk-color-text, #1e293b))}.fk-onboarding-guide__pill-sub{margin-top:2px;font-size:11.5px;white-space:nowrap;color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b))}.fk-onboarding-guide__pill-sub b{color:var(--fk-onboarding-guide-accent, var(--fk-color-text, #1a1a1a));font-weight:600}.fk-onboarding-guide__pill-expand{display:grid;place-items:center;width:28px;height:28px;flex:none;margin-left:2px;border-radius:50%;background:var(--fk-onboarding-guide-surface-muted, var(--fk-color-surface-muted, #f8fafc));color:var(--fk-onboarding-guide-text-muted, var(--fk-color-muted, #64748b))}.fk-onboarding-guide--complete .fk-onboarding-guide__ring-prog{stroke:var(--fk-onboarding-guide-complete, var(--fk-color-success, #16a34a))}.fk-onboarding-guide--complete .fk-onboarding-guide__ring-num{color:var(--fk-onboarding-guide-complete, var(--fk-color-success, #16a34a))}:host(.fk-onboarding-guide--collapsed) .fk-onboarding-guide__card{display:none}:host(.fk-onboarding-guide--collapsed) .fk-onboarding-guide__pill{display:flex}\n"] }]
|
|
1237
|
+
}], ctorParameters: () => [], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], storageKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "storageKey", required: false }] }], startCollapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "startCollapsed", required: false }] }], startLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "startLabel", required: false }] }], markDoneLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "markDoneLabel", required: false }] }], goLiveLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "goLiveLabel", required: false }] }], stepsWord: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepsWord", required: false }] }], doneWord: [{ type: i0.Input, args: [{ isSignal: true, alias: "doneWord", required: false }] }], stepsLeftWord: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepsLeftWord", required: false }] }], allDoneLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "allDoneLabel", required: false }] }], renameLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "renameLabel", required: false }] }], collapseLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapseLabel", required: false }] }], dismissLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissLabel", required: false }] }], expandLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandLabel", required: false }] }], checkIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "checkIcon", required: false }] }], caretIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "caretIcon", required: false }] }], editIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "editIcon", required: false }] }], collapseIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapseIcon", required: false }] }], dismissIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissIcon", required: false }] }], expandIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandIcon", required: false }] }], actionIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionIcon", required: false }] }], stepAction: [{ type: i0.Output, args: ["stepAction"] }], stepMarkDone: [{ type: i0.Output, args: ["stepMarkDone"] }], substepToggle: [{ type: i0.Output, args: ["substepToggle"] }], goLive: [{ type: i0.Output, args: ["goLive"] }], renameClick: [{ type: i0.Output, args: ["renameClick"] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }], collapsedChange: [{ type: i0.Output, args: ["collapsedChange"] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], hostClass: [{
|
|
1238
|
+
type: HostBinding,
|
|
1239
|
+
args: ['class']
|
|
1240
|
+
}], hostId: [{
|
|
1241
|
+
type: HostBinding,
|
|
1242
|
+
args: ['attr.id']
|
|
1243
|
+
}] } });
|
|
1244
|
+
|
|
1245
|
+
/**
|
|
1246
|
+
* Layout for a dashboard search/filter bar. It lays out a primary search field
|
|
1247
|
+
* and fixed-width filter dropdowns in a responsive row and compacts the
|
|
1248
|
+
* projected `fk-form-field` / `fk-input` / `fk-select` controls to the house
|
|
1249
|
+
* filter-bar size — so every dashboard's filter bar reads the same without
|
|
1250
|
+
* per-page CSS.
|
|
1251
|
+
*
|
|
1252
|
+
* It owns **layout and responsiveness only** — no surrounding border,
|
|
1253
|
+
* background, or elevation. If you want the bar to sit inside a card, wrap it in
|
|
1254
|
+
* your own surface.
|
|
1255
|
+
*
|
|
1256
|
+
* Tag the primary search field with the `search` attribute (grows to fill) and
|
|
1257
|
+
* each fixed-width filter with the `filter` attribute. Under a narrow container
|
|
1258
|
+
* the row stacks and every control goes full-width.
|
|
1259
|
+
*
|
|
1260
|
+
* ```html
|
|
1261
|
+
* <fk-search-bar-layout>
|
|
1262
|
+
* <fk-form-field search>
|
|
1263
|
+
* <fk-icon fkPrefix name="magnifier-outline" size="sm" />
|
|
1264
|
+
* <fk-input formControlName="q" placeholder="Search…" />
|
|
1265
|
+
* </fk-form-field>
|
|
1266
|
+
*
|
|
1267
|
+
* <fk-form-field filter>
|
|
1268
|
+
* <fk-select formControlName="status" [options]="options" />
|
|
1269
|
+
* </fk-form-field>
|
|
1270
|
+
* </fk-search-bar-layout>
|
|
1271
|
+
* ```
|
|
1272
|
+
*
|
|
1273
|
+
* Uses `ViewEncapsulation.None` so it can style the projected controls (the
|
|
1274
|
+
* `[search]` / `[filter]` children and the select chevron); its rules are scoped
|
|
1275
|
+
* under the block class.
|
|
1276
|
+
*/
|
|
1277
|
+
class SearchBarLayoutComponent {
|
|
1278
|
+
// ===== BASE PROPS =====
|
|
1279
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
1280
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
1281
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
1282
|
+
// ===== COMPUTED =====
|
|
1283
|
+
classes = computed(() => ['fk-search-bar-layout', this.className()].filter(Boolean).join(' '), ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
1284
|
+
get hostClass() {
|
|
1285
|
+
return this.classes();
|
|
1286
|
+
}
|
|
1287
|
+
role = 'search';
|
|
1288
|
+
get hostId() {
|
|
1289
|
+
return this.id();
|
|
1290
|
+
}
|
|
1291
|
+
get hostAriaLabel() {
|
|
1292
|
+
return this.ariaLabel();
|
|
1293
|
+
}
|
|
1294
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SearchBarLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1295
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: SearchBarLayoutComponent, isStandalone: true, selector: "fk-search-bar-layout", inputs: { 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", "attr.role": "this.role", "attr.id": "this.hostId", "attr.aria-label": "this.hostAriaLabel" } }, ngImport: i0, template: "<div class=\"fk-search-bar-layout__row\">\n <ng-content />\n</div>\n", styles: [".fk-search-bar-layout{display:block;container-type:inline-size}.fk-search-bar-layout__row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--fk-search-bar-layout-gap);--fk-form-label-gap: 0;--fk-form-label-margin-top: 0;--fk-form-subscript-gap: 0;--fk-form-subscript-display: none;--fk-form-subscript-min-height: 0;--fk-form-field-gap: 0;--fk-input-padding: var(--fk-search-bar-layout-control-padding);--fk-input-font-size: var(--fk-search-bar-layout-control-font-size);--fk-input-border-radius: var(--fk-search-bar-layout-control-radius);--fk-select-arrow-color: var(--fk-search-bar-layout-chevron-color)}@container (max-width: 500px){.fk-search-bar-layout__row{flex-direction:column;align-items:stretch}}.fk-search-bar-layout__row>[search]{flex:1;min-width:0;--fk-input-bg: var(--fk-search-bar-layout-search-bg)}.fk-search-bar-layout__row>[filter]{flex:0 0 auto;min-width:var(--fk-search-bar-layout-filter-min-width);--fk-input-font-weight: var(--fk-search-bar-layout-filter-font-weight)}@container (max-width: 500px){.fk-search-bar-layout__row>[search],.fk-search-bar-layout__row>[filter]{flex:none;width:100%}}.fk-search-bar-layout__row .fk-select__arrow{stroke-width:var(--fk-search-bar-layout-chevron-stroke)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1296
|
+
}
|
|
1297
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SearchBarLayoutComponent, decorators: [{
|
|
1298
|
+
type: Component,
|
|
1299
|
+
args: [{ selector: 'fk-search-bar-layout', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"fk-search-bar-layout__row\">\n <ng-content />\n</div>\n", styles: [".fk-search-bar-layout{display:block;container-type:inline-size}.fk-search-bar-layout__row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--fk-search-bar-layout-gap);--fk-form-label-gap: 0;--fk-form-label-margin-top: 0;--fk-form-subscript-gap: 0;--fk-form-subscript-display: none;--fk-form-subscript-min-height: 0;--fk-form-field-gap: 0;--fk-input-padding: var(--fk-search-bar-layout-control-padding);--fk-input-font-size: var(--fk-search-bar-layout-control-font-size);--fk-input-border-radius: var(--fk-search-bar-layout-control-radius);--fk-select-arrow-color: var(--fk-search-bar-layout-chevron-color)}@container (max-width: 500px){.fk-search-bar-layout__row{flex-direction:column;align-items:stretch}}.fk-search-bar-layout__row>[search]{flex:1;min-width:0;--fk-input-bg: var(--fk-search-bar-layout-search-bg)}.fk-search-bar-layout__row>[filter]{flex:0 0 auto;min-width:var(--fk-search-bar-layout-filter-min-width);--fk-input-font-weight: var(--fk-search-bar-layout-filter-font-weight)}@container (max-width: 500px){.fk-search-bar-layout__row>[search],.fk-search-bar-layout__row>[filter]{flex:none;width:100%}}.fk-search-bar-layout__row .fk-select__arrow{stroke-width:var(--fk-search-bar-layout-chevron-stroke)}\n"] }]
|
|
1300
|
+
}], propDecorators: { 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: [{
|
|
1301
|
+
type: HostBinding,
|
|
1302
|
+
args: ['class']
|
|
1303
|
+
}], role: [{
|
|
1304
|
+
type: HostBinding,
|
|
1305
|
+
args: ['attr.role']
|
|
1306
|
+
}], hostId: [{
|
|
1307
|
+
type: HostBinding,
|
|
1308
|
+
args: ['attr.id']
|
|
1309
|
+
}], hostAriaLabel: [{
|
|
1310
|
+
type: HostBinding,
|
|
1311
|
+
args: ['attr.aria-label']
|
|
1312
|
+
}] } });
|
|
1313
|
+
|
|
1314
|
+
/**
|
|
1315
|
+
* A titled content section for a dashboard page: an optional heading followed by
|
|
1316
|
+
* projected content, with consistent vertical rhythm between the section and its
|
|
1317
|
+
* own children.
|
|
1318
|
+
*
|
|
1319
|
+
* Spacing is top-margin only (never a parent `gap`), so a consumer's per-child
|
|
1320
|
+
* `margin-top` overrides cleanly instead of stacking on an invisible gap. The
|
|
1321
|
+
* first child sits flush; each subsequent child gets the section rhythm.
|
|
1322
|
+
* `marginTop` overrides the section's own top margin per instance.
|
|
1323
|
+
*
|
|
1324
|
+
* ```html
|
|
1325
|
+
* <fk-content-page-section title="Members" [level]="3">
|
|
1326
|
+
* <p>…</p>
|
|
1327
|
+
* <fk-data-table />
|
|
1328
|
+
* </fk-content-page-section>
|
|
1329
|
+
* ```
|
|
1330
|
+
*
|
|
1331
|
+
* Uses `ViewEncapsulation.None` so the inter-child rhythm rule reaches projected
|
|
1332
|
+
* content; its rules are scoped under the block class.
|
|
1333
|
+
*/
|
|
1334
|
+
class ContentPageSectionComponent {
|
|
1335
|
+
// ===== INPUTS =====
|
|
1336
|
+
title = input(null, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
1337
|
+
level = input(5, ...(ngDevMode ? [{ debugName: "level" }] : /* istanbul ignore next */ []));
|
|
1338
|
+
marginTop = input(null, ...(ngDevMode ? [{ debugName: "marginTop" }] : /* istanbul ignore next */ []));
|
|
1339
|
+
// ===== BASE PROPS =====
|
|
1340
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
1341
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
1342
|
+
// ===== COMPUTED =====
|
|
1343
|
+
classes = computed(() => ['fk-content-page-section', this.className()].filter(Boolean).join(' '), ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
1344
|
+
get hostClass() {
|
|
1345
|
+
return this.classes();
|
|
1346
|
+
}
|
|
1347
|
+
get hostId() {
|
|
1348
|
+
return this.id();
|
|
1349
|
+
}
|
|
1350
|
+
get hostMarginTop() {
|
|
1351
|
+
return this.marginTop();
|
|
1352
|
+
}
|
|
1353
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContentPageSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1354
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ContentPageSectionComponent, isStandalone: true, selector: "fk-content-page-section", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, marginTop: { classPropertyName: "marginTop", publicName: "marginTop", 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 } }, host: { properties: { "class": "this.hostClass", "attr.id": "this.hostId", "style.margin-top": "this.hostMarginTop" } }, ngImport: i0, template: "@if (title()) {\n <fk-headline [level]=\"level()\">{{ title() }}</fk-headline>\n}\n\n<ng-content />\n", styles: [".fk-content-page-section{display:flex;flex-direction:column;margin-top:var(--fk-content-page-section-margin-top);--fk-headline-margin-block-start: 0}.fk-content-page-section>*+*{margin-top:var(--fk-content-page-section-gap)}\n"], dependencies: [{ kind: "component", type: HeadlineComponent, selector: "fk-headline", inputs: ["ariaLabel", "className", "fontSize", "id", "level", "variant", "visuallyHidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1355
|
+
}
|
|
1356
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContentPageSectionComponent, decorators: [{
|
|
1357
|
+
type: Component,
|
|
1358
|
+
args: [{ selector: 'fk-content-page-section', standalone: true, imports: [HeadlineComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@if (title()) {\n <fk-headline [level]=\"level()\">{{ title() }}</fk-headline>\n}\n\n<ng-content />\n", styles: [".fk-content-page-section{display:flex;flex-direction:column;margin-top:var(--fk-content-page-section-margin-top);--fk-headline-margin-block-start: 0}.fk-content-page-section>*+*{margin-top:var(--fk-content-page-section-gap)}\n"] }]
|
|
1359
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }], marginTop: [{ type: i0.Input, args: [{ isSignal: true, alias: "marginTop", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], hostClass: [{
|
|
1360
|
+
type: HostBinding,
|
|
1361
|
+
args: ['class']
|
|
1362
|
+
}], hostId: [{
|
|
1363
|
+
type: HostBinding,
|
|
1364
|
+
args: ['attr.id']
|
|
1365
|
+
}], hostMarginTop: [{
|
|
1366
|
+
type: HostBinding,
|
|
1367
|
+
args: ['style.margin-top']
|
|
1368
|
+
}] } });
|
|
1369
|
+
|
|
1370
|
+
/**
|
|
1371
|
+
* Lays its `fk-content-column` children out **side by side**, wrapping and
|
|
1372
|
+
* ultimately stacking to a single column based on the row's *own* available
|
|
1373
|
+
* width — never the viewport (so it reacts when a sidenav opens or it sits in a
|
|
1374
|
+
* narrow panel). Same intrinsic CSS grid as `fk-columns`
|
|
1375
|
+
* (`repeat(auto-fit, minmax(min, 1fr))`); `minColumnWidth` is the single knob
|
|
1376
|
+
* for when columns stack.
|
|
1377
|
+
*
|
|
1378
|
+
* Optionally **bordered**, with an optional **headline**
|
|
1379
|
+
* (`fk-content-column-headline`) that sits *outside* the border — so the row
|
|
1380
|
+
* reads as a titled section wrapping a set of columns.
|
|
1381
|
+
*
|
|
1382
|
+
* ```html
|
|
1383
|
+
* <fk-content-row [bordered]="true" minColumnWidth="16rem">
|
|
1384
|
+
* <fk-content-column-headline>Providers</fk-content-column-headline>
|
|
1385
|
+
* <fk-content-column>…</fk-content-column>
|
|
1386
|
+
* <fk-content-column>…</fk-content-column>
|
|
1387
|
+
* </fk-content-row>
|
|
1388
|
+
* ```
|
|
1389
|
+
*/
|
|
1390
|
+
class ContentRowComponent {
|
|
1391
|
+
// ===== INPUTS =====
|
|
1392
|
+
/**
|
|
1393
|
+
* The smallest width a column may shrink to before the row drops to fewer
|
|
1394
|
+
* columns — the single knob that controls when columns wrap/stack.
|
|
1395
|
+
*/
|
|
1396
|
+
minColumnWidth = input('16rem', ...(ngDevMode ? [{ debugName: "minColumnWidth" }] : /* istanbul ignore next */ []));
|
|
1397
|
+
/**
|
|
1398
|
+
* Optional cap on how wide a column may grow. Unset (default), columns fill
|
|
1399
|
+
* the row (`1fr`); when set, columns stop at this width and leftover space
|
|
1400
|
+
* stays empty (columns aligned to the start).
|
|
1401
|
+
*/
|
|
1402
|
+
maxColumnWidth = input(null, ...(ngDevMode ? [{ debugName: "maxColumnWidth" }] : /* istanbul ignore next */ []));
|
|
1403
|
+
/** Gap between side-by-side columns and between wrapped rows. */
|
|
1404
|
+
gutter = input('var(--fk-rhythm-4, 1rem)', ...(ngDevMode ? [{ debugName: "gutter" }] : /* istanbul ignore next */ []));
|
|
1405
|
+
/** Draws a bordered, padded box around the columns (not the headline). */
|
|
1406
|
+
bordered = input(false, ...(ngDevMode ? [{ debugName: "bordered" }] : /* istanbul ignore next */ []));
|
|
1407
|
+
// ===== BASE PROPS =====
|
|
1408
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
1409
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
1410
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
1411
|
+
// ===== COMPUTED =====
|
|
1412
|
+
classes = computed(() => ['fk-content-row', this.className()].filter(Boolean).join(' '), ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
1413
|
+
get hostClass() {
|
|
1414
|
+
return this.classes();
|
|
1415
|
+
}
|
|
1416
|
+
get hostId() {
|
|
1417
|
+
return this.id();
|
|
1418
|
+
}
|
|
1419
|
+
get hostAriaLabel() {
|
|
1420
|
+
return this.ariaLabel();
|
|
1421
|
+
}
|
|
1422
|
+
get hostMin() {
|
|
1423
|
+
return this.minColumnWidth();
|
|
1424
|
+
}
|
|
1425
|
+
// Null leaves the property unset, so the SCSS falls back to `1fr` (fill).
|
|
1426
|
+
get hostMax() {
|
|
1427
|
+
return this.maxColumnWidth();
|
|
1428
|
+
}
|
|
1429
|
+
get hostGutter() {
|
|
1430
|
+
return this.gutter();
|
|
1431
|
+
}
|
|
1432
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContentRowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1433
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: ContentRowComponent, isStandalone: true, selector: "fk-content-row", inputs: { minColumnWidth: { classPropertyName: "minColumnWidth", publicName: "minColumnWidth", isSignal: true, isRequired: false, transformFunction: null }, maxColumnWidth: { classPropertyName: "maxColumnWidth", publicName: "maxColumnWidth", isSignal: true, isRequired: false, transformFunction: null }, gutter: { classPropertyName: "gutter", publicName: "gutter", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", 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", "attr.id": "this.hostId", "attr.aria-label": "this.hostAriaLabel", "style.--fk-content-row-min": "this.hostMin", "style.--fk-content-row-max": "this.hostMax", "style.--fk-content-row-gutter": "this.hostGutter" } }, ngImport: i0, template: "<!-- Headline sits outside the bordered region. -->\n<ng-content select=\"fk-content-column-headline\" />\n\n<div\n class=\"fk-content-row__grid\"\n [class.fk-content-row__grid--bordered]=\"bordered()\"\n>\n <ng-content />\n</div>\n", styles: [":host{display:block}.fk-content-row__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(var(--fk-content-row-min, 16rem),100%),var(--fk-content-row-max, 1fr)));gap:var(--fk-content-row-gutter, var(--fk-rhythm-4, 1rem));align-items:stretch;justify-content:start}.fk-content-row__grid:not(:first-child){margin-top:var(--fk-content-column-headline-gap)}.fk-content-row__grid--bordered{padding:var(--fk-content-row-padding);border:1px solid var(--fk-content-row-border-color);border-radius:var(--fk-content-row-radius)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1434
|
+
}
|
|
1435
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContentRowComponent, decorators: [{
|
|
1436
|
+
type: Component,
|
|
1437
|
+
args: [{ selector: 'fk-content-row', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Headline sits outside the bordered region. -->\n<ng-content select=\"fk-content-column-headline\" />\n\n<div\n class=\"fk-content-row__grid\"\n [class.fk-content-row__grid--bordered]=\"bordered()\"\n>\n <ng-content />\n</div>\n", styles: [":host{display:block}.fk-content-row__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(var(--fk-content-row-min, 16rem),100%),var(--fk-content-row-max, 1fr)));gap:var(--fk-content-row-gutter, var(--fk-rhythm-4, 1rem));align-items:stretch;justify-content:start}.fk-content-row__grid:not(:first-child){margin-top:var(--fk-content-column-headline-gap)}.fk-content-row__grid--bordered{padding:var(--fk-content-row-padding);border:1px solid var(--fk-content-row-border-color);border-radius:var(--fk-content-row-radius)}\n"] }]
|
|
1438
|
+
}], propDecorators: { minColumnWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minColumnWidth", required: false }] }], maxColumnWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxColumnWidth", required: false }] }], gutter: [{ type: i0.Input, args: [{ isSignal: true, alias: "gutter", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", 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: [{
|
|
1439
|
+
type: HostBinding,
|
|
1440
|
+
args: ['class']
|
|
1441
|
+
}], hostId: [{
|
|
1442
|
+
type: HostBinding,
|
|
1443
|
+
args: ['attr.id']
|
|
1444
|
+
}], hostAriaLabel: [{
|
|
1445
|
+
type: HostBinding,
|
|
1446
|
+
args: ['attr.aria-label']
|
|
1447
|
+
}], hostMin: [{
|
|
1448
|
+
type: HostBinding,
|
|
1449
|
+
args: ['style.--fk-content-row-min']
|
|
1450
|
+
}], hostMax: [{
|
|
1451
|
+
type: HostBinding,
|
|
1452
|
+
args: ['style.--fk-content-row-max']
|
|
1453
|
+
}], hostGutter: [{
|
|
1454
|
+
type: HostBinding,
|
|
1455
|
+
args: ['style.--fk-content-row-gutter']
|
|
1456
|
+
}] } });
|
|
1457
|
+
|
|
1458
|
+
/**
|
|
1459
|
+
* A single content column — a vertical block of stacked content, with an
|
|
1460
|
+
* optional **border** and an optional **headline** (`fk-content-column-headline`)
|
|
1461
|
+
* that sits *outside* that border. The semantic unit that goes inside an
|
|
1462
|
+
* `fk-content-row` (which lays columns side by side and stacks them when narrow),
|
|
1463
|
+
* or stands alone as a bordered, titled section.
|
|
1464
|
+
*
|
|
1465
|
+
* ```html
|
|
1466
|
+
* <fk-content-column [bordered]="true">
|
|
1467
|
+
* <fk-content-column-headline>Provider</fk-content-column-headline>
|
|
1468
|
+
* …
|
|
1469
|
+
* </fk-content-column>
|
|
1470
|
+
* ```
|
|
1471
|
+
*/
|
|
1472
|
+
class ContentColumnComponent {
|
|
1473
|
+
// ===== INPUTS =====
|
|
1474
|
+
/** Draws a bordered, padded box around the content (not the headline). */
|
|
1475
|
+
bordered = input(false, ...(ngDevMode ? [{ debugName: "bordered" }] : /* istanbul ignore next */ []));
|
|
1476
|
+
// ===== BASE PROPS =====
|
|
1477
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
1478
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
1479
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
1480
|
+
// ===== COMPUTED =====
|
|
1481
|
+
classes = computed(() => ['fk-content-column', this.className()].filter(Boolean).join(' '), ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
1482
|
+
get hostClass() {
|
|
1483
|
+
return this.classes();
|
|
1484
|
+
}
|
|
1485
|
+
get hostId() {
|
|
1486
|
+
return this.id();
|
|
1487
|
+
}
|
|
1488
|
+
get hostAriaLabel() {
|
|
1489
|
+
return this.ariaLabel();
|
|
1490
|
+
}
|
|
1491
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContentColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1492
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: ContentColumnComponent, isStandalone: true, selector: "fk-content-column", inputs: { bordered: { classPropertyName: "bordered", publicName: "bordered", 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", "attr.id": "this.hostId", "attr.aria-label": "this.hostAriaLabel" } }, ngImport: i0, template: "<!-- Headline sits outside the bordered region. -->\n<ng-content select=\"fk-content-column-headline\" />\n\n<div\n class=\"fk-content-column__content\"\n [class.fk-content-column__content--bordered]=\"bordered()\"\n>\n <ng-content />\n</div>\n", styles: [":host{display:flex;flex-direction:column}.fk-content-column__content{flex:1;display:flex;flex-direction:column}.fk-content-column__content:not(:first-child){margin-top:var(--fk-content-column-headline-gap)}.fk-content-column__content--bordered{padding:var(--fk-content-column-padding);border:1px solid var(--fk-content-column-border-color);border-radius:var(--fk-content-column-radius)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1493
|
+
}
|
|
1494
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContentColumnComponent, decorators: [{
|
|
1495
|
+
type: Component,
|
|
1496
|
+
args: [{ selector: 'fk-content-column', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Headline sits outside the bordered region. -->\n<ng-content select=\"fk-content-column-headline\" />\n\n<div\n class=\"fk-content-column__content\"\n [class.fk-content-column__content--bordered]=\"bordered()\"\n>\n <ng-content />\n</div>\n", styles: [":host{display:flex;flex-direction:column}.fk-content-column__content{flex:1;display:flex;flex-direction:column}.fk-content-column__content:not(:first-child){margin-top:var(--fk-content-column-headline-gap)}.fk-content-column__content--bordered{padding:var(--fk-content-column-padding);border:1px solid var(--fk-content-column-border-color);border-radius:var(--fk-content-column-radius)}\n"] }]
|
|
1497
|
+
}], propDecorators: { bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", 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: [{
|
|
1498
|
+
type: HostBinding,
|
|
1499
|
+
args: ['class']
|
|
1500
|
+
}], hostId: [{
|
|
1501
|
+
type: HostBinding,
|
|
1502
|
+
args: ['attr.id']
|
|
1503
|
+
}], hostAriaLabel: [{
|
|
1504
|
+
type: HostBinding,
|
|
1505
|
+
args: ['attr.aria-label']
|
|
1506
|
+
}] } });
|
|
1507
|
+
|
|
1508
|
+
/**
|
|
1509
|
+
* Optional headline for `fk-content-column` / `fk-content-row`. Projected
|
|
1510
|
+
* *outside* the bordered region, so it labels the group without being boxed in
|
|
1511
|
+
* with the content. Projects its own text/markup.
|
|
1512
|
+
*
|
|
1513
|
+
* ```html
|
|
1514
|
+
* <fk-content-column [bordered]="true">
|
|
1515
|
+
* <fk-content-column-headline>Provider</fk-content-column-headline>
|
|
1516
|
+
* …
|
|
1517
|
+
* </fk-content-column>
|
|
1518
|
+
* ```
|
|
1519
|
+
*/
|
|
1520
|
+
class ContentColumnHeadlineComponent {
|
|
1521
|
+
// ===== BASE PROPS =====
|
|
1522
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
1523
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
1524
|
+
// ===== COMPUTED =====
|
|
1525
|
+
classes = computed(() => ['fk-content-column-headline', this.className()].filter(Boolean).join(' '), ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
1526
|
+
get hostClass() {
|
|
1527
|
+
return this.classes();
|
|
1528
|
+
}
|
|
1529
|
+
get hostId() {
|
|
1530
|
+
return this.id();
|
|
1531
|
+
}
|
|
1532
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContentColumnHeadlineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1533
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: ContentColumnHeadlineComponent, isStandalone: true, selector: "fk-content-column-headline", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.hostClass", "attr.id": "this.hostId" } }, ngImport: i0, template: "<ng-content />\n", styles: [":host{display:block;color:var(--fk-content-column-headline-color);font-size:var(--fk-content-column-headline-font-size);font-weight:var(--fk-content-column-headline-font-weight)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1534
|
+
}
|
|
1535
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContentColumnHeadlineComponent, decorators: [{
|
|
1536
|
+
type: Component,
|
|
1537
|
+
args: [{ selector: 'fk-content-column-headline', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content />\n", styles: [":host{display:block;color:var(--fk-content-column-headline-color);font-size:var(--fk-content-column-headline-font-size);font-weight:var(--fk-content-column-headline-font-weight)}\n"] }]
|
|
1538
|
+
}], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], hostClass: [{
|
|
1539
|
+
type: HostBinding,
|
|
1540
|
+
args: ['class']
|
|
1541
|
+
}], hostId: [{
|
|
1542
|
+
type: HostBinding,
|
|
1543
|
+
args: ['attr.id']
|
|
1544
|
+
}] } });
|
|
1545
|
+
|
|
927
1546
|
/**
|
|
928
1547
|
* Generated bundle index. Do not edit.
|
|
929
1548
|
*/
|
|
930
1549
|
|
|
931
|
-
export { ColumnsComponent, ContentSplitLayoutComponent, DetailPanelComponent, DialogFooterComponent, DialogHeaderComponent, DialogShellComponent, PageHeaderComponent, SidebarNavComponent, SidebarNavItemDirective, TableEmptyStateComponent };
|
|
1550
|
+
export { ColumnsComponent, ContentColumnComponent, ContentColumnHeadlineComponent, ContentPageSectionComponent, ContentRowComponent, ContentSplitLayoutComponent, DetailPanelComponent, DialogFooterComponent, DialogHeaderComponent, DialogShellComponent, OnboardingGuideComponent, PageHeaderComponent, SearchBarLayoutComponent, SidebarNavComponent, SidebarNavItemDirective, TableEmptyStateComponent };
|
|
932
1551
|
//# sourceMappingURL=frame-kit-ui-ng-patterns-dashboard.mjs.map
|