@gjermundgaraba-designs/pixel-paper 0.26.0 → 0.27.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 (940) hide show
  1. package/DESIGN.md +28 -3
  2. package/dist/src/adapters/diagram.d.ts +38 -0
  3. package/dist/src/adapters/diagram.d.ts.map +1 -0
  4. package/dist/src/adapters/diagram.js +206 -0
  5. package/dist/src/adapters/mermaid.d.ts +2 -20
  6. package/dist/src/adapters/mermaid.d.ts.map +1 -1
  7. package/dist/src/adapters/mermaid.js +9 -229
  8. package/dist/src/announcer/announcer.d.ts +0 -4
  9. package/dist/src/announcer/announcer.d.ts.map +1 -1
  10. package/dist/src/announcer/announcer.js +19 -18
  11. package/dist/src/attributes/attributes.d.ts.map +1 -1
  12. package/dist/src/{audioFrame/audioFrame.d.ts → audio-frame/audio-frame.d.ts} +1 -1
  13. package/dist/src/audio-frame/audio-frame.d.ts.map +1 -0
  14. package/dist/src/{audioFrame/audioFrame.js → audio-frame/audio-frame.js} +1 -1
  15. package/dist/src/audio-frame/index.d.ts +3 -0
  16. package/dist/src/audio-frame/index.d.ts.map +1 -0
  17. package/dist/src/audio-frame/index.js +1 -0
  18. package/dist/src/banner/banner.d.ts.map +1 -1
  19. package/dist/src/banner/index.d.ts.map +1 -1
  20. package/dist/src/{barChart/barChart.d.ts → bar-chart/bar-chart.d.ts} +2 -2
  21. package/dist/src/bar-chart/bar-chart.d.ts.map +1 -0
  22. package/dist/src/{barChart/barChart.js → bar-chart/bar-chart.js} +40 -35
  23. package/dist/src/bar-chart/index.d.ts +3 -0
  24. package/dist/src/bar-chart/index.d.ts.map +1 -0
  25. package/dist/src/bar-chart/index.js +1 -0
  26. package/dist/src/bench/bench.d.ts.map +1 -1
  27. package/dist/src/bench/index.d.ts.map +1 -1
  28. package/dist/src/board/board.d.ts +45 -46
  29. package/dist/src/board/board.d.ts.map +1 -1
  30. package/dist/src/board/board.js +76 -102
  31. package/dist/src/board/index.d.ts +1 -1
  32. package/dist/src/board/index.d.ts.map +1 -1
  33. package/dist/src/button/button.d.ts +1 -2
  34. package/dist/src/button/button.d.ts.map +1 -1
  35. package/dist/src/button/button.js +7 -5
  36. package/dist/src/button/index.d.ts +1 -1
  37. package/dist/src/button/index.d.ts.map +1 -1
  38. package/dist/src/card/card.d.ts.map +1 -1
  39. package/dist/src/card/card.js +4 -2
  40. package/dist/src/card/index.d.ts.map +1 -1
  41. package/dist/src/{chartTable/chartTable.d.ts → chart-table/chart-table.d.ts} +4 -14
  42. package/dist/src/chart-table/chart-table.d.ts.map +1 -0
  43. package/dist/src/{chartTable/chartTable.js → chart-table/chart-table.js} +9 -16
  44. package/dist/src/chip/chip.d.ts.map +1 -1
  45. package/dist/src/chip/chip.js +4 -2
  46. package/dist/src/chip/index.d.ts.map +1 -1
  47. package/dist/src/choice/choice.d.ts.map +1 -1
  48. package/dist/src/choice/choice.js +3 -1
  49. package/dist/src/choice/index.d.ts.map +1 -1
  50. package/dist/src/choices/choices.d.ts.map +1 -1
  51. package/dist/src/choices/index.d.ts.map +1 -1
  52. package/dist/src/{codeEditor/codeEditor.d.ts → code-editor/code-editor.d.ts} +1 -1
  53. package/dist/src/code-editor/code-editor.d.ts.map +1 -0
  54. package/dist/src/{codeEditor/codeEditor.js → code-editor/code-editor.js} +2 -2
  55. package/dist/src/code-editor/index.d.ts +3 -0
  56. package/dist/src/code-editor/index.d.ts.map +1 -0
  57. package/dist/src/code-editor/index.js +1 -0
  58. package/dist/src/{codeSurface/codeSurface.d.ts → code-surface/code-surface.d.ts} +1 -1
  59. package/dist/src/code-surface/code-surface.d.ts.map +1 -0
  60. package/dist/src/{codeSurface/codeSurface.js → code-surface/code-surface.js} +6 -1
  61. package/dist/src/code-surface/index.d.ts +3 -0
  62. package/dist/src/code-surface/index.d.ts.map +1 -0
  63. package/dist/src/code-surface/index.js +1 -0
  64. package/dist/src/{commandPalette/commandPalette.d.ts → command-palette/command-palette.d.ts} +85 -77
  65. package/dist/src/command-palette/command-palette.d.ts.map +1 -0
  66. package/dist/src/command-palette/command-palette.js +625 -0
  67. package/dist/src/{commandPalette → command-palette}/index.d.ts +2 -2
  68. package/dist/src/command-palette/index.d.ts.map +1 -0
  69. package/dist/src/{commandPalette → command-palette}/index.js +1 -1
  70. package/dist/src/{commandPalette → command-palette}/keys.d.ts +0 -21
  71. package/dist/src/command-palette/keys.d.ts.map +1 -0
  72. package/dist/src/command-palette/keys.js +85 -0
  73. package/dist/src/{commandPalette → command-palette}/match.d.ts +5 -11
  74. package/dist/src/command-palette/match.d.ts.map +1 -0
  75. package/dist/src/{commandPalette → command-palette}/match.js +20 -24
  76. package/dist/src/{commandPalette → command-palette}/message.d.ts +37 -26
  77. package/dist/src/command-palette/message.d.ts.map +1 -0
  78. package/dist/src/{commandPalette → command-palette}/message.js +8 -20
  79. package/dist/src/{confirmDialog/confirmDialog.d.ts → confirm-dialog/confirm-dialog.d.ts} +1 -1
  80. package/dist/src/confirm-dialog/confirm-dialog.d.ts.map +1 -0
  81. package/dist/src/{confirmDialog/confirmDialog.js → confirm-dialog/confirm-dialog.js} +18 -23
  82. package/dist/src/confirm-dialog/index.d.ts +3 -0
  83. package/dist/src/confirm-dialog/index.d.ts.map +1 -0
  84. package/dist/src/{confirmDialog → confirm-dialog}/index.js +1 -1
  85. package/dist/src/{contextMenu/contextMenu.d.ts → context-menu/context-menu.d.ts} +18 -21
  86. package/dist/src/context-menu/context-menu.d.ts.map +1 -0
  87. package/dist/src/{contextMenu/contextMenu.js → context-menu/context-menu.js} +45 -57
  88. package/dist/src/{contextMenu → context-menu}/index.d.ts +2 -2
  89. package/dist/src/context-menu/index.d.ts.map +1 -0
  90. package/dist/src/{contextMenu → context-menu}/index.js +1 -1
  91. package/dist/src/{copyButton/copyButton.d.ts → copy-button/copy-button.d.ts} +5 -7
  92. package/dist/src/copy-button/copy-button.d.ts.map +1 -0
  93. package/dist/src/{copyButton/copyButton.js → copy-button/copy-button.js} +18 -27
  94. package/dist/src/copy-button/index.d.ts +3 -0
  95. package/dist/src/copy-button/index.d.ts.map +1 -0
  96. package/dist/src/copy-button/index.js +1 -0
  97. package/dist/src/crumbs/crumbs.d.ts +1 -1
  98. package/dist/src/crumbs/crumbs.d.ts.map +1 -1
  99. package/dist/src/crumbs/index.d.ts.map +1 -1
  100. package/dist/src/deck/deck.d.ts.map +1 -1
  101. package/dist/src/deck/index.d.ts.map +1 -1
  102. package/dist/src/dialog/dialog.d.ts +6 -14
  103. package/dist/src/dialog/dialog.d.ts.map +1 -1
  104. package/dist/src/dialog/dialog.js +29 -36
  105. package/dist/src/dialog/fold.d.ts +3 -3
  106. package/dist/src/dialog/fold.d.ts.map +1 -1
  107. package/dist/src/dialog/fold.js +5 -4
  108. package/dist/src/dialog/index.d.ts +1 -1
  109. package/dist/src/dialog/index.d.ts.map +1 -1
  110. package/dist/src/disclosure/disclosure.d.ts.map +1 -1
  111. package/dist/src/disclosure/disclosure.js +3 -1
  112. package/dist/src/disclosure/index.d.ts.map +1 -1
  113. package/dist/src/dom/html-element.d.ts +3 -0
  114. package/dist/src/dom/html-element.d.ts.map +1 -0
  115. package/dist/src/dom/html-element.js +6 -0
  116. package/dist/src/drag/drag.d.ts +0 -34
  117. package/dist/src/drag/drag.d.ts.map +1 -1
  118. package/dist/src/drag/drag.js +27 -73
  119. package/dist/src/{dropZone/dropZone.d.ts → drop-zone/drop-zone.d.ts} +3 -3
  120. package/dist/src/drop-zone/drop-zone.d.ts.map +1 -0
  121. package/dist/src/{dropZone/dropZone.js → drop-zone/drop-zone.js} +13 -19
  122. package/dist/src/drop-zone/index.d.ts +3 -0
  123. package/dist/src/drop-zone/index.d.ts.map +1 -0
  124. package/dist/src/drop-zone/index.js +1 -0
  125. package/dist/src/{editableTitle/editableTitle.d.ts → editable-title/editable-title.d.ts} +14 -12
  126. package/dist/src/editable-title/editable-title.d.ts.map +1 -0
  127. package/dist/src/{editableTitle/editableTitle.js → editable-title/editable-title.js} +33 -39
  128. package/dist/src/editable-title/index.d.ts +4 -0
  129. package/dist/src/editable-title/index.d.ts.map +1 -0
  130. package/dist/src/{editableTitle → editable-title}/index.js +1 -1
  131. package/dist/src/{emptyState/emptyState.d.ts → empty-state/empty-state.d.ts} +1 -1
  132. package/dist/src/empty-state/empty-state.d.ts.map +1 -0
  133. package/dist/src/{emptyState/emptyState.js → empty-state/empty-state.js} +5 -2
  134. package/dist/src/empty-state/index.d.ts +3 -0
  135. package/dist/src/empty-state/index.d.ts.map +1 -0
  136. package/dist/src/empty-state/index.js +1 -0
  137. package/dist/src/{errorSummary/errorSummary.d.ts → error-summary/error-summary.d.ts} +2 -2
  138. package/dist/src/error-summary/error-summary.d.ts.map +1 -0
  139. package/dist/src/{errorSummary/errorSummary.js → error-summary/error-summary.js} +7 -5
  140. package/dist/src/error-summary/index.d.ts +3 -0
  141. package/dist/src/error-summary/index.d.ts.map +1 -0
  142. package/dist/src/error-summary/index.js +1 -0
  143. package/dist/src/field/field.d.ts +2 -7
  144. package/dist/src/field/field.d.ts.map +1 -1
  145. package/dist/src/field/field.js +12 -13
  146. package/dist/src/field/index.d.ts.map +1 -1
  147. package/dist/src/{fieldGrid/fieldGrid.d.ts → field-grid/field-grid.d.ts} +1 -1
  148. package/dist/src/field-grid/field-grid.d.ts.map +1 -0
  149. package/dist/src/{fieldGrid/fieldGrid.js → field-grid/field-grid.js} +1 -1
  150. package/dist/src/field-grid/index.d.ts +3 -0
  151. package/dist/src/field-grid/index.d.ts.map +1 -0
  152. package/dist/src/field-grid/index.js +1 -0
  153. package/dist/src/fields/fields.d.ts.map +1 -1
  154. package/dist/src/fields/fields.js +4 -1
  155. package/dist/src/fields/index.d.ts.map +1 -1
  156. package/dist/src/fieldset/fieldset.d.ts.map +1 -1
  157. package/dist/src/fieldset/index.d.ts.map +1 -1
  158. package/dist/src/{fileTree/fileTree.d.ts → file-tree/file-tree.d.ts} +5 -5
  159. package/dist/src/file-tree/file-tree.d.ts.map +1 -0
  160. package/dist/src/file-tree/file-tree.js +242 -0
  161. package/dist/src/file-tree/index.d.ts +3 -0
  162. package/dist/src/file-tree/index.d.ts.map +1 -0
  163. package/dist/src/{fileTree → file-tree}/index.js +1 -1
  164. package/dist/src/{filterChip/filterChip.d.ts → filter-chip/filter-chip.d.ts} +1 -1
  165. package/dist/src/filter-chip/filter-chip.d.ts.map +1 -0
  166. package/dist/src/{filterChip/filterChip.js → filter-chip/filter-chip.js} +11 -7
  167. package/dist/src/filter-chip/index.d.ts +3 -0
  168. package/dist/src/filter-chip/index.d.ts.map +1 -0
  169. package/dist/src/filter-chip/index.js +1 -0
  170. package/dist/src/{filterStrip/filterStrip.d.ts → filter-strip/filter-strip.d.ts} +1 -1
  171. package/dist/src/filter-strip/filter-strip.d.ts.map +1 -0
  172. package/dist/src/{filterStrip/filterStrip.js → filter-strip/filter-strip.js} +1 -1
  173. package/dist/src/filter-strip/index.d.ts +3 -0
  174. package/dist/src/filter-strip/index.d.ts.map +1 -0
  175. package/dist/src/filter-strip/index.js +1 -0
  176. package/dist/src/{flashWord/flashWord.d.ts → flash-word/flash-word.d.ts} +2 -2
  177. package/dist/src/flash-word/flash-word.d.ts.map +1 -0
  178. package/dist/src/{flashWord/flashWord.js → flash-word/flash-word.js} +2 -3
  179. package/dist/src/flash-word/index.d.ts +3 -0
  180. package/dist/src/flash-word/index.d.ts.map +1 -0
  181. package/dist/src/flash-word/index.js +1 -0
  182. package/dist/src/focus/focus.d.ts.map +1 -1
  183. package/dist/src/focus/focus.js +0 -2
  184. package/dist/src/format/format.d.ts +0 -7
  185. package/dist/src/format/format.d.ts.map +1 -1
  186. package/dist/src/format/format.js +7 -16
  187. package/dist/src/format/index.d.ts.map +1 -1
  188. package/dist/src/glyph/glyph.d.ts +1 -2
  189. package/dist/src/glyph/glyph.d.ts.map +1 -1
  190. package/dist/src/glyph/glyph.js +0 -2
  191. package/dist/src/glyph/glyphs.d.ts +19 -4
  192. package/dist/src/glyph/glyphs.d.ts.map +1 -1
  193. package/dist/src/glyph/glyphs.js +2577 -2594
  194. package/dist/src/glyph/index.d.ts.map +1 -1
  195. package/dist/src/group/group.d.ts.map +1 -1
  196. package/dist/src/group/index.d.ts.map +1 -1
  197. package/dist/src/history/history.d.ts +1 -1
  198. package/dist/src/history/history.d.ts.map +1 -1
  199. package/dist/src/history/history.js +6 -3
  200. package/dist/src/history/index.d.ts.map +1 -1
  201. package/dist/src/{iconButton/iconButton.d.ts → icon-button/icon-button.d.ts} +1 -1
  202. package/dist/src/icon-button/icon-button.d.ts.map +1 -0
  203. package/dist/src/{iconButton/iconButton.js → icon-button/icon-button.js} +6 -4
  204. package/dist/src/icon-button/index.d.ts +3 -0
  205. package/dist/src/icon-button/index.d.ts.map +1 -0
  206. package/dist/src/icon-button/index.js +1 -0
  207. package/dist/src/identity/identity.d.ts.map +1 -1
  208. package/dist/src/identity/index.d.ts.map +1 -1
  209. package/dist/src/{imageFrame/imageFrame.d.ts → image-frame/image-frame.d.ts} +1 -1
  210. package/dist/src/image-frame/image-frame.d.ts.map +1 -0
  211. package/dist/src/{imageFrame/imageFrame.js → image-frame/image-frame.js} +19 -12
  212. package/dist/src/image-frame/index.d.ts +3 -0
  213. package/dist/src/image-frame/index.d.ts.map +1 -0
  214. package/dist/src/image-frame/index.js +1 -0
  215. package/dist/src/index.d.ts +41 -41
  216. package/dist/src/index.d.ts.map +1 -1
  217. package/dist/src/index.js +41 -41
  218. package/dist/src/inline-input/index.d.ts +3 -0
  219. package/dist/src/inline-input/index.d.ts.map +1 -0
  220. package/dist/src/{inlineInput → inline-input}/index.js +1 -1
  221. package/dist/src/{inlineInput/inlineInput.d.ts → inline-input/inline-input.d.ts} +8 -12
  222. package/dist/src/inline-input/inline-input.d.ts.map +1 -0
  223. package/dist/src/{inlineInput/inlineInput.js → inline-input/inline-input.js} +60 -75
  224. package/dist/src/key-help/index.d.ts +3 -0
  225. package/dist/src/key-help/index.d.ts.map +1 -0
  226. package/dist/src/{keyHelp → key-help}/index.js +1 -1
  227. package/dist/src/{keyHelp/keyHelp.d.ts → key-help/key-help.d.ts} +7 -7
  228. package/dist/src/key-help/key-help.d.ts.map +1 -0
  229. package/dist/src/{keyHelp/keyHelp.js → key-help/key-help.js} +48 -47
  230. package/dist/src/key-hint/index.d.ts +4 -0
  231. package/dist/src/key-hint/index.d.ts.map +1 -0
  232. package/dist/src/key-hint/index.js +2 -0
  233. package/dist/src/{keyHint/keyHint.d.ts → key-hint/key-hint.d.ts} +2 -2
  234. package/dist/src/key-hint/key-hint.d.ts.map +1 -0
  235. package/dist/src/{keyHint/keyHint.js → key-hint/key-hint.js} +2 -2
  236. package/dist/src/{keyHint/keyLabel.d.ts → key-hint/key-label.d.ts} +2 -3
  237. package/dist/src/key-hint/key-label.d.ts.map +1 -0
  238. package/dist/src/{keyHint/keyLabel.js → key-hint/key-label.js} +29 -24
  239. package/dist/src/keymap/index.d.ts.map +1 -1
  240. package/dist/src/keymap/keymap.d.ts +2 -2
  241. package/dist/src/keymap/keymap.d.ts.map +1 -1
  242. package/dist/src/keymap/keymap.js +3 -1
  243. package/dist/src/keys/keys.d.ts +0 -2
  244. package/dist/src/keys/keys.d.ts.map +1 -1
  245. package/dist/src/keys/keys.js +0 -2
  246. package/dist/src/line-chart/index.d.ts +3 -0
  247. package/dist/src/line-chart/index.d.ts.map +1 -0
  248. package/dist/src/line-chart/index.js +1 -0
  249. package/dist/src/{lineChart/lineChart.d.ts → line-chart/line-chart.d.ts} +2 -2
  250. package/dist/src/line-chart/line-chart.d.ts.map +1 -0
  251. package/dist/src/{lineChart/lineChart.js → line-chart/line-chart.js} +52 -44
  252. package/dist/src/line-diff/diff.d.ts +29 -0
  253. package/dist/src/line-diff/diff.d.ts.map +1 -0
  254. package/dist/src/line-diff/diff.js +85 -0
  255. package/dist/src/line-diff/index.d.ts +5 -0
  256. package/dist/src/line-diff/index.d.ts.map +1 -0
  257. package/dist/src/line-diff/index.js +2 -0
  258. package/dist/src/{lineDiff/lineDiff.d.ts → line-diff/line-diff.d.ts} +1 -1
  259. package/dist/src/line-diff/line-diff.d.ts.map +1 -0
  260. package/dist/src/{lineDiff/lineDiff.js → line-diff/line-diff.js} +26 -19
  261. package/dist/src/{lineDiff → line-diff}/patch.d.ts +5 -9
  262. package/dist/src/line-diff/patch.d.ts.map +1 -0
  263. package/dist/src/{lineDiff → line-diff}/patch.js +54 -62
  264. package/dist/src/link-button/index.d.ts +3 -0
  265. package/dist/src/link-button/index.d.ts.map +1 -0
  266. package/dist/src/link-button/index.js +1 -0
  267. package/dist/src/{linkButton/linkButton.d.ts → link-button/link-button.d.ts} +2 -2
  268. package/dist/src/link-button/link-button.d.ts.map +1 -0
  269. package/dist/src/{linkButton/linkButton.js → link-button/link-button.js} +1 -1
  270. package/dist/src/link-state/index.d.ts +3 -0
  271. package/dist/src/link-state/index.d.ts.map +1 -0
  272. package/dist/src/link-state/index.js +1 -0
  273. package/dist/src/{linkState/linkState.d.ts → link-state/link-state.d.ts} +1 -1
  274. package/dist/src/link-state/link-state.d.ts.map +1 -0
  275. package/dist/src/link-state/link-state.js +24 -0
  276. package/dist/src/live-region/index.d.ts +3 -0
  277. package/dist/src/live-region/index.d.ts.map +1 -0
  278. package/dist/src/live-region/index.js +1 -0
  279. package/dist/src/{liveRegion/liveRegion.d.ts → live-region/live-region.d.ts} +6 -3
  280. package/dist/src/live-region/live-region.d.ts.map +1 -0
  281. package/dist/src/{liveRegion/liveRegion.js → live-region/live-region.js} +7 -5
  282. package/dist/src/loading/index.d.ts.map +1 -1
  283. package/dist/src/loading/loading.d.ts.map +1 -1
  284. package/dist/src/loading/loading.js +5 -1
  285. package/dist/src/mark/index.d.ts.map +1 -1
  286. package/dist/src/mark/mark.d.ts +0 -4
  287. package/dist/src/mark/mark.d.ts.map +1 -1
  288. package/dist/src/mark/mark.js +6 -3
  289. package/dist/src/media/index.d.ts.map +1 -1
  290. package/dist/src/media/media.d.ts +17 -42
  291. package/dist/src/media/media.d.ts.map +1 -1
  292. package/dist/src/media/media.js +106 -104
  293. package/dist/src/menu/index.d.ts.map +1 -1
  294. package/dist/src/menu/item.d.ts +8 -8
  295. package/dist/src/menu/item.d.ts.map +1 -1
  296. package/dist/src/menu/menu.d.ts +2 -5
  297. package/dist/src/menu/menu.d.ts.map +1 -1
  298. package/dist/src/menu/menu.js +19 -30
  299. package/dist/src/menu/slip.d.ts +4 -18
  300. package/dist/src/menu/slip.d.ts.map +1 -1
  301. package/dist/src/menu/slip.js +36 -36
  302. package/dist/src/meter/index.d.ts.map +1 -1
  303. package/dist/src/meter/meter.d.ts +1 -1
  304. package/dist/src/meter/meter.d.ts.map +1 -1
  305. package/dist/src/meter/meter.js +12 -15
  306. package/dist/src/monogram/index.d.ts.map +1 -1
  307. package/dist/src/monogram/monogram.d.ts.map +1 -1
  308. package/dist/src/monogram/monogram.js +9 -8
  309. package/dist/src/nav-strip/index.d.ts +3 -0
  310. package/dist/src/nav-strip/index.d.ts.map +1 -0
  311. package/dist/src/nav-strip/index.js +1 -0
  312. package/dist/src/{navStrip/navStrip.d.ts → nav-strip/nav-strip.d.ts} +3 -6
  313. package/dist/src/nav-strip/nav-strip.d.ts.map +1 -0
  314. package/dist/src/nav-strip/nav-strip.js +25 -0
  315. package/dist/src/notice/index.d.ts.map +1 -1
  316. package/dist/src/notice/notice.d.ts +0 -4
  317. package/dist/src/notice/notice.d.ts.map +1 -1
  318. package/dist/src/notice/notice.js +1 -4
  319. package/dist/src/outcome/index.d.ts.map +1 -1
  320. package/dist/src/outcome/outcome.d.ts.map +1 -1
  321. package/dist/src/outcome/outcome.js +1 -1
  322. package/dist/src/page-head/index.d.ts +3 -0
  323. package/dist/src/page-head/index.d.ts.map +1 -0
  324. package/dist/src/page-head/index.js +1 -0
  325. package/dist/src/{pageHead/pageHead.d.ts → page-head/page-head.d.ts} +1 -1
  326. package/dist/src/page-head/page-head.d.ts.map +1 -0
  327. package/dist/src/{pageHead/pageHead.js → page-head/page-head.js} +1 -1
  328. package/dist/src/panel/index.d.ts.map +1 -1
  329. package/dist/src/panel/panel.d.ts +0 -1
  330. package/dist/src/panel/panel.d.ts.map +1 -1
  331. package/dist/src/panel/panel.js +0 -1
  332. package/dist/src/password-field/index.d.ts +3 -0
  333. package/dist/src/password-field/index.d.ts.map +1 -0
  334. package/dist/src/password-field/index.js +1 -0
  335. package/dist/src/{passwordField/passwordField.d.ts → password-field/password-field.d.ts} +1 -1
  336. package/dist/src/password-field/password-field.d.ts.map +1 -0
  337. package/dist/src/{passwordField/passwordField.js → password-field/password-field.js} +4 -5
  338. package/dist/src/places/index.d.ts.map +1 -1
  339. package/dist/src/places/places.d.ts +3 -4
  340. package/dist/src/places/places.d.ts.map +1 -1
  341. package/dist/src/places/places.js +8 -2
  342. package/dist/src/props-list/index.d.ts +3 -0
  343. package/dist/src/props-list/index.d.ts.map +1 -0
  344. package/dist/src/props-list/index.js +1 -0
  345. package/dist/src/{propsList/propsList.d.ts → props-list/props-list.d.ts} +2 -2
  346. package/dist/src/props-list/props-list.d.ts.map +1 -0
  347. package/dist/src/{propsList/propsList.js → props-list/props-list.js} +2 -2
  348. package/dist/src/prose/index.d.ts.map +1 -1
  349. package/dist/src/prose/prose.d.ts.map +1 -1
  350. package/dist/src/query-chip/index.d.ts +3 -0
  351. package/dist/src/query-chip/index.d.ts.map +1 -0
  352. package/dist/src/query-chip/index.js +1 -0
  353. package/dist/src/{queryChip/queryChip.d.ts → query-chip/query-chip.d.ts} +1 -1
  354. package/dist/src/query-chip/query-chip.d.ts.map +1 -0
  355. package/dist/src/{queryChip/queryChip.js → query-chip/query-chip.js} +7 -4
  356. package/dist/src/{radioChoices → radio-choices}/index.d.ts +2 -2
  357. package/dist/src/radio-choices/index.d.ts.map +1 -0
  358. package/dist/src/{radioChoices → radio-choices}/index.js +1 -1
  359. package/dist/src/{radioChoices/radioChoices.d.ts → radio-choices/radio-choices.d.ts} +3 -3
  360. package/dist/src/radio-choices/radio-choices.d.ts.map +1 -0
  361. package/dist/src/{radioChoices/radioChoices.js → radio-choices/radio-choices.js} +25 -24
  362. package/dist/src/rail/index.d.ts.map +1 -1
  363. package/dist/src/rail/rail.d.ts +16 -32
  364. package/dist/src/rail/rail.d.ts.map +1 -1
  365. package/dist/src/rail/rail.js +97 -65
  366. package/dist/src/reel/index.d.ts +1 -1
  367. package/dist/src/reel/index.d.ts.map +1 -1
  368. package/dist/src/reel/layout.d.ts +12 -54
  369. package/dist/src/reel/layout.d.ts.map +1 -1
  370. package/dist/src/reel/layout.js +120 -145
  371. package/dist/src/reel/reel.d.ts +35 -34
  372. package/dist/src/reel/reel.d.ts.map +1 -1
  373. package/dist/src/reel/reel.js +253 -233
  374. package/dist/src/remote/index.d.ts.map +1 -1
  375. package/dist/src/remote/remote.d.ts +2 -2
  376. package/dist/src/remote/remote.d.ts.map +1 -1
  377. package/dist/src/remote/remote.js +6 -2
  378. package/dist/src/rows/index.d.ts.map +1 -1
  379. package/dist/src/rows/rows.d.ts +2 -2
  380. package/dist/src/rows/rows.d.ts.map +1 -1
  381. package/dist/src/rows/rows.js +16 -7
  382. package/dist/src/scheme/index.d.ts +1 -1
  383. package/dist/src/scheme/index.d.ts.map +1 -1
  384. package/dist/src/scheme/index.js +1 -1
  385. package/dist/src/scheme/{schemeSwitch.d.ts → scheme-switch.d.ts} +2 -2
  386. package/dist/src/scheme/scheme-switch.d.ts.map +1 -0
  387. package/dist/src/scheme/{schemeSwitch.js → scheme-switch.js} +33 -38
  388. package/dist/src/scheme/scheme.d.ts +0 -2
  389. package/dist/src/scheme/scheme.d.ts.map +1 -1
  390. package/dist/src/scheme/scheme.js +0 -2
  391. package/dist/src/secret/index.d.ts.map +1 -1
  392. package/dist/src/secret/secret.d.ts.map +1 -1
  393. package/dist/src/segmented/index.d.ts.map +1 -1
  394. package/dist/src/segmented/segmented.d.ts.map +1 -1
  395. package/dist/src/segmented/segmented.js +14 -3
  396. package/dist/src/select-all/index.d.ts +3 -0
  397. package/dist/src/select-all/index.d.ts.map +1 -0
  398. package/dist/src/select-all/index.js +1 -0
  399. package/dist/src/{selectAll/selectAll.d.ts → select-all/select-all.d.ts} +1 -1
  400. package/dist/src/select-all/select-all.d.ts.map +1 -0
  401. package/dist/src/{selectAll/selectAll.js → select-all/select-all.js} +2 -2
  402. package/dist/src/select-field/index.d.ts +3 -0
  403. package/dist/src/select-field/index.d.ts.map +1 -0
  404. package/dist/src/select-field/index.js +1 -0
  405. package/dist/src/{selectField/selectField.d.ts → select-field/select-field.d.ts} +2 -2
  406. package/dist/src/select-field/select-field.d.ts.map +1 -0
  407. package/dist/src/{selectField/selectField.js → select-field/select-field.js} +10 -7
  408. package/dist/src/sheet/index.d.ts.map +1 -1
  409. package/dist/src/sheet/sheet.d.ts.map +1 -1
  410. package/dist/src/sheet/sheet.js +4 -1
  411. package/dist/src/skip-link/index.d.ts +2 -0
  412. package/dist/src/skip-link/index.d.ts.map +1 -0
  413. package/dist/src/skip-link/index.js +1 -0
  414. package/dist/src/{skipLink/skipLink.d.ts → skip-link/skip-link.d.ts} +1 -3
  415. package/dist/src/skip-link/skip-link.d.ts.map +1 -0
  416. package/dist/src/{skipLink/skipLink.js → skip-link/skip-link.js} +7 -11
  417. package/dist/src/slot/slot.d.ts +1 -4
  418. package/dist/src/slot/slot.d.ts.map +1 -1
  419. package/dist/src/slot/slot.js +3 -3
  420. package/dist/src/sortable/index.d.ts.map +1 -1
  421. package/dist/src/sortable/sortable.d.ts +44 -44
  422. package/dist/src/sortable/sortable.d.ts.map +1 -1
  423. package/dist/src/sortable/sortable.js +60 -93
  424. package/dist/src/stack/index.d.ts.map +1 -1
  425. package/dist/src/stack/stack.d.ts.map +1 -1
  426. package/dist/src/stack/stack.js +0 -2
  427. package/dist/src/stage/index.d.ts.map +1 -1
  428. package/dist/src/stage/stage.d.ts +1 -1
  429. package/dist/src/stage/stage.d.ts.map +1 -1
  430. package/dist/src/stage/stage.js +4 -1
  431. package/dist/src/stat/index.d.ts.map +1 -1
  432. package/dist/src/stat/stat.d.ts +1 -1
  433. package/dist/src/stat/stat.d.ts.map +1 -1
  434. package/dist/src/stat/stat.js +17 -8
  435. package/dist/src/status-bar/index.d.ts +4 -0
  436. package/dist/src/status-bar/index.d.ts.map +1 -0
  437. package/dist/src/status-bar/index.js +2 -0
  438. package/dist/src/{statusBar/statusBar.d.ts → status-bar/status-bar.d.ts} +4 -4
  439. package/dist/src/status-bar/status-bar.d.ts.map +1 -0
  440. package/dist/src/{statusBar/statusBar.js → status-bar/status-bar.js} +5 -6
  441. package/dist/src/subscription/{prefixKeys.d.ts → prefix-keys.d.ts} +1 -2
  442. package/dist/src/subscription/prefix-keys.d.ts.map +1 -0
  443. package/dist/src/subscription/{prefixKeys.js → prefix-keys.js} +2 -5
  444. package/dist/src/table/index.d.ts.map +1 -1
  445. package/dist/src/table/table.d.ts +1 -1
  446. package/dist/src/table/table.d.ts.map +1 -1
  447. package/dist/src/table/table.js +19 -7
  448. package/dist/src/tabs/index.d.ts.map +1 -1
  449. package/dist/src/tabs/tabs.d.ts +4 -4
  450. package/dist/src/tabs/tabs.d.ts.map +1 -1
  451. package/dist/src/tabs/tabs.js +1 -6
  452. package/dist/src/tag/index.d.ts.map +1 -1
  453. package/dist/src/tag/tag.d.ts.map +1 -1
  454. package/dist/src/tag/tag.js +4 -1
  455. package/dist/src/text-button/index.d.ts +3 -0
  456. package/dist/src/text-button/index.d.ts.map +1 -0
  457. package/dist/src/text-button/index.js +1 -0
  458. package/dist/src/{textButton/textButton.d.ts → text-button/text-button.d.ts} +1 -1
  459. package/dist/src/text-button/text-button.d.ts.map +1 -0
  460. package/dist/src/{textButton/textButton.js → text-button/text-button.js} +2 -2
  461. package/dist/src/textarea-field/index.d.ts +3 -0
  462. package/dist/src/textarea-field/index.d.ts.map +1 -0
  463. package/dist/src/textarea-field/index.js +1 -0
  464. package/dist/src/{textareaField/textareaField.d.ts → textarea-field/textarea-field.d.ts} +1 -1
  465. package/dist/src/textarea-field/textarea-field.d.ts.map +1 -0
  466. package/dist/src/{textareaField/textareaField.js → textarea-field/textarea-field.js} +2 -2
  467. package/dist/src/time/index.d.ts.map +1 -1
  468. package/dist/src/time/time.d.ts.map +1 -1
  469. package/dist/src/time/time.js +16 -9
  470. package/dist/src/tips/index.d.ts.map +1 -1
  471. package/dist/src/tips/tips.d.ts +7 -18
  472. package/dist/src/tips/tips.d.ts.map +1 -1
  473. package/dist/src/tips/tips.js +67 -65
  474. package/dist/src/toast/index.d.ts.map +1 -1
  475. package/dist/src/toast/stack.d.ts +1 -8
  476. package/dist/src/toast/stack.d.ts.map +1 -1
  477. package/dist/src/toast/stack.js +5 -18
  478. package/dist/src/toast/toast.d.ts +3 -5
  479. package/dist/src/toast/toast.d.ts.map +1 -1
  480. package/dist/src/toast/toast.js +42 -39
  481. package/dist/src/toc/index.d.ts.map +1 -1
  482. package/dist/src/toc/toc.d.ts +3 -3
  483. package/dist/src/toc/toc.d.ts.map +1 -1
  484. package/dist/src/toc/toc.js +10 -7
  485. package/dist/src/toolbar/index.d.ts.map +1 -1
  486. package/dist/src/toolbar/toolbar.d.ts +1 -1
  487. package/dist/src/toolbar/toolbar.d.ts.map +1 -1
  488. package/dist/src/toolbar/toolbar.js +27 -24
  489. package/dist/src/{topBar/barHeight.d.ts → top-bar/bar-height.d.ts} +1 -2
  490. package/dist/src/top-bar/bar-height.d.ts.map +1 -0
  491. package/dist/src/{topBar/barHeight.js → top-bar/bar-height.js} +20 -13
  492. package/dist/src/top-bar/index.d.ts +4 -0
  493. package/dist/src/top-bar/index.d.ts.map +1 -0
  494. package/dist/src/top-bar/index.js +2 -0
  495. package/dist/src/{topBar/topBar.d.ts → top-bar/top-bar.d.ts} +3 -3
  496. package/dist/src/top-bar/top-bar.d.ts.map +1 -0
  497. package/dist/src/{topBar/topBar.js → top-bar/top-bar.js} +2 -2
  498. package/dist/src/video-frame/index.d.ts +3 -0
  499. package/dist/src/video-frame/index.d.ts.map +1 -0
  500. package/dist/src/video-frame/index.js +1 -0
  501. package/dist/src/{videoFrame/videoFrame.d.ts → video-frame/video-frame.d.ts} +1 -1
  502. package/dist/src/video-frame/video-frame.d.ts.map +1 -0
  503. package/dist/src/{videoFrame/videoFrame.js → video-frame/video-frame.js} +11 -7
  504. package/dist/src/wall/index.d.ts.map +1 -1
  505. package/dist/src/wall/wall.d.ts.map +1 -1
  506. package/dist/src/window/index.d.ts.map +1 -1
  507. package/dist/src/window/window.d.ts +2 -2
  508. package/dist/src/window/window.d.ts.map +1 -1
  509. package/dist/src/window/window.js +4 -2
  510. package/dist/src/wordmark/index.d.ts.map +1 -1
  511. package/dist/src/wordmark/wordmark.d.ts.map +1 -1
  512. package/dist/src/wrap/index.d.ts.map +1 -1
  513. package/dist/src/wrap/wrap.d.ts.map +1 -1
  514. package/package.json +6 -6
  515. package/src/adapters/diagram.ts +278 -0
  516. package/src/adapters/mermaid.ts +13 -273
  517. package/src/announcer/announcer.ts +54 -35
  518. package/src/attributes/attributes.ts +3 -1
  519. package/src/{audioFrame/audioFrame.ts → audio-frame/audio-frame.ts} +4 -6
  520. package/src/audio-frame/index.ts +3 -0
  521. package/src/banner/banner.ts +5 -4
  522. package/src/banner/index.ts +1 -0
  523. package/src/{barChart/barChart.ts → bar-chart/bar-chart.ts} +81 -43
  524. package/src/bar-chart/index.ts +3 -0
  525. package/src/bench/bench.ts +5 -4
  526. package/src/bench/index.ts +1 -0
  527. package/src/board/board.ts +338 -243
  528. package/src/board/index.ts +8 -1
  529. package/src/button/button.ts +24 -16
  530. package/src/button/index.ts +8 -1
  531. package/src/card/card.ts +23 -21
  532. package/src/card/index.ts +1 -0
  533. package/src/chart-table/chart-table.ts +87 -0
  534. package/src/chip/chip.ts +13 -9
  535. package/src/chip/index.ts +1 -0
  536. package/src/choice/choice.ts +13 -7
  537. package/src/choice/index.ts +1 -0
  538. package/src/choices/choices.ts +4 -3
  539. package/src/choices/index.ts +1 -0
  540. package/src/{codeEditor/codeEditor.ts → code-editor/code-editor.ts} +5 -4
  541. package/src/code-editor/index.ts +3 -0
  542. package/src/{codeSurface/codeSurface.ts → code-surface/code-surface.ts} +11 -5
  543. package/src/code-surface/index.ts +3 -0
  544. package/src/{commandPalette/commandPalette.ts → command-palette/command-palette.ts} +470 -295
  545. package/src/{commandPalette → command-palette}/index.ts +12 -2
  546. package/src/{commandPalette → command-palette}/keys.ts +44 -43
  547. package/src/{commandPalette → command-palette}/match.ts +42 -30
  548. package/src/{commandPalette → command-palette}/message.ts +13 -20
  549. package/src/{confirmDialog/confirmDialog.ts → confirm-dialog/confirm-dialog.ts} +51 -46
  550. package/src/{confirmDialog → confirm-dialog}/index.ts +3 -2
  551. package/src/{contextMenu/contextMenu.ts → context-menu/context-menu.ts} +71 -70
  552. package/src/{contextMenu → context-menu}/index.ts +4 -2
  553. package/src/{copyButton/copyButton.ts → copy-button/copy-button.ts} +51 -54
  554. package/src/{copyButton → copy-button}/index.ts +3 -2
  555. package/src/crumbs/crumbs.ts +7 -6
  556. package/src/crumbs/index.ts +1 -0
  557. package/src/deck/deck.ts +4 -3
  558. package/src/deck/index.ts +1 -0
  559. package/src/dialog/dialog.ts +135 -113
  560. package/src/dialog/fold.ts +44 -25
  561. package/src/dialog/index.ts +9 -1
  562. package/src/disclosure/disclosure.ts +14 -8
  563. package/src/disclosure/index.ts +1 -0
  564. package/src/dom/html-element.ts +10 -0
  565. package/src/drag/drag.ts +102 -119
  566. package/src/{dropZone/dropZone.ts → drop-zone/drop-zone.ts} +43 -43
  567. package/src/drop-zone/index.ts +11 -0
  568. package/src/{editableTitle/editableTitle.ts → editable-title/editable-title.ts} +29 -32
  569. package/src/{editableTitle → editable-title}/index.ts +4 -2
  570. package/src/{emptyState/emptyState.ts → empty-state/empty-state.ts} +9 -5
  571. package/src/empty-state/index.ts +3 -0
  572. package/src/{errorSummary/errorSummary.ts → error-summary/error-summary.ts} +16 -7
  573. package/src/error-summary/index.ts +3 -0
  574. package/src/field/field.ts +38 -28
  575. package/src/field/index.ts +1 -0
  576. package/src/{fieldGrid/fieldGrid.ts → field-grid/field-grid.ts} +4 -3
  577. package/src/field-grid/index.ts +3 -0
  578. package/src/fields/fields.ts +9 -5
  579. package/src/fields/index.ts +1 -0
  580. package/src/fieldset/fieldset.ts +6 -5
  581. package/src/fieldset/index.ts +1 -0
  582. package/src/{fileTree/fileTree.ts → file-tree/file-tree.ts} +241 -166
  583. package/src/file-tree/index.ts +12 -0
  584. package/src/{filterChip/filterChip.ts → filter-chip/filter-chip.ts} +32 -13
  585. package/src/filter-chip/index.ts +3 -0
  586. package/src/{filterStrip/filterStrip.ts → filter-strip/filter-strip.ts} +4 -3
  587. package/src/filter-strip/index.ts +3 -0
  588. package/src/{flashWord/flashWord.ts → flash-word/flash-word.ts} +9 -7
  589. package/src/flash-word/index.ts +3 -0
  590. package/src/focus/focus.ts +5 -5
  591. package/src/format/format.ts +37 -31
  592. package/src/format/index.ts +1 -0
  593. package/src/glyph/glyph.ts +7 -6
  594. package/src/glyph/glyphs.ts +2601 -2611
  595. package/src/glyph/index.ts +3 -0
  596. package/src/group/group.ts +4 -3
  597. package/src/group/index.ts +1 -0
  598. package/src/history/history.ts +18 -10
  599. package/src/history/index.ts +1 -0
  600. package/src/{iconButton/iconButton.ts → icon-button/icon-button.ts} +13 -7
  601. package/src/icon-button/index.ts +3 -0
  602. package/src/identity/identity.ts +7 -6
  603. package/src/identity/index.ts +1 -0
  604. package/src/{imageFrame/imageFrame.ts → image-frame/image-frame.ts} +43 -25
  605. package/src/image-frame/index.ts +3 -0
  606. package/src/index.ts +139 -41
  607. package/src/{inlineInput → inline-input}/index.ts +3 -2
  608. package/src/{inlineInput/inlineInput.ts → inline-input/inline-input.ts} +97 -88
  609. package/src/{keyHelp → key-help}/index.ts +3 -2
  610. package/src/{keyHelp/keyHelp.ts → key-help/key-help.ts} +74 -62
  611. package/src/key-hint/index.ts +5 -0
  612. package/src/{keyHint/keyHint.ts → key-hint/key-hint.ts} +10 -5
  613. package/src/{keyHint/keyLabel.ts → key-hint/key-label.ts} +43 -22
  614. package/src/keymap/index.ts +1 -0
  615. package/src/keymap/keymap.ts +23 -9
  616. package/src/keys/keys.ts +0 -2
  617. package/src/line-chart/index.ts +3 -0
  618. package/src/{lineChart/lineChart.ts → line-chart/line-chart.ts} +71 -49
  619. package/src/line-diff/diff.ts +196 -0
  620. package/src/line-diff/index.ts +7 -0
  621. package/src/{lineDiff/lineDiff.ts → line-diff/line-diff.ts} +45 -23
  622. package/src/{lineDiff → line-diff}/patch.ts +104 -76
  623. package/src/link-button/index.ts +3 -0
  624. package/src/{linkButton/linkButton.ts → link-button/link-button.ts} +7 -5
  625. package/src/link-state/index.ts +3 -0
  626. package/src/{linkState/linkState.ts → link-state/link-state.ts} +20 -9
  627. package/src/live-region/index.ts +3 -0
  628. package/src/{liveRegion/liveRegion.ts → live-region/live-region.ts} +15 -11
  629. package/src/loading/index.ts +1 -0
  630. package/src/loading/loading.ts +10 -5
  631. package/src/mark/index.ts +1 -0
  632. package/src/mark/mark.ts +17 -15
  633. package/src/media/index.ts +1 -0
  634. package/src/media/media.ts +255 -157
  635. package/src/menu/index.ts +4 -0
  636. package/src/menu/item.ts +10 -11
  637. package/src/menu/menu.ts +110 -97
  638. package/src/menu/slip.ts +129 -92
  639. package/src/meter/index.ts +1 -0
  640. package/src/meter/meter.ts +52 -33
  641. package/src/monogram/index.ts +1 -0
  642. package/src/monogram/monogram.ts +27 -19
  643. package/src/nav-strip/index.ts +3 -0
  644. package/src/{navStrip/navStrip.ts → nav-strip/nav-strip.ts} +21 -13
  645. package/src/notice/index.ts +1 -0
  646. package/src/notice/notice.ts +24 -16
  647. package/src/outcome/index.ts +1 -0
  648. package/src/outcome/outcome.ts +14 -6
  649. package/src/page-head/index.ts +3 -0
  650. package/src/{pageHead/pageHead.ts → page-head/page-head.ts} +6 -5
  651. package/src/panel/index.ts +1 -0
  652. package/src/panel/panel.ts +6 -6
  653. package/src/password-field/index.ts +3 -0
  654. package/src/{passwordField/passwordField.ts → password-field/password-field.ts} +13 -13
  655. package/src/pixel-paper.css +26 -508
  656. package/src/places/index.ts +1 -0
  657. package/src/places/places.ts +22 -11
  658. package/src/props-list/index.ts +3 -0
  659. package/src/{propsList/propsList.ts → props-list/props-list.ts} +6 -6
  660. package/src/prose/index.ts +1 -0
  661. package/src/prose/prose.ts +4 -4
  662. package/src/query-chip/index.ts +3 -0
  663. package/src/{queryChip/queryChip.ts → query-chip/query-chip.ts} +18 -7
  664. package/src/{radioChoices → radio-choices}/index.ts +3 -2
  665. package/src/{radioChoices/radioChoices.ts → radio-choices/radio-choices.ts} +79 -65
  666. package/src/rail/index.ts +1 -0
  667. package/src/rail/rail.ts +291 -225
  668. package/src/reel/index.ts +8 -1
  669. package/src/reel/layout.ts +393 -238
  670. package/src/reel/reel.ts +750 -452
  671. package/src/remote/index.ts +1 -0
  672. package/src/remote/remote.ts +18 -11
  673. package/src/rows/index.ts +1 -0
  674. package/src/rows/rows.ts +83 -47
  675. package/src/scheme/index.ts +3 -1
  676. package/src/scheme/{schemeSwitch.ts → scheme-switch.ts} +24 -35
  677. package/src/scheme/scheme.ts +4 -4
  678. package/src/secret/index.ts +1 -0
  679. package/src/secret/secret.ts +5 -4
  680. package/src/segmented/index.ts +1 -0
  681. package/src/segmented/segmented.ts +22 -10
  682. package/src/select-all/index.ts +3 -0
  683. package/src/{selectAll/selectAll.ts → select-all/select-all.ts} +9 -8
  684. package/src/{selectField → select-field}/index.ts +3 -2
  685. package/src/{selectField/selectField.ts → select-field/select-field.ts} +25 -11
  686. package/src/sheet/index.ts +1 -0
  687. package/src/sheet/sheet.ts +9 -5
  688. package/src/skip-link/index.ts +1 -0
  689. package/src/{skipLink/skipLink.ts → skip-link/skip-link.ts} +9 -15
  690. package/src/slot/slot.ts +5 -6
  691. package/src/sortable/index.ts +1 -0
  692. package/src/sortable/sortable.ts +287 -206
  693. package/src/stack/index.ts +1 -0
  694. package/src/stack/stack.ts +6 -7
  695. package/src/stage/index.ts +1 -0
  696. package/src/stage/stage.ts +12 -8
  697. package/src/stat/index.ts +1 -0
  698. package/src/stat/stat.ts +39 -20
  699. package/src/status-bar/index.ts +5 -0
  700. package/src/{statusBar/statusBar.ts → status-bar/status-bar.ts} +18 -11
  701. package/src/subscription/{prefixKeys.ts → prefix-keys.ts} +5 -6
  702. package/src/table/index.ts +1 -0
  703. package/src/table/table.ts +49 -24
  704. package/src/tabs/index.ts +1 -0
  705. package/src/tabs/tabs.ts +58 -60
  706. package/src/tag/index.ts +1 -0
  707. package/src/tag/tag.ts +14 -7
  708. package/src/text-button/index.ts +3 -0
  709. package/src/{textButton/textButton.ts → text-button/text-button.ts} +7 -5
  710. package/src/textarea-field/index.ts +3 -0
  711. package/src/{textareaField/textareaField.ts → textarea-field/textarea-field.ts} +15 -7
  712. package/src/time/index.ts +1 -0
  713. package/src/time/time.ts +58 -25
  714. package/src/tips/index.ts +1 -0
  715. package/src/tips/tips.ts +183 -127
  716. package/src/toast/index.ts +3 -0
  717. package/src/toast/stack.ts +22 -23
  718. package/src/toast/toast.ts +168 -100
  719. package/src/toc/index.ts +1 -0
  720. package/src/toc/toc.ts +42 -27
  721. package/src/tokens.css +7 -24
  722. package/src/toolbar/index.ts +1 -0
  723. package/src/toolbar/toolbar.ts +78 -40
  724. package/src/{topBar/barHeight.ts → top-bar/bar-height.ts} +26 -12
  725. package/src/top-bar/index.ts +5 -0
  726. package/src/{topBar/topBar.ts → top-bar/top-bar.ts} +13 -7
  727. package/src/video-frame/index.ts +3 -0
  728. package/src/{videoFrame/videoFrame.ts → video-frame/video-frame.ts} +31 -18
  729. package/src/wall/index.ts +1 -0
  730. package/src/wall/wall.ts +13 -10
  731. package/src/window/index.ts +1 -0
  732. package/src/window/window.ts +15 -9
  733. package/src/wordmark/index.ts +1 -0
  734. package/src/wordmark/wordmark.ts +4 -3
  735. package/src/wrap/index.ts +1 -0
  736. package/src/wrap/wrap.ts +4 -3
  737. package/dist/src/audioFrame/audioFrame.d.ts.map +0 -1
  738. package/dist/src/audioFrame/index.d.ts +0 -3
  739. package/dist/src/audioFrame/index.d.ts.map +0 -1
  740. package/dist/src/audioFrame/index.js +0 -1
  741. package/dist/src/barChart/barChart.d.ts.map +0 -1
  742. package/dist/src/barChart/index.d.ts +0 -3
  743. package/dist/src/barChart/index.d.ts.map +0 -1
  744. package/dist/src/barChart/index.js +0 -1
  745. package/dist/src/chartTable/chartTable.d.ts.map +0 -1
  746. package/dist/src/codeEditor/codeEditor.d.ts.map +0 -1
  747. package/dist/src/codeEditor/index.d.ts +0 -3
  748. package/dist/src/codeEditor/index.d.ts.map +0 -1
  749. package/dist/src/codeEditor/index.js +0 -1
  750. package/dist/src/codeSurface/codeSurface.d.ts.map +0 -1
  751. package/dist/src/codeSurface/index.d.ts +0 -3
  752. package/dist/src/codeSurface/index.d.ts.map +0 -1
  753. package/dist/src/codeSurface/index.js +0 -1
  754. package/dist/src/commandPalette/commandPalette.d.ts.map +0 -1
  755. package/dist/src/commandPalette/commandPalette.js +0 -611
  756. package/dist/src/commandPalette/index.d.ts.map +0 -1
  757. package/dist/src/commandPalette/keys.d.ts.map +0 -1
  758. package/dist/src/commandPalette/keys.js +0 -102
  759. package/dist/src/commandPalette/match.d.ts.map +0 -1
  760. package/dist/src/commandPalette/message.d.ts.map +0 -1
  761. package/dist/src/confirmDialog/confirmDialog.d.ts.map +0 -1
  762. package/dist/src/confirmDialog/index.d.ts +0 -3
  763. package/dist/src/confirmDialog/index.d.ts.map +0 -1
  764. package/dist/src/contextMenu/contextMenu.d.ts.map +0 -1
  765. package/dist/src/contextMenu/index.d.ts.map +0 -1
  766. package/dist/src/copyButton/copyButton.d.ts.map +0 -1
  767. package/dist/src/copyButton/index.d.ts +0 -3
  768. package/dist/src/copyButton/index.d.ts.map +0 -1
  769. package/dist/src/copyButton/index.js +0 -1
  770. package/dist/src/dropZone/dropZone.d.ts.map +0 -1
  771. package/dist/src/dropZone/index.d.ts +0 -3
  772. package/dist/src/dropZone/index.d.ts.map +0 -1
  773. package/dist/src/dropZone/index.js +0 -1
  774. package/dist/src/editableTitle/editableTitle.d.ts.map +0 -1
  775. package/dist/src/editableTitle/index.d.ts +0 -4
  776. package/dist/src/editableTitle/index.d.ts.map +0 -1
  777. package/dist/src/emptyState/emptyState.d.ts.map +0 -1
  778. package/dist/src/emptyState/index.d.ts +0 -3
  779. package/dist/src/emptyState/index.d.ts.map +0 -1
  780. package/dist/src/emptyState/index.js +0 -1
  781. package/dist/src/errorSummary/errorSummary.d.ts.map +0 -1
  782. package/dist/src/errorSummary/index.d.ts +0 -3
  783. package/dist/src/errorSummary/index.d.ts.map +0 -1
  784. package/dist/src/errorSummary/index.js +0 -1
  785. package/dist/src/fieldGrid/fieldGrid.d.ts.map +0 -1
  786. package/dist/src/fieldGrid/index.d.ts +0 -3
  787. package/dist/src/fieldGrid/index.d.ts.map +0 -1
  788. package/dist/src/fieldGrid/index.js +0 -1
  789. package/dist/src/fileTree/fileTree.d.ts.map +0 -1
  790. package/dist/src/fileTree/fileTree.js +0 -230
  791. package/dist/src/fileTree/index.d.ts +0 -3
  792. package/dist/src/fileTree/index.d.ts.map +0 -1
  793. package/dist/src/filterChip/filterChip.d.ts.map +0 -1
  794. package/dist/src/filterChip/index.d.ts +0 -3
  795. package/dist/src/filterChip/index.d.ts.map +0 -1
  796. package/dist/src/filterChip/index.js +0 -1
  797. package/dist/src/filterStrip/filterStrip.d.ts.map +0 -1
  798. package/dist/src/filterStrip/index.d.ts +0 -3
  799. package/dist/src/filterStrip/index.d.ts.map +0 -1
  800. package/dist/src/filterStrip/index.js +0 -1
  801. package/dist/src/flashWord/flashWord.d.ts.map +0 -1
  802. package/dist/src/flashWord/index.d.ts +0 -3
  803. package/dist/src/flashWord/index.d.ts.map +0 -1
  804. package/dist/src/flashWord/index.js +0 -1
  805. package/dist/src/iconButton/iconButton.d.ts.map +0 -1
  806. package/dist/src/iconButton/index.d.ts +0 -3
  807. package/dist/src/iconButton/index.d.ts.map +0 -1
  808. package/dist/src/iconButton/index.js +0 -1
  809. package/dist/src/imageFrame/imageFrame.d.ts.map +0 -1
  810. package/dist/src/imageFrame/index.d.ts +0 -3
  811. package/dist/src/imageFrame/index.d.ts.map +0 -1
  812. package/dist/src/imageFrame/index.js +0 -1
  813. package/dist/src/inlineInput/index.d.ts +0 -3
  814. package/dist/src/inlineInput/index.d.ts.map +0 -1
  815. package/dist/src/inlineInput/inlineInput.d.ts.map +0 -1
  816. package/dist/src/keyHelp/index.d.ts +0 -3
  817. package/dist/src/keyHelp/index.d.ts.map +0 -1
  818. package/dist/src/keyHelp/keyHelp.d.ts.map +0 -1
  819. package/dist/src/keyHint/index.d.ts +0 -4
  820. package/dist/src/keyHint/index.d.ts.map +0 -1
  821. package/dist/src/keyHint/index.js +0 -2
  822. package/dist/src/keyHint/keyHint.d.ts.map +0 -1
  823. package/dist/src/keyHint/keyLabel.d.ts.map +0 -1
  824. package/dist/src/lineChart/index.d.ts +0 -3
  825. package/dist/src/lineChart/index.d.ts.map +0 -1
  826. package/dist/src/lineChart/index.js +0 -1
  827. package/dist/src/lineChart/lineChart.d.ts.map +0 -1
  828. package/dist/src/lineDiff/diff.d.ts +0 -41
  829. package/dist/src/lineDiff/diff.d.ts.map +0 -1
  830. package/dist/src/lineDiff/diff.js +0 -92
  831. package/dist/src/lineDiff/index.d.ts +0 -5
  832. package/dist/src/lineDiff/index.d.ts.map +0 -1
  833. package/dist/src/lineDiff/index.js +0 -2
  834. package/dist/src/lineDiff/lineDiff.d.ts.map +0 -1
  835. package/dist/src/lineDiff/patch.d.ts.map +0 -1
  836. package/dist/src/linkButton/index.d.ts +0 -3
  837. package/dist/src/linkButton/index.d.ts.map +0 -1
  838. package/dist/src/linkButton/index.js +0 -1
  839. package/dist/src/linkButton/linkButton.d.ts.map +0 -1
  840. package/dist/src/linkState/index.d.ts +0 -3
  841. package/dist/src/linkState/index.d.ts.map +0 -1
  842. package/dist/src/linkState/index.js +0 -1
  843. package/dist/src/linkState/linkState.d.ts.map +0 -1
  844. package/dist/src/linkState/linkState.js +0 -14
  845. package/dist/src/liveRegion/index.d.ts +0 -3
  846. package/dist/src/liveRegion/index.d.ts.map +0 -1
  847. package/dist/src/liveRegion/index.js +0 -1
  848. package/dist/src/liveRegion/liveRegion.d.ts.map +0 -1
  849. package/dist/src/navStrip/index.d.ts +0 -3
  850. package/dist/src/navStrip/index.d.ts.map +0 -1
  851. package/dist/src/navStrip/index.js +0 -1
  852. package/dist/src/navStrip/navStrip.d.ts.map +0 -1
  853. package/dist/src/navStrip/navStrip.js +0 -27
  854. package/dist/src/pageHead/index.d.ts +0 -3
  855. package/dist/src/pageHead/index.d.ts.map +0 -1
  856. package/dist/src/pageHead/index.js +0 -1
  857. package/dist/src/pageHead/pageHead.d.ts.map +0 -1
  858. package/dist/src/passwordField/index.d.ts +0 -3
  859. package/dist/src/passwordField/index.d.ts.map +0 -1
  860. package/dist/src/passwordField/index.js +0 -1
  861. package/dist/src/passwordField/passwordField.d.ts.map +0 -1
  862. package/dist/src/propsList/index.d.ts +0 -3
  863. package/dist/src/propsList/index.d.ts.map +0 -1
  864. package/dist/src/propsList/index.js +0 -1
  865. package/dist/src/propsList/propsList.d.ts.map +0 -1
  866. package/dist/src/queryChip/index.d.ts +0 -3
  867. package/dist/src/queryChip/index.d.ts.map +0 -1
  868. package/dist/src/queryChip/index.js +0 -1
  869. package/dist/src/queryChip/queryChip.d.ts.map +0 -1
  870. package/dist/src/radioChoices/index.d.ts.map +0 -1
  871. package/dist/src/radioChoices/radioChoices.d.ts.map +0 -1
  872. package/dist/src/scheme/schemeSwitch.d.ts.map +0 -1
  873. package/dist/src/selectAll/index.d.ts +0 -3
  874. package/dist/src/selectAll/index.d.ts.map +0 -1
  875. package/dist/src/selectAll/index.js +0 -1
  876. package/dist/src/selectAll/selectAll.d.ts.map +0 -1
  877. package/dist/src/selectField/index.d.ts +0 -3
  878. package/dist/src/selectField/index.d.ts.map +0 -1
  879. package/dist/src/selectField/index.js +0 -1
  880. package/dist/src/selectField/selectField.d.ts.map +0 -1
  881. package/dist/src/skipLink/index.d.ts +0 -2
  882. package/dist/src/skipLink/index.d.ts.map +0 -1
  883. package/dist/src/skipLink/index.js +0 -1
  884. package/dist/src/skipLink/skipLink.d.ts.map +0 -1
  885. package/dist/src/statusBar/index.d.ts +0 -4
  886. package/dist/src/statusBar/index.d.ts.map +0 -1
  887. package/dist/src/statusBar/index.js +0 -2
  888. package/dist/src/statusBar/statusBar.d.ts.map +0 -1
  889. package/dist/src/subscription/prefixKeys.d.ts.map +0 -1
  890. package/dist/src/textButton/index.d.ts +0 -3
  891. package/dist/src/textButton/index.d.ts.map +0 -1
  892. package/dist/src/textButton/index.js +0 -1
  893. package/dist/src/textButton/textButton.d.ts.map +0 -1
  894. package/dist/src/textareaField/index.d.ts +0 -3
  895. package/dist/src/textareaField/index.d.ts.map +0 -1
  896. package/dist/src/textareaField/index.js +0 -1
  897. package/dist/src/textareaField/textareaField.d.ts.map +0 -1
  898. package/dist/src/topBar/barHeight.d.ts.map +0 -1
  899. package/dist/src/topBar/index.d.ts +0 -4
  900. package/dist/src/topBar/index.d.ts.map +0 -1
  901. package/dist/src/topBar/index.js +0 -2
  902. package/dist/src/topBar/topBar.d.ts.map +0 -1
  903. package/dist/src/videoFrame/index.d.ts +0 -3
  904. package/dist/src/videoFrame/index.d.ts.map +0 -1
  905. package/dist/src/videoFrame/index.js +0 -1
  906. package/dist/src/videoFrame/videoFrame.d.ts.map +0 -1
  907. package/src/audioFrame/index.ts +0 -2
  908. package/src/barChart/index.ts +0 -2
  909. package/src/chartTable/chartTable.ts +0 -88
  910. package/src/codeEditor/index.ts +0 -2
  911. package/src/codeSurface/index.ts +0 -2
  912. package/src/dropZone/index.ts +0 -2
  913. package/src/emptyState/index.ts +0 -2
  914. package/src/errorSummary/index.ts +0 -2
  915. package/src/fieldGrid/index.ts +0 -2
  916. package/src/fileTree/index.ts +0 -2
  917. package/src/filterChip/index.ts +0 -2
  918. package/src/filterStrip/index.ts +0 -2
  919. package/src/flashWord/index.ts +0 -2
  920. package/src/iconButton/index.ts +0 -2
  921. package/src/imageFrame/index.ts +0 -2
  922. package/src/keyHint/index.ts +0 -3
  923. package/src/lineChart/index.ts +0 -2
  924. package/src/lineDiff/diff.ts +0 -182
  925. package/src/lineDiff/index.ts +0 -4
  926. package/src/linkButton/index.ts +0 -2
  927. package/src/linkState/index.ts +0 -2
  928. package/src/liveRegion/index.ts +0 -2
  929. package/src/navStrip/index.ts +0 -2
  930. package/src/pageHead/index.ts +0 -2
  931. package/src/passwordField/index.ts +0 -2
  932. package/src/propsList/index.ts +0 -2
  933. package/src/queryChip/index.ts +0 -2
  934. package/src/selectAll/index.ts +0 -2
  935. package/src/skipLink/index.ts +0 -1
  936. package/src/statusBar/index.ts +0 -3
  937. package/src/textButton/index.ts +0 -2
  938. package/src/textareaField/index.ts +0 -2
  939. package/src/topBar/index.ts +0 -3
  940. package/src/videoFrame/index.ts +0 -2
