@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.
Files changed (220) hide show
  1. package/COMPONENTS.md +683 -0
  2. package/DEVELOPMENT_GUIDE.md +1102 -0
  3. package/LICENSE +21 -0
  4. package/README.md +69 -0
  5. package/THEMING.md +130 -0
  6. package/core/headline/README.md +121 -0
  7. package/core/icon/README.md +173 -0
  8. package/core/image/README.md +210 -0
  9. package/core/link/README.md +297 -0
  10. package/core/separator/README.md +145 -0
  11. package/core/text/README.md +240 -0
  12. package/directives/infinite-scroll/README.md +102 -0
  13. package/directives/spotlight/README.md +154 -0
  14. package/directives/tooltip/README.md +147 -0
  15. package/docs/endpoint-link/README.md +142 -0
  16. package/docs/method-badge/README.md +154 -0
  17. package/fesm2022/frame-kit-ui-ng-core-headline.mjs +122 -0
  18. package/fesm2022/frame-kit-ui-ng-core-headline.mjs.map +1 -0
  19. package/fesm2022/frame-kit-ui-ng-core-icon.mjs +189 -0
  20. package/fesm2022/frame-kit-ui-ng-core-icon.mjs.map +1 -0
  21. package/fesm2022/frame-kit-ui-ng-core-image.mjs +123 -0
  22. package/fesm2022/frame-kit-ui-ng-core-image.mjs.map +1 -0
  23. package/fesm2022/frame-kit-ui-ng-core-link.mjs +369 -0
  24. package/fesm2022/frame-kit-ui-ng-core-link.mjs.map +1 -0
  25. package/fesm2022/frame-kit-ui-ng-core-separator.mjs +59 -0
  26. package/fesm2022/frame-kit-ui-ng-core-separator.mjs.map +1 -0
  27. package/fesm2022/frame-kit-ui-ng-core-text.mjs +204 -0
  28. package/fesm2022/frame-kit-ui-ng-core-text.mjs.map +1 -0
  29. package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs +74 -0
  30. package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs.map +1 -0
  31. package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs +76 -0
  32. package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs.map +1 -0
  33. package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs +425 -0
  34. package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs.map +1 -0
  35. package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs +63 -0
  36. package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs.map +1 -0
  37. package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs +43 -0
  38. package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs.map +1 -0
  39. package/fesm2022/frame-kit-ui-ng-forms.mjs +3632 -0
  40. package/fesm2022/frame-kit-ui-ng-forms.mjs.map +1 -0
  41. package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs +239 -0
  42. package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs.map +1 -0
  43. package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs +132 -0
  44. package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs.map +1 -0
  45. package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs +133 -0
  46. package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs.map +1 -0
  47. package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs +60 -0
  48. package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs.map +1 -0
  49. package/fesm2022/frame-kit-ui-ng-services-toast.mjs +166 -0
  50. package/fesm2022/frame-kit-ui-ng-services-toast.mjs.map +1 -0
  51. package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs +214 -0
  52. package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs.map +1 -0
  53. package/fesm2022/frame-kit-ui-ng-ui-alert.mjs +82 -0
  54. package/fesm2022/frame-kit-ui-ng-ui-alert.mjs.map +1 -0
  55. package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs +76 -0
  56. package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs.map +1 -0
  57. package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs +81 -0
  58. package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs.map +1 -0
  59. package/fesm2022/frame-kit-ui-ng-ui-badge.mjs +81 -0
  60. package/fesm2022/frame-kit-ui-ng-ui-badge.mjs.map +1 -0
  61. package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs +68 -0
  62. package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs.map +1 -0
  63. package/fesm2022/frame-kit-ui-ng-ui-button.mjs +108 -0
  64. package/fesm2022/frame-kit-ui-ng-ui-button.mjs.map +1 -0
  65. package/fesm2022/frame-kit-ui-ng-ui-callout.mjs +58 -0
  66. package/fesm2022/frame-kit-ui-ng-ui-callout.mjs.map +1 -0
  67. package/fesm2022/frame-kit-ui-ng-ui-card.mjs +70 -0
  68. package/fesm2022/frame-kit-ui-ng-ui-card.mjs.map +1 -0
  69. package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs +113 -0
  70. package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs.map +1 -0
  71. package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs +1288 -0
  72. package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs.map +1 -0
  73. package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs +456 -0
  74. package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs.map +1 -0
  75. package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs +398 -0
  76. package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs.map +1 -0
  77. package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs +398 -0
  78. package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs.map +1 -0
  79. package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs +125 -0
  80. package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs.map +1 -0
  81. package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs +113 -0
  82. package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs.map +1 -0
  83. package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs +111 -0
  84. package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs.map +1 -0
  85. package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs +103 -0
  86. package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs.map +1 -0
  87. package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs +135 -0
  88. package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs.map +1 -0
  89. package/fesm2022/frame-kit-ui-ng-ui-loader.mjs +81 -0
  90. package/fesm2022/frame-kit-ui-ng-ui-loader.mjs.map +1 -0
  91. package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs +79 -0
  92. package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs.map +1 -0
  93. package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs +40 -0
  94. package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs.map +1 -0
  95. package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs +110 -0
  96. package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs.map +1 -0
  97. package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs +91 -0
  98. package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs.map +1 -0
  99. package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs +86 -0
  100. package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs.map +1 -0
  101. package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs +443 -0
  102. package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs.map +1 -0
  103. package/fesm2022/frame-kit-ui-ng-ui-note.mjs +56 -0
  104. package/fesm2022/frame-kit-ui-ng-ui-note.mjs.map +1 -0
  105. package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs +105 -0
  106. package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs.map +1 -0
  107. package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs +110 -0
  108. package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs.map +1 -0
  109. package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs +129 -0
  110. package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs.map +1 -0
  111. package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs +42 -0
  112. package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs.map +1 -0
  113. package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs +894 -0
  114. package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs.map +1 -0
  115. package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs +81 -0
  116. package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs.map +1 -0
  117. package/fesm2022/frame-kit-ui-ng-ui-toast.mjs +179 -0
  118. package/fesm2022/frame-kit-ui-ng-ui-toast.mjs.map +1 -0
  119. package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs +143 -0
  120. package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs.map +1 -0
  121. package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs +191 -0
  122. package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs.map +1 -0
  123. package/fesm2022/frame-kit-ui-ng.mjs +58 -0
  124. package/fesm2022/frame-kit-ui-ng.mjs.map +1 -0
  125. package/layouts/app-shell/README.md +357 -0
  126. package/layouts/content-split/README.md +180 -0
  127. package/package.json +253 -0
  128. package/services/overlay-orchestrator/README.md +184 -0
  129. package/services/spotlight/README.md +61 -0
  130. package/services/toast/README.md +118 -0
  131. package/types/frame-kit-ui-ng-core-headline.d.ts +38 -0
  132. package/types/frame-kit-ui-ng-core-icon.d.ts +74 -0
  133. package/types/frame-kit-ui-ng-core-image.d.ts +93 -0
  134. package/types/frame-kit-ui-ng-core-link.d.ts +251 -0
  135. package/types/frame-kit-ui-ng-core-separator.d.ts +28 -0
  136. package/types/frame-kit-ui-ng-core-text.d.ts +186 -0
  137. package/types/frame-kit-ui-ng-directives-infinite-scroll.d.ts +42 -0
  138. package/types/frame-kit-ui-ng-directives-spotlight.d.ts +51 -0
  139. package/types/frame-kit-ui-ng-directives-tooltip.d.ts +70 -0
  140. package/types/frame-kit-ui-ng-docs-endpoint-link.d.ts +43 -0
  141. package/types/frame-kit-ui-ng-docs-method-badge.d.ts +30 -0
  142. package/types/frame-kit-ui-ng-forms.d.ts +1674 -0
  143. package/types/frame-kit-ui-ng-layouts-app-shell.d.ts +75 -0
  144. package/types/frame-kit-ui-ng-layouts-content-split.d.ts +43 -0
  145. package/types/frame-kit-ui-ng-services-overlay-orchestrator.d.ts +96 -0
  146. package/types/frame-kit-ui-ng-services-spotlight.d.ts +32 -0
  147. package/types/frame-kit-ui-ng-services-toast.d.ts +100 -0
  148. package/types/frame-kit-ui-ng-ui-accordion.d.ts +86 -0
  149. package/types/frame-kit-ui-ng-ui-alert.d.ts +34 -0
  150. package/types/frame-kit-ui-ng-ui-avatar-stack.d.ts +38 -0
  151. package/types/frame-kit-ui-ng-ui-avatar.d.ts +36 -0
  152. package/types/frame-kit-ui-ng-ui-badge.d.ts +33 -0
  153. package/types/frame-kit-ui-ng-ui-breadcrumb.d.ts +45 -0
  154. package/types/frame-kit-ui-ng-ui-button.d.ts +48 -0
  155. package/types/frame-kit-ui-ng-ui-callout.d.ts +26 -0
  156. package/types/frame-kit-ui-ng-ui-card.d.ts +30 -0
  157. package/types/frame-kit-ui-ng-ui-copyable-field.d.ts +62 -0
  158. package/types/frame-kit-ui-ng-ui-data-table.d.ts +482 -0
  159. package/types/frame-kit-ui-ng-ui-dialog.d.ts +166 -0
  160. package/types/frame-kit-ui-ng-ui-drawer.d.ts +130 -0
  161. package/types/frame-kit-ui-ng-ui-dropdown-menu.d.ts +77 -0
  162. package/types/frame-kit-ui-ng-ui-editable-field.d.ts +65 -0
  163. package/types/frame-kit-ui-ng-ui-icon-badge.d.ts +45 -0
  164. package/types/frame-kit-ui-ng-ui-icon-list.d.ts +67 -0
  165. package/types/frame-kit-ui-ng-ui-inline-edit.d.ts +44 -0
  166. package/types/frame-kit-ui-ng-ui-list-editor.d.ts +56 -0
  167. package/types/frame-kit-ui-ng-ui-loader.d.ts +32 -0
  168. package/types/frame-kit-ui-ng-ui-menu-item.d.ts +27 -0
  169. package/types/frame-kit-ui-ng-ui-nav-brand.d.ts +25 -0
  170. package/types/frame-kit-ui-ng-ui-nav-group.d.ts +60 -0
  171. package/types/frame-kit-ui-ng-ui-nav-separator.d.ts +33 -0
  172. package/types/frame-kit-ui-ng-ui-node-tree-breadcrumb.d.ts +35 -0
  173. package/types/frame-kit-ui-ng-ui-node-tree.d.ts +135 -0
  174. package/types/frame-kit-ui-ng-ui-note.d.ts +22 -0
  175. package/types/frame-kit-ui-ng-ui-numbered-list.d.ts +52 -0
  176. package/types/frame-kit-ui-ng-ui-pagination.d.ts +49 -0
  177. package/types/frame-kit-ui-ng-ui-progress-bar.d.ts +50 -0
  178. package/types/frame-kit-ui-ng-ui-sidenav-link.d.ts +24 -0
  179. package/types/frame-kit-ui-ng-ui-tabs.d.ts +266 -0
  180. package/types/frame-kit-ui-ng-ui-timeline.d.ts +42 -0
  181. package/types/frame-kit-ui-ng-ui-toast.d.ts +56 -0
  182. package/types/frame-kit-ui-ng-ui-user-menu.d.ts +87 -0
  183. package/types/frame-kit-ui-ng-ui-wizard-dialog.d.ts +116 -0
  184. package/types/frame-kit-ui-ng.d.ts +53 -0
  185. package/ui/accordion/README.md +261 -0
  186. package/ui/alert/README.md +211 -0
  187. package/ui/avatar/README.md +167 -0
  188. package/ui/avatar-stack/README.md +164 -0
  189. package/ui/badge/README.md +162 -0
  190. package/ui/breadcrumb/README.md +240 -0
  191. package/ui/button/README.md +184 -0
  192. package/ui/callout/README.md +159 -0
  193. package/ui/card/README.md +174 -0
  194. package/ui/copyable-field/README.md +235 -0
  195. package/ui/data-table/README.md +408 -0
  196. package/ui/dialog/README.md +222 -0
  197. package/ui/drawer/README.md +274 -0
  198. package/ui/dropdown-menu/README.md +336 -0
  199. package/ui/editable-field/README.md +171 -0
  200. package/ui/icon-badge/README.md +131 -0
  201. package/ui/icon-list/README.md +205 -0
  202. package/ui/inline-edit/README.md +135 -0
  203. package/ui/list-editor/README.md +162 -0
  204. package/ui/loader/README.md +160 -0
  205. package/ui/menu-item/README.md +204 -0
  206. package/ui/nav-brand/README.md +111 -0
  207. package/ui/nav-group/README.md +145 -0
  208. package/ui/nav-separator/README.md +44 -0
  209. package/ui/node-tree/README.md +278 -0
  210. package/ui/node-tree-breadcrumb/README.md +164 -0
  211. package/ui/note/README.md +146 -0
  212. package/ui/numbered-list/README.md +187 -0
  213. package/ui/pagination/README.md +174 -0
  214. package/ui/progress-bar/README.md +223 -0
  215. package/ui/sidenav-link/README.md +214 -0
  216. package/ui/tabs/README.md +204 -0
  217. package/ui/timeline/README.md +285 -0
  218. package/ui/toast/README.md +243 -0
  219. package/ui/user-menu/README.md +260 -0
  220. package/ui/wizard-dialog/README.md +283 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FrameKit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # @frame-kit/ui-ng
