@moldable-ai/ui 0.2.19 → 0.2.21

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 (464) hide show
  1. package/dist/catalog/catalog-coverage.d.ts +15 -0
  2. package/dist/catalog/catalog-coverage.d.ts.map +1 -0
  3. package/dist/catalog/catalog-coverage.js +44 -0
  4. package/dist/catalog/catalog-manifest.d.ts +6 -0
  5. package/dist/catalog/catalog-manifest.d.ts.map +1 -0
  6. package/dist/catalog/catalog-manifest.js +117 -0
  7. package/dist/catalog/catalog-types.d.ts +64 -0
  8. package/dist/catalog/catalog-types.d.ts.map +1 -0
  9. package/dist/catalog/catalog-types.js +20 -0
  10. package/dist/catalog/component-catalog.d.ts +14 -0
  11. package/dist/catalog/component-catalog.d.ts.map +1 -0
  12. package/dist/catalog/component-catalog.js +49 -0
  13. package/dist/catalog/core-catalog-exclusions.d.ts +8 -0
  14. package/dist/catalog/core-catalog-exclusions.d.ts.map +1 -0
  15. package/dist/catalog/core-catalog-exclusions.js +151 -0
  16. package/dist/catalog/core-catalog.d.ts +2 -0
  17. package/dist/catalog/core-catalog.d.ts.map +1 -0
  18. package/dist/catalog/core-catalog.js +19 -0
  19. package/dist/catalog/core-collection-stories.d.ts +3 -0
  20. package/dist/catalog/core-collection-stories.d.ts.map +1 -0
  21. package/dist/catalog/core-collection-stories.js +42 -0
  22. package/dist/catalog/core-control-stories.d.ts +3 -0
  23. package/dist/catalog/core-control-stories.d.ts.map +1 -0
  24. package/dist/catalog/core-control-stories.js +94 -0
  25. package/dist/catalog/core-feedback-stories.d.ts +3 -0
  26. package/dist/catalog/core-feedback-stories.d.ts.map +1 -0
  27. package/dist/catalog/core-feedback-stories.js +50 -0
  28. package/dist/catalog/core-foundation-stories.d.ts +3 -0
  29. package/dist/catalog/core-foundation-stories.d.ts.map +1 -0
  30. package/dist/catalog/core-foundation-stories.js +53 -0
  31. package/dist/catalog/core-navigation-stories.d.ts +3 -0
  32. package/dist/catalog/core-navigation-stories.d.ts.map +1 -0
  33. package/dist/catalog/core-navigation-stories.js +25 -0
  34. package/dist/catalog/core-overlay-stories.d.ts +3 -0
  35. package/dist/catalog/core-overlay-stories.d.ts.map +1 -0
  36. package/dist/catalog/core-overlay-stories.js +20 -0
  37. package/dist/catalog/index.d.ts +7 -0
  38. package/dist/catalog/index.d.ts.map +1 -0
  39. package/dist/catalog/index.js +6 -0
  40. package/dist/components/app-error-boundary.d.ts +1 -0
  41. package/dist/components/app-error-boundary.d.ts.map +1 -1
  42. package/dist/components/app-error-boundary.js +13 -0
  43. package/dist/components/chat/chat-image-lightbox.d.ts +9 -0
  44. package/dist/components/chat/chat-image-lightbox.d.ts.map +1 -0
  45. package/dist/components/chat/chat-image-lightbox.js +9 -0
  46. package/dist/components/chat/chat-message.d.ts +19 -1
  47. package/dist/components/chat/chat-message.d.ts.map +1 -1
  48. package/dist/components/chat/chat-message.js +66 -16
  49. package/dist/components/chat/chat-messages.d.ts +5 -2
  50. package/dist/components/chat/chat-messages.d.ts.map +1 -1
  51. package/dist/components/chat/chat-messages.js +61 -6
  52. package/dist/components/chat/chat-panel.d.ts +49 -6
  53. package/dist/components/chat/chat-panel.d.ts.map +1 -1
  54. package/dist/components/chat/chat-panel.js +196 -163
  55. package/dist/components/chat/conversation-history.d.ts +39 -5
  56. package/dist/components/chat/conversation-history.d.ts.map +1 -1
  57. package/dist/components/chat/conversation-history.js +192 -26
  58. package/dist/components/chat/index.d.ts +2 -2
  59. package/dist/components/chat/index.d.ts.map +1 -1
  60. package/dist/components/chat/index.js +1 -1
  61. package/dist/components/chat/tool-handlers.d.ts.map +1 -1
  62. package/dist/components/chat/tool-handlers.js +40 -2
  63. package/dist/components/chat/vertical-scroll-fade.d.ts +6 -0
  64. package/dist/components/chat/vertical-scroll-fade.d.ts.map +1 -0
  65. package/dist/components/chat/vertical-scroll-fade.js +12 -0
  66. package/dist/components/native-capabilities/bluetooth-panel-helpers.d.ts +9 -0
  67. package/dist/components/native-capabilities/bluetooth-panel-helpers.d.ts.map +1 -0
  68. package/dist/components/native-capabilities/bluetooth-panel-helpers.js +37 -0
  69. package/dist/components/native-capabilities/bluetooth-panel.d.ts +56 -0
  70. package/dist/components/native-capabilities/bluetooth-panel.d.ts.map +1 -0
  71. package/dist/components/native-capabilities/bluetooth-panel.js +470 -0
  72. package/dist/components/native-capabilities/camera-preview.d.ts +39 -0
  73. package/dist/components/native-capabilities/camera-preview.d.ts.map +1 -0
  74. package/dist/components/native-capabilities/camera-preview.js +228 -0
  75. package/dist/components/native-capabilities/capability-badge.d.ts +23 -0
  76. package/dist/components/native-capabilities/capability-badge.d.ts.map +1 -0
  77. package/dist/components/native-capabilities/capability-badge.js +39 -0
  78. package/dist/components/native-capabilities/capability-matrix.d.ts +14 -0
  79. package/dist/components/native-capabilities/capability-matrix.d.ts.map +1 -0
  80. package/dist/components/native-capabilities/capability-matrix.js +97 -0
  81. package/dist/components/native-capabilities/clipboard-button.d.ts +26 -0
  82. package/dist/components/native-capabilities/clipboard-button.d.ts.map +1 -0
  83. package/dist/components/native-capabilities/clipboard-button.js +99 -0
  84. package/dist/components/native-capabilities/device-io-controls.d.ts +4 -0
  85. package/dist/components/native-capabilities/device-io-controls.d.ts.map +1 -0
  86. package/dist/components/native-capabilities/device-io-controls.js +28 -0
  87. package/dist/components/native-capabilities/device-list.d.ts +20 -0
  88. package/dist/components/native-capabilities/device-list.d.ts.map +1 -0
  89. package/dist/components/native-capabilities/device-list.js +14 -0
  90. package/dist/components/native-capabilities/display-map.d.ts +23 -0
  91. package/dist/components/native-capabilities/display-map.d.ts.map +1 -0
  92. package/dist/components/native-capabilities/display-map.js +114 -0
  93. package/dist/components/native-capabilities/haptic-button.d.ts +26 -0
  94. package/dist/components/native-capabilities/haptic-button.d.ts.map +1 -0
  95. package/dist/components/native-capabilities/haptic-button.js +94 -0
  96. package/dist/components/native-capabilities/hid-panel.d.ts +40 -0
  97. package/dist/components/native-capabilities/hid-panel.d.ts.map +1 -0
  98. package/dist/components/native-capabilities/hid-panel.js +373 -0
  99. package/dist/components/native-capabilities/index.d.ts +27 -0
  100. package/dist/components/native-capabilities/index.d.ts.map +1 -0
  101. package/dist/components/native-capabilities/index.js +26 -0
  102. package/dist/components/native-capabilities/live-indicator.d.ts +15 -0
  103. package/dist/components/native-capabilities/live-indicator.d.ts.map +1 -0
  104. package/dist/components/native-capabilities/live-indicator.js +26 -0
  105. package/dist/components/native-capabilities/local-auth-button.d.ts +33 -0
  106. package/dist/components/native-capabilities/local-auth-button.d.ts.map +1 -0
  107. package/dist/components/native-capabilities/local-auth-button.js +115 -0
  108. package/dist/components/native-capabilities/location-panel.d.ts +29 -0
  109. package/dist/components/native-capabilities/location-panel.d.ts.map +1 -0
  110. package/dist/components/native-capabilities/location-panel.js +146 -0
  111. package/dist/components/native-capabilities/microphone-meter.d.ts +35 -0
  112. package/dist/components/native-capabilities/microphone-meter.d.ts.map +1 -0
  113. package/dist/components/native-capabilities/microphone-meter.js +244 -0
  114. package/dist/components/native-capabilities/midi-monitor.d.ts +54 -0
  115. package/dist/components/native-capabilities/midi-monitor.d.ts.map +1 -0
  116. package/dist/components/native-capabilities/midi-monitor.js +534 -0
  117. package/dist/components/native-capabilities/native-capability-panel.d.ts +11 -0
  118. package/dist/components/native-capabilities/native-capability-panel.d.ts.map +1 -0
  119. package/dist/components/native-capabilities/native-capability-panel.js +28 -0
  120. package/dist/components/native-capabilities/notification-panel.d.ts +24 -0
  121. package/dist/components/native-capabilities/notification-panel.d.ts.map +1 -0
  122. package/dist/components/native-capabilities/notification-panel.js +124 -0
  123. package/dist/components/native-capabilities/power-blocker-controller.d.ts +19 -0
  124. package/dist/components/native-capabilities/power-blocker-controller.d.ts.map +1 -0
  125. package/dist/components/native-capabilities/power-blocker-controller.js +83 -0
  126. package/dist/components/native-capabilities/power-panel.d.ts +67 -0
  127. package/dist/components/native-capabilities/power-panel.d.ts.map +1 -0
  128. package/dist/components/native-capabilities/power-panel.js +309 -0
  129. package/dist/components/native-capabilities/readout.d.ts +10 -0
  130. package/dist/components/native-capabilities/readout.d.ts.map +1 -0
  131. package/dist/components/native-capabilities/readout.js +11 -0
  132. package/dist/components/native-capabilities/screen-share-preview.d.ts +36 -0
  133. package/dist/components/native-capabilities/screen-share-preview.d.ts.map +1 -0
  134. package/dist/components/native-capabilities/screen-share-preview.js +191 -0
  135. package/dist/components/native-capabilities/secure-storage-panel.d.ts +36 -0
  136. package/dist/components/native-capabilities/secure-storage-panel.d.ts.map +1 -0
  137. package/dist/components/native-capabilities/secure-storage-panel.js +193 -0
  138. package/dist/components/native-capabilities/serial-console.d.ts +64 -0
  139. package/dist/components/native-capabilities/serial-console.d.ts.map +1 -0
  140. package/dist/components/native-capabilities/serial-console.js +399 -0
  141. package/dist/components/native-capabilities/shortcut-recorder.d.ts +35 -0
  142. package/dist/components/native-capabilities/shortcut-recorder.d.ts.map +1 -0
  143. package/dist/components/native-capabilities/shortcut-recorder.js +217 -0
  144. package/dist/components/native-capabilities/stream-log.d.ts +35 -0
  145. package/dist/components/native-capabilities/stream-log.d.ts.map +1 -0
  146. package/dist/components/native-capabilities/stream-log.js +65 -0
  147. package/dist/components/native-capabilities/system-audio-monitor.d.ts +34 -0
  148. package/dist/components/native-capabilities/system-audio-monitor.d.ts.map +1 -0
  149. package/dist/components/native-capabilities/system-audio-monitor.js +275 -0
  150. package/dist/components/native-capabilities/usb-panel.d.ts +54 -0
  151. package/dist/components/native-capabilities/usb-panel.d.ts.map +1 -0
  152. package/dist/components/native-capabilities/usb-panel.js +363 -0
  153. package/dist/components/native-capabilities/use-capability.d.ts +20 -0
  154. package/dist/components/native-capabilities/use-capability.d.ts.map +1 -0
  155. package/dist/components/native-capabilities/use-capability.js +61 -0
  156. package/dist/components/ui/alert-dialog.d.ts +7 -3
  157. package/dist/components/ui/alert-dialog.d.ts.map +1 -1
  158. package/dist/components/ui/alert-dialog.js +9 -5
  159. package/dist/components/ui/alert.d.ts +19 -3
  160. package/dist/components/ui/alert.d.ts.map +1 -1
  161. package/dist/components/ui/alert.js +25 -8
  162. package/dist/components/ui/app-frame.d.ts +28 -0
  163. package/dist/components/ui/app-frame.d.ts.map +1 -0
  164. package/dist/components/ui/app-frame.js +95 -0
  165. package/dist/components/ui/button-group.d.ts +1 -1
  166. package/dist/components/ui/button.js +1 -1
  167. package/dist/components/ui/collapsible.d.ts +9 -1
  168. package/dist/components/ui/collapsible.d.ts.map +1 -1
  169. package/dist/components/ui/collapsible.js +13 -2
  170. package/dist/components/ui/collection-navigation.d.ts +8 -0
  171. package/dist/components/ui/collection-navigation.d.ts.map +1 -0
  172. package/dist/components/ui/collection-navigation.js +19 -0
  173. package/dist/components/ui/color-well.d.ts +13 -0
  174. package/dist/components/ui/color-well.d.ts.map +1 -0
  175. package/dist/components/ui/color-well.js +30 -0
  176. package/dist/components/ui/command.d.ts +5 -1
  177. package/dist/components/ui/command.d.ts.map +1 -1
  178. package/dist/components/ui/command.js +13 -1
  179. package/dist/components/ui/confirm-dialog.d.ts +19 -0
  180. package/dist/components/ui/confirm-dialog.d.ts.map +1 -0
  181. package/dist/components/ui/confirm-dialog.js +45 -0
  182. package/dist/components/ui/date-field.d.ts +19 -0
  183. package/dist/components/ui/date-field.d.ts.map +1 -0
  184. package/dist/components/ui/date-field.js +54 -0
  185. package/dist/components/ui/date-picker.d.ts +24 -0
  186. package/dist/components/ui/date-picker.d.ts.map +1 -0
  187. package/dist/components/ui/date-picker.js +92 -0
  188. package/dist/components/ui/dialog.d.ts +4 -2
  189. package/dist/components/ui/dialog.d.ts.map +1 -1
  190. package/dist/components/ui/dialog.js +8 -5
  191. package/dist/components/ui/edge-fade.d.ts +11 -0
  192. package/dist/components/ui/edge-fade.d.ts.map +1 -0
  193. package/dist/components/ui/edge-fade.js +41 -0
  194. package/dist/components/ui/empty.d.ts +7 -2
  195. package/dist/components/ui/empty.d.ts.map +1 -1
  196. package/dist/components/ui/empty.js +20 -7
  197. package/dist/components/ui/field.d.ts +1 -1
  198. package/dist/components/ui/grid.d.ts +24 -0
  199. package/dist/components/ui/grid.d.ts.map +1 -0
  200. package/dist/components/ui/grid.js +258 -0
  201. package/dist/components/ui/icon-button.d.ts +15 -0
  202. package/dist/components/ui/icon-button.d.ts.map +1 -0
  203. package/dist/components/ui/icon-button.js +15 -0
  204. package/dist/components/ui/index.d.ts +23 -0
  205. package/dist/components/ui/index.d.ts.map +1 -1
  206. package/dist/components/ui/index.js +23 -0
  207. package/dist/components/ui/input-group.d.ts +1 -1
  208. package/dist/components/ui/inspector.d.ts +15 -0
  209. package/dist/components/ui/inspector.d.ts.map +1 -0
  210. package/dist/components/ui/inspector.js +26 -0
  211. package/dist/components/ui/kbd.d.ts +1 -1
  212. package/dist/components/ui/list.d.ts +28 -0
  213. package/dist/components/ui/list.d.ts.map +1 -0
  214. package/dist/components/ui/list.js +235 -0
  215. package/dist/components/ui/material.d.ts +34 -0
  216. package/dist/components/ui/material.d.ts.map +1 -0
  217. package/dist/components/ui/material.js +34 -0
  218. package/dist/components/ui/message-scroller-controller.d.ts +162 -0
  219. package/dist/components/ui/message-scroller-controller.d.ts.map +1 -0
  220. package/dist/components/ui/message-scroller-controller.js +888 -0
  221. package/dist/components/ui/message-scroller-layout-stability.d.ts +33 -0
  222. package/dist/components/ui/message-scroller-layout-stability.d.ts.map +1 -0
  223. package/dist/components/ui/message-scroller-layout-stability.js +153 -0
  224. package/dist/components/ui/message-scroller-policy.d.ts +74 -0
  225. package/dist/components/ui/message-scroller-policy.d.ts.map +1 -0
  226. package/dist/components/ui/message-scroller-policy.js +129 -0
  227. package/dist/components/ui/message-scroller-primitive.d.ts +55 -0
  228. package/dist/components/ui/message-scroller-primitive.d.ts.map +1 -0
  229. package/dist/components/ui/message-scroller-primitive.js +226 -0
  230. package/dist/components/ui/message-scroller.d.ts +11 -0
  231. package/dist/components/ui/message-scroller.d.ts.map +1 -0
  232. package/dist/components/ui/message-scroller.js +25 -0
  233. package/dist/components/ui/navigation-button-group.d.ts +16 -0
  234. package/dist/components/ui/navigation-button-group.d.ts.map +1 -0
  235. package/dist/components/ui/navigation-button-group.js +9 -0
  236. package/dist/components/ui/notification-dot.d.ts +4 -0
  237. package/dist/components/ui/notification-dot.d.ts.map +1 -0
  238. package/dist/components/ui/notification-dot.js +7 -0
  239. package/dist/components/ui/number-input.d.ts +16 -0
  240. package/dist/components/ui/number-input.d.ts.map +1 -0
  241. package/dist/components/ui/number-input.js +56 -0
  242. package/dist/components/ui/panel.d.ts +18 -0
  243. package/dist/components/ui/panel.d.ts.map +1 -0
  244. package/dist/components/ui/panel.js +40 -0
  245. package/dist/components/ui/popover.d.ts +9 -2
  246. package/dist/components/ui/popover.d.ts.map +1 -1
  247. package/dist/components/ui/popover.js +14 -4
  248. package/dist/components/ui/scroll-area.d.ts +8 -2
  249. package/dist/components/ui/scroll-area.d.ts.map +1 -1
  250. package/dist/components/ui/scroll-area.js +6 -3
  251. package/dist/components/ui/search-field.d.ts +19 -0
  252. package/dist/components/ui/search-field.d.ts.map +1 -0
  253. package/dist/components/ui/search-field.js +64 -0
  254. package/dist/components/ui/segmented-control.d.ts +21 -0
  255. package/dist/components/ui/segmented-control.d.ts.map +1 -0
  256. package/dist/components/ui/segmented-control.js +62 -0
  257. package/dist/components/ui/sheet.d.ts +4 -2
  258. package/dist/components/ui/sheet.d.ts.map +1 -1
  259. package/dist/components/ui/sheet.js +12 -9
  260. package/dist/components/ui/sidebar.js +1 -1
  261. package/dist/components/ui/sonner.d.ts +4 -3
  262. package/dist/components/ui/sonner.d.ts.map +1 -1
  263. package/dist/components/ui/sonner.js +7 -6
  264. package/dist/components/ui/split-view.d.ts +11 -0
  265. package/dist/components/ui/split-view.d.ts.map +1 -0
  266. package/dist/components/ui/split-view.js +13 -0
  267. package/dist/components/ui/status.d.ts +13 -0
  268. package/dist/components/ui/status.d.ts.map +1 -0
  269. package/dist/components/ui/status.js +36 -0
  270. package/dist/components/ui/table.d.ts +11 -2
  271. package/dist/components/ui/table.d.ts.map +1 -1
  272. package/dist/components/ui/table.js +33 -6
  273. package/dist/components/ui/text.d.ts +17 -0
  274. package/dist/components/ui/text.d.ts.map +1 -0
  275. package/dist/components/ui/text.js +55 -0
  276. package/dist/components/ui/toggle.d.ts +12 -4
  277. package/dist/components/ui/toggle.d.ts.map +1 -1
  278. package/dist/components/ui/toggle.js +13 -2
  279. package/dist/components/ui/toolbar.d.ts +27 -0
  280. package/dist/components/ui/toolbar.d.ts.map +1 -0
  281. package/dist/components/ui/toolbar.js +71 -0
  282. package/dist/components/ui/tooltip.d.ts +8 -3
  283. package/dist/components/ui/tooltip.d.ts.map +1 -1
  284. package/dist/components/ui/tooltip.js +11 -6
  285. package/dist/index.d.ts +2 -2
  286. package/dist/index.d.ts.map +1 -1
  287. package/dist/index.js +4 -4
  288. package/dist/lib/frame-lifecycle.d.ts +29 -0
  289. package/dist/lib/frame-lifecycle.d.ts.map +1 -1
  290. package/dist/lib/frame-lifecycle.js +85 -0
  291. package/dist/lib/native-capabilities/access.d.ts +13 -0
  292. package/dist/lib/native-capabilities/access.d.ts.map +1 -0
  293. package/dist/lib/native-capabilities/access.js +53 -0
  294. package/dist/lib/native-capabilities/bluetooth-access.d.ts +14 -0
  295. package/dist/lib/native-capabilities/bluetooth-access.d.ts.map +1 -0
  296. package/dist/lib/native-capabilities/bluetooth-access.js +43 -0
  297. package/dist/lib/native-capabilities/bluetooth-connection.d.ts +19 -0
  298. package/dist/lib/native-capabilities/bluetooth-connection.d.ts.map +1 -0
  299. package/dist/lib/native-capabilities/bluetooth-connection.js +88 -0
  300. package/dist/lib/native-capabilities/bluetooth-gatt.d.ts +7 -0
  301. package/dist/lib/native-capabilities/bluetooth-gatt.d.ts.map +1 -0
  302. package/dist/lib/native-capabilities/bluetooth-gatt.js +77 -0
  303. package/dist/lib/native-capabilities/bluetooth-internal.d.ts +10 -0
  304. package/dist/lib/native-capabilities/bluetooth-internal.d.ts.map +1 -0
  305. package/dist/lib/native-capabilities/bluetooth-internal.js +105 -0
  306. package/dist/lib/native-capabilities/bluetooth-native-fallback.d.ts +33 -0
  307. package/dist/lib/native-capabilities/bluetooth-native-fallback.d.ts.map +1 -0
  308. package/dist/lib/native-capabilities/bluetooth-native-fallback.js +214 -0
  309. package/dist/lib/native-capabilities/bluetooth-types.d.ts +85 -0
  310. package/dist/lib/native-capabilities/bluetooth-types.d.ts.map +1 -0
  311. package/dist/lib/native-capabilities/bluetooth-types.js +2 -0
  312. package/dist/lib/native-capabilities/bluetooth.d.ts +7 -0
  313. package/dist/lib/native-capabilities/bluetooth.d.ts.map +1 -0
  314. package/dist/lib/native-capabilities/bluetooth.js +4 -0
  315. package/dist/lib/native-capabilities/bridge.d.ts +23 -0
  316. package/dist/lib/native-capabilities/bridge.d.ts.map +1 -0
  317. package/dist/lib/native-capabilities/bridge.js +266 -0
  318. package/dist/lib/native-capabilities/capabilities.d.ts +7 -0
  319. package/dist/lib/native-capabilities/capabilities.d.ts.map +1 -0
  320. package/dist/lib/native-capabilities/capabilities.js +95 -0
  321. package/dist/lib/native-capabilities/clipboard.d.ts +11 -0
  322. package/dist/lib/native-capabilities/clipboard.d.ts.map +1 -0
  323. package/dist/lib/native-capabilities/clipboard.js +58 -0
  324. package/dist/lib/native-capabilities/device-io-errors.d.ts +11 -0
  325. package/dist/lib/native-capabilities/device-io-errors.d.ts.map +1 -0
  326. package/dist/lib/native-capabilities/device-io-errors.js +82 -0
  327. package/dist/lib/native-capabilities/displays.d.ts +38 -0
  328. package/dist/lib/native-capabilities/displays.d.ts.map +1 -0
  329. package/dist/lib/native-capabilities/displays.js +12 -0
  330. package/dist/lib/native-capabilities/global-shortcuts.d.ts +86 -0
  331. package/dist/lib/native-capabilities/global-shortcuts.d.ts.map +1 -0
  332. package/dist/lib/native-capabilities/global-shortcuts.js +351 -0
  333. package/dist/lib/native-capabilities/haptics.d.ts +25 -0
  334. package/dist/lib/native-capabilities/haptics.d.ts.map +1 -0
  335. package/dist/lib/native-capabilities/haptics.js +18 -0
  336. package/dist/lib/native-capabilities/hid-native.d.ts +26 -0
  337. package/dist/lib/native-capabilities/hid-native.d.ts.map +1 -0
  338. package/dist/lib/native-capabilities/hid-native.js +229 -0
  339. package/dist/lib/native-capabilities/hid.d.ts +52 -0
  340. package/dist/lib/native-capabilities/hid.d.ts.map +1 -0
  341. package/dist/lib/native-capabilities/hid.js +163 -0
  342. package/dist/lib/native-capabilities/index.d.ts +40 -0
  343. package/dist/lib/native-capabilities/index.d.ts.map +1 -0
  344. package/dist/lib/native-capabilities/index.js +21 -0
  345. package/dist/lib/native-capabilities/local-authentication.d.ts +32 -0
  346. package/dist/lib/native-capabilities/local-authentication.d.ts.map +1 -0
  347. package/dist/lib/native-capabilities/local-authentication.js +46 -0
  348. package/dist/lib/native-capabilities/location.d.ts +49 -0
  349. package/dist/lib/native-capabilities/location.d.ts.map +1 -0
  350. package/dist/lib/native-capabilities/location.js +114 -0
  351. package/dist/lib/native-capabilities/media-permissions.d.ts +28 -0
  352. package/dist/lib/native-capabilities/media-permissions.d.ts.map +1 -0
  353. package/dist/lib/native-capabilities/media-permissions.js +37 -0
  354. package/dist/lib/native-capabilities/media.d.ts +17 -0
  355. package/dist/lib/native-capabilities/media.d.ts.map +1 -0
  356. package/dist/lib/native-capabilities/media.js +104 -0
  357. package/dist/lib/native-capabilities/midi-access.d.ts +13 -0
  358. package/dist/lib/native-capabilities/midi-access.d.ts.map +1 -0
  359. package/dist/lib/native-capabilities/midi-access.js +68 -0
  360. package/dist/lib/native-capabilities/midi-internal.d.ts +12 -0
  361. package/dist/lib/native-capabilities/midi-internal.d.ts.map +1 -0
  362. package/dist/lib/native-capabilities/midi-internal.js +88 -0
  363. package/dist/lib/native-capabilities/midi-native-fallback.d.ts +27 -0
  364. package/dist/lib/native-capabilities/midi-native-fallback.d.ts.map +1 -0
  365. package/dist/lib/native-capabilities/midi-native-fallback.js +127 -0
  366. package/dist/lib/native-capabilities/midi-ports.d.ts +6 -0
  367. package/dist/lib/native-capabilities/midi-ports.d.ts.map +1 -0
  368. package/dist/lib/native-capabilities/midi-ports.js +115 -0
  369. package/dist/lib/native-capabilities/midi-types.d.ts +25 -0
  370. package/dist/lib/native-capabilities/midi-types.d.ts.map +1 -0
  371. package/dist/lib/native-capabilities/midi-types.js +1 -0
  372. package/dist/lib/native-capabilities/midi.d.ts +6 -0
  373. package/dist/lib/native-capabilities/midi.d.ts.map +1 -0
  374. package/dist/lib/native-capabilities/midi.js +3 -0
  375. package/dist/lib/native-capabilities/native-device-io.d.ts +28 -0
  376. package/dist/lib/native-capabilities/native-device-io.d.ts.map +1 -0
  377. package/dist/lib/native-capabilities/native-device-io.js +91 -0
  378. package/dist/lib/native-capabilities/native-device-lifecycle.d.ts +13 -0
  379. package/dist/lib/native-capabilities/native-device-lifecycle.d.ts.map +1 -0
  380. package/dist/lib/native-capabilities/native-device-lifecycle.js +40 -0
  381. package/dist/lib/native-capabilities/notifications.d.ts +38 -0
  382. package/dist/lib/native-capabilities/notifications.d.ts.map +1 -0
  383. package/dist/lib/native-capabilities/notifications.js +50 -0
  384. package/dist/lib/native-capabilities/power-session.d.ts +113 -0
  385. package/dist/lib/native-capabilities/power-session.d.ts.map +1 -0
  386. package/dist/lib/native-capabilities/power-session.js +264 -0
  387. package/dist/lib/native-capabilities/secure-storage.d.ts +36 -0
  388. package/dist/lib/native-capabilities/secure-storage.d.ts.map +1 -0
  389. package/dist/lib/native-capabilities/secure-storage.js +64 -0
  390. package/dist/lib/native-capabilities/serial-native.d.ts +23 -0
  391. package/dist/lib/native-capabilities/serial-native.d.ts.map +1 -0
  392. package/dist/lib/native-capabilities/serial-native.js +181 -0
  393. package/dist/lib/native-capabilities/serial.d.ts +76 -0
  394. package/dist/lib/native-capabilities/serial.d.ts.map +1 -0
  395. package/dist/lib/native-capabilities/serial.js +215 -0
  396. package/dist/lib/native-capabilities/system-audio.d.ts +127 -0
  397. package/dist/lib/native-capabilities/system-audio.d.ts.map +1 -0
  398. package/dist/lib/native-capabilities/system-audio.js +330 -0
  399. package/dist/lib/native-capabilities/types.d.ts +62 -0
  400. package/dist/lib/native-capabilities/types.d.ts.map +1 -0
  401. package/dist/lib/native-capabilities/types.js +27 -0
  402. package/dist/lib/native-capabilities/usb-native.d.ts +39 -0
  403. package/dist/lib/native-capabilities/usb-native.d.ts.map +1 -0
  404. package/dist/lib/native-capabilities/usb-native.js +217 -0
  405. package/dist/lib/native-capabilities/usb.d.ts +85 -0
  406. package/dist/lib/native-capabilities/usb.d.ts.map +1 -0
  407. package/dist/lib/native-capabilities/usb.js +225 -0
  408. package/dist/lib/theme.d.ts.map +1 -1
  409. package/dist/lib/theme.js +2 -1
  410. package/docs/README.md +39 -0
  411. package/docs/accessibility.md +32 -0
  412. package/docs/adaptive-materials.md +79 -0
  413. package/docs/app-anatomy.md +74 -0
  414. package/docs/component-catalog.md +82 -0
  415. package/docs/component-guide-template.md +37 -0
  416. package/docs/design-tokens.md +185 -0
  417. package/docs/foundations.md +58 -0
  418. package/docs/native-integration.md +33 -0
  419. package/docs/standalone-app-windows.md +136 -0
  420. package/package.json +8 -3
  421. package/src/components/ui/alert-dialog.md +31 -0
  422. package/src/components/ui/alert.md +77 -0
  423. package/src/components/ui/app-frame.md +38 -0
  424. package/src/components/ui/badge.md +57 -0
  425. package/src/components/ui/button.md +76 -0
  426. package/src/components/ui/collapsible.md +52 -0
  427. package/src/components/ui/color-well.md +11 -0
  428. package/src/components/ui/combobox.md +42 -0
  429. package/src/components/ui/command.md +54 -0
  430. package/src/components/ui/date-field.md +32 -0
  431. package/src/components/ui/date-picker.md +55 -0
  432. package/src/components/ui/dialog.md +40 -0
  433. package/src/components/ui/edge-fade.md +7 -0
  434. package/src/components/ui/empty.md +87 -0
  435. package/src/components/ui/field.md +77 -0
  436. package/src/components/ui/grid.md +109 -0
  437. package/src/components/ui/icon-button.md +36 -0
  438. package/src/components/ui/inspector.md +11 -0
  439. package/src/components/ui/item.md +87 -0
  440. package/src/components/ui/list.md +140 -0
  441. package/src/components/ui/material.md +51 -0
  442. package/src/components/ui/navigation-button-group.md +46 -0
  443. package/src/components/ui/notification-dot.md +7 -0
  444. package/src/components/ui/number-input.md +19 -0
  445. package/src/components/ui/panel.md +11 -0
  446. package/src/components/ui/popover.md +31 -0
  447. package/src/components/ui/resizable.md +66 -0
  448. package/src/components/ui/scroll-area.md +72 -0
  449. package/src/components/ui/search-field.md +33 -0
  450. package/src/components/ui/segmented-control.md +36 -0
  451. package/src/components/ui/sheet.md +30 -0
  452. package/src/components/ui/sidebar.md +113 -0
  453. package/src/components/ui/sonner.md +37 -0
  454. package/src/components/ui/split-view.md +15 -0
  455. package/src/components/ui/status.md +12 -0
  456. package/src/components/ui/table.md +37 -0
  457. package/src/components/ui/tabs.md +66 -0
  458. package/src/components/ui/text.md +17 -0
  459. package/src/components/ui/toggle-button.md +48 -0
  460. package/src/components/ui/toggle-group.md +80 -0
  461. package/src/components/ui/toggle.md +73 -0
  462. package/src/components/ui/toolbar.md +26 -0
  463. package/src/components/ui/tooltip.md +31 -0
  464. package/src/styles/index.css +704 -3