@@ -1,8 +1,24 @@
1
1
  import { Input as UiInput } from "@foldkit/ui";
2
- import { Array, Effect, Equal, HashSet, Match, Option, Schema, Stream, String, pipe } from "effect";
2
+ import {
3
+ Array,
4
+ Effect,
5
+ Equal,
6
+ HashSet,
7
+ Match,
8
+ Option,
9
+ Schema,
10
+ Stream,
11
+ String,
12
+ pipe,
13
+ } from "effect";
3
14
  import * as FoldkitCommand from "foldkit/command";
4
15
  import * as Dom from "foldkit/dom";
5
- import type { Attribute, Html, HtmlBuilder, KeyboardModifiers } from "foldkit/html";
16
+ import type {
17
+ Attribute,
18
+ Html,
19
+ HtmlBuilder,
20
+ KeyboardModifiers,
21
+ } from "foldkit/html";
6
22
  import { defineMessageUnion } from "foldkit/message";
7
23
  import * as Render from "foldkit/render";
8
24
  import { modifyFields } from "foldkit/struct";
@@ -14,32 +30,29 @@ import * as Dialog from "../dialog/dialog.ts";
14
30
  import { foldDialog } from "../dialog/fold.ts";
15
31
  import { Focus } from "../focus/focus.ts";
