@frame-kit/ui-ng 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/COMPONENTS.md +683 -0
  2. package/DEVELOPMENT_GUIDE.md +1102 -0
  3. package/LICENSE +21 -0
  4. package/README.md +69 -0
  5. package/THEMING.md +130 -0
  6. package/core/headline/README.md +121 -0
  7. package/core/icon/README.md +173 -0
  8. package/core/image/README.md +210 -0
  9. package/core/link/README.md +297 -0
  10. package/core/separator/README.md +145 -0
  11. package/core/text/README.md +240 -0
  12. package/directives/infinite-scroll/README.md +102 -0
  13. package/directives/spotlight/README.md +154 -0
  14. package/directives/tooltip/README.md +147 -0
  15. package/docs/endpoint-link/README.md +142 -0
  16. package/docs/method-badge/README.md +154 -0
  17. package/fesm2022/frame-kit-ui-ng-core-headline.mjs +122 -0
  18. package/fesm2022/frame-kit-ui-ng-core-headline.mjs.map +1 -0
  19. package/fesm2022/frame-kit-ui-ng-core-icon.mjs +189 -0
  20. package/fesm2022/frame-kit-ui-ng-core-icon.mjs.map +1 -0
  21. package/fesm2022/frame-kit-ui-ng-core-image.mjs +123 -0
  22. package/fesm2022/frame-kit-ui-ng-core-image.mjs.map +1 -0
  23. package/fesm2022/frame-kit-ui-ng-core-link.mjs +369 -0
  24. package/fesm2022/frame-kit-ui-ng-core-link.mjs.map +1 -0
  25. package/fesm2022/frame-kit-ui-ng-core-separator.mjs +59 -0
  26. package/fesm2022/frame-kit-ui-ng-core-separator.mjs.map +1 -0
  27. package/fesm2022/frame-kit-ui-ng-core-text.mjs +204 -0
  28. package/fesm2022/frame-kit-ui-ng-core-text.mjs.map +1 -0
  29. package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs +74 -0
  30. package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs.map +1 -0
  31. package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs +76 -0
  32. package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs.map +1 -0
  33. package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs +425 -0
  34. package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs.map +1 -0
  35. package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs +63 -0
  36. package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs.map +1 -0
  37. package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs +43 -0
  38. package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs.map +1 -0
  39. package/fesm2022/frame-kit-ui-ng-forms.mjs +3632 -0
  40. package/fesm2022/frame-kit-ui-ng-forms.mjs.map +1 -0
  41. package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs +239 -0
  42. package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs.map +1 -0
  43. package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs +132 -0
  44. package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs.map +1 -0
  45. package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs +133 -0
  46. package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs.map +1 -0
  47. package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs +60 -0
  48. package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs.map +1 -0
  49. package/fesm2022/frame-kit-ui-ng-services-toast.mjs +166 -0
  50. package/fesm2022/frame-kit-ui-ng-services-toast.mjs.map +1 -0
  51. package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs +214 -0
  52. package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs.map +1 -0
  53. package/fesm2022/frame-kit-ui-ng-ui-alert.mjs +82 -0
  54. package/fesm2022/frame-kit-ui-ng-ui-alert.mjs.map +1 -0
  55. package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs +76 -0
  56. package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs.map +1 -0
  57. package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs +81 -0
  58. package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs.map +1 -0
  59. package/fesm2022/frame-kit-ui-ng-ui-badge.mjs +81 -0
  60. package/fesm2022/frame-kit-ui-ng-ui-badge.mjs.map +1 -0
  61. package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs +68 -0
  62. package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs.map +1 -0
  63. package/fesm2022/frame-kit-ui-ng-ui-button.mjs +108 -0
  64. package/fesm2022/frame-kit-ui-ng-ui-button.mjs.map +1 -0
  65. package/fesm2022/frame-kit-ui-ng-ui-callout.mjs +58 -0
  66. package/fesm2022/frame-kit-ui-ng-ui-callout.mjs.map +1 -0
  67. package/fesm2022/frame-kit-ui-ng-ui-card.mjs +70 -0
  68. package/fesm2022/frame-kit-ui-ng-ui-card.mjs.map +1 -0
  69. package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs +113 -0
  70. package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs.map +1 -0
  71. package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs +1288 -0
  72. package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs.map +1 -0
  73. package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs +456 -0
  74. package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs.map +1 -0
  75. package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs +398 -0
  76. package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs.map +1 -0
  77. package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs +398 -0
  78. package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs.map +1 -0
  79. package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs +125 -0
  80. package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs.map +1 -0
  81. package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs +113 -0
  82. package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs.map +1 -0
  83. package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs +111 -0
  84. package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs.map +1 -0
  85. package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs +103 -0
  86. package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs.map +1 -0
  87. package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs +135 -0
  88. package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs.map +1 -0
  89. package/fesm2022/frame-kit-ui-ng-ui-loader.mjs +81 -0
  90. package/fesm2022/frame-kit-ui-ng-ui-loader.mjs.map +1 -0
  91. package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs +79 -0
  92. package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs.map +1 -0
  93. package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs +40 -0
  94. package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs.map +1 -0
  95. package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs +110 -0
  96. package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs.map +1 -0
  97. package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs +91 -0
  98. package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs.map +1 -0
  99. package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs +86 -0
  100. package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs.map +1 -0
  101. package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs +443 -0
  102. package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs.map +1 -0
  103. package/fesm2022/frame-kit-ui-ng-ui-note.mjs +56 -0
  104. package/fesm2022/frame-kit-ui-ng-ui-note.mjs.map +1 -0
  105. package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs +105 -0
  106. package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs.map +1 -0
  107. package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs +110 -0
  108. package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs.map +1 -0
  109. package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs +129 -0
  110. package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs.map +1 -0
  111. package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs +42 -0
  112. package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs.map +1 -0
  113. package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs +894 -0
  114. package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs.map +1 -0
  115. package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs +81 -0
  116. package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs.map +1 -0
  117. package/fesm2022/frame-kit-ui-ng-ui-toast.mjs +179 -0
  118. package/fesm2022/frame-kit-ui-ng-ui-toast.mjs.map +1 -0
  119. package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs +143 -0
  120. package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs.map +1 -0
  121. package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs +191 -0
  122. package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs.map +1 -0
  123. package/fesm2022/frame-kit-ui-ng.mjs +58 -0
  124. package/fesm2022/frame-kit-ui-ng.mjs.map +1 -0
  125. package/layouts/app-shell/README.md +357 -0
  126. package/layouts/content-split/README.md +180 -0
  127. package/package.json +253 -0
  128. package/services/overlay-orchestrator/README.md +184 -0
  129. package/services/spotlight/README.md +61 -0
  130. package/services/toast/README.md +118 -0
  131. package/types/frame-kit-ui-ng-core-headline.d.ts +38 -0
  132. package/types/frame-kit-ui-ng-core-icon.d.ts +74 -0
  133. package/types/frame-kit-ui-ng-core-image.d.ts +93 -0
  134. package/types/frame-kit-ui-ng-core-link.d.ts +251 -0
  135. package/types/frame-kit-ui-ng-core-separator.d.ts +28 -0
  136. package/types/frame-kit-ui-ng-core-text.d.ts +186 -0
  137. package/types/frame-kit-ui-ng-directives-infinite-scroll.d.ts +42 -0
  138. package/types/frame-kit-ui-ng-directives-spotlight.d.ts +51 -0
  139. package/types/frame-kit-ui-ng-directives-tooltip.d.ts +70 -0
  140. package/types/frame-kit-ui-ng-docs-endpoint-link.d.ts +43 -0
  141. package/types/frame-kit-ui-ng-docs-method-badge.d.ts +30 -0
  142. package/types/frame-kit-ui-ng-forms.d.ts +1674 -0
  143. package/types/frame-kit-ui-ng-layouts-app-shell.d.ts +75 -0
  144. package/types/frame-kit-ui-ng-layouts-content-split.d.ts +43 -0
  145. package/types/frame-kit-ui-ng-services-overlay-orchestrator.d.ts +96 -0
  146. package/types/frame-kit-ui-ng-services-spotlight.d.ts +32 -0
  147. package/types/frame-kit-ui-ng-services-toast.d.ts +100 -0
  148. package/types/frame-kit-ui-ng-ui-accordion.d.ts +86 -0
  149. package/types/frame-kit-ui-ng-ui-alert.d.ts +34 -0
  150. package/types/frame-kit-ui-ng-ui-avatar-stack.d.ts +38 -0
  151. package/types/frame-kit-ui-ng-ui-avatar.d.ts +36 -0
  152. package/types/frame-kit-ui-ng-ui-badge.d.ts +33 -0
  153. package/types/frame-kit-ui-ng-ui-breadcrumb.d.ts +45 -0
  154. package/types/frame-kit-ui-ng-ui-button.d.ts +48 -0
  155. package/types/frame-kit-ui-ng-ui-callout.d.ts +26 -0
  156. package/types/frame-kit-ui-ng-ui-card.d.ts +30 -0
  157. package/types/frame-kit-ui-ng-ui-copyable-field.d.ts +62 -0
  158. package/types/frame-kit-ui-ng-ui-data-table.d.ts +482 -0
  159. package/types/frame-kit-ui-ng-ui-dialog.d.ts +166 -0
  160. package/types/frame-kit-ui-ng-ui-drawer.d.ts +130 -0
  161. package/types/frame-kit-ui-ng-ui-dropdown-menu.d.ts +77 -0
  162. package/types/frame-kit-ui-ng-ui-editable-field.d.ts +65 -0
  163. package/types/frame-kit-ui-ng-ui-icon-badge.d.ts +45 -0
  164. package/types/frame-kit-ui-ng-ui-icon-list.d.ts +67 -0
  165. package/types/frame-kit-ui-ng-ui-inline-edit.d.ts +44 -0
  166. package/types/frame-kit-ui-ng-ui-list-editor.d.ts +56 -0
  167. package/types/frame-kit-ui-ng-ui-loader.d.ts +32 -0
  168. package/types/frame-kit-ui-ng-ui-menu-item.d.ts +27 -0
  169. package/types/frame-kit-ui-ng-ui-nav-brand.d.ts +25 -0
  170. package/types/frame-kit-ui-ng-ui-nav-group.d.ts +60 -0
  171. package/types/frame-kit-ui-ng-ui-nav-separator.d.ts +33 -0
  172. package/types/frame-kit-ui-ng-ui-node-tree-breadcrumb.d.ts +35 -0
  173. package/types/frame-kit-ui-ng-ui-node-tree.d.ts +135 -0
  174. package/types/frame-kit-ui-ng-ui-note.d.ts +22 -0
  175. package/types/frame-kit-ui-ng-ui-numbered-list.d.ts +52 -0
  176. package/types/frame-kit-ui-ng-ui-pagination.d.ts +49 -0
  177. package/types/frame-kit-ui-ng-ui-progress-bar.d.ts +50 -0
  178. package/types/frame-kit-ui-ng-ui-sidenav-link.d.ts +24 -0
  179. package/types/frame-kit-ui-ng-ui-tabs.d.ts +266 -0
  180. package/types/frame-kit-ui-ng-ui-timeline.d.ts +42 -0
  181. package/types/frame-kit-ui-ng-ui-toast.d.ts +56 -0
  182. package/types/frame-kit-ui-ng-ui-user-menu.d.ts +87 -0
  183. package/types/frame-kit-ui-ng-ui-wizard-dialog.d.ts +116 -0
  184. package/types/frame-kit-ui-ng.d.ts +53 -0
  185. package/ui/accordion/README.md +261 -0
  186. package/ui/alert/README.md +211 -0
  187. package/ui/avatar/README.md +167 -0
  188. package/ui/avatar-stack/README.md +164 -0
  189. package/ui/badge/README.md +162 -0
  190. package/ui/breadcrumb/README.md +240 -0
  191. package/ui/button/README.md +184 -0
  192. package/ui/callout/README.md +159 -0
  193. package/ui/card/README.md +174 -0
  194. package/ui/copyable-field/README.md +235 -0
  195. package/ui/data-table/README.md +408 -0
  196. package/ui/dialog/README.md +222 -0
  197. package/ui/drawer/README.md +274 -0
  198. package/ui/dropdown-menu/README.md +336 -0
  199. package/ui/editable-field/README.md +171 -0
  200. package/ui/icon-badge/README.md +131 -0
  201. package/ui/icon-list/README.md +205 -0
  202. package/ui/inline-edit/README.md +135 -0
  203. package/ui/list-editor/README.md +162 -0
  204. package/ui/loader/README.md +160 -0
  205. package/ui/menu-item/README.md +204 -0
  206. package/ui/nav-brand/README.md +111 -0
  207. package/ui/nav-group/README.md +145 -0
  208. package/ui/nav-separator/README.md +44 -0
  209. package/ui/node-tree/README.md +278 -0
  210. package/ui/node-tree-breadcrumb/README.md +164 -0
  211. package/ui/note/README.md +146 -0
  212. package/ui/numbered-list/README.md +187 -0
  213. package/ui/pagination/README.md +174 -0
  214. package/ui/progress-bar/README.md +223 -0
  215. package/ui/sidenav-link/README.md +214 -0
  216. package/ui/tabs/README.md +204 -0
  217. package/ui/timeline/README.md +285 -0
  218. package/ui/toast/README.md +243 -0
  219. package/ui/user-menu/README.md +260 -0
  220. package/ui/wizard-dialog/README.md +283 -0
@@ -0,0 +1,278 @@
1
+ # fk-node-tree
2
+
3
+ A token-driven, hierarchical tree component for Angular with expand/collapse, selection, drag-and-drop reparenting, position-aware sibling insertion, consumer drop validation, and custom row templates.
4
+
5
+ ---
6
+
7
+ ## API
8
+
9
+ ### Inputs
10
+
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
+ | `className` | `string` | `''` | Additional CSS classes for the host |
19
+
20
+ ### Outputs
21
+
22
+ | Output | Type | Description |
23
+ | ------------ | ----------------- | ----------------------------------------------- |
24
+ | `nodeSelect` | `TreeNode` | Emitted when a row is clicked |
25
+ | `nodeExpand` | `NodeExpandEvent` | Emitted when a node is expanded or collapsed |
26
+ | `nodeDrop` | `NodeDropEvent` | Emitted when a valid drag-and-drop is completed |
27
+
28
+ ### Types
29
+
30
+ ```ts
31
+ interface TreeNode<T = unknown> {
32
+ id: string;
33
+ label: string;
34
+ icon?: string;
35
+ parentId?: string | null;
36
+ draggable?: boolean;
37
+ data?: T;
38
+ }
39
+
40
+ interface NodeExpandEvent {
41
+ nodeId: string;
42
+ expanded: boolean;
43
+ }
44
+
45
+ type DropPosition = 'before' | 'inside' | 'after';
46
+
47
+ interface NodeDropEvent {
48
+ nodeId: string;
49
+ newParentId: string | null;
50
+ previousParentId: string | null;
51
+ position: DropPosition;
52
+ referenceNodeId: string;
53
+ }
54
+
55
+ type CanDropFn = (draggedNode: FlatNode, targetNode: FlatNode, position: DropPosition) => boolean;
56
+ ```
57
+
58
+ ### Content Projection
59
+
60
+ Custom row templates use the `fkNodeTreeRow` structural directive:
61
+
62
+ ```html
63
+ <fk-node-tree [nodes]="nodes">
64
+ <ng-template fkNodeTreeRow let-node>
65
+ <fk-icon [name]="node.icon" size="sm" />
66
+ <span>{{ node.label }}</span>
67
+ </ng-template>
68
+ </fk-node-tree>
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Features
74
+
75
+ - Hierarchical tree rendering from flat node array
76
+ - Expand/collapse (uncontrolled and controlled)
77
+ - Row selection
78
+ - Drag-and-drop reparenting via drag handle
79
+ - Position-aware drops (before, inside, after)
80
+ - Consumer drop validation via `canDrop` callback
81
+ - Auto-expand on hover during drag
82
+ - Custom row templates
83
+ - Token-driven styling with dark mode support
84
+ - Accessible (role=tree, treeitem, aria-level, aria-expanded, aria-selected)
85
+
86
+ ---
87
+
88
+ ## Quick Start
89
+
90
+ ```html
91
+ <fk-node-tree [nodes]="nodes" [selectedNodeId]="selectedId" (nodeSelect)="onSelect($event)" (nodeExpand)="onExpand($event)" />
92
+ ```
93
+
94
+ ---
95
+
96
+ ## Import
97
+
98
+ ```ts
99
+ import { FkNodeTreeComponent } from '@frame-kit/ui-ng';
100
+ ```
101
+
102
+ ```ts
103
+ @Component({
104
+ selector: 'app-org-tree',
105
+ imports: [FkNodeTreeComponent],
106
+ templateUrl: './org-tree.component.html',
107
+ })
108
+ export class OrgTreeComponent {
109
+ nodes: TreeNode[] = [
110
+ { id: 'root', label: 'Acme Realty', parentId: null },
111
+ { id: 'west', label: 'West Region', parentId: 'root' },
112
+ { id: 'east', label: 'East Region', parentId: 'root' },
113
+ ];
114
+ }
115
+ ```
116
+
117
+ ---
118
+
119
+ ## Selector
120
+
121
+ ```html
122
+ <fk-node-tree></fk-node-tree>
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Examples
128
+
129
+ ### Basic tree
130
+
131
+ ```html
132
+ <fk-node-tree [nodes]="nodes" [selectedNodeId]="selectedId" (nodeSelect)="onSelect($event)" (nodeExpand)="onExpand($event)" />
133
+ ```
134
+
135
+ ### Controlled expand
136
+
137
+ ```html
138
+ <fk-node-tree [nodes]="nodes" [expandedNodeIds]="expandedIds" (nodeExpand)="onExpand($event)" />
139
+ ```
140
+
141
+ When `expandedNodeIds` is provided, the tree delegates expand/collapse state to the consumer.
142
+
143
+ ### Drag and drop
144
+
145
+ ```html
146
+ <fk-node-tree [nodes]="nodes" [draggable]="true" (nodeDrop)="onDrop($event)" />
147
+ ```
148
+
149
+ When `draggable` is true, each row with `draggable !== false` shows a grip handle. Dragging to the top 25% of a row triggers a `'before'` drop, the middle 50% triggers `'inside'`, and the bottom 25% triggers `'after'`.
150
+
151
+ ### Drop validation
152
+
153
+ ```ts
154
+ canDrop: CanDropFn = (dragged, target, position) => {
155
+ // Block agents from being dropped into regions
156
+ if (dragged.id.startsWith('agent-') && target.id.startsWith('region-')) {
157
+ return false;
158
+ }
159
+ return true;
160
+ };
161
+ ```
162
+
163
+ ```html
164
+ <fk-node-tree [nodes]="nodes" [draggable]="true" [canDrop]="canDrop" (nodeDrop)="onDrop($event)" />
165
+ ```
166
+
167
+ When `canDrop` returns `false`, the drop target is not highlighted and the drop is blocked.
168
+
169
+ ### Custom row template
170
+
171
+ ```html
172
+ <fk-node-tree [nodes]="nodes">
173
+ <ng-template fkNodeTreeRow let-node>
174
+ @if (node.icon) {
175
+ <fk-icon [name]="node.icon" size="sm" />
176
+ }
177
+ <span style="font-weight: 500;">{{ node.label }}</span>
178
+ <span style="margin-left: auto; font-size: 0.75rem;">Level {{ node.level }}</span>
179
+ </ng-template>
180
+ </fk-node-tree>
181
+ ```
182
+
183
+ ### Locked nodes
184
+
185
+ Set `draggable: false` on individual `TreeNode` entries to prevent them from being dragged while keeping the rest of the tree draggable.
186
+
187
+ ```ts
188
+ nodes = [
189
+ { id: 'root', label: 'Root', parentId: null, draggable: false },
190
+ { id: 'child', label: 'Child', parentId: 'root' },
191
+ ];
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Accessibility
197
+
198
+ - Host element has `role="tree"`
199
+ - Each row has `role="treeitem"` with `aria-level` (1-based), `aria-expanded`, and `aria-selected`
200
+ - All rows are keyboard-focusable (`tabindex="0"`)
201
+ - Expand/collapse toggle has `aria-label` ("Expand" / "Collapse")
202
+ - Drag handle SVG is `aria-hidden="true"`
203
+ - Focus ring uses the `--fk-focus-ring` token
204
+
205
+ ---
206
+
207
+ ## Design Tokens
208
+
209
+ `fk-node-tree` uses the following design tokens:
210
+
211
+ ```scss
212
+ // Row layout
213
+ --fk-node-tree-row-gap
214
+ --fk-node-tree-row-padding
215
+ --fk-node-tree-row-radius
216
+ --fk-node-tree-row-color
217
+ --fk-node-tree-row-font-size
218
+
219
+ // Hover & selection
220
+ --fk-node-tree-row-bg-hover
221
+ --fk-node-tree-row-bg-selected
222
+ --fk-node-tree-row-color-selected
223
+ --fk-node-tree-row-font-weight-selected
224
+
225
+ // Toggle chevron
226
+ --fk-node-tree-row-toggle-color
227
+ --fk-node-tree-row-toggle-color-hover
228
+ --fk-node-tree-row-toggle-bg-hover
229
+
230
+ // Drag handle
231
+ --fk-node-tree-row-handle-color
232
+ --fk-node-tree-row-handle-color-hover
233
+
234
+ // Drop target
235
+ --fk-node-tree-row-bg-drop-target
236
+ --fk-node-tree-row-border-drop-target
237
+ --fk-node-tree-row-drag-source-opacity
238
+
239
+ // Drag preview & placeholder
240
+ --fk-node-tree-drag-preview-bg
241
+ --fk-node-tree-drag-preview-shadow
242
+ --fk-node-tree-drag-placeholder-bg
243
+ ```
244
+
245
+ ### Customizing Tokens
246
+
247
+ Override tokens in your application's global stylesheet or a scoped selector:
248
+
249
+ ```css
250
+ :root {
251
+ --fk-node-tree-row-bg-selected: #ede9fe;
252
+ --fk-node-tree-row-color-selected: #7c3aed;
253
+ --fk-node-tree-row-border-drop-target: #7c3aed;
254
+ }
255
+ ```
256
+
257
+ Or scope overrides to a specific context:
258
+
259
+ ```css
260
+ .dark-theme fk-node-tree {
261
+ --fk-node-tree-row-color: #e2e8f0;
262
+ --fk-node-tree-row-bg-hover: #1e293b;
263
+ --fk-node-tree-row-bg-selected: rgba(99, 102, 241, 0.15);
264
+ --fk-node-tree-row-handle-color: #64748b;
265
+ }
266
+ ```
267
+
268
+ ---
269
+
270
+ ## Behavior Notes
271
+
272
+ - Nodes are provided as a flat array. Parent-child relationships are derived from `parentId`.
273
+ - Nodes with `parentId: null` or `parentId: undefined` are treated as root nodes.
274
+ - When `expandedNodeIds` is provided, the tree operates in controlled mode and will not manage expand state internally.
275
+ - Self-drops and drops onto descendants are blocked automatically.
276
+ - The `canDrop` callback is invoked during drag movement, not at drop time, so invalid targets never highlight.
277
+ - Auto-expand during drag (800ms hover delay) only triggers for the `'inside'` drop position.
278
+ - The drag handle (`cdkDragHandle`) restricts drag initiation to the grip icon, allowing normal click interactions on the rest of the row.
@@ -0,0 +1,164 @@
1
+ # fk-node-tree-breadcrumb
2
+
3
+ A token-driven breadcrumb that displays the ancestry path from root to a
4
+ selected node in a tree hierarchy. Paired with `fk-node-tree` — consume a
5
+ flat `TreeNode[]` array plus a selected node id and render the path as
6
+ clickable ancestor buttons terminating in the current node.
7
+
8
+ Use this when the breadcrumb reflects a tree/hierarchy selection. For
9
+ route-driven crumbs (e.g. URL segments), use a route-based breadcrumb
10
+ instead — this component does not consume routes.
11
+
12
+ ---
13
+
14
+ ## API
15
+
16
+ ### Inputs
17
+
18
+ | Input | Type | Default | Description |
19
+ | ---------------- | --------------------- | ----------- | --------------------------------------------------- |
20
+ | `nodes` | `TreeNode[]` | _required_ | Flat array of tree nodes with `parentId` references |
21
+ | `selectedNodeId` | `string \| undefined` | `undefined` | ID of the currently selected node |
22
+ | `className` | `string` | `''` | Additional CSS classes merged onto the host element |
23
+
24
+ ### Outputs
25
+
26
+ | Output | Type | Description |
27
+ | ------------ | ------------------------ | -------------------------------------------- |
28
+ | `nodeSelect` | `NodeTreeBreadcrumbItem` | Emits when an ancestor breadcrumb is clicked |
29
+
30
+ ---
31
+
32
+ ## Features
33
+
34
+ - Computes full ancestry path from root to selected node
35
+ - Ancestor crumbs are clickable buttons; current node is a non-interactive span
36
+ - Inline SVG chevron separators
37
+ - Token-driven styling with two-tier fallbacks
38
+ - Self-sufficient rendering without any theme file loaded
39
+
40
+ ---
41
+
42
+ ## Quick Start
43
+
44
+ ```html
45
+ <fk-node-tree-breadcrumb [nodes]="nodes()" [selectedNodeId]="selectedNodeId()" (nodeSelect)="onNodeSelect($event)" />
46
+ ```
47
+
48
+ ---
49
+
50
+ ## Import
51
+
52
+ ```ts
53
+ import { NodeTreeBreadcrumbComponent } from '@frame-kit/ui-ng';
54
+ ```
55
+
56
+ ```ts
57
+ @Component({
58
+ selector: 'app-example',
59
+ imports: [NodeTreeBreadcrumbComponent],
60
+ templateUrl: './example.component.html',
61
+ })
62
+ export class ExampleComponent {}
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Selector
68
+
69
+ ```html
70
+ <fk-node-tree-breadcrumb></fk-node-tree-breadcrumb>
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Examples
76
+
77
+ ### Root node selected
78
+
79
+ ```html
80
+ <fk-node-tree-breadcrumb [nodes]="nodes" selectedNodeId="org-1" />
81
+ ```
82
+
83
+ Renders: **Acme Realty**
84
+
85
+ ### Deep node selected
86
+
87
+ ```html
88
+ <fk-node-tree-breadcrumb [nodes]="nodes" selectedNodeId="office-1" />
89
+ ```
90
+
91
+ Renders: Acme Realty > West Region > **Downtown Office**
92
+
93
+ ---
94
+
95
+ ## Accessibility
96
+
97
+ `fk-node-tree-breadcrumb` renders a `<nav>` element with proper ARIA attributes.
98
+
99
+ Accessibility behavior:
100
+
101
+ - Host has `role="navigation"` and `aria-label="Breadcrumb"`
102
+ - Rendered as an ordered list (`<ol>`) for semantic structure
103
+ - Ancestor crumbs are `<button>` elements for keyboard interaction
104
+ - Current (last) crumb has `aria-current="location"`
105
+ - Chevron separators are marked `aria-hidden="true"`
106
+
107
+ ---
108
+
109
+ ## Design Tokens
110
+
111
+ `fk-node-tree-breadcrumb` is styled entirely through design tokens.
112
+
113
+ ### Component-specific tokens
114
+
115
+ ```
116
+ --fk-node-tree-breadcrumb-gap
117
+ --fk-node-tree-breadcrumb-font-size
118
+ --fk-node-tree-breadcrumb-link-color
119
+ --fk-node-tree-breadcrumb-link-color-hover
120
+ --fk-node-tree-breadcrumb-current-color
121
+ --fk-node-tree-breadcrumb-current-font-weight
122
+ --fk-node-tree-breadcrumb-separator-color
123
+ ```
124
+
125
+ ### Shared tokens
126
+
127
+ ```
128
+ --fk-rhythm-1
129
+ --fk-typography-caption-font-size
130
+ --fk-font-weight-medium
131
+ --fk-color-muted
132
+ --fk-color-text
133
+ --fk-focus-ring
134
+ --fk-radius-sm
135
+ ```
136
+
137
+ ### Customizing Tokens
138
+
139
+ Override tokens in your application's stylesheet:
140
+
141
+ ```scss
142
+ :root {
143
+ --fk-node-tree-breadcrumb-font-size: 0.875rem;
144
+ --fk-node-tree-breadcrumb-link-color: #475569;
145
+ --fk-node-tree-breadcrumb-current-font-weight: 600;
146
+ }
147
+ ```
148
+
149
+ Or scope overrides to a specific context:
150
+
151
+ ```scss
152
+ .dark-theme fk-node-tree-breadcrumb {
153
+ --fk-node-tree-breadcrumb-link-color: #94a3b8;
154
+ --fk-node-tree-breadcrumb-current-color: #e2e8f0;
155
+ }
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Behavior Notes
161
+
162
+ - Returns an empty list when `selectedNodeId` is `undefined` or does not match any node
163
+ - The `NodeTreeBreadcrumbItem` type includes `id`, `label`, and optional `icon` fields (icon is not rendered by the breadcrumb but is available for consumers)
164
+ - `text-transform` is not applied by the component; consumers can apply it externally via CSS
@@ -0,0 +1,146 @@
1
+ # fk-note
2
+
3
+ A lightweight, token-driven inline callout that draws attention to a line of prose with a colored left rail — no box chrome, no background, no border radius.
4
+
5
+ ---
6
+
7
+ ## API
8
+
9
+ ### Inputs
10
+
11
+ | Input | Type | Default | Description |
12
+ | ----------- | ---------------- | -------- | --------------------------------------------------------------------- |
13
+ | `variant` | `NoteVariant` | `"info"` | Accent tone: `"info"`, `"success"`, `"warning"`, or `"danger"` |
14
+ | `italic` | `boolean` | `false` | Render the note's text in italic style |
15
+ | `className` | `string` | `''` | Additional CSS classes merged onto the host element |
16
+ | `id` | `string \| null` | `null` | Optional ID applied to the host element |
17
+ | `ariaLabel` | `string \| null` | `null` | Accessible label when the note's visual content alone is insufficient |
18
+
19
+ ### Outputs
20
+
21
+ None.
22
+
23
+ ### Content
24
+
25
+ `fk-note` projects its content:
26
+
27
+ ```html
28
+ <fk-note>Permissions inherit through the hierarchy.</fk-note>
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Features
34
+
35
+ - Left-rail accent in info / success / warning / danger tones
36
+ - No box chrome — sits inline with surrounding prose
37
+ - Fully token-driven accent colors, border width, and padding
38
+ - Works with any inline or block content (text, links, code)
39
+ - Renders correctly without any theme file via two-tier fallbacks
40
+
41
+ ---
42
+
43
+ ## Quick Start
44
+
45
+ ```html
46
+ <fk-note>Your first request is ready to send.</fk-note>
47
+ ```
48
+
49
+ ```html
50
+ <fk-note variant="warning"> API keys are shown only once. Copy yours before leaving this screen. </fk-note>
51
+ ```
52
+
53
+ ---
54
+
55
+ ## Import
56
+
57
+ ```ts
58
+ import { NoteComponent } from '@frame-kit/ui-ng';
59
+ ```
60
+
61
+ ```ts
62
+ @Component({
63
+ selector: 'app-example',
64
+ imports: [NoteComponent],
65
+ templateUrl: './example.component.html',
66
+ })
67
+ export class ExampleComponent {}
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Selector
73
+
74
+ ```html
75
+ <fk-note></fk-note>
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Examples
81
+
82
+ ### Tone variants
83
+
84
+ ```html
85
+ <fk-note variant="info">Neutral attention marker.</fk-note>
86
+ <fk-note variant="success">Positive confirmation.</fk-note>
87
+ <fk-note variant="warning">Caveat or caution.</fk-note>
88
+ <fk-note variant="danger">Destructive or irreversible action.</fk-note>
89
+ ```
90
+
91
+ ### With rich inline content
92
+
93
+ ```html
94
+ <fk-note variant="info"> Use the <code>X-API-Key</code> header for server-to-server requests. <a href="/docs/api-reference">Learn more</a>. </fk-note>
95
+ ```
96
+
97
+ ### Custom accessible label
98
+
99
+ ```html
100
+ <fk-note variant="warning" ariaLabel="Deprecation notice"> This endpoint will be removed in v2. </fk-note>
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Accessibility
106
+
107
+ - Renders as a plain block container; content inside is read in source order
108
+ - Use `ariaLabel` when the note conveys meaning beyond its visible text (e.g. "Deprecation notice", "Security warning")
109
+ - For a note that announces dynamic updates, wrap it in a parent `role="status"` or `role="alert"` element — `fk-note` itself stays presentation-only
110
+ - Color alone is never the sole signal; pair the variant with clear wording so screen-reader users get the same cue
111
+
112
+ ---
113
+
114
+ ## Design Tokens
115
+
116
+ ```scss
117
+ --fk-note-border-width;
118
+ --fk-note-padding-block;
119
+ --fk-note-padding-inline-start;
120
+ --fk-note-color;
121
+ --fk-note-font-size;
122
+ --fk-note-line-height;
123
+
124
+ --fk-note-info-accent;
125
+ --fk-note-success-accent;
126
+ --fk-note-warning-accent;
127
+ --fk-note-danger-accent;
128
+ ```
129
+
130
+ Override in your app stylesheet:
131
+
132
+ ```scss
133
+ :root {
134
+ --fk-note-border-width: 4px;
135
+ --fk-note-padding-inline-start: 1.25rem;
136
+ --fk-note-info-accent: var(--fk-color-primary-hover);
137
+ }
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Behavior Notes
143
+
144
+ - The left rail uses `border-inline-start` so it automatically flips for RTL languages
145
+ - Vertical rhythm above and below is the caller's responsibility — `fk-note` does not carry its own margin. Use utility classes (`.fk-mt-4`, etc.) or parent `gap` for spacing
146
+ - Accent tokens resolve to `--fk-color-primary / success / warning / danger` by default, so dark mode is picked up from the semantic color layer without per-note overrides