@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/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.
|