16
32
  import * as Glyph from "../glyph/glyph.ts";
17
- import * as IconButton from "../iconButton/iconButton.ts";
33
+ import * as IconButton from "../icon-button/icon-button.ts";
18
34
  import { isPlain } from "../keys/keys.ts";
19
35
  import { LOCALE } from "../locale/locale.ts";
20
36
  import { slotView } from "../slot/slot.ts";
21
- import { prefixKeys } from "../subscription/prefixKeys.ts";
37
+ import { prefixKeys } from "../subscription/prefix-keys.ts";
22
38
  import {
23
39
  BindPaletteKeys,
24
40
  FIELD_ATTRIBUTE,
25
41
  OPTION_SELECTOR,
26
42
  PAGE_ATTRIBUTE,
27
43
  earlyKeys,
28
- shownPageOf,
29
44
  } from "./keys.ts";
30
45
  import { findCommands, pageChoices } from "./match.ts";
31
46
  import type { Choice, Command, Page } from "./match.ts";
32
47
  import { Message } from "./message.ts";
33
- import type { ArrowKey, ShownRow } from "./message.ts";
34
-
35
- // MODEL
48
+ import type { ArrowKey, RenderSnapshot, ShownRow } from "./message.ts";
36
49
 
37
- /** An open page: its command, its own query, and its cursor once the reader moved it. */
38
50
  const OpenPage = Schema.Struct({
39
51
  commandId: Schema.String,
40
52
  query: Schema.String,
41
53
  maybeCursor: Schema.Option(Schema.String),
42
54
  });
