@nordmanai/nif 0.2.1 → 0.2.3

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 (365) hide show
  1. package/README.md +1 -1
  2. package/dist/index.d.ts +7 -0
  3. package/dist/index.js +31332 -11730
  4. package/dist/styles.css +1 -1
  5. package/dist/ui/components/nm-ai/nm-ai.d.ts +4 -0
  6. package/dist/ui/components/nm-alert/nm-alert.d.ts +13 -0
  7. package/dist/ui/components/nm-button/nm-button.d.ts +7 -3
  8. package/dist/ui/components/nm-checkbox/nm-checkbox.d.ts +1 -1
  9. package/dist/ui/components/nm-chip/nm-chip.d.ts +5 -2
  10. package/dist/ui/components/nm-collapsible/nm-collapsible.d.ts +6 -0
  11. package/dist/ui/components/nm-combobox/nm-combobox.d.ts +1 -1
  12. package/dist/ui/components/nm-command/nm-command.d.ts +8 -1
  13. package/dist/ui/components/nm-composer/nm-composer.d.ts +47 -4
  14. package/dist/ui/components/nm-context-menu/nm-context-menu.d.ts +1 -1
  15. package/dist/ui/components/nm-dialog/nm-dialog.d.ts +1 -1
  16. package/dist/ui/components/nm-dropdown/nm-dropdown.d.ts +1 -1
  17. package/dist/ui/components/nm-dropdown-menu/nm-dropdown-menu.d.ts +11 -2
  18. package/dist/ui/components/nm-hover-card/nm-hover-card.d.ts +1 -1
  19. package/dist/ui/components/nm-icon/animated/activity.d.ts +72 -0
  20. package/dist/ui/components/nm-icon/animated/archive.d.ts +31 -0
  21. package/dist/ui/components/nm-icon/animated/arrow-down.d.ts +128 -0
  22. package/dist/ui/components/nm-icon/animated/arrow-left.d.ts +128 -0
  23. package/dist/ui/components/nm-icon/animated/arrow-right.d.ts +128 -0
  24. package/dist/ui/components/nm-icon/animated/arrow-up-down.d.ts +119 -0
  25. package/dist/ui/components/nm-icon/animated/arrow-up.d.ts +128 -0
  26. package/dist/ui/components/nm-icon/animated/audio-lines.d.ts +99 -0
  27. package/dist/ui/components/nm-icon/animated/bookmark-plus.d.ts +35 -0
  28. package/dist/ui/components/nm-icon/animated/bookmark.d.ts +52 -0
  29. package/dist/ui/components/nm-icon/animated/bot.d.ts +90 -0
  30. package/dist/ui/components/nm-icon/animated/calendar-days.d.ts +87 -0
  31. package/dist/ui/components/nm-icon/animated/calendar.d.ts +36 -0
  32. package/dist/ui/components/nm-icon/animated/camera.d.ts +50 -0
  33. package/dist/ui/components/nm-icon/animated/chart-column-increasing.d.ts +37 -0
  34. package/dist/ui/components/nm-icon/animated/chart-column.d.ts +86 -0
  35. package/dist/ui/components/nm-icon/animated/chart-line.d.ts +51 -0
  36. package/dist/ui/components/nm-icon/animated/check-check.d.ts +50 -0
  37. package/dist/ui/components/nm-icon/animated/check.d.ts +25 -0
  38. package/dist/ui/components/nm-icon/animated/chevron-down.d.ts +39 -0
  39. package/dist/ui/components/nm-icon/animated/chevron-left.d.ts +39 -0
  40. package/dist/ui/components/nm-icon/animated/chevron-right.d.ts +39 -0
  41. package/dist/ui/components/nm-icon/animated/chevron-up.d.ts +39 -0
  42. package/dist/ui/components/nm-icon/animated/circle-alert.d.ts +23 -0
  43. package/dist/ui/components/nm-icon/animated/circle-check-big.d.ts +26 -0
  44. package/dist/ui/components/nm-icon/animated/circle-check.d.ts +26 -0
  45. package/dist/ui/components/nm-icon/animated/circle-plus.d.ts +44 -0
  46. package/dist/ui/components/nm-icon/animated/circle-question-mark.d.ts +22 -0
  47. package/dist/ui/components/nm-icon/animated/circle-x.d.ts +44 -0
  48. package/dist/ui/components/nm-icon/animated/clock-3.d.ts +44 -0
  49. package/dist/ui/components/nm-icon/animated/clock-4.d.ts +44 -0
  50. package/dist/ui/components/nm-icon/animated/clock.d.ts +44 -0
  51. package/dist/ui/components/nm-icon/animated/cloud-sun.d.ts +9 -0
  52. package/dist/ui/components/nm-icon/animated/cloud-upload.d.ts +45 -0
  53. package/dist/ui/components/nm-icon/animated/copy.d.ts +135 -0
  54. package/dist/ui/components/nm-icon/animated/download.d.ts +45 -0
  55. package/dist/ui/components/nm-icon/animated/ellipsis.d.ts +141 -0
  56. package/dist/ui/components/nm-icon/animated/external-link.d.ts +49 -0
  57. package/dist/ui/components/nm-icon/animated/eye-off.d.ts +23 -0
  58. package/dist/ui/components/nm-icon/animated/eye.d.ts +39 -0
  59. package/dist/ui/components/nm-icon/animated/fast-forward.d.ts +34 -0
  60. package/dist/ui/components/nm-icon/animated/file-clock.d.ts +48 -0
  61. package/dist/ui/components/nm-icon/animated/file-text.d.ts +56 -0
  62. package/dist/ui/components/nm-icon/animated/file.d.ts +67 -0
  63. package/dist/ui/components/nm-icon/animated/folder.d.ts +92 -0
  64. package/dist/ui/components/nm-icon/animated/gauge.d.ts +47 -0
  65. package/dist/ui/components/nm-icon/animated/globe.d.ts +21 -0
  66. package/dist/ui/components/nm-icon/animated/graduation-cap.d.ts +41 -0
  67. package/dist/ui/components/nm-icon/animated/headphones.d.ts +50 -0
  68. package/dist/ui/components/nm-icon/animated/image.d.ts +40 -0
  69. package/dist/ui/components/nm-icon/animated/index.d.ts +2 -0
  70. package/dist/ui/components/nm-icon/animated/info.d.ts +37 -0
  71. package/dist/ui/components/nm-icon/animated/key-round.d.ts +37 -0
  72. package/dist/ui/components/nm-icon/animated/layers.d.ts +61 -0
  73. package/dist/ui/components/nm-icon/animated/layout-dashboard.d.ts +131 -0
  74. package/dist/ui/components/nm-icon/animated/library-big.d.ts +29 -0
  75. package/dist/ui/components/nm-icon/animated/lightbulb.d.ts +51 -0
  76. package/dist/ui/components/nm-icon/animated/link.d.ts +193 -0
  77. package/dist/ui/components/nm-icon/animated/list-filter.d.ts +13 -0
  78. package/dist/ui/components/nm-icon/animated/list.d.ts +111 -0
  79. package/dist/ui/components/nm-icon/animated/loader-circle.d.ts +24 -0
  80. package/dist/ui/components/nm-icon/animated/lock.d.ts +94 -0
  81. package/dist/ui/components/nm-icon/animated/log-out.d.ts +45 -0
  82. package/dist/ui/components/nm-icon/animated/mail.d.ts +100 -0
  83. package/dist/ui/components/nm-icon/animated/map-pin.d.ts +67 -0
  84. package/dist/ui/components/nm-icon/animated/menu.d.ts +57 -0
  85. package/dist/ui/components/nm-icon/animated/message-circle-dashed.d.ts +34 -0
  86. package/dist/ui/components/nm-icon/animated/message-circle.d.ts +23 -0
  87. package/dist/ui/components/nm-icon/animated/message-square-plus.d.ts +49 -0
  88. package/dist/ui/components/nm-icon/animated/message-square-text.d.ts +104 -0
  89. package/dist/ui/components/nm-icon/animated/message-square.d.ts +23 -0
  90. package/dist/ui/components/nm-icon/animated/mic-off.d.ts +23 -0
  91. package/dist/ui/components/nm-icon/animated/mic.d.ts +37 -0
  92. package/dist/ui/components/nm-icon/animated/minimize.d.ts +139 -0
  93. package/dist/ui/components/nm-icon/animated/minus.d.ts +54 -0
  94. package/dist/ui/components/nm-icon/animated/moon.d.ts +62 -0
  95. package/dist/ui/components/nm-icon/animated/music.d.ts +22 -0
  96. package/dist/ui/components/nm-icon/animated/notebook-pen.d.ts +41 -0
  97. package/dist/ui/components/nm-icon/animated/panel-left.d.ts +29 -0
  98. package/dist/ui/components/nm-icon/animated/panel-right.d.ts +29 -0
  99. package/dist/ui/components/nm-icon/animated/paperclip.d.ts +49 -0
  100. package/dist/ui/components/nm-icon/animated/pause.d.ts +59 -0
  101. package/dist/ui/components/nm-icon/animated/pencil.d.ts +25 -0
  102. package/dist/ui/components/nm-icon/animated/pin-off.d.ts +44 -0
  103. package/dist/ui/components/nm-icon/animated/pin.d.ts +85 -0
  104. package/dist/ui/components/nm-icon/animated/plane-takeoff.d.ts +25 -0
  105. package/dist/ui/components/nm-icon/animated/play.d.ts +43 -0
  106. package/dist/ui/components/nm-icon/animated/plug-zap.d.ts +49 -0
  107. package/dist/ui/components/nm-icon/animated/plus.d.ts +95 -0
  108. package/dist/ui/components/nm-icon/animated/radio.d.ts +24 -0
  109. package/dist/ui/components/nm-icon/animated/refresh-cw.d.ts +55 -0
  110. package/dist/ui/components/nm-icon/animated/rocket.d.ts +48 -0
  111. package/dist/ui/components/nm-icon/animated/rotate-ccw.d.ts +51 -0
  112. package/dist/ui/components/nm-icon/animated/rotate-cw.d.ts +71 -0
  113. package/dist/ui/components/nm-icon/animated/save.d.ts +21 -0
  114. package/dist/ui/components/nm-icon/animated/search.d.ts +42 -0
  115. package/dist/ui/components/nm-icon/animated/send.d.ts +39 -0
  116. package/dist/ui/components/nm-icon/animated/settings.d.ts +39 -0
  117. package/dist/ui/components/nm-icon/animated/share-2.d.ts +122 -0
  118. package/dist/ui/components/nm-icon/animated/share.d.ts +40 -0
  119. package/dist/ui/components/nm-icon/animated/shield-check.d.ts +36 -0
  120. package/dist/ui/components/nm-icon/animated/shopping-bag.d.ts +35 -0
  121. package/dist/ui/components/nm-icon/animated/sliders-horizontal.d.ts +239 -0
  122. package/dist/ui/components/nm-icon/animated/sparkles.d.ts +205 -0
  123. package/dist/ui/components/nm-icon/animated/star.d.ts +48 -0
  124. package/dist/ui/components/nm-icon/animated/sun.d.ts +9 -0
  125. package/dist/ui/components/nm-icon/animated/terminal.d.ts +22 -0
  126. package/dist/ui/components/nm-icon/animated/trash-2.d.ts +61 -0
  127. package/dist/ui/components/nm-icon/animated/trash.d.ts +37 -0
  128. package/dist/ui/components/nm-icon/animated/trending-up.d.ts +40 -0
  129. package/dist/ui/components/nm-icon/animated/triangle-alert.d.ts +37 -0
  130. package/dist/ui/components/nm-icon/animated/trophy.d.ts +23 -0
  131. package/dist/ui/components/nm-icon/animated/type.d.ts +57 -0
  132. package/dist/ui/components/nm-icon/animated/upload.d.ts +49 -0
  133. package/dist/ui/components/nm-icon/animated/user-round.d.ts +33 -0
  134. package/dist/ui/components/nm-icon/animated/user.d.ts +33 -0
  135. package/dist/ui/components/nm-icon/animated/users-round.d.ts +93 -0
  136. package/dist/ui/components/nm-icon/animated/users.d.ts +93 -0
  137. package/dist/ui/components/nm-icon/animated/volume-2.d.ts +10 -0
  138. package/dist/ui/components/nm-icon/animated/wand-sparkles.d.ts +71 -0
  139. package/dist/ui/components/nm-icon/animated/x.d.ts +95 -0
  140. package/dist/ui/components/nm-icon/animated/zap.d.ts +65 -0
  141. package/dist/ui/components/nm-icon/animated/zoom-in.d.ts +35 -0
  142. package/dist/ui/components/nm-icon/animated/zoom-out.d.ts +53 -0
  143. package/dist/ui/components/nm-icon/nm-icon.d.ts +6 -3
  144. package/dist/ui/components/nm-icon/nm-lucide-extended.d.ts +3 -0
  145. package/dist/ui/components/nm-icon/nm-lucide.d.ts +7 -3
  146. package/dist/ui/components/nm-kbd/nm-kbd.d.ts +5 -0
  147. package/dist/ui/components/nm-menubar/nm-menubar.d.ts +2 -2
  148. package/dist/ui/components/nm-panel/nm-panel.d.ts +5 -1
  149. package/dist/ui/components/nm-popover/nm-popover.d.ts +2 -2
  150. package/dist/ui/components/nm-progress/nm-progress.d.ts +1 -1
  151. package/dist/ui/components/nm-radio-group/nm-radio-group.d.ts +2 -2
  152. package/dist/ui/components/nm-select/nm-select.d.ts +1 -1
  153. package/dist/ui/components/nm-skeleton/nm-skeleton.d.ts +3 -0
  154. package/dist/ui/components/nm-slider/nm-slider.d.ts +1 -1
  155. package/dist/ui/components/nm-small-icon-button/nm-small-icon-button.d.ts +3 -3
  156. package/dist/ui/components/nm-spinner/nm-spinner.d.ts +3 -0
  157. package/dist/ui/components/nm-switch/nm-switch.d.ts +1 -1
  158. package/dist/ui/components/nm-tabs/nm-tabs.d.ts +6 -0
  159. package/dist/ui/components/nm-toggle/nm-toggle.d.ts +1 -1
  160. package/dist/ui/components/nm-toolbar/nm-toolbar.d.ts +6 -2
  161. package/dist/ui/components/nm-tooltip/nm-tooltip.d.ts +1 -1
  162. package/dist/ui/components/nm-voice-orb/nm-voice-orb.d.ts +18 -0
  163. package/dist/ui/components/nm-voice-orb/use-nm-voice-orb-theme.d.ts +2 -0
  164. package/dist/ui/config/nm-app-panel.d.ts +2 -0
  165. package/dist/ui/config/nm-button.d.ts +6 -0
  166. package/dist/ui/config/nm-composer.d.ts +11 -0
  167. package/dist/ui/config/nm-icon-button.d.ts +0 -2
  168. package/dist/ui/config/nm-icons-extended.d.ts +1 -0
  169. package/dist/ui/config/nm-icons.d.ts +4 -1
  170. package/dist/ui/config/nm-voice-orb.d.ts +22 -0
  171. package/dist/ui/lib/nm-motion.d.ts +29 -0
  172. package/package.json +12 -8
  173. package/registry/index.json +5113 -72
  174. package/registry/ui/components/nm-ai/nm-ai.tsx +7 -4
  175. package/registry/ui/components/nm-alert/nm-alert.css +85 -0
  176. package/registry/ui/components/nm-alert/nm-alert.tsx +35 -0
  177. package/registry/ui/components/nm-button/nm-button.css +24 -0
  178. package/registry/ui/components/nm-button/nm-button.tsx +41 -20
  179. package/registry/ui/components/nm-checkbox/nm-checkbox.tsx +1 -1
  180. package/registry/ui/components/nm-chip/nm-chip.css +25 -0
  181. package/registry/ui/components/nm-chip/nm-chip.tsx +9 -3
  182. package/registry/ui/components/nm-collapsible/nm-collapsible.css +3 -0
  183. package/registry/ui/components/nm-collapsible/nm-collapsible.tsx +16 -0
  184. package/registry/ui/components/nm-combobox/nm-combobox.tsx +1 -1
  185. package/registry/ui/components/nm-command/nm-command.css +48 -0
  186. package/registry/ui/components/nm-command/nm-command.tsx +19 -5
  187. package/registry/ui/components/nm-composer/nm-composer.css +87 -3
  188. package/registry/ui/components/nm-composer/nm-composer.tsx +321 -33
  189. package/registry/ui/components/nm-context-menu/nm-context-menu.tsx +1 -1
  190. package/registry/ui/components/nm-dialog/nm-dialog.css +5 -6
  191. package/registry/ui/components/nm-dialog/nm-dialog.tsx +1 -1
  192. package/registry/ui/components/nm-dropdown/nm-dropdown.css +5 -0
  193. package/registry/ui/components/nm-dropdown/nm-dropdown.tsx +29 -250
  194. package/registry/ui/components/nm-dropdown-menu/nm-dropdown-menu.css +8 -0
  195. package/registry/ui/components/nm-dropdown-menu/nm-dropdown-menu.tsx +85 -6
  196. package/registry/ui/components/nm-hover-card/nm-hover-card.tsx +1 -1
  197. package/registry/ui/components/nm-icon/animated/activity.tsx +109 -0
  198. package/registry/ui/components/nm-icon/animated/archive.tsx +85 -0
  199. package/registry/ui/components/nm-icon/animated/arrow-down.tsx +149 -0
  200. package/registry/ui/components/nm-icon/animated/arrow-left.tsx +149 -0
  201. package/registry/ui/components/nm-icon/animated/arrow-right.tsx +149 -0
  202. package/registry/ui/components/nm-icon/animated/arrow-up-down.tsx +168 -0
  203. package/registry/ui/components/nm-icon/animated/arrow-up.tsx +149 -0
  204. package/registry/ui/components/nm-icon/animated/audio-lines.tsx +190 -0
  205. package/registry/ui/components/nm-icon/animated/bookmark-plus.tsx +65 -0
  206. package/registry/ui/components/nm-icon/animated/bookmark.tsx +77 -0
  207. package/registry/ui/components/nm-icon/animated/bot.tsx +167 -0
  208. package/registry/ui/components/nm-icon/animated/calendar-days.tsx +128 -0
  209. package/registry/ui/components/nm-icon/animated/calendar.tsx +83 -0
  210. package/registry/ui/components/nm-icon/animated/camera.tsx +85 -0
  211. package/registry/ui/components/nm-icon/animated/chart-column-increasing.tsx +150 -0
  212. package/registry/ui/components/nm-icon/animated/chart-column.tsx +179 -0
  213. package/registry/ui/components/nm-icon/animated/chart-line.tsx +88 -0
  214. package/registry/ui/components/nm-icon/animated/check-check.tsx +105 -0
  215. package/registry/ui/components/nm-icon/animated/check.tsx +70 -0
  216. package/registry/ui/components/nm-icon/animated/chevron-down.tsx +73 -0
  217. package/registry/ui/components/nm-icon/animated/chevron-left.tsx +73 -0
  218. package/registry/ui/components/nm-icon/animated/chevron-right.tsx +73 -0
  219. package/registry/ui/components/nm-icon/animated/chevron-up.tsx +73 -0
  220. package/registry/ui/components/nm-icon/animated/circle-alert.tsx +84 -0
  221. package/registry/ui/components/nm-icon/animated/circle-check-big.tsx +75 -0
  222. package/registry/ui/components/nm-icon/animated/circle-check.tsx +77 -0
  223. package/registry/ui/components/nm-icon/animated/circle-plus.tsx +93 -0
  224. package/registry/ui/components/nm-icon/animated/circle-question-mark.tsx +62 -0
  225. package/registry/ui/components/nm-icon/animated/circle-x.tsx +93 -0
  226. package/registry/ui/components/nm-icon/animated/clock-3.tsx +95 -0
  227. package/registry/ui/components/nm-icon/animated/clock-4.tsx +95 -0
  228. package/registry/ui/components/nm-icon/animated/clock.tsx +95 -0
  229. package/registry/ui/components/nm-icon/animated/cloud-sun.tsx +130 -0
  230. package/registry/ui/components/nm-icon/animated/cloud-upload.tsx +93 -0
  231. package/registry/ui/components/nm-icon/animated/copy.tsx +153 -0
  232. package/registry/ui/components/nm-icon/animated/download.tsx +93 -0
  233. package/registry/ui/components/nm-icon/animated/ellipsis.tsx +189 -0
  234. package/registry/ui/components/nm-icon/animated/external-link.tsx +97 -0
  235. package/registry/ui/components/nm-icon/animated/eye-off.tsx +63 -0
  236. package/registry/ui/components/nm-icon/animated/eye.tsx +82 -0
  237. package/registry/ui/components/nm-icon/animated/fast-forward.tsx +72 -0
  238. package/registry/ui/components/nm-icon/animated/file-clock.tsx +105 -0
  239. package/registry/ui/components/nm-icon/animated/file-text.tsx +102 -0
  240. package/registry/ui/components/nm-icon/animated/file.tsx +124 -0
  241. package/registry/ui/components/nm-icon/animated/folder.tsx +132 -0
  242. package/registry/ui/components/nm-icon/animated/gauge.tsx +84 -0
  243. package/registry/ui/components/nm-icon/animated/globe.tsx +61 -0
  244. package/registry/ui/components/nm-icon/animated/graduation-cap.tsx +92 -0
  245. package/registry/ui/components/nm-icon/animated/headphones.tsx +85 -0
  246. package/registry/ui/components/nm-icon/animated/image.tsx +88 -0
  247. package/registry/ui/components/nm-icon/animated/index.ts +251 -0
  248. package/registry/ui/components/nm-icon/animated/info.tsx +75 -0
  249. package/registry/ui/components/nm-icon/animated/key-round.tsx +67 -0
  250. package/registry/ui/components/nm-icon/animated/layers.tsx +116 -0
  251. package/registry/ui/components/nm-icon/animated/layout-dashboard.tsx +176 -0
  252. package/registry/ui/components/nm-icon/animated/library-big.tsx +89 -0
  253. package/registry/ui/components/nm-icon/animated/lightbulb.tsx +106 -0
  254. package/registry/ui/components/nm-icon/animated/link.tsx +210 -0
  255. package/registry/ui/components/nm-icon/animated/list-filter.tsx +78 -0
  256. package/registry/ui/components/nm-icon/animated/list.tsx +184 -0
  257. package/registry/ui/components/nm-icon/animated/loader-circle.tsx +68 -0
  258. package/registry/ui/components/nm-icon/animated/lock.tsx +152 -0
  259. package/registry/ui/components/nm-icon/animated/log-out.tsx +93 -0
  260. package/registry/ui/components/nm-icon/animated/mail.tsx +131 -0
  261. package/registry/ui/components/nm-icon/animated/map-pin.tsx +111 -0
  262. package/registry/ui/components/nm-icon/animated/menu.tsx +121 -0
  263. package/registry/ui/components/nm-icon/animated/message-circle-dashed.tsx +140 -0
  264. package/registry/ui/components/nm-icon/animated/message-circle.tsx +66 -0
  265. package/registry/ui/components/nm-icon/animated/message-square-plus.tsx +106 -0
  266. package/registry/ui/components/nm-icon/animated/message-square-text.tsx +153 -0
  267. package/registry/ui/components/nm-icon/animated/message-square.tsx +66 -0
  268. package/registry/ui/components/nm-icon/animated/mic-off.tsx +65 -0
  269. package/registry/ui/components/nm-icon/animated/mic.tsx +77 -0
  270. package/registry/ui/components/nm-icon/animated/minimize.tsx +164 -0
  271. package/registry/ui/components/nm-icon/animated/minus.tsx +84 -0
  272. package/registry/ui/components/nm-icon/animated/moon.tsx +98 -0
  273. package/registry/ui/components/nm-icon/animated/music.tsx +62 -0
  274. package/registry/ui/components/nm-icon/animated/notebook-pen.tsx +114 -0
  275. package/registry/ui/components/nm-icon/animated/panel-left.tsx +77 -0
  276. package/registry/ui/components/nm-icon/animated/panel-right.tsx +77 -0
  277. package/registry/ui/components/nm-icon/animated/paperclip.tsx +83 -0
  278. package/registry/ui/components/nm-icon/animated/pause.tsx +116 -0
  279. package/registry/ui/components/nm-icon/animated/pencil.tsx +70 -0
  280. package/registry/ui/components/nm-icon/animated/pin-off.tsx +102 -0
  281. package/registry/ui/components/nm-icon/animated/pin.tsx +124 -0
  282. package/registry/ui/components/nm-icon/animated/plane-takeoff.tsx +62 -0
  283. package/registry/ui/components/nm-icon/animated/play.tsx +74 -0
  284. package/registry/ui/components/nm-icon/animated/plug-zap.tsx +117 -0
  285. package/registry/ui/components/nm-icon/animated/plus.tsx +122 -0
  286. package/registry/ui/components/nm-icon/animated/radio.tsx +137 -0
  287. package/registry/ui/components/nm-icon/animated/refresh-cw.tsx +103 -0
  288. package/registry/ui/components/nm-icon/animated/rocket.tsx +93 -0
  289. package/registry/ui/components/nm-icon/animated/rotate-ccw.tsx +87 -0
  290. package/registry/ui/components/nm-icon/animated/rotate-cw.tsx +98 -0
  291. package/registry/ui/components/nm-icon/animated/save.tsx +58 -0
  292. package/registry/ui/components/nm-icon/animated/search.tsx +90 -0
  293. package/registry/ui/components/nm-icon/animated/send.tsx +87 -0
  294. package/registry/ui/components/nm-icon/animated/settings.tsx +92 -0
  295. package/registry/ui/components/nm-icon/animated/share-2.tsx +148 -0
  296. package/registry/ui/components/nm-icon/animated/share.tsx +76 -0
  297. package/registry/ui/components/nm-icon/animated/shield-check.tsx +70 -0
  298. package/registry/ui/components/nm-icon/animated/shopping-bag.tsx +71 -0
  299. package/registry/ui/components/nm-icon/animated/sliders-horizontal.tsx +243 -0
  300. package/registry/ui/components/nm-icon/animated/sparkles.tsx +227 -0
  301. package/registry/ui/components/nm-icon/animated/star.tsx +86 -0
  302. package/registry/ui/components/nm-icon/animated/sun.tsx +148 -0
  303. package/registry/ui/components/nm-icon/animated/terminal.tsx +71 -0
  304. package/registry/ui/components/nm-icon/animated/trash-2.tsx +136 -0
  305. package/registry/ui/components/nm-icon/animated/trash.tsx +94 -0
  306. package/registry/ui/components/nm-icon/animated/trending-up.tsx +75 -0
  307. package/registry/ui/components/nm-icon/animated/triangle-alert.tsx +75 -0
  308. package/registry/ui/components/nm-icon/animated/trophy.tsx +62 -0
  309. package/registry/ui/components/nm-icon/animated/type.tsx +106 -0
  310. package/registry/ui/components/nm-icon/animated/upload.tsx +94 -0
  311. package/registry/ui/components/nm-icon/animated/user-round.tsx +84 -0
  312. package/registry/ui/components/nm-icon/animated/user.tsx +84 -0
  313. package/registry/ui/components/nm-icon/animated/users-round.tsx +156 -0
  314. package/registry/ui/components/nm-icon/animated/users.tsx +156 -0
  315. package/registry/ui/components/nm-icon/animated/volume-2.tsx +119 -0
  316. package/registry/ui/components/nm-icon/animated/wand-sparkles.tsx +111 -0
  317. package/registry/ui/components/nm-icon/animated/x.tsx +122 -0
  318. package/registry/ui/components/nm-icon/animated/zap.tsx +86 -0
  319. package/registry/ui/components/nm-icon/animated/zoom-in.tsx +66 -0
  320. package/registry/ui/components/nm-icon/animated/zoom-out.tsx +85 -0
  321. package/registry/ui/components/nm-icon/nm-icon.css +0 -1
  322. package/registry/ui/components/nm-icon/nm-icon.tsx +20 -5
  323. package/registry/ui/components/nm-icon/nm-lucide-extended.tsx +284 -0
  324. package/registry/ui/components/nm-icon/nm-lucide.tsx +55 -5
  325. package/registry/ui/components/nm-icon-border/nm-icon-border.tsx +1 -1
  326. package/registry/ui/components/nm-input/nm-input.css +1 -0
  327. package/registry/ui/components/nm-kbd/nm-kbd.css +23 -0
  328. package/registry/ui/components/nm-kbd/nm-kbd.tsx +12 -0
  329. package/registry/ui/components/nm-menubar/nm-menubar.tsx +2 -2
  330. package/registry/ui/components/nm-panel/nm-panel.css +7 -0
  331. package/registry/ui/components/nm-panel/nm-panel.tsx +19 -2
  332. package/registry/ui/components/nm-popover/nm-popover.tsx +4 -3
  333. package/registry/ui/components/nm-progress/nm-progress.tsx +1 -1
  334. package/registry/ui/components/nm-radio-group/nm-radio-group.tsx +2 -2
  335. package/registry/ui/components/nm-segmented/nm-segmented.tsx +1 -1
  336. package/registry/ui/components/nm-select/nm-select.tsx +1 -1
  337. package/registry/ui/components/nm-skeleton/nm-skeleton.css +17 -0
  338. package/registry/ui/components/nm-skeleton/nm-skeleton.tsx +7 -0
  339. package/registry/ui/components/nm-slider/nm-slider.tsx +1 -1
  340. package/registry/ui/components/nm-small-icon-button/nm-small-icon-button.tsx +3 -3
  341. package/registry/ui/components/nm-spinner/nm-spinner.css +22 -0
  342. package/registry/ui/components/nm-spinner/nm-spinner.tsx +7 -0
  343. package/registry/ui/components/nm-switch/nm-switch.css +20 -3
  344. package/registry/ui/components/nm-switch/nm-switch.tsx +1 -1
  345. package/registry/ui/components/nm-tabs/nm-tabs.css +4 -0
  346. package/registry/ui/components/nm-tabs/nm-tabs.tsx +19 -0
  347. package/registry/ui/components/nm-textarea/nm-textarea.css +1 -0
  348. package/registry/ui/components/nm-toggle/nm-toggle.tsx +1 -1
  349. package/registry/ui/components/nm-toolbar/nm-toolbar.css +0 -6
  350. package/registry/ui/components/nm-toolbar/nm-toolbar.tsx +16 -7
  351. package/registry/ui/components/nm-tooltip/nm-tooltip.css +17 -0
  352. package/registry/ui/components/nm-tooltip/nm-tooltip.tsx +1 -1
  353. package/registry/ui/components/nm-voice-orb/nm-voice-orb.css +17 -0
  354. package/registry/ui/components/nm-voice-orb/nm-voice-orb.tsx +112 -0
  355. package/registry/ui/components/nm-voice-orb/use-nm-voice-orb-theme.ts +34 -0
  356. package/registry/ui/components/nordman-icon-button/nordman-icon-button.css +6 -9
  357. package/registry/ui/components/nordman-icon-button/nordman-icon-button.tsx +7 -3
  358. package/registry/ui/config/nm-button.ts +6 -0
  359. package/registry/ui/config/nm-composer.ts +12 -0
  360. package/registry/ui/config/nm-icon-button.ts +0 -2
  361. package/registry/ui/config/nm-icons-extended.ts +141 -0
  362. package/registry/ui/config/nm-icons.ts +6 -2
  363. package/registry/ui/config/nm-voice-orb.ts +50 -0
  364. package/registry/ui/lib/nm-motion.ts +30 -0
  365. package/registry/ui/styles/tokens.css +7 -0