2
+
3
+ A **style-agnostic, token-driven Angular UI component library.** Components own structure, layout,
4
+ accessibility, and behavior; their entire appearance comes from `--fk-*` CSS custom properties, so you
5
+ theme the whole library by supplying tokens — never by overriding component CSS.
6
+
7
+ - **Standalone + OnPush + signal inputs** throughout (Angular 21+).
8
+ - **Tree-shakeable** — every component is its own entry point, so you only ship what you import.
9
+ - **Themeable** via [`@frame-kit/tokens`](https://www.npmjs.com/package/@frame-kit/tokens) and your own `--fk-*` overrides.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm i @frame-kit/ui-ng @frame-kit/tokens
15
+ ```
16
+
17
+ Peer dependencies: `@angular/{core,common,forms,router,platform-browser,cdk}` ^21.2 and `rxjs` ^7.
18
+
19
+ ## Quick start
20
+
21
+ **1. Load the default theme** (in `angular.json` → `styles`, order matters):
22
+
23
+ ```jsonc
24
+ "styles": [
25
+ "node_modules/@frame-kit/tokens/base.css",
26
+ "node_modules/@frame-kit/tokens/dark.css", // optional dark mode
27
+ "src/styles.css" // your overrides last
28
+ ]
29
+ ```
30
+
31
+ **2. Register the icons your app uses** (the library ships none):
32
+
33
+ ```ts
34
+ import { provideIcons } from '@frame-kit/ui-ng';
35
+ import { searchIcon, lockIcon } from 'your-icon-source';
36
+
37
+ export const appConfig = {
38
+ providers: [provideIcons({ search: searchIcon, lock: lockIcon })],
39
+ };
40
+ ```
41
+
42
+ **3. Import components where you use them** (standalone):
43
+
44
+ ```ts
45
+ import { Component } from '@angular/core';
46
+ import { ButtonComponent } from '@frame-kit/ui-ng';
47
+
48
+ @Component({
49
+ selector: 'app-example',
50
+ imports: [ButtonComponent],
51
+ template: `<fk-button variant="primary">Save</fk-button>`,
52
+ })
53
+ export class ExampleComponent {}
54
+ ```
55
+
56
+ Both forms work and tree-shake identically — the barrel `@frame-kit/ui-ng` or the per-component entry
57
+ point `@frame-kit/ui-ng/ui/button`. Use the barrel unless you have a reason not to.
58
+
59
+ ## Documentation
60
+
61
+ - **[Component catalog](./COMPONENTS.md)** — every component, with a link to its full README.
62
+ - **[Theming guide](./THEMING.md)** — the `--fk-*` token contract and how to override appearance.
63
+ - **[Development guide](./DEVELOPMENT_GUIDE.md)** — for contributing components.
64
+
65
+ Each component also ships its own `README.md` inside the package.
66
+
67
+ ## License
68
+
69
+ MIT
package/THEMING.md ADDED
@@ -0,0 +1,130 @@
1
+ # Theming `@frame-kit/ui-ng`
2
+
3
+ `@frame-kit/ui-ng` is **style-agnostic**. Components define structure, layout,
4
+ accessibility, and behavior; their appearance comes entirely from `--fk-*` CSS custom
5
+ properties (design tokens). You theme the library by supplying or overriding those tokens —
6
+ never by editing component CSS.
7
+
8
+ ---
9
+
10
+ ## Quick start
11
+
12
+ ```bash
13
+ npm i @frame-kit/ui-ng @frame-kit/tokens
14
+ ```
15
+
16
+ ```ts
17
+ // app config — register the icons your app uses (the library ships none)
18
+ import { provideIcons } from '@frame-kit/ui-ng';
19
+ import { searchIcon, lockIcon } from 'your-icon-source';
20
+
21
+ export const appConfig = {
22
+ providers: [provideIcons({ search: searchIcon, lock: lockIcon })],
23
+ };
24
+ ```
25
+
26
+ ```jsonc
27
+ // angular.json → architect.build.options.styles (order matters)
28
+ "styles": [
29
+ "node_modules/@frame-kit/tokens/base.css", // default neutral theme
30
+ "node_modules/@frame-kit/tokens/dark.css", // optional dark mode
31
+ "src/styles.css" // YOUR overrides come last
32
+ ]
33
+ ```
34
+
35
+ That's it — components now render with the default neutral theme.
36
+
37
+ ---
38
+
39
+ ## How it works (three layers)
40
+
41
+ ```css
42
+ /* 1. Component (ui-ng) — reads tokens with a triple fallback, never hardcodes */
43
+ .fk-button--primary {
44
+ background: var(--fk-button-primary-bg, var(--fk-color-primary, #2563eb));
45
+ }
46
+
47
+ /* 2. @frame-kit/tokens base.css — defines the defaults in :root */
48
+ :root {
49
+ --fk-color-primary: #2563eb;
50
+ --fk-button-primary-bg: var(--fk-color-primary);
51
+ }
52
+
53
+ /* 3. Your app — re-declares only what you want, AFTER the import → cascade wins */
54
+ :root {
55
+ --fk-color-primary: #7c3aed;
56
+ } /* your brand — buttons, links, focus all follow */
57
+ ```
58
+
59
+ You never edit `node_modules`. You layer a thin override stylesheet on top.
60
+
61
+ ---
62
+
63
+ ## Overriding tokens
64
+
65
+ **Two tiers — choose your blast radius:**
66
+
67
+ - Override a **primitive** (`--fk-color-primary`, `--fk-radius-md`, `--fk-font-size-md`) → cascades everywhere.
68
+ - Override a **component token** (`--fk-button-primary-bg`) → affects only that component.
69
+
70
+ ```css
71
+ :root {
72
+ --fk-color-primary: #7c3aed; /* sweeping brand change */
73
+ --fk-radius-md: 4px;
74
+ --fk-font-family-base: 'Geist', sans-serif;
75
+ --fk-button-primary-bg: #111; /* surgical: buttons only */
76
+ }
77
+ ```
78
+
79
+ **Scope it** to part of the DOM (tokens inherit down the tree):
80
+
81
+ ```css
82
+ .marketing {
83
+ --fk-color-primary: #e11d48;
84
+ } /* only this subtree */
85
+ ```
86
+
87
+ **Runtime theming** (no rebuild — they're live CSS variables):
88
+
89
+ ```ts
90
+ document.documentElement.style.setProperty('--fk-color-primary', userColor);
91
+ ```
92
+
93
+ **Dark mode** ships in `dark.css`: it activates on the system preference
94
+ (`prefers-color-scheme: dark`) and on an explicit `html.dark` class (which wins). Toggle dark
95
+ mode by adding/removing `dark` on `<html>`.
96
+
97
+ ---
98
+
99
+ ## The rules (contract)
100
+
101
+ These govern what is and isn't themeable. Contributors must follow them; the guardrail spec
102
+ (`tokens/src/contract.guardrail.spec.ts`) enforces R7.
103
+
104
+ - **R1 — Appearance is tokenized; structure is not.** Color, background, border-color, radius,
105
+ font, spacing/rhythm, shadow, transition, opacity → `var(--fk-*)`. `display`, flex/grid,
106
+ positioning, functional `z-index`, internal geometry → raw CSS, not a customization point.
107
+ - **R2 — Two tiers.** Primitives hold brand values; component tokens reference primitives via `var()`.
108
+ - **R3 — Triple fallback.** `var(--fk-component-x, var(--fk-primitive, <hardcoded>))` — always renders.
109
+ - **R4 — Components consume only `--fk-*` for themeable props** (no raw hex/rgba/hsl as direct values).
110
+ - **R5 — Naming:** `--fk-<scope>-<prop>[-variant][-state]` (e.g. `--fk-button-primary-bg-hover`).
111
+ - **R6 — Encapsulation:** default `Emulated`. No `::ng-deep` / `ViewEncapsulation.None` / `!important` for theming.
112
+ - **R7 — `@frame-kit/tokens` defines a default for every primitive consumed.** Enforced by the guardrail.
113
+ - **R8 — Dark mode remaps color tokens only**, never structural ones.
114
+
115
+ ### Sanctioned exceptions to R6
116
+
117
+ A few uses of `::ng-deep` / `!important` are intentional and **not** for theming (no colors leak):
118
+
119
+ - `core/icon` — `:host ::ng-deep svg` sizes the SVG injected via `[innerHTML]` (unscoped by design).
120
+ - `ui/dialog` — `::ng-deep [fkDialogFooter]/[fkDialogActions]` styles **consumer-projected** content.
121
+ - `ui/progress-bar` — `width: 40% !important` overrides the determinate width binding during the
122
+ indeterminate animation.
123
+
124
+ ---
125
+
126
+ ## Token reference
127
+
128
+ The complete, current list of tokens (with default values) is the generated
129
+ `@frame-kit/tokens` output — see `base.css` / `dark.css`, or the typed `tokens` object from
130
+ the package root. Token _values_ are authored in `tokens/src/scss/tokens.base.scss`.
@@ -0,0 +1,121 @@
1
+ # fk-headline
2
+
3
+ A heading component that renders semantic `h1`–`h6` elements with token-driven typography and optional visually hidden mode.
4
+
5
+ ---
6
+
7
+ ## API
8
+
9
+ ### Inputs
10
+
11
+ | Input | Type | Default | Description |
12
+ | ---------------- | ----------------- | ----------- | ----------------------------------------------------------------------- |
13
+ | `ariaLabel` | `string \| null` | `null` | ARIA label when the visible text is not sufficient |
14
+ | `className` | `string` | `''` | Additional CSS classes for the host |
15
+ | `id` | `string \| null` | `null` | Optional ID for the heading element |
16
+ | `level` | `HeadlineLevel` | `2` | Heading level (`1`–`6`) |
17
+ | `variant` | `HeadlineVariant` | `"default"` | Visual variant (e.g. default, muted) |
18
+ | `visuallyHidden` | `boolean` | `false` | When `true`, hides the heading visually but keeps it for screen readers |
19
+
20
+ Content is provided via projection:
21
+
22
+ ```html
23
+ <fk-headline [level]="2">Section title</fk-headline>
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Features
29
+
30
+ - Renders proper semantic heading elements based on `level`
31
+ - Token-driven typography for each heading level and variant
32
+ - Visually hidden option for screen-reader-only headings
33
+ - Dev-time warning when multiple `h1` elements are detected on a page
34
+
35
+ ---
36
+
37
+ ## Quick Start
38
+
39
+ ```html
40
+ <fk-headline [level]="1"> Project dashboard </fk-headline>
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Import
46
+
47
+ ```ts
48
+ import { HeadlineComponent } from '@frame-kit/ui-ng';
49
+ ```
50
+
51
+ ```ts
52
+ @Component({
53
+ selector: 'app-example',
54
+ imports: [HeadlineComponent],
55
+ templateUrl: './example.component.html',
56
+ })
57
+ export class ExampleComponent {}
58
+ ```
59
+
60
+ ---
61
+
62
+ ## Selector
63
+
64
+ ```html
65
+ <fk-headline></fk-headline>
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Examples
71
+
72
+ ### Heading hierarchy
73
+
74
+ ```html
75
+ <fk-headline [level]="1">Dashboard</fk-headline>
76
+ <fk-headline [level]="2">Open projects</fk-headline>
77
+ <fk-headline [level]="3">Pending approvals</fk-headline>
78
+ ```
79
+
80
+ ### Muted variant
81
+
82
+ ```html
83
+ <fk-headline [level]="4" variant="muted"> Optional details </fk-headline>
84
+ ```
85
+
86
+ ### Visually hidden heading
87
+
88
+ ```html
89
+ <fk-headline [level]="2" [visuallyHidden]="true"> Recent activity </fk-headline>
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Accessibility
95
+
96
+ - Use `level` to maintain a logical heading order (only one `h1` per page is recommended).
97
+ - When `visuallyHidden` is `true`, the heading remains in the accessibility tree while being visually hidden using a screen-reader-only utility class.
98
+ - In dev mode, the component warns if multiple `h1` elements are detected, encouraging good document structure.
99
+
100
+ ---
101
+
102
+ ## Design Tokens
103
+
104
+ `fk-headline` uses heading typography tokens such as:
105
+
106
+ ```scss
107
+ --fk-headline-h1-font-size;
108
+ --fk-headline-h2-font-size;
109
+ --fk-headline-h3-font-size;
110
+ --fk-headline-color;
111
+ --fk-headline-muted-color;
112
+ ```
113
+
114
+ Override in your theme as needed to match your brand type scale.
115
+
116
+ ---
117
+
118
+ ## Behavior Notes
119
+
120
+ - `variant="muted"` adds a `fk-headline--muted` class, typically reducing contrast or emphasis.
121
+ - When used as a visual-only heading (for example inside a card), choose an appropriate `level` relative to the surrounding document structure.
@@ -0,0 +1,173 @@
1
+ # fk-icon
2
+
3
+ An SVG icon renderer for Angular that pulls icons from a shared registry and supports token-driven size and color.
4
+
5
+ ---
6
+
7
+ ## API
8
+
9
+ ### Inputs
10
+
11
+ | Input | Type | Default | Description |
12
+ | ------------ | --------------------- | ----------- | ----------------------------------------------------------------------------- |
13
+ | `name` | `string` (required) | — | Icon name registered in `IconRegistryService` |
14
+ | `size` | `IconSize \| string` | `"md"` | Preset size (`xs`–`xl`) or custom CSS size string (e.g. `"20px"`, `"1.5rem"`) |
15
+ | `color` | `IconColor \| string` | `"inherit"` | Color variant or custom CSS color value |
16
+ | `className` | `string` | `''` | Additional CSS classes merged onto the host element |
17
+ | `id` | `string \| null` | `null` | Optional ID for the icon element |
18
+ | `ariaLabel` | `string \| null` | `null` | Accessible label when the icon conveys meaning |
19
+ | `ariaHidden` | `boolean \| null` | `null` | Explicit ARIA hidden flag; when `null`, derived from `ariaLabel` |
20
+
21
+ `size` supports named presets (`xs`, `sm`, `md`, `lg`, `xl`). Any other value is treated as a custom CSS `font-size`.
22
+
23
+ ### Outputs
24
+
25
+ `fk-icon` is presentational and does not emit outputs.
26
+
27
+ ---
28
+
29
+ ## Features
30
+
31
+ - Centralized SVG icon management via `IconRegistryService`
32
+ - Size presets plus custom sizing via `size`
33
+ - Color variants mapped to tokens, with support for custom CSS colors
34
+ - Smart accessibility defaults (`aria-hidden` unless labeled)
35
+
36
+ ---
37
+
38
+ ## Quick Start
39
+
40
+ \`\`\`ts
41
+ constructor(private readonly iconRegistry: IconRegistryService) {
42
+ this.iconRegistry.registerIcon("check", "<svg>...</svg>");
43
+ }
44
+ \`\`\`
45
+
46
+ \`\`\`html
47
+ <fk-icon name="check" color="success"></fk-icon>
48
+ \`\`\`
49
+
50
+ ---
51
+
52
+ ## Import
53
+
54
+ \`\`\`ts
55
+ import { IconComponent } from "@frame-kit/ui-ng";
56
+ \`\`\`
57
+
58
+ \`\`\`ts
59
+ @Component({
60
+ selector: "app-example",
61
+ imports: [IconComponent],
62
+ templateUrl: "./example.component.html",
63
+ })
64
+ export class ExampleComponent {}
65
+ \`\`\`
66
+
67
+ ---
68
+
69
+ ## Selector
70
+
71
+ \`\`\`html
72
+ <fk-icon></fk-icon>
73
+ \`\`\`
74
+
75
+ ---
76
+
77
+ ## Examples
78
+
79
+ ### Size presets
80
+
81
+ \`\`\`html
82
+ <fk-icon name="home" size="xs"></fk-icon>
83
+ <fk-icon name="home" size="sm"></fk-icon>
84
+ <fk-icon name="home" size="md"></fk-icon>
85
+ <fk-icon name="home" size="lg"></fk-icon>
86
+ <fk-icon name="home" size="xl"></fk-icon>
87
+ \`\`\`
88
+
89
+ ### Custom size
90
+
91
+ \`\`\`html
92
+ <fk-icon name="logo" size="32px"></fk-icon>
93
+ <fk-icon name="logo" size="2rem"></fk-icon>
94
+ \`\`\`
95
+
96
+ ### Color variants
97
+
98
+ \`\`\`html
99
+ <fk-icon name="info" color="default"></fk-icon>
100
+ <fk-icon name="info" color="muted"></fk-icon>
101
+ <fk-icon name="check-circle" color="success"></fk-icon>
102
+ <fk-icon name="alert-circle" color="danger"></fk-icon>
103
+ \`\`\`
104
+
105
+ ### Custom color
106
+
107
+ \`\`\`html
108
+ <fk-icon name="star" color="#facc15"></fk-icon>
109
+ \`\`\`
110
+
111
+ ### Accessible icons
112
+
113
+ \`\`\`html
114
+
115
+ <!-- Decorative icon (hidden from screen readers) -->
116
+
117
+ <fk-icon name="chevron-right"></fk-icon>
118
+
119
+ <!-- Meaningful icon with label -->
120
+
121
+ <fk-icon name="warning" ariaLabel="High priority"></fk-icon>
122
+ \`\`\`
123
+
124
+ ---
125
+
126
+ ## Accessibility
127
+
128
+ - If `ariaHidden` is `null` and `ariaLabel` is not provided, the icon is treated as decorative (`aria-hidden="true"`)
129
+ - If `ariaLabel` is provided, the icon gets `role="img"` and `aria-hidden` is not applied
130
+ - Use `ariaLabel` for standalone icons that convey meaning; leave it unset for purely decorative icons
131
+
132
+ ---
133
+
134
+ ## Design Tokens
135
+
136
+ `fk-icon` uses icon tokens for presets and colors:
137
+
138
+ \`\`\`scss
139
+ --fk-icon-size-xs;
140
+ --fk-icon-size-sm;
141
+ --fk-icon-size-md;
142
+ --fk-icon-size-lg;
143
+ --fk-icon-size-xl;
144
+
145
+ --fk-icon-color-default;
146
+ --fk-icon-color-muted;
147
+ --fk-icon-color-primary;
148
+ --fk-icon-color-danger;
149
+ --fk-icon-color-success;
150
+ \`\`\`
151
+
152
+ Override tokens in your application stylesheet:
153
+
154
+ \`\`\`scss
155
+ :root {
156
+ --fk-icon-size-md: 1.25rem;
157
+ }
158
+ \`\`\`
159
+
160
+ ---
161
+
162
+ ## Behavior Notes
163
+
164
+ - In dev mode, attempting to render a non-registered `name` logs a console warning
165
+ - When `size` is not one of the presets, a custom `font-size` is applied via inline style
166
+
167
+ ---
168
+
169
+ ## Security
170
+
171
+ `IconRegistryService.registerIcon` calls `bypassSecurityTrustHtml` on the SVG content it receives. The bypass is required: Angular's HTML sanitizer strips most SVG attributes that icons rely on, so the registry has to mark icons as trusted. The safety story rests on **every registered SVG originating from a build-time import** of an `.svg` file in `libs/icons/src/lib/icons/svg/**` — never from a runtime fetch and never from an inline string literal in a feature module.
172
+
173
+ A repo-level guardrail enforces this: `libs/ui-ng/src/lib/core/icon/icon-registry.guardrail.spec.ts` walks every production TypeScript file under `apps/` and `libs/` and fails if it finds a `<svg` literal outside the icon library or the registry's own normalization regex. Any future caller that hand-rolls an SVG string trips the test.