@flyingrobots/bijou-tui 7.1.0 → 7.2.0

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 (569) hide show
  1. package/README.md +27 -4
  2. package/dist/accordion.d.ts +3 -108
  3. package/dist/accordion.d.ts.map +1 -1
  4. package/dist/accordion.js +2 -161
  5. package/dist/accordion.js.map +1 -1
  6. package/dist/accordion.part01.d.ts +25 -0
  7. package/dist/accordion.part01.d.ts.map +1 -0
  8. package/dist/accordion.part01.js +61 -0
  9. package/dist/accordion.part01.js.map +1 -0
  10. package/dist/accordion.part02.d.ts +8 -0
  11. package/dist/accordion.part02.d.ts.map +1 -0
  12. package/dist/accordion.part02.js +15 -0
  13. package/dist/accordion.part02.js.map +1 -0
  14. package/dist/animate.d.ts.map +1 -1
  15. package/dist/animate.js +5 -6
  16. package/dist/animate.js.map +1 -1
  17. package/dist/app-frame-actions.d.ts +1 -18
  18. package/dist/app-frame-actions.d.ts.map +1 -1
  19. package/dist/app-frame-actions.js +44 -42
  20. package/dist/app-frame-actions.js.map +1 -1
  21. package/dist/app-frame-i18n.d.ts.map +1 -1
  22. package/dist/app-frame-i18n.js +19 -2
  23. package/dist/app-frame-i18n.js.map +1 -1
  24. package/dist/app-frame-overlays.d.ts +1 -8
  25. package/dist/app-frame-overlays.d.ts.map +1 -1
  26. package/dist/app-frame-overlays.js +54 -24
  27. package/dist/app-frame-overlays.js.map +1 -1
  28. package/dist/app-frame-palette.d.ts +1 -11
  29. package/dist/app-frame-palette.d.ts.map +1 -1
  30. package/dist/app-frame-palette.js +19 -18
  31. package/dist/app-frame-palette.js.map +1 -1
  32. package/dist/app-frame-render.d.ts +0 -7
  33. package/dist/app-frame-render.d.ts.map +1 -1
  34. package/dist/app-frame-render.js +17 -26
  35. package/dist/app-frame-render.js.map +1 -1
  36. package/dist/app-frame-types.d.ts +8 -4
  37. package/dist/app-frame-types.d.ts.map +1 -1
  38. package/dist/app-frame-types.js +5 -5
  39. package/dist/app-frame-types.js.map +1 -1
  40. package/dist/app-frame-utils.d.ts +2 -1
  41. package/dist/app-frame-utils.d.ts.map +1 -1
  42. package/dist/app-frame-utils.js +8 -1
  43. package/dist/app-frame-utils.js.map +1 -1
  44. package/dist/app-frame.d.ts +14 -3
  45. package/dist/app-frame.d.ts.map +1 -1
  46. package/dist/app-frame.js +295 -231
  47. package/dist/app-frame.js.map +1 -1
  48. package/dist/app-frame.test-support.part01.d.ts +149 -0
  49. package/dist/app-frame.test-support.part01.d.ts.map +1 -0
  50. package/dist/app-frame.test-support.part01.js +106 -0
  51. package/dist/app-frame.test-support.part01.js.map +1 -0
  52. package/dist/app-frame.test-support.part02.d.ts +15 -0
  53. package/dist/app-frame.test-support.part02.d.ts.map +1 -0
  54. package/dist/app-frame.test-support.part02.js +89 -0
  55. package/dist/app-frame.test-support.part02.js.map +1 -0
  56. package/dist/browsable-list.d.ts +5 -5
  57. package/dist/browsable-list.d.ts.map +1 -1
  58. package/dist/browsable-list.js.map +1 -1
  59. package/dist/canvas.d.ts +2 -34
  60. package/dist/canvas.d.ts.map +1 -1
  61. package/dist/canvas.js +43 -47
  62. package/dist/canvas.js.map +1 -1
  63. package/dist/cell-glyph-fit.js +1 -1
  64. package/dist/cell-glyph-fit.js.map +1 -1
  65. package/dist/collection-surface-types.d.ts +12 -0
  66. package/dist/collection-surface-types.d.ts.map +1 -0
  67. package/dist/collection-surface-types.js +2 -0
  68. package/dist/collection-surface-types.js.map +1 -0
  69. package/dist/collection-surface.d.ts +2 -7
  70. package/dist/collection-surface.d.ts.map +1 -1
  71. package/dist/collection-surface.js +8 -18
  72. package/dist/collection-surface.js.map +1 -1
  73. package/dist/command-palette.d.ts.map +1 -1
  74. package/dist/command-palette.js +2 -1
  75. package/dist/command-palette.js.map +1 -1
  76. package/dist/commands.d.ts.map +1 -1
  77. package/dist/commands.js +1 -1
  78. package/dist/commands.js.map +1 -1
  79. package/dist/css/install.js.map +1 -1
  80. package/dist/css/parser.js +9 -3
  81. package/dist/css/parser.js.map +1 -1
  82. package/dist/css/resolver-types.d.ts +13 -0
  83. package/dist/css/resolver-types.d.ts.map +1 -0
  84. package/dist/css/resolver-types.js +2 -0
  85. package/dist/css/resolver-types.js.map +1 -0
  86. package/dist/css/resolver.d.ts +2 -12
  87. package/dist/css/resolver.d.ts.map +1 -1
  88. package/dist/css/resolver.js +13 -20
  89. package/dist/css/resolver.js.map +1 -1
  90. package/dist/css/text-style.d.ts +4 -8
  91. package/dist/css/text-style.d.ts.map +1 -1
  92. package/dist/css/text-style.js +13 -18
  93. package/dist/css/text-style.js.map +1 -1
  94. package/dist/dag-pane.d.ts +4 -224
  95. package/dist/dag-pane.d.ts.map +1 -1
  96. package/dist/dag-pane.js +3 -516
  97. package/dist/dag-pane.js.map +1 -1
  98. package/dist/dag-pane.part01.d.ts +58 -0
  99. package/dist/dag-pane.part01.d.ts.map +1 -0
  100. package/dist/dag-pane.part01.js +2 -0
  101. package/dist/dag-pane.part01.js.map +1 -0
  102. package/dist/dag-pane.part02.d.ts +4 -0
  103. package/dist/dag-pane.part02.d.ts.map +1 -0
  104. package/dist/dag-pane.part02.js +56 -0
  105. package/dist/dag-pane.part02.js.map +1 -0
  106. package/dist/dag-pane.part03.d.ts +6 -0
  107. package/dist/dag-pane.part03.d.ts.map +1 -0
  108. package/dist/dag-pane.part03.js +76 -0
  109. package/dist/dag-pane.part03.js.map +1 -0
  110. package/dist/dag-pane.part04.d.ts +7 -0
  111. package/dist/dag-pane.part04.d.ts.map +1 -0
  112. package/dist/dag-pane.part04.js +66 -0
  113. package/dist/dag-pane.part04.js.map +1 -0
  114. package/dist/dag-pane.part05.d.ts +7 -0
  115. package/dist/dag-pane.part05.d.ts.map +1 -0
  116. package/dist/dag-pane.part05.js +78 -0
  117. package/dist/dag-pane.part05.js.map +1 -0
  118. package/dist/dag-pane.part06.d.ts +14 -0
  119. package/dist/dag-pane.part06.d.ts.map +1 -0
  120. package/dist/dag-pane.part06.js +65 -0
  121. package/dist/dag-pane.part06.js.map +1 -0
  122. package/dist/dag-pane.part07.d.ts +18 -0
  123. package/dist/dag-pane.part07.d.ts.map +1 -0
  124. package/dist/dag-pane.part07.js +22 -0
  125. package/dist/dag-pane.part07.js.map +1 -0
  126. package/dist/driver.d.ts +35 -21
  127. package/dist/driver.d.ts.map +1 -1
  128. package/dist/driver.js +69 -39
  129. package/dist/driver.js.map +1 -1
  130. package/dist/eventbus.d.ts.map +1 -1
  131. package/dist/eventbus.js +13 -23
  132. package/dist/eventbus.js.map +1 -1
  133. package/dist/file-picker.d.ts +4 -164
  134. package/dist/file-picker.d.ts.map +1 -1
  135. package/dist/file-picker.js +3 -292
  136. package/dist/file-picker.js.map +1 -1
  137. package/dist/file-picker.part01.d.ts +54 -0
  138. package/dist/file-picker.part01.d.ts.map +1 -0
  139. package/dist/file-picker.part01.js +47 -0
  140. package/dist/file-picker.part01.js.map +1 -0
  141. package/dist/file-picker.part02.d.ts +9 -0
  142. package/dist/file-picker.part02.d.ts.map +1 -0
  143. package/dist/file-picker.part02.js +77 -0
  144. package/dist/file-picker.part02.js.map +1 -0
  145. package/dist/file-picker.part03.d.ts +12 -0
  146. package/dist/file-picker.part03.d.ts.map +1 -0
  147. package/dist/file-picker.part03.js +35 -0
  148. package/dist/file-picker.part03.js.map +1 -0
  149. package/dist/flex.d.ts +0 -61
  150. package/dist/flex.d.ts.map +1 -1
  151. package/dist/flex.js +11 -161
  152. package/dist/flex.js.map +1 -1
  153. package/dist/focus-area.d.ts +6 -210
  154. package/dist/focus-area.d.ts.map +1 -1
  155. package/dist/focus-area.js +5 -425
  156. package/dist/focus-area.js.map +1 -1
  157. package/dist/focus-area.part01.d.ts +57 -0
  158. package/dist/focus-area.part01.d.ts.map +1 -0
  159. package/dist/focus-area.part01.js +23 -0
  160. package/dist/focus-area.part01.js.map +1 -0
  161. package/dist/focus-area.part02.d.ts +13 -0
  162. package/dist/focus-area.part02.d.ts.map +1 -0
  163. package/dist/focus-area.part02.js +65 -0
  164. package/dist/focus-area.part02.js.map +1 -0
  165. package/dist/focus-area.part03.d.ts +5 -0
  166. package/dist/focus-area.part03.d.ts.map +1 -0
  167. package/dist/focus-area.part03.js +42 -0
  168. package/dist/focus-area.part03.js.map +1 -0
  169. package/dist/focus-area.part04.d.ts +5 -0
  170. package/dist/focus-area.part04.d.ts.map +1 -0
  171. package/dist/focus-area.part04.js +49 -0
  172. package/dist/focus-area.part04.js.map +1 -0
  173. package/dist/focus-area.part05.d.ts +10 -0
  174. package/dist/focus-area.part05.d.ts.map +1 -0
  175. package/dist/focus-area.part05.js +66 -0
  176. package/dist/focus-area.part05.js.map +1 -0
  177. package/dist/focus-area.part06.d.ts +17 -0
  178. package/dist/focus-area.part06.d.ts.map +1 -0
  179. package/dist/focus-area.part06.js +48 -0
  180. package/dist/focus-area.part06.js.map +1 -0
  181. package/dist/focus-map.d.ts.map +1 -1
  182. package/dist/focus-map.js +8 -10
  183. package/dist/focus-map.js.map +1 -1
  184. package/dist/index.d.ts +8 -80
  185. package/dist/index.d.ts.map +1 -1
  186. package/dist/index.js +8 -107
  187. package/dist/index.js.map +1 -1
  188. package/dist/index.part01.d.ts +15 -0
  189. package/dist/index.part01.d.ts.map +1 -0
  190. package/dist/index.part01.js +11 -0
  191. package/dist/index.part01.js.map +1 -0
  192. package/dist/index.part02.d.ts +26 -0
  193. package/dist/index.part02.d.ts.map +1 -0
  194. package/dist/index.part02.js +24 -0
  195. package/dist/index.part02.js.map +1 -0
  196. package/dist/index.part03.d.ts +17 -0
  197. package/dist/index.part03.d.ts.map +1 -0
  198. package/dist/index.part03.js +11 -0
  199. package/dist/index.part03.js.map +1 -0
  200. package/dist/index.part04.d.ts +6 -0
  201. package/dist/index.part04.d.ts.map +1 -0
  202. package/dist/index.part04.js +11 -0
  203. package/dist/index.part04.js.map +1 -0
  204. package/dist/index.part05.d.ts +10 -0
  205. package/dist/index.part05.d.ts.map +1 -0
  206. package/dist/index.part05.js +26 -0
  207. package/dist/index.part05.js.map +1 -0
  208. package/dist/index.part06.d.ts +9 -0
  209. package/dist/index.part06.d.ts.map +1 -0
  210. package/dist/index.part06.js +16 -0
  211. package/dist/index.part06.js.map +1 -0
  212. package/dist/index.part07.d.ts +8 -0
  213. package/dist/index.part07.d.ts.map +1 -0
  214. package/dist/index.part07.js +15 -0
  215. package/dist/index.part07.js.map +1 -0
  216. package/dist/index.part08.d.ts +5 -0
  217. package/dist/index.part08.d.ts.map +1 -0
  218. package/dist/index.part08.js +9 -0
  219. package/dist/index.part08.js.map +1 -0
  220. package/dist/input-map.d.ts.map +1 -1
  221. package/dist/input-map.js +1 -2
  222. package/dist/input-map.js.map +1 -1
  223. package/dist/input-parser.d.ts +3 -0
  224. package/dist/input-parser.d.ts.map +1 -0
  225. package/dist/input-parser.js +95 -0
  226. package/dist/input-parser.js.map +1 -0
  227. package/dist/input-routing-inspector.js +3 -3
  228. package/dist/input-routing-inspector.js.map +1 -1
  229. package/dist/inputstack.d.ts.map +1 -1
  230. package/dist/inputstack.js +2 -0
  231. package/dist/inputstack.js.map +1 -1
  232. package/dist/keybindings.d.ts.map +1 -1
  233. package/dist/keybindings.js +5 -2
  234. package/dist/keybindings.js.map +1 -1
  235. package/dist/keys.d.ts +0 -36
  236. package/dist/keys.d.ts.map +1 -1
  237. package/dist/keys.js +11 -66
  238. package/dist/keys.js.map +1 -1
  239. package/dist/layout-inspector.d.ts +2 -30
  240. package/dist/layout-inspector.d.ts.map +1 -1
  241. package/dist/layout-inspector.js +1 -132
  242. package/dist/layout-inspector.js.map +1 -1
  243. package/dist/layout-inspector.part01.d.ts +52 -0
  244. package/dist/layout-inspector.part01.d.ts.map +1 -0
  245. package/dist/layout-inspector.part01.js +48 -0
  246. package/dist/layout-inspector.part01.js.map +1 -0
  247. package/dist/layout-inspector.part02.d.ts +11 -0
  248. package/dist/layout-inspector.part02.d.ts.map +1 -0
  249. package/dist/layout-inspector.part02.js +80 -0
  250. package/dist/layout-inspector.part02.js.map +1 -0
  251. package/dist/layout-inspector.part03.d.ts +5 -0
  252. package/dist/layout-inspector.part03.d.ts.map +1 -0
  253. package/dist/layout-inspector.part03.js +11 -0
  254. package/dist/layout-inspector.part03.js.map +1 -0
  255. package/dist/layout-preset.js +4 -4
  256. package/dist/layout-preset.js.map +1 -1
  257. package/dist/layout.d.ts.map +1 -1
  258. package/dist/layout.js +5 -3
  259. package/dist/layout.js.map +1 -1
  260. package/dist/motion/motion.js +8 -4
  261. package/dist/motion/motion.js.map +1 -1
  262. package/dist/motion/reconciler.d.ts.map +1 -1
  263. package/dist/motion/reconciler.js +9 -7
  264. package/dist/motion/reconciler.js.map +1 -1
  265. package/dist/mouse-mode.d.ts +5 -0
  266. package/dist/mouse-mode.d.ts.map +1 -0
  267. package/dist/mouse-mode.js +17 -0
  268. package/dist/mouse-mode.js.map +1 -0
  269. package/dist/navigable-table.d.ts +3 -136
  270. package/dist/navigable-table.d.ts.map +1 -1
  271. package/dist/navigable-table.js +2 -234
  272. package/dist/navigable-table.js.map +1 -1
  273. package/dist/navigable-table.part01.d.ts +42 -0
  274. package/dist/navigable-table.part01.d.ts.map +1 -0
  275. package/dist/navigable-table.part01.js +42 -0
  276. package/dist/navigable-table.part01.js.map +1 -0
  277. package/dist/navigable-table.part02.d.ts +16 -0
  278. package/dist/navigable-table.part02.d.ts.map +1 -0
  279. package/dist/navigable-table.part02.js +83 -0
  280. package/dist/navigable-table.part02.js.map +1 -0
  281. package/dist/notification-card.d.ts +11 -0
  282. package/dist/notification-card.d.ts.map +1 -0
  283. package/dist/notification-card.js +157 -0
  284. package/dist/notification-card.js.map +1 -0
  285. package/dist/notification-stack.d.ts +6 -0
  286. package/dist/notification-stack.d.ts.map +1 -0
  287. package/dist/notification-stack.js +257 -0
  288. package/dist/notification-stack.js.map +1 -0
  289. package/dist/notification.d.ts +14 -112
  290. package/dist/notification.d.ts.map +1 -1
  291. package/dist/notification.js +12 -1087
  292. package/dist/notification.js.map +1 -1
  293. package/dist/notification.part01.d.ts +77 -0
  294. package/dist/notification.part01.d.ts.map +1 -0
  295. package/dist/notification.part01.js +19 -0
  296. package/dist/notification.part01.js.map +1 -0
  297. package/dist/notification.part02.d.ts +42 -0
  298. package/dist/notification.part02.d.ts.map +1 -0
  299. package/dist/notification.part02.js +44 -0
  300. package/dist/notification.part02.js.map +1 -0
  301. package/dist/notification.part03.d.ts +6 -0
  302. package/dist/notification.part03.d.ts.map +1 -0
  303. package/dist/notification.part03.js +81 -0
  304. package/dist/notification.part03.js.map +1 -0
  305. package/dist/notification.part04.d.ts +4 -0
  306. package/dist/notification.part04.d.ts.map +1 -0
  307. package/dist/notification.part04.js +32 -0
  308. package/dist/notification.part04.js.map +1 -0
  309. package/dist/notification.part05.d.ts +6 -0
  310. package/dist/notification.part05.d.ts.map +1 -0
  311. package/dist/notification.part05.js +95 -0
  312. package/dist/notification.part05.js.map +1 -0
  313. package/dist/notification.part06.d.ts +9 -0
  314. package/dist/notification.part06.d.ts.map +1 -0
  315. package/dist/notification.part06.js +65 -0
  316. package/dist/notification.part06.js.map +1 -0
  317. package/dist/notification.part07.d.ts +10 -0
  318. package/dist/notification.part07.d.ts.map +1 -0
  319. package/dist/notification.part07.js +70 -0
  320. package/dist/notification.part07.js.map +1 -0
  321. package/dist/notification.part08.d.ts +5 -0
  322. package/dist/notification.part08.d.ts.map +1 -0
  323. package/dist/notification.part08.js +79 -0
  324. package/dist/notification.part08.js.map +1 -0
  325. package/dist/notification.part09.d.ts +14 -0
  326. package/dist/notification.part09.d.ts.map +1 -0
  327. package/dist/notification.part09.js +96 -0
  328. package/dist/notification.part09.js.map +1 -0
  329. package/dist/notification.part10.d.ts +13 -0
  330. package/dist/notification.part10.d.ts.map +1 -0
  331. package/dist/notification.part10.js +94 -0
  332. package/dist/notification.part10.js.map +1 -0
  333. package/dist/notification.part11.d.ts +6 -0
  334. package/dist/notification.part11.d.ts.map +1 -0
  335. package/dist/notification.part11.js +42 -0
  336. package/dist/notification.part11.js.map +1 -0
  337. package/dist/overlay.d.ts +8 -232
  338. package/dist/overlay.d.ts.map +1 -1
  339. package/dist/overlay.js +5 -629
  340. package/dist/overlay.js.map +1 -1
  341. package/dist/overlay.part01.d.ts +71 -0
  342. package/dist/overlay.part01.d.ts.map +1 -0
  343. package/dist/overlay.part01.js +34 -0
  344. package/dist/overlay.part01.js.map +1 -0
  345. package/dist/overlay.part02.d.ts +8 -0
  346. package/dist/overlay.part02.d.ts.map +1 -0
  347. package/dist/overlay.part02.js +81 -0
  348. package/dist/overlay.part02.js.map +1 -0
  349. package/dist/overlay.part03.d.ts +27 -0
  350. package/dist/overlay.part03.d.ts.map +1 -0
  351. package/dist/overlay.part03.js +83 -0
  352. package/dist/overlay.part03.js.map +1 -0
  353. package/dist/overlay.part04.d.ts +8 -0
  354. package/dist/overlay.part04.d.ts.map +1 -0
  355. package/dist/overlay.part04.js +103 -0
  356. package/dist/overlay.part04.js.map +1 -0
  357. package/dist/overlay.part05.d.ts +8 -0
  358. package/dist/overlay.part05.d.ts.map +1 -0
  359. package/dist/overlay.part05.js +66 -0
  360. package/dist/overlay.part05.js.map +1 -0
  361. package/dist/overlay.part06.d.ts +46 -0
  362. package/dist/overlay.part06.d.ts.map +1 -0
  363. package/dist/overlay.part06.js +35 -0
  364. package/dist/overlay.part06.js.map +1 -0
  365. package/dist/overlay.part07.d.ts +4 -0
  366. package/dist/overlay.part07.d.ts.map +1 -0
  367. package/dist/overlay.part07.js +64 -0
  368. package/dist/overlay.part07.js.map +1 -0
  369. package/dist/overlay.part08.d.ts +34 -0
  370. package/dist/overlay.part08.d.ts.map +1 -0
  371. package/dist/overlay.part08.js +54 -0
  372. package/dist/overlay.part08.js.map +1 -0
  373. package/dist/overlay.part09.d.ts +6 -0
  374. package/dist/overlay.part09.d.ts.map +1 -0
  375. package/dist/overlay.part09.js +42 -0
  376. package/dist/overlay.part09.js.map +1 -0
  377. package/dist/pager.d.ts.map +1 -1
  378. package/dist/pager.js +2 -4
  379. package/dist/pager.js.map +1 -1
  380. package/dist/panel-dock.d.ts.map +1 -1
  381. package/dist/panel-dock.js +9 -11
  382. package/dist/panel-dock.js.map +1 -1
  383. package/dist/panels.d.ts.map +1 -1
  384. package/dist/panels.js +2 -0
  385. package/dist/panels.js.map +1 -1
  386. package/dist/pipeline/middleware/css.d.ts +3 -5
  387. package/dist/pipeline/middleware/css.d.ts.map +1 -1
  388. package/dist/pipeline/middleware/css.js +12 -6
  389. package/dist/pipeline/middleware/css.js.map +1 -1
  390. package/dist/pipeline/middleware/grayscale.js +15 -10
  391. package/dist/pipeline/middleware/grayscale.js.map +1 -1
  392. package/dist/pipeline/middleware/motion.js +9 -1
  393. package/dist/pipeline/middleware/motion.js.map +1 -1
  394. package/dist/pipeline/middleware/paint.js +9 -1
  395. package/dist/pipeline/middleware/paint.js.map +1 -1
  396. package/dist/pipeline/middleware/surface-shaders.js +13 -11
  397. package/dist/pipeline/middleware/surface-shaders.js.map +1 -1
  398. package/dist/pipeline/pipeline.d.ts +7 -52
  399. package/dist/pipeline/pipeline.d.ts.map +1 -1
  400. package/dist/pipeline/pipeline.js +37 -27
  401. package/dist/pipeline/pipeline.js.map +1 -1
  402. package/dist/raster-glyph.d.ts +2 -44
  403. package/dist/raster-glyph.d.ts.map +1 -1
  404. package/dist/raster-glyph.js +1 -404
  405. package/dist/raster-glyph.js.map +1 -1
  406. package/dist/raster-glyph.part01.d.ts +75 -0
  407. package/dist/raster-glyph.part01.d.ts.map +1 -0
  408. package/dist/raster-glyph.part01.js +25 -0
  409. package/dist/raster-glyph.part01.js.map +1 -0
  410. package/dist/raster-glyph.part02.d.ts +12 -0
  411. package/dist/raster-glyph.part02.d.ts.map +1 -0
  412. package/dist/raster-glyph.part02.js +81 -0
  413. package/dist/raster-glyph.part02.js.map +1 -0
  414. package/dist/raster-glyph.part03.d.ts +6 -0
  415. package/dist/raster-glyph.part03.d.ts.map +1 -0
  416. package/dist/raster-glyph.part03.js +60 -0
  417. package/dist/raster-glyph.part03.js.map +1 -0
  418. package/dist/raster-glyph.part04.d.ts +7 -0
  419. package/dist/raster-glyph.part04.d.ts.map +1 -0
  420. package/dist/raster-glyph.part04.js +59 -0
  421. package/dist/raster-glyph.part04.js.map +1 -0
  422. package/dist/raster-glyph.part05.d.ts +6 -0
  423. package/dist/raster-glyph.part05.d.ts.map +1 -0
  424. package/dist/raster-glyph.part05.js +71 -0
  425. package/dist/raster-glyph.part05.js.map +1 -0
  426. package/dist/raster-glyph.part06.d.ts +18 -0
  427. package/dist/raster-glyph.part06.d.ts.map +1 -0
  428. package/dist/raster-glyph.part06.js +78 -0
  429. package/dist/raster-glyph.part06.js.map +1 -0
  430. package/dist/raster-glyph.part07.d.ts +11 -0
  431. package/dist/raster-glyph.part07.d.ts.map +1 -0
  432. package/dist/raster-glyph.part07.js +55 -0
  433. package/dist/raster-glyph.part07.js.map +1 -0
  434. package/dist/raytrace.d.ts +3 -58
  435. package/dist/raytrace.d.ts.map +1 -1
  436. package/dist/raytrace.js +2 -120
  437. package/dist/raytrace.js.map +1 -1
  438. package/dist/raytrace.part01.d.ts +47 -0
  439. package/dist/raytrace.part01.d.ts.map +1 -0
  440. package/dist/raytrace.part01.js +45 -0
  441. package/dist/raytrace.part01.js.map +1 -0
  442. package/dist/raytrace.part02.d.ts +12 -0
  443. package/dist/raytrace.part02.d.ts.map +1 -0
  444. package/dist/raytrace.part02.js +73 -0
  445. package/dist/raytrace.part02.js.map +1 -0
  446. package/dist/runtime-binding.d.ts +2 -3
  447. package/dist/runtime-binding.d.ts.map +1 -1
  448. package/dist/runtime-binding.js +49 -38
  449. package/dist/runtime-binding.js.map +1 -1
  450. package/dist/runtime-engine.d.ts +2 -2
  451. package/dist/runtime-engine.d.ts.map +1 -1
  452. package/dist/runtime-engine.js +15 -4
  453. package/dist/runtime-engine.js.map +1 -1
  454. package/dist/runtime.d.ts +2 -18
  455. package/dist/runtime.d.ts.map +1 -1
  456. package/dist/runtime.js +33 -59
  457. package/dist/runtime.js.map +1 -1
  458. package/dist/screen.js +1 -1
  459. package/dist/screen.js.map +1 -1
  460. package/dist/shell-quit.d.ts.map +1 -1
  461. package/dist/shell-quit.js +48 -5
  462. package/dist/shell-quit.js.map +1 -1
  463. package/dist/split-pane.d.ts +3 -104
  464. package/dist/split-pane.d.ts.map +1 -1
  465. package/dist/split-pane.js +2 -190
  466. package/dist/split-pane.js.map +1 -1
  467. package/dist/split-pane.part01.d.ts +60 -0
  468. package/dist/split-pane.part01.d.ts.map +1 -0
  469. package/dist/split-pane.part01.js +45 -0
  470. package/dist/split-pane.part01.js.map +1 -0
  471. package/dist/split-pane.part02.d.ts +8 -0
  472. package/dist/split-pane.part02.d.ts.map +1 -0
  473. package/dist/split-pane.part02.js +73 -0
  474. package/dist/split-pane.part02.js.map +1 -0
  475. package/dist/split-pane.part03.d.ts +4 -0
  476. package/dist/split-pane.part03.d.ts.map +1 -0
  477. package/dist/split-pane.part03.js +40 -0
  478. package/dist/split-pane.part03.js.map +1 -0
  479. package/dist/spring.d.ts +4 -187
  480. package/dist/spring.d.ts.map +1 -1
  481. package/dist/spring.js +2 -142
  482. package/dist/spring.js.map +1 -1
  483. package/dist/spring.part01.d.ts +90 -0
  484. package/dist/spring.part01.d.ts.map +1 -0
  485. package/dist/spring.part01.js +58 -0
  486. package/dist/spring.part01.js.map +1 -0
  487. package/dist/spring.part02.d.ts +25 -0
  488. package/dist/spring.part02.d.ts.map +1 -0
  489. package/dist/spring.part02.js +21 -0
  490. package/dist/spring.part02.js.map +1 -0
  491. package/dist/status-bar.js +1 -1
  492. package/dist/status-bar.js.map +1 -1
  493. package/dist/subapp/mount.d.ts +6 -6
  494. package/dist/subapp/mount.d.ts.map +1 -1
  495. package/dist/subapp/mount.js +19 -14
  496. package/dist/subapp/mount.js.map +1 -1
  497. package/dist/surface-budget-types.d.ts +26 -0
  498. package/dist/surface-budget-types.d.ts.map +1 -0
  499. package/dist/surface-budget-types.js +2 -0
  500. package/dist/surface-budget-types.js.map +1 -0
  501. package/dist/surface-budget.d.ts +2 -25
  502. package/dist/surface-budget.d.ts.map +1 -1
  503. package/dist/surface-budget.js.map +1 -1
  504. package/dist/surface-diff.js +26 -28
  505. package/dist/surface-diff.js.map +1 -1
  506. package/dist/surface-layout.d.ts.map +1 -1
  507. package/dist/surface-layout.js +1 -2
  508. package/dist/surface-layout.js.map +1 -1
  509. package/dist/timeline.d.ts +1 -1
  510. package/dist/timeline.d.ts.map +1 -1
  511. package/dist/timeline.js +17 -15
  512. package/dist/timeline.js.map +1 -1
  513. package/dist/transition-shaders.d.ts +5 -142
  514. package/dist/transition-shaders.d.ts.map +1 -1
  515. package/dist/transition-shaders.js +4 -391
  516. package/dist/transition-shaders.js.map +1 -1
  517. package/dist/transition-shaders.part01.d.ts +41 -0
  518. package/dist/transition-shaders.part01.d.ts.map +1 -0
  519. package/dist/transition-shaders.part01.js +38 -0
  520. package/dist/transition-shaders.part01.js.map +1 -0
  521. package/dist/transition-shaders.part02.d.ts +12 -0
  522. package/dist/transition-shaders.part02.d.ts.map +1 -0
  523. package/dist/transition-shaders.part02.js +88 -0
  524. package/dist/transition-shaders.part02.js.map +1 -0
  525. package/dist/transition-shaders.part03.d.ts +6 -0
  526. package/dist/transition-shaders.part03.d.ts.map +1 -0
  527. package/dist/transition-shaders.part03.js +82 -0
  528. package/dist/transition-shaders.part03.js.map +1 -0
  529. package/dist/transition-shaders.part04.d.ts +16 -0
  530. package/dist/transition-shaders.part04.d.ts.map +1 -0
  531. package/dist/transition-shaders.part04.js +98 -0
  532. package/dist/transition-shaders.part04.js.map +1 -0
  533. package/dist/types.d.ts +10 -42
  534. package/dist/types.d.ts.map +1 -1
  535. package/dist/types.js +9 -36
  536. package/dist/types.js.map +1 -1
  537. package/dist/view-output.d.ts +1 -1
  538. package/dist/view-output.d.ts.map +1 -1
  539. package/dist/view-output.js +3 -2
  540. package/dist/view-output.js.map +1 -1
  541. package/dist/viewport.d.ts +7 -213
  542. package/dist/viewport.d.ts.map +1 -1
  543. package/dist/viewport.js +6 -470
  544. package/dist/viewport.js.map +1 -1
  545. package/dist/viewport.part01.d.ts +51 -0
  546. package/dist/viewport.part01.d.ts.map +1 -0
  547. package/dist/viewport.part01.js +10 -0
  548. package/dist/viewport.part01.js.map +1 -0
  549. package/dist/viewport.part02.d.ts +2 -0
  550. package/dist/viewport.part02.d.ts.map +1 -0
  551. package/dist/viewport.part02.js +69 -0
  552. package/dist/viewport.part02.js.map +1 -0
  553. package/dist/viewport.part03.d.ts +10 -0
  554. package/dist/viewport.part03.d.ts.map +1 -0
  555. package/dist/viewport.part03.js +78 -0
  556. package/dist/viewport.part03.js.map +1 -0
  557. package/dist/viewport.part04.d.ts +4 -0
  558. package/dist/viewport.part04.d.ts.map +1 -0
  559. package/dist/viewport.part04.js +50 -0
  560. package/dist/viewport.part04.js.map +1 -0
  561. package/dist/viewport.part05.d.ts +5 -0
  562. package/dist/viewport.part05.d.ts.map +1 -0
  563. package/dist/viewport.part05.js +59 -0
  564. package/dist/viewport.part05.js.map +1 -0
  565. package/dist/viewport.part06.d.ts +14 -0
  566. package/dist/viewport.part06.d.ts.map +1 -0
  567. package/dist/viewport.part06.js +58 -0
  568. package/dist/viewport.part06.js.map +1 -0
  569. package/package.json +3 -3