55
+
43
56
  type OpenPage = typeof OpenPage.Type;
44
57
 
45
58
  /** Schema for a command palette: its Dialog, the commands' query and cursor (kept while a
@@ -53,19 +66,20 @@ type OpenPage = typeof OpenPage.Type;
53
66
  * last query's rows) cannot name a row yet: `cursorShift` counts the arrows, which the next
54
67
  * render applies from the cursor's row, and `isEnterPending` an Enter. Such a key returns
55
68
  * `ReportPendingKeys`, which reads the row the next render shows the cursor on: it becomes
56
- * the cursor, and a waiting Enter acts on it. */
69
+ * the cursor, and a waiting Enter acts on it. `renderGeneration` counts the changes to the
70
+ * page, the query and the waiting arrows, so a report from an older render is refused. */
57
71
  export const Model = Schema.Struct({
58
72
  dialog: Dialog.Model,
59
73
  query: Schema.String,
60
74
  maybeCursor: Schema.Option(Schema.String),
61
- cursorShift: Schema.Number,
75
+ cursorShift: Schema.Finite,
62
76
  isEnterPending: Schema.Boolean,
77
+ renderGeneration: Schema.Int,
63
78
  maybePage: Schema.Option(OpenPage),
64
79
  maybePicking: Schema.Option(Schema.String),
65
80
  });
