@frame-kit/ui-ng 0.1.6 → 0.1.8
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/DEVELOPMENT_GUIDE.md +15 -0
- package/fesm2022/frame-kit-ui-ng-forms.mjs +71 -21
- package/fesm2022/frame-kit-ui-ng-forms.mjs.map +1 -1
- package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs +2 -3
- package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs.map +1 -1
- package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs +2 -4
- package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs.map +1 -1
- package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs +39 -9
- package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs.map +1 -1
- package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs +14 -9
- package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs.map +1 -1
- package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs +2 -3
- package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs.map +1 -1
- package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs +7 -4
- package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs.map +1 -1
- package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs +13 -4
- package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs.map +1 -1
- package/package.json +1 -1
- package/types/frame-kit-ui-ng-forms.d.ts +47 -9
- package/types/frame-kit-ui-ng-ui-menu-item.d.ts +29 -13
- package/types/frame-kit-ui-ng-ui-node-tree.d.ts +12 -2
- package/types/frame-kit-ui-ng-ui-timeline.d.ts +7 -1
- package/types/frame-kit-ui-ng-ui-user-menu.d.ts +16 -1
- package/ui/dropdown-menu/README.md +13 -14
- package/ui/menu-item/README.md +27 -14
- package/ui/node-tree/README.md +25 -10
- package/ui/timeline/README.md +20 -12
- package/ui/user-menu/README.md +36 -26
|
@@ -1,27 +1,43 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { ElementRef } from '@angular/core';
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { ElementRef, InjectionToken } from '@angular/core';
|
|
3
3
|
|
|
4
4
|
declare class MenuItemComponent {
|
|
5
|
-
/** Optional icon name rendered to the leading side of the label. */
|
|
6
|
-
readonly icon: _angular_core.InputSignal<string | null>;
|
|
7
5
|
/** When true, applies destructive (danger) color styling to the item. */
|
|
8
|
-
readonly danger:
|
|
6
|
+
readonly danger: i0.InputSignal<boolean>;
|
|
9
7
|
/** When true, prevents interaction and applies disabled styling. */
|
|
10
|
-
readonly disabled:
|
|
8
|
+
readonly disabled: i0.InputSignal<boolean>;
|
|
11
9
|
/** Fires when the user activates the item via click or keyboard. */
|
|
12
|
-
readonly itemClick:
|
|
10
|
+
readonly itemClick: i0.OutputEmitterRef<void>;
|
|
13
11
|
readonly elRef: ElementRef<any>;
|
|
14
|
-
readonly classes:
|
|
12
|
+
readonly classes: i0.Signal<string>;
|
|
15
13
|
get hostClass(): string;
|
|
16
14
|
onClick(): void;
|
|
17
15
|
onKeydown(event: KeyboardEvent): void;
|
|
18
|
-
static ɵfac:
|
|
19
|
-
static ɵcmp:
|
|
16
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MenuItemComponent, never>;
|
|
17
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MenuItemComponent, "fk-menu-item", never, { "danger": { "alias": "danger"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; }, never, ["[fkMenuItemIcon]", "*"], true, never>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Injection token for the leading-icon slot of `fk-menu-item`. */
|
|
21
|
+
declare const FK_MENU_ITEM_ICON: InjectionToken<FkMenuItemIconDirective>;
|
|
22
|
+
/**
|
|
23
|
+
* Marks projected content as the leading icon of an `fk-menu-item`. Project any
|
|
24
|
+
* icon element (the app owns the icon system):
|
|
25
|
+
*
|
|
26
|
+
* ```html
|
|
27
|
+
* <fk-menu-item>
|
|
28
|
+
* <fk-icon fkMenuItemIcon name="pen-outline" />
|
|
29
|
+
* Edit
|
|
30
|
+
* </fk-menu-item>
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
declare class FkMenuItemIconDirective {
|
|
34
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FkMenuItemIconDirective, never>;
|
|
35
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<FkMenuItemIconDirective, "[fkMenuItemIcon]", never, {}, {}, never, never, true, never>;
|
|
20
36
|
}
|
|
21
37
|
|
|
22
38
|
declare class MenuSeparatorComponent {
|
|
23
|
-
static ɵfac:
|
|
24
|
-
static ɵcmp:
|
|
39
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MenuSeparatorComponent, never>;
|
|
40
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MenuSeparatorComponent, "fk-menu-separator", never, {}, {}, never, never, true, never>;
|
|
25
41
|
}
|
|
26
42
|
|
|
27
|
-
export { MenuItemComponent, MenuSeparatorComponent };
|
|
43
|
+
export { FK_MENU_ITEM_ICON, FkMenuItemIconDirective, MenuItemComponent, MenuSeparatorComponent };
|
|
@@ -55,6 +55,11 @@ declare class FkNodeTreeComponent {
|
|
|
55
55
|
readonly selectedNodeId: _angular_core.InputSignal<string | undefined>;
|
|
56
56
|
/** Controlled set of expanded node IDs; when undefined the tree manages expansion internally. */
|
|
57
57
|
readonly expandedNodeIds: _angular_core.InputSignal<string[] | undefined>;
|
|
58
|
+
/** Optional template rendering each row's leading icon (the app owns the icon
|
|
59
|
+
* system). Receives the node as `$implicit`; render it from `node.icon`. */
|
|
60
|
+
readonly iconTemplate: _angular_core.InputSignal<TemplateRef<{
|
|
61
|
+
$implicit: FlatNode;
|
|
62
|
+
}> | undefined>;
|
|
58
63
|
/** When true, rows can be dragged to reorder or reparent nodes. */
|
|
59
64
|
readonly draggable: _angular_core.InputSignal<boolean>;
|
|
60
65
|
/** Optional guard called during drag to determine whether a drop at a given position is allowed. */
|
|
@@ -90,7 +95,7 @@ declare class FkNodeTreeComponent {
|
|
|
90
95
|
private clearAutoExpand;
|
|
91
96
|
private resetDragState;
|
|
92
97
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FkNodeTreeComponent, never>;
|
|
93
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FkNodeTreeComponent, "fk-node-tree", never, { "className": { "alias": "className"; "required": false; "isSignal": true; }; "nodes": { "alias": "nodes"; "required": true; "isSignal": true; }; "selectedNodeId": { "alias": "selectedNodeId"; "required": false; "isSignal": true; }; "expandedNodeIds": { "alias": "expandedNodeIds"; "required": false; "isSignal": true; }; "draggable": { "alias": "draggable"; "required": false; "isSignal": true; }; "canDrop": { "alias": "canDrop"; "required": false; "isSignal": true; }; }, { "nodeSelect": "nodeSelect"; "nodeExpand": "nodeExpand"; "nodeDrop": "nodeDrop"; }, ["rowTemplate"], never, true, never>;
|
|
98
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FkNodeTreeComponent, "fk-node-tree", never, { "className": { "alias": "className"; "required": false; "isSignal": true; }; "nodes": { "alias": "nodes"; "required": true; "isSignal": true; }; "selectedNodeId": { "alias": "selectedNodeId"; "required": false; "isSignal": true; }; "expandedNodeIds": { "alias": "expandedNodeIds"; "required": false; "isSignal": true; }; "iconTemplate": { "alias": "iconTemplate"; "required": false; "isSignal": true; }; "draggable": { "alias": "draggable"; "required": false; "isSignal": true; }; "canDrop": { "alias": "canDrop"; "required": false; "isSignal": true; }; }, { "nodeSelect": "nodeSelect"; "nodeExpand": "nodeExpand"; "nodeDrop": "nodeDrop"; }, ["rowTemplate"], never, true, never>;
|
|
94
99
|
}
|
|
95
100
|
|
|
96
101
|
declare function isDescendantOf(nodeId: string, ancestorId: string, childrenMap: Map<string | null, TreeNode[]>): boolean;
|
|
@@ -111,6 +116,11 @@ declare class FkNodeTreeRowComponent {
|
|
|
111
116
|
readonly showDragHandle: _angular_core.InputSignal<boolean>;
|
|
112
117
|
/** Optional custom template used to render the row content. */
|
|
113
118
|
readonly customTemplate: _angular_core.InputSignal<TemplateRef<NodeTreeRowContext> | undefined>;
|
|
119
|
+
/** Optional template rendering the row's leading icon (the app owns the icon).
|
|
120
|
+
* Receives the node as `$implicit`; render it from `node.icon`. */
|
|
121
|
+
readonly iconTemplate: _angular_core.InputSignal<TemplateRef<{
|
|
122
|
+
$implicit: FlatNode;
|
|
123
|
+
}> | undefined>;
|
|
114
124
|
/** Fires when the user clicks the expand/collapse chevron. */
|
|
115
125
|
readonly toggleNode: _angular_core.OutputEmitterRef<void>;
|
|
116
126
|
/** Fires when the user clicks the row body to select the node. */
|
|
@@ -128,7 +138,7 @@ declare class FkNodeTreeRowComponent {
|
|
|
128
138
|
onClick(): void;
|
|
129
139
|
onToggleClick(event: MouseEvent): void;
|
|
130
140
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FkNodeTreeRowComponent, never>;
|
|
131
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FkNodeTreeRowComponent, "fk-node-tree-row", never, { "className": { "alias": "className"; "required": false; "isSignal": true; }; "node": { "alias": "node"; "required": true; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "dropPosition": { "alias": "dropPosition"; "required": false; "isSignal": true; }; "isDragSource": { "alias": "isDragSource"; "required": false; "isSignal": true; }; "showDragHandle": { "alias": "showDragHandle"; "required": false; "isSignal": true; }; "customTemplate": { "alias": "customTemplate"; "required": false; "isSignal": true; }; }, { "toggleNode": "toggleNode"; "selectNode": "selectNode"; }, never, ["*"], true, never>;
|
|
141
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FkNodeTreeRowComponent, "fk-node-tree-row", never, { "className": { "alias": "className"; "required": false; "isSignal": true; }; "node": { "alias": "node"; "required": true; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "dropPosition": { "alias": "dropPosition"; "required": false; "isSignal": true; }; "isDragSource": { "alias": "isDragSource"; "required": false; "isSignal": true; }; "showDragHandle": { "alias": "showDragHandle"; "required": false; "isSignal": true; }; "customTemplate": { "alias": "customTemplate"; "required": false; "isSignal": true; }; "iconTemplate": { "alias": "iconTemplate"; "required": false; "isSignal": true; }; }, { "toggleNode": "toggleNode"; "selectNode": "selectNode"; }, never, ["*"], true, never>;
|
|
132
142
|
}
|
|
133
143
|
|
|
134
144
|
export { FkNodeTreeComponent, FkNodeTreeRowComponent, FkNodeTreeRowDirective, buildChildrenMap, flattenTree, isDescendantOf };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { TemplateRef } from '@angular/core';
|
|
2
3
|
|
|
3
4
|
type TimelineOrientation = 'vertical' | 'horizontal';
|
|
4
5
|
type TimelineAlign = 'start' | 'end' | 'alternate';
|
|
@@ -16,6 +17,11 @@ interface TimelineItemData {
|
|
|
16
17
|
declare class TimelineComponent {
|
|
17
18
|
/** Array of timeline item data objects rendered in order. */
|
|
18
19
|
readonly items: _angular_core.InputSignal<TimelineItemData[]>;
|
|
20
|
+
/** Optional template rendering each item's marker icon (the app owns the icon
|
|
21
|
+
* system). Receives the item as `$implicit`; render it from `item.icon`. */
|
|
22
|
+
readonly iconTemplate: _angular_core.InputSignal<TemplateRef<{
|
|
23
|
+
$implicit: TimelineItemData;
|
|
24
|
+
}> | undefined>;
|
|
19
25
|
/** Direction the timeline runs — vertical stacks items top-to-bottom, horizontal left-to-right. */
|
|
20
26
|
readonly orientation: _angular_core.InputSignal<TimelineOrientation>;
|
|
21
27
|
/** Alignment of the item content relative to the connector line. */
|
|
@@ -35,7 +41,7 @@ declare class TimelineComponent {
|
|
|
35
41
|
get hostAriaOrientation(): TimelineOrientation;
|
|
36
42
|
get hostId(): string | null;
|
|
37
43
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TimelineComponent, never>;
|
|
38
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<TimelineComponent, "fk-timeline", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "reverse": { "alias": "reverse"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
44
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<TimelineComponent, "fk-timeline", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "iconTemplate": { "alias": "iconTemplate"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "reverse": { "alias": "reverse"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
export { TimelineComponent };
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { TemplateRef } from '@angular/core';
|
|
2
3
|
import { AvatarStatus, AvatarSize } from '@frame-kit/ui-ng/ui/avatar';
|
|
3
4
|
import { DropdownMenuComponent } from '@frame-kit/ui-ng/ui/dropdown-menu';
|
|
4
5
|
|
|
5
6
|
interface MenuItem {
|
|
6
7
|
label: string;
|
|
7
8
|
value: string;
|
|
9
|
+
/**
|
|
10
|
+
* Icon identifier for this item. The widget does **not** render it directly
|
|
11
|
+
* (ui-ng is icon-agnostic) — pass an `iconTemplate` to `fk-user-menu` that
|
|
12
|
+
* reads this field and renders your own icon. Items render without an icon
|
|
13
|
+
* when no `iconTemplate` is supplied.
|
|
14
|
+
*/
|
|
8
15
|
icon?: string;
|
|
9
16
|
disabled?: boolean;
|
|
10
17
|
danger?: boolean;
|
|
@@ -31,6 +38,14 @@ declare class UserMenuComponent {
|
|
|
31
38
|
readonly showStatus: _angular_core.InputSignal<boolean>;
|
|
32
39
|
/** Array of menu item configurations rendered in the dropdown. */
|
|
33
40
|
readonly menuItems: _angular_core.InputSignal<MenuItem[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Optional template used to render each item's leading icon (the app owns the
|
|
43
|
+
* icon system). Receives the `MenuItem` as `$implicit`; render the icon from
|
|
44
|
+
* `item.icon`. When omitted, items render without an icon.
|
|
45
|
+
*/
|
|
46
|
+
readonly iconTemplate: _angular_core.InputSignal<TemplateRef<{
|
|
47
|
+
$implicit: MenuItem;
|
|
48
|
+
}> | null>;
|
|
34
49
|
/** Preferred placement of the dropdown panel relative to the trigger. */
|
|
35
50
|
readonly placement: _angular_core.InputSignal<MenuPlacement>;
|
|
36
51
|
/** Size of the avatar trigger. */
|
|
@@ -80,7 +95,7 @@ declare class UserMenuComponent {
|
|
|
80
95
|
/** Toggles the user-menu dropdown programmatically. */
|
|
81
96
|
toggle(): void;
|
|
82
97
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UserMenuComponent, never>;
|
|
83
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UserMenuComponent, "fk-user-menu", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "email": { "alias": "email"; "required": false; "isSignal": true; }; "avatarUrl": { "alias": "avatarUrl"; "required": false; "isSignal": true; }; "initials": { "alias": "initials"; "required": false; "isSignal": true; }; "userId": { "alias": "userId"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "showStatus": { "alias": "showStatus"; "required": false; "isSignal": true; }; "menuItems": { "alias": "menuItems"; "required": false; "isSignal": true; }; "placement": { "alias": "placement"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "showName": { "alias": "showName"; "required": false; "isSignal": true; }; "showEmail": { "alias": "showEmail"; "required": false; "isSignal": true; }; "showChevron": { "alias": "showChevron"; "required": false; "isSignal": true; }; "infoPlacement": { "alias": "infoPlacement"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "avatarClick": "avatarClick"; "menuOpen": "menuOpen"; "menuClose": "menuClose"; "menuItemClick": "menuItemClick"; "logoutClick": "logoutClick"; }, never, never, true, never>;
|
|
98
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UserMenuComponent, "fk-user-menu", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "email": { "alias": "email"; "required": false; "isSignal": true; }; "avatarUrl": { "alias": "avatarUrl"; "required": false; "isSignal": true; }; "initials": { "alias": "initials"; "required": false; "isSignal": true; }; "userId": { "alias": "userId"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "showStatus": { "alias": "showStatus"; "required": false; "isSignal": true; }; "menuItems": { "alias": "menuItems"; "required": false; "isSignal": true; }; "iconTemplate": { "alias": "iconTemplate"; "required": false; "isSignal": true; }; "placement": { "alias": "placement"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "showName": { "alias": "showName"; "required": false; "isSignal": true; }; "showEmail": { "alias": "showEmail"; "required": false; "isSignal": true; }; "showChevron": { "alias": "showChevron"; "required": false; "isSignal": true; }; "infoPlacement": { "alias": "infoPlacement"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "avatarClick": "avatarClick"; "menuOpen": "menuOpen"; "menuClose": "menuClose"; "menuItemClick": "menuItemClick"; "logoutClick": "logoutClick"; }, never, never, true, never>;
|
|
84
99
|
}
|
|
85
100
|
|
|
86
101
|
export { UserMenuComponent };
|
|
@@ -52,17 +52,16 @@ Applied to an `<ng-template>` that contains menu items. The template is rendered
|
|
|
52
52
|
|
|
53
53
|
### fk-menu-item
|
|
54
54
|
|
|
55
|
-
| Input | Type
|
|
56
|
-
| ---------- |
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `disabled` | `boolean` | `false` | Disables the item |
|
|
55
|
+
| Input | Type | Default | Description |
|
|
56
|
+
| ---------- | --------- | ------- | ---------------------------------- |
|
|
57
|
+
| `danger` | `boolean` | `false` | Applies destructive/danger styling |
|
|
58
|
+
| `disabled` | `boolean` | `false` | Disables the item |
|
|
60
59
|
|
|
61
60
|
| Output | Type | Description |
|
|
62
61
|
| ----------- | ------ | ---------------------------------- |
|
|
63
62
|
| `itemClick` | `void` | Emitted when the item is activated |
|
|
64
63
|
|
|
65
|
-
The item label is
|
|
64
|
+
The item label is the default projected content; a leading icon is projected via the `[fkMenuItemIcon]` slot (project your own `fk-icon`). See the `fk-menu-item` README.
|
|
66
65
|
|
|
67
66
|
### fk-menu-separator
|
|
68
67
|
|
|
@@ -90,10 +89,10 @@ A visual divider between menu item groups. No inputs or outputs.
|
|
|
90
89
|
<fk-dropdown-menu>
|
|
91
90
|
<button fkDropdownTrigger>Actions</button>
|
|
92
91
|
<ng-template fkDropdownPanel>
|
|
93
|
-
<fk-menu-item
|
|
94
|
-
<fk-menu-item
|
|
92
|
+
<fk-menu-item><fk-icon fkMenuItemIcon name="eye" size="sm" />View</fk-menu-item>
|
|
93
|
+
<fk-menu-item><fk-icon fkMenuItemIcon name="gear-outline" size="sm" />Settings</fk-menu-item>
|
|
95
94
|
<fk-menu-separator />
|
|
96
|
-
<fk-menu-item icon="open-rect-arrow-out-fill"
|
|
95
|
+
<fk-menu-item [danger]="true"><fk-icon fkMenuItemIcon name="open-rect-arrow-out-fill" size="sm" />Delete</fk-menu-item>
|
|
97
96
|
</ng-template>
|
|
98
97
|
</fk-dropdown-menu>
|
|
99
98
|
```
|
|
@@ -153,10 +152,10 @@ Directives:
|
|
|
153
152
|
<fk-dropdown-menu>
|
|
154
153
|
<button fkDropdownTrigger>Options</button>
|
|
155
154
|
<ng-template fkDropdownPanel>
|
|
156
|
-
<fk-menu-item
|
|
157
|
-
<fk-menu-item icon="gear-outline"
|
|
155
|
+
<fk-menu-item><fk-icon fkMenuItemIcon name="eye" size="sm" />View</fk-menu-item>
|
|
156
|
+
<fk-menu-item [disabled]="true"><fk-icon fkMenuItemIcon name="gear-outline" size="sm" />Settings (locked)</fk-menu-item>
|
|
158
157
|
<fk-menu-separator />
|
|
159
|
-
<fk-menu-item
|
|
158
|
+
<fk-menu-item><fk-icon fkMenuItemIcon name="info" size="sm" />Help</fk-menu-item>
|
|
160
159
|
</ng-template>
|
|
161
160
|
</fk-dropdown-menu>
|
|
162
161
|
```
|
|
@@ -167,9 +166,9 @@ Directives:
|
|
|
167
166
|
<fk-dropdown-menu>
|
|
168
167
|
<button fkDropdownTrigger>Manage</button>
|
|
169
168
|
<ng-template fkDropdownPanel>
|
|
170
|
-
<fk-menu-item
|
|
169
|
+
<fk-menu-item><fk-icon fkMenuItemIcon name="eye" size="sm" />View</fk-menu-item>
|
|
171
170
|
<fk-menu-separator />
|
|
172
|
-
<fk-menu-item icon="open-rect-arrow-out-fill"
|
|
171
|
+
<fk-menu-item [danger]="true"><fk-icon fkMenuItemIcon name="open-rect-arrow-out-fill" size="sm" />Remove</fk-menu-item>
|
|
173
172
|
</ng-template>
|
|
174
173
|
</fk-dropdown-menu>
|
|
175
174
|
```
|
package/ui/menu-item/README.md
CHANGED
|
@@ -10,11 +10,10 @@ Atom-level menu primitives for rendering actionable items and visual dividers in
|
|
|
10
10
|
|
|
11
11
|
#### Inputs
|
|
12
12
|
|
|
13
|
-
| Input | Type
|
|
14
|
-
| ---------- |
|
|
15
|
-
| `
|
|
16
|
-
| `
|
|
17
|
-
| `disabled` | `boolean` | `false` | Disables the item |
|
|
13
|
+
| Input | Type | Default | Description |
|
|
14
|
+
| ---------- | --------- | ------- | ---------------------------------- |
|
|
15
|
+
| `danger` | `boolean` | `false` | Applies destructive/danger styling |
|
|
16
|
+
| `disabled` | `boolean` | `false` | Disables the item |
|
|
18
17
|
|
|
19
18
|
#### Outputs
|
|
20
19
|
|
|
@@ -24,12 +23,17 @@ Atom-level menu primitives for rendering actionable items and visual dividers in
|
|
|
24
23
|
|
|
25
24
|
#### Content
|
|
26
25
|
|
|
27
|
-
The item label is
|
|
26
|
+
The item label is the default projected content. A leading icon is projected via the `[fkMenuItemIcon]` slot — the app owns the icon system, so project your own `fk-icon` (or any element):
|
|
28
27
|
|
|
29
28
|
```html
|
|
30
|
-
<fk-menu-item>
|
|
29
|
+
<fk-menu-item>
|
|
30
|
+
<fk-icon fkMenuItemIcon name="eye" size="sm" />
|
|
31
|
+
View Details
|
|
32
|
+
</fk-menu-item>
|
|
31
33
|
```
|
|
32
34
|
|
|
35
|
+
`FkMenuItemIconDirective` (the `[fkMenuItemIcon]` marker) is exported from `@frame-kit/ui-ng`.
|
|
36
|
+
|
|
33
37
|
### fk-menu-separator
|
|
34
38
|
|
|
35
39
|
A visual divider between menu item groups. No inputs or outputs.
|
|
@@ -42,7 +46,7 @@ A visual divider between menu item groups. No inputs or outputs.
|
|
|
42
46
|
|
|
43
47
|
## Features
|
|
44
48
|
|
|
45
|
-
-
|
|
49
|
+
- Label + optional leading-icon slot (`[fkMenuItemIcon]`) via content projection
|
|
46
50
|
- Danger variant for destructive actions
|
|
47
51
|
- Disabled state with `aria-disabled` and keyboard exclusion
|
|
48
52
|
- Keyboard activation via Enter and Space
|
|
@@ -55,9 +59,15 @@ A visual divider between menu item groups. No inputs or outputs.
|
|
|
55
59
|
## Quick Start
|
|
56
60
|
|
|
57
61
|
```html
|
|
58
|
-
<fk-menu-item
|
|
62
|
+
<fk-menu-item (itemClick)="onView()">
|
|
63
|
+
<fk-icon fkMenuItemIcon name="eye" size="sm" />
|
|
64
|
+
View Details
|
|
65
|
+
</fk-menu-item>
|
|
59
66
|
<fk-menu-separator />
|
|
60
|
-
<fk-menu-item
|
|
67
|
+
<fk-menu-item [disabled]="true">
|
|
68
|
+
<fk-icon fkMenuItemIcon name="gear-outline" size="sm" />
|
|
69
|
+
Settings
|
|
70
|
+
</fk-menu-item>
|
|
61
71
|
<fk-menu-item [danger]="true" (itemClick)="onDelete()">Delete</fk-menu-item>
|
|
62
72
|
```
|
|
63
73
|
|
|
@@ -93,7 +103,10 @@ export class ExampleComponent {}
|
|
|
93
103
|
### With icon
|
|
94
104
|
|
|
95
105
|
```html
|
|
96
|
-
<fk-menu-item
|
|
106
|
+
<fk-menu-item>
|
|
107
|
+
<fk-icon fkMenuItemIcon name="eye" size="sm" />
|
|
108
|
+
View
|
|
109
|
+
</fk-menu-item>
|
|
97
110
|
```
|
|
98
111
|
|
|
99
112
|
### Without icon
|
|
@@ -117,10 +130,10 @@ export class ExampleComponent {}
|
|
|
117
130
|
### With separator
|
|
118
131
|
|
|
119
132
|
```html
|
|
120
|
-
<fk-menu-item
|
|
121
|
-
<fk-menu-item
|
|
133
|
+
<fk-menu-item><fk-icon fkMenuItemIcon name="eye" size="sm" />View</fk-menu-item>
|
|
134
|
+
<fk-menu-item><fk-icon fkMenuItemIcon name="gear-outline" size="sm" />Edit</fk-menu-item>
|
|
122
135
|
<fk-menu-separator />
|
|
123
|
-
<fk-menu-item icon="open-rect-arrow-out-fill"
|
|
136
|
+
<fk-menu-item [danger]="true"> <fk-icon fkMenuItemIcon name="open-rect-arrow-out-fill" size="sm" />Delete </fk-menu-item>
|
|
124
137
|
```
|
|
125
138
|
|
|
126
139
|
### Handling clicks
|
package/ui/node-tree/README.md
CHANGED
|
@@ -8,14 +8,15 @@ A token-driven, hierarchical tree component for Angular with expand/collapse, se
|
|
|
8
8
|
|
|
9
9
|
### Inputs
|
|
10
10
|
|
|
11
|
-
| Input | Type
|
|
12
|
-
| ----------------- |
|
|
13
|
-
| `nodes` | `TreeNode[]`
|
|
14
|
-
| `selectedNodeId` | `string \| undefined`
|
|
15
|
-
| `expandedNodeIds` | `string[] \| undefined`
|
|
16
|
-
| `draggable` | `boolean`
|
|
17
|
-
| `canDrop` | `CanDropFn \| undefined`
|
|
18
|
-
| `
|
|
11
|
+
| Input | Type | Default | Description |
|
|
12
|
+
| ----------------- | ----------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| `nodes` | `TreeNode[]` | _required_ | Flat array of tree nodes; parent-child relationships via `parentId` |
|
|
14
|
+
| `selectedNodeId` | `string \| undefined` | `undefined` | Currently selected node ID |
|
|
15
|
+
| `expandedNodeIds` | `string[] \| undefined` | `undefined` | Controlled expanded state; `undefined` uses internal state |
|
|
16
|
+
| `draggable` | `boolean` | `false` | Enables drag-and-drop with drag handles |
|
|
17
|
+
| `canDrop` | `CanDropFn \| undefined` | `undefined` | Consumer callback to validate drop targets |
|
|
18
|
+
| `iconTemplate` | `TemplateRef<{ $implicit: FlatNode }>` \| `undefined` | `undefined` | Template rendering each row's leading icon (receives the node as `$implicit`); default rows render no icon when omitted |
|
|
19
|
+
| `className` | `string` | `''` | Additional CSS classes for the host |
|
|
19
20
|
|
|
20
21
|
### Outputs
|
|
21
22
|
|
|
@@ -31,7 +32,7 @@ A token-driven, hierarchical tree component for Angular with expand/collapse, se
|
|
|
31
32
|
interface TreeNode<T = unknown> {
|
|
32
33
|
id: string;
|
|
33
34
|
label: string;
|
|
34
|
-
icon?: string;
|
|
35
|
+
icon?: string; // rendered only via [iconTemplate] — the tree is icon-agnostic
|
|
35
36
|
parentId?: string | null;
|
|
36
37
|
draggable?: boolean;
|
|
37
38
|
data?: T;
|
|
@@ -55,14 +56,28 @@ interface NodeDropEvent {
|
|
|
55
56
|
type CanDropFn = (draggedNode: FlatNode, targetNode: FlatNode, position: DropPosition) => boolean;
|
|
56
57
|
```
|
|
57
58
|
|
|
59
|
+
### Row icons
|
|
60
|
+
|
|
61
|
+
The tree is icon-agnostic: `node.icon` is only rendered if you supply an `iconTemplate` that reads it (the app owns the icon system). Default rows show no icon without it:
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<ng-template #nodeIcon let-node>
|
|
65
|
+
<fk-icon [name]="node.icon" size="sm" />
|
|
66
|
+
</ng-template>
|
|
67
|
+
|
|
68
|
+
<fk-node-tree [nodes]="nodes" [iconTemplate]="nodeIcon" />
|
|
69
|
+
```
|
|
70
|
+
|
|
58
71
|
### Content Projection
|
|
59
72
|
|
|
60
|
-
|
|
73
|
+
For full control of the row, use the `fkNodeTreeRow` structural directive instead — it replaces the whole row (icon included), so you render your own icon in the template:
|
|
61
74
|
|
|
62
75
|
```html
|
|
63
76
|
<fk-node-tree [nodes]="nodes">
|
|
64
77
|
<ng-template fkNodeTreeRow let-node>
|
|
78
|
+
@if (node.icon) {
|
|
65
79
|
<fk-icon [name]="node.icon" size="sm" />
|
|
80
|
+
}
|
|
66
81
|
<span>{{ node.label }}</span>
|
|
67
82
|
</ng-template>
|
|
68
83
|
</fk-node-tree>
|
package/ui/timeline/README.md
CHANGED
|
@@ -8,16 +8,17 @@ A token-driven timeline component for displaying ordered steps, resolution chain
|
|
|
8
8
|
|
|
9
9
|
### Inputs
|
|
10
10
|
|
|
11
|
-
| Input
|
|
12
|
-
|
|
|
13
|
-
| `items`
|
|
14
|
-
| `
|
|
15
|
-
| `
|
|
16
|
-
| `
|
|
17
|
-
| `
|
|
18
|
-
| `
|
|
19
|
-
| `
|
|
20
|
-
| `
|
|
11
|
+
| Input | Type | Default | Description |
|
|
12
|
+
| -------------- | ------------------------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| `items` | `TimelineItemData[]` | `[]` | Declarative data for timeline entries |
|
|
14
|
+
| `iconTemplate` | `TemplateRef<{ $implicit: TimelineItemData }>` \| `undefined` | `undefined` | Template rendering each item's marker icon (receives the item as `$implicit`); items render no icon when omitted |
|
|
15
|
+
| `orientation` | `'vertical' \| 'horizontal'` | `'vertical'` | Layout direction |
|
|
16
|
+
| `align` | `'start' \| 'end' \| 'alternate'` | `'start'` | Content alignment relative to connector line |
|
|
17
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Marker and connector sizing |
|
|
18
|
+
| `reverse` | `boolean` | `false` | Reverse item order |
|
|
19
|
+
| `ariaLabel` | `string \| null` | `null` | Accessible label |
|
|
20
|
+
| `id` | `string \| null` | `null` | Element ID |
|
|
21
|
+
| `className` | `string` | `''` | Additional CSS classes merged onto the host |
|
|
21
22
|
|
|
22
23
|
### Types
|
|
23
24
|
|
|
@@ -27,7 +28,7 @@ interface TimelineItemData {
|
|
|
27
28
|
title?: string;
|
|
28
29
|
description?: string;
|
|
29
30
|
timestamp?: string;
|
|
30
|
-
icon?: string;
|
|
31
|
+
icon?: string; // rendered only via [iconTemplate] — the timeline is icon-agnostic
|
|
31
32
|
status?: TimelineItemStatus;
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -49,7 +50,7 @@ None.
|
|
|
49
50
|
- Three alignment modes (start, end, alternate)
|
|
50
51
|
- Three size presets (sm, md, lg)
|
|
51
52
|
- Five status variants (default, active, completed, error, warning)
|
|
52
|
-
-
|
|
53
|
+
- Per-item marker icons via a consumer-supplied `iconTemplate`
|
|
53
54
|
- Optional timestamp display
|
|
54
55
|
- Reversible item order
|
|
55
56
|
- Content projection for complex custom items
|
|
@@ -142,8 +143,15 @@ export class ExampleComponent {}
|
|
|
142
143
|
|
|
143
144
|
### With icons
|
|
144
145
|
|
|
146
|
+
Supply an `iconTemplate` that reads `item.icon` — the timeline never renders `fk-icon` itself:
|
|
147
|
+
|
|
145
148
|
```html
|
|
149
|
+
<ng-template #marker let-item>
|
|
150
|
+
<fk-icon [name]="item.icon" size="xs" />
|
|
151
|
+
</ng-template>
|
|
152
|
+
|
|
146
153
|
<fk-timeline
|
|
154
|
+
[iconTemplate]="marker"
|
|
147
155
|
[items]="[
|
|
148
156
|
{ title: 'Submitted', icon: 'circle-check-outline', status: 'completed' },
|
|
149
157
|
{ title: 'In Review', icon: 'shield-alert', status: 'active' },
|
package/ui/user-menu/README.md
CHANGED
|
@@ -8,29 +8,30 @@ A token-driven user menu molecule that composes an avatar trigger with a dropdow
|
|
|
8
8
|
|
|
9
9
|
### Inputs
|
|
10
10
|
|
|
11
|
-
| Input | Type | Default | Description
|
|
12
|
-
| ------------- | ----------------------------------------------------------- | -------------- |
|
|
13
|
-
| name | `string` | — | **Required.** User's display name
|
|
14
|
-
| email | `string` \| `null` | `null` | User's email address
|
|
15
|
-
| avatarUrl | `string` \| `null` | `null` | URL to the user's avatar image
|
|
16
|
-
| initials | `string` \| `null` | `null` | Custom initials — auto-derived from `name` if absent
|
|
17
|
-
| userId | `string` \| `null` | `null` | Optional user identifier
|
|
18
|
-
| status | `"online"` \| `"offline"` \| `"away"` \| `"busy"` \| `null` | `null` | Presence status passed to the avatar
|
|
19
|
-
| showStatus | `boolean` | `false` | Show the status indicator on the avatar
|
|
20
|
-
| menuItems | `MenuItem[]` | `[]` | Configurable list of menu actions
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
11
|
+
| Input | Type | Default | Description |
|
|
12
|
+
| ------------- | ----------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| name | `string` | — | **Required.** User's display name |
|
|
14
|
+
| email | `string` \| `null` | `null` | User's email address |
|
|
15
|
+
| avatarUrl | `string` \| `null` | `null` | URL to the user's avatar image |
|
|
16
|
+
| initials | `string` \| `null` | `null` | Custom initials — auto-derived from `name` if absent |
|
|
17
|
+
| userId | `string` \| `null` | `null` | Optional user identifier |
|
|
18
|
+
| status | `"online"` \| `"offline"` \| `"away"` \| `"busy"` \| `null` | `null` | Presence status passed to the avatar |
|
|
19
|
+
| showStatus | `boolean` | `false` | Show the status indicator on the avatar |
|
|
20
|
+
| menuItems | `MenuItem[]` | `[]` | Configurable list of menu actions |
|
|
21
|
+
| iconTemplate | `TemplateRef<{ $implicit: MenuItem }>` \| `undefined` | `undefined` | Template rendering each item's leading icon (receives the item as `$implicit`); items render without an icon when omitted |
|
|
22
|
+
| placement | `"bottom-start"` \| `"bottom-end"` | `"bottom-end"` | Preferred panel alignment — auto-flips and shifts to stay within the viewport |
|
|
23
|
+
| size | `"sm"` \| `"md"` \| `"lg"` | `"md"` | Avatar size |
|
|
24
|
+
| variant | `"dropdown"` \| `"popover"` | `"dropdown"` | `"popover"` adds a user header inside the panel |
|
|
25
|
+
| showName | `boolean` | `false` | Show user name next to the avatar in the trigger |
|
|
26
|
+
| showEmail | `boolean` | `false` | Show email next to the avatar in the trigger |
|
|
27
|
+
| showChevron | `boolean` | `true` | Show a chevron indicator on the trigger |
|
|
28
|
+
| infoPlacement | `"start"` \| `"end"` | `"end"` | Position name/email relative to the avatar — `"start"` places text on the left |
|
|
29
|
+
| badge | `string` \| `null` | `null` | Badge label (e.g. "Admin", "Pro") |
|
|
30
|
+
| disabled | `boolean` | `false` | Disable the trigger |
|
|
31
|
+
| loading | `boolean` | `false` | Disable the trigger during loading |
|
|
32
|
+
| className | `string` | `""` | Additional CSS classes merged with hook classes |
|
|
33
|
+
| id | `string` \| `null` | `null` | Sets the host `id` attribute |
|
|
34
|
+
| ariaLabel | `string` \| `null` | `null` | Custom `aria-label` (defaults to "User menu for {name}") |
|
|
34
35
|
|
|
35
36
|
### Outputs
|
|
36
37
|
|
|
@@ -48,7 +49,7 @@ A token-driven user menu molecule that composes an avatar trigger with a dropdow
|
|
|
48
49
|
interface MenuItem {
|
|
49
50
|
label: string;
|
|
50
51
|
value: string;
|
|
51
|
-
icon?: string;
|
|
52
|
+
icon?: string; // rendered only via [iconTemplate] — see below
|
|
52
53
|
disabled?: boolean;
|
|
53
54
|
danger?: boolean;
|
|
54
55
|
separator?: boolean;
|
|
@@ -57,12 +58,14 @@ interface MenuItem {
|
|
|
57
58
|
|
|
58
59
|
When `separator` is `true`, the item renders as a horizontal divider instead of a button.
|
|
59
60
|
|
|
61
|
+
`fk-user-menu` is icon-agnostic: `icon` is just a string your `iconTemplate` reads — the widget never renders `fk-icon` itself. Without an `iconTemplate`, items show no icon.
|
|
62
|
+
|
|
60
63
|
---
|
|
61
64
|
|
|
62
65
|
## Features
|
|
63
66
|
|
|
64
67
|
- Composes `fk-avatar` for the trigger display
|
|
65
|
-
- Configurable menu items with
|
|
68
|
+
- Configurable menu items with danger styling, disabled state, separators, and consumer-supplied icons (via `iconTemplate`)
|
|
66
69
|
- Two variants: `dropdown` (items only) and `popover` (user header + items)
|
|
67
70
|
- Optional name, email, badge, and chevron in the trigger with configurable info placement (`start` or `end`)
|
|
68
71
|
- Viewport-aware positioning — panel auto-flips vertically and shifts horizontally to avoid clipping
|
|
@@ -75,7 +78,12 @@ When `separator` is `true`, the item renders as a horizontal divider instead of
|
|
|
75
78
|
## Quick Start
|
|
76
79
|
|
|
77
80
|
```html
|
|
78
|
-
|
|
81
|
+
<!-- Supply an icon template that reads item.icon; the app owns the icon system. -->
|
|
82
|
+
<ng-template #menuIcon let-item>
|
|
83
|
+
<fk-icon [name]="item.icon" size="sm" />
|
|
84
|
+
</ng-template>
|
|
85
|
+
|
|
86
|
+
<fk-user-menu name="Jane Doe" [menuItems]="menuItems" [iconTemplate]="menuIcon" (menuItemClick)="onMenuItem($event)" (logoutClick)="onLogout()" />
|
|
79
87
|
```
|
|
80
88
|
|
|
81
89
|
```ts
|
|
@@ -87,6 +95,8 @@ menuItems: MenuItem[] = [
|
|
|
87
95
|
];
|
|
88
96
|
```
|
|
89
97
|
|
|
98
|
+
Omit `[iconTemplate]` (and the `icon` fields) if you don't need icons.
|
|
99
|
+
|
|
90
100
|
---
|
|
91
101
|
|
|
92
102
|
## Import
|