@@ -1,1088 +1,13 @@
1
- import { createSurface, isPackedSurface, prepareWrappedText, segmentGraphemes, surfaceToString, wrapPreparedTextToWidth, } from '@flyingrobots/bijou';
2
- import { parseHex, encodeModifiers } from '@flyingrobots/bijou/perf';
3
- import { visibleLength } from './viewport.js';
4
- import { resolveNotificationGap, resolveOverlayMargin } from './design-language.js';
5
- import { vstackSurface } from './surface-layout.js';
6
- import { forceTextPresentation } from './icon-presentation.js';
7
- function resolvedColorRgb(ref) {
8
- return typeof ref === 'object'
9
- && ref !== null
10
- && 'kind' in ref
11
- && ref.kind === 'resolved-color'
12
- && 'rgb' in ref
13
- ? ref.rgb
14
- : undefined;
15
- }
16
- function resolvedColorHex(ref) {
17
- if (typeof ref === 'string')
18
- return ref;
19
- return typeof ref === 'object'
20
- && ref !== null
21
- && 'kind' in ref
22
- && ref.kind === 'resolved-color'
23
- && 'hex' in ref
24
- ? ref.hex
25
- : undefined;
26
- }
27
- const ENTER_DURATION_MS = 180;
28
- const EXIT_DURATION_MS = 320;
29
- const HISTORY_LIMIT = 250;
30
- const TONE_ICONS = {
31
- INFO: forceTextPresentation('\u2139'),
32
- SUCCESS: forceTextPresentation('\u2714'),
33
- WARNING: forceTextPresentation('\u26a0'),
34
- ERROR: forceTextPresentation('\u2718'),
35
- };
36
- const TONE_BORDER_KEYS = {
37
- INFO: 'primary',
38
- SUCCESS: 'success',
39
- WARNING: 'warning',
40
- ERROR: 'error',
41
- };
42
- export function createNotificationState() {
43
- return {
44
- items: [],
45
- overflowExits: [],
46
- history: [],
47
- nextId: 1,
48
- };
49
- }
50
- function matchesHistoryFilter(item, filter) {
51
- if (filter === 'ALL')
52
- return true;
53
- if (filter === 'ACTIONABLE')
54
- return item.variant === 'ACTIONABLE';
55
- return item.tone === filter;
56
- }
57
- export function countNotificationHistory(state, filter = 'ALL') {
58
- let count = 0;
59
- for (const item of state.history) {
60
- if (matchesHistoryFilter(item, filter))
61
- count++;
62
- }
63
- return count;
64
- }
65
- function filterLabel(filter, labels) {
66
- return labels?.filterLabel?.(filter)
67
- ?? (filter === 'ALL' ? 'All' : filter === 'ACTIONABLE' ? 'Actionable' : filter);
68
- }
69
- function renderHistoryEntry(item, width, ctx, actionLabel) {
70
- const safeWidth = Math.max(1, width);
71
- const prepared = prepareNotificationHistoryEntry(item, ctx, actionLabel);
72
- const lines = [
73
- ...wrapPreparedTextToWidth(prepared.title, safeWidth),
74
- ...wrapPreparedTextToWidth(prepared.metaLine, safeWidth),
75
- ...(prepared.messageLine == null ? [] : wrapPreparedTextToWidth(prepared.messageLine, safeWidth)),
76
- ...(prepared.actionLine == null ? [] : wrapPreparedTextToWidth(prepared.actionLine, safeWidth)),
77
- ];
78
- return lines.length === 0 ? [''] : lines;
79
- }
80
- function prepareNotificationHistoryEntry(item, ctx, actionLabel) {
81
- const toneLabel = `[${item.tone}]`;
82
- const title = ctx == null
83
- ? `${toneLabel} ${item.title}`
84
- : `${ctx.style.styled(ctx.semantic(toneSemanticKey(item.tone)), toneLabel)} ${ctx.style.bold(item.title)}`;
85
- const meta = `${formatTimeLabel(item.createdAtMs)} • ${item.variant} • ${item.placement}`;
86
- const metaLine = ctx == null ? meta : ctx.style.styled(ctx.semantic('muted'), meta);
87
- const actionLine = item.action == null
88
- ? undefined
89
- : (ctx == null
90
- ? (actionLabel?.(item.action.label) ?? `Action: ${item.action.label}`)
91
- : ctx.style.styled(ctx.semantic('muted'), actionLabel?.(item.action.label) ?? `Action: ${item.action.label}`));
92
- const messageLine = item.message.length === 0
93
- ? undefined
94
- : (ctx == null ? item.message : ctx.style.styled(ctx.semantic('muted'), item.message));
95
- return {
96
- title: prepareWrappedText(title),
97
- metaLine: prepareWrappedText(metaLine),
98
- messageLine: messageLine == null ? undefined : prepareWrappedText(messageLine),
99
- actionLine: actionLine == null ? undefined : prepareWrappedText(actionLine),
100
- };
101
- }
102
- export function renderNotificationHistory(state, options) {
103
- const safeWidth = Math.max(1, options.width);
104
- const safeHeight = Math.max(3, options.height);
105
- const filter = options.filter ?? 'ALL';
106
- const filterName = filterLabel(filter, options.labels);
107
- const filtered = state.history.filter((item) => matchesHistoryFilter(item, filter));
108
- const maxBodyLines = Math.max(1, safeHeight - 2);
109
- const start = Math.max(0, Math.min(options.scroll ?? 0, Math.max(0, filtered.length - 1)));
110
- if (filtered.length === 0) {
111
- const emptyText = options.ctx == null
112
- ? (options.labels?.emptyLabel?.({ filterLabel: filterName }) ?? `No archived notifications for ${filterName} yet.`)
113
- : options.ctx.style.styled(options.ctx.semantic('muted'), options.labels?.emptyLabel?.({ filterLabel: filterName }) ?? `No archived notifications for ${filterName} yet.`);
114
- const empty = wrapPreparedTextToWidth(prepareWrappedText(emptyText), safeWidth).slice(0, maxBodyLines);
115
- const header = options.labels?.headerLabel?.({
116
- filterLabel: filterName,
117
- start: 0,
118
- end: 0,
119
- total: 0,
120
- }) ?? `History • ${filterName} • 0 items`;
121
- return [
122
- header,
123
- '',
124
- ...empty,
125
- ].join('\n');
126
- }
127
- const bodyLines = [];
128
- let renderedCount = 0;
129
- for (const item of filtered.slice(start)) {
130
- const entryLines = renderHistoryEntry(item, safeWidth, options.ctx, options.labels?.actionLabel);
131
- const remaining = maxBodyLines - bodyLines.length;
132
- if (remaining <= 0)
133
- break;
134
- if (bodyLines.length > 0) {
135
- if (remaining <= 1)
136
- break;
137
- bodyLines.push('');
138
- }
139
- bodyLines.push(...entryLines.slice(0, maxBodyLines - bodyLines.length));
140
- renderedCount++;
141
- if (bodyLines.length >= maxBodyLines)
142
- break;
143
- }
144
- const end = Math.min(filtered.length, start + Math.max(1, renderedCount));
145
- const header = options.labels?.headerLabel?.({
146
- filterLabel: filterName,
147
- start: start + 1,
148
- end,
149
- total: filtered.length,
150
- }) ?? `History • ${filterName} • ${start + 1}-${end} of ${filtered.length}`;
151
- return [
152
- header,
153
- '',
154
- ...bodyLines,
155
- ].join('\n');
156
- }
157
- export function renderNotificationReviewEntrySurface(item, options) {
158
- const safeWidth = Math.max(1, options.width);
159
- const ctx = options.ctx;
160
- const meta = options.metaLabel ?? `${formatTimeLabel(item.createdAtMs)} • ${item.variant} • ${item.placement}`;
161
- const mutedStyle = tokenToCellStyle(ctx?.semantic('muted'));
162
- const toneStyle = tokenToCellStyle(ctx?.semantic(toneSemanticKey(item.tone)));
163
- const titleStyle = withModifiers({}, ['bold']);
164
- const rows = [];
165
- rows.push(...renderInsetWrappedSurface(createSegmentSurface([
166
- { text: `[${item.tone}]`, style: toneStyle },
167
- { text: ' ' },
168
- { text: item.title, style: titleStyle },
169
- ]), safeWidth));
170
- rows.push(...renderInsetWrappedSurface(createSegmentSurface([
171
- { text: meta, style: mutedStyle },
172
- ]), safeWidth));
173
- if (item.message.length > 0) {
174
- rows.push(...renderInsetWrappedSurface(createSegmentSurface([
175
- { text: item.message, style: mutedStyle },
176
- ]), safeWidth));
177
- }
178
- if (item.action != null) {
179
- rows.push(...renderInsetWrappedSurface(createSegmentSurface([
180
- { text: options.actionLabel?.(item.action.label) ?? `Action: ${item.action.label}`, style: mutedStyle },
181
- ]), safeWidth));
182
- }
183
- return rows.length === 0 ? createBlankLineSurface(safeWidth) : vstackSurface(...rows);
184
- }
185
- export function renderNotificationHistorySurface(state, options) {
186
- const safeWidth = Math.max(1, options.width);
187
- const safeHeight = Math.max(3, options.height);
188
- const filter = options.filter ?? 'ALL';
189
- const filterName = filterLabel(filter, options.labels);
190
- const filtered = state.history.filter((item) => matchesHistoryFilter(item, filter));
191
- const maxBodyLines = Math.max(1, safeHeight - 2);
192
- const start = Math.max(0, Math.min(options.scroll ?? 0, Math.max(0, filtered.length - 1)));
193
- const rows = [
194
- ...renderInsetWrappedSurface(createSegmentSurface([
195
- { text: filtered.length === 0
196
- ? (options.labels?.headerLabel?.({
197
- filterLabel: filterName,
198
- start: 0,
199
- end: 0,
200
- total: 0,
201
- }) ?? `History • ${filterName} • 0 items`)
202
- : (options.labels?.headerLabel?.({
203
- filterLabel: filterName,
204
- start: start + 1,
205
- end: Math.min(filtered.length, start + 1),
206
- total: filtered.length,
207
- }) ?? `History • ${filterName} • ${start + 1}-${Math.min(filtered.length, start + 1)} of ${filtered.length}`),
208
- style: withModifiers({}, ['bold']) },
209
- ]), safeWidth),
210
- createBlankLineSurface(safeWidth),
211
- ];
212
- if (filtered.length === 0) {
213
- rows.push(...renderInsetWrappedSurface(createSegmentSurface([{
214
- text: options.labels?.emptyLabel?.({ filterLabel: filterName }) ?? `No archived notifications for ${filterName} yet.`,
215
- style: tokenToCellStyle(options.ctx?.semantic('muted')),
216
- }]), safeWidth));
217
- return vstackSurface(...rows);
218
- }
219
- let bodyLines = 0;
220
- let end = start;
221
- for (const item of filtered.slice(start)) {
222
- const entry = renderNotificationReviewEntrySurface(item, {
223
- width: safeWidth,
224
- ctx: options.ctx,
225
- actionLabel: options.labels?.actionLabel,
226
- });
227
- const remaining = maxBodyLines - bodyLines;
228
- if (remaining <= 0)
229
- break;
230
- if (bodyLines > 0) {
231
- if (remaining <= 1)
232
- break;
233
- rows.push(createBlankLineSurface(safeWidth));
234
- bodyLines += 1;
235
- }
236
- const clipped = clipSurfaceHeight(entry, maxBodyLines - bodyLines);
237
- rows.push(clipped);
238
- bodyLines += clipped.height;
239
- end += 1;
240
- if (clipped.height < entry.height || bodyLines >= maxBodyLines)
241
- break;
242
- }
243
- // Rewrite header with the actual rendered end range.
244
- rows[0] = renderInsetWrappedSurface(createSegmentSurface([
245
- { text: options.labels?.headerLabel?.({
246
- filterLabel: filterName,
247
- start: start + 1,
248
- end: Math.max(start + 1, end),
249
- total: filtered.length,
250
- }) ?? `History • ${filterName} • ${start + 1}-${Math.max(start + 1, end)} of ${filtered.length}`,
251
- style: withModifiers({}, ['bold']) },
252
- ]), safeWidth)[0];
253
- return vstackSurface(...rows);
254
- }
255
- function defaultDurationMs(variant) {
256
- switch (variant) {
257
- case 'ACTIONABLE':
258
- return null;
259
- case 'INLINE':
260
- return 5_000;
261
- case 'TOAST':
262
- return 4_000;
263
- }
264
- }
265
- function focusableIds(items) {
266
- return items
267
- .filter((item) => item.action != null)
268
- .map((item) => item.id);
269
- }
270
- function normalizeFocusedId(items, focusedId) {
271
- const focusable = focusableIds(items);
272
- if (focusable.length === 0)
273
- return undefined;
274
- if (focusedId != null && focusable.includes(focusedId))
275
- return focusedId;
276
- return focusable[focusable.length - 1];
277
- }
278
- function archiveNotifications(history, items) {
279
- if (items.length === 0)
280
- return history;
281
- const archived = [...items].sort((left, right) => right.updatedAtMs - left.updatedAtMs || right.id - left.id);
282
- return [...archived, ...history].slice(0, HISTORY_LIMIT);
283
- }
284
- function advanceExitRecord(item, nowMs) {
285
- const deltaMs = Math.max(0, nowMs - item.updatedAtMs);
286
- const progress = Math.max(0, item.progress - (deltaMs / EXIT_DURATION_MS));
287
- if (progress > 0) {
288
- return {
289
- active: {
290
- ...item,
291
- progress,
292
- updatedAtMs: nowMs,
293
- },
294
- };
295
- }
296
- return {
297
- archived: {
298
- ...item,
299
- progress: 0,
300
- updatedAtMs: nowMs,
301
- },
302
- };
303
- }
304
- export function pushNotification(state, spec, nowMs) {
305
- const variant = spec.variant ?? 'TOAST';
306
- const next = {
307
- id: state.nextId,
308
- title: spec.title,
309
- message: spec.message ?? '',
310
- variant,
311
- tone: spec.tone ?? 'INFO',
312
- width: spec.width,
313
- durationMs: spec.durationMs === undefined ? defaultDurationMs(variant) : spec.durationMs,
314
- placement: spec.placement ?? 'LOWER_RIGHT',
315
- action: spec.action,
316
- bgToken: spec.bgToken,
317
- accentToken: spec.accentToken,
318
- overflow: spec.overflow ?? 'wrap',
319
- createdAtMs: nowMs,
320
- updatedAtMs: nowMs,
321
- phase: 'entering',
322
- progress: 0,
323
- };
324
- const items = [...state.items, next];
325
- return {
326
- ...state,
327
- items,
328
- nextId: state.nextId + 1,
329
- focusedId: normalizeFocusedId(items, next.action != null ? next.id : state.focusedId),
330
- };
331
- }
332
- export function dismissNotification(state, id, nowMs) {
333
- const items = state.items.map((item) => {
334
- if (item.id !== id || item.phase === 'exiting')
335
- return item;
336
- return {
337
- ...item,
338
- phase: 'exiting',
339
- updatedAtMs: nowMs,
340
- exitStartedAtMs: nowMs,
341
- };
342
- });
343
- return {
344
- ...state,
345
- items,
346
- focusedId: normalizeFocusedId(items, state.focusedId),
347
- };
348
- }
349
- export function dismissFocusedNotification(state, nowMs) {
350
- if (state.focusedId == null)
351
- return state;
352
- return dismissNotification(state, state.focusedId, nowMs);
353
- }
354
- export function relocateNotifications(state, placement, nowMs) {
355
- if (state.items.every((item) => item.placement === placement))
356
- return state;
357
- return {
358
- ...state,
359
- items: state.items.map((item) => {
360
- if (nowMs == null || item.phase === 'exiting') {
361
- return { ...item, placement };
362
- }
363
- return {
364
- ...item,
365
- placement,
366
- phase: 'entering',
367
- progress: 0,
368
- updatedAtMs: nowMs,
369
- enteredAtMs: undefined,
370
- exitStartedAtMs: undefined,
371
- };
372
- }),
373
- };
374
- }
375
- export function cycleNotificationFocus(state, delta) {
376
- const focusable = focusableIds(state.items);
377
- if (focusable.length === 0)
378
- return state;
379
- const index = state.focusedId == null ? -1 : focusable.indexOf(state.focusedId);
380
- const nextIndex = index < 0
381
- ? (delta >= 0 ? 0 : focusable.length - 1)
382
- : (index + delta + focusable.length) % focusable.length;
383
- return {
384
- ...state,
385
- focusedId: focusable[nextIndex],
386
- };
387
- }
388
- export function activateFocusedNotification(state, nowMs) {
389
- if (state.focusedId == null)
390
- return { state };
391
- const target = state.items.find((item) => item.id === state.focusedId);
392
- if (target?.action == null)
393
- return { state };
394
- return {
395
- state: dismissNotification(state, target.id, nowMs),
396
- payload: target.action.payload,
397
- };
398
- }
399
- export function tickNotifications(state, nowMs) {
400
- const nextItems = [];
401
- const archived = [];
402
- const nextOverflowExits = [];
403
- const archivedOverflowExits = [];
404
- for (const item of state.items) {
405
- const deltaMs = Math.max(0, nowMs - item.updatedAtMs);
406
- if (item.phase === 'entering') {
407
- const progress = Math.min(1, item.progress + (deltaMs / ENTER_DURATION_MS));
408
- nextItems.push(progress >= 1
409
- ? {
410
- ...item,
411
- phase: 'visible',
412
- progress: 1,
413
- enteredAtMs: nowMs,
414
- updatedAtMs: nowMs,
415
- }
416
- : {
417
- ...item,
418
- progress,
419
- updatedAtMs: nowMs,
420
- });
421
- continue;
422
- }
423
- if (item.phase === 'visible') {
424
- const visibleSince = item.enteredAtMs ?? item.createdAtMs;
425
- if (item.durationMs != null && nowMs - visibleSince >= item.durationMs) {
426
- nextItems.push({
427
- ...item,
428
- phase: 'exiting',
429
- exitStartedAtMs: nowMs,
430
- updatedAtMs: nowMs,
431
- });
432
- }
433
- else {
434
- nextItems.push({
435
- ...item,
436
- updatedAtMs: nowMs,
437
- });
438
- }
439
- continue;
440
- }
441
- const result = advanceExitRecord(item, nowMs);
442
- if (result.active != null) {
443
- nextItems.push(result.active);
444
- continue;
445
- }
446
- if (result.archived != null) {
447
- archived.push(result.archived);
448
- }
449
- }
450
- for (const item of state.overflowExits) {
451
- const result = advanceExitRecord(item, nowMs);
452
- if (result.active != null) {
453
- nextOverflowExits.push(result.active);
454
- continue;
455
- }
456
- if (result.archived != null) {
457
- archivedOverflowExits.push(result.archived);
458
- }
459
- }
460
- return {
461
- ...state,
462
- items: nextItems,
463
- overflowExits: nextOverflowExits,
464
- history: archiveNotifications(state.history, [...archived, ...archivedOverflowExits]),
465
- focusedId: normalizeFocusedId(nextItems, state.focusedId),
466
- };
467
- }
468
- export function hasNotifications(state) {
469
- return state.items.length > 0;
470
- }
471
- export function notificationsNeedTick(state) {
472
- return state.overflowExits.length > 0
473
- || state.items.some((item) => item.phase !== 'visible' || item.durationMs != null);
474
- }
475
- function toneSemanticKey(tone) {
476
- switch (tone) {
477
- case 'INFO':
478
- return 'info';
479
- case 'SUCCESS':
480
- return 'success';
481
- case 'WARNING':
482
- return 'warning';
483
- case 'ERROR':
484
- return 'error';
485
- }
486
- }
487
- function defaultBgToken(ctx) {
488
- return ctx?.theme.theme.surface.overlay;
489
- }
490
- function formatTimeLabel(ms) {
491
- return new Date(ms).toLocaleTimeString('en-US', {
492
- hour: '2-digit',
493
- minute: '2-digit',
494
- second: '2-digit',
495
- });
496
- }
497
- function tokenToCellStyle(token) {
498
- if (token == null)
499
- return {};
500
- // Pass pre-parsed RGB alongside hex so encodeCellIntoBuf can skip
501
- // inlineHexRGB on the hot path. Build the object with conditional
502
- // spreads so readonly fields stay readonly.
503
- return {
504
- fg: token.hex,
505
- bg: token.bg,
506
- ...(token.fgRGB ? { fgRGB: token.fgRGB } : {}),
507
- ...(token.bgRGB ? { bgRGB: token.bgRGB } : {}),
508
- modifiers: token.modifiers,
509
- };
510
- }
511
- function withModifiers(style, modifiers) {
512
- const next = new Set(style.modifiers ?? []);
513
- for (const modifier of modifiers) {
514
- next.add(modifier);
515
- }
516
- return {
517
- ...style,
518
- modifiers: next.size === 0 ? undefined : Array.from(next),
519
- };
520
- }
521
- function createSegmentSurface(segments) {
522
- const graphemeSegments = segments.map((segment) => ({
523
- graphemes: segmentGraphemes(segment.text ?? ''),
524
- style: segment.style,
525
- }));
526
- const width = graphemeSegments.reduce((sum, segment) => sum + segment.graphemes.length, 0);
527
- const surface = createSurface(width, 1);
528
- let x = 0;
529
- const packed = isPackedSurface(surface);
530
- for (const segment of graphemeSegments) {
531
- // Pre-parse style once per segment for setRGB fast path
532
- const s = segment.style;
533
- if (packed && s) {
534
- let fR = -1, fG = 0, fB = 0, bR = -1, bG = 0, bB = 0;
535
- const fgHex = resolvedColorHex(s.fg);
536
- const fgRgb = s.fgRGB ?? resolvedColorRgb(s.fg) ?? (fgHex ? parseHex(fgHex) : undefined);
537
- if (fgRgb) {
538
- [fR, fG, fB] = fgRgb;
539
- }
540
- const bgHex = resolvedColorHex(s.bg);
541
- const bgRgb = s.bgRGB ?? resolvedColorRgb(s.bg) ?? (bgHex ? parseHex(bgHex) : undefined);
542
- if (bgRgb) {
543
- [bR, bG, bB] = bgRgb;
544
- }
545
- const fl = s.modifiers ? encodeModifiers(s.modifiers) : 0;
546
- for (const char of segment.graphemes) {
547
- surface.setRGB(x, 0, char, fR, fG, fB, bR, bG, bB, fl);
548
- x++;
549
- }
550
- }
551
- else {
552
- for (const char of segment.graphemes) {
553
- surface.set(x, 0, {
554
- char,
555
- fg: s?.fg,
556
- bg: s?.bg,
557
- fgRGB: s?.fgRGB,
558
- bgRGB: s?.bgRGB,
559
- modifiers: s?.modifiers ? [...s.modifiers] : undefined,
560
- empty: false,
561
- });
562
- x++;
563
- }
564
- }
565
- }
566
- return surface;
567
- }
568
- function createBlankLineSurface(width) {
569
- return createSurface(Math.max(0, width), 1);
570
- }
571
- function insetContentSurface(surface, width) {
572
- const safeWidth = Math.max(1, width);
573
- const inset = safeWidth >= 3 ? 1 : 0;
574
- const innerWidth = Math.max(1, safeWidth - (inset * 2));
575
- const result = createSurface(safeWidth, surface.height);
576
- result.blit(surface, inset, 0, 0, 0, innerWidth, surface.height);
577
- return result;
578
- }
579
- function renderInsetWrappedSurface(lineSurface, width) {
580
- const safeWidth = Math.max(1, width);
581
- const inset = safeWidth >= 3 ? 1 : 0;
582
- const innerWidth = Math.max(1, safeWidth - (inset * 2));
583
- return standaloneRows(lineSurface, innerWidth, 'wrap').map((row) => insetContentSurface(row, safeWidth));
584
- }
585
- function clipSurfaceHeight(surface, height) {
586
- const safeHeight = Math.max(0, height);
587
- if (surface.height <= safeHeight)
588
- return surface;
589
- const clipped = createSurface(surface.width, safeHeight);
590
- clipped.blit(surface, 0, 0, 0, 0, surface.width, safeHeight);
591
- return clipped;
592
- }
593
- function fitLineSurface(surface, width) {
594
- const safeWidth = Math.max(0, width);
595
- const line = createSurface(safeWidth, 1);
596
- if (safeWidth > 0) {
597
- line.blit(surface, 0, 0, 0, 0, safeWidth, 1);
598
- }
599
- return line;
600
- }
601
- function wrapLineSurface(surface, width) {
602
- const safeWidth = Math.max(1, width);
603
- if (surface.width === 0)
604
- return [createBlankLineSurface(safeWidth)];
605
- const rows = [];
606
- let offset = 0;
607
- while (offset < surface.width) {
608
- const hardEnd = Math.min(surface.width, offset + safeWidth);
609
- const end = hardEnd >= surface.width
610
- ? surface.width
611
- : wordBoundarySurfaceEnd(surface, offset, hardEnd);
612
- rows.push(sliceLineSurface(surface, offset, end, safeWidth));
613
- offset = hardEnd >= surface.width
614
- ? surface.width
615
- : trimLeadingSurfaceWhitespace(surface, end < hardEnd ? end + 1 : hardEnd);
616
- }
617
- return rows.length === 0 ? [createBlankLineSurface(safeWidth)] : rows;
618
- }
619
- function sliceLineSurface(surface, start, end, width) {
620
- const row = createSurface(width, 1);
621
- const span = Math.max(0, Math.min(surface.width, end) - start);
622
- if (span > 0) {
623
- row.blit(surface, 0, 0, start, 0, span, 1);
624
- }
625
- return row;
626
- }
627
- function wordBoundarySurfaceEnd(surface, start, hardEnd) {
628
- let breakAt = -1;
629
- for (let index = start; index < hardEnd; index++) {
630
- if (isWhitespaceSurfaceCell(surface, index)) {
631
- breakAt = index;
632
- }
633
- }
634
- return breakAt > start ? breakAt : hardEnd;
635
- }
636
- function trimLeadingSurfaceWhitespace(surface, start) {
637
- let offset = start;
638
- while (offset < surface.width && isWhitespaceSurfaceCell(surface, offset)) {
639
- offset++;
640
- }
641
- return offset;
642
- }
643
- function isWhitespaceSurfaceCell(surface, col) {
644
- return /^\s+$/.test(surface.get(col, 0).char);
645
- }
646
- function renderPlainSurface(surface) {
647
- const lines = [];
648
- for (let y = 0; y < surface.height; y++) {
649
- let line = '';
650
- for (let x = 0; x < surface.width; x++) {
651
- line += surface.get(x, y).char;
652
- }
653
- lines.push(line);
654
- }
655
- return lines.join('\n');
656
- }
657
- function standaloneRows(lineSurface, width, overflow) {
658
- if (overflow === 'truncate')
659
- return [fitLineSurface(lineSurface, width)];
660
- return wrapLineSurface(lineSurface, width);
661
- }
662
- function composeColumnRows(left, right, width, overflow) {
663
- const safeWidth = Math.max(1, width);
664
- const rightWidth = Math.min(right.width, safeWidth);
665
- if (overflow === 'truncate') {
666
- const row = createSurface(safeWidth, 1);
667
- const leftWidth = Math.max(0, safeWidth - rightWidth);
668
- if (leftWidth > 0) {
669
- row.blit(left, 0, 0, 0, 0, leftWidth, 1);
670
- }
671
- if (rightWidth > 0) {
672
- row.blit(right, safeWidth - rightWidth, 0, Math.max(0, right.width - rightWidth), 0, rightWidth, 1);
673
- }
674
- return [row];
675
- }
676
- const gap = rightWidth > 0 ? 1 : 0;
677
- const leftWidth = Math.max(1, safeWidth - rightWidth - gap);
678
- const wrappedLeft = wrapLineSurface(left, leftWidth);
679
- return wrappedLeft.map((rowSurface, index) => {
680
- const row = createSurface(safeWidth, 1);
681
- row.blit(rowSurface, 0, 0);
682
- if (index === 0 && rightWidth > 0) {
683
- row.blit(right, safeWidth - rightWidth, 0, Math.max(0, right.width - rightWidth), 0, rightWidth, 1);
684
- }
685
- return row;
686
- });
687
- }
688
- function resolveRegion(options) {
689
- const screenWidth = Math.max(0, options.screenWidth);
690
- const screenHeight = Math.max(0, options.screenHeight);
691
- if (options.region == null) {
692
- return { row: 0, col: 0, width: screenWidth, height: screenHeight };
693
- }
694
- return {
695
- row: Math.max(0, options.region.row),
696
- col: Math.max(0, options.region.col),
697
- width: Math.max(0, options.region.width),
698
- height: Math.max(0, options.region.height),
699
- };
700
- }
701
- function measureTextWidth(item, screenWidth) {
702
- const available = Math.max(18, screenWidth - 7);
703
- if (item.width != null) {
704
- return Math.max(18, Math.min(available, item.width));
705
- }
706
- const titleWidth = visibleLength(item.title);
707
- const messageWidth = visibleLength(item.message);
708
- const buttonWidth = item.action == null ? 0 : visibleLength(item.action.label) + 6;
709
- const base = Math.max(titleWidth + 8, messageWidth + 2, buttonWidth + 2);
710
- if (item.variant === 'INLINE') {
711
- const target = Math.max(base + 8, Math.floor(screenWidth * 0.66));
712
- return Math.min(available, Math.max(28, target));
713
- }
714
- return Math.min(available, Math.max(26, Math.min(52, base + 6)));
715
- }
716
- function renderNotificationSurface(item, options, focused) {
717
- const ctx = options.ctx;
718
- const textWidth = measureTextWidth(item, resolveRegion(options).width);
719
- const mutedStyle = tokenToCellStyle(ctx?.semantic('muted'));
720
- const titleStyle = withModifiers({}, ['bold']);
721
- const iconStyle = tokenToCellStyle(ctx?.semantic(toneSemanticKey(item.tone)));
722
- const accentStyle = tokenToCellStyle(item.accentToken ?? ctx?.border(TONE_BORDER_KEYS[item.tone]));
723
- const backgroundStyle = tokenToCellStyle(item.bgToken ?? defaultBgToken(ctx));
724
- const closeSurface = createSegmentSurface([{ text: '\u2715', style: mutedStyle }]);
725
- const icon = TONE_ICONS[item.tone];
726
- const overflow = item.overflow;
727
- const rows = [];
728
- let actionRect;
729
- if (item.variant === 'INLINE') {
730
- const left = createSegmentSurface([
731
- { text: icon, style: iconStyle },
732
- { text: ' ' },
733
- { text: item.title, style: titleStyle },
734
- ...(item.message.length > 0
735
- ? [
736
- { text: ' ' },
737
- { text: item.message, style: mutedStyle },
738
- ]
739
- : []),
740
- ]);
741
- rows.push(...composeColumnRows(left, closeSurface, textWidth, overflow));
742
- }
743
- else {
744
- const titleLeft = createSegmentSurface([
745
- { text: icon, style: iconStyle },
746
- { text: ' ' },
747
- { text: item.title, style: titleStyle },
748
- ]);
749
- rows.push(...composeColumnRows(titleLeft, closeSurface, textWidth, overflow));
750
- if (item.message.length > 0) {
751
- const messageSurface = createSegmentSurface([{ text: item.message, style: mutedStyle }]);
752
- rows.push(...standaloneRows(messageSurface, textWidth, overflow));
753
- }
754
- if (item.variant === 'ACTIONABLE') {
755
- rows.push(createBlankLineSurface(textWidth));
756
- const actionLabel = item.action == null
757
- ? 'Dismiss'
758
- : (focused ? `[ ${item.action.label} ]` : ` ${item.action.label} `);
759
- const actionStyle = focused ? withModifiers({}, ['bold']) : {};
760
- const actionRows = standaloneRows(createSegmentSurface([{ text: actionLabel, style: actionStyle }]), textWidth, overflow);
761
- actionRect = {
762
- row: rows.length,
763
- col: 2,
764
- width: textWidth,
765
- height: actionRows.length,
766
- };
767
- rows.push(...actionRows);
768
- }
769
- if (item.variant === 'TOAST') {
770
- rows.push(createBlankLineSurface(textWidth));
771
- const timestampSurface = createSegmentSurface([{ text: formatTimeLabel(item.createdAtMs), style: mutedStyle }]);
772
- rows.push(...standaloneRows(timestampSurface, textWidth, overflow));
773
- }
774
- }
775
- const contentRows = rows.length === 0 ? [createBlankLineSurface(textWidth)] : rows;
776
- const cardWidth = textWidth + 3;
777
- const cardHeight = contentRows.length;
778
- const card = createSurface(cardWidth, cardHeight, {
779
- char: ' ',
780
- fg: backgroundStyle.fg,
781
- bg: backgroundStyle.bg,
782
- modifiers: backgroundStyle.modifiers ? [...backgroundStyle.modifiers] : undefined,
783
- empty: false,
784
- });
785
- const cardPacked = isPackedSurface(card);
786
- for (let y = 0; y < contentRows.length; y++) {
787
- const accentRgb = cardPacked
788
- ? (() => {
789
- const accentHex = resolvedColorHex(accentStyle.fg);
790
- return accentStyle.fgRGB ?? resolvedColorRgb(accentStyle.fg) ?? (accentHex ? parseHex(accentHex) : undefined);
791
- })()
792
- : undefined;
793
- if (accentRgb) {
794
- const [fR, fG, fB] = accentRgb;
795
- let bR = -1, bG = 0, bB = 0;
796
- const backgroundHex = resolvedColorHex(backgroundStyle.bg);
797
- const bgRgb = backgroundStyle.bgRGB
798
- ?? resolvedColorRgb(backgroundStyle.bg)
799
- ?? (backgroundHex ? parseHex(backgroundHex) : undefined);
800
- if (bgRgb) {
801
- [bR, bG, bB] = bgRgb;
802
- }
803
- card.setRGB(0, y, '\u258e', fR, fG, fB, bR, bG, bB, encodeModifiers(accentStyle.modifiers));
804
- }
805
- else {
806
- card.set(0, y, {
807
- char: '\u258e',
808
- fg: accentStyle.fg,
809
- bg: backgroundStyle.bg,
810
- fgRGB: accentStyle.fgRGB,
811
- bgRGB: backgroundStyle.bgRGB,
812
- modifiers: accentStyle.modifiers ? [...accentStyle.modifiers] : undefined,
813
- empty: false,
814
- });
815
- }
816
- card.blit(contentRows[y], 2, y, 0, 0, contentRows[y].width, 1, {
817
- char: true,
818
- fg: true,
819
- bg: false,
820
- modifiers: true,
821
- alpha: true,
822
- });
823
- }
824
- return {
825
- item,
826
- surface: card,
827
- dismissRect: {
828
- row: 0,
829
- col: Math.max(0, card.width - 2),
830
- width: 1,
831
- height: 1,
832
- },
833
- actionRect,
834
- };
835
- }
836
- function sortForPlacement(items, placement) {
837
- const ordered = [...items].sort((left, right) => right.createdAtMs - left.createdAtMs || right.id - left.id);
838
- return placementSortSign(placement) === 'bottom' ? ordered.reverse() : ordered;
839
- }
840
- function placementSortSign(placement) {
841
- switch (placement) {
842
- case 'UPPER_LEFT':
843
- case 'UPPER_RIGHT':
844
- case 'TOP_CENTER':
845
- return 'top';
846
- case 'LOWER_LEFT':
847
- case 'LOWER_RIGHT':
848
- case 'BOTTOM_CENTER':
849
- return 'bottom';
850
- case 'CENTER':
851
- return 'center';
852
- }
853
- }
854
- function anchoredCol(placement, width, screenWidth, margin) {
855
- switch (placement) {
856
- case 'UPPER_LEFT':
857
- case 'LOWER_LEFT':
858
- return margin;
859
- case 'UPPER_RIGHT':
860
- case 'LOWER_RIGHT':
861
- return Math.max(margin, screenWidth - width - margin);
862
- case 'TOP_CENTER':
863
- case 'BOTTOM_CENTER':
864
- case 'CENTER':
865
- return Math.max(0, Math.floor((screenWidth - width) / 2));
866
- }
867
- }
868
- function applyAnimationOffset(placement, width, height, margin, progress) {
869
- const remaining = 1 - progress;
870
- const slideX = Math.round(remaining * (width + margin));
871
- const slideY = Math.round(remaining * (height + margin));
872
- switch (placement) {
873
- case 'UPPER_LEFT':
874
- case 'LOWER_LEFT':
875
- return { rowDelta: 0, colDelta: -slideX };
876
- case 'UPPER_RIGHT':
877
- case 'LOWER_RIGHT':
878
- return { rowDelta: 0, colDelta: slideX };
879
- case 'TOP_CENTER':
880
- return { rowDelta: -slideY, colDelta: 0 };
881
- case 'BOTTOM_CENTER':
882
- return { rowDelta: slideY, colDelta: 0 };
883
- case 'CENTER':
884
- return { rowDelta: -slideY, colDelta: 0 };
885
- }
886
- }
887
- function createRenderEntry(item, options, focusedId) {
888
- return renderNotificationSurface(item, options, focusedId === item.id);
889
- }
890
- function prepareRenderEntriesById(items, options, focusedId) {
891
- const prepared = new Map();
892
- for (const item of items) {
893
- prepared.set(item.id, createRenderEntry(item, options, focusedId));
894
- }
895
- return prepared;
896
- }
897
- function selectVisibleNotificationIds(state, options, preparedEntries = prepareRenderEntriesById(state.items, options, state.focusedId)) {
898
- const region = resolveRegion(options);
899
- const margin = resolveOverlayMargin(region.width, region.height, options.margin);
900
- const gap = resolveNotificationGap(options.gap);
901
- const availableHeight = Math.max(1, region.height - (margin * 2));
902
- const grouped = new Map();
903
- for (const item of state.items) {
904
- const placementItems = grouped.get(item.placement) ?? [];
905
- placementItems.push(item);
906
- grouped.set(item.placement, placementItems);
907
- }
908
- const visibleIds = new Set();
909
- for (const items of grouped.values()) {
910
- const newestFirst = [...items].sort((left, right) => right.createdAtMs - left.createdAtMs || right.id - left.id);
911
- let usedHeight = 0;
912
- let keptCount = 0;
913
- for (const item of newestFirst) {
914
- const entry = preparedEntries.get(item.id);
915
- const required = entry.surface.height + (keptCount > 0 ? gap : 0);
916
- if (keptCount === 0 || usedHeight + required <= availableHeight) {
917
- visibleIds.add(item.id);
918
- usedHeight += required;
919
- keptCount++;
920
- }
921
- }
922
- }
923
- return visibleIds;
924
- }
925
- export function trimNotificationsToViewport(state, options, nowMs) {
926
- const visibleIds = selectVisibleNotificationIds(state, options);
927
- const keptItems = state.items.filter((item) => visibleIds.has(item.id));
928
- if (keptItems.length === state.items.length) {
929
- const focusedId = normalizeFocusedId(keptItems, state.focusedId);
930
- return focusedId === state.focusedId ? state : { ...state, focusedId };
931
- }
932
- const evictedItems = state.items.filter((item) => !visibleIds.has(item.id));
933
- const exitStartedAtMs = nowMs ?? evictedItems.reduce((max, item) => Math.max(max, item.updatedAtMs, item.createdAtMs), 0);
934
- const overflowExits = [
935
- ...state.overflowExits,
936
- ...evictedItems.map((item) => ({
937
- ...item,
938
- phase: 'exiting',
939
- progress: 1,
940
- updatedAtMs: exitStartedAtMs,
941
- exitStartedAtMs,
942
- })),
943
- ].sort((left, right) => right.updatedAtMs - left.updatedAtMs || right.id - left.id);
944
- return {
945
- ...state,
946
- items: keptItems,
947
- overflowExits,
948
- focusedId: normalizeFocusedId(keptItems, state.focusedId),
949
- };
950
- }
951
- function renderOverflowExits(exits, placement, activeTotalHeight, region, margin, gap, preparedEntries) {
952
- if (exits.length === 0)
953
- return [];
954
- const rendered = [...exits]
955
- .sort((left, right) => right.updatedAtMs - left.updatedAtMs || right.id - left.id)
956
- .map((item) => preparedEntries.get(item.id))
957
- .filter((entry) => entry != null);
958
- const entries = [];
959
- const mode = placementSortSign(placement);
960
- if (mode === 'bottom') {
961
- let cursor = Math.max(margin, region.height - activeTotalHeight - margin) - gap;
962
- for (const entry of rendered) {
963
- cursor -= entry.surface.height;
964
- const baseCol = anchoredCol(placement, entry.surface.width, region.width, margin);
965
- const offset = applyAnimationOffset(placement, entry.surface.width, entry.surface.height, margin, entry.item.progress);
966
- entries.push({
967
- ...entry,
968
- row: region.row + cursor + offset.rowDelta,
969
- col: region.col + baseCol + offset.colDelta,
970
- });
971
- cursor -= gap;
972
- }
973
- return entries;
974
- }
975
- let cursor = mode === 'top'
976
- ? margin + activeTotalHeight + (activeTotalHeight > 0 ? gap : 0)
977
- : Math.max(0, Math.floor((region.height + activeTotalHeight) / 2) + gap);
978
- for (const entry of rendered) {
979
- const baseCol = anchoredCol(placement, entry.surface.width, region.width, margin);
980
- const offset = applyAnimationOffset(placement, entry.surface.width, entry.surface.height, margin, entry.item.progress);
981
- entries.push({
982
- ...entry,
983
- row: region.row + cursor + offset.rowDelta,
984
- col: region.col + baseCol + offset.colDelta,
985
- });
986
- cursor += entry.surface.height + gap;
987
- }
988
- return entries;
989
- }
990
- function resolveNotificationOverlayEntries(state, options) {
991
- const screenWidth = Math.max(0, options.screenWidth);
992
- const screenHeight = Math.max(0, options.screenHeight);
993
- if (screenWidth <= 0 || screenHeight <= 0)
994
- return [];
995
- const region = resolveRegion(options);
996
- if (region.width <= 0 || region.height <= 0)
997
- return [];
998
- const margin = resolveOverlayMargin(region.width, region.height, options.margin);
999
- const gap = resolveNotificationGap(options.gap);
1000
- const activePrepared = prepareRenderEntriesById(state.items, options, state.focusedId);
1001
- const overflowPrepared = prepareRenderEntriesById(state.overflowExits, options, state.focusedId);
1002
- const visibleIds = selectVisibleNotificationIds(state, options, activePrepared);
1003
- const grouped = new Map();
1004
- const overflowGrouped = new Map();
1005
- for (const item of state.items) {
1006
- if (!visibleIds.has(item.id))
1007
- continue;
1008
- const placementItems = grouped.get(item.placement) ?? [];
1009
- placementItems.push(item);
1010
- grouped.set(item.placement, placementItems);
1011
- }
1012
- for (const item of state.overflowExits) {
1013
- const placementItems = overflowGrouped.get(item.placement) ?? [];
1014
- placementItems.push(item);
1015
- overflowGrouped.set(item.placement, placementItems);
1016
- }
1017
- const entries = [];
1018
- const placements = new Set([
1019
- ...grouped.keys(),
1020
- ...overflowGrouped.keys(),
1021
- ]);
1022
- for (const placement of placements) {
1023
- const items = grouped.get(placement) ?? [];
1024
- const rendered = sortForPlacement(items, placement).map((item) => activePrepared.get(item.id)).filter((entry) => entry != null);
1025
- const totalHeight = rendered.reduce((sum, entry) => sum + entry.surface.height, 0)
1026
- + Math.max(0, rendered.length - 1) * gap;
1027
- const mode = placementSortSign(placement);
1028
- let cursor = mode === 'top'
1029
- ? margin
1030
- : (mode === 'bottom'
1031
- ? Math.max(margin, region.height - totalHeight - margin)
1032
- : Math.max(0, Math.floor((region.height - totalHeight) / 2)));
1033
- for (const entry of rendered) {
1034
- const baseRow = cursor;
1035
- const baseCol = anchoredCol(placement, entry.surface.width, region.width, margin);
1036
- const offset = applyAnimationOffset(placement, entry.surface.width, entry.surface.height, margin, entry.item.progress);
1037
- entries.push({
1038
- ...entry,
1039
- row: region.row + baseRow + offset.rowDelta,
1040
- col: region.col + baseCol + offset.colDelta,
1041
- });
1042
- cursor += entry.surface.height + gap;
1043
- }
1044
- entries.push(...renderOverflowExits(overflowGrouped.get(placement) ?? [], placement, totalHeight, region, margin, gap, overflowPrepared));
1045
- }
1046
- return entries;
1047
- }
1048
- function containsRect(rect, col, row) {
1049
- if (rect == null)
1050
- return false;
1051
- return col >= rect.col
1052
- && col < rect.col + rect.width
1053
- && row >= rect.row
1054
- && row < rect.row + rect.height;
1055
- }
1056
- export function hitTestNotificationStack(state, options, col, row) {
1057
- const entries = resolveNotificationOverlayEntries(state, options);
1058
- for (let index = entries.length - 1; index >= 0; index--) {
1059
- const entry = entries[index];
1060
- if (col < entry.col
1061
- || col >= entry.col + entry.surface.width
1062
- || row < entry.row
1063
- || row >= entry.row + entry.surface.height) {
1064
- continue;
1065
- }
1066
- const localCol = col - entry.col;
1067
- const localRow = row - entry.row;
1068
- if (containsRect(entry.dismissRect, localCol, localRow)) {
1069
- return { item: entry.item, kind: 'dismiss' };
1070
- }
1071
- if (containsRect(entry.actionRect, localCol, localRow)) {
1072
- return { item: entry.item, kind: 'action' };
1073
- }
1074
- return { item: entry.item, kind: 'body' };
1075
- }
1076
- return undefined;
1077
- }
1078
- export function renderNotificationStack(state, options) {
1079
- return resolveNotificationOverlayEntries(state, options).map((entry) => ({
1080
- row: entry.row,
1081
- col: entry.col,
1082
- surface: entry.surface,
1083
- content: options.ctx != null
1084
- ? surfaceToString(entry.surface, options.ctx.style)
1085
- : renderPlainSurface(entry.surface),
1086
- }));
1087
- }
1
+ export { hitTestNotificationStack, renderNotificationStack, trimNotificationsToViewport, } from './notification-stack.js';
2
+ export { resolvedColorHex, resolvedColorRgb } from './notification.part01.js';
3
+ export { countNotificationHistory, createNotificationState } from './notification.part02.js';
4
+ export { renderNotificationHistory } from './notification.part03.js';
5
+ export { renderNotificationReviewEntrySurface } from './notification.part04.js';
6
+ export { renderNotificationHistorySurface } from './notification.part05.js';
7
+ export { normalizeFocusedId, pushNotification } from './notification.part06.js';
8
+ export { activateFocusedNotification, cycleNotificationFocus, dismissFocusedNotification, dismissNotification, relocateNotifications } from './notification.part07.js';
9
+ export { hasNotifications, notificationsNeedTick, tickNotifications } from './notification.part08.js';
10
+ export { createBlankLineSurface, createSegmentSurface, defaultBgToken, formatTimeLabel, tokenToCellStyle, toneSemanticKey, withModifiers } from './notification.part09.js';
11
+ export { renderPlainSurface, standaloneRows } from './notification.part10.js';
12
+ export { composeColumnRows, resolveRegion } from './notification.part11.js';
1088
13
  //# sourceMappingURL=notification.js.map