@@ -0,0 +1,124 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Bell, Send } from 'lucide-react';
4
+ import { useCallback, useEffect, useRef, useState } from 'react';
5
+ import { NATIVE_NOTIFICATION_MAX_BODY_LENGTH, NATIVE_NOTIFICATION_MAX_TAG_LENGTH, NATIVE_NOTIFICATION_MAX_TITLE_LENGTH, getMoldableNotificationPermission, requestMoldableNotificationPermission, sendMoldableNotification, } from '../../lib/native-capabilities';
6
+ import { Button } from '../ui/button';
7
+ import { Input } from '../ui/input';
8
+ import { Spinner } from '../ui/spinner';
9
+ import { Switch } from '../ui/switch';
10
+ import { CapabilityBadge } from './capability-badge';
11
+ import { NativeCapabilityPanel, NativeCapabilityPanelAction, NativeCapabilityPanelContent, NativeCapabilityPanelFooter, NativeCapabilityPanelHeader, NativeCapabilityPanelIcon, NativeCapabilityPanelTitle, } from './native-capability-panel';
12
+ import { useMoldableCapability, } from './use-capability';
13
+ /**
14
+ * Notification state machine behind `NotificationsPanel`: permission loading,
15
+ * explicit permission requests, and sends with the library's length limits
16
+ * enforced by truncation.
17
+ */
18
+ export function useMoldableNotifications() {
19
+ const [permission, setPermission] = useState('unknown');
20
+ const [status, setStatus] = useState('idle');
21
+ const [sentAt, setSentAt] = useState(null);
22
+ const [error, setError] = useState(null);
23
+ const tokenRef = useRef(0);
24
+ useEffect(() => {
25
+ let live = true;
26
+ getMoldableNotificationPermission()
27
+ .then((result) => {
28
+ if (live)
29
+ setPermission(result.permission);
30
+ })
31
+ .catch(() => {
32
+ // Best-effort: outside Moldable the permission stays unknown.
33
+ });
34
+ return () => {
35
+ live = false;
36
+ };
37
+ }, []);
38
+ const request = useCallback(async () => {
39
+ const token = ++tokenRef.current;
40
+ try {
41
+ const result = await requestMoldableNotificationPermission();
42
+ if (tokenRef.current !== token)
43
+ return null;
44
+ setPermission(result.permission);
45
+ return result.permission;
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ }, []);
51
+ const send = useCallback(async (options) => {
52
+ const token = ++tokenRef.current;
53
+ setStatus('sending');
54
+ setError(null);
55
+ try {
56
+ await sendMoldableNotification({
57
+ ...options,
58
+ title: options.title.slice(0, NATIVE_NOTIFICATION_MAX_TITLE_LENGTH),
59
+ body: options.body?.slice(0, NATIVE_NOTIFICATION_MAX_BODY_LENGTH),
60
+ tag: options.tag?.slice(0, NATIVE_NOTIFICATION_MAX_TAG_LENGTH),
61
+ });
62
+ if (tokenRef.current !== token)
63
+ return false;
64
+ setSentAt(Date.now());
65
+ setStatus('sent');
66
+ return true;
67
+ }
68
+ catch (cause) {
69
+ if (tokenRef.current !== token)
70
+ return false;
71
+ setError(cause instanceof Error ? cause : new Error(String(cause)));
72
+ setStatus('error');
73
+ return false;
74
+ }
75
+ }, []);
76
+ useEffect(() => () => {
77
+ tokenRef.current++;
78
+ }, []);
79
+ return { permission, status, sentAt, error, request, send };
80
+ }
81
+ const PERMISSION_CHIP = {
82
+ granted: { status: 'supported', label: 'Granted' },
83
+ prompt: { status: 'partial', label: 'Not requested' },
84
+ denied: { status: 'unsupported', label: 'Denied' },
85
+ };
86
+ function formatClock(timestamp) {
87
+ const date = new Date(timestamp);
88
+ const pad = (value) => value.toString().padStart(2, '0');
89
+ return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
90
+ }
91
+ /**
92
+ * Notification composer panel: permission chip with an inline allow flow, a
93
+ * compact title/body/silent composer, and delivery feedback.
94
+ */
95
+ function NotificationsPanel({ className, ...props }) {
96
+ const notifications = useMoldableNotifications();
97
+ const capability = useMoldableCapability('notifications');
98
+ const [title, setTitle] = useState('Hello from Moldable');
99
+ const [body, setBody] = useState('');
100
+ const [silent, setSilent] = useState(false);
101
+ const [requesting, setRequesting] = useState(false);
102
+ const sending = notifications.status === 'sending';
103
+ const canSend = title.trim().length > 0 && !sending;
104
+ const sendNotification = async () => {
105
+ await notifications.send({
106
+ title,
107
+ body: body.trim().length > 0 ? body : undefined,
108
+ tag: 'moldable-native-capabilities',
109
+ silent,
110
+ });
111
+ };
112
+ const requestPermission = async () => {
113
+ setRequesting(true);
114
+ await notifications.request();
115
+ setRequesting(false);
116
+ };
117
+ const chip = notifications.permission === 'unknown'
118
+ ? null
119
+ : PERMISSION_CHIP[notifications.permission];
120
+ return (_jsxs(NativeCapabilityPanel, { "data-slot": "notifications-panel", "data-status": notifications.status, "data-permission": notifications.permission, className: className, ...props, children: [_jsxs(NativeCapabilityPanelHeader, { children: [_jsx(NativeCapabilityPanelIcon, { children: _jsx(Bell, {}) }), _jsx(NativeCapabilityPanelTitle, { children: "Notifications" }), _jsx(CapabilityBadge, { capability: "notifications" }), _jsx(NativeCapabilityPanelAction, { children: notifications.permission === 'prompt' ? (_jsxs(Button, { size: "sm", variant: "outline", disabled: requesting, onClick: () => void requestPermission(), children: [requesting ? _jsx(Spinner, {}) : null, "Allow"] })) : chip ? (_jsx(CapabilityBadge, { status: chip.status, label: chip.label })) : null })] }), _jsxs(NativeCapabilityPanelContent, { className: "space-y-3", children: [_jsxs("div", { className: "grid gap-2", children: [_jsx(Input, { value: title, maxLength: NATIVE_NOTIFICATION_MAX_TITLE_LENGTH, placeholder: "Title", "aria-label": "Notification title", onChange: (event) => setTitle(event.target.value) }), _jsx(Input, { value: body, maxLength: NATIVE_NOTIFICATION_MAX_BODY_LENGTH, placeholder: "Body (optional)", "aria-label": "Notification body", onChange: (event) => setBody(event.target.value) })] }), _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("label", { className: "text-muted-foreground flex items-center gap-2 text-xs", children: [_jsx(Switch, { size: "sm", checked: silent, onCheckedChange: setSilent }), "Silent"] }), _jsxs(Button, { size: "sm", disabled: !canSend, onClick: () => void sendNotification(), children: [sending ? _jsx(Spinner, {}) : _jsx(Send, {}), "Send notification"] })] }), notifications.status === 'sent' && notifications.sentAt !== null ? (_jsxs("p", { className: "text-success animate-in fade-in font-mono text-xs tabular-nums duration-300 motion-reduce:animate-none", children: ["Delivered ", formatClock(notifications.sentAt)] })) : notifications.status === 'error' ? (_jsx("p", { className: "text-status-error text-xs", children: notifications.error?.message ??
121
+ 'The notification could not be sent.' })) : null] }), _jsx(NativeCapabilityPanelFooter, { children: _jsx("span", { className: "truncate", children: capability.descriptor?.reason ??
122
+ 'Notifications appear via the OS notification center.' }) })] }));
123
+ }
124
+ export { NotificationsPanel };
@@ -0,0 +1,19 @@
1
+ import { type MoldableSleepBlocker, type MoldableSleepBlockerType } from '../../lib/native-capabilities';
2
+ type StartSleepBlocker = (type: MoldableSleepBlockerType) => Promise<MoldableSleepBlocker>;
3
+ declare const BLOCKER_TYPES: readonly ["prevent-display-sleep", "prevent-app-suspension"];
4
+ /**
5
+ * Owns sleep-blocker handles independently from React state. Handles are only
6
+ * discarded after the host confirms they stopped, so a failed cleanup remains
7
+ * retryable.
8
+ */
9
+ export declare class MoldableSleepBlockerController {
10
+ #private;
11
+ private readonly startSleepBlocker;
12
+ constructor(startSleepBlocker?: StartSleepBlocker);
13
+ has(type: MoldableSleepBlockerType): boolean;
14
+ toggle(type: MoldableSleepBlockerType): Promise<boolean>;
15
+ check(type: MoldableSleepBlockerType): Promise<boolean>;
16
+ stopAll(): Promise<void>;
17
+ }
18
+ export { BLOCKER_TYPES };
19
+ //# sourceMappingURL=power-blocker-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"power-blocker-controller.d.ts","sourceRoot":"","sources":["../../../src/components/native-capabilities/power-blocker-controller.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAE9B,MAAM,+BAA+B,CAAA;AAEtC,KAAK,iBAAiB,GAAG,CACvB,IAAI,EAAE,wBAAwB,KAC3B,OAAO,CAAC,oBAAoB,CAAC,CAAA;AAElC,QAAA,MAAM,aAAa,8DAGqC,CAAA;AAExD;;;;GAIG;AACH,qBAAa,8BAA8B;;IAkBvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAAjB,iBAAiB,GAAE,iBAA6C;IAGnF,GAAG,CAAC,IAAI,EAAE,wBAAwB,GAAG,OAAO;IAI5C,MAAM,CAAC,IAAI,EAAE,wBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBxD,KAAK,CAAC,IAAI,EAAE,wBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC;IAYjD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CA+B/B;AAED,OAAO,EAAE,aAAa,EAAE,CAAA"}
@@ -0,0 +1,83 @@
1
+ import { startMoldableSleepBlocker, } from '../../lib/native-capabilities';
2
+ const BLOCKER_TYPES = [
3
+ 'prevent-display-sleep',
4
+ 'prevent-app-suspension',
5
+ ];
6
+ /**
7
+ * Owns sleep-blocker handles independently from React state. Handles are only
8
+ * discarded after the host confirms they stopped, so a failed cleanup remains
9
+ * retryable.
10
+ */
11
+ export class MoldableSleepBlockerController {
12
+ startSleepBlocker;
13
+ #handles = {
14
+ 'prevent-display-sleep': null,
15
+ 'prevent-app-suspension': null,
16
+ };
17
+ #operations = {
18
+ 'prevent-display-sleep': null,
19
+ 'prevent-app-suspension': null,
20
+ };
21
+ constructor(startSleepBlocker = startMoldableSleepBlocker) {
22
+ this.startSleepBlocker = startSleepBlocker;
23
+ }
24
+ has(type) {
25
+ return this.#handles[type] !== null;
26
+ }
27
+ toggle(type) {
28
+ return this.#enqueue(type, async () => {
29
+ const current = this.#handles[type];
30
+ if (current) {
31
+ await current.stop();
32
+ if (this.#handles[type] === current)
33
+ this.#handles[type] = null;
34
+ return false;
35
+ }
36
+ const blocker = await this.startSleepBlocker(type);
37
+ this.#handles[type] = blocker;
38
+ const started = await blocker.isStarted();
39
+ if (!started && this.#handles[type] === blocker) {
40
+ this.#handles[type] = null;
41
+ }
42
+ return started;
43
+ });
44
+ }
45
+ check(type) {
46
+ return this.#enqueue(type, async () => {
47
+ const blocker = this.#handles[type];
48
+ if (!blocker)
49
+ return false;
50
+ const started = await blocker.isStarted();
51
+ if (!started && this.#handles[type] === blocker) {
52
+ this.#handles[type] = null;
53
+ }
54
+ return started;
55
+ });
56
+ }
57
+ async stopAll() {
58
+ const results = await Promise.allSettled(BLOCKER_TYPES.map((type) => this.#enqueue(type, async () => {
59
+ const blocker = this.#handles[type];
60
+ if (!blocker)
61
+ return;
62
+ await blocker.stop();
63
+ if (this.#handles[type] === blocker)
64
+ this.#handles[type] = null;
65
+ })));
66
+ const failed = results.find((result) => result.status === 'rejected');
67
+ if (failed)
68
+ throw failed.reason;
69
+ }
70
+ #enqueue(type, operation) {
71
+ const previous = this.#operations[type] ?? Promise.resolve();
72
+ const current = previous.catch(() => undefined).then(operation);
73
+ this.#operations[type] = current;
74
+ void current
75
+ .finally(() => {
76
+ if (this.#operations[type] === current)
77
+ this.#operations[type] = null;
78
+ })
79
+ .catch(() => undefined);
80
+ return current;
81
+ }
82
+ }
83
+ export { BLOCKER_TYPES };
@@ -0,0 +1,67 @@
1
+ import * as React from 'react';
2
+ import { type MoldablePowerSessionEvent, type MoldablePowerState, type MoldableSleepBlockerType, type MoldableSystemIdleState, type MoldableThermalState } from '../../lib/native-capabilities';
3
+ export interface MoldablePowerSessionLogEntry {
4
+ /** Monotonic id, stable across the rolling window. */
5
+ id: number;
6
+ /** Epoch millis parsed from the event's `occurredAt`. */
7
+ timestamp: number;
8
+ event: MoldablePowerSessionEvent;
9
+ }
10
+ export interface MoldablePowerIdleSnapshot {
11
+ state: MoldableSystemIdleState;
12
+ seconds: number;
13
+ }
14
+ export interface UseMoldablePowerOptions {
15
+ /** Poll cadence for power/thermal/idle state. Defaults to 30 000 ms. */
16
+ pollIntervalMs?: number;
17
+ }
18
+ /**
19
+ * Power/session state machine behind `PowerPanel`: polled power + thermal +
20
+ * idle state, live session events, and a managed sleep blocker. Every native
21
+ * failure degrades to nulls so it is safe outside Moldable.
22
+ */
23
+ export declare function useMoldablePower(options?: UseMoldablePowerOptions): {
24
+ power: MoldablePowerState | null;
25
+ thermal: MoldableThermalState | null;
26
+ idle: MoldablePowerIdleSnapshot | null;
27
+ events: MoldablePowerSessionLogEntry[];
28
+ updatedAt: number | null;
29
+ error: Error | null;
30
+ refresh: () => void;
31
+ sleepBlocker: {
32
+ active: boolean;
33
+ type: "prevent-display-sleep" | null;
34
+ toggle: (type?: MoldableSleepBlockerType) => Promise<void>;
35
+ };
36
+ sleepBlockers: Record<MoldableSleepBlockerType, {
37
+ active: boolean;
38
+ busy: boolean;
39
+ toggle: () => Promise<void>;
40
+ check: () => Promise<void>;
41
+ }>;
42
+ };
43
+ export interface BatteryGaugeProps extends React.ComponentProps<'span'> {
44
+ /** Controlled charge percent (0-100). Omit all data props to self-manage. */
45
+ percent?: number;
46
+ /** Controlled charging flag. */
47
+ charging?: boolean;
48
+ /** The machine has no battery — renders an AC power presentation. */
49
+ noBattery?: boolean;
50
+ }
51
+ /**
52
+ * Compact inline battery glyph + percent. Pass `percent`/`charging` (and
53
+ * optionally `noBattery`) to control it, or no data props to let it poll
54
+ * `useMoldablePower` itself.
55
+ */
56
+ declare function BatteryGauge({ percent, charging, noBattery, ...props }: BatteryGaugeProps): import("react/jsx-runtime").JSX.Element;
57
+ export interface PowerPanelProps extends React.ComponentProps<'div'> {
58
+ /** Poll cadence for power/thermal/idle state. Defaults to 30 000 ms. */
59
+ pollIntervalMs?: number;
60
+ }
61
+ /**
62
+ * Power panel: battery gauge, source/thermal/idle readout, live session event
63
+ * log, and a "keep awake" sleep-blocker switch.
64
+ */
65
+ declare function PowerPanel({ className, pollIntervalMs, ...props }: PowerPanelProps): import("react/jsx-runtime").JSX.Element;
66
+ export { PowerPanel, BatteryGauge };
67
+ //# sourceMappingURL=power-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"power-panel.d.ts","sourceRoot":"","sources":["../../../src/components/native-capabilities/power-panel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EAO1B,MAAM,+BAA+B,CAAA;AAuBtC,MAAM,WAAW,4BAA4B;IAC3C,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAA;IACV,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,yBAAyB,CAAA;CACjC;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,uBAAuB,CAAA;IAC9B,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAMD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B;;;;;;;;;;;wBA0HrD,wBAAwB;;mBAwEhC,MAAM,CACT,wBAAwB,EACxB;QACE,MAAM,EAAE,OAAO,CAAA;QACf,IAAI,EAAE,OAAO,CAAA;QACb,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;QAC3B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KAC3B,CACF;EAEJ;AA0DD,MAAM,WAAW,iBAAkB,SAAQ,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC;IACrE,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AA2DD;;;;GAIG;AACH,iBAAS,YAAY,CAAC,EACpB,OAAO,EACP,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,iBAAiB,2CAgBnB;AAsCD,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IAClE,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;GAGG;AACH,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,2CA0J3E;AAED,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAA"}
@@ -0,0 +1,309 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { BatteryCharging, Plug, RefreshCw, Zap } from 'lucide-react';
4
+ import { useCallback, useEffect, useRef, useState } from 'react';
5
+ import { getMoldableCurrentThermalState, getMoldablePowerState, getMoldableSystemIdleState, getMoldableSystemIdleTime, watchMoldablePowerSession, } from '../../lib/native-capabilities';
6
+ import { cn } from '../../lib/utils';
7
+ import { Button } from '../ui/button';
8
+ import { Switch } from '../ui/switch';
9
+ import { CapabilityBadge } from './capability-badge';
10
+ import { NativeCapabilityPanel, NativeCapabilityPanelAction, NativeCapabilityPanelContent, NativeCapabilityPanelFooter, NativeCapabilityPanelHeader, NativeCapabilityPanelIcon, NativeCapabilityPanelTitle, } from './native-capability-panel';
11
+ import { BLOCKER_TYPES, MoldableSleepBlockerController, } from './power-blocker-controller';
12
+ import { Readout, ReadoutItem } from './readout';
13
+ import { StreamLog, useStreamLog } from './stream-log';
14
+ const MAX_POWER_EVENTS = 100;
15
+ function toError(cause) {
16
+ return cause instanceof Error ? cause : new Error(String(cause));
17
+ }
18
+ /**
19
+ * Power/session state machine behind `PowerPanel`: polled power + thermal +
20
+ * idle state, live session events, and a managed sleep blocker. Every native
21
+ * failure degrades to nulls so it is safe outside Moldable.
22
+ */
23
+ export function useMoldablePower(options = {}) {
24
+ const { pollIntervalMs = 30_000 } = options;
25
+ const [power, setPower] = useState(null);
26
+ const [thermal, setThermal] = useState(null);
27
+ const [idle, setIdle] = useState(null);
28
+ const [events, setEvents] = useState([]);
29
+ const [updatedAt, setUpdatedAt] = useState(null);
30
+ const [error, setError] = useState(null);
31
+ const [blockerActive, setBlockerActive] = useState({
32
+ 'prevent-display-sleep': false,
33
+ 'prevent-app-suspension': false,
34
+ });
35
+ const [blockerBusy, setBlockerBusy] = useState({
36
+ 'prevent-display-sleep': false,
37
+ 'prevent-app-suspension': false,
38
+ });
39
+ const generationRef = useRef(0);
40
+ const eventIdRef = useRef(0);
41
+ const mountedRef = useRef(true);
42
+ const blockerControllerRef = useRef(null);
43
+ blockerControllerRef.current ??= new MoldableSleepBlockerController();
44
+ const refresh = useCallback(() => {
45
+ const generation = ++generationRef.current;
46
+ void Promise.allSettled([
47
+ getMoldablePowerState(),
48
+ getMoldableCurrentThermalState(),
49
+ getMoldableSystemIdleState(60),
50
+ getMoldableSystemIdleTime(),
51
+ ]).then(([powerResult, thermalResult, idleStateResult, idleTimeResult]) => {
52
+ if (generationRef.current !== generation)
53
+ return;
54
+ setPower(powerResult.status === 'fulfilled' ? powerResult.value : null);
55
+ setThermal(thermalResult.status === 'fulfilled' ? thermalResult.value : null);
56
+ setIdle(idleStateResult.status === 'fulfilled'
57
+ ? {
58
+ state: idleStateResult.value.state,
59
+ seconds: idleTimeResult.status === 'fulfilled'
60
+ ? idleTimeResult.value
61
+ : idleStateResult.value.seconds,
62
+ }
63
+ : null);
64
+ const failed = [
65
+ powerResult,
66
+ thermalResult,
67
+ idleStateResult,
68
+ idleTimeResult,
69
+ ].find((result) => result.status === 'rejected');
70
+ setError(failed ? toError(failed.reason) : null);
71
+ setUpdatedAt(Date.now());
72
+ });
73
+ }, []);
74
+ useEffect(() => {
75
+ refresh();
76
+ const interval = window.setInterval(refresh, Math.max(1000, pollIntervalMs));
77
+ const liveGeneration = generationRef;
78
+ return () => {
79
+ window.clearInterval(interval);
80
+ liveGeneration.current++;
81
+ };
82
+ }, [pollIntervalMs, refresh]);
83
+ useEffect(() => {
84
+ let cancelled = false;
85
+ let stopWatching = null;
86
+ watchMoldablePowerSession((event) => {
87
+ if (cancelled)
88
+ return;
89
+ const parsed = Date.parse(event.occurredAt);
90
+ const entry = {
91
+ id: ++eventIdRef.current,
92
+ timestamp: Number.isNaN(parsed) ? Date.now() : parsed,
93
+ event,
94
+ };
95
+ setEvents((previous) => {
96
+ const next = [...previous, entry];
97
+ return next.length > MAX_POWER_EVENTS
98
+ ? next.slice(next.length - MAX_POWER_EVENTS)
99
+ : next;
100
+ });
101
+ if (event.kind === 'power-source-change')
102
+ setPower(event.powerState);
103
+ if (event.kind === 'thermal-state-change')
104
+ setThermal(event.state);
105
+ })
106
+ .then((stop) => {
107
+ if (cancelled) {
108
+ // Unmounted before the subscription resolved — stop immediately.
109
+ void stop().catch(() => undefined);
110
+ return;
111
+ }
112
+ stopWatching = stop;
113
+ })
114
+ .catch(() => {
115
+ // Session events are unavailable outside Moldable.
116
+ });
117
+ return () => {
118
+ cancelled = true;
119
+ if (stopWatching)
120
+ void stopWatching().catch(() => undefined);
121
+ };
122
+ }, []);
123
+ useEffect(() => {
124
+ mountedRef.current = true;
125
+ const liveMounted = mountedRef;
126
+ const controller = blockerControllerRef.current;
127
+ return () => {
128
+ liveMounted.current = false;
129
+ if (controller)
130
+ void controller.stopAll().catch(() => undefined);
131
+ };
132
+ }, []);
133
+ const toggleSleepBlocker = useCallback(async (type = 'prevent-display-sleep') => {
134
+ const controller = blockerControllerRef.current;
135
+ if (!controller)
136
+ return;
137
+ setBlockerBusy((previous) => ({ ...previous, [type]: true }));
138
+ try {
139
+ const active = await controller.toggle(type);
140
+ if (!mountedRef.current)
141
+ return;
142
+ setBlockerActive((previous) => ({ ...previous, [type]: active }));
143
+ setError(null);
144
+ }
145
+ catch (cause) {
146
+ if (!mountedRef.current)
147
+ return;
148
+ setBlockerActive((previous) => ({
149
+ ...previous,
150
+ [type]: controller.has(type),
151
+ }));
152
+ setError(toError(cause));
153
+ }
154
+ finally {
155
+ if (mountedRef.current) {
156
+ setBlockerBusy((previous) => ({ ...previous, [type]: false }));
157
+ }
158
+ }
159
+ }, []);
160
+ const checkSleepBlocker = useCallback(async (type) => {
161
+ const controller = blockerControllerRef.current;
162
+ if (!controller)
163
+ return;
164
+ setBlockerBusy((previous) => ({ ...previous, [type]: true }));
165
+ try {
166
+ const active = await controller.check(type);
167
+ if (!mountedRef.current)
168
+ return;
169
+ setBlockerActive((previous) => ({ ...previous, [type]: active }));
170
+ setError(null);
171
+ }
172
+ catch (cause) {
173
+ if (!mountedRef.current)
174
+ return;
175
+ setError(toError(cause));
176
+ }
177
+ finally {
178
+ if (mountedRef.current) {
179
+ setBlockerBusy((previous) => ({ ...previous, [type]: false }));
180
+ }
181
+ }
182
+ }, []);
183
+ return {
184
+ power,
185
+ thermal,
186
+ idle,
187
+ events,
188
+ updatedAt,
189
+ error,
190
+ refresh,
191
+ sleepBlocker: {
192
+ active: blockerActive['prevent-display-sleep'],
193
+ type: blockerActive['prevent-display-sleep']
194
+ ? 'prevent-display-sleep'
195
+ : null,
196
+ toggle: toggleSleepBlocker,
197
+ },
198
+ sleepBlockers: Object.fromEntries(BLOCKER_TYPES.map((type) => [
199
+ type,
200
+ {
201
+ active: blockerActive[type],
202
+ busy: blockerBusy[type],
203
+ toggle: () => toggleSleepBlocker(type),
204
+ check: () => checkSleepBlocker(type),
205
+ },
206
+ ])),
207
+ };
208
+ }
209
+ function BatteryGlyph({ percent, charging, className, }) {
210
+ const clamped = Math.max(0, Math.min(100, percent));
211
+ const fillClass = charging
212
+ ? 'text-status-running'
213
+ : clamped < 15
214
+ ? 'text-status-error'
215
+ : 'text-foreground';
216
+ return (_jsxs("svg", { viewBox: "0 0 28 14", "aria-hidden": true, className: cn('h-[1em] w-[2em] shrink-0', className), children: [_jsx("rect", { x: "1", y: "1.5", width: "23", height: "11", rx: "3", fill: "none", stroke: "currentColor", strokeWidth: "1.5", className: "opacity-50" }), _jsx("rect", { x: "25.5", y: "4.75", width: "2", height: "4.5", rx: "1", fill: "currentColor", className: "opacity-50" }), _jsx("rect", { x: "3.5", y: "4", width: (clamped / 100) * 18, height: "6", rx: "1.5", className: cn('fill-current transition-all duration-500 motion-reduce:transition-none', fillClass) })] }));
217
+ }
218
+ function BatteryGaugeBase({ percent, charging = false, noBattery = false, className, ...props }) {
219
+ return (_jsx("span", { "data-slot": "battery-gauge", "data-status": noBattery ? 'ac' : percent === undefined ? 'unknown' : 'battery', className: cn('inline-flex items-center gap-2 text-sm', className), ...props, children: noBattery ? (_jsxs(_Fragment, { children: [_jsx(Plug, { "aria-hidden": true, className: "text-muted-foreground size-[1.15em]" }), _jsx("span", { className: "font-mono tabular-nums", children: "AC power" })] })) : percent === undefined ? (_jsxs(_Fragment, { children: [_jsx(BatteryGlyph, { percent: 0, charging: false }), _jsx("span", { className: "text-muted-foreground/60 font-mono tabular-nums", children: "\u2014" })] })) : (_jsxs(_Fragment, { children: [_jsx(BatteryGlyph, { percent: percent, charging: charging }), _jsxs("span", { className: "font-mono tabular-nums", children: [Math.round(percent), "%"] }), charging ? (_jsx(Zap, { "aria-label": "Charging", className: "text-status-running size-3 fill-current" })) : null] })) }));
220
+ }
221
+ function ManagedBatteryGauge(props) {
222
+ const { power } = useMoldablePower();
223
+ const battery = power?.batteries[0] ?? null;
224
+ return (_jsx(BatteryGaugeBase, { percent: battery?.chargePercent, charging: battery?.state === 'charging', noBattery: power !== null && power.batteries.length === 0, ...props }));
225
+ }
226
+ /**
227
+ * Compact inline battery glyph + percent. Pass `percent`/`charging` (and
228
+ * optionally `noBattery`) to control it, or no data props to let it poll
229
+ * `useMoldablePower` itself.
230
+ */
231
+ function BatteryGauge({ percent, charging, noBattery, ...props }) {
232
+ if (percent === undefined &&
233
+ charging === undefined &&
234
+ noBattery === undefined) {
235
+ return _jsx(ManagedBatteryGauge, { ...props });
236
+ }
237
+ return (_jsx(BatteryGaugeBase, { percent: percent, charging: charging, noBattery: noBattery, ...props }));
238
+ }
239
+ const POWER_SOURCE_LABEL = {
240
+ ac: 'AC',
241
+ battery: 'Battery',
242
+ unknown: 'Unknown',
243
+ };
244
+ function capitalize(value) {
245
+ return value.charAt(0).toUpperCase() + value.slice(1);
246
+ }
247
+ function formatIdleSeconds(value) {
248
+ const seconds = Math.max(0, Math.floor(value));
249
+ if (seconds < 60)
250
+ return `${seconds}s`;
251
+ if (seconds < 3600)
252
+ return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
253
+ return `${Math.floor(seconds / 3600)}h ${Math.floor((seconds % 3600) / 60)}m`;
254
+ }
255
+ function formatClock(timestamp) {
256
+ return new Date(timestamp).toLocaleTimeString(undefined, { hour12: false });
257
+ }
258
+ function describePowerSessionEvent(event) {
259
+ switch (event.kind) {
260
+ case 'power-source-change':
261
+ return event.powerState.source === 'battery'
262
+ ? 'on-battery'
263
+ : event.powerState.source === 'ac'
264
+ ? 'on-ac'
265
+ : 'power-source-change';
266
+ case 'thermal-state-change':
267
+ return `thermal-${event.state}`;
268
+ default:
269
+ return event.kind;
270
+ }
271
+ }
272
+ /**
273
+ * Power panel: battery gauge, source/thermal/idle readout, live session event
274
+ * log, and a "keep awake" sleep-blocker switch.
275
+ */
276
+ function PowerPanel({ className, pollIntervalMs, ...props }) {
277
+ const power = useMoldablePower({ pollIntervalMs });
278
+ const log = useStreamLog(MAX_POWER_EVENTS);
279
+ const appendRef = useRef(log.append);
280
+ appendRef.current = log.append;
281
+ const lastEventIdRef = useRef(0);
282
+ const { events } = power;
283
+ useEffect(() => {
284
+ for (const entry of events) {
285
+ if (entry.id <= lastEventIdRef.current)
286
+ continue;
287
+ lastEventIdRef.current = entry.id;
288
+ appendRef.current({
289
+ id: entry.id,
290
+ timestamp: entry.timestamp,
291
+ direction: 'info',
292
+ data: describePowerSessionEvent(entry.event),
293
+ });
294
+ }
295
+ }, [events]);
296
+ const battery = power.power?.batteries[0] ?? null;
297
+ const noBattery = power.power !== null && power.power.batteries.length === 0;
298
+ const status = power.power !== null || power.thermal !== null
299
+ ? 'ready'
300
+ : power.error
301
+ ? 'unavailable'
302
+ : 'loading';
303
+ return (_jsxs(NativeCapabilityPanel, { "data-slot": "power-panel", "data-status": status, className: className, ...props, children: [_jsxs(NativeCapabilityPanelHeader, { children: [_jsx(NativeCapabilityPanelIcon, { children: _jsx(BatteryCharging, {}) }), _jsx(NativeCapabilityPanelTitle, { children: "Power" }), _jsx(CapabilityBadge, { capability: "power-monitor" }), _jsx(NativeCapabilityPanelAction, { children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("label", { className: "text-muted-foreground flex items-center gap-2 text-xs font-medium", children: ["Display", _jsx(Switch, { size: "sm", checked: power.sleepBlockers['prevent-display-sleep'].active, disabled: power.sleepBlockers['prevent-display-sleep'].busy, onCheckedChange: () => void power.sleepBlockers['prevent-display-sleep'].toggle(), "aria-label": "Keep the display awake" })] }), _jsxs("label", { className: "text-muted-foreground flex items-center gap-2 text-xs font-medium", children: ["App", _jsx(Switch, { size: "sm", checked: power.sleepBlockers['prevent-app-suspension'].active, disabled: power.sleepBlockers['prevent-app-suspension'].busy, onCheckedChange: () => void power.sleepBlockers['prevent-app-suspension'].toggle(), "aria-label": "Keep the app active" })] })] }) })] }), _jsx(NativeCapabilityPanelContent, { children: _jsxs("div", { className: "animate-in fade-in space-y-4 duration-300 motion-reduce:animate-none", children: [_jsx(BatteryGauge, { className: "text-xl font-medium tracking-tight sm:text-2xl", percent: battery?.chargePercent, charging: battery?.state === 'charging', noBattery: noBattery }), _jsxs(Readout, { className: "grid-cols-2 sm:grid-cols-4", children: [_jsx(ReadoutItem, { label: "Source", value: power.power ? POWER_SOURCE_LABEL[power.power.source] : null }), _jsx(ReadoutItem, { label: "State", value: battery ? capitalize(battery.state) : null }), _jsx(ReadoutItem, { label: "Thermal", value: power.thermal ? capitalize(power.thermal) : null }), _jsx(ReadoutItem, { label: "Idle", value: power.idle
304
+ ? `${formatIdleSeconds(power.idle.seconds)} · ${power.idle.state}`
305
+ : null })] }), power.error ? (_jsx("p", { className: "text-status-error text-xs", children: power.error.message })) : null, _jsxs("div", { className: "space-y-1.5", children: [_jsx("div", { className: "text-muted-foreground text-[10px] font-medium uppercase tracking-wider", children: "Session events" }), _jsx(StreamLog, { entries: log.entries, maxHeight: 160, emptyLabel: "No session events yet" })] })] }) }), _jsxs(NativeCapabilityPanelFooter, { children: [_jsx("span", { className: "truncate font-mono tabular-nums", children: power.updatedAt
306
+ ? `Updated ${formatClock(power.updatedAt)}`
307
+ : 'Waiting for first reading' }), _jsx(Button, { variant: "ghost", size: "icon-xs", "aria-label": "Refresh power state", className: "ml-auto", onClick: power.refresh, children: _jsx(RefreshCw, {}) }), _jsx(Button, { variant: "ghost", size: "xs", className: "gap-1", disabled: BLOCKER_TYPES.some((type) => power.sleepBlockers[type].busy), onClick: () => void Promise.all(BLOCKER_TYPES.map((type) => power.sleepBlockers[type].check())), children: "Check blockers" })] })] }));
308
+ }
309
+ export { PowerPanel, BatteryGauge };
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ declare function Readout({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
3
+ export interface ReadoutItemProps extends React.ComponentProps<'div'> {
4
+ label: React.ReactNode;
5
+ value?: React.ReactNode;
6
+ unit?: React.ReactNode;
7
+ }
8
+ declare function ReadoutItem({ label, value, unit, className, children, ...props }: ReadoutItemProps): import("react/jsx-runtime").JSX.Element;
9
+ export { Readout, ReadoutItem };
10
+ //# sourceMappingURL=readout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readout.d.ts","sourceRoot":"","sources":["../../../src/components/native-capabilities/readout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,iBAAS,OAAO,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAWpE;AAED,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IACnE,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACvB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACvB;AAED,iBAAS,WAAW,CAAC,EACnB,KAAK,EACL,KAAK,EACL,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,gBAAgB,2CA6BlB;AAED,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -0,0 +1,11 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { cn } from '../../lib/utils';
4
+ function Readout({ className, ...props }) {
5
+ return (_jsx("div", { "data-slot": "readout", className: cn('grid grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-3', className), ...props }));
6
+ }
7
+ function ReadoutItem({ label, value, unit, className, children, ...props }) {
8
+ const content = children ?? value;
9
+ return (_jsxs("div", { "data-slot": "readout-item", className: cn('min-w-0', className), ...props, children: [_jsx("div", { "data-slot": "readout-label", className: "text-muted-foreground text-[10px] font-medium uppercase tracking-wider", children: label }), _jsxs("div", { "data-slot": "readout-value", className: "mt-1 truncate font-mono text-sm tabular-nums", children: [content === null || content === undefined ? (_jsx("span", { className: "text-muted-foreground/60", children: "\u2014" })) : (content), unit !== undefined && content !== null && content !== undefined ? (_jsx("span", { className: "text-muted-foreground ml-1 text-xs", children: unit })) : null] })] }));
10
+ }
11
+ export { Readout, ReadoutItem };