66
- export type Model = typeof Model.Type;
67
81
 
68
- // OUT MESSAGE
82
+ export type Model = typeof Model.Type;
69
83
 
70
84
  /** Union of OutMessages a command palette reports. `SelectedCommand`: run this command; the
71
85
  * palette has closed first, so what it opens takes focus. `SelectedChoice`: apply this choice
@@ -78,9 +92,8 @@ export const OutMessage = defineMessageUnion({
78
92
  SelectedChoice: { commandId: Schema.String, choiceId: Schema.String },
79
93
  Closed: {},
80
94
  });
81
- export type OutMessage = typeof OutMessage.Type;
82
95
 
83
- // INIT
96
+ export type OutMessage = typeof OutMessage.Type;
84
97
 
85
98
  /** Configuration for creating a command palette with `init`. The `id` must be unique in the
86
99
  * document. */
@@ -96,12 +109,11 @@ export const init = (config: InitConfig): Model => ({
96
109
  maybeCursor: Option.none(),
97
110
  cursorShift: 0,
98
111
  isEnterPending: false,
112
+ renderGeneration: 0,
99
113
  maybePage: Option.none(),
100
114
  maybePicking: Option.none(),
101
115
  });
102
116
 
103
- // ACCESSORS
104
-
105
117
  /** The palette's id, unique in the document. */
106
118
  export const id = (model: Model): string => Dialog.id(model.dialog);
107
119
 
@@ -111,20 +123,21 @@ export const isOpen = (model: Model): boolean => Dialog.isOpen(model.dialog);
111
123
  /** The words in the field: the open page's, or the commands'. A page whose choices are a
112
124
  * function of what is typed reads it here. */
113
125
  export const query = (model: Model): string =>
114
- Option.match(model.maybePage, { onNone: () => model.query, onSome: (page) => page.query });
126
+ Option.match(model.maybePage, {
127
+ onNone: () => model.query,
128
+ onSome: (page) => page.query,
129
+ });
115
130
 
116
131
  /** The command whose page is open. */
117
132
  export const maybePageId = (model: Model): Option.Option<string> =>
118
133
  Option.map(model.maybePage, (page) => page.commandId);
119
134
 
120
135
  /** Whether a picked choice is waiting for the caller's answer. */
121
- export const isPicking = (model: Model): boolean => Option.isSome(model.maybePicking);
122
-
123
- // COMMAND
136
+ export const isPicking = (model: Model): boolean =>
137
+ Option.isSome(model.maybePicking);
124
138
 
125
- /** The data attribute on a row: its id. */
126
139
  const ROW_ATTRIBUTE = "value";
127
- /** The data attribute on a command's row that opens a page. */
140
+
128
141
  const OPENS_PAGE_ATTRIBUTE = "pixel-paper-palette-opens-page";
129
142
 
130
143
  /**
@@ -139,63 +152,63 @@ export const ScrollToCursor = FoldkitCommand.define("ScrollToCursor", {
139
152
  messages: [Message.CompletedScrollToCursor],
140
153
  execute: ({ paletteId }) =>
141
154
  Effect.suspend(() =>
142
- Dom.scrollIntoView(`#${CSS.escape(listIdOf(paletteId))} [aria-selected="true"]`),
155
+ Dom.scrollIntoView(
156
+ `#${CSS.escape(listIdOf(paletteId))} [aria-selected="true"]`
157
+ )
143
158
  ).pipe(Effect.ignore, Effect.as(Message.CompletedScrollToCursor())),
144
159
  });
145
160
 
146
161
  const shownRowOf = (row: Element): Option.Option<ShownRow> =>
147
- Option.map(Option.fromNullishOr(row.getAttribute(`data-${ROW_ATTRIBUTE}`)), (rowId) => ({
148
- id: rowId,
149
- isHeld: row.getAttribute("aria-disabled") === "true",
150
- hasPage: row.hasAttribute(`data-${OPENS_PAGE_ATTRIBUTE}`),
151
- }));
152
-
153
- // The page the palette's render shows and the row it shows the cursor on, from its markup.
154
- const shownCursorOf = (paletteId: string) => {
155
- const find = (selector: string): Option.Option<Element> =>
156
- Option.fromNullishOr(document.querySelector(selector));
157
- return {
158
- maybeShownPage: Option.flatMap(
159
- find(`#${CSS.escape(paletteId)} [data-${PAGE_ATTRIBUTE}]`),
160
- shownPageOf,
161
- ),
162
- maybeRow: Option.flatMap(
163
- find(`#${CSS.escape(listIdOf(paletteId))} ${OPTION_SELECTOR}[aria-selected="true"]`),
164
- shownRowOf,
162
+ Option.map(
163
+ Option.fromNullishOr(row.getAttribute(`data-${ROW_ATTRIBUTE}`)),
164
+ (rowId) => ({
165
+ id: rowId,
166
+ isHeld: row.getAttribute("aria-disabled") === "true",
167
+ hasPage: row.hasAttribute(`data-${OPENS_PAGE_ATTRIBUTE}`),
168
+ })
169
+ );
170
+
171
+ const find = (selector: string): Option.Option<Element> =>
172
+ Option.fromNullishOr(document.querySelector(selector));
173
+
174
+ const shownCursorOf = (paletteId: string): Option.Option<ShownRow> =>
175
+ Option.flatMap(
176
+ find(
177
+ `#${CSS.escape(listIdOf(paletteId))} ${OPTION_SELECTOR}[aria-selected="true"]`
165
178
  ),
166
- };
167
- };
179
+ shownRowOf
180
+ );
168
181
 
169
182
  /** Reads, once the next render has committed, the row it shows the cursor on while keys wait
170
- * for it (see `Model`), with the query and waiting arrows the Model had as they waited, so
171
- * update knows whether that render is still the list. The palette's update returns it as a
172
- * key waits; in a Scene, resolve it with `Message.CompletedReportPendingKeys`. */
183
+ * for it (see `Model`), with the Model's `renderGeneration` as they waited, so update knows
184
+ * whether that render is still the list. The palette's update returns it as a key waits; in
185
+ * a Scene, resolve it with `Message.CompletedReportPendingKeys`. */
173
186
  export const ReportPendingKeys = FoldkitCommand.define("ReportPendingKeys", {
174
- args: { paletteId: Schema.String, shownQuery: Schema.String, shownShift: Schema.Number },
187
+ args: {
188
+ paletteId: Schema.String,
189
+ renderGeneration: Schema.Int,
190
+ },
175
191
  messages: [Message.CompletedReportPendingKeys],
176
- execute: ({ paletteId, shownQuery, shownShift }) =>
192
+ execute: ({ paletteId, renderGeneration }) =>
177
193
  Effect.gen(function* () {
178
194
  yield* Render.afterCommit;
179
- const shown = yield* Effect.sync(() => shownCursorOf(paletteId));
180
- return Message.CompletedReportPendingKeys({ shownQuery, shownShift, ...shown });
195
+ const maybeRow = yield* Effect.sync(() => shownCursorOf(paletteId));
196
+
197
+ return Message.CompletedReportPendingKeys({ renderGeneration, maybeRow });
181
198
  }),
182
199
  });
183
200
 
184
- // UPDATE
185
-
186
201
  type UpdateReturn = Update.ReturnWithOutMessage<Model, Message, OutMessage>;
187
202
 
188
- const scrollPaletteToCursor = (model: Model) => ScrollToCursor({ paletteId: id(model) });
203
+ const scrollPaletteToCursor = (model: Model) =>
204
+ ScrollToCursor({ paletteId: id(model) });
189
205
 
190
206
  const reportPendingKeys = (model: Model) =>
191
207
  ReportPendingKeys({
192
208
  paletteId: id(model),
193
- shownQuery: query(model),
194
- shownShift: model.cursorShift,
209
+ renderGeneration: model.renderGeneration,
195
210
  });
196
211
 
197
- // Focus goes back to the field as the view changes between the commands and a page (the Back
198
- // button that had it is gone).
199
212
  const focusField = (model: Model) => Focus({ id: fieldId(id(model)) });
200
213
 
201
214
  const toClosed = Dialog.OutMessage.match<OutMessage>({
@@ -206,7 +219,8 @@ const dialogFold = foldDialog(Dialog, {
206
219
  read: (model: Model) => model.dialog,
207
220
  write: (model: Model, nextDialog: Dialog.Model): Model =>
208
221
  modifyFields(model, { dialog: () => nextDialog }),
209
- toParentMessage: (message: Dialog.Message) => Message.GotDialogMessage({ message }),
222
+ toParentMessage: (message: Dialog.Message) =>
223
+ Message.GotDialogMessage({ message }),
210
224
  toParentOutMessage: toClosed,
211
225
  });
212
226
 
@@ -216,9 +230,14 @@ const freshPage = (commandId: string): OpenPage => ({
216
230
  maybeCursor: Option.none(),
217
231
  });
218
232
 
219
- /** No key waits for the next render (see `Model`). */
233
+ const nextGeneration = (generation: number): number => generation + 1;
234
+
220
235
  const clearPendingKeys = (model: Model): Model =>
221
- modifyFields(model, { cursorShift: () => 0, isEnterPending: () => false });
236
+ modifyFields(model, {
237
+ cursorShift: () => 0,
238
+ isEnterPending: () => false,
239
+ renderGeneration: nextGeneration,
240
+ });
222
241
 
223
242
  const fresh = (model: Model, maybePage: Option.Option<OpenPage>): Model =>
224
243
  clearPendingKeys(
@@ -227,38 +246,45 @@ const fresh = (model: Model, maybePage: Option.Option<OpenPage>): Model =>
227
246
  maybeCursor: () => Option.none(),
228
247
  maybePage: () => maybePage,
229
248
  maybePicking: () => Option.none(),
230
- }),
249
+ })
231
250
  );
232
251
 
233
- /** Makes the Model follow what the view showed: a page whose command is gone is dropped (with
234
- * a pick out on it), so the commands' query and cursor take the reader's input again. */
235
- const followShown = (model: Model, maybeShownPage: Option.Option<string>): Model =>
252
+ const followShown = (
253
+ model: Model,
254
+ maybeShownPage: Option.Option<string>
255
+ ): Model =>
236
256
  Equal.equals(maybePageId(model), maybeShownPage)
237
257
  ? model
238
258
  : clearPendingKeys(
239
259
  modifyFields(model, {
240
260
  maybePage: () => Option.map(maybeShownPage, freshPage),
241
261
  maybePicking: () => Option.none(),
242
- }),
262
+ })
243
263
  );
244
264
 
245
- const modifyPage = (model: Model, modifyOpenPage: (page: OpenPage) => OpenPage): Model =>
246
- modifyFields(model, { maybePage: Option.map(modifyOpenPage) });
265
+ const modifyPage = (
266
+ model: Model,
267
+ modifyOpenPage: (page: OpenPage) => OpenPage
268
+ ): Model => modifyFields(model, { maybePage: Option.map(modifyOpenPage) });
247
269
 
248
- const unlessPicking = (model: Model, next: (model: Model) => UpdateReturn): UpdateReturn =>
249
- isPicking(model) ? { model } : next(model);
270
+ const unlessPicking = (
271
+ model: Model,
272
+ next: (model: Model) => UpdateReturn
273
+ ): UpdateReturn => (isPicking(model) ? { model } : next(model));
250
274
 
251
275
  const leavePage = (model: Model): UpdateReturn =>
252
276
  isPicking(model) || Option.isNone(model.maybePage)
253
277
  ? { model }
254
278
  : {
255
- model: clearPendingKeys(modifyFields(model, { maybePage: () => Option.none() })),
279
+ model: clearPendingKeys(
280
+ modifyFields(model, { maybePage: () => Option.none() })
281
+ ),
256
282
  commands: [focusField(model), scrollPaletteToCursor(model)],
257
283
  };
258
284
 
259
285
  const openPage = (model: Model, commandId: string): UpdateReturn => ({
260
286
  model: clearPendingKeys(
261
- modifyFields(model, { maybePage: () => Option.some(freshPage(commandId)) }),
287
+ modifyFields(model, { maybePage: () => Option.some(freshPage(commandId)) })
262
288
  ),
263
289
  commands: [focusField(model), scrollPaletteToCursor(model)],
264
290
  });
@@ -266,39 +292,44 @@ const openPage = (model: Model, commandId: string): UpdateReturn => ({
266
292
  const selectCommand = (model: Model, commandId: string): UpdateReturn =>
267
293
  pipe(
268
294
  dialogFold.close(model),
269
- Update.withOutMessage(OutMessage.SelectedCommand({ id: commandId })),
295
+ Update.withOutMessage(OutMessage.SelectedCommand({ id: commandId }))
270
296
  );
271
297
 
272
298
  const moveCursor = (model: Model, cursorId: string): Model =>
273
299
  modifyFields(
274
300
  Option.match(model.maybePage, {
275
- onNone: () => modifyFields(model, { maybeCursor: () => Option.some(cursorId) }),
301
+ onNone: () =>
302
+ modifyFields(model, { maybeCursor: () => Option.some(cursorId) }),
276
303
  onSome: () =>
277
304
  modifyPage(model, (page) =>
278
- modifyFields(page, { maybeCursor: () => Option.some(cursorId) }),
305
+ modifyFields(page, { maybeCursor: () => Option.some(cursorId) })
279
306
  ),
280
307
  }),
281
- { cursorShift: () => 0 },
308
+ { cursorShift: () => 0, renderGeneration: nextGeneration }
282
309
  );
283
310
 
284
- // A pick drops the keys waiting for the next render: the row picked is the one acted on.
285
- const pick = (model: Model, commandId: string, choiceId: string): UpdateReturn => ({
311
+ const pick = (
312
+ model: Model,
313
+ commandId: string,
314
+ choiceId: string
315
+ ): UpdateReturn => ({
286
316
  model: clearPendingKeys(
287
- modifyFields(moveCursor(model, choiceId), { maybePicking: () => Option.some(choiceId) }),
317
+ modifyFields(moveCursor(model, choiceId), {
318
+ maybePicking: () => Option.some(choiceId),
319
+ })
288
320
  ),
289
321
  outMessage: OutMessage.SelectedChoice({ commandId, choiceId }),
290
322
  });
291
323
 
292
- // What a click on a row or Enter on the cursor's does: nothing when it is held, else pick it
293
- // on a page, open its page, or select it. Never while a pick is out: the click and the keys
294
- // come through `unlessPicking`, and a pick clears the waiting Enter `settlePending` runs.
295
324
  const runRow = (model: Model, row: ShownRow): UpdateReturn => {
296
325
  if (row.isHeld) {
297
326
  return { model };
298
327
  }
328
+
299
329
  return Option.match(maybePageId(model), {
300
330
  onSome: (commandId) => pick(model, commandId, row.id),
301
- onNone: () => (row.hasPage ? openPage(model, row.id) : selectCommand(model, row.id)),
331
+ onNone: () =>
332
+ row.hasPage ? openPage(model, row.id) : selectCommand(model, row.id),
302
333
  });
303
334
  };
304
335
 
@@ -308,40 +339,50 @@ const maybeCurrentCursor = (model: Model): Option.Option<string> =>
308
339
  onSome: (page) => page.maybeCursor,
309
340
  });
310
341
 
311
- const ARROW_STEP: Readonly<Record<ArrowKey, number>> = { ArrowUp: -1, ArrowDown: 1 };
342
+ const ARROW_STEP: Readonly<Record<ArrowKey, number>> = {
343
+ ArrowUp: -1,
344
+ ArrowDown: 1,
345
+ };
312
346
 
313
- type ShownList = Omit<typeof Message.PressedEnter.Type, "_tag" | "maybeShownPage">;
347
+ const isListed = (
348
+ rows: ReadonlyArray<Readonly<{ id: string }>>,
349
+ rowId: string
350
+ ): boolean => Array.some(rows, (row) => row.id === rowId);
314
351
 
315
- const isListed = (rows: ReadonlyArray<Readonly<{ id: string }>>, rowId: string): boolean =>
316
- Array.some(rows, (row) => row.id === rowId);
352
+ type CursorAsShown =
353
+ | Readonly<{ _tag: "Listed"; rowId: string }>
354
+ | Readonly<{ _tag: "Shown"; maybeRowId: Option.Option<string> }>
355
+ | Readonly<{ _tag: "Waiting" }>;
317
356
 
318
- // NOTE: where the cursor is among the rows a key carries (see `Model`). With no arrows waiting
319
- // it is the Model's cursor while that row is listed, else the shown one, so each key acts from
320
- // where the last left it, also when several come before the next render; with arrows waiting,
321
- // the shown row once the render has applied them. Rows that are not the list: none, and the
322
- // key waits for the next render.
323
- const cursorAsShown = (model: Model, shown: ShownList): Option.Option<Option.Option<string>> => {
357
+ const cursorAsShown = (model: Model, shown: RenderSnapshot): CursorAsShown => {
324
358
  const { rows, maybeShownCursor, shownQuery, shownShift } = shown;
325
359
  const isTheList = shownQuery === query(model);
360
+ const hasNoWaitingArrows = model.cursorShift === 0;
361
+ const hasAppliedWaitingArrows = shownShift === model.cursorShift;
326
362
 
327
- if (isTheList && model.cursorShift === 0) {
328
- return Option.some(
329
- Option.orElse(
330
- Option.filter(maybeCurrentCursor(model), (rowId) => isListed(rows, rowId)),
331
- () => maybeShownCursor,
363
+ if (isTheList && hasNoWaitingArrows) {
364
+ return Option.match(
365
+ Option.filter(maybeCurrentCursor(model), (rowId) =>
366
+ isListed(rows, rowId)
332
367
  ),
368
+ {
369
+ onSome: (rowId): CursorAsShown => ({ _tag: "Listed", rowId }),
370
+ onNone: (): CursorAsShown => ({
371
+ _tag: "Shown",
372
+ maybeRowId: maybeShownCursor,
373
+ }),
374
+ }
333
375
  );
334
- } else if (isTheList && shownShift === model.cursorShift) {
335
- return Option.some(maybeShownCursor);
336
- } else {
337
- return Option.none();
376
+ } else if (isTheList && hasAppliedWaitingArrows) {
377
+ return { _tag: "Shown", maybeRowId: maybeShownCursor };
338
378
  }
379
+
380
+ return { _tag: "Waiting" };
339
381
  };
340
382
 
341
- // The cursor moves to a row and the waiting arrows are spent; a waiting Enter asks for the
342
- // next render again, which shows the cursor on that row.
343
383
  const stepTo = (model: Model, rowId: string): UpdateReturn => {
344
384
  const moved = moveCursor(model, rowId);
385
+
345
386
  return {
346
387
  model: moved,
347
388
  commands: [
@@ -351,86 +392,104 @@ const stepTo = (model: Model, rowId: string): UpdateReturn => {
351
392
  };
352
393
  };
353
394
 
354
- // The row `steps` rows on from the cursor's, held at the ends. Update's arrows, one at a time,
355
- // and the view's waiting arrows, all at once, both land through this, so they land alike.
356
395
  const rowAfter = <Row extends Readonly<{ id: string }>>(
357
- rows: ReadonlyArray<Row>,
396
+ rows: readonly Row[],
358
397
  maybeFrom: Option.Option<string>,
359
- steps: number,
398
+ steps: number
360
399
  ): Option.Option<Row> =>
361
400
  pipe(
362
401
  maybeFrom,
363
- Option.flatMap((rowId) => Array.findFirstIndex(rows, (row) => row.id === rowId)),
364
- Option.flatMap((index) =>
365
- Array.get(rows, Math.min(Math.max(index + steps, 0), rows.length - 1)),
402
+ Option.flatMap((rowId) =>
403
+ Array.findFirstIndex(rows, (row) => row.id === rowId)
366
404
  ),
405
+ Option.flatMap((index) =>
406
+ Array.get(rows, Math.min(Math.max(index + steps, 0), rows.length - 1))
407
+ )
367
408
  );
368
409
 
369
410
  const stepFrom = (
370
411
  model: Model,
371
412
  key: ArrowKey,
372
- rows: ReadonlyArray<ShownRow>,
373
- maybeFrom: Option.Option<string>,
413
+ rows: readonly ShownRow[],
414
+ maybeFrom: Option.Option<string>
374
415
  ): UpdateReturn =>
375
416
  Option.match(rowAfter(rows, maybeFrom, ARROW_STEP[key]), {
376
417
  onNone: () => ({ model }),
377
418
  onSome: (row) => stepTo(model, row.id),
378
419
  });
379
420
 
380
- // An arrow that cannot name a row yet waits for the next render, which applies it from the
381
- // cursor's row (see `Model`).
382
421
  const pendArrow = (model: Model, key: ArrowKey): UpdateReturn => {
383
- const pending = modifyFields(model, { cursorShift: (shift) => shift + ARROW_STEP[key] });
384
- return { model: pending, commands: [scrollPaletteToCursor(model), reportPendingKeys(pending)] };
422
+ const pending = modifyFields(model, {
423
+ cursorShift: (shift) => shift + ARROW_STEP[key],
424
+ renderGeneration: nextGeneration,
425
+ });
426
+
427
+ return {
428
+ model: pending,
429
+ commands: [scrollPaletteToCursor(model), reportPendingKeys(pending)],
430
+ };
385
431
  };
386
432
 
387
- // An arrow steps one row from the cursor as its render showed it, and stops at the ends.
388
- const pressArrow = (model: Model, key: ArrowKey, shown: ShownList): UpdateReturn =>
389
- Option.match(cursorAsShown(model, shown), {
390
- onNone: () => pendArrow(model, key),
391
- onSome: (maybeFrom) => stepFrom(model, key, shown.rows, maybeFrom),
433
+ const pressArrow = (
434
+ model: Model,
435
+ key: ArrowKey,
436
+ shown: RenderSnapshot
437
+ ): UpdateReturn =>
438
+ Match.valueTags(cursorAsShown(model, shown), {
439
+ Listed: ({ rowId }) => stepFrom(model, key, shown.rows, Option.some(rowId)),
440
+ Shown: ({ maybeRowId }) => stepFrom(model, key, shown.rows, maybeRowId),
441
+ Waiting: () => pendArrow(model, key),
392
442
  });
393
443
 
394
444
  const pendEnter = (model: Model): UpdateReturn => {
395
445
  const pending = modifyFields(model, { isEnterPending: () => true });
446
+
396
447
  return { model: pending, commands: [reportPendingKeys(pending)] };
397
448
  };
398
449
 
399
- // An Enter acts on the cursor's row as its render showed it, or waits for the next render.
400
- const pressEnter = (model: Model, shown: ShownList): UpdateReturn =>
401
- Option.match(cursorAsShown(model, shown), {
402
- onNone: () => pendEnter(model),
403
- onSome: (maybeRowId) =>
404
- pipe(
405
- maybeRowId,
406
- Option.flatMap((rowId) => Array.findFirst(shown.rows, (row) => row.id === rowId)),
407
- Option.match({ onNone: () => ({ model }), onSome: (row) => runRow(model, row) }),
408
- ),
450
+ const enterOn = (
451
+ model: Model,
452
+ rows: readonly ShownRow[],
453
+ maybeRowId: Option.Option<string>
454
+ ): UpdateReturn =>
455
+ pipe(
456
+ maybeRowId,
457
+ Option.flatMap((rowId) => Array.findFirst(rows, (row) => row.id === rowId)),
458
+ Option.match({
459
+ onNone: () => ({ model }),
460
+ onSome: (row) => runRow(model, row),
461
+ })
462
+ );
463
+
464
+ const pressEnter = (model: Model, shown: RenderSnapshot): UpdateReturn =>
465
+ Match.valueTags(cursorAsShown(model, shown), {
466
+ Listed: ({ rowId }) => enterOn(model, shown.rows, Option.some(rowId)),
467
+ Shown: ({ maybeRowId }) => enterOn(model, shown.rows, maybeRowId),
468
+ Waiting: () => pendEnter(model),
409
469
  });
410
470
 
411
- const isPending = (model: Model): boolean => model.cursorShift !== 0 || model.isEnterPending;
471
+ const isPending = (model: Model): boolean =>
472
+ model.cursorShift !== 0 || model.isEnterPending;
412
473
 
413
474
  type PendingReport = typeof Message.CompletedReportPendingKeys.Type;
414
475
 
415
- // A report settles the waiting keys (see `Model`) only from the render the Model is at. One from
416
- // a render it has moved on from (another page, query or count of arrows) is left: the key that
417
- // moved it on cleared the waiting keys or asked again.
418
476
  const settlePending = (model: Model, report: PendingReport): UpdateReturn => {
419
- const { maybeShownPage, shownQuery, shownShift, maybeRow } = report;
420
- const isCurrent =
421
- Equal.equals(maybePageId(model), maybeShownPage) &&
422
- shownShift === model.cursorShift &&
423
- shownQuery === query(model);
424
- if (!isPending(model) || !isCurrent) {
477
+ if (!isPending(model) || report.renderGeneration !== model.renderGeneration) {
425
478
  return { model };
426
479
  }
480
+
427
481
  const settled = clearPendingKeys(model);
428
- return Option.match(maybeRow, {
482
+
483
+ return Option.match(report.maybeRow, {
429
484
  onNone: () => ({ model: settled }),
430
485
  onSome: (row) => {
431
486
  const moved = moveCursor(settled, row.id);
432
487
  const ran = model.isEnterPending ? runRow(moved, row) : { model: moved };
433
- return { ...ran, commands: [scrollPaletteToCursor(model), ...(ran.commands ?? [])] };
488
+
489
+ return {
490
+ ...ran,
491
+ commands: [scrollPaletteToCursor(model), ...(ran.commands ?? [])],
492
+ };
434
493
  },
435
494
  });
436
495
  };
@@ -438,35 +497,49 @@ const settlePending = (model: Model, report: PendingReport): UpdateReturn => {
438
497
  const updateQuery = (model: Model, value: string): Model =>
439
498
  clearPendingKeys(
440
499
  Option.match(model.maybePage, {
441
- onNone: () => modifyFields(model, { query: () => value, maybeCursor: () => Option.none() }),
500
+ onNone: () =>
501
+ modifyFields(model, {
502
+ query: () => value,
503
+ maybeCursor: () => Option.none(),
504
+ }),
442
505
  onSome: () =>
443
506
  modifyPage(model, (page) =>
444
- modifyFields(page, { query: () => value, maybeCursor: () => Option.none() }),
507
+ modifyFields(page, {
508
+ query: () => value,
509
+ maybeCursor: () => Option.none(),
510
+ })
445
511
  ),
446
- }),
512
+ })
447
513
  );
448
514
 
449
515
  /** Processes a command palette Message and returns the next Model, Commands and OutMessage. */
450
516
  export const update = (model: Model, message: Message) =>
451
517
  Message.match<UpdateReturn>(message, {
452
- GotDialogMessage: ({ message: dialogMessage }) => dialogFold.update(model, dialogMessage),
518
+ GotDialogMessage: ({ message: dialogMessage }) =>
519
+ dialogFold.update(model, dialogMessage),
453
520
  UpdatedQuery: ({ value, maybeShownPage }) =>
454
521
  unlessPicking(followShown(model, maybeShownPage), (shown) => ({
455
522
  model: updateQuery(shown, value),
456
523
  commands: [scrollPaletteToCursor(shown)],
457
524
  })),
458
- PressedArrowKey: ({ key, maybeShownPage, ...shown }) =>
459
- unlessPicking(followShown(model, maybeShownPage), (current) =>
460
- pressArrow(current, key, shown),
525
+ PressedArrowKey: ({ key, snapshot }) =>
526
+ unlessPicking(followShown(model, snapshot.maybeShownPage), (current) =>
527
+ pressArrow(current, key, snapshot)
461
528
  ),
462
- PressedEarlyArrowKey: ({ key }) => unlessPicking(model, (current) => pendArrow(current, key)),
529
+ PressedEarlyArrowKey: ({ key }) =>
530
+ unlessPicking(model, (current) => pendArrow(current, key)),
463
531
  CompletedReportPendingKeys: (report) => settlePending(model, report),
464
- PressedEnter: ({ maybeShownPage, ...shown }) =>
465
- unlessPicking(followShown(model, maybeShownPage), (current) => pressEnter(current, shown)),
532
+ PressedEnter: ({ snapshot }) =>
533
+ unlessPicking(followShown(model, snapshot.maybeShownPage), (current) =>
534
+ pressEnter(current, snapshot)
535
+ ),
466
536
  PressedEarlyEnter: () => unlessPicking(model, pendEnter),
467
- PressedBackspace: ({ maybeShownPage }) => leavePage(followShown(model, maybeShownPage)),
537
+ PressedBackspace: ({ maybeShownPage }) =>
538
+ leavePage(followShown(model, maybeShownPage)),
468
539
  ClickedRow: ({ row, maybeShownPage }) =>
469
- unlessPicking(followShown(model, maybeShownPage), (current) => runRow(current, row)),
540
+ unlessPicking(followShown(model, maybeShownPage), (current) =>
541
+ runRow(current, row)
542
+ ),
470
543
  ClickedBack: () => leavePage(model),
471
544
  CompletedScrollToCursor: () => ({ model }),
472
545
  CompletedFocus: () => ({ model }),
@@ -486,13 +559,19 @@ export type OpenAtConfig = Readonly<{
486
559
  }>;
487
560
 
488
561
  /** Opens the palette straight on a command's page. Back still leads to the commands. */
489
- export const openAt = (model: Model, config: OpenAtConfig): Update.Return<Model, Message> =>
562
+ export const openAt = (
563
+ model: Model,
564
+ config: OpenAtConfig
565
+ ): Update.Return<Model, Message> =>
490
566
  dialogFold.open(fresh(model, Option.some(freshPage(config.commandId))));
491
567
 
492
568
  /** The caller applied the choice: the palette closes. An answer for a pick that is no longer
493
569
  * out (the palette was dismissed, its page left, or a newer pick replaced it) changes
494
570
  * nothing; the caller keeps the write it made. */
495
- export const pickSucceeded = (model: Model, choiceId: string): Update.Return<Model, Message> =>
571
+ export const pickSucceeded = (
572
+ model: Model,
573
+ choiceId: string
574
+ ): Update.Return<Model, Message> =>
496
575
  Option.contains(model.maybePicking, choiceId)
497
576
  ? dialogFold.close(fresh(model, Option.none()))
498
577
  : { model };
@@ -500,13 +579,14 @@ export const pickSucceeded = (model: Model, choiceId: string): Update.Return<Mod
500
579
  /** The caller refused the choice: the page stays with its query, focus and the cursor on that
501
580
  * choice; say why in the view's `toDetailView`. An answer for a pick that is no longer out
502
581
  * changes nothing. */
503
- export const pickFailed = (model: Model, choiceId: string): Update.Return<Model, Message> =>
582
+ export const pickFailed = (
583
+ model: Model,
584
+ choiceId: string
585
+ ): Update.Return<Model, Message> =>
504
586
  Option.contains(model.maybePicking, choiceId)
505
587
  ? { model: modifyFields(model, { maybePicking: () => Option.none() }) }
506
588
  : { model };
507
589
 
508
- // SUBSCRIPTIONS
509
-
510
590
  const earlyKeySubscriptions = Subscription.make<Model, Message>()((entry) => ({
511
591
  earlyKeys: entry(
512
592
  { maybeOpenId: Schema.Option(Schema.String) },
@@ -515,8 +595,11 @@ const earlyKeySubscriptions = Subscription.make<Model, Message>()((entry) => ({
515
595
  maybeOpenId: isOpen(model) ? Option.some(id(model)) : Option.none(),
516
596
  }),
517
597
  dependenciesToStream: ({ maybeOpenId }) =>
518
- Option.match(maybeOpenId, { onNone: () => Stream.empty, onSome: earlyKeys }),
519
- },
598
+ Option.match(maybeOpenId, {
599
+ onNone: () => Stream.empty,
600
+ onSome: earlyKeys,
601
+ }),
602
+ }
520
603
  ),
521
604
  }));
522
605
 
@@ -528,13 +611,11 @@ const earlyKeySubscriptions = Subscription.make<Model, Message>()((entry) => ({
528
611
  export const subscriptions = <Prefix extends string>(keyPrefix: Prefix) =>
529
612
  prefixKeys(keyPrefix, earlyKeySubscriptions);
530
613
 
531
- // VIEW
532
-
533
614
  /** Per-render inputs passed to `view` through `h.submodel`'s `viewInputs`. */
534
615
  export type ViewInputs = Readonly<{
535
616
  /** Built from what the caller snapshotted as the palette opened (see `open`). A command
536
617
  * that leaves while its page is open sends the reader back to the commands. */
537
- commands: ReadonlyArray<Command>;
618
+ commands: readonly Command[];
538
619
  /** What the commands act on, kept on every page (the selected item's name). Defaults to
539
620
  * `"commands"`. */
540
621
  scope?: string;
@@ -554,85 +635,113 @@ type ShownPageState = Readonly<{ page: Page; state: OpenPage }>;
554
635
  type Shown = Readonly<{
555
636
  maybePage: Option.Option<ShownPageState>;
556
637
  rows: ReadonlyArray<Choice | Command>;
557
- /** The rows a page's query keeps only to show where a row it finds sits in the tree. */
558
638
  contextIds: HashSet.HashSet<string>;
559
639
  maybeCursorId: Option.Option<string>;
560
640
  }>;
561
641
 
562
- const pageOf = (commands: ReadonlyArray<Command>, state: OpenPage): Option.Option<ShownPageState> =>
642
+ const pageOf = (
643
+ commands: readonly Command[],
644
+ state: OpenPage
645
+ ): Option.Option<ShownPageState> =>
563
646
  pipe(
564
647
  Array.findFirst(commands, (command) => command.id === state.commandId),
565
648
  Option.flatMap((command) => Option.fromNullishOr(command.page)),
566
- Option.map((page) => ({ page, state })),
649
+ Option.map((page) => ({ page, state }))
567
650
  );
568
651
 
569
652
  const firstListed = (
570
- rows: ReadonlyArray<Choice>,
571
- candidates: ReadonlyArray<Option.Option<string>>,
653
+ rows: ReadonlyArray<Readonly<{ id: string }>>,
654
+ candidates: ReadonlyArray<Option.Option<string>>
572
655
  ): Option.Option<string> =>
573
- Array.findFirst(Array.getSomes(candidates), (cursorId) => isListed(rows, cursorId));
656
+ Array.findFirst(Array.getSomes(candidates), (cursorId) =>
657
+ isListed(rows, cursorId)
658
+ );
574
659
 
575
- const firstId = (rows: ReadonlyArray<Choice | Command>): Option.Option<string> =>
576
- Option.map(Array.head(rows), (row) => row.id);
660
+ const firstId = (
661
+ rows: ReadonlyArray<Readonly<{ id: string }>>
662
+ ): Option.Option<string> => Option.map(Array.head(rows), (row) => row.id);
663
+
664
+ const cursorRowFallback = ({
665
+ maybeMovedTo,
666
+ rows,
667
+ found,
668
+ pageDefaults,
669
+ }: Readonly<{
670
+ maybeMovedTo: Option.Option<string>;
671
+ rows: ReadonlyArray<Readonly<{ id: string }>>;
672
+ found: ReadonlyArray<Readonly<{ id: string }>>;
673
+ pageDefaults: ReadonlyArray<Option.Option<string>>;
674
+ }>): Option.Option<string> =>
675
+ pipe(
676
+ Option.filter(maybeMovedTo, (rowId) => isListed(rows, rowId)),
677
+ Option.orElse(() => firstListed(found, pageDefaults)),
678
+ Option.orElse(() => firstId(found))
679
+ );
577
680
 
578
681
  const shifted = (shown: Shown, shift: number): Shown => ({
579
682
  ...shown,
580
- maybeCursorId: Option.map(rowAfter(shown.rows, shown.maybeCursorId, shift), (row) => row.id),
683
+ maybeCursorId: Option.map(
684
+ rowAfter(shown.rows, shown.maybeCursorId, shift),
685
+ (row) => row.id
686
+ ),
581
687
  });
582
688
 
583
- // NOTE: arrows waiting for the view count from the cursor's row. When that row has left the
584
- // list (the application changed it in between), they are dropped rather than counted from
585
- // another row.
586
- const shownOf = (model: Model, commands: ReadonlyArray<Command>): Shown => {
587
- const unshifted = unshiftedOf(model, commands);
588
- const isAnchored = Option.match(maybeCurrentCursor(model), {
589
- onNone: () => true,
590
- onSome: (rowId) => Option.contains(unshifted.maybeCursorId, rowId),
591
- });
592
- return isAnchored ? shifted(unshifted, model.cursorShift) : unshifted;
593
- };
689
+ const unshiftedOf = (model: Model, commands: readonly Command[]): Shown => {
690
+ const maybePage = Option.flatMap(model.maybePage, (state) =>
691
+ pageOf(commands, state)
692
+ );
594
693
 
595
- // What the view shows of the Model with `commands`: the open page while its command is
596
- // listed, the rows its query finds (on a tree page, with the rows they sit under), and the
597
- // cursor's row: the row the reader moved it to while that row is listed, else the page's
598
- // `start`, else its `current`, else the first row, these three only among the rows the query
599
- // finds; none when nothing is listed.
600
- const unshiftedOf = (model: Model, commands: ReadonlyArray<Command>): Shown => {
601
- const maybePage = Option.flatMap(model.maybePage, (state) => pageOf(commands, state));
602
694
  return Option.match(maybePage, {
603
695
  onNone: () => {
604
696
  const rows = findCommands(commands, model.query);
697
+
605
698
  return {
606
699
  maybePage,
607
700
  rows,
608
701
  contextIds: HashSet.empty(),
609
- maybeCursorId: pipe(
610
- Option.filter(model.maybeCursor, (rowId) => isListed(rows, rowId)),
611
- Option.orElse(() => firstId(rows)),
612
- ),
702
+ maybeCursorId: cursorRowFallback({
703
+ maybeMovedTo: model.maybeCursor,
704
+ rows,
705
+ found: rows,
706
+ pageDefaults: [],
707
+ }),
613
708
  };
614
709
  },
615
710
  onSome: ({ page, state }) => {
616
711
  const { rows, found, contextIds } = pageChoices(page, state.query);
712
+
617
713
  return {
618
714
  maybePage,
619
715
  rows,
620
716
  contextIds,
621
- maybeCursorId: pipe(
622
- Option.filter(state.maybeCursor, (rowId) => isListed(rows, rowId)),
623
- Option.orElse(() =>
624
- firstListed(found, [
625
- Option.fromNullishOr(page.start),
626
- Option.fromNullishOr(page.current),
627
- ]),
628
- ),
629
- Option.orElse(() => firstId(found)),
630
- ),
717
+ maybeCursorId: cursorRowFallback({
718
+ maybeMovedTo: state.maybeCursor,
719
+ rows,
720
+ found,
721
+ pageDefaults: [
722
+ Option.fromNullishOr(page.start),
723
+ Option.fromNullishOr(page.current),
724
+ ],
725
+ }),
631
726
  };
632
727
  },
633
728
  });
634
729
  };
635
730
 
731
+ const hasCursorRowLeft = (model: Model, unshifted: Shown): boolean =>
732
+ Option.exists(
733
+ maybeCurrentCursor(model),
734
+ (rowId) => !Option.contains(unshifted.maybeCursorId, rowId)
735
+ );
736
+
737
+ const dropArrowsWhenCursorRowGone = (model: Model, unshifted: Shown): Shown =>
738
+ hasCursorRowLeft(model, unshifted)
739
+ ? unshifted
740
+ : shifted(unshifted, model.cursorShift);
741
+
742
+ const shownOf = (model: Model, commands: readonly Command[]): Shown =>
743
+ dropArrowsWhenCursorRowGone(model, unshiftedOf(model, commands));
744
+
636
745
  /** The row the cursor is on as the view shows it with `commands`: the row the reader moved it
637
746
  * to while that row is listed, else the page's `start` or `current` while the query finds it,
638
747
  * else the first row the query finds; none when nothing is listed. Compare it before and after
@@ -641,7 +750,7 @@ const unshiftedOf = (model: Model, commands: ReadonlyArray<Command>): Shown => {
641
750
  * it, and the list its scroll. */
642
751
  export const maybeCursorId = (
643
752
  model: Model,
644
- commands: ReadonlyArray<Command>,
753
+ commands: readonly Command[]
645
754
  ): Option.Option<string> => shownOf(model, commands).maybeCursorId;
646
755
 
647
756
  const isCommand = (row: Choice | Command): row is Command => "group" in row;
@@ -655,70 +764,76 @@ const isContextRow = (shown: Shown, row: Choice | Command): boolean =>
655
764
  const levelOf = (row: Choice | Command): Option.Option<number> =>
656
765
  "level" in row ? Option.fromNullishOr(row.level) : Option.none();
657
766
 
658
- // What a row is as this render shows it, which Enter acts on as a click would.
659
767
  const shownRowFor = (shown: Shown, row: Choice | Command): ShownRow => ({
660
768
  id: row.id,
661
769
  isHeld: row.isDisabled === true || isCurrentRow(shown, row),
662
770
  hasPage: isCommand(row) && row.page !== undefined,
663
771
  });
664
772
 
665
- // The query the shown rows were found by: the open page's, or the commands' when the view
666
- // shows them (also for a page whose command left).
667
773
  const shownQueryOf = (model: Model, shown: Shown): string =>
668
- Option.match(shown.maybePage, { onNone: () => model.query, onSome: ({ state }) => state.query });
774
+ Option.match(shown.maybePage, {
775
+ onNone: () => model.query,
776
+ onSome: ({ state }) => state.query,
777
+ });
669
778
 
670
- // The command whose page the view shows.
671
779
  const shownPageIdOf = (shown: Shown): Option.Option<string> =>
672
780
  Option.map(shown.maybePage, ({ state }) => state.commandId);
673
781
 
674
- // NOTE: the field's keys that act on the rows are taken here, where the rows are known, as a
675
- // Mount on the document cannot know them: ↑, ↓ and Enter carry what this render shows (see
676
- // `Model`), and each is taken from the field (its default prevented). A modified key and every
677
- // key while a pick is out are left to the field.
678
- const fieldKeyDown =
782
+ const renderedListOf = (model: Model, shown: Shown): RenderSnapshot => ({
783
+ rows: Array.map(shown.rows, (row) => shownRowFor(shown, row)),
784
+ maybeShownCursor: shown.maybeCursorId,
785
+ maybeShownPage: shownPageIdOf(shown),
786
+ shownQuery: shownQueryOf(model, shown),
787
+ shownShift: model.cursorShift,
788
+ });
789
+
790
+ const rowKeysWithRenderedList =
679
791
  (model: Model, shown: Shown) =>
680
792
  (key: string, modifiers: KeyboardModifiers): Option.Option<Message> => {
681
- const list = {
682
- rows: Array.map(shown.rows, (row) => shownRowFor(shown, row)),
683
- maybeShownCursor: shown.maybeCursorId,
684
- maybeShownPage: shownPageIdOf(shown),
685
- shownQuery: shownQueryOf(model, shown),
686
- shownShift: model.cursorShift,
687
- };
793
+ const snapshot = renderedListOf(model, shown);
794
+
688
795
  return isPicking(model) || !isPlain(modifiers)
689
796
  ? Option.none()
690
797
  : Match.value(key).pipe(
691
798
  Match.withReturnType<Option.Option<Message>>(),
692
799
  Match.whenOr("ArrowDown", "ArrowUp", (arrow) =>
693
- Option.some(Message.PressedArrowKey({ key: arrow, ...list })),
800
+ Option.some(Message.PressedArrowKey({ key: arrow, snapshot }))
801
+ ),
802
+ Match.when("Enter", () =>
803
+ Option.some(Message.PressedEnter({ snapshot }))
694
804
  ),
695
- Match.when("Enter", () => Option.some(Message.PressedEnter(list))),
696
- Match.orElse(() => Option.none()),
805
+ Match.orElse(() => Option.none())
697
806
  );
698
807
  };
699
808
 
700
- const optionId = (paletteId: string, index: number): string => `${paletteId}-option-${index}`;
809
+ const optionId = (paletteId: string, index: number): string =>
810
+ `${paletteId}-option-${index}`;
701
811
 
702
812
  const NOTHING_FOUND = "nothing matches · try fewer letters";
703
813
  const COMMANDS_FOOT = "↑ ↓ move · enter runs · esc closes";
704
814
  const PAGE_FOOT = "↑ ↓ move · enter picks · ⌫ back · esc closes";
705
815
 
706
- const resultWord = (count: number): string => (count === 1 ? "result" : "results");
816
+ const resultWord = (count: number): string =>
817
+ count === 1 ? "result" : "results";
707
818
 
708
819
  const countWords = (count: number): string =>
709
- count === 0 ? "Nothing matches." : `${count.toLocaleString(LOCALE)} ${resultWord(count)}.`;
820
+ count === 0
821
+ ? "Nothing matches."
822
+ : `${count.toLocaleString(LOCALE)} ${resultWord(count)}.`;
710
823
 
711
824
  const rowPartsView = (
712
825
  model: Model,
713
826
  shown: Shown,
714
827
  row: Choice | Command,
715
- h: HtmlBuilder<Message>,
716
- ): ReadonlyArray<Html> => {
828
+ h: HtmlBuilder<Message>
829
+ ): readonly Html[] => {
717
830
  const hint = row.isDisabled === true ? (row.reason ?? row.hint) : row.hint;
831
+
718
832
  const opens = h.span(
719
833
  [h.Class("glyph opens"), h.AriaHidden(true)],
720
- [Glyph.view({ name: "caret-right" }, h)],
834
+ [Glyph.view({ name: "caret-right" }, h)]
721
835
  );
836
+
722
837
  return [
723
838
  ...(row.glyph === undefined
724
839
  ? []
@@ -727,13 +842,17 @@ const rowPartsView = (
727
842
  [h.Class("palette-label")],
728
843
  [
729
844
  row.label,
730
- ...(isContextRow(shown, row) ? [h.span([h.Class("sr-only")], [" (context)"])] : []),
731
- ],
845
+ ...(isContextRow(shown, row)
846
+ ? [h.span([h.Class("sr-only")], [" (context)"])]
847
+ : []),
848
+ ]
732
849
  ),
733
850
  ...(Option.contains(model.maybePicking, row.id)
734
851
  ? [h.span([h.Class("cursor"), h.AriaHidden(true)])]
735
852
  : []),
736
- ...(isCurrentRow(shown, row) ? [h.span([h.Class("tag")], ["current"])] : []),
853
+ ...(isCurrentRow(shown, row)
854
+ ? [h.span([h.Class("tag")], ["current"])]
855
+ : []),
737
856
  ...(hint === undefined ? [] : [h.span([h.Class("hint")], [hint])]),
738
857
  ...(shownRowFor(shown, row).hasPage ? [opens] : []),
739
858
  ];
@@ -744,9 +863,10 @@ const rowView = (
744
863
  shown: Shown,
745
864
  row: Choice | Command,
746
865
  index: number,
747
- h: HtmlBuilder<Message>,
866
+ h: HtmlBuilder<Message>
748
867
  ): Html => {
749
868
  const shownRow = shownRowFor(shown, row);
869
+
750
870
  return h.keyed("div")(
751
871
  row.id,
752
872
  [
@@ -763,8 +883,8 @@ const rowView = (
763
883
  ...(row.isAuthored === true ? ["authored"] : []),
764
884
  ...(isContextRow(shown, row) ? ["context"] : []),
765
885
  ],
766
- " ",
767
- ),
886
+ " "
887
+ )
768
888
  ),
769
889
  ...Option.match(levelOf(row), {
770
890
  onNone: () => [],
@@ -772,32 +892,59 @@ const rowView = (
772
892
  }),
773
893
  ...(shownRow.isHeld || isPicking(model)
774
894
  ? []
775
- : [h.OnClick(Message.ClickedRow({ row: shownRow, maybeShownPage: shownPageIdOf(shown) }))]),
895
+ : [
896
+ h.OnClick(
897
+ Message.ClickedRow({
898
+ row: shownRow,
899
+ maybeShownPage: shownPageIdOf(shown),
900
+ })
901
+ ),
902
+ ]),
776
903
  ],
777
- rowPartsView(model, shown, row, h),
904
+ rowPartsView(model, shown, row, h)
778
905
  );
779
906
  };
780
907
 
781
- const groupedRows = (model: Model, shown: Shown, h: HtmlBuilder<Message>): ReadonlyArray<Html> => {
908
+ const groupedRows = (
909
+ model: Model,
910
+ shown: Shown,
911
+ h: HtmlBuilder<Message>
912
+ ): readonly Html[] => {
782
913
  const indexed = Array.map(shown.rows, (row, index) => ({ row, index }));
914
+
783
915
  return Option.match(shown.maybePage, {
784
- onSome: () => Array.map(indexed, ({ row, index }) => rowView(model, shown, row, index, h)),
916
+ onSome: () =>
917
+ Array.map(indexed, ({ row, index }) =>
918
+ rowView(model, shown, row, index, h)
919
+ ),
785
920
  onNone: () => {
786
921
  const groups = Array.dedupe(
787
- Array.map(shown.rows, (row) => (isCommand(row) ? row.group : "")),
922
+ Array.map(shown.rows, (row) => (isCommand(row) ? row.group : ""))
788
923
  );
924
+
789
925
  return Array.map(groups, (group, groupIndex) => {
790
926
  const headingId = `${id(model)}-group-${groupIndex}`;
927
+
791
928
  return h.keyed("div")(
792
929
  `group-${group}`,
793
930
  [h.Role("group"), h.AriaLabelledBy(headingId)],
794
931
  [
795
- h.div([h.Id(headingId), h.Role("presentation"), h.Class("palette-group")], [group]),
932
+ h.div(
933
+ [
934
+ h.Id(headingId),
935
+ h.Role("presentation"),
936
+ h.Class("palette-group"),
937
+ ],
938
+ [group]
939
+ ),
796
940
  ...Array.map(
797
- Array.filter(indexed, ({ row }) => isCommand(row) && row.group === group),
798
- ({ row, index }) => rowView(model, shown, row, index, h),
941
+ Array.filter(
942
+ indexed,
943
+ ({ row }) => isCommand(row) && row.group === group
944
+ ),
945
+ ({ row, index }) => rowView(model, shown, row, index, h)
799
946
  ),
800
- ],
947
+ ]
801
948
  );
802
949
  });
803
950
  },
@@ -808,26 +955,30 @@ const comboboxAttributes = (
808
955
  model: Model,
809
956
  shown: Shown,
810
957
  noun: string,
811
- h: HtmlBuilder<Message>,
958
+ h: HtmlBuilder<Message>
812
959
  ): ReadonlyArray<Attribute<Message>> => {
813
960
  const paletteId = id(model);
961
+
814
962
  const maybeCursorIndex = Option.flatMap(shown.maybeCursorId, (cursorId) =>
815
- Array.findFirstIndex(shown.rows, (row) => row.id === cursorId),
963
+ Array.findFirstIndex(shown.rows, (row) => row.id === cursorId)
816
964
  );
965
+
817
966
  return [
818
- h.OnKeyDownPreventDefault(fieldKeyDown(model, shown)),
967
+ h.OnKeyDownPreventDefault(rowKeysWithRenderedList(model, shown)),
819
968
  h.Role("combobox"),
820
969
  h.AriaExpanded(true),
821
970
  h.AriaControls(listIdOf(paletteId)),
822
971
  h.AriaAutocomplete("list"),
823
972
  ...Option.toArray(
824
- Option.map(maybeCursorIndex, (index) => h.AriaActiveDescendant(optionId(paletteId, index))),
973
+ Option.map(maybeCursorIndex, (index) =>
974
+ h.AriaActiveDescendant(optionId(paletteId, index))
975
+ )
825
976
  ),
826
977
  h.AriaLabel(
827
978
  Option.match(shown.maybePage, {
828
979
  onNone: () => `Command or ${noun}`,
829
980
  onSome: ({ page }) => page.title,
830
- }),
981
+ })
831
982
  ),
832
983
  h.Autocomplete("off"),
833
984
  h.DataAttribute(FIELD_ATTRIBUTE, ""),
@@ -839,9 +990,10 @@ const fieldView = (
839
990
  shown: Shown,
840
991
  noun: string,
841
992
  render: Dialog.RenderInfo,
842
- h: HtmlBuilder<Message>,
993
+ h: HtmlBuilder<Message>
843
994
  ): Html => {
844
995
  const maybeShownPage = shownPageIdOf(shown);
996
+
845
997
  return UiInput.view(
846
998
  {
847
999
  id: fieldId(id(model)),
@@ -859,7 +1011,7 @@ const fieldView = (
859
1011
  ...comboboxAttributes(model, shown, noun, h),
860
1012
  ]),
861
1013
  },
862
- h,
1014
+ h
863
1015
  );
864
1016
  };
865
1017
 
@@ -868,7 +1020,7 @@ const headView = (
868
1020
  shown: Shown,
869
1021
  scope: string,
870
1022
  field: Html,
871
- h: HtmlBuilder<Message>,
1023
+ h: HtmlBuilder<Message>
872
1024
  ): Html =>
873
1025
  h.div(
874
1026
  [h.Class("palette-q field")],
@@ -883,16 +1035,18 @@ const headView = (
883
1035
  isDisabled: isPicking(model),
884
1036
  onClick: Message.ClickedBack(),
885
1037
  },
886
- h,
887
- ),
888
- ),
1038
+ h
1039
+ )
1040
+ )
889
1041
  ),
890
1042
  h.span([h.Class("palette-scope")], [scope]),
891
1043
  ...Option.toArray(
892
- Option.map(shown.maybePage, ({ page }) => h.span([h.Class("palette-title")], [page.title])),
1044
+ Option.map(shown.maybePage, ({ page }) =>
1045
+ h.span([h.Class("palette-title")], [page.title])
1046
+ )
893
1047
  ),
894
1048
  field,
895
- ],
1049
+ ]
896
1050
  );
897
1051
 
898
1052
  const listView = (model: Model, shown: Shown, h: HtmlBuilder<Message>): Html =>
@@ -904,27 +1058,34 @@ const listView = (model: Model, shown: Shown, h: HtmlBuilder<Message>): Html =>
904
1058
  Option.match(shown.maybePage, {
905
1059
  onNone: () => "Results",
906
1060
  onSome: ({ page }) => page.title,
907
- }),
1061
+ })
908
1062
  ),
909
1063
  ...(isPicking(model) ? [h.AriaBusy(true)] : []),
910
1064
  h.Class("palette-list"),
911
1065
  ],
912
1066
  Array.match(shown.rows, {
913
- onEmpty: () => [h.div([h.Role("presentation"), h.Class("palette-group")], [NOTHING_FOUND])],
1067
+ onEmpty: () => [
1068
+ h.div(
1069
+ [h.Role("presentation"), h.Class("palette-group")],
1070
+ [NOTHING_FOUND]
1071
+ ),
1072
+ ],
914
1073
  onNonEmpty: () => groupedRows(model, shown, h),
915
- }),
1074
+ })
916
1075
  );
917
1076
 
918
- // The count is said once a query is typed: the status is mounted empty as the card opens (a
919
- // status mounted holding its words goes unheard), and the rows an empty field lists need no
920
- // count.
921
- const countView = (model: Model, shown: Shown, h: HtmlBuilder<Message>): Html => {
1077
+ const countView = (
1078
+ model: Model,
1079
+ shown: Shown,
1080
+ h: HtmlBuilder<Message>
1081
+ ): Html => {
922
1082
  const shownQuery = shownQueryOf(model, shown);
1083
+
923
1084
  return h.div(
924
1085
  [h.Role("status"), h.Class("sr-only")],
925
1086
  String.isEmpty(shownQuery)
926
1087
  ? []
927
- : [countWords(shown.rows.length - HashSet.size(shown.contextIds))],
1088
+ : [countWords(shown.rows.length - HashSet.size(shown.contextIds))]
928
1089
  );
929
1090
  };
930
1091
 
@@ -932,29 +1093,48 @@ const cardView = (
932
1093
  model: Model,
933
1094
  viewInputs: ViewInputs,
934
1095
  render: Dialog.RenderInfo,
935
- h: HtmlBuilder<Message>,
1096
+ h: HtmlBuilder<Message>
936
1097
  ): Html => {
937
- const { commands, scope = "commands", noun = "title", toDetailView = () => [] } = viewInputs;
1098
+ const {
1099
+ commands,
1100
+ scope = "commands",
1101
+ noun = "title",
1102
+ toDetailView = () => [],
1103
+ } = viewInputs;
1104
+
938
1105
  const shown = shownOf(model, commands);
939
1106
 
940
1107
  return h.div(
941
1108
  [
942
1109
  ...Option.toArray(
943
- Option.map(shownPageIdOf(shown), (commandId) => h.DataAttribute(PAGE_ATTRIBUTE, commandId)),
1110
+ Option.map(shownPageIdOf(shown), (commandId) =>
1111
+ h.DataAttribute(PAGE_ATTRIBUTE, commandId)
1112
+ )
944
1113
  ),
945
1114
  h.OnMount(BindPaletteKeys()),
946
1115
  h.Class("card palette"),
947
1116
  ],
948
1117
  [
949
- headView(model, shown, scope, fieldView(model, shown, noun, render, h), h),
1118
+ headView(
1119
+ model,
1120
+ shown,
1121
+ scope,
1122
+ fieldView(model, shown, noun, render, h),
1123
+ h
1124
+ ),
950
1125
  ...slotView("div", "palette-detail", toDetailView(), h),
951
1126
  listView(model, shown, h),
952
1127
  countView(model, shown, h),
953
1128
  h.div(
954
1129
  [h.Class("palette-more")],
955
- [Option.match(shown.maybePage, { onNone: () => COMMANDS_FOOT, onSome: () => PAGE_FOOT })],
1130
+ [
1131
+ Option.match(shown.maybePage, {
1132
+ onNone: () => COMMANDS_FOOT,
1133
+ onSome: () => PAGE_FOOT,
1134
+ }),
1135
+ ]
956
1136
  ),
957
- ],
1137
+ ]
958
1138
  );
959
1139
  };
960
1140
 
@@ -972,23 +1152,18 @@ const cardView = (
972
1152
  * `@foldkit/ui`'s Input as an ARIA combobox (`aria-activedescendant` on the cursor's row) over
973
1153
  * an always open `role="listbox"` of `role="option"` rows, grouped under their headings.
974
1154
  */
975
- // NOTE: @foldkit/ui gap: Combobox's popup does not fit an always open list in a card, so the
976
- // palette is not built on it. Its list is a popup anchored under the field (portaled
977
- // unless told not to) behind a press-catcher, hidden until positioned; its cursor is an index
978
- // that wraps and passes disabled rows; pointer movement moves it; leaving the field closes
979
- // it; and its Escape is handled (default prevented), so the Dialog never sees the Escape that
980
- // must close the whole palette.
981
- export const view = defineView<Model, Message, ViewInputs>((model, viewInputs, h): Html =>
982
- h.submodel({
983
- slotId: id(model),
984
- model: model.dialog,
985
- view: Dialog.view,
986
- viewInputs: {
987
- label: "Commands",
988
- placement: "Top",
989
- toLiveRegionView: viewInputs.toLiveRegionView,
990
- toView: (render) => cardView(model, viewInputs, render, h),
991
- },
992
- toParentMessage: (message) => Message.GotDialogMessage({ message }),
993
- }),
1155
+ export const view = defineView<Model, Message, ViewInputs>(
1156
+ (model, viewInputs, h): Html =>
1157
+ h.submodel({
1158
+ slotId: id(model),
1159
+ model: model.dialog,
1160
+ view: Dialog.view,
1161
+ viewInputs: {
1162
+ label: "Commands",
1163
+ placement: "Top",
1164
+ toLiveRegionView: viewInputs.toLiveRegionView,
1165
+ toView: (render) => cardView(model, viewInputs, render, h),
1166
+ },
1167
+ toParentMessage: (message) => Message.GotDialogMessage({ message }),
1168
+ })
994
1169
  );