@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
package/package.json
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@frame-kit/ui-ng",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Style-agnostic, token-driven Angular UI component library for FrameKit.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/frame-kit/packages.git",
|
|
9
|
+
"directory": "packages/ui-ng"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/frame-kit/packages/tree/main/packages/ui-ng#readme",
|
|
12
|
+
"bugs": "https://github.com/frame-kit/packages/issues",
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"@angular/cdk": "^21.2.0",
|
|
15
|
+
"@angular/common": "^21.2.0",
|
|
16
|
+
"@angular/core": "^21.2.0",
|
|
17
|
+
"@angular/forms": "^21.2.0",
|
|
18
|
+
"@angular/platform-browser": "^21.2.0",
|
|
19
|
+
"@angular/router": "^21.2.0",
|
|
20
|
+
"rxjs": "^7.0.0"
|
|
21
|
+
},
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"module": "fesm2022/frame-kit-ui-ng.mjs",
|
|
27
|
+
"typings": "types/frame-kit-ui-ng.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
"./package.json": {
|
|
30
|
+
"default": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./types/frame-kit-ui-ng.d.ts",
|
|
34
|
+
"default": "./fesm2022/frame-kit-ui-ng.mjs"
|
|
35
|
+
},
|
|
36
|
+
"./core/headline": {
|
|
37
|
+
"types": "./types/frame-kit-ui-ng-core-headline.d.ts",
|
|
38
|
+
"default": "./fesm2022/frame-kit-ui-ng-core-headline.mjs"
|
|
39
|
+
},
|
|
40
|
+
"./core/icon": {
|
|
41
|
+
"types": "./types/frame-kit-ui-ng-core-icon.d.ts",
|
|
42
|
+
"default": "./fesm2022/frame-kit-ui-ng-core-icon.mjs"
|
|
43
|
+
},
|
|
44
|
+
"./core/image": {
|
|
45
|
+
"types": "./types/frame-kit-ui-ng-core-image.d.ts",
|
|
46
|
+
"default": "./fesm2022/frame-kit-ui-ng-core-image.mjs"
|
|
47
|
+
},
|
|
48
|
+
"./core/link": {
|
|
49
|
+
"types": "./types/frame-kit-ui-ng-core-link.d.ts",
|
|
50
|
+
"default": "./fesm2022/frame-kit-ui-ng-core-link.mjs"
|
|
51
|
+
},
|
|
52
|
+
"./core/separator": {
|
|
53
|
+
"types": "./types/frame-kit-ui-ng-core-separator.d.ts",
|
|
54
|
+
"default": "./fesm2022/frame-kit-ui-ng-core-separator.mjs"
|
|
55
|
+
},
|
|
56
|
+
"./core/text": {
|
|
57
|
+
"types": "./types/frame-kit-ui-ng-core-text.d.ts",
|
|
58
|
+
"default": "./fesm2022/frame-kit-ui-ng-core-text.mjs"
|
|
59
|
+
},
|
|
60
|
+
"./directives/infinite-scroll": {
|
|
61
|
+
"types": "./types/frame-kit-ui-ng-directives-infinite-scroll.d.ts",
|
|
62
|
+
"default": "./fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs"
|
|
63
|
+
},
|
|
64
|
+
"./directives/spotlight": {
|
|
65
|
+
"types": "./types/frame-kit-ui-ng-directives-spotlight.d.ts",
|
|
66
|
+
"default": "./fesm2022/frame-kit-ui-ng-directives-spotlight.mjs"
|
|
67
|
+
},
|
|
68
|
+
"./directives/tooltip": {
|
|
69
|
+
"types": "./types/frame-kit-ui-ng-directives-tooltip.d.ts",
|
|
70
|
+
"default": "./fesm2022/frame-kit-ui-ng-directives-tooltip.mjs"
|
|
71
|
+
},
|
|
72
|
+
"./docs/endpoint-link": {
|
|
73
|
+
"types": "./types/frame-kit-ui-ng-docs-endpoint-link.d.ts",
|
|
74
|
+
"default": "./fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs"
|
|
75
|
+
},
|
|
76
|
+
"./docs/method-badge": {
|
|
77
|
+
"types": "./types/frame-kit-ui-ng-docs-method-badge.d.ts",
|
|
78
|
+
"default": "./fesm2022/frame-kit-ui-ng-docs-method-badge.mjs"
|
|
79
|
+
},
|
|
80
|
+
"./forms": {
|
|
81
|
+
"types": "./types/frame-kit-ui-ng-forms.d.ts",
|
|
82
|
+
"default": "./fesm2022/frame-kit-ui-ng-forms.mjs"
|
|
83
|
+
},
|
|
84
|
+
"./layouts/app-shell": {
|
|
85
|
+
"types": "./types/frame-kit-ui-ng-layouts-app-shell.d.ts",
|
|
86
|
+
"default": "./fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs"
|
|
87
|
+
},
|
|
88
|
+
"./layouts/content-split": {
|
|
89
|
+
"types": "./types/frame-kit-ui-ng-layouts-content-split.d.ts",
|
|
90
|
+
"default": "./fesm2022/frame-kit-ui-ng-layouts-content-split.mjs"
|
|
91
|
+
},
|
|
92
|
+
"./services/overlay-orchestrator": {
|
|
93
|
+
"types": "./types/frame-kit-ui-ng-services-overlay-orchestrator.d.ts",
|
|
94
|
+
"default": "./fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs"
|
|
95
|
+
},
|
|
96
|
+
"./services/spotlight": {
|
|
97
|
+
"types": "./types/frame-kit-ui-ng-services-spotlight.d.ts",
|
|
98
|
+
"default": "./fesm2022/frame-kit-ui-ng-services-spotlight.mjs"
|
|
99
|
+
},
|
|
100
|
+
"./services/toast": {
|
|
101
|
+
"types": "./types/frame-kit-ui-ng-services-toast.d.ts",
|
|
102
|
+
"default": "./fesm2022/frame-kit-ui-ng-services-toast.mjs"
|
|
103
|
+
},
|
|
104
|
+
"./ui/accordion": {
|
|
105
|
+
"types": "./types/frame-kit-ui-ng-ui-accordion.d.ts",
|
|
106
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-accordion.mjs"
|
|
107
|
+
},
|
|
108
|
+
"./ui/alert": {
|
|
109
|
+
"types": "./types/frame-kit-ui-ng-ui-alert.d.ts",
|
|
110
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-alert.mjs"
|
|
111
|
+
},
|
|
112
|
+
"./ui/avatar": {
|
|
113
|
+
"types": "./types/frame-kit-ui-ng-ui-avatar.d.ts",
|
|
114
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-avatar.mjs"
|
|
115
|
+
},
|
|
116
|
+
"./ui/avatar-stack": {
|
|
117
|
+
"types": "./types/frame-kit-ui-ng-ui-avatar-stack.d.ts",
|
|
118
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs"
|
|
119
|
+
},
|
|
120
|
+
"./ui/badge": {
|
|
121
|
+
"types": "./types/frame-kit-ui-ng-ui-badge.d.ts",
|
|
122
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-badge.mjs"
|
|
123
|
+
},
|
|
124
|
+
"./ui/breadcrumb": {
|
|
125
|
+
"types": "./types/frame-kit-ui-ng-ui-breadcrumb.d.ts",
|
|
126
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs"
|
|
127
|
+
},
|
|
128
|
+
"./ui/button": {
|
|
129
|
+
"types": "./types/frame-kit-ui-ng-ui-button.d.ts",
|
|
130
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-button.mjs"
|
|
131
|
+
},
|
|
132
|
+
"./ui/callout": {
|
|
133
|
+
"types": "./types/frame-kit-ui-ng-ui-callout.d.ts",
|
|
134
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-callout.mjs"
|
|
135
|
+
},
|
|
136
|
+
"./ui/card": {
|
|
137
|
+
"types": "./types/frame-kit-ui-ng-ui-card.d.ts",
|
|
138
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-card.mjs"
|
|
139
|
+
},
|
|
140
|
+
"./ui/copyable-field": {
|
|
141
|
+
"types": "./types/frame-kit-ui-ng-ui-copyable-field.d.ts",
|
|
142
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs"
|
|
143
|
+
},
|
|
144
|
+
"./ui/data-table": {
|
|
145
|
+
"types": "./types/frame-kit-ui-ng-ui-data-table.d.ts",
|
|
146
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-data-table.mjs"
|
|
147
|
+
},
|
|
148
|
+
"./ui/dialog": {
|
|
149
|
+
"types": "./types/frame-kit-ui-ng-ui-dialog.d.ts",
|
|
150
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-dialog.mjs"
|
|
151
|
+
},
|
|
152
|
+
"./ui/drawer": {
|
|
153
|
+
"types": "./types/frame-kit-ui-ng-ui-drawer.d.ts",
|
|
154
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-drawer.mjs"
|
|
155
|
+
},
|
|
156
|
+
"./ui/dropdown-menu": {
|
|
157
|
+
"types": "./types/frame-kit-ui-ng-ui-dropdown-menu.d.ts",
|
|
158
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs"
|
|
159
|
+
},
|
|
160
|
+
"./ui/editable-field": {
|
|
161
|
+
"types": "./types/frame-kit-ui-ng-ui-editable-field.d.ts",
|
|
162
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-editable-field.mjs"
|
|
163
|
+
},
|
|
164
|
+
"./ui/icon-badge": {
|
|
165
|
+
"types": "./types/frame-kit-ui-ng-ui-icon-badge.d.ts",
|
|
166
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs"
|
|
167
|
+
},
|
|
168
|
+
"./ui/icon-list": {
|
|
169
|
+
"types": "./types/frame-kit-ui-ng-ui-icon-list.d.ts",
|
|
170
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-icon-list.mjs"
|
|
171
|
+
},
|
|
172
|
+
"./ui/inline-edit": {
|
|
173
|
+
"types": "./types/frame-kit-ui-ng-ui-inline-edit.d.ts",
|
|
174
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs"
|
|
175
|
+
},
|
|
176
|
+
"./ui/list-editor": {
|
|
177
|
+
"types": "./types/frame-kit-ui-ng-ui-list-editor.d.ts",
|
|
178
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-list-editor.mjs"
|
|
179
|
+
},
|
|
180
|
+
"./ui/loader": {
|
|
181
|
+
"types": "./types/frame-kit-ui-ng-ui-loader.d.ts",
|
|
182
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-loader.mjs"
|
|
183
|
+
},
|
|
184
|
+
"./ui/menu-item": {
|
|
185
|
+
"types": "./types/frame-kit-ui-ng-ui-menu-item.d.ts",
|
|
186
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-menu-item.mjs"
|
|
187
|
+
},
|
|
188
|
+
"./ui/nav-brand": {
|
|
189
|
+
"types": "./types/frame-kit-ui-ng-ui-nav-brand.d.ts",
|
|
190
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs"
|
|
191
|
+
},
|
|
192
|
+
"./ui/nav-group": {
|
|
193
|
+
"types": "./types/frame-kit-ui-ng-ui-nav-group.d.ts",
|
|
194
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-nav-group.mjs"
|
|
195
|
+
},
|
|
196
|
+
"./ui/nav-separator": {
|
|
197
|
+
"types": "./types/frame-kit-ui-ng-ui-nav-separator.d.ts",
|
|
198
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs"
|
|
199
|
+
},
|
|
200
|
+
"./ui/node-tree": {
|
|
201
|
+
"types": "./types/frame-kit-ui-ng-ui-node-tree.d.ts",
|
|
202
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-node-tree.mjs"
|
|
203
|
+
},
|
|
204
|
+
"./ui/node-tree-breadcrumb": {
|
|
205
|
+
"types": "./types/frame-kit-ui-ng-ui-node-tree-breadcrumb.d.ts",
|
|
206
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs"
|
|
207
|
+
},
|
|
208
|
+
"./ui/note": {
|
|
209
|
+
"types": "./types/frame-kit-ui-ng-ui-note.d.ts",
|
|
210
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-note.mjs"
|
|
211
|
+
},
|
|
212
|
+
"./ui/numbered-list": {
|
|
213
|
+
"types": "./types/frame-kit-ui-ng-ui-numbered-list.d.ts",
|
|
214
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs"
|
|
215
|
+
},
|
|
216
|
+
"./ui/pagination": {
|
|
217
|
+
"types": "./types/frame-kit-ui-ng-ui-pagination.d.ts",
|
|
218
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-pagination.mjs"
|
|
219
|
+
},
|
|
220
|
+
"./ui/progress-bar": {
|
|
221
|
+
"types": "./types/frame-kit-ui-ng-ui-progress-bar.d.ts",
|
|
222
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs"
|
|
223
|
+
},
|
|
224
|
+
"./ui/sidenav-link": {
|
|
225
|
+
"types": "./types/frame-kit-ui-ng-ui-sidenav-link.d.ts",
|
|
226
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs"
|
|
227
|
+
},
|
|
228
|
+
"./ui/tabs": {
|
|
229
|
+
"types": "./types/frame-kit-ui-ng-ui-tabs.d.ts",
|
|
230
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-tabs.mjs"
|
|
231
|
+
},
|
|
232
|
+
"./ui/timeline": {
|
|
233
|
+
"types": "./types/frame-kit-ui-ng-ui-timeline.d.ts",
|
|
234
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-timeline.mjs"
|
|
235
|
+
},
|
|
236
|
+
"./ui/toast": {
|
|
237
|
+
"types": "./types/frame-kit-ui-ng-ui-toast.d.ts",
|
|
238
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-toast.mjs"
|
|
239
|
+
},
|
|
240
|
+
"./ui/user-menu": {
|
|
241
|
+
"types": "./types/frame-kit-ui-ng-ui-user-menu.d.ts",
|
|
242
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-user-menu.mjs"
|
|
243
|
+
},
|
|
244
|
+
"./ui/wizard-dialog": {
|
|
245
|
+
"types": "./types/frame-kit-ui-ng-ui-wizard-dialog.d.ts",
|
|
246
|
+
"default": "./fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs"
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
"type": "module",
|
|
250
|
+
"dependencies": {
|
|
251
|
+
"tslib": "^2.3.0"
|
|
252
|
+
}
|
|
253
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# OverlayOrchestrator
|
|
2
|
+
|
|
3
|
+
A centralized service for managing overlay interactions (dialogs, drawers, popovers, navigation panels, tooltips) using a priority-based stack. Prevents UI conflicts like drawers staying open behind dialogs, or menus persisting when modals appear.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Initialization
|
|
8
|
+
|
|
9
|
+
The `OverlayOrchestrator` is provided at the root level (`providedIn: 'root'`). No setup is needed — inject it wherever you need overlay coordination.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { OverlayOrchestrator, OVERLAY_PRIORITY } from '@frame-kit/ui-ng';
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Built-in Integration
|
|
16
|
+
|
|
17
|
+
`DialogService` and `DrawerService` automatically register with the orchestrator. Opening a dialog auto-closes any open drawer or popover. Opening a drawer auto-closes any open popover. No consumer code is needed for these — it works out of the box.
|
|
18
|
+
|
|
19
|
+
### Registering Custom Overlays
|
|
20
|
+
|
|
21
|
+
For overlays not managed by `DialogService` or `DrawerService` (e.g., custom popovers, app navigation panels, kebab menus), register them manually:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
@Component({ ... })
|
|
25
|
+
export class MyComponent {
|
|
26
|
+
private readonly orchestrator = inject(OverlayOrchestrator);
|
|
27
|
+
private overlayId: string | null = null;
|
|
28
|
+
|
|
29
|
+
open(): void {
|
|
30
|
+
// Register with a priority — closes all lower-priority overlays
|
|
31
|
+
this.overlayId = this.orchestrator.register({
|
|
32
|
+
priority: OVERLAY_PRIORITY.POPOVER,
|
|
33
|
+
type: "my-popover",
|
|
34
|
+
close: () => this.close(),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
close(): void {
|
|
39
|
+
if (this.overlayId) {
|
|
40
|
+
this.orchestrator.unregister(this.overlayId);
|
|
41
|
+
this.overlayId = null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ... your close logic
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Registering App Navigation
|
|
50
|
+
|
|
51
|
+
The app shell sidebar should register at the highest priority so it always opens on top:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
@Component({ ... })
|
|
55
|
+
export class AppShellComponent {
|
|
56
|
+
private readonly orchestrator = inject(OverlayOrchestrator);
|
|
57
|
+
private navOverlayId: string | null = null;
|
|
58
|
+
|
|
59
|
+
openNav(): void {
|
|
60
|
+
this.navOverlayId = this.orchestrator.register({
|
|
61
|
+
priority: OVERLAY_PRIORITY.NAVIGATION,
|
|
62
|
+
type: "navigation",
|
|
63
|
+
close: () => this.closeNav(),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
closeNav(): void {
|
|
68
|
+
if (this.navOverlayId) {
|
|
69
|
+
this.orchestrator.unregister(this.navOverlayId);
|
|
70
|
+
this.navOverlayId = null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ... your close logic
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Guarding Before Opening
|
|
79
|
+
|
|
80
|
+
Check if a higher-priority overlay is already open before opening yours:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
if (!this.orchestrator.hasOverlayAtOrAbove(OVERLAY_PRIORITY.DIALOG)) {
|
|
84
|
+
this.openDrawer();
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## API
|
|
91
|
+
|
|
92
|
+
### OverlayOrchestrator (Injectable)
|
|
93
|
+
|
|
94
|
+
#### Methods
|
|
95
|
+
|
|
96
|
+
| Method | Signature | Description |
|
|
97
|
+
| --------------------- | --------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
98
|
+
| `register` | `(entry: Omit<OverlayEntry, 'id'>) => string` | Register an overlay. Auto-closes lower-priority overlays. Returns a unique ID. |
|
|
99
|
+
| `unregister` | `(id: string) => void` | Remove an overlay by ID. Call when the overlay closes. |
|
|
100
|
+
| `closeAll` | `() => void` | Close all overlays, lowest priority first. |
|
|
101
|
+
| `closeAtOrBelow` | `(priority: number) => void` | Close all overlays at or below the given priority. |
|
|
102
|
+
| `hasOverlayAtOrAbove` | `(priority: number) => boolean` | Check if any overlay at or above a priority is open. |
|
|
103
|
+
| `hasOverlayOfType` | `(type: string) => boolean` | Check if any overlay of a given type is open. |
|
|
104
|
+
|
|
105
|
+
#### Signals (Reactive)
|
|
106
|
+
|
|
107
|
+
| Signal | Type | Description |
|
|
108
|
+
| ------------------ | ------------------------------ | ---------------------------------- |
|
|
109
|
+
| `hasActiveOverlay` | `Signal<boolean>` | Whether any overlay is open. |
|
|
110
|
+
| `topOverlay` | `Signal<OverlayEntry \| null>` | The highest-priority open overlay. |
|
|
111
|
+
| `count` | `Signal<number>` | Number of active overlays. |
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Priority Levels
|
|
116
|
+
|
|
117
|
+
Default priority constants are provided via `OVERLAY_PRIORITY`. You can use any number — these are conventions, not constraints.
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { OVERLAY_PRIORITY } from '@frame-kit/ui-ng';
|
|
121
|
+
|
|
122
|
+
OVERLAY_PRIORITY.TOOLTIP; // 0 — tooltips, inline hints
|
|
123
|
+
OVERLAY_PRIORITY.POPOVER; // 10 — dropdown menus, kebab menus
|
|
124
|
+
OVERLAY_PRIORITY.DRAWER; // 20 — side panels, detail drawers
|
|
125
|
+
OVERLAY_PRIORITY.DIALOG; // 30 — modal dialogs, confirmations
|
|
126
|
+
OVERLAY_PRIORITY.NAVIGATION; // 40 — app-level navigation sidebar
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Custom Priorities
|
|
130
|
+
|
|
131
|
+
Use any number to fine-tune behavior:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
// A toast notification that sits between popover and drawer
|
|
135
|
+
orchestrator.register({
|
|
136
|
+
priority: 15,
|
|
137
|
+
type: 'toast',
|
|
138
|
+
close: () => this.dismissToast(),
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## OverlayEntry Interface
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
interface OverlayEntry {
|
|
148
|
+
id: string; // Auto-generated unique ID
|
|
149
|
+
priority: number; // Higher = stays open longer
|
|
150
|
+
type: string; // Label for debugging/querying
|
|
151
|
+
close: () => void; // Called by orchestrator to close
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Behavior Rules
|
|
158
|
+
|
|
159
|
+
1. **Opening a new overlay closes all overlays with LOWER priority.**
|
|
160
|
+
- Opening a dialog (30) closes drawers (20), popovers (10), tooltips (0).
|
|
161
|
+
- Opening a drawer (20) closes popovers (10) and tooltips (0).
|
|
162
|
+
- Opening the nav (40) does not close dialogs (30) — they have lower priority.
|
|
163
|
+
|
|
164
|
+
2. **Overlays with EQUAL or HIGHER priority are left open.**
|
|
165
|
+
- Opening a second dialog does not close the first dialog.
|
|
166
|
+
- Opening the nav while a dialog is open leaves the dialog open.
|
|
167
|
+
|
|
168
|
+
3. **Unregistration is the consumer's responsibility.**
|
|
169
|
+
- The orchestrator calls `close()` on entries to request closure.
|
|
170
|
+
- The consumer must call `unregister(id)` when the overlay actually closes.
|
|
171
|
+
- `DialogService` and `DrawerService` handle this automatically.
|
|
172
|
+
|
|
173
|
+
4. **Priority is set per instance, not per type.**
|
|
174
|
+
- The same component can register at different priorities depending on context.
|
|
175
|
+
- A critical confirmation dialog could register at 35 to stay above normal dialogs.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Import
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
import { OverlayOrchestrator, OVERLAY_PRIORITY } from '@frame-kit/ui-ng';
|
|
183
|
+
import type { OverlayEntry } from '@frame-kit/ui-ng';
|
|
184
|
+
```
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# SpotlightService
|
|
2
|
+
|
|
3
|
+
Coordinates a single global "active key" with reference-counted holders, so unrelated parts of the DOM can pulse together when the same key is active. The `fkSpotlightTrigger` and `fkSpotlightTarget` directives are the typical consumers — this service is the registry they talk through.
|
|
4
|
+
|
|
5
|
+
For most use cases you don't inject `SpotlightService` directly; you bind the directives to a shared key. Reach for the service when you need a programmatic activation (e.g. auto-spotlight on panel open) that should coexist with hover-driven triggers.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Initialization
|
|
10
|
+
|
|
11
|
+
Provided in root (`@Injectable({ providedIn: "root" })`). No setup required:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { SpotlightService } from '@frame-kit/ui-ng';
|
|
15
|
+
|
|
16
|
+
export class MyComponent {
|
|
17
|
+
private readonly spotlight = inject(SpotlightService);
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
There's a single coordinator across the whole app — keys broadcast in any feature module are picked up by targets in any other module.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## API
|
|
26
|
+
|
|
27
|
+
### Signals
|
|
28
|
+
|
|
29
|
+
| Signal | Type | Description |
|
|
30
|
+
| ----------- | ------------------------ | ------------------------------------------------------------------- |
|
|
31
|
+
| `activeKey` | `Signal<string \| null>` | The currently active spotlight key, or `null` when nothing is held. |
|
|
32
|
+
|
|
33
|
+
### Methods
|
|
34
|
+
|
|
35
|
+
| Method | Returns | Description |
|
|
36
|
+
| ----------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
37
|
+
| `activate(key)` | `void` | Add a holder for `key` and set it as the active key. If a different key is currently active, this replaces it (last write wins). |
|
|
38
|
+
| `deactivate(key)` | `void` | Release a holder for `key`. The key only clears when every holder has released; if it's still the active key, `activeKey` resets to `null`. |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const spotlight = inject(SpotlightService);
|
|
46
|
+
|
|
47
|
+
// One-shot activation (e.g. on panel open) — release after 2s
|
|
48
|
+
spotlight.activate('open-roadmap');
|
|
49
|
+
setTimeout(() => spotlight.deactivate('open-roadmap'), 2000);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
A hover-driven `fkSpotlightTrigger` activating the same key while the timer is still pending coexists with this programmatic holder — the spotlight only clears when both have released.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Behavior Notes
|
|
57
|
+
|
|
58
|
+
- **Holders are reference-counted, not idempotent.** Calling `activate(key)` twice requires two `deactivate(key)` calls to clear. This is what lets a hover trigger and a programmatic one-shot coexist without one cancelling the other.
|
|
59
|
+
- **Single global active key.** If `activate("foo")` runs while `"bar"` is held, the active key flips to `"foo"`. The `"bar"` holders still count, so re-activating `"bar"` later restores it. This matches the primary use case (onboarding "find this thing" cues are mutually exclusive by nature).
|
|
60
|
+
- **Pure read interface.** `activeKey` is exposed as a read-only signal — consumers (typically the `fkSpotlightTarget` directive) read it via `computed(() => spotlight.activeKey() === myKey)` and react.
|
|
61
|
+
- `deactivate(key)` on a key with no holders is a no-op — safe to call defensively.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# ToastService
|
|
2
|
+
|
|
3
|
+
Global notification queue. Push transient messages onto a single stack rendered by `<fk-toast-container>` somewhere near the app root. Default toasts cover the four severities (success / error / warning / info); custom-component toasts let you embed action affordances (retry buttons, undo links, etc.) inside the toast body.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Initialization
|
|
8
|
+
|
|
9
|
+
Provided in root (`@Injectable({ providedIn: "root" })`). No setup required to use:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { ToastService } from '@frame-kit/ui-ng';
|
|
13
|
+
|
|
14
|
+
export class MyComponent {
|
|
15
|
+
private readonly toast = inject(ToastService);
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Container placement
|
|
20
|
+
|
|
21
|
+
The service holds the queue; rendering is the consumer's job. Place a single `<fk-toast-container />` near the app root so toasts surface above everything else:
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<!-- app.component.html -->
|
|
25
|
+
<router-outlet />
|
|
26
|
+
<fk-toast-container />
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Optional configuration
|
|
30
|
+
|
|
31
|
+
Override defaults via the `TOAST_CONFIG` injection token at app bootstrap:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { TOAST_CONFIG } from '@frame-kit/ui-ng';
|
|
35
|
+
|
|
36
|
+
bootstrapApplication(AppComponent, {
|
|
37
|
+
providers: [
|
|
38
|
+
{
|
|
39
|
+
provide: TOAST_CONFIG,
|
|
40
|
+
useValue: { defaultDuration: 4000, errorDuration: 10000 },
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If absent, defaults are 5000 ms for non-error toasts and 8000 ms for errors.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## API
|
|
51
|
+
|
|
52
|
+
### Signals
|
|
53
|
+
|
|
54
|
+
| Signal | Type | Description |
|
|
55
|
+
| -------- | ----------------- | --------------------------------------------------------- |
|
|
56
|
+
| `toasts` | `Signal<Toast[]>` | Current toast stack. The container renders this directly. |
|
|
57
|
+
|
|
58
|
+
### Severity helpers
|
|
59
|
+
|
|
60
|
+
| Method | Returns | Description |
|
|
61
|
+
| --------------------------- | -------- | ---------------------------------------------------------------------- |
|
|
62
|
+
| `success(summary, detail?)` | `string` | Push a green/success toast. Returns the toast id for manual dismissal. |
|
|
63
|
+
| `error(summary, detail?)` | `string` | Push a red/error toast. Defaults to the longer `errorDuration`. |
|
|
64
|
+
| `warning(summary, detail?)` | `string` | Push a yellow/warning toast. |
|
|
65
|
+
| `info(summary, detail?)` | `string` | Push a neutral/info toast. |
|
|
66
|
+
|
|
67
|
+
### Generic API
|
|
68
|
+
|
|
69
|
+
| Method | Returns | Description |
|
|
70
|
+
| ------------------------------------------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
71
|
+
| `show({ severity, summary, detail?, duration? })` | `string` | Push a default toast with explicit fields. Returns the toast id. |
|
|
72
|
+
| `open<TData>(component, { severity, data, duration? })` | `ToastRef<TData>` | Push a custom-component toast. Use this when the toast needs interactive children (retry buttons, undo links, progress bars). |
|
|
73
|
+
| `dismiss(id)` | `void` | Remove a toast by id (e.g. when its associated work completes early). |
|
|
74
|
+
| `clear()` | `void` | Drop every queued toast. |
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
### Default severity helpers
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
const toast = inject(ToastService);
|
|
84
|
+
|
|
85
|
+
toast.success('Saved successfully');
|
|
86
|
+
toast.error('Something went wrong', 'Please try again.');
|
|
87
|
+
toast.info('Sync started');
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Custom-component toast
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
toast.open(RetryToastComponent, {
|
|
94
|
+
severity: 'error',
|
|
95
|
+
data: { message: 'Failed to save', retryFn: () => this.save() },
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The custom component receives the `data` payload via DI (typically `inject(TOAST_DATA)` inside the component) and can call `dismiss()` on the returned `ToastRef` to close itself.
|
|
100
|
+
|
|
101
|
+
### Manual dismissal
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
const id = toast.info('Uploading…', '0 of 10 files');
|
|
105
|
+
|
|
106
|
+
// later, when the upload finishes early:
|
|
107
|
+
toast.dismiss(id);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Behavior Notes
|
|
113
|
+
|
|
114
|
+
- **Auto-dismiss** is scheduled per toast at push time. The default duration depends on severity (`errorDuration` for `"error"`, `defaultDuration` otherwise) unless an explicit `duration` is passed.
|
|
115
|
+
- **Stack growth is uncapped** — the service doesn't drop old toasts when the queue grows. The container renders them in arrival order; if you expect bursts (e.g. reacting to a multi-error response), call `clear()` first or batch your message into a single toast.
|
|
116
|
+
- **Custom toasts return a `ToastRef`** with `dismiss()` and the toast id. The base `show()` and severity helpers return just the id — call `dismiss(id)` on the service to remove them.
|
|
117
|
+
- **The container is a separate component** (`fk-toast-container`) — placing it once near the app root is enough; the service is global.
|
|
118
|
+
- **Resolved config** is exposed as `resolvedConfig` on the service for tests or for components that want to align their own timeouts with the toast duration.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { TemplateRef } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
type HeadlineLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
5
|
+
type HeadlineVariant = 'default' | 'muted';
|
|
6
|
+
|
|
7
|
+
declare class HeadlineComponent {
|
|
8
|
+
readonly ariaLabel: _angular_core.InputSignal<string | null>;
|
|
9
|
+
readonly className: _angular_core.InputSignal<string>;
|
|
10
|
+
/** Custom font-size override applied directly to the host element. */
|
|
11
|
+
readonly fontSize: _angular_core.InputSignal<string | null>;
|
|
12
|
+
readonly id: _angular_core.InputSignal<string | null>;
|
|
13
|
+
/** Semantic heading level rendered in the DOM (h1–h6). */
|
|
14
|
+
readonly level: _angular_core.InputSignal<HeadlineLevel>;
|
|
15
|
+
/** Visual style applied to the heading — `"muted"` reduces contrast. */
|
|
16
|
+
readonly variant: _angular_core.InputSignal<HeadlineVariant>;
|
|
17
|
+
/** Hides the heading visually while keeping it in the accessibility tree. */
|
|
18
|
+
readonly visuallyHidden: _angular_core.InputSignal<boolean>;
|
|
19
|
+
private readonly h1;
|
|
20
|
+
private readonly h2;
|
|
21
|
+
private readonly h3;
|
|
22
|
+
private readonly h4;
|
|
23
|
+
private readonly h5;
|
|
24
|
+
private readonly h6;
|
|
25
|
+
private readonly injector;
|
|
26
|
+
private readonly doc;
|
|
27
|
+
readonly classes: _angular_core.Signal<string>;
|
|
28
|
+
get hostClass(): string;
|
|
29
|
+
get hostFontSize(): string | null;
|
|
30
|
+
readonly template: _angular_core.Signal<TemplateRef<unknown>>;
|
|
31
|
+
private static lastWarnedH1Count;
|
|
32
|
+
constructor();
|
|
33
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<HeadlineComponent, never>;
|
|
34
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<HeadlineComponent, "fk-headline", never, { "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "fontSize": { "alias": "fontSize"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "level": { "alias": "level"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "visuallyHidden": { "alias": "visuallyHidden"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { HeadlineComponent };
|
|
38
|
+
export type { HeadlineLevel, HeadlineVariant };
|