@@ -124,10 +124,11 @@ export function NmMessage(props: {
124
124
 
125
125
  /* ----- Reasoning ----- */
126
126
 
127
- export function NmReasoning(props: { text: string; streaming?: boolean; seconds?: number; defaultOpen?: boolean }): ReactNode {
128
- const label = props.streaming ? 'Thinking' : `Thought for ${props.seconds ?? 0} seconds`;
127
+ /** `label` is the heading in the product's language; without it the heading says Thinking, or how long the thought took. */
128
+ export function NmReasoning(props: { text: string; streaming?: boolean; seconds?: number; label?: string; defaultOpen?: boolean }): ReactNode {
129
+ const label = props.label ?? (props.streaming ? 'Thinking' : props.seconds == null ? 'Thoughts' : `Thought for ${props.seconds} seconds`);
129
130
  return (
130
- <NmTrace ariaLabel="Reasoning">
131
+ <NmTrace ariaLabel={label}>
131
132
  <NmTraceCollapsible defaultOpen={props.defaultOpen}>
132
133
  <NmTraceCollapsibleTrigger>
133
134
  <NmTraceLine status={props.streaming ? 'running' : undefined}>
@@ -519,8 +520,10 @@ const TOOL_TITLE: Record<NmToolState, (name: string) => string> = {
519
520
  'output-denied': (n) => `Denied ${n}`,
520
521
  };
521
522
 
523
+ /** `title` is the row's heading in the product's language; without it the heading is built from the state and name. */
522
524
  export function NmTool(props: {
523
525
  name: string;
526
+ title?: string;
524
527
  state: NmToolState;
525
528
  input?: string;
526
529
  output?: string;
@@ -542,7 +545,7 @@ export function NmTool(props: {
542
545
  <NmTraceCollapsibleTrigger>
543
546
  <NmTraceLine status={status}>
544
547
  <NmTraceIcon><NmTraceGlyph kind="command" /></NmTraceIcon>
545
- <NmTraceTitle shimmer={running}>{TOOL_TITLE[props.state](props.name)}</NmTraceTitle>
548
+ <NmTraceTitle shimmer={running}>{props.title ?? TOOL_TITLE[props.state](props.name)}</NmTraceTitle>
546
549
  </NmTraceLine>
547
550
  </NmTraceCollapsibleTrigger>
548
551
  <NmTraceCollapsibleContent>
@@ -0,0 +1,85 @@
1
+ .nm-alert {
2
+ position: relative;
3
+ display: grid;
4
+ grid-template-columns: auto 1fr auto;
5
+ column-gap: var(--nm-space-12);
6
+ row-gap: var(--nm-space-4);
7
+ align-items: start;
8
+ padding: var(--nm-space-16);
9
+ border: var(--nm-rule) solid var(--nm-line-strong);
10
+ border-radius: var(--nm-radius-lg);
11
+ background: var(--nm-panel);
12
+ color: var(--nm-fg);
13
+ font-family: var(--nm-font);
14
+ font-size: var(--nm-type-ui);
15
+ line-height: var(--nm-leading-normal);
16
+ width: 100%;
17
+ }
18
+
19
+ .nm-alert[data-tone='danger'],
20
+ .nm-alert[data-tone='destructive'] {
21
+ border-color: rgb(var(--nm-destructive-rgb) / 40%);
22
+ background: rgb(var(--nm-destructive-rgb) / 10%);
23
+ color: rgb(var(--nm-destructive-rgb));
24
+ }
25
+
26
+ .nm-alert[data-tone='warning'],
27
+ .nm-alert[data-tone='info'],
28
+ .nm-alert[data-tone='success'] {
29
+ background: var(--nm-raised);
30
+ }
31
+
32
+ .nm-alert > svg,
33
+ .nm-alert > .nm-icon,
34
+ .nm-alert__icon {
35
+ grid-column: 1;
36
+ grid-row: 1 / -1;
37
+ display: inline-flex;
38
+ flex-shrink: 0;
39
+ margin-top: var(--nm-space-2);
40
+ color: currentColor;
41
+ }
42
+
43
+ .nm-alert__title {
44
+ grid-column: 2;
45
+ grid-row: 1;
46
+ font-weight: var(--nm-weight-semibold);
47
+ font-size: var(--nm-type-ui);
48
+ line-height: var(--nm-leading-tight);
49
+ letter-spacing: var(--nm-track-tight);
50
+ margin: 0;
51
+ }
52
+
53
+ .nm-alert__description {
54
+ grid-column: 2;
55
+ font-size: var(--nm-type-ui-sm);
56
+ color: var(--nm-fg-muted);
57
+ line-height: var(--nm-leading-relaxed);
58
+ margin: 0;
59
+ }
60
+
61
+ .nm-alert[data-tone='danger'] .nm-alert__description,
62
+ .nm-alert[data-tone='destructive'] .nm-alert__description {
63
+ color: rgb(var(--nm-destructive-rgb) / 80%);
64
+ }
65
+
66
+ .nm-alert__action {
67
+ grid-column: 3;
68
+ grid-row: 1 / -1;
69
+ align-self: center;
70
+ margin-left: auto;
71
+ display: inline-flex;
72
+ align-items: center;
73
+ }
74
+
75
+ .nm-alert__body {
76
+ grid-column: 2;
77
+ display: flex;
78
+ flex-direction: column;
79
+ gap: var(--nm-space-4);
80
+ min-width: 0;
81
+ }
82
+
83
+ .nm-alert > :not(svg):not(.nm-icon):not(.nm-alert__icon):not(.nm-alert__title):not(.nm-alert__description):not(.nm-alert__action):not(.nm-alert__body) {
84
+ grid-column: 2;
85
+ }
@@ -0,0 +1,35 @@
1
+ import type { ComponentProps, ReactNode } from 'react';
2
+ import { nmClass } from '../../lib/nm-class.ts';
3
+
4
+ export type NmAlertTone = 'default' | 'info' | 'warning' | 'danger' | 'success';
5
+
6
+ /**
7
+ * A notice inside the page. The shadcn Alert composition, styled by NIF tokens.
8
+ * Compose with NmIcon, NmAlertTitle, NmAlertDescription and NmAlertAction.
9
+ */
10
+ export function NmAlert({
11
+ tone = 'default',
12
+ icon,
13
+ className,
14
+ children,
15
+ ...props
16
+ }: ComponentProps<'div'> & { tone?: NmAlertTone; icon?: ReactNode }): ReactNode {
17
+ return (
18
+ <div role="alert" data-slot="alert" data-tone={tone} className={nmClass('nm-alert', className)} {...props}>
19
+ {icon != null ? <span className="nm-alert__icon">{icon}</span> : null}
20
+ {children}
21
+ </div>
22
+ );
23
+ }
24
+
25
+ export function NmAlertTitle({ className, ...props }: ComponentProps<'div'>): ReactNode {
26
+ return <div data-slot="alert-title" className={nmClass('nm-alert__title', className)} {...props} />;
27
+ }
28
+
29
+ export function NmAlertDescription({ className, ...props }: ComponentProps<'div'>): ReactNode {
30
+ return <div data-slot="alert-description" className={nmClass('nm-alert__description', className)} {...props} />;
31
+ }
32
+
33
+ export function NmAlertAction({ className, ...props }: ComponentProps<'div'>): ReactNode {
34
+ return <div data-slot="alert-action" className={nmClass('nm-alert__action', className)} {...props} />;
35
+ }
@@ -64,6 +64,30 @@
64
64
  color: rgb(var(--nm-destructive-rgb));
65
65
  }
66
66
 
67
+ .nm-button--ghost {
68
+ border-color: transparent;
69
+ background: transparent;
70
+ color: var(--nm-fg);
71
+ }
72
+
73
+ .nm-button--ghost:hover:not(:disabled) {
74
+ background: var(--nm-panel);
75
+ }
76
+
77
+ .nm-button--link {
78
+ height: auto;
79
+ padding: 0;
80
+ line-height: var(--nm-leading-snug);
81
+ border-color: transparent;
82
+ background: transparent;
83
+ color: var(--nm-fg);
84
+ text-underline-offset: 4px;
85
+ }
86
+
87
+ .nm-button--link:hover:not(:disabled) {
88
+ text-decoration: underline;
89
+ }
90
+
67
91
  .nm-button--filled:hover:not(:disabled),
68
92
  .nm-button--danger:hover:not(:disabled) {
69
93
  opacity: var(--btn-hover);
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from 'react';
1
+ import { forwardRef, type ButtonHTMLAttributes, type MouseEvent, type ReactNode } from 'react';
2
2
  import type { NmIconId } from '../../config/nm-icons.ts';
3
3
  import {
4
4
  NM_BUTTON_CLASSES,
@@ -8,12 +8,15 @@ import {
8
8
  type NmButtonTone,
9
9
  } from '../../config/nm-button.ts';
10
10
  import { createLogger } from '../../kit-logger.ts';
11
+ import { AnimateIcon, Button as MotionButton } from '../../lib/nm-motion.ts';
11
12
  import { NmIcon } from '../nm-icon/nm-icon.tsx';
12
13
 
13
14
  const logger = createLogger('interface-nm-button');
14
15
 
15
16
  export type NmButtonProps = {
16
17
  label: string;
18
+ /** Content of the button in place of the icon and label, for a button that holds more than text. The label is still its accessible name when icon only. */
19
+ children?: ReactNode;
17
20
  tone: NmButtonTone;
18
21
  size?: NmButtonSize;
19
22
  block?: boolean;
@@ -24,35 +27,53 @@ export type NmButtonProps = {
24
27
  /** Shows the icon alone, in a square. The label is still its accessible name. */
25
28
  iconOnly?: boolean;
26
29
  testId?: string;
27
- onClick?: () => void;
30
+ onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
28
31
  };
29
32
 
30
- export function NmButton(props: NmButtonProps): ReactNode {
31
- const size = props.size ?? NM_BUTTON_SIZES.default;
33
+ /** Any other button attribute, ref and event goes to the button, so a Base UI trigger can render a NmButton. */
34
+ type NmButtonNativeProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, keyof NmButtonProps | 'children' | 'aria-pressed'>;
35
+
36
+ export const NmButton = forwardRef<HTMLButtonElement, NmButtonProps & NmButtonNativeProps>(function NmButton(props, ref): ReactNode {
37
+ const { label, children, tone, size: sizeProp, block, type, disabled, pressed, icon, iconOnly, testId, onClick, className: extra, ...rest } = props;
38
+ const size = sizeProp ?? NM_BUTTON_SIZES.default;
32
39
  const className = [
33
40
  NM_BUTTON_CLASSES.root,
34
- NM_BUTTON_CLASSES[props.tone],
41
+ NM_BUTTON_CLASSES[tone],
35
42
  NM_BUTTON_CLASSES[size],
36
- props.block ? NM_BUTTON_CLASSES.block : null,
37
- props.iconOnly ? NM_BUTTON_CLASSES.icon : null,
43
+ block ? NM_BUTTON_CLASSES.block : null,
44
+ iconOnly ? NM_BUTTON_CLASSES.icon : null,
45
+ extra,
38
46
  ]
39
47
  .filter(Boolean)
40
48
  .join(' ');
41
- logger.debug('render', props.label, { tone: props.tone, size });
42
- return (
43
- <button
49
+ logger.debug('render', label, { tone, size });
50
+ const button = (
51
+ <MotionButton
52
+ {...(rest as object)}
53
+ ref={ref}
44
54
  className={className}
45
- type={props.type ?? 'button'}
46
- disabled={props.disabled}
47
- aria-pressed={props.pressed}
48
- aria-label={props.iconOnly ? props.label : undefined}
49
- data-testid={props.testId}
50
- onClick={props.onClick}
55
+ type={type ?? 'button'}
56
+ disabled={disabled}
57
+ aria-pressed={pressed}
58
+ aria-label={rest['aria-label'] ?? (iconOnly ? label : undefined)}
59
+ data-testid={testId ?? rest['data-testid' as keyof typeof rest]}
60
+ onClick={onClick}
61
+ hoverScale={disabled ? 1 : 1.02}
62
+ tapScale={disabled ? 1 : 0.97}
51
63
  >
52
- {props.icon ? <NmIcon id={props.icon} className="nm-button__icon" /> : null}
53
- {props.iconOnly ? null : <span className="nm-button__label">{props.label}</span>}
54
- </button>
64
+ {children != null ? (
65
+ children
66
+ ) : (
67
+ <>
68
+ {icon ? <NmIcon id={icon} className="nm-button__icon" /> : null}
69
+ {iconOnly ? null : <span className="nm-button__label">{label}</span>}
70
+ </>
71
+ )}
72
+ </MotionButton>
55
73
  );
56
- }
74
+ // The icon plays its animation when the button is hovered.
75
+ // Always wrapped, so the control keeps its place in the tree when its icon is added or removed.
76
+ return <AnimateIcon animateOnHover={Boolean(icon)} asChild>{button}</AnimateIcon>;
77
+ });
57
78
 
58
79
  export { NM_BUTTON_SIZES, NM_BUTTON_TONES };
@@ -1,4 +1,4 @@
1
- import { Checkbox as CheckboxPrimitive } from '@base-ui/react/checkbox';
1
+ import { Checkbox as CheckboxPrimitive } from '../../lib/nm-motion.ts';
2
2
  import { nmClass } from '../../lib/nm-class.ts';
3
3
  import { NmIcon } from '../nm-icon/nm-icon.tsx';
4
4
 
@@ -26,12 +26,37 @@
26
26
  padding: 0 var(--badge-px);
27
27
  }
28
28
 
29
+ /* In a sentence: the type of the text around it, and a height that fits a line of it. */
30
+ .nm-chip[data-size='inline'] {
31
+ --nm-chip-fs: 1em;
32
+ --nm-chip-h: calc(var(--nm-chip-fs) * var(--nm-leading-normal));
33
+ padding: 0 var(--nm-space-8);
34
+ font-size: var(--nm-chip-fs);
35
+ line-height: var(--nm-leading-none);
36
+ vertical-align: top;
37
+ position: relative;
38
+ /* Centred in the host's line, which the host may name; without a name the line is as tall as the chip. */
39
+ top: calc((var(--nm-inline-line, var(--nm-chip-h)) - var(--nm-chip-h)) / 2);
40
+ }
41
+
29
42
  /* Icons read these two tokens, so the chip scales them to its own type. */
30
43
  .nm-chip {
31
44
  --nm-icon: var(--nm-chip-fs);
32
45
  --nm-icon-button: var(--nm-chip-fs);
33
46
  }
34
47
 
48
+ .nm-chip__leading {
49
+ display: inline-flex;
50
+ flex-shrink: 0;
51
+ width: var(--nm-chip-fs);
52
+ height: var(--nm-chip-fs);
53
+ }
54
+
55
+ .nm-chip__leading > * {
56
+ width: 100%;
57
+ height: 100%;
58
+ }
59
+
35
60
  .nm-chip svg {
36
61
  flex-shrink: 0;
37
62
  }
@@ -1,10 +1,12 @@
1
1
  import type { ComponentProps, ReactNode } from 'react';
2
2
  import { nmClass } from '../../lib/nm-class.ts';
3
3
  import type { NmIconId } from '../../config/nm-icons.ts';
4
+ import { AnimateIcon } from '../../lib/nm-motion.ts';
4
5
  import { NmIcon } from '../nm-icon/nm-icon.tsx';
5
6
 
6
7
  export const NM_CHIP_TONES = ['neutral', 'outline', 'filled', 'ok', 'warn', 'error'] as const;
7
- export const NM_CHIP_SIZES = ['default', 'sm'] as const;
8
+ /** `inline` takes the size of the text around it, for a chip that sits in a sentence. */
9
+ export const NM_CHIP_SIZES = ['default', 'sm', 'inline'] as const;
8
10
  export type NmChipTone = (typeof NM_CHIP_TONES)[number];
9
11
  export type NmChipSize = (typeof NM_CHIP_SIZES)[number];
10
12
 
@@ -12,6 +14,8 @@ type NmChipBase = {
12
14
  tone?: NmChipTone;
13
15
  size?: NmChipSize;
14
16
  icon?: NmIconId;
17
+ /** A mark in the icon's place, such as an app's logo. `icon` wins when both are given. */
18
+ leading?: ReactNode;
15
19
  /** A chip that stands for a chosen filter or option. */
16
20
  selected?: boolean;
17
21
  disabled?: boolean;
@@ -35,6 +39,7 @@ export function NmChip({
35
39
  tone = 'neutral',
36
40
  size = 'default',
37
41
  icon,
42
+ leading,
38
43
  selected,
39
44
  disabled,
40
45
  children,
@@ -55,7 +60,7 @@ export function NmChip({
55
60
  } as const;
56
61
  const body = (
57
62
  <>
58
- {icon ? <NmIcon id={icon} /> : null}
63
+ {icon ? <NmIcon id={icon} /> : leading != null ? <span className="nm-chip__leading">{leading}</span> : null}
59
64
  {children}
60
65
  </>
61
66
  );
@@ -67,11 +72,12 @@ export function NmChip({
67
72
  );
68
73
  }
69
74
  if (onClick) {
70
- return (
75
+ const button = (
71
76
  <button className={classes} {...(rest as ComponentProps<'button'>)} {...state} type="button" disabled={disabled} aria-pressed={rest.role ? undefined : (selected ?? undefined)} onClick={onClick}>
72
77
  {body}
73
78
  </button>
74
79
  );
80
+ return <AnimateIcon animateOnHover={Boolean(icon)} asChild>{button}</AnimateIcon>;
75
81
  }
76
82
  return (
77
83
  <span {...rest} {...state} className={classes}>
@@ -0,0 +1,3 @@
1
+ .nm-collapsible__content {
2
+ overflow: hidden;
3
+ }
@@ -0,0 +1,16 @@
1
+ import type { ReactNode } from 'react';
2
+ import { Collapsible as CollapsiblePrimitive } from '../../lib/nm-motion.ts';
3
+ import { nmClass } from '../../lib/nm-class.ts';
4
+
5
+ /** Content that opens and closes under a trigger. Built on the Base UI Collapsible, animated by Animate UI. */
6
+ export function NmCollapsible(props: CollapsiblePrimitive.Root.Props): ReactNode {
7
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
8
+ }
9
+
10
+ export function NmCollapsibleTrigger(props: CollapsiblePrimitive.Trigger.Props): ReactNode {
11
+ return <CollapsiblePrimitive.Trigger data-slot="collapsible-trigger" {...props} />;
12
+ }
13
+
14
+ export function NmCollapsibleContent({ className, ...props }: CollapsiblePrimitive.Panel.Props): ReactNode {
15
+ return <CollapsiblePrimitive.Panel data-slot="collapsible-content" className={nmClass('nm-collapsible__content', className as string)} {...props} />;
16
+ }
@@ -1,5 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
- import { Combobox as ComboboxPrimitive } from '@base-ui/react/combobox';
2
+ import { Combobox as ComboboxPrimitive } from '../../lib/nm-motion.ts';
3
3
  import { nmClass } from '../../lib/nm-class.ts';
4
4
  import { NmIcon } from '../nm-icon/nm-icon.tsx';
5
5
 
@@ -188,3 +188,51 @@
188
188
  transform: rotate(360deg);
189
189
  }
190
190
  }
191
+
192
+ /* The compact list for a popover: it takes the popover's frame, and its rows are menu rows. */
193
+ .nm-command[data-variant='menu'] {
194
+ gap: var(--nm-space-4);
195
+ padding: 0;
196
+ border: 0;
197
+ border-radius: 0;
198
+ background: transparent;
199
+ }
200
+
201
+ .nm-command[data-variant='menu'] .nm-command__list {
202
+ margin: 0;
203
+ }
204
+
205
+ .nm-command[data-variant='menu'] [cmdk-list-sizer] {
206
+ gap: var(--nm-space-4);
207
+ }
208
+
209
+ .nm-command[data-variant='menu'] .nm-command__item {
210
+ min-height: var(--nm-icon-control);
211
+ padding: var(--nm-icon-pad);
212
+ border-radius: var(--nm-panel-item-radius);
213
+ }
214
+
215
+ .nm-command__description {
216
+ color: var(--nm-fg-subtle);
217
+ font-size: var(--nm-type-ui-sm);
218
+ font-weight: var(--nm-weight-regular);
219
+ }
220
+
221
+ .nm-command[data-variant='menu'] .nm-command__description {
222
+ margin-left: auto;
223
+ color: var(--nm-fg-subtle);
224
+ font-size: var(--nm-type-ui-sm);
225
+ font-weight: var(--nm-weight-regular);
226
+ }
227
+
228
+ .nm-command__icon {
229
+ display: inline-flex;
230
+ flex-shrink: 0;
231
+ width: var(--nm-icon);
232
+ height: var(--nm-icon);
233
+ }
234
+
235
+ .nm-command__icon > * {
236
+ width: 100%;
237
+ height: 100%;
238
+ }
@@ -1,6 +1,7 @@
1
1
  import { NmChip } from '../nm-chip/nm-chip.tsx';
2
2
  import { useState, type ComponentProps, type ReactNode } from 'react';
3
3
  import { Command as CommandPrimitive } from 'cmdk';
4
+ import { AnimateIcon } from '../../lib/nm-motion.ts';
4
5
  import { nmClass } from '../../lib/nm-class.ts';
5
6
  import { NmDialog, NmDialogContent, NmDialogDescription, NmDialogHeader, NmDialogTitle } from '../nm-dialog/nm-dialog.tsx';
6
7
  import { NmIcon } from '../nm-icon/nm-icon.tsx';
@@ -9,8 +10,9 @@ import { NmIcon } from '../nm-icon/nm-icon.tsx';
9
10
  * Command: search and run. The shadcn Command composition on cmdk, which gives filtering, arrow-key
10
11
  * navigation and the listbox roles. Everything you see is NIF tokens.
11
12
  */
12
- export function NmCommand({ className, ...props }: ComponentProps<typeof CommandPrimitive>) {
13
- return <CommandPrimitive data-slot="command" className={nmClass('nm-command', className)} {...props} />;
13
+ /** `variant="menu"` is the compact list for a popover: no frame, rows the size of menu rows. */
14
+ export function NmCommand({ className, variant = 'panel', ...props }: ComponentProps<typeof CommandPrimitive> & { variant?: 'panel' | 'menu' }) {
15
+ return <CommandPrimitive data-slot="command" data-variant={variant} className={nmClass('nm-command', className)} {...props} />;
14
16
  }
15
17
 
16
18
  export function NmCommandDialog({
@@ -109,9 +111,11 @@ export function NmCommandSeparator({ className, ...props }: ComponentProps<typeo
109
111
 
110
112
  export function NmCommandItem({ className, children, ...props }: ComponentProps<typeof CommandPrimitive.Item>) {
111
113
  return (
112
- <CommandPrimitive.Item data-slot="command-item" className={nmClass('nm-command__item', className)} {...props}>
113
- {children}
114
- </CommandPrimitive.Item>
114
+ <AnimateIcon animateOnHover asChild>
115
+ <CommandPrimitive.Item data-slot="command-item" className={nmClass('nm-command__item', className)} {...props}>
116
+ {children}
117
+ </CommandPrimitive.Item>
118
+ </AnimateIcon>
115
119
  );
116
120
  }
117
121
 
@@ -123,3 +127,13 @@ export function NmCommandItemActions({ className, ...props }: ComponentProps<'sp
123
127
  export function NmCommandShortcut({ className, ...props }: ComponentProps<'span'>) {
124
128
  return <span data-slot="command-shortcut" className={nmClass('nm-command__shortcut', className)} {...props} />;
125
129
  }
130
+
131
+ /** A quiet line after an item's name. In the menu variant it sits at the end of the row. */
132
+ export function NmCommandDescription({ className, ...props }: ComponentProps<'span'>) {
133
+ return <span data-slot="command-description" className={nmClass('nm-command__description', className)} {...props} />;
134
+ }
135
+
136
+ /** The slot for a mark at the start of an item, such as an app's logo. It sizes whatever it holds. */
137
+ export function NmCommandIcon({ className, ...props }: ComponentProps<'span'>) {
138
+ return <span data-slot="command-icon" className={nmClass('nm-command__icon', className)} {...props} />;
139
+ }
@@ -1,4 +1,5 @@
1
1
  .nm-composer {
2
+ position: relative;
2
3
  box-sizing: border-box;
3
4
  display: flex;
4
5
  flex-direction: column;
@@ -33,13 +34,85 @@
33
34
  gap: var(--nm-space-8);
34
35
  }
35
36
 
37
+ /*
38
+ * While it listens, the field stays where it is, hidden, so the box keeps its height. The listening content lies
39
+ * over it and fills exactly that space, whatever it draws.
40
+ */
41
+ .nm-composer__listening {
42
+ position: absolute;
43
+ inset: 0;
44
+ z-index: 2;
45
+ display: flex;
46
+ align-items: center;
47
+ overflow: hidden;
48
+ }
49
+
50
+ /* Whatever the host puts there is the size of the space and no more. */
51
+ .nm-composer .nm-composer__listening > * {
52
+ flex: 1 1 auto;
53
+ width: 100%;
54
+ min-width: 0;
55
+ height: 100%;
56
+ min-height: 0;
57
+ }
58
+
59
+ .nm-composer__field-wrap[data-listening='true'] > :not(.nm-composer__listening) {
60
+ visibility: hidden;
61
+ pointer-events: none;
62
+ }
63
+
64
+ .nm-composer__field-wrap {
65
+ --nm-composer-line: var(--nm-space-24);
66
+ position: relative;
67
+ }
68
+
69
+ .nm-composer__field[data-inline='true'] {
70
+ position: relative;
71
+ z-index: 1;
72
+ color: transparent;
73
+ -webkit-text-fill-color: transparent;
74
+ caret-color: var(--nm-fg);
75
+ }
76
+
77
+ /* The words with the chips drawn in them, over the field, with the field's own type and line. */
78
+ .nm-composer__inline {
79
+ position: absolute;
80
+ inset: 0;
81
+ z-index: 0;
82
+ overflow: auto;
83
+ scrollbar-width: none;
84
+ pointer-events: none;
85
+ white-space: pre-wrap;
86
+ overflow-wrap: anywhere;
87
+ color: var(--nm-fg);
88
+ font: inherit;
89
+ line-height: var(--nm-composer-line);
90
+ user-select: none;
91
+ }
92
+
93
+ .nm-composer__inline::-webkit-scrollbar {
94
+ display: none;
95
+ }
96
+
97
+ .nm-composer__inline {
98
+ --nm-inline-line: var(--nm-composer-line);
99
+ }
100
+
101
+ .nm-composer__inline-chip {
102
+ pointer-events: auto;
103
+ user-select: none;
104
+ }
105
+
36
106
  .nm-composer__field {
37
107
  display: block;
38
108
  box-sizing: border-box;
39
109
  width: 100%;
40
- --nm-composer-line: calc(var(--nm-space-16) + var(--nm-space-4));
110
+ --nm-composer-line: var(--nm-space-24);
41
111
  min-height: var(--nm-composer-line);
42
- max-height: calc(var(--nm-composer-line) * 8);
112
+ /* Three lines, then it scrolls, without a scrollbar in any browser. */
113
+ max-height: calc(var(--nm-composer-line) * 3);
114
+ overflow-y: auto;
115
+ scrollbar-width: none;
43
116
  margin: 0;
44
117
  padding: 0;
45
118
  border: 0;
@@ -49,7 +122,17 @@
49
122
  line-height: var(--nm-composer-line);
50
123
  outline: none;
51
124
  resize: none;
52
- field-sizing: content;
125
+ transition: height var(--reveal) var(--ease);
126
+ }
127
+
128
+ @media (prefers-reduced-motion: reduce) {
129
+ .nm-composer__field {
130
+ transition: none;
131
+ }
132
+ }
133
+
134
+ .nm-composer__field::-webkit-scrollbar {
135
+ display: none;
53
136
  }
54
137
 
55
138
  .nm-composer__field::placeholder {
@@ -58,6 +141,7 @@
58
141
  }
59
142
 
60
143
  .nm-composer__bar {
144
+ min-height: var(--control-h);
61
145
  display: flex;
62
146
  align-items: center;
63
147
  justify-content: space-between;