@frame-kit/ui-ng 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENTS.md +683 -0
- package/DEVELOPMENT_GUIDE.md +1102 -0
- package/LICENSE +21 -0
- package/README.md +69 -0
- package/THEMING.md +130 -0
- package/core/headline/README.md +121 -0
- package/core/icon/README.md +173 -0
- package/core/image/README.md +210 -0
- package/core/link/README.md +297 -0
- package/core/separator/README.md +145 -0
- package/core/text/README.md +240 -0
- package/directives/infinite-scroll/README.md +102 -0
- package/directives/spotlight/README.md +154 -0
- package/directives/tooltip/README.md +147 -0
- package/docs/endpoint-link/README.md +142 -0
- package/docs/method-badge/README.md +154 -0
- package/fesm2022/frame-kit-ui-ng-core-headline.mjs +122 -0
- package/fesm2022/frame-kit-ui-ng-core-headline.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-icon.mjs +189 -0
- package/fesm2022/frame-kit-ui-ng-core-icon.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-image.mjs +123 -0
- package/fesm2022/frame-kit-ui-ng-core-image.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-link.mjs +369 -0
- package/fesm2022/frame-kit-ui-ng-core-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-separator.mjs +59 -0
- package/fesm2022/frame-kit-ui-ng-core-separator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-text.mjs +204 -0
- package/fesm2022/frame-kit-ui-ng-core-text.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs +74 -0
- package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs +76 -0
- package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs +425 -0
- package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs +63 -0
- package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs +43 -0
- package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-forms.mjs +3632 -0
- package/fesm2022/frame-kit-ui-ng-forms.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs +239 -0
- package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs +132 -0
- package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs +133 -0
- package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs +60 -0
- package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-toast.mjs +166 -0
- package/fesm2022/frame-kit-ui-ng-services-toast.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs +214 -0
- package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-alert.mjs +82 -0
- package/fesm2022/frame-kit-ui-ng-ui-alert.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs +76 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-badge.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs +68 -0
- package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-button.mjs +108 -0
- package/fesm2022/frame-kit-ui-ng-ui-button.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-callout.mjs +58 -0
- package/fesm2022/frame-kit-ui-ng-ui-callout.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-card.mjs +70 -0
- package/fesm2022/frame-kit-ui-ng-ui-card.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs +113 -0
- package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs +1288 -0
- package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs +456 -0
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs +398 -0
- package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs +398 -0
- package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs +125 -0
- package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs +113 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs +111 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs +103 -0
- package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs +135 -0
- package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-loader.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-loader.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs +79 -0
- package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs +40 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs +110 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs +91 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs +86 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs +443 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-note.mjs +56 -0
- package/fesm2022/frame-kit-ui-ng-ui-note.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs +105 -0
- package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs +110 -0
- package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs +129 -0
- package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs +42 -0
- package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs +894 -0
- package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-toast.mjs +179 -0
- package/fesm2022/frame-kit-ui-ng-ui-toast.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs +143 -0
- package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs +191 -0
- package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng.mjs +58 -0
- package/fesm2022/frame-kit-ui-ng.mjs.map +1 -0
- package/layouts/app-shell/README.md +357 -0
- package/layouts/content-split/README.md +180 -0
- package/package.json +253 -0
- package/services/overlay-orchestrator/README.md +184 -0
- package/services/spotlight/README.md +61 -0
- package/services/toast/README.md +118 -0
- package/types/frame-kit-ui-ng-core-headline.d.ts +38 -0
- package/types/frame-kit-ui-ng-core-icon.d.ts +74 -0
- package/types/frame-kit-ui-ng-core-image.d.ts +93 -0
- package/types/frame-kit-ui-ng-core-link.d.ts +251 -0
- package/types/frame-kit-ui-ng-core-separator.d.ts +28 -0
- package/types/frame-kit-ui-ng-core-text.d.ts +186 -0
- package/types/frame-kit-ui-ng-directives-infinite-scroll.d.ts +42 -0
- package/types/frame-kit-ui-ng-directives-spotlight.d.ts +51 -0
- package/types/frame-kit-ui-ng-directives-tooltip.d.ts +70 -0
- package/types/frame-kit-ui-ng-docs-endpoint-link.d.ts +43 -0
- package/types/frame-kit-ui-ng-docs-method-badge.d.ts +30 -0
- package/types/frame-kit-ui-ng-forms.d.ts +1674 -0
- package/types/frame-kit-ui-ng-layouts-app-shell.d.ts +75 -0
- package/types/frame-kit-ui-ng-layouts-content-split.d.ts +43 -0
- package/types/frame-kit-ui-ng-services-overlay-orchestrator.d.ts +96 -0
- package/types/frame-kit-ui-ng-services-spotlight.d.ts +32 -0
- package/types/frame-kit-ui-ng-services-toast.d.ts +100 -0
- package/types/frame-kit-ui-ng-ui-accordion.d.ts +86 -0
- package/types/frame-kit-ui-ng-ui-alert.d.ts +34 -0
- package/types/frame-kit-ui-ng-ui-avatar-stack.d.ts +38 -0
- package/types/frame-kit-ui-ng-ui-avatar.d.ts +36 -0
- package/types/frame-kit-ui-ng-ui-badge.d.ts +33 -0
- package/types/frame-kit-ui-ng-ui-breadcrumb.d.ts +45 -0
- package/types/frame-kit-ui-ng-ui-button.d.ts +48 -0
- package/types/frame-kit-ui-ng-ui-callout.d.ts +26 -0
- package/types/frame-kit-ui-ng-ui-card.d.ts +30 -0
- package/types/frame-kit-ui-ng-ui-copyable-field.d.ts +62 -0
- package/types/frame-kit-ui-ng-ui-data-table.d.ts +482 -0
- package/types/frame-kit-ui-ng-ui-dialog.d.ts +166 -0
- package/types/frame-kit-ui-ng-ui-drawer.d.ts +130 -0
- package/types/frame-kit-ui-ng-ui-dropdown-menu.d.ts +77 -0
- package/types/frame-kit-ui-ng-ui-editable-field.d.ts +65 -0
- package/types/frame-kit-ui-ng-ui-icon-badge.d.ts +45 -0
- package/types/frame-kit-ui-ng-ui-icon-list.d.ts +67 -0
- package/types/frame-kit-ui-ng-ui-inline-edit.d.ts +44 -0
- package/types/frame-kit-ui-ng-ui-list-editor.d.ts +56 -0
- package/types/frame-kit-ui-ng-ui-loader.d.ts +32 -0
- package/types/frame-kit-ui-ng-ui-menu-item.d.ts +27 -0
- package/types/frame-kit-ui-ng-ui-nav-brand.d.ts +25 -0
- package/types/frame-kit-ui-ng-ui-nav-group.d.ts +60 -0
- package/types/frame-kit-ui-ng-ui-nav-separator.d.ts +33 -0
- package/types/frame-kit-ui-ng-ui-node-tree-breadcrumb.d.ts +35 -0
- package/types/frame-kit-ui-ng-ui-node-tree.d.ts +135 -0
- package/types/frame-kit-ui-ng-ui-note.d.ts +22 -0
- package/types/frame-kit-ui-ng-ui-numbered-list.d.ts +52 -0
- package/types/frame-kit-ui-ng-ui-pagination.d.ts +49 -0
- package/types/frame-kit-ui-ng-ui-progress-bar.d.ts +50 -0
- package/types/frame-kit-ui-ng-ui-sidenav-link.d.ts +24 -0
- package/types/frame-kit-ui-ng-ui-tabs.d.ts +266 -0
- package/types/frame-kit-ui-ng-ui-timeline.d.ts +42 -0
- package/types/frame-kit-ui-ng-ui-toast.d.ts +56 -0
- package/types/frame-kit-ui-ng-ui-user-menu.d.ts +87 -0
- package/types/frame-kit-ui-ng-ui-wizard-dialog.d.ts +116 -0
- package/types/frame-kit-ui-ng.d.ts +53 -0
- package/ui/accordion/README.md +261 -0
- package/ui/alert/README.md +211 -0
- package/ui/avatar/README.md +167 -0
- package/ui/avatar-stack/README.md +164 -0
- package/ui/badge/README.md +162 -0
- package/ui/breadcrumb/README.md +240 -0
- package/ui/button/README.md +184 -0
- package/ui/callout/README.md +159 -0
- package/ui/card/README.md +174 -0
- package/ui/copyable-field/README.md +235 -0
- package/ui/data-table/README.md +408 -0
- package/ui/dialog/README.md +222 -0
- package/ui/drawer/README.md +274 -0
- package/ui/dropdown-menu/README.md +336 -0
- package/ui/editable-field/README.md +171 -0
- package/ui/icon-badge/README.md +131 -0
- package/ui/icon-list/README.md +205 -0
- package/ui/inline-edit/README.md +135 -0
- package/ui/list-editor/README.md +162 -0
- package/ui/loader/README.md +160 -0
- package/ui/menu-item/README.md +204 -0
- package/ui/nav-brand/README.md +111 -0
- package/ui/nav-group/README.md +145 -0
- package/ui/nav-separator/README.md +44 -0
- package/ui/node-tree/README.md +278 -0
- package/ui/node-tree-breadcrumb/README.md +164 -0
- package/ui/note/README.md +146 -0
- package/ui/numbered-list/README.md +187 -0
- package/ui/pagination/README.md +174 -0
- package/ui/progress-bar/README.md +223 -0
- package/ui/sidenav-link/README.md +214 -0
- package/ui/tabs/README.md +204 -0
- package/ui/timeline/README.md +285 -0
- package/ui/toast/README.md +243 -0
- package/ui/user-menu/README.md +260 -0
- package/ui/wizard-dialog/README.md +283 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, output, viewChild, computed, HostBinding, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { AvatarComponent } from '@frame-kit/ui-ng/ui/avatar';
|
|
4
|
+
import { DropdownMenuComponent, DropdownTriggerDirective, DropdownPanelDirective } from '@frame-kit/ui-ng/ui/dropdown-menu';
|
|
5
|
+
import { MenuItemComponent, MenuSeparatorComponent } from '@frame-kit/ui-ng/ui/menu-item';
|
|
6
|
+
|
|
7
|
+
class UserMenuComponent {
|
|
8
|
+
// ===== IDENTITY =====
|
|
9
|
+
/** Full display name of the user shown in the avatar and optional info section. */
|
|
10
|
+
name = input.required(...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
11
|
+
/** User's email address shown in the optional info section. */
|
|
12
|
+
email = input(null, ...(ngDevMode ? [{ debugName: "email" }] : /* istanbul ignore next */ []));
|
|
13
|
+
/** URL of the user's avatar image. */
|
|
14
|
+
avatarUrl = input(null, ...(ngDevMode ? [{ debugName: "avatarUrl" }] : /* istanbul ignore next */ []));
|
|
15
|
+
/** Explicit two-character initials that override the name-derived fallback. */
|
|
16
|
+
initials = input(null, ...(ngDevMode ? [{ debugName: "initials" }] : /* istanbul ignore next */ []));
|
|
17
|
+
/** Optional user ID displayed in the info section for debugging or display. */
|
|
18
|
+
userId = input(null, ...(ngDevMode ? [{ debugName: "userId" }] : /* istanbul ignore next */ []));
|
|
19
|
+
// ===== STATUS =====
|
|
20
|
+
/** Online/offline/away status reflected on the avatar indicator dot. */
|
|
21
|
+
status = input(null, ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
22
|
+
/** When true, renders the status indicator dot on the avatar. */
|
|
23
|
+
showStatus = input(false, ...(ngDevMode ? [{ debugName: "showStatus" }] : /* istanbul ignore next */ []));
|
|
24
|
+
// ===== MENU =====
|
|
25
|
+
/** Array of menu item configurations rendered in the dropdown. */
|
|
26
|
+
menuItems = input([], ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
|
|
27
|
+
/** Preferred placement of the dropdown panel relative to the trigger. */
|
|
28
|
+
placement = input('bottom-end', ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
|
|
29
|
+
// ===== DISPLAY =====
|
|
30
|
+
/** Size of the avatar trigger. */
|
|
31
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
32
|
+
/** Layout variant — "dropdown" renders a full avatar menu, "compact" renders a minimal trigger. */
|
|
33
|
+
variant = input('dropdown', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
34
|
+
/** When true, renders the user's display name next to the avatar. */
|
|
35
|
+
showName = input(false, ...(ngDevMode ? [{ debugName: "showName" }] : /* istanbul ignore next */ []));
|
|
36
|
+
/** When true, renders the user's email next to the avatar. */
|
|
37
|
+
showEmail = input(false, ...(ngDevMode ? [{ debugName: "showEmail" }] : /* istanbul ignore next */ []));
|
|
38
|
+
/** When true, renders a chevron indicator showing the menu is expandable. */
|
|
39
|
+
showChevron = input(true, ...(ngDevMode ? [{ debugName: "showChevron" }] : /* istanbul ignore next */ []));
|
|
40
|
+
/** Side where the name/email info block appears relative to the avatar. */
|
|
41
|
+
infoPlacement = input('end', ...(ngDevMode ? [{ debugName: "infoPlacement" }] : /* istanbul ignore next */ []));
|
|
42
|
+
/** Optional badge text overlaid on the avatar. */
|
|
43
|
+
badge = input(null, ...(ngDevMode ? [{ debugName: "badge" }] : /* istanbul ignore next */ []));
|
|
44
|
+
/** When true, prevents the menu from opening. */
|
|
45
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
46
|
+
/** When true, shows a loading state on the trigger. */
|
|
47
|
+
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
48
|
+
// ===== BASE PROPS =====
|
|
49
|
+
className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
50
|
+
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
51
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
52
|
+
// ===== OUTPUTS =====
|
|
53
|
+
/** Fires when the user clicks the avatar trigger to open the menu. */
|
|
54
|
+
avatarClick = output();
|
|
55
|
+
/** Fires when the dropdown menu opens. */
|
|
56
|
+
menuOpen = output();
|
|
57
|
+
/** Fires when the dropdown menu closes. */
|
|
58
|
+
menuClose = output();
|
|
59
|
+
/** Fires when the user selects a menu item, emitting the selected `MenuItem`. */
|
|
60
|
+
menuItemClick = output();
|
|
61
|
+
/** Fires when the user selects the item with `value === "logout"`. */
|
|
62
|
+
logoutClick = output();
|
|
63
|
+
// ===== REFS =====
|
|
64
|
+
dropdownRef = viewChild(DropdownMenuComponent, ...(ngDevMode ? [{ debugName: "dropdownRef" }] : /* istanbul ignore next */ []));
|
|
65
|
+
// ===== COMPUTED =====
|
|
66
|
+
isOpen = computed(() => this.dropdownRef()?.isOpen() ?? false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
67
|
+
classes = computed(() => {
|
|
68
|
+
return [
|
|
69
|
+
'fk-user-menu',
|
|
70
|
+
`fk-user-menu--${this.size()}`,
|
|
71
|
+
`fk-user-menu--${this.variant()}`,
|
|
72
|
+
this.infoPlacement() === 'start' ? 'fk-user-menu--info-start' : '',
|
|
73
|
+
this.isOpen() ? 'fk-user-menu--open' : '',
|
|
74
|
+
this.disabled() ? 'fk-user-menu--disabled' : '',
|
|
75
|
+
this.loading() ? 'fk-user-menu--loading' : '',
|
|
76
|
+
this.className(),
|
|
77
|
+
]
|
|
78
|
+
.filter(Boolean)
|
|
79
|
+
.join(' ');
|
|
80
|
+
}, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
81
|
+
get hostClass() {
|
|
82
|
+
return this.classes();
|
|
83
|
+
}
|
|
84
|
+
get hostId() {
|
|
85
|
+
return this.id();
|
|
86
|
+
}
|
|
87
|
+
// ===== ACTIONS =====
|
|
88
|
+
/** Emits `menuItemClick` (and `logoutClick` when applicable) for the given menu item. */
|
|
89
|
+
selectItem(item) {
|
|
90
|
+
if (item.disabled) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
this.menuItemClick.emit(item);
|
|
94
|
+
if (item.value === 'logout') {
|
|
95
|
+
this.logoutClick.emit();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
onMenuOpen() {
|
|
99
|
+
this.avatarClick.emit();
|
|
100
|
+
this.menuOpen.emit();
|
|
101
|
+
}
|
|
102
|
+
onMenuClose() {
|
|
103
|
+
this.menuClose.emit();
|
|
104
|
+
}
|
|
105
|
+
/** Opens the user-menu dropdown programmatically. */
|
|
106
|
+
open() {
|
|
107
|
+
this.dropdownRef()?.open();
|
|
108
|
+
}
|
|
109
|
+
/** Closes the user-menu dropdown programmatically. */
|
|
110
|
+
close() {
|
|
111
|
+
this.dropdownRef()?.close();
|
|
112
|
+
}
|
|
113
|
+
/** Toggles the user-menu dropdown programmatically. */
|
|
114
|
+
toggle() {
|
|
115
|
+
this.dropdownRef()?.toggle();
|
|
116
|
+
}
|
|
117
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: UserMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
118
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: UserMenuComponent, isStandalone: true, selector: "fk-user-menu", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, email: { classPropertyName: "email", publicName: "email", isSignal: true, isRequired: false, transformFunction: null }, avatarUrl: { classPropertyName: "avatarUrl", publicName: "avatarUrl", isSignal: true, isRequired: false, transformFunction: null }, initials: { classPropertyName: "initials", publicName: "initials", isSignal: true, isRequired: false, transformFunction: null }, userId: { classPropertyName: "userId", publicName: "userId", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, showStatus: { classPropertyName: "showStatus", publicName: "showStatus", isSignal: true, isRequired: false, transformFunction: null }, menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, showName: { classPropertyName: "showName", publicName: "showName", isSignal: true, isRequired: false, transformFunction: null }, showEmail: { classPropertyName: "showEmail", publicName: "showEmail", isSignal: true, isRequired: false, transformFunction: null }, showChevron: { classPropertyName: "showChevron", publicName: "showChevron", isSignal: true, isRequired: false, transformFunction: null }, infoPlacement: { classPropertyName: "infoPlacement", publicName: "infoPlacement", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { avatarClick: "avatarClick", menuOpen: "menuOpen", menuClose: "menuClose", menuItemClick: "menuItemClick", logoutClick: "logoutClick" }, host: { properties: { "class": "this.hostClass", "attr.id": "this.hostId" } }, viewQueries: [{ propertyName: "dropdownRef", first: true, predicate: DropdownMenuComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<fk-dropdown-menu\n [placement]=\"placement()\"\n [disabled]=\"disabled() || loading()\"\n [ariaLabel]=\"'Menu for ' + name()\"\n (menuOpen)=\"onMenuOpen()\"\n (menuClose)=\"onMenuClose()\"\n>\n <!-- Trigger button -->\n <button\n fkDropdownTrigger\n class=\"fk-user-menu__trigger\"\n type=\"button\"\n [disabled]=\"disabled() || loading()\"\n [attr.aria-label]=\"ariaLabel() ?? 'User menu for ' + name()\"\n >\n <!-- Avatar -->\n <fk-avatar\n [name]=\"name()\"\n [avatarUrl]=\"avatarUrl()\"\n [initials]=\"initials()\"\n [size]=\"size()\"\n [status]=\"status()\"\n [showStatus]=\"showStatus()\"\n />\n\n <!-- Name & email block -->\n @if (showName() || showEmail()) {\n <span class=\"fk-user-menu__info\">\n @if (showName()) {\n <span class=\"fk-user-menu__name\">{{ name() }}</span>\n }\n @if (showEmail() && email()) {\n <span class=\"fk-user-menu__email\">{{ email() }}</span>\n }\n </span>\n }\n\n <!-- Badge -->\n @if (badge()) {\n <span class=\"fk-user-menu__badge\">{{ badge() }}</span>\n }\n\n <!-- Chevron -->\n @if (showChevron()) {\n <span\n class=\"fk-user-menu__chevron\"\n [class.fk-user-menu__chevron--open]=\"isOpen()\"\n aria-hidden=\"true\"\n >\n <svg\n class=\"fk-user-menu__chevron-svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 18 18\"\n >\n <path\n d=\"M4.5 6.75L9 11.25L13.5 6.75\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n fill=\"none\"\n />\n </svg>\n </span>\n }\n </button>\n\n <!-- Panel content -->\n <ng-template fkDropdownPanel>\n <!-- User header inside panel (popover variant) -->\n @if (variant() === 'popover') {\n <div class=\"fk-user-menu__panel-header\">\n <span class=\"fk-user-menu__panel-name\">{{ name() }}</span>\n @if (email()) {\n <span class=\"fk-user-menu__panel-email\">{{ email() }}</span>\n }\n </div>\n }\n\n <!-- Menu items -->\n @for (item of menuItems(); track item.value) {\n @if (item.separator) {\n <fk-menu-separator />\n } @else {\n <fk-menu-item\n [icon]=\"item.icon ?? null\"\n [danger]=\"item.danger ?? false\"\n [disabled]=\"item.disabled ?? false\"\n (itemClick)=\"selectItem(item)\"\n >\n {{ item.label }}\n </fk-menu-item>\n }\n }\n </ng-template>\n</fk-dropdown-menu>\n", styles: [":host{display:inline-block;position:relative;--fk-dropdown-menu-panel-z: var(--fk-user-menu-panel-z, 100);--fk-dropdown-menu-panel-min-width: var( --fk-user-menu-panel-min-width, 12rem );--fk-dropdown-menu-panel-padding: var( --fk-user-menu-panel-padding, var(--fk-rhythm-1, .25rem) );--fk-dropdown-menu-panel-radius: var( --fk-user-menu-panel-radius, var(--fk-radius-lg, .75rem) );--fk-dropdown-menu-panel-bg: var( --fk-user-menu-panel-bg, var(--fk-color-surface, #ffffff) );--fk-dropdown-menu-panel-border: var( --fk-user-menu-panel-border, var(--fk-color-border, #d9e2ee) );--fk-dropdown-menu-panel-shadow: var( --fk-user-menu-panel-shadow, 0 4px 16px rgba(0, 0, 0, .08), 0 1px 4px rgba(0, 0, 0, .04) );--fk-menu-item-gap: var(--fk-user-menu-item-gap, var(--fk-rhythm-2, .5rem));--fk-menu-item-padding: var( --fk-user-menu-item-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem) );--fk-menu-item-radius: var( --fk-user-menu-item-radius, var(--fk-radius-md, .375rem) );--fk-menu-item-font-family: var( --fk-user-menu-item-font-family, var(--fk-font-family-base) );--fk-menu-item-font-size: var(--fk-user-menu-item-font-size, .875rem);--fk-menu-item-color: var( --fk-user-menu-item-color, var(--fk-color-text, #1f2d3d) );--fk-menu-item-bg-hover: var( --fk-user-menu-item-bg-hover, var(--fk-color-surface-muted, #f7f9fb) );--fk-menu-item-danger-color: var( --fk-user-menu-item-danger-color, var(--fk-color-danger, #e02424) );--fk-menu-item-danger-bg-hover: var( --fk-user-menu-item-danger-bg-hover, #fef2f2 );--fk-menu-item-focus-ring: var( --fk-user-menu-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)) );--fk-menu-separator-color: var( --fk-user-menu-separator-color, var(--fk-color-border, #d9e2ee) )}.fk-user-menu__trigger{display:inline-flex;align-items:center;gap:var(--fk-user-menu-trigger-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-user-menu-trigger-padding, var(--fk-rhythm-1, .25rem));border:none;border-radius:var(--fk-user-menu-trigger-radius, var(--fk-radius-md, .375rem));background:var(--fk-user-menu-trigger-bg, transparent);cursor:pointer;transition:background-color .15s ease}.fk-user-menu__trigger:hover{background-color:var(--fk-user-menu-trigger-bg-hover, var(--fk-color-surface-muted, #f7f9fb))}.fk-user-menu__trigger:focus-visible{outline:none;box-shadow:var(--fk-user-menu-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-user-menu__trigger:disabled{opacity:var(--fk-user-menu-opacity-disabled, .6);cursor:not-allowed}.fk-user-menu__info{display:flex;flex-direction:column;align-items:flex-start;text-align:left;line-height:1.3}.fk-user-menu__name{font-family:var(--fk-user-menu-name-font-family, var(--fk-font-family-base));font-size:var(--fk-user-menu-name-font-size, .875rem);font-weight:var(--fk-user-menu-name-font-weight, var(--fk-font-weight-semibold, 600));color:var(--fk-user-menu-name-color, var(--fk-color-text, #1f2d3d))}.fk-user-menu__email{font-family:var(--fk-user-menu-email-font-family, var(--fk-font-family-base));font-size:var(--fk-user-menu-email-font-size, .75rem);color:var(--fk-user-menu-email-color, var(--fk-color-muted, #8a98a8))}.fk-user-menu__badge{display:inline-flex;align-items:center;padding:.125rem .5rem;border-radius:var(--fk-user-menu-badge-radius, var(--fk-radius-full, 9999px));background-color:var(--fk-user-menu-badge-bg, var(--fk-color-primary, #0a84ff));color:var(--fk-user-menu-badge-color, var(--fk-color-surface, #ffffff));font-family:var(--fk-user-menu-badge-font-family, var(--fk-font-family-base));font-size:var(--fk-user-menu-badge-font-size, .625rem);font-weight:var(--fk-user-menu-badge-font-weight, var(--fk-font-weight-semibold, 600));text-transform:uppercase;letter-spacing:.04em;line-height:1.4}.fk-user-menu__chevron{display:inline-flex;color:var(--fk-user-menu-chevron-color, var(--fk-color-muted, #8a98a8));transition:transform .15s ease}.fk-user-menu__chevron--open{transform:rotate(180deg)}.fk-user-menu__chevron-svg{display:block}.fk-user-menu__panel-header{display:flex;flex-direction:column;padding:var(--fk-rhythm-3, .75rem) var(--fk-rhythm-3, .75rem) var(--fk-rhythm-2, .5rem);border-bottom:1px solid var(--fk-user-menu-separator-color, var(--fk-color-border, #d9e2ee));margin-bottom:var(--fk-rhythm-1, .25rem)}.fk-user-menu__panel-name{font-family:var(--fk-user-menu-name-font-family, var(--fk-font-family-base));font-size:var(--fk-user-menu-name-font-size, .875rem);font-weight:var(--fk-user-menu-name-font-weight, var(--fk-font-weight-semibold, 600));color:var(--fk-user-menu-name-color, var(--fk-color-text, #1f2d3d))}.fk-user-menu__panel-email{font-family:var(--fk-user-menu-email-font-family, var(--fk-font-family-base));font-size:var(--fk-user-menu-email-font-size, .75rem);color:var(--fk-user-menu-email-color, var(--fk-color-muted, #8a98a8));margin-top:.125rem}:host.fk-user-menu--info-start .fk-user-menu__info{order:-1;align-items:flex-end;text-align:right}:host.fk-user-menu--disabled{pointer-events:none}\n"], dependencies: [{ kind: "component", type: AvatarComponent, selector: "fk-avatar", inputs: ["name", "avatarUrl", "initials", "status", "showStatus", "size", "className", "id", "ariaLabel"] }, { kind: "component", type: DropdownMenuComponent, selector: "fk-dropdown-menu", inputs: ["placement", "disabled", "portal", "panelClass", "ariaLabel", "className", "id"], outputs: ["menuOpen", "menuClose"] }, { kind: "directive", type: DropdownTriggerDirective, selector: "[fkDropdownTrigger]" }, { kind: "directive", type: DropdownPanelDirective, selector: "[fkDropdownPanel]" }, { kind: "component", type: MenuItemComponent, selector: "fk-menu-item", inputs: ["icon", "danger", "disabled"], outputs: ["itemClick"] }, { kind: "component", type: MenuSeparatorComponent, selector: "fk-menu-separator" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
119
|
+
}
|
|
120
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: UserMenuComponent, decorators: [{
|
|
121
|
+
type: Component,
|
|
122
|
+
args: [{ selector: 'fk-user-menu', standalone: true, imports: [
|
|
123
|
+
AvatarComponent,
|
|
124
|
+
DropdownMenuComponent,
|
|
125
|
+
DropdownTriggerDirective,
|
|
126
|
+
DropdownPanelDirective,
|
|
127
|
+
MenuItemComponent,
|
|
128
|
+
MenuSeparatorComponent,
|
|
129
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<fk-dropdown-menu\n [placement]=\"placement()\"\n [disabled]=\"disabled() || loading()\"\n [ariaLabel]=\"'Menu for ' + name()\"\n (menuOpen)=\"onMenuOpen()\"\n (menuClose)=\"onMenuClose()\"\n>\n <!-- Trigger button -->\n <button\n fkDropdownTrigger\n class=\"fk-user-menu__trigger\"\n type=\"button\"\n [disabled]=\"disabled() || loading()\"\n [attr.aria-label]=\"ariaLabel() ?? 'User menu for ' + name()\"\n >\n <!-- Avatar -->\n <fk-avatar\n [name]=\"name()\"\n [avatarUrl]=\"avatarUrl()\"\n [initials]=\"initials()\"\n [size]=\"size()\"\n [status]=\"status()\"\n [showStatus]=\"showStatus()\"\n />\n\n <!-- Name & email block -->\n @if (showName() || showEmail()) {\n <span class=\"fk-user-menu__info\">\n @if (showName()) {\n <span class=\"fk-user-menu__name\">{{ name() }}</span>\n }\n @if (showEmail() && email()) {\n <span class=\"fk-user-menu__email\">{{ email() }}</span>\n }\n </span>\n }\n\n <!-- Badge -->\n @if (badge()) {\n <span class=\"fk-user-menu__badge\">{{ badge() }}</span>\n }\n\n <!-- Chevron -->\n @if (showChevron()) {\n <span\n class=\"fk-user-menu__chevron\"\n [class.fk-user-menu__chevron--open]=\"isOpen()\"\n aria-hidden=\"true\"\n >\n <svg\n class=\"fk-user-menu__chevron-svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 18 18\"\n >\n <path\n d=\"M4.5 6.75L9 11.25L13.5 6.75\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n fill=\"none\"\n />\n </svg>\n </span>\n }\n </button>\n\n <!-- Panel content -->\n <ng-template fkDropdownPanel>\n <!-- User header inside panel (popover variant) -->\n @if (variant() === 'popover') {\n <div class=\"fk-user-menu__panel-header\">\n <span class=\"fk-user-menu__panel-name\">{{ name() }}</span>\n @if (email()) {\n <span class=\"fk-user-menu__panel-email\">{{ email() }}</span>\n }\n </div>\n }\n\n <!-- Menu items -->\n @for (item of menuItems(); track item.value) {\n @if (item.separator) {\n <fk-menu-separator />\n } @else {\n <fk-menu-item\n [icon]=\"item.icon ?? null\"\n [danger]=\"item.danger ?? false\"\n [disabled]=\"item.disabled ?? false\"\n (itemClick)=\"selectItem(item)\"\n >\n {{ item.label }}\n </fk-menu-item>\n }\n }\n </ng-template>\n</fk-dropdown-menu>\n", styles: [":host{display:inline-block;position:relative;--fk-dropdown-menu-panel-z: var(--fk-user-menu-panel-z, 100);--fk-dropdown-menu-panel-min-width: var( --fk-user-menu-panel-min-width, 12rem );--fk-dropdown-menu-panel-padding: var( --fk-user-menu-panel-padding, var(--fk-rhythm-1, .25rem) );--fk-dropdown-menu-panel-radius: var( --fk-user-menu-panel-radius, var(--fk-radius-lg, .75rem) );--fk-dropdown-menu-panel-bg: var( --fk-user-menu-panel-bg, var(--fk-color-surface, #ffffff) );--fk-dropdown-menu-panel-border: var( --fk-user-menu-panel-border, var(--fk-color-border, #d9e2ee) );--fk-dropdown-menu-panel-shadow: var( --fk-user-menu-panel-shadow, 0 4px 16px rgba(0, 0, 0, .08), 0 1px 4px rgba(0, 0, 0, .04) );--fk-menu-item-gap: var(--fk-user-menu-item-gap, var(--fk-rhythm-2, .5rem));--fk-menu-item-padding: var( --fk-user-menu-item-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem) );--fk-menu-item-radius: var( --fk-user-menu-item-radius, var(--fk-radius-md, .375rem) );--fk-menu-item-font-family: var( --fk-user-menu-item-font-family, var(--fk-font-family-base) );--fk-menu-item-font-size: var(--fk-user-menu-item-font-size, .875rem);--fk-menu-item-color: var( --fk-user-menu-item-color, var(--fk-color-text, #1f2d3d) );--fk-menu-item-bg-hover: var( --fk-user-menu-item-bg-hover, var(--fk-color-surface-muted, #f7f9fb) );--fk-menu-item-danger-color: var( --fk-user-menu-item-danger-color, var(--fk-color-danger, #e02424) );--fk-menu-item-danger-bg-hover: var( --fk-user-menu-item-danger-bg-hover, #fef2f2 );--fk-menu-item-focus-ring: var( --fk-user-menu-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)) );--fk-menu-separator-color: var( --fk-user-menu-separator-color, var(--fk-color-border, #d9e2ee) )}.fk-user-menu__trigger{display:inline-flex;align-items:center;gap:var(--fk-user-menu-trigger-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-user-menu-trigger-padding, var(--fk-rhythm-1, .25rem));border:none;border-radius:var(--fk-user-menu-trigger-radius, var(--fk-radius-md, .375rem));background:var(--fk-user-menu-trigger-bg, transparent);cursor:pointer;transition:background-color .15s ease}.fk-user-menu__trigger:hover{background-color:var(--fk-user-menu-trigger-bg-hover, var(--fk-color-surface-muted, #f7f9fb))}.fk-user-menu__trigger:focus-visible{outline:none;box-shadow:var(--fk-user-menu-focus-ring, var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18)))}.fk-user-menu__trigger:disabled{opacity:var(--fk-user-menu-opacity-disabled, .6);cursor:not-allowed}.fk-user-menu__info{display:flex;flex-direction:column;align-items:flex-start;text-align:left;line-height:1.3}.fk-user-menu__name{font-family:var(--fk-user-menu-name-font-family, var(--fk-font-family-base));font-size:var(--fk-user-menu-name-font-size, .875rem);font-weight:var(--fk-user-menu-name-font-weight, var(--fk-font-weight-semibold, 600));color:var(--fk-user-menu-name-color, var(--fk-color-text, #1f2d3d))}.fk-user-menu__email{font-family:var(--fk-user-menu-email-font-family, var(--fk-font-family-base));font-size:var(--fk-user-menu-email-font-size, .75rem);color:var(--fk-user-menu-email-color, var(--fk-color-muted, #8a98a8))}.fk-user-menu__badge{display:inline-flex;align-items:center;padding:.125rem .5rem;border-radius:var(--fk-user-menu-badge-radius, var(--fk-radius-full, 9999px));background-color:var(--fk-user-menu-badge-bg, var(--fk-color-primary, #0a84ff));color:var(--fk-user-menu-badge-color, var(--fk-color-surface, #ffffff));font-family:var(--fk-user-menu-badge-font-family, var(--fk-font-family-base));font-size:var(--fk-user-menu-badge-font-size, .625rem);font-weight:var(--fk-user-menu-badge-font-weight, var(--fk-font-weight-semibold, 600));text-transform:uppercase;letter-spacing:.04em;line-height:1.4}.fk-user-menu__chevron{display:inline-flex;color:var(--fk-user-menu-chevron-color, var(--fk-color-muted, #8a98a8));transition:transform .15s ease}.fk-user-menu__chevron--open{transform:rotate(180deg)}.fk-user-menu__chevron-svg{display:block}.fk-user-menu__panel-header{display:flex;flex-direction:column;padding:var(--fk-rhythm-3, .75rem) var(--fk-rhythm-3, .75rem) var(--fk-rhythm-2, .5rem);border-bottom:1px solid var(--fk-user-menu-separator-color, var(--fk-color-border, #d9e2ee));margin-bottom:var(--fk-rhythm-1, .25rem)}.fk-user-menu__panel-name{font-family:var(--fk-user-menu-name-font-family, var(--fk-font-family-base));font-size:var(--fk-user-menu-name-font-size, .875rem);font-weight:var(--fk-user-menu-name-font-weight, var(--fk-font-weight-semibold, 600));color:var(--fk-user-menu-name-color, var(--fk-color-text, #1f2d3d))}.fk-user-menu__panel-email{font-family:var(--fk-user-menu-email-font-family, var(--fk-font-family-base));font-size:var(--fk-user-menu-email-font-size, .75rem);color:var(--fk-user-menu-email-color, var(--fk-color-muted, #8a98a8));margin-top:.125rem}:host.fk-user-menu--info-start .fk-user-menu__info{order:-1;align-items:flex-end;text-align:right}:host.fk-user-menu--disabled{pointer-events:none}\n"] }]
|
|
130
|
+
}], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], email: [{ type: i0.Input, args: [{ isSignal: true, alias: "email", required: false }] }], avatarUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarUrl", required: false }] }], initials: [{ type: i0.Input, args: [{ isSignal: true, alias: "initials", required: false }] }], userId: [{ type: i0.Input, args: [{ isSignal: true, alias: "userId", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], showStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "showStatus", required: false }] }], menuItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuItems", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], showName: [{ type: i0.Input, args: [{ isSignal: true, alias: "showName", required: false }] }], showEmail: [{ type: i0.Input, args: [{ isSignal: true, alias: "showEmail", required: false }] }], showChevron: [{ type: i0.Input, args: [{ isSignal: true, alias: "showChevron", required: false }] }], infoPlacement: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoPlacement", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", 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 }] }], avatarClick: [{ type: i0.Output, args: ["avatarClick"] }], menuOpen: [{ type: i0.Output, args: ["menuOpen"] }], menuClose: [{ type: i0.Output, args: ["menuClose"] }], menuItemClick: [{ type: i0.Output, args: ["menuItemClick"] }], logoutClick: [{ type: i0.Output, args: ["logoutClick"] }], dropdownRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => DropdownMenuComponent), { isSignal: true }] }], hostClass: [{
|
|
131
|
+
type: HostBinding,
|
|
132
|
+
args: ['class']
|
|
133
|
+
}], hostId: [{
|
|
134
|
+
type: HostBinding,
|
|
135
|
+
args: ['attr.id']
|
|
136
|
+
}] } });
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Generated bundle index. Do not edit.
|
|
140
|
+
*/
|
|
141
|
+
|
|
142
|
+
export { UserMenuComponent };
|
|
143
|
+
//# sourceMappingURL=frame-kit-ui-ng-ui-user-menu.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-user-menu.mjs","sources":["../../../../packages/ui-ng/ui/user-menu/user-menu.component.ts","../../../../packages/ui-ng/ui/user-menu/user-menu.component.html","../../../../packages/ui-ng/ui/user-menu/frame-kit-ui-ng-ui-user-menu.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n HostBinding,\n input,\n output,\n viewChild,\n} from '@angular/core';\n\nimport { AvatarComponent } from '@frame-kit/ui-ng/ui/avatar';\nimport type { AvatarSize, AvatarStatus } from '@frame-kit/ui-ng/ui/avatar';\nimport { DropdownMenuComponent } from '@frame-kit/ui-ng/ui/dropdown-menu';\nimport { DropdownPanelDirective } from '@frame-kit/ui-ng/ui/dropdown-menu';\nimport { DropdownTriggerDirective } from '@frame-kit/ui-ng/ui/dropdown-menu';\nimport { MenuItemComponent } from '@frame-kit/ui-ng/ui/menu-item';\nimport { MenuSeparatorComponent } from '@frame-kit/ui-ng/ui/menu-item';\nimport type {\n InfoPlacement,\n MenuItem,\n MenuPlacement,\n UserMenuVariant,\n} from './user-menu.types';\n\n@Component({\n selector: 'fk-user-menu',\n standalone: true,\n imports: [\n AvatarComponent,\n DropdownMenuComponent,\n DropdownTriggerDirective,\n DropdownPanelDirective,\n MenuItemComponent,\n MenuSeparatorComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './user-menu.component.html',\n styleUrl: './user-menu.component.scss',\n})\nexport class UserMenuComponent {\n // ===== IDENTITY =====\n /** Full display name of the user shown in the avatar and optional info section. */\n readonly name = input.required<string>();\n /** User's email address shown in the optional info section. */\n readonly email = input<string | null>(null);\n /** URL of the user's avatar image. */\n readonly avatarUrl = input<string | null>(null);\n /** Explicit two-character initials that override the name-derived fallback. */\n readonly initials = input<string | null>(null);\n /** Optional user ID displayed in the info section for debugging or display. */\n readonly userId = input<string | null>(null);\n\n // ===== STATUS =====\n /** Online/offline/away status reflected on the avatar indicator dot. */\n readonly status = input<AvatarStatus | null>(null);\n /** When true, renders the status indicator dot on the avatar. */\n readonly showStatus = input<boolean>(false);\n\n // ===== MENU =====\n /** Array of menu item configurations rendered in the dropdown. */\n readonly menuItems = input<MenuItem[]>([]);\n /** Preferred placement of the dropdown panel relative to the trigger. */\n readonly placement = input<MenuPlacement>('bottom-end');\n\n // ===== DISPLAY =====\n /** Size of the avatar trigger. */\n readonly size = input<AvatarSize>('md');\n /** Layout variant — \"dropdown\" renders a full avatar menu, \"compact\" renders a minimal trigger. */\n readonly variant = input<UserMenuVariant>('dropdown');\n /** When true, renders the user's display name next to the avatar. */\n readonly showName = input<boolean>(false);\n /** When true, renders the user's email next to the avatar. */\n readonly showEmail = input<boolean>(false);\n /** When true, renders a chevron indicator showing the menu is expandable. */\n readonly showChevron = input<boolean>(true);\n /** Side where the name/email info block appears relative to the avatar. */\n readonly infoPlacement = input<InfoPlacement>('end');\n /** Optional badge text overlaid on the avatar. */\n readonly badge = input<string | null>(null);\n /** When true, prevents the menu from opening. */\n readonly disabled = input<boolean>(false);\n /** When true, shows a loading state on the trigger. */\n readonly loading = input<boolean>(false);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n readonly id = input<string | null>(null);\n readonly ariaLabel = input<string | null>(null);\n\n // ===== OUTPUTS =====\n /** Fires when the user clicks the avatar trigger to open the menu. */\n readonly avatarClick = output<void>();\n /** Fires when the dropdown menu opens. */\n readonly menuOpen = output<void>();\n /** Fires when the dropdown menu closes. */\n readonly menuClose = output<void>();\n /** Fires when the user selects a menu item, emitting the selected `MenuItem`. */\n readonly menuItemClick = output<MenuItem>();\n /** Fires when the user selects the item with `value === \"logout\"`. */\n readonly logoutClick = output<void>();\n\n // ===== REFS =====\n readonly dropdownRef = viewChild(DropdownMenuComponent);\n\n // ===== COMPUTED =====\n\n readonly isOpen = computed(() => this.dropdownRef()?.isOpen() ?? false);\n\n readonly classes = computed(() => {\n return [\n 'fk-user-menu',\n `fk-user-menu--${this.size()}`,\n `fk-user-menu--${this.variant()}`,\n this.infoPlacement() === 'start' ? 'fk-user-menu--info-start' : '',\n this.isOpen() ? 'fk-user-menu--open' : '',\n this.disabled() ? 'fk-user-menu--disabled' : '',\n this.loading() ? 'fk-user-menu--loading' : '',\n this.className(),\n ]\n .filter(Boolean)\n .join(' ');\n });\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n @HostBinding('attr.id')\n get hostId(): string | null {\n return this.id();\n }\n\n // ===== ACTIONS =====\n\n /** Emits `menuItemClick` (and `logoutClick` when applicable) for the given menu item. */\n selectItem(item: MenuItem): void {\n if (item.disabled) {\n return;\n }\n\n this.menuItemClick.emit(item);\n\n if (item.value === 'logout') {\n this.logoutClick.emit();\n }\n }\n\n onMenuOpen(): void {\n this.avatarClick.emit();\n this.menuOpen.emit();\n }\n\n onMenuClose(): void {\n this.menuClose.emit();\n }\n\n /** Opens the user-menu dropdown programmatically. */\n open(): void {\n this.dropdownRef()?.open();\n }\n\n /** Closes the user-menu dropdown programmatically. */\n close(): void {\n this.dropdownRef()?.close();\n }\n\n /** Toggles the user-menu dropdown programmatically. */\n toggle(): void {\n this.dropdownRef()?.toggle();\n }\n}\n","<fk-dropdown-menu\n [placement]=\"placement()\"\n [disabled]=\"disabled() || loading()\"\n [ariaLabel]=\"'Menu for ' + name()\"\n (menuOpen)=\"onMenuOpen()\"\n (menuClose)=\"onMenuClose()\"\n>\n <!-- Trigger button -->\n <button\n fkDropdownTrigger\n class=\"fk-user-menu__trigger\"\n type=\"button\"\n [disabled]=\"disabled() || loading()\"\n [attr.aria-label]=\"ariaLabel() ?? 'User menu for ' + name()\"\n >\n <!-- Avatar -->\n <fk-avatar\n [name]=\"name()\"\n [avatarUrl]=\"avatarUrl()\"\n [initials]=\"initials()\"\n [size]=\"size()\"\n [status]=\"status()\"\n [showStatus]=\"showStatus()\"\n />\n\n <!-- Name & email block -->\n @if (showName() || showEmail()) {\n <span class=\"fk-user-menu__info\">\n @if (showName()) {\n <span class=\"fk-user-menu__name\">{{ name() }}</span>\n }\n @if (showEmail() && email()) {\n <span class=\"fk-user-menu__email\">{{ email() }}</span>\n }\n </span>\n }\n\n <!-- Badge -->\n @if (badge()) {\n <span class=\"fk-user-menu__badge\">{{ badge() }}</span>\n }\n\n <!-- Chevron -->\n @if (showChevron()) {\n <span\n class=\"fk-user-menu__chevron\"\n [class.fk-user-menu__chevron--open]=\"isOpen()\"\n aria-hidden=\"true\"\n >\n <svg\n class=\"fk-user-menu__chevron-svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 18 18\"\n >\n <path\n d=\"M4.5 6.75L9 11.25L13.5 6.75\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n fill=\"none\"\n />\n </svg>\n </span>\n }\n </button>\n\n <!-- Panel content -->\n <ng-template fkDropdownPanel>\n <!-- User header inside panel (popover variant) -->\n @if (variant() === 'popover') {\n <div class=\"fk-user-menu__panel-header\">\n <span class=\"fk-user-menu__panel-name\">{{ name() }}</span>\n @if (email()) {\n <span class=\"fk-user-menu__panel-email\">{{ email() }}</span>\n }\n </div>\n }\n\n <!-- Menu items -->\n @for (item of menuItems(); track item.value) {\n @if (item.separator) {\n <fk-menu-separator />\n } @else {\n <fk-menu-item\n [icon]=\"item.icon ?? null\"\n [danger]=\"item.danger ?? false\"\n [disabled]=\"item.disabled ?? false\"\n (itemClick)=\"selectItem(item)\"\n >\n {{ item.label }}\n </fk-menu-item>\n }\n }\n </ng-template>\n</fk-dropdown-menu>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { signal, computed, inject, Injector, viewChild, ViewContainerRef, HostBinding, ChangeDetectionStrategy, Component, Injectable } from '@angular/core';
|
|
3
|
+
import { DIALOG_DATA, DialogService } from '@frame-kit/ui-ng/ui/dialog';
|
|
4
|
+
import { ButtonComponent } from '@frame-kit/ui-ng/ui/button';
|
|
5
|
+
import { Subject } from 'rxjs';
|
|
6
|
+
|
|
7
|
+
const WIZARD_DIALOG_REF = Symbol('WIZARD_DIALOG_REF');
|
|
8
|
+
class WizardDialogRef {
|
|
9
|
+
dialogRef;
|
|
10
|
+
consumerData;
|
|
11
|
+
submitSubject = new Subject();
|
|
12
|
+
stepChangeSubject = new Subject();
|
|
13
|
+
// ===== CONFIG =====
|
|
14
|
+
steps;
|
|
15
|
+
linear;
|
|
16
|
+
submitLabel;
|
|
17
|
+
cancelLabel;
|
|
18
|
+
nextLabel;
|
|
19
|
+
backLabel;
|
|
20
|
+
// ===== NAVIGATION STATE =====
|
|
21
|
+
currentIndex = signal(0, ...(ngDevMode ? [{ debugName: "currentIndex" }] : /* istanbul ignore next */ []));
|
|
22
|
+
highestVisitedIndex = signal(0, ...(ngDevMode ? [{ debugName: "highestVisitedIndex" }] : /* istanbul ignore next */ []));
|
|
23
|
+
totalSteps = computed(() => this.steps.length, ...(ngDevMode ? [{ debugName: "totalSteps" }] : /* istanbul ignore next */ []));
|
|
24
|
+
isFirstStep = computed(() => this.currentIndex() === 0, ...(ngDevMode ? [{ debugName: "isFirstStep" }] : /* istanbul ignore next */ []));
|
|
25
|
+
isLastStep = computed(() => this.currentIndex() === this.steps.length - 1, ...(ngDevMode ? [{ debugName: "isLastStep" }] : /* istanbul ignore next */ []));
|
|
26
|
+
currentStep = computed(() => this.steps[this.currentIndex()], ...(ngDevMode ? [{ debugName: "currentStep" }] : /* istanbul ignore next */ []));
|
|
27
|
+
// ===== CONSUMER-CONTROLLED STATE =====
|
|
28
|
+
submitDisabled = signal(false, ...(ngDevMode ? [{ debugName: "submitDisabled" }] : /* istanbul ignore next */ []));
|
|
29
|
+
nextDisabled = signal(false, ...(ngDevMode ? [{ debugName: "nextDisabled" }] : /* istanbul ignore next */ []));
|
|
30
|
+
chromeVisible = signal(true, ...(ngDevMode ? [{ debugName: "chromeVisible" }] : /* istanbul ignore next */ []));
|
|
31
|
+
/**
|
|
32
|
+
* Optional third footer button. When non-null, the wizard chrome
|
|
33
|
+
* renders an additional `<fk-button>` between Back and Submit
|
|
34
|
+
* using this metadata. Consumers typically wire this in an
|
|
35
|
+
* `effect` keyed on `currentIndex` so the button only appears on
|
|
36
|
+
* the step(s) that need it.
|
|
37
|
+
*/
|
|
38
|
+
extraAction = signal(null, ...(ngDevMode ? [{ debugName: "extraAction" }] : /* istanbul ignore next */ []));
|
|
39
|
+
// ===== OBSERVABLES =====
|
|
40
|
+
submitted = this.submitSubject.asObservable();
|
|
41
|
+
stepChanged = this.stepChangeSubject.asObservable();
|
|
42
|
+
constructor(config) {
|
|
43
|
+
this.steps = config.steps;
|
|
44
|
+
this.linear = config.linear ?? true;
|
|
45
|
+
this.submitLabel = config.submitLabel ?? 'Submit';
|
|
46
|
+
this.cancelLabel = config.cancelLabel ?? 'Cancel';
|
|
47
|
+
this.nextLabel = config.nextLabel ?? 'Next';
|
|
48
|
+
this.backLabel = config.backLabel ?? 'Back';
|
|
49
|
+
this.consumerData = config.data;
|
|
50
|
+
}
|
|
51
|
+
get data() {
|
|
52
|
+
return this.consumerData;
|
|
53
|
+
}
|
|
54
|
+
// ===== NAVIGATION =====
|
|
55
|
+
next() {
|
|
56
|
+
if (this.isLastStep()) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
this.currentIndex.update((i) => i + 1);
|
|
60
|
+
this.updateHighestVisited();
|
|
61
|
+
this.stepChangeSubject.next(this.currentIndex());
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
previous() {
|
|
65
|
+
if (this.isFirstStep()) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
this.currentIndex.update((i) => i - 1);
|
|
69
|
+
this.stepChangeSubject.next(this.currentIndex());
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
goTo(index) {
|
|
73
|
+
if (index < 0 || index >= this.steps.length) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
if (this.linear && index > this.highestVisitedIndex()) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
if (index > this.currentIndex() && this.nextDisabled()) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
this.currentIndex.set(index);
|
|
83
|
+
this.updateHighestVisited();
|
|
84
|
+
this.stepChangeSubject.next(index);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
updateHighestVisited() {
|
|
88
|
+
const current = this.currentIndex();
|
|
89
|
+
if (current > this.highestVisitedIndex()) {
|
|
90
|
+
this.highestVisitedIndex.set(current);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ===== DIALOG LIFECYCLE =====
|
|
94
|
+
close(result) {
|
|
95
|
+
this.dialogRef.close(result);
|
|
96
|
+
}
|
|
97
|
+
afterClosed() {
|
|
98
|
+
return this.dialogRef.afterClosed();
|
|
99
|
+
}
|
|
100
|
+
// ===== INTERNAL =====
|
|
101
|
+
/** @internal Called by container when submit button is clicked. */
|
|
102
|
+
emitSubmit() {
|
|
103
|
+
this.submitSubject.next();
|
|
104
|
+
}
|
|
105
|
+
/** @internal Called by WizardDialogService after dialog is opened. */
|
|
106
|
+
setDialogRef(ref) {
|
|
107
|
+
this.dialogRef = ref;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
class WizardDialogContainerComponent {
|
|
112
|
+
data = inject(DIALOG_DATA);
|
|
113
|
+
injector = inject(Injector);
|
|
114
|
+
bodyOutlet = viewChild('bodyOutlet', { ...(ngDevMode ? { debugName: "bodyOutlet" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
|
|
115
|
+
ref = this.data.wizardRef;
|
|
116
|
+
classes = computed(() => 'fk-wizard-dialog', ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
117
|
+
get hostClass() {
|
|
118
|
+
return this.classes();
|
|
119
|
+
}
|
|
120
|
+
ngAfterViewInit() {
|
|
121
|
+
const outlet = this.bodyOutlet();
|
|
122
|
+
if (!outlet) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const childInjector = Injector.create({
|
|
126
|
+
parent: this.injector,
|
|
127
|
+
providers: [{ provide: WIZARD_DIALOG_REF, useValue: this.ref }],
|
|
128
|
+
});
|
|
129
|
+
outlet.createComponent(this.data.contentComponent, {
|
|
130
|
+
injector: childInjector,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
onCancel() {
|
|
134
|
+
this.ref.close();
|
|
135
|
+
}
|
|
136
|
+
onSubmit() {
|
|
137
|
+
this.ref.emitSubmit();
|
|
138
|
+
}
|
|
139
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WizardDialogContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
140
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: WizardDialogContainerComponent, isStandalone: true, selector: "fk-wizard-dialog-container", host: { properties: { "class": "this.hostClass" } }, viewQueries: [{ propertyName: "bodyOutlet", first: true, predicate: ["bodyOutlet"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<!-- Stepper -->\n<div\n class=\"fk-wizard-dialog__stepper\"\n [class.fk-wizard-dialog__stepper--hidden]=\"!ref.chromeVisible()\"\n role=\"tablist\"\n>\n @for (step of ref.steps; track $index) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"fk-wizard-dialog__step\"\n [class.fk-wizard-dialog__step--active]=\"$index === ref.currentIndex()\"\n [class.fk-wizard-dialog__step--completed]=\"$index < ref.currentIndex()\"\n [attr.aria-selected]=\"$index === ref.currentIndex()\"\n [disabled]=\"ref.linear && $index > ref.highestVisitedIndex()\"\n (click)=\"ref.goTo($index)\"\n >\n <span class=\"fk-wizard-dialog__step-number\">{{ $index + 1 }}</span>\n <span class=\"fk-wizard-dialog__step-title\">{{ step.title }}</span>\n @if (step.optional) {\n <span class=\"fk-wizard-dialog__step-optional\">(Optional)</span>\n }\n </button>\n }\n</div>\n\n<!-- Scrollable body -->\n<div class=\"fk-wizard-dialog__body\">\n <ng-template #bodyOutlet />\n</div>\n\n<!-- Footer (moved to dialog footer by DialogService) -->\n<div\n class=\"fk-wizard-dialog__footer\"\n [class.fk-wizard-dialog__footer--hidden]=\"!ref.chromeVisible()\"\n libDialogFooter\n>\n @if (ref.isFirstStep()) {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"onCancel()\">\n {{ ref.cancelLabel }}\n </fk-button>\n } @else {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"ref.previous()\">\n {{ ref.backLabel }}\n </fk-button>\n }\n\n @if (ref.extraAction(); as action) {\n <fk-button\n [variant]=\"action.variant ?? 'outline'\"\n type=\"button\"\n (click)=\"action.onClick()\"\n >\n {{ action.label }}\n </fk-button>\n }\n\n @if (ref.isLastStep()) {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.submitDisabled()\"\n (click)=\"onSubmit()\"\n >\n {{ ref.submitLabel }}\n </fk-button>\n } @else {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.nextDisabled()\"\n (click)=\"ref.next()\"\n >\n {{ ref.nextLabel }}\n </fk-button>\n }\n</div>\n", styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden;margin-top:-1rem}.fk-wizard-dialog__stepper{display:flex;gap:var(--fk-wizard-dialog-stepper-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-wizard-dialog-stepper-padding, 0 0 .75rem);flex-shrink:0}.fk-wizard-dialog__stepper--hidden{display:none}.fk-wizard-dialog__step{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--fk-rhythm-2, .5rem);padding:var(--fk-rhythm-2, .5rem);font-family:var(--fk-input-font-family, inherit);font-size:var(--fk-form-label-font-size, var(--fk-typography-label-font-size, .875rem));color:var(--fk-wizard-dialog-step-color, var(--fk-form-hint-color, #6b7280));background:transparent;border:none;cursor:pointer}.fk-wizard-dialog__step:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18));border-radius:var(--fk-radius-sm, .25rem)}.fk-wizard-dialog__step:disabled{opacity:.5;cursor:not-allowed}.fk-wizard-dialog__step--active{color:var(--fk-wizard-dialog-step-active-color, var(--fk-color-primary, #0a84ff))}.fk-wizard-dialog__step--completed{color:var(--fk-wizard-dialog-step-completed-color, var(--fk-form-label-color, #0b1420))}.fk-wizard-dialog__step-number{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;font-size:var(--fk-font-size-xs, .75rem);font-weight:600;border-radius:50%;border:1px solid currentColor}.fk-wizard-dialog__step--active .fk-wizard-dialog__step-number{background:var(--fk-wizard-dialog-step-active-color, var(--fk-color-primary, #0a84ff));color:var(--fk-wizard-dialog-step-number-active-color, #fff);border-color:var(--fk-wizard-dialog-step-active-color, var(--fk-color-primary, #0a84ff))}.fk-wizard-dialog__step-optional{font-size:var(--fk-font-size-xs, .75rem);opacity:.7}.fk-wizard-dialog__body{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;padding:var(--fk-wizard-dialog-body-padding, var(--fk-rhythm-4, 1rem) 0);--fk-form-field-gap: 0}.fk-wizard-dialog__footer{display:flex;gap:var(--fk-wizard-dialog-footer-gap, var(--fk-rhythm-3, .75rem));padding:var(--fk-wizard-dialog-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-6, 1.5rem));border-top:var(--fk-wizard-dialog-footer-border, 1px solid var(--fk-color-border, #d9e2ee));flex-shrink:0}.fk-wizard-dialog__footer--hidden{display:none}.fk-wizard-dialog__footer>*{flex:1 1 0;min-width:0}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "fk-button", inputs: ["variant", "size", "loading", "disabled", "type", "fullWidth", "id", "className", "ariaLabel", "ariaDescribedBy"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
141
|
+
}
|
|
142
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WizardDialogContainerComponent, decorators: [{
|
|
143
|
+
type: Component,
|
|
144
|
+
args: [{ selector: 'fk-wizard-dialog-container', standalone: true, imports: [ButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Stepper -->\n<div\n class=\"fk-wizard-dialog__stepper\"\n [class.fk-wizard-dialog__stepper--hidden]=\"!ref.chromeVisible()\"\n role=\"tablist\"\n>\n @for (step of ref.steps; track $index) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"fk-wizard-dialog__step\"\n [class.fk-wizard-dialog__step--active]=\"$index === ref.currentIndex()\"\n [class.fk-wizard-dialog__step--completed]=\"$index < ref.currentIndex()\"\n [attr.aria-selected]=\"$index === ref.currentIndex()\"\n [disabled]=\"ref.linear && $index > ref.highestVisitedIndex()\"\n (click)=\"ref.goTo($index)\"\n >\n <span class=\"fk-wizard-dialog__step-number\">{{ $index + 1 }}</span>\n <span class=\"fk-wizard-dialog__step-title\">{{ step.title }}</span>\n @if (step.optional) {\n <span class=\"fk-wizard-dialog__step-optional\">(Optional)</span>\n }\n </button>\n }\n</div>\n\n<!-- Scrollable body -->\n<div class=\"fk-wizard-dialog__body\">\n <ng-template #bodyOutlet />\n</div>\n\n<!-- Footer (moved to dialog footer by DialogService) -->\n<div\n class=\"fk-wizard-dialog__footer\"\n [class.fk-wizard-dialog__footer--hidden]=\"!ref.chromeVisible()\"\n libDialogFooter\n>\n @if (ref.isFirstStep()) {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"onCancel()\">\n {{ ref.cancelLabel }}\n </fk-button>\n } @else {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"ref.previous()\">\n {{ ref.backLabel }}\n </fk-button>\n }\n\n @if (ref.extraAction(); as action) {\n <fk-button\n [variant]=\"action.variant ?? 'outline'\"\n type=\"button\"\n (click)=\"action.onClick()\"\n >\n {{ action.label }}\n </fk-button>\n }\n\n @if (ref.isLastStep()) {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.submitDisabled()\"\n (click)=\"onSubmit()\"\n >\n {{ ref.submitLabel }}\n </fk-button>\n } @else {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.nextDisabled()\"\n (click)=\"ref.next()\"\n >\n {{ ref.nextLabel }}\n </fk-button>\n }\n</div>\n", styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden;margin-top:-1rem}.fk-wizard-dialog__stepper{display:flex;gap:var(--fk-wizard-dialog-stepper-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-wizard-dialog-stepper-padding, 0 0 .75rem);flex-shrink:0}.fk-wizard-dialog__stepper--hidden{display:none}.fk-wizard-dialog__step{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--fk-rhythm-2, .5rem);padding:var(--fk-rhythm-2, .5rem);font-family:var(--fk-input-font-family, inherit);font-size:var(--fk-form-label-font-size, var(--fk-typography-label-font-size, .875rem));color:var(--fk-wizard-dialog-step-color, var(--fk-form-hint-color, #6b7280));background:transparent;border:none;cursor:pointer}.fk-wizard-dialog__step:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18));border-radius:var(--fk-radius-sm, .25rem)}.fk-wizard-dialog__step:disabled{opacity:.5;cursor:not-allowed}.fk-wizard-dialog__step--active{color:var(--fk-wizard-dialog-step-active-color, var(--fk-color-primary, #0a84ff))}.fk-wizard-dialog__step--completed{color:var(--fk-wizard-dialog-step-completed-color, var(--fk-form-label-color, #0b1420))}.fk-wizard-dialog__step-number{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;font-size:var(--fk-font-size-xs, .75rem);font-weight:600;border-radius:50%;border:1px solid currentColor}.fk-wizard-dialog__step--active .fk-wizard-dialog__step-number{background:var(--fk-wizard-dialog-step-active-color, var(--fk-color-primary, #0a84ff));color:var(--fk-wizard-dialog-step-number-active-color, #fff);border-color:var(--fk-wizard-dialog-step-active-color, var(--fk-color-primary, #0a84ff))}.fk-wizard-dialog__step-optional{font-size:var(--fk-font-size-xs, .75rem);opacity:.7}.fk-wizard-dialog__body{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;padding:var(--fk-wizard-dialog-body-padding, var(--fk-rhythm-4, 1rem) 0);--fk-form-field-gap: 0}.fk-wizard-dialog__footer{display:flex;gap:var(--fk-wizard-dialog-footer-gap, var(--fk-rhythm-3, .75rem));padding:var(--fk-wizard-dialog-footer-padding, var(--fk-rhythm-4, 1rem) var(--fk-rhythm-6, 1.5rem));border-top:var(--fk-wizard-dialog-footer-border, 1px solid var(--fk-color-border, #d9e2ee));flex-shrink:0}.fk-wizard-dialog__footer--hidden{display:none}.fk-wizard-dialog__footer>*{flex:1 1 0;min-width:0}\n"] }]
|
|
145
|
+
}], propDecorators: { bodyOutlet: [{ type: i0.ViewChild, args: ['bodyOutlet', { ...{
|
|
146
|
+
read: ViewContainerRef,
|
|
147
|
+
}, isSignal: true }] }], hostClass: [{
|
|
148
|
+
type: HostBinding,
|
|
149
|
+
args: ['class']
|
|
150
|
+
}] } });
|
|
151
|
+
|
|
152
|
+
class WizardDialogService {
|
|
153
|
+
dialogService = inject(DialogService);
|
|
154
|
+
open(content, config) {
|
|
155
|
+
const wizardRef = new WizardDialogRef(config);
|
|
156
|
+
const dialogRef = this.dialogService.open(WizardDialogContainerComponent, {
|
|
157
|
+
header: config.header,
|
|
158
|
+
size: config.size ?? 'lg',
|
|
159
|
+
closable: config.closable,
|
|
160
|
+
closeOnEscape: config.closeOnEscape,
|
|
161
|
+
closeOnBackdrop: config.closeOnBackdrop,
|
|
162
|
+
animation: config.animation,
|
|
163
|
+
fullscreenMobile: config.fullscreenMobile,
|
|
164
|
+
className: ['fk-wizard-dialog-host', config.className]
|
|
165
|
+
.filter(Boolean)
|
|
166
|
+
.join(' '),
|
|
167
|
+
ariaLabel: config.ariaLabel,
|
|
168
|
+
ariaDescribedBy: config.ariaDescribedBy,
|
|
169
|
+
flexBody: true,
|
|
170
|
+
data: {
|
|
171
|
+
wizardRef: wizardRef,
|
|
172
|
+
contentComponent: content,
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
wizardRef.setDialogRef(dialogRef);
|
|
176
|
+
return wizardRef;
|
|
177
|
+
}
|
|
178
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WizardDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
179
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WizardDialogService, providedIn: 'root' });
|
|
180
|
+
}
|
|
181
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WizardDialogService, decorators: [{
|
|
182
|
+
type: Injectable,
|
|
183
|
+
args: [{ providedIn: 'root' }]
|
|
184
|
+
}] });
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Generated bundle index. Do not edit.
|
|
188
|
+
*/
|
|
189
|
+
|
|
190
|
+
export { WIZARD_DIALOG_REF, WizardDialogContainerComponent, WizardDialogRef, WizardDialogService };
|
|
191
|
+
//# sourceMappingURL=frame-kit-ui-ng-ui-wizard-dialog.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-ui-wizard-dialog.mjs","sources":["../../../../packages/ui-ng/ui/wizard-dialog/wizard-dialog-ref.ts","../../../../packages/ui-ng/ui/wizard-dialog/wizard-dialog-container.component.ts","../../../../packages/ui-ng/ui/wizard-dialog/wizard-dialog-container.component.html","../../../../packages/ui-ng/ui/wizard-dialog/wizard-dialog.service.ts","../../../../packages/ui-ng/ui/wizard-dialog/frame-kit-ui-ng-ui-wizard-dialog.ts"],"sourcesContent":["import { computed, signal } from '@angular/core';\n\nimport { Observable, Subject } from 'rxjs';\n\nimport type { DialogRef } from '@frame-kit/ui-ng/ui/dialog';\nimport type {\n WizardDialogConfig,\n WizardDialogStep,\n} from './wizard-dialog.types';\n\n/**\n * Optional extra footer button the consumer can surface on any step\n * — typically a \"View X\" jump-off on the results/last step. Sits\n * between Back and Submit in the wizard's footer. Set via\n * `WizardDialogRef.extraAction.set(...)` on step entry; clear with\n * `null` on step exit (or just rely on swapping it out).\n */\nexport interface WizardExtraAction {\n /** Button label, e.g. \"View Identities\". */\n label: string;\n /** Visual variant. Defaults to `\"outline\"` so the extra action\n * doesn't compete with the primary Submit button. */\n variant?: 'primary' | 'outline' | 'secondary' | 'danger';\n /** Click handler — typically closes the wizard with a sentinel. */\n onClick: () => void;\n}\n\nexport const WIZARD_DIALOG_REF = Symbol('WIZARD_DIALOG_REF');\n\nexport class WizardDialogRef<TResult = unknown, TData = unknown> {\n private dialogRef!: DialogRef<TResult>;\n private readonly consumerData: TData | undefined;\n private readonly submitSubject = new Subject<void>();\n private readonly stepChangeSubject = new Subject<number>();\n\n // ===== CONFIG =====\n\n readonly steps: WizardDialogStep[];\n readonly linear: boolean;\n readonly submitLabel: string;\n readonly cancelLabel: string;\n readonly nextLabel: string;\n readonly backLabel: string;\n\n // ===== NAVIGATION STATE =====\n\n readonly currentIndex = signal(0);\n readonly highestVisitedIndex = signal(0);\n\n readonly totalSteps = computed(() => this.steps.length);\n\n readonly isFirstStep = computed(() => this.currentIndex() === 0);\n\n readonly isLastStep = computed(\n () => this.currentIndex() === this.steps.length - 1,\n );\n\n readonly currentStep = computed(() => this.steps[this.currentIndex()]);\n\n // ===== CONSUMER-CONTROLLED STATE =====\n\n readonly submitDisabled = signal(false);\n readonly nextDisabled = signal(false);\n readonly chromeVisible = signal(true);\n /**\n * Optional third footer button. When non-null, the wizard chrome\n * renders an additional `<fk-button>` between Back and Submit\n * using this metadata. Consumers typically wire this in an\n * `effect` keyed on `currentIndex` so the button only appears on\n * the step(s) that need it.\n */\n readonly extraAction = signal<WizardExtraAction | null>(null);\n\n // ===== OBSERVABLES =====\n\n readonly submitted: Observable<void> = this.submitSubject.asObservable();\n readonly stepChanged: Observable<number> =\n this.stepChangeSubject.asObservable();\n\n constructor(config: WizardDialogConfig<TData>) {\n this.steps = config.steps;\n this.linear = config.linear ?? true;\n this.submitLabel = config.submitLabel ?? 'Submit';\n this.cancelLabel = config.cancelLabel ?? 'Cancel';\n this.nextLabel = config.nextLabel ?? 'Next';\n this.backLabel = config.backLabel ?? 'Back';\n this.consumerData = config.data;\n }\n\n get data(): TData | undefined {\n return this.consumerData;\n }\n\n // ===== NAVIGATION =====\n\n next(): boolean {\n if (this.isLastStep()) {\n return false;\n }\n\n this.currentIndex.update((i) => i + 1);\n this.updateHighestVisited();\n this.stepChangeSubject.next(this.currentIndex());\n\n return true;\n }\n\n previous(): boolean {\n if (this.isFirstStep()) {\n return false;\n }\n\n this.currentIndex.update((i) => i - 1);\n this.stepChangeSubject.next(this.currentIndex());\n\n return true;\n }\n\n goTo(index: number): boolean {\n if (index < 0 || index >= this.steps.length) {\n return false;\n }\n\n if (this.linear && index > this.highestVisitedIndex()) {\n return false;\n }\n\n if (index > this.currentIndex() && this.nextDisabled()) {\n return false;\n }\n\n this.currentIndex.set(index);\n this.updateHighestVisited();\n this.stepChangeSubject.next(index);\n\n return true;\n }\n\n private updateHighestVisited(): void {\n const current = this.currentIndex();\n\n if (current > this.highestVisitedIndex()) {\n this.highestVisitedIndex.set(current);\n }\n }\n\n // ===== DIALOG LIFECYCLE =====\n\n close(result?: TResult): void {\n this.dialogRef.close(result);\n }\n\n afterClosed(): Observable<TResult | undefined> {\n return this.dialogRef.afterClosed();\n }\n\n // ===== INTERNAL =====\n\n /** @internal Called by container when submit button is clicked. */\n emitSubmit(): void {\n this.submitSubject.next();\n }\n\n /** @internal Called by WizardDialogService after dialog is opened. */\n setDialogRef(ref: DialogRef<TResult>): void {\n this.dialogRef = ref;\n }\n}\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n HostBinding,\n inject,\n Injector,\n viewChild,\n ViewContainerRef,\n} from '@angular/core';\n\nimport { ButtonComponent } from '@frame-kit/ui-ng/ui/button';\nimport { DIALOG_DATA } from '@frame-kit/ui-ng/ui/dialog';\nimport type { WizardDialogContainerData } from './wizard-dialog.service';\nimport { WIZARD_DIALOG_REF, WizardDialogRef } from './wizard-dialog-ref';\n\n@Component({\n selector: 'fk-wizard-dialog-container',\n standalone: true,\n imports: [ButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './wizard-dialog-container.component.html',\n styleUrl: './wizard-dialog-container.component.scss',\n})\nexport class WizardDialogContainerComponent implements AfterViewInit {\n private readonly data = inject(\n DIALOG_DATA as never,\n ) as WizardDialogContainerData;\n private readonly injector = inject(Injector);\n private readonly bodyOutlet = viewChild('bodyOutlet', {\n read: ViewContainerRef,\n });\n\n readonly ref: WizardDialogRef = this.data.wizardRef;\n\n readonly classes = computed(() => 'fk-wizard-dialog');\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n ngAfterViewInit(): void {\n const outlet = this.bodyOutlet();\n\n if (!outlet) {\n return;\n }\n\n const childInjector = Injector.create({\n parent: this.injector,\n providers: [{ provide: WIZARD_DIALOG_REF as never, useValue: this.ref }],\n });\n\n outlet.createComponent(this.data.contentComponent, {\n injector: childInjector,\n });\n }\n\n onCancel(): void {\n this.ref.close();\n }\n\n onSubmit(): void {\n this.ref.emitSubmit();\n }\n}\n","<!-- Stepper -->\n<div\n class=\"fk-wizard-dialog__stepper\"\n [class.fk-wizard-dialog__stepper--hidden]=\"!ref.chromeVisible()\"\n role=\"tablist\"\n>\n @for (step of ref.steps; track $index) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"fk-wizard-dialog__step\"\n [class.fk-wizard-dialog__step--active]=\"$index === ref.currentIndex()\"\n [class.fk-wizard-dialog__step--completed]=\"$index < ref.currentIndex()\"\n [attr.aria-selected]=\"$index === ref.currentIndex()\"\n [disabled]=\"ref.linear && $index > ref.highestVisitedIndex()\"\n (click)=\"ref.goTo($index)\"\n >\n <span class=\"fk-wizard-dialog__step-number\">{{ $index + 1 }}</span>\n <span class=\"fk-wizard-dialog__step-title\">{{ step.title }}</span>\n @if (step.optional) {\n <span class=\"fk-wizard-dialog__step-optional\">(Optional)</span>\n }\n </button>\n }\n</div>\n\n<!-- Scrollable body -->\n<div class=\"fk-wizard-dialog__body\">\n <ng-template #bodyOutlet />\n</div>\n\n<!-- Footer (moved to dialog footer by DialogService) -->\n<div\n class=\"fk-wizard-dialog__footer\"\n [class.fk-wizard-dialog__footer--hidden]=\"!ref.chromeVisible()\"\n libDialogFooter\n>\n @if (ref.isFirstStep()) {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"onCancel()\">\n {{ ref.cancelLabel }}\n </fk-button>\n } @else {\n <fk-button variant=\"outline\" type=\"button\" (click)=\"ref.previous()\">\n {{ ref.backLabel }}\n </fk-button>\n }\n\n @if (ref.extraAction(); as action) {\n <fk-button\n [variant]=\"action.variant ?? 'outline'\"\n type=\"button\"\n (click)=\"action.onClick()\"\n >\n {{ action.label }}\n </fk-button>\n }\n\n @if (ref.isLastStep()) {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.submitDisabled()\"\n (click)=\"onSubmit()\"\n >\n {{ ref.submitLabel }}\n </fk-button>\n } @else {\n <fk-button\n variant=\"primary\"\n type=\"button\"\n [disabled]=\"ref.nextDisabled()\"\n (click)=\"ref.next()\"\n >\n {{ ref.nextLabel }}\n </fk-button>\n }\n</div>\n","import { inject, Injectable, Type } from '@angular/core';\n\nimport { DialogService } from '@frame-kit/ui-ng/ui/dialog';\nimport type { DialogRef } from '@frame-kit/ui-ng/ui/dialog';\nimport type { WizardDialogConfig } from './wizard-dialog.types';\nimport { WizardDialogContainerComponent } from './wizard-dialog-container.component';\nimport { WizardDialogRef } from './wizard-dialog-ref';\n\nexport interface WizardDialogContainerData {\n wizardRef: WizardDialogRef;\n contentComponent: Type<unknown>;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class WizardDialogService {\n private readonly dialogService = inject(DialogService);\n\n open<TResult = unknown, TData = unknown>(\n content: Type<unknown>,\n config: WizardDialogConfig<TData>,\n ): WizardDialogRef<TResult, TData> {\n const wizardRef = new WizardDialogRef<TResult, TData>(config);\n\n const dialogRef = this.dialogService.open<\n TResult,\n WizardDialogContainerData\n >(WizardDialogContainerComponent, {\n header: config.header,\n size: config.size ?? 'lg',\n closable: config.closable,\n closeOnEscape: config.closeOnEscape,\n closeOnBackdrop: config.closeOnBackdrop,\n animation: config.animation,\n fullscreenMobile: config.fullscreenMobile,\n className: ['fk-wizard-dialog-host', config.className]\n .filter(Boolean)\n .join(' '),\n ariaLabel: config.ariaLabel,\n ariaDescribedBy: config.ariaDescribedBy,\n flexBody: true,\n data: {\n wizardRef: wizardRef as WizardDialogRef,\n contentComponent: content,\n },\n });\n\n wizardRef.setDialogRef(dialogRef as DialogRef<TResult>);\n\n return wizardRef;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export * from '@frame-kit/ui-ng/core/headline';
|
|
2
|
+
export * from '@frame-kit/ui-ng/core/icon';
|
|
3
|
+
export * from '@frame-kit/ui-ng/core/image';
|
|
4
|
+
export * from '@frame-kit/ui-ng/core/link';
|
|
5
|
+
export * from '@frame-kit/ui-ng/core/separator';
|
|
6
|
+
export * from '@frame-kit/ui-ng/core/text';
|
|
7
|
+
export * from '@frame-kit/ui-ng/directives/infinite-scroll';
|
|
8
|
+
export * from '@frame-kit/ui-ng/directives/spotlight';
|
|
9
|
+
export * from '@frame-kit/ui-ng/directives/tooltip';
|
|
10
|
+
export * from '@frame-kit/ui-ng/docs/endpoint-link';
|
|
11
|
+
export * from '@frame-kit/ui-ng/docs/method-badge';
|
|
12
|
+
export * from '@frame-kit/ui-ng/forms';
|
|
13
|
+
export * from '@frame-kit/ui-ng/layouts/app-shell';
|
|
14
|
+
export * from '@frame-kit/ui-ng/layouts/content-split';
|
|
15
|
+
export * from '@frame-kit/ui-ng/services/overlay-orchestrator';
|
|
16
|
+
export * from '@frame-kit/ui-ng/services/spotlight';
|
|
17
|
+
export * from '@frame-kit/ui-ng/services/toast';
|
|
18
|
+
export * from '@frame-kit/ui-ng/ui/accordion';
|
|
19
|
+
export * from '@frame-kit/ui-ng/ui/alert';
|
|
20
|
+
export * from '@frame-kit/ui-ng/ui/avatar';
|
|
21
|
+
export * from '@frame-kit/ui-ng/ui/avatar-stack';
|
|
22
|
+
export * from '@frame-kit/ui-ng/ui/badge';
|
|
23
|
+
export * from '@frame-kit/ui-ng/ui/breadcrumb';
|
|
24
|
+
export * from '@frame-kit/ui-ng/ui/button';
|
|
25
|
+
export * from '@frame-kit/ui-ng/ui/callout';
|
|
26
|
+
export * from '@frame-kit/ui-ng/ui/card';
|
|
27
|
+
export * from '@frame-kit/ui-ng/ui/copyable-field';
|
|
28
|
+
export * from '@frame-kit/ui-ng/ui/data-table';
|
|
29
|
+
export * from '@frame-kit/ui-ng/ui/dialog';
|
|
30
|
+
export * from '@frame-kit/ui-ng/ui/drawer';
|
|
31
|
+
export * from '@frame-kit/ui-ng/ui/dropdown-menu';
|
|
32
|
+
export * from '@frame-kit/ui-ng/ui/editable-field';
|
|
33
|
+
export * from '@frame-kit/ui-ng/ui/icon-badge';
|
|
34
|
+
export * from '@frame-kit/ui-ng/ui/icon-list';
|
|
35
|
+
export * from '@frame-kit/ui-ng/ui/inline-edit';
|
|
36
|
+
export * from '@frame-kit/ui-ng/ui/list-editor';
|
|
37
|
+
export * from '@frame-kit/ui-ng/ui/loader';
|
|
38
|
+
export * from '@frame-kit/ui-ng/ui/menu-item';
|
|
39
|
+
export * from '@frame-kit/ui-ng/ui/nav-brand';
|
|
40
|
+
export * from '@frame-kit/ui-ng/ui/nav-group';
|
|
41
|
+
export * from '@frame-kit/ui-ng/ui/nav-separator';
|
|
42
|
+
export * from '@frame-kit/ui-ng/ui/node-tree';
|
|
43
|
+
export * from '@frame-kit/ui-ng/ui/node-tree-breadcrumb';
|
|
44
|
+
export * from '@frame-kit/ui-ng/ui/note';
|
|
45
|
+
export * from '@frame-kit/ui-ng/ui/numbered-list';
|
|
46
|
+
export * from '@frame-kit/ui-ng/ui/pagination';
|
|
47
|
+
export * from '@frame-kit/ui-ng/ui/progress-bar';
|
|
48
|
+
export * from '@frame-kit/ui-ng/ui/sidenav-link';
|
|
49
|
+
export * from '@frame-kit/ui-ng/ui/tabs';
|
|
50
|
+
export * from '@frame-kit/ui-ng/ui/timeline';
|
|
51
|
+
export * from '@frame-kit/ui-ng/ui/toast';
|
|
52
|
+
export * from '@frame-kit/ui-ng/ui/user-menu';
|
|
53
|
+
export * from '@frame-kit/ui-ng/ui/wizard-dialog';
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Generated bundle index. Do not edit.
|
|
57
|
+
*/
|
|
58
|
+
//# sourceMappingURL=frame-kit-ui-ng.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng.mjs","sources":["../../../../packages/ui-ng/frame-kit-ui-ng.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;AAEG"}
|