@frame-kit/ui-ng 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENTS.md +683 -0
- package/DEVELOPMENT_GUIDE.md +1102 -0
- package/LICENSE +21 -0
- package/README.md +69 -0
- package/THEMING.md +130 -0
- package/core/headline/README.md +121 -0
- package/core/icon/README.md +173 -0
- package/core/image/README.md +210 -0
- package/core/link/README.md +297 -0
- package/core/separator/README.md +145 -0
- package/core/text/README.md +240 -0
- package/directives/infinite-scroll/README.md +102 -0
- package/directives/spotlight/README.md +154 -0
- package/directives/tooltip/README.md +147 -0
- package/docs/endpoint-link/README.md +142 -0
- package/docs/method-badge/README.md +154 -0
- package/fesm2022/frame-kit-ui-ng-core-headline.mjs +122 -0
- package/fesm2022/frame-kit-ui-ng-core-headline.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-icon.mjs +189 -0
- package/fesm2022/frame-kit-ui-ng-core-icon.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-image.mjs +123 -0
- package/fesm2022/frame-kit-ui-ng-core-image.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-link.mjs +369 -0
- package/fesm2022/frame-kit-ui-ng-core-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-separator.mjs +59 -0
- package/fesm2022/frame-kit-ui-ng-core-separator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-core-text.mjs +204 -0
- package/fesm2022/frame-kit-ui-ng-core-text.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs +74 -0
- package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs +76 -0
- package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs +425 -0
- package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs +63 -0
- package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs +43 -0
- package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-forms.mjs +3632 -0
- package/fesm2022/frame-kit-ui-ng-forms.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs +239 -0
- package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs +132 -0
- package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs +133 -0
- package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs +60 -0
- package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-services-toast.mjs +166 -0
- package/fesm2022/frame-kit-ui-ng-services-toast.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs +214 -0
- package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-alert.mjs +82 -0
- package/fesm2022/frame-kit-ui-ng-ui-alert.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs +76 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-badge.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs +68 -0
- package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-button.mjs +108 -0
- package/fesm2022/frame-kit-ui-ng-ui-button.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-callout.mjs +58 -0
- package/fesm2022/frame-kit-ui-ng-ui-callout.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-card.mjs +70 -0
- package/fesm2022/frame-kit-ui-ng-ui-card.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs +113 -0
- package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs +1288 -0
- package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs +456 -0
- package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs +398 -0
- package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs +398 -0
- package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs +125 -0
- package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs +113 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs +111 -0
- package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs +103 -0
- package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs +135 -0
- package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-loader.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-loader.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs +79 -0
- package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs +40 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs +110 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs +91 -0
- package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs +86 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs +443 -0
- package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-note.mjs +56 -0
- package/fesm2022/frame-kit-ui-ng-ui-note.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs +105 -0
- package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs +110 -0
- package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs +129 -0
- package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs +42 -0
- package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs +894 -0
- package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs +81 -0
- package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-toast.mjs +179 -0
- package/fesm2022/frame-kit-ui-ng-ui-toast.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs +143 -0
- package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs +191 -0
- package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs.map +1 -0
- package/fesm2022/frame-kit-ui-ng.mjs +58 -0
- package/fesm2022/frame-kit-ui-ng.mjs.map +1 -0
- package/layouts/app-shell/README.md +357 -0
- package/layouts/content-split/README.md +180 -0
- package/package.json +253 -0
- package/services/overlay-orchestrator/README.md +184 -0
- package/services/spotlight/README.md +61 -0
- package/services/toast/README.md +118 -0
- package/types/frame-kit-ui-ng-core-headline.d.ts +38 -0
- package/types/frame-kit-ui-ng-core-icon.d.ts +74 -0
- package/types/frame-kit-ui-ng-core-image.d.ts +93 -0
- package/types/frame-kit-ui-ng-core-link.d.ts +251 -0
- package/types/frame-kit-ui-ng-core-separator.d.ts +28 -0
- package/types/frame-kit-ui-ng-core-text.d.ts +186 -0
- package/types/frame-kit-ui-ng-directives-infinite-scroll.d.ts +42 -0
- package/types/frame-kit-ui-ng-directives-spotlight.d.ts +51 -0
- package/types/frame-kit-ui-ng-directives-tooltip.d.ts +70 -0
- package/types/frame-kit-ui-ng-docs-endpoint-link.d.ts +43 -0
- package/types/frame-kit-ui-ng-docs-method-badge.d.ts +30 -0
- package/types/frame-kit-ui-ng-forms.d.ts +1674 -0
- package/types/frame-kit-ui-ng-layouts-app-shell.d.ts +75 -0
- package/types/frame-kit-ui-ng-layouts-content-split.d.ts +43 -0
- package/types/frame-kit-ui-ng-services-overlay-orchestrator.d.ts +96 -0
- package/types/frame-kit-ui-ng-services-spotlight.d.ts +32 -0
- package/types/frame-kit-ui-ng-services-toast.d.ts +100 -0
- package/types/frame-kit-ui-ng-ui-accordion.d.ts +86 -0
- package/types/frame-kit-ui-ng-ui-alert.d.ts +34 -0
- package/types/frame-kit-ui-ng-ui-avatar-stack.d.ts +38 -0
- package/types/frame-kit-ui-ng-ui-avatar.d.ts +36 -0
- package/types/frame-kit-ui-ng-ui-badge.d.ts +33 -0
- package/types/frame-kit-ui-ng-ui-breadcrumb.d.ts +45 -0
- package/types/frame-kit-ui-ng-ui-button.d.ts +48 -0
- package/types/frame-kit-ui-ng-ui-callout.d.ts +26 -0
- package/types/frame-kit-ui-ng-ui-card.d.ts +30 -0
- package/types/frame-kit-ui-ng-ui-copyable-field.d.ts +62 -0
- package/types/frame-kit-ui-ng-ui-data-table.d.ts +482 -0
- package/types/frame-kit-ui-ng-ui-dialog.d.ts +166 -0
- package/types/frame-kit-ui-ng-ui-drawer.d.ts +130 -0
- package/types/frame-kit-ui-ng-ui-dropdown-menu.d.ts +77 -0
- package/types/frame-kit-ui-ng-ui-editable-field.d.ts +65 -0
- package/types/frame-kit-ui-ng-ui-icon-badge.d.ts +45 -0
- package/types/frame-kit-ui-ng-ui-icon-list.d.ts +67 -0
- package/types/frame-kit-ui-ng-ui-inline-edit.d.ts +44 -0
- package/types/frame-kit-ui-ng-ui-list-editor.d.ts +56 -0
- package/types/frame-kit-ui-ng-ui-loader.d.ts +32 -0
- package/types/frame-kit-ui-ng-ui-menu-item.d.ts +27 -0
- package/types/frame-kit-ui-ng-ui-nav-brand.d.ts +25 -0
- package/types/frame-kit-ui-ng-ui-nav-group.d.ts +60 -0
- package/types/frame-kit-ui-ng-ui-nav-separator.d.ts +33 -0
- package/types/frame-kit-ui-ng-ui-node-tree-breadcrumb.d.ts +35 -0
- package/types/frame-kit-ui-ng-ui-node-tree.d.ts +135 -0
- package/types/frame-kit-ui-ng-ui-note.d.ts +22 -0
- package/types/frame-kit-ui-ng-ui-numbered-list.d.ts +52 -0
- package/types/frame-kit-ui-ng-ui-pagination.d.ts +49 -0
- package/types/frame-kit-ui-ng-ui-progress-bar.d.ts +50 -0
- package/types/frame-kit-ui-ng-ui-sidenav-link.d.ts +24 -0
- package/types/frame-kit-ui-ng-ui-tabs.d.ts +266 -0
- package/types/frame-kit-ui-ng-ui-timeline.d.ts +42 -0
- package/types/frame-kit-ui-ng-ui-toast.d.ts +56 -0
- package/types/frame-kit-ui-ng-ui-user-menu.d.ts +87 -0
- package/types/frame-kit-ui-ng-ui-wizard-dialog.d.ts +116 -0
- package/types/frame-kit-ui-ng.d.ts +53 -0
- package/ui/accordion/README.md +261 -0
- package/ui/alert/README.md +211 -0
- package/ui/avatar/README.md +167 -0
- package/ui/avatar-stack/README.md +164 -0
- package/ui/badge/README.md +162 -0
- package/ui/breadcrumb/README.md +240 -0
- package/ui/button/README.md +184 -0
- package/ui/callout/README.md +159 -0
- package/ui/card/README.md +174 -0
- package/ui/copyable-field/README.md +235 -0
- package/ui/data-table/README.md +408 -0
- package/ui/dialog/README.md +222 -0
- package/ui/drawer/README.md +274 -0
- package/ui/dropdown-menu/README.md +336 -0
- package/ui/editable-field/README.md +171 -0
- package/ui/icon-badge/README.md +131 -0
- package/ui/icon-list/README.md +205 -0
- package/ui/inline-edit/README.md +135 -0
- package/ui/list-editor/README.md +162 -0
- package/ui/loader/README.md +160 -0
- package/ui/menu-item/README.md +204 -0
- package/ui/nav-brand/README.md +111 -0
- package/ui/nav-group/README.md +145 -0
- package/ui/nav-separator/README.md +44 -0
- package/ui/node-tree/README.md +278 -0
- package/ui/node-tree-breadcrumb/README.md +164 -0
- package/ui/note/README.md +146 -0
- package/ui/numbered-list/README.md +187 -0
- package/ui/pagination/README.md +174 -0
- package/ui/progress-bar/README.md +223 -0
- package/ui/sidenav-link/README.md +214 -0
- package/ui/tabs/README.md +204 -0
- package/ui/timeline/README.md +285 -0
- package/ui/toast/README.md +243 -0
- package/ui/user-menu/README.md +260 -0
- package/ui/wizard-dialog/README.md +283 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# fk-sidenav-link
|
|
2
|
+
|
|
3
|
+
A token-driven sidebar navigation link that renders an icon and label, automatically hiding the label when the parent `fk-app-shell` is collapsed.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## API
|
|
8
|
+
|
|
9
|
+
### Inputs
|
|
10
|
+
|
|
11
|
+
| Input | Type | Default | Description |
|
|
12
|
+
| ---------- | -------------------------------- | ------- | ------------------------------------------------------------------------------ |
|
|
13
|
+
| icon | `string` | — | **Required.** Icon name from the icon registry |
|
|
14
|
+
| iconSize | `IconSize` | `"sm"` | Size of the icon (`"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`, or custom CSS value) |
|
|
15
|
+
| label | `string` | — | **Required.** Visible text label |
|
|
16
|
+
| routerLink | `string` \| `string[]` \| `null` | `null` | Angular Router link — renders `<a>` when set |
|
|
17
|
+
| exact | `boolean` | `false` | Use exact match for `routerLinkActive` highlighting |
|
|
18
|
+
|
|
19
|
+
### Methods
|
|
20
|
+
|
|
21
|
+
| Method | Description |
|
|
22
|
+
| --------- | ------------------------------------------------------------------------ |
|
|
23
|
+
| dismiss() | Calls `dismissSidenav()` on the parent app-shell (closes mobile overlay) |
|
|
24
|
+
|
|
25
|
+
### Computed (read-only)
|
|
26
|
+
|
|
27
|
+
| Property | Type | Description |
|
|
28
|
+
| ----------- | ----------------- | -------------------------------------------------- |
|
|
29
|
+
| isCollapsed | `Signal<boolean>` | Whether the parent app-shell is in collapsed state |
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
- Renders `<a>` with `routerLink` when a route is provided, `<button>` otherwise
|
|
36
|
+
- `routerLinkActive` class applied automatically for active route highlighting
|
|
37
|
+
- Label hides when parent `fk-app-shell` is collapsed (icon-only rail)
|
|
38
|
+
- Auto-dismisses mobile sidebar overlay on click
|
|
39
|
+
- Works standalone (outside an app-shell) — collapse detection gracefully defaults to `false`
|
|
40
|
+
- Token-driven styling with full override capability
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
```html
|
|
47
|
+
<fk-sidenav-link icon="chart-activity-fill" label="Overview" routerLink="/app" [exact]="true" />
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Import
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { SidenavLinkComponent } from '@frame-kit/ui-ng';
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
@Component({
|
|
60
|
+
selector: 'app-sidebar',
|
|
61
|
+
imports: [SidenavLinkComponent],
|
|
62
|
+
templateUrl: './sidebar.component.html',
|
|
63
|
+
})
|
|
64
|
+
export class SidebarComponent {}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Selector
|
|
70
|
+
|
|
71
|
+
```html
|
|
72
|
+
<fk-sidenav-link />
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Examples
|
|
78
|
+
|
|
79
|
+
### With Router Link
|
|
80
|
+
|
|
81
|
+
```html
|
|
82
|
+
<fk-sidenav-link icon="chart-activity-fill" label="Overview" routerLink="/app" [exact]="true" />
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Button Mode (no route)
|
|
86
|
+
|
|
87
|
+
Renders a `<button>` instead of `<a>`. Useful for actions like opening a dialog.
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<fk-sidenav-link icon="email" label="Notifications" />
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Nav List
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<nav style="display: flex; flex-direction: column; gap: 0.25rem;">
|
|
97
|
+
<fk-sidenav-link icon="chart-activity-fill" label="Overview" routerLink="/app" [exact]="true" />
|
|
98
|
+
<fk-sidenav-link icon="organization" label="Properties" />
|
|
99
|
+
<fk-sidenav-link icon="email" label="Notifications" />
|
|
100
|
+
<fk-sidenav-link icon="lock" label="Compliance" />
|
|
101
|
+
<fk-sidenav-link icon="shield-alert" label="Insurance" />
|
|
102
|
+
</nav>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Inside App Shell
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<fk-app-shell mode="icon">
|
|
109
|
+
<nav appShellSidenav>
|
|
110
|
+
<fk-sidenav-link icon="chart-activity-fill" label="Overview" routerLink="/app" [exact]="true" />
|
|
111
|
+
<fk-sidenav-link icon="organization" label="Properties" />
|
|
112
|
+
<fk-sidenav-link icon="email" label="Notifications" />
|
|
113
|
+
</nav>
|
|
114
|
+
|
|
115
|
+
<div appShellSidenavFooter>
|
|
116
|
+
<fk-sidenav-link icon="info" label="Help & Support" />
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<div appShellContent>
|
|
120
|
+
<router-outlet />
|
|
121
|
+
</div>
|
|
122
|
+
</fk-app-shell>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
When the shell is collapsed, only icons are shown. When expanded, icons and labels are both visible.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Accessibility
|
|
130
|
+
|
|
131
|
+
- Renders a native `<a>` or `<button>` element — keyboard accessible by default
|
|
132
|
+
- Supports Enter and Space through native element behavior
|
|
133
|
+
- `focus-visible` ring applied via CSS token
|
|
134
|
+
- `routerLinkActive` provides visual indication of the current route
|
|
135
|
+
- When collapsed, the icon remains visible and the label is removed from the DOM (not just hidden)
|
|
136
|
+
- When collapsed, the host carries `aria-label="<label>"` so screen readers still get a name for the link, and a tooltip appears to the right on hover or keyboard focus (via the `[fkTooltip]` directive). When expanded, the visible label text serves both purposes — `aria-label` is omitted and the tooltip is disabled.
|
|
137
|
+
|
|
138
|
+
### Recommended
|
|
139
|
+
|
|
140
|
+
Always register the icon before use:
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
provideIcons({
|
|
144
|
+
'chart-activity-fill': chartActivityFill,
|
|
145
|
+
organization,
|
|
146
|
+
email,
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Design Tokens
|
|
153
|
+
|
|
154
|
+
### Component Tokens
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
--fk-sidenav-link-gap
|
|
158
|
+
--fk-sidenav-link-padding-block
|
|
159
|
+
--fk-sidenav-link-padding-inline
|
|
160
|
+
--fk-sidenav-link-radius
|
|
161
|
+
--fk-sidenav-link-bg
|
|
162
|
+
--fk-sidenav-link-bg-hover
|
|
163
|
+
--fk-sidenav-link-bg-active
|
|
164
|
+
--fk-sidenav-link-font-family
|
|
165
|
+
--fk-sidenav-link-font-size
|
|
166
|
+
--fk-sidenav-link-font-weight-active
|
|
167
|
+
--fk-sidenav-link-color
|
|
168
|
+
--fk-sidenav-link-color-hover
|
|
169
|
+
--fk-sidenav-link-color-active
|
|
170
|
+
--fk-sidenav-link-focus-ring
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Each component token falls back to a semantic token, then a raw value. For example:
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
--fk-sidenav-link-color → --fk-color-text → #1f2d3d
|
|
177
|
+
--fk-sidenav-link-color-hover → --fk-color-primary → #0a84ff
|
|
178
|
+
--fk-sidenav-link-color-active → --fk-color-primary → #0a84ff
|
|
179
|
+
--fk-sidenav-link-radius → --fk-radius-md → 0.5rem
|
|
180
|
+
--fk-sidenav-link-bg-hover → --fk-color-surface-dim → #edf1f5
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Customizing Tokens
|
|
184
|
+
|
|
185
|
+
Override tokens at any scope:
|
|
186
|
+
|
|
187
|
+
```css
|
|
188
|
+
:root {
|
|
189
|
+
--fk-sidenav-link-color: #4338ca;
|
|
190
|
+
--fk-sidenav-link-bg-hover: #eef2ff;
|
|
191
|
+
--fk-sidenav-link-bg-active: #e0e7ff;
|
|
192
|
+
--fk-sidenav-link-font-weight-active: 700;
|
|
193
|
+
--fk-sidenav-link-radius: 0.25rem;
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Or scope to a specific context:
|
|
198
|
+
|
|
199
|
+
```css
|
|
200
|
+
.dark-theme fk-sidenav-link {
|
|
201
|
+
--fk-sidenav-link-color: #e2e8f0;
|
|
202
|
+
--fk-sidenav-link-bg-hover: #1e293b;
|
|
203
|
+
--fk-sidenav-link-bg-active: #334155;
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Behavior Notes
|
|
210
|
+
|
|
211
|
+
- When used inside `fk-app-shell`, the component injects the parent via `inject(AppShellComponent, { optional: true })` to read collapse state
|
|
212
|
+
- When used outside an app-shell, `isCollapsed` is always `false` and labels are always visible
|
|
213
|
+
- Clicking any link calls `dismissSidenav()` on the parent shell, which closes the mobile overlay
|
|
214
|
+
- In collapsed state, the anchor centers its icon with `justify-content: center` and removes inline padding via the `.fk-app-shell--collapsed .fk-sidenav-link__anchor` rule
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# fk-tabs
|
|
2
|
+
|
|
3
|
+
A compound component system for building accessible, keyboard-navigable tabbed interfaces. Follows the [WAI-ARIA Tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## API
|
|
8
|
+
|
|
9
|
+
### `fk-tabs`
|
|
10
|
+
|
|
11
|
+
Root container that provides shared state to all child tab components.
|
|
12
|
+
|
|
13
|
+
| Input | Type | Default | Description |
|
|
14
|
+
| ------------------- | -------------------------------------- | -------------- | ----------------------------------------------- |
|
|
15
|
+
| `value` | `string \| undefined` | `undefined` | Controlled active tab value |
|
|
16
|
+
| `defaultValue` | `string \| undefined` | `undefined` | Initial active tab (uncontrolled mode) |
|
|
17
|
+
| `variant` | `'underline' \| 'pill' \| 'contained'` | `'underline'` | Visual style of the tabs |
|
|
18
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of tab labels |
|
|
19
|
+
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout direction |
|
|
20
|
+
| `activationMode` | `'automatic' \| 'manual'` | `'automatic'` | Whether tabs activate on focus or require Enter |
|
|
21
|
+
| `lazy` | `boolean` | `false` | Defer panel rendering until first activation |
|
|
22
|
+
| `keepMounted` | `boolean` | `true` | Keep lazy panels in DOM after deactivation |
|
|
23
|
+
| `stretch` | `boolean` | `false` | Stretch tabs to fill available width |
|
|
24
|
+
| `fullWidth` | `boolean` | `false` | Make the tab bar span full width |
|
|
25
|
+
| `scrollable` | `boolean` | `false` | Enable horizontal scrolling for overflow tabs |
|
|
26
|
+
| `showScrollButtons` | `boolean` | `false` | Show prev/next scroll buttons |
|
|
27
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
28
|
+
|
|
29
|
+
| Output | Type | Description |
|
|
30
|
+
| ------------- | ------------------ | -------------------------------------- |
|
|
31
|
+
| `valueChange` | `string` | Emits new value when selection changes |
|
|
32
|
+
| `tabChange` | `FkTabChangeEvent` | Emits `{ previousValue, value }` |
|
|
33
|
+
| `tabClose` | `FkTabCloseEvent` | Emits `{ value }` when a tab is closed |
|
|
34
|
+
|
|
35
|
+
### `fk-tab-list`
|
|
36
|
+
|
|
37
|
+
Container for tab triggers. Applies `role="tablist"` and handles keyboard navigation.
|
|
38
|
+
|
|
39
|
+
| Input | Type | Default | Description |
|
|
40
|
+
| ----------- | ---------------- | ------- | --------------------------------- |
|
|
41
|
+
| `ariaLabel` | `string \| null` | `null` | Accessible label for the tab list |
|
|
42
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
43
|
+
|
|
44
|
+
### `fk-tab`
|
|
45
|
+
|
|
46
|
+
Individual tab trigger. Applies `role="tab"` with full ARIA attributes.
|
|
47
|
+
|
|
48
|
+
| Input | Type | Default | Description |
|
|
49
|
+
| ----------- | --------------------------------------------- | ----------- | ------------------------------- |
|
|
50
|
+
| `value` | `string` (required) | — | Unique identifier for this tab |
|
|
51
|
+
| `disabled` | `boolean` | `false` | Prevents selection |
|
|
52
|
+
| `closable` | `boolean` | `false` | Shows a close button |
|
|
53
|
+
| `badge` | `string \| number \| undefined` | `undefined` | Badge content next to the label |
|
|
54
|
+
| `icon` | `TemplateRef<unknown> \| string \| undefined` | `undefined` | Icon before the label |
|
|
55
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
56
|
+
|
|
57
|
+
### `fk-tab-panel`
|
|
58
|
+
|
|
59
|
+
Content panel associated with a tab. Applies `role="tabpanel"`.
|
|
60
|
+
|
|
61
|
+
| Input | Type | Default | Description |
|
|
62
|
+
| ----------- | ------------------- | ------- | ----------------------------------------- |
|
|
63
|
+
| `value` | `string` (required) | — | Must match a corresponding `fk-tab` value |
|
|
64
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Features
|
|
69
|
+
|
|
70
|
+
- WAI-ARIA Tabs pattern with full keyboard support (arrow keys, Home/End, Enter/Space in manual mode)
|
|
71
|
+
- Three visual variants: `underline` (default, with sliding indicator), `pill`, `contained`
|
|
72
|
+
- Three sizes: `sm`, `md`, `lg`
|
|
73
|
+
- Horizontal and vertical orientations
|
|
74
|
+
- Automatic and manual activation modes
|
|
75
|
+
- Lazy panel rendering with optional keep-mounted (state preservation across deactivation)
|
|
76
|
+
- Closable tabs with `(tabClose)` event for dynamic tab strips
|
|
77
|
+
- Optional badge and icon slots on each tab
|
|
78
|
+
- Stretch / fullWidth / scrollable layouts for dense or overflow tab strips
|
|
79
|
+
- Controlled and uncontrolled modes (bind `[value]` + `(valueChange)`, or pass `defaultValue`)
|
|
80
|
+
- Auto-select fallback when the active tab is removed
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Quick Start
|
|
85
|
+
|
|
86
|
+
```html
|
|
87
|
+
<fk-tabs defaultValue="account">
|
|
88
|
+
<fk-tab-list>
|
|
89
|
+
<fk-tab value="account">Account</fk-tab>
|
|
90
|
+
<fk-tab value="documents">Documents</fk-tab>
|
|
91
|
+
<fk-tab value="settings">Settings</fk-tab>
|
|
92
|
+
</fk-tab-list>
|
|
93
|
+
|
|
94
|
+
<fk-tab-panel value="account">Account content</fk-tab-panel>
|
|
95
|
+
<fk-tab-panel value="documents">Documents content</fk-tab-panel>
|
|
96
|
+
<fk-tab-panel value="settings">Settings content</fk-tab-panel>
|
|
97
|
+
</fk-tabs>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Import
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import { FkTabsComponent, FkTabListComponent, FkTabComponent, FkTabPanelComponent } from '@frame-kit/ui-ng';
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
@Component({
|
|
110
|
+
selector: 'app-example',
|
|
111
|
+
imports: [FkTabsComponent, FkTabListComponent, FkTabComponent, FkTabPanelComponent],
|
|
112
|
+
templateUrl: './example.component.html',
|
|
113
|
+
})
|
|
114
|
+
export class ExampleComponent {}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Examples
|
|
120
|
+
|
|
121
|
+
### Controlled mode
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<fk-tabs [value]="activeTab()" (valueChange)="activeTab.set($event)">
|
|
125
|
+
<fk-tab-list>
|
|
126
|
+
<fk-tab value="a">A</fk-tab>
|
|
127
|
+
<fk-tab value="b">B</fk-tab>
|
|
128
|
+
</fk-tab-list>
|
|
129
|
+
<fk-tab-panel value="a">Panel A</fk-tab-panel>
|
|
130
|
+
<fk-tab-panel value="b">Panel B</fk-tab-panel>
|
|
131
|
+
</fk-tabs>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Closable tabs
|
|
135
|
+
|
|
136
|
+
```html
|
|
137
|
+
<fk-tabs (tabClose)="removeTab($event.value)">
|
|
138
|
+
<fk-tab-list>
|
|
139
|
+
@for (tab of tabs(); track tab.id) {
|
|
140
|
+
<fk-tab [value]="tab.id" [closable]="true">{{ tab.label }}</fk-tab>
|
|
141
|
+
}
|
|
142
|
+
</fk-tab-list>
|
|
143
|
+
@for (tab of tabs(); track tab.id) {
|
|
144
|
+
<fk-tab-panel [value]="tab.id">{{ tab.content }}</fk-tab-panel>
|
|
145
|
+
}
|
|
146
|
+
</fk-tabs>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Lazy rendering
|
|
150
|
+
|
|
151
|
+
```html
|
|
152
|
+
<fk-tabs defaultValue="first" [lazy]="true" [keepMounted]="true">
|
|
153
|
+
<fk-tab-list>
|
|
154
|
+
<fk-tab value="first">First</fk-tab>
|
|
155
|
+
<fk-tab value="second">Second</fk-tab>
|
|
156
|
+
</fk-tab-list>
|
|
157
|
+
<fk-tab-panel value="first">Rendered immediately</fk-tab-panel>
|
|
158
|
+
<fk-tab-panel value="second">Rendered on first activation, then kept alive</fk-tab-panel>
|
|
159
|
+
</fk-tabs>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Vertical orientation
|
|
163
|
+
|
|
164
|
+
```html
|
|
165
|
+
<fk-tabs defaultValue="a" orientation="vertical">
|
|
166
|
+
<div style="display: flex;">
|
|
167
|
+
<fk-tab-list>
|
|
168
|
+
<fk-tab value="a">Account</fk-tab>
|
|
169
|
+
<fk-tab value="b">Security</fk-tab>
|
|
170
|
+
</fk-tab-list>
|
|
171
|
+
<div>
|
|
172
|
+
<fk-tab-panel value="a">Account settings</fk-tab-panel>
|
|
173
|
+
<fk-tab-panel value="b">Security settings</fk-tab-panel>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
</fk-tabs>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Accessibility
|
|
182
|
+
|
|
183
|
+
- `fk-tab-list` renders `role="tablist"` with `aria-orientation`
|
|
184
|
+
- Each `fk-tab` renders `role="tab"` with `aria-selected`, `aria-controls`, `aria-disabled`, and roving `tabindex`
|
|
185
|
+
- Each `fk-tab-panel` renders `role="tabpanel"` with `aria-labelledby` and `tabindex="0"`
|
|
186
|
+
- Tab and panel IDs are auto-generated and cross-linked
|
|
187
|
+
- Keyboard navigation: `ArrowLeft`/`ArrowRight` (horizontal), `ArrowUp`/`ArrowDown` (vertical), `Home`, `End`, `Enter`/`Space` (manual mode)
|
|
188
|
+
- Disabled tabs are skipped during keyboard navigation
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Design Tokens
|
|
193
|
+
|
|
194
|
+
Tab styling is driven by CSS custom properties scoped under the `.fk-tabs`, `.fk-tab-list`, `.fk-tab`, and `.fk-tab-panel` blocks. Override these in your theme to adjust colors, spacing, border radius, and indicator dimensions. The component responds to the global light/dark theme tokens from `@canopy/ui-shared`.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Behavior Notes
|
|
199
|
+
|
|
200
|
+
- **Uncontrolled mode** (default): Pass `defaultValue` and the component manages selection internally.
|
|
201
|
+
- **Controlled mode**: Bind `[value]` and listen to `(valueChange)` to drive selection externally.
|
|
202
|
+
- **Auto-select**: If no `value` or `defaultValue` is provided, the first non-disabled tab is selected automatically.
|
|
203
|
+
- **Fallback**: When the active tab is removed, the first remaining enabled tab is selected.
|
|
204
|
+
- **Indicator**: The underline variant renders a sliding indicator that tracks the active tab via DOM measurement.
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# fk-timeline
|
|
2
|
+
|
|
3
|
+
A token-driven timeline component for displaying ordered steps, resolution chains, audit trails, and workflow progress with status indicators and connectors.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## API
|
|
8
|
+
|
|
9
|
+
### Inputs
|
|
10
|
+
|
|
11
|
+
| Input | Type | Default | Description |
|
|
12
|
+
| ------------- | --------------------------------- | ------------ | -------------------------------------------- |
|
|
13
|
+
| `items` | `TimelineItemData[]` | `[]` | Declarative data for timeline entries |
|
|
14
|
+
| `orientation` | `'vertical' \| 'horizontal'` | `'vertical'` | Layout direction |
|
|
15
|
+
| `align` | `'start' \| 'end' \| 'alternate'` | `'start'` | Content alignment relative to connector line |
|
|
16
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Marker and connector sizing |
|
|
17
|
+
| `reverse` | `boolean` | `false` | Reverse item order |
|
|
18
|
+
| `ariaLabel` | `string \| null` | `null` | Accessible label |
|
|
19
|
+
| `id` | `string \| null` | `null` | Element ID |
|
|
20
|
+
| `className` | `string` | `''` | Additional CSS classes merged onto the host |
|
|
21
|
+
|
|
22
|
+
### Types
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
interface TimelineItemData {
|
|
26
|
+
id?: string;
|
|
27
|
+
title?: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
timestamp?: string;
|
|
30
|
+
icon?: string;
|
|
31
|
+
status?: TimelineItemStatus;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
type TimelineItemStatus = 'default' | 'active' | 'completed' | 'error' | 'warning';
|
|
35
|
+
type TimelineOrientation = 'vertical' | 'horizontal';
|
|
36
|
+
type TimelineAlign = 'start' | 'end' | 'alternate';
|
|
37
|
+
type TimelineSize = 'sm' | 'md' | 'lg';
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Outputs
|
|
41
|
+
|
|
42
|
+
None.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- Vertical and horizontal orientations
|
|
49
|
+
- Three alignment modes (start, end, alternate)
|
|
50
|
+
- Three size presets (sm, md, lg)
|
|
51
|
+
- Five status variants (default, active, completed, error, warning)
|
|
52
|
+
- Custom icon support per item
|
|
53
|
+
- Optional timestamp display
|
|
54
|
+
- Reversible item order
|
|
55
|
+
- Content projection for complex custom items
|
|
56
|
+
- Token-driven styling with two-tier fallbacks
|
|
57
|
+
- Full ARIA list semantics
|
|
58
|
+
- Dark mode support
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Quick Start
|
|
63
|
+
|
|
64
|
+
```html
|
|
65
|
+
<fk-timeline
|
|
66
|
+
[items]="[
|
|
67
|
+
{ title: 'Step 1', status: 'completed' },
|
|
68
|
+
{ title: 'Step 2', status: 'active' },
|
|
69
|
+
{ title: 'Step 3', status: 'default' }
|
|
70
|
+
]"
|
|
71
|
+
></fk-timeline>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Import
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { TimelineComponent } from '@frame-kit/ui-ng';
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
@Component({
|
|
84
|
+
selector: 'app-example',
|
|
85
|
+
imports: [TimelineComponent],
|
|
86
|
+
templateUrl: './example.component.html',
|
|
87
|
+
})
|
|
88
|
+
export class ExampleComponent {}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Selector
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<fk-timeline></fk-timeline>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Examples
|
|
102
|
+
|
|
103
|
+
### Default (vertical, start-aligned)
|
|
104
|
+
|
|
105
|
+
```html
|
|
106
|
+
<fk-timeline [items]="items"></fk-timeline>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Horizontal
|
|
110
|
+
|
|
111
|
+
```html
|
|
112
|
+
<fk-timeline [items]="items" orientation="horizontal"></fk-timeline>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Alternate alignment
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<fk-timeline [items]="items" align="alternate"></fk-timeline>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Sizes
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<fk-timeline [items]="items" size="sm"></fk-timeline>
|
|
125
|
+
<fk-timeline [items]="items" size="md"></fk-timeline>
|
|
126
|
+
<fk-timeline [items]="items" size="lg"></fk-timeline>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### All status variants
|
|
130
|
+
|
|
131
|
+
```html
|
|
132
|
+
<fk-timeline
|
|
133
|
+
[items]="[
|
|
134
|
+
{ title: 'Done', status: 'completed' },
|
|
135
|
+
{ title: 'Current', status: 'active' },
|
|
136
|
+
{ title: 'Attention', status: 'warning' },
|
|
137
|
+
{ title: 'Failed', status: 'error' },
|
|
138
|
+
{ title: 'Pending', status: 'default' }
|
|
139
|
+
]"
|
|
140
|
+
></fk-timeline>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### With icons
|
|
144
|
+
|
|
145
|
+
```html
|
|
146
|
+
<fk-timeline
|
|
147
|
+
[items]="[
|
|
148
|
+
{ title: 'Submitted', icon: 'circle-check-outline', status: 'completed' },
|
|
149
|
+
{ title: 'In Review', icon: 'shield-alert', status: 'active' },
|
|
150
|
+
{ title: 'Approved', icon: 'lock', status: 'default' }
|
|
151
|
+
]"
|
|
152
|
+
></fk-timeline>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### With timestamps
|
|
156
|
+
|
|
157
|
+
```html
|
|
158
|
+
<fk-timeline
|
|
159
|
+
[items]="[
|
|
160
|
+
{ title: 'Created', timestamp: 'Jan 15', status: 'completed' },
|
|
161
|
+
{ title: 'Updated', timestamp: 'Feb 1', status: 'active' }
|
|
162
|
+
]"
|
|
163
|
+
></fk-timeline>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Reversed order
|
|
167
|
+
|
|
168
|
+
```html
|
|
169
|
+
<fk-timeline [items]="items" [reverse]="true"></fk-timeline>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Content projection (advanced)
|
|
173
|
+
|
|
174
|
+
```html
|
|
175
|
+
<fk-timeline>
|
|
176
|
+
<ng-content />
|
|
177
|
+
</fk-timeline>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Accessibility
|
|
183
|
+
|
|
184
|
+
`fk-timeline` applies `role="list"` on the host element with `aria-orientation` reflecting the layout direction.
|
|
185
|
+
|
|
186
|
+
Accessibility behavior:
|
|
187
|
+
|
|
188
|
+
- `role="list"` on the timeline container
|
|
189
|
+
- `role="listitem"` on each timeline item
|
|
190
|
+
- `aria-orientation` reflects vertical or horizontal
|
|
191
|
+
- Supports `ariaLabel` for additional context
|
|
192
|
+
|
|
193
|
+
### Recommended
|
|
194
|
+
|
|
195
|
+
```html
|
|
196
|
+
<fk-timeline [items]="items" ariaLabel="Policy resolution chain"></fk-timeline>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Design Tokens
|
|
202
|
+
|
|
203
|
+
`fk-timeline` is styled entirely through design tokens.
|
|
204
|
+
|
|
205
|
+
### Component-specific tokens
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
--fk-timeline-gap
|
|
209
|
+
--fk-timeline-item-gap
|
|
210
|
+
--fk-timeline-marker-size-sm
|
|
211
|
+
--fk-timeline-marker-size-md
|
|
212
|
+
--fk-timeline-marker-size-lg
|
|
213
|
+
--fk-timeline-marker-bg
|
|
214
|
+
--fk-timeline-marker-border-color
|
|
215
|
+
--fk-timeline-marker-border-width
|
|
216
|
+
--fk-timeline-marker-color
|
|
217
|
+
--fk-timeline-marker-active
|
|
218
|
+
--fk-timeline-marker-completed
|
|
219
|
+
--fk-timeline-marker-error
|
|
220
|
+
--fk-timeline-marker-warning
|
|
221
|
+
--fk-timeline-connector-width
|
|
222
|
+
--fk-timeline-connector-color
|
|
223
|
+
--fk-timeline-connector-length
|
|
224
|
+
--fk-timeline-content-gap
|
|
225
|
+
--fk-timeline-title-font-size
|
|
226
|
+
--fk-timeline-title-font-weight
|
|
227
|
+
--fk-timeline-title-color
|
|
228
|
+
--fk-timeline-description-font-size
|
|
229
|
+
--fk-timeline-description-color
|
|
230
|
+
--fk-timeline-timestamp-font-size
|
|
231
|
+
--fk-timeline-timestamp-color
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Shared tokens
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
--fk-color-primary
|
|
238
|
+
--fk-color-success
|
|
239
|
+
--fk-color-danger
|
|
240
|
+
--fk-color-warning
|
|
241
|
+
--fk-color-surface
|
|
242
|
+
--fk-color-border
|
|
243
|
+
--fk-color-text
|
|
244
|
+
--fk-color-muted
|
|
245
|
+
--fk-typography-body-font-size
|
|
246
|
+
--fk-typography-small-font-size
|
|
247
|
+
--fk-typography-caption-font-size
|
|
248
|
+
--fk-font-weight-medium
|
|
249
|
+
--fk-rhythm-1
|
|
250
|
+
--fk-rhythm-2
|
|
251
|
+
--fk-rhythm-3
|
|
252
|
+
--fk-radius-md
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Customizing Tokens
|
|
256
|
+
|
|
257
|
+
Override tokens in your application's stylesheet:
|
|
258
|
+
|
|
259
|
+
```scss
|
|
260
|
+
:root {
|
|
261
|
+
--fk-timeline-marker-size-md: 2rem;
|
|
262
|
+
--fk-timeline-connector-color: #e5e7eb;
|
|
263
|
+
--fk-timeline-marker-active: #6366f1;
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Or scope overrides to a specific context:
|
|
268
|
+
|
|
269
|
+
```scss
|
|
270
|
+
.compact-timeline fk-timeline {
|
|
271
|
+
--fk-timeline-marker-size-md: 1rem;
|
|
272
|
+
--fk-timeline-item-gap: 0.5rem;
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Behavior Notes
|
|
279
|
+
|
|
280
|
+
- Horizontal timelines expand to fill the parent container width; wrap in a sized container to constrain
|
|
281
|
+
- Vertical timelines take only the height of their content
|
|
282
|
+
- The last item never renders a connector line
|
|
283
|
+
- Alternate alignment uses CSS grid to keep the connector line centered
|
|
284
|
+
- Icons must be registered via `provideIcons()` before use
|
|
285
|
+
- Status variants control marker fill color; the default status renders as an outlined circle
|