@esportsplus/ui 0.56.4 → 0.57.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 (1613) hide show
  1. package/NOTICE +232 -0
  2. package/README.md +129 -138
  3. package/build/components/accordion/index.d.ts +23 -9
  4. package/build/components/accordion/index.js +95 -11
  5. package/build/components/accordion/scss/index.scss +1 -1
  6. package/build/components/announcement/index.d.ts +2167 -0
  7. package/build/components/announcement/index.js +35 -0
  8. package/build/components/announcement/scss/index.scss +2 -0
  9. package/build/components/banner/scss/index.scss +1 -1
  10. package/build/components/breadcrumb/index.d.ts +25 -25
  11. package/build/components/breadcrumb/index.js +189 -17
  12. package/build/components/breadcrumb/scss/index.scss +1 -1
  13. package/build/components/button/copy.js +6 -6
  14. package/build/components/button/faces.js +4 -4
  15. package/build/components/button/fan.js +85 -84
  16. package/build/components/button/hold.js +8 -10
  17. package/build/components/button/icons.js +33 -10
  18. package/build/components/button/index.d.ts +6 -0
  19. package/build/components/button/index.js +4 -1
  20. package/build/components/button/kbd.js +25 -25
  21. package/build/components/button/loading.js +7 -7
  22. package/build/components/button/morph.d.ts +22 -0
  23. package/build/components/button/morph.js +115 -0
  24. package/build/components/button/scss/index.scss +1 -1
  25. package/build/components/button/sidebar.d.ts +18 -0
  26. package/build/components/button/sidebar.js +19 -0
  27. package/build/components/button/split.d.ts +23 -0
  28. package/build/components/button/split.js +41 -0
  29. package/build/components/capslock/index.d.ts +19 -0
  30. package/build/components/capslock/index.js +39 -0
  31. package/build/components/capslock/scss/index.scss +2 -0
  32. package/build/components/card/expand.d.ts +22 -0
  33. package/build/components/card/expand.js +118 -0
  34. package/build/components/card/index.d.ts +6 -0
  35. package/build/components/card/index.js +4 -0
  36. package/build/components/card/scss/index.scss +1 -1
  37. package/build/components/cc/index.d.ts +30 -0
  38. package/build/components/cc/index.js +569 -0
  39. package/build/components/cc/scss/index.scss +2 -0
  40. package/build/components/chat-minimap/index.d.ts +28 -0
  41. package/build/components/chat-minimap/index.js +223 -0
  42. package/build/components/chat-minimap/range.d.ts +9 -0
  43. package/build/components/chat-minimap/range.js +30 -0
  44. package/build/components/chat-minimap/scss/index.scss +2 -0
  45. package/build/components/chat-minimap/spy.d.ts +14 -0
  46. package/build/components/chat-minimap/spy.js +107 -0
  47. package/build/components/checkbox/group.d.ts +33 -0
  48. package/build/components/checkbox/group.js +156 -0
  49. package/build/components/checkbox/index.d.ts +3 -1456
  50. package/build/components/checkbox/index.js +3 -69
  51. package/build/components/checkbox/options.d.ts +6513 -0
  52. package/build/components/checkbox/options.js +79 -0
  53. package/build/components/checkbox/scss/index.scss +1 -1
  54. package/build/components/clipboard/copy.js +5 -5
  55. package/build/components/clipboard/index.d.ts +15 -3
  56. package/build/components/color-picker/index.d.ts +5 -7
  57. package/build/components/color-picker/index.js +175 -222
  58. package/build/components/color-picker/scss/index.scss +1 -1
  59. package/build/components/command/index.d.ts +83 -17
  60. package/build/components/command/index.js +556 -143
  61. package/build/components/command/scss/index.scss +1 -1
  62. package/build/components/container/scss/index.scss +1 -1
  63. package/build/components/copy/index.d.ts +23 -0
  64. package/build/components/copy/index.js +61 -0
  65. package/build/components/copy/scss/index.scss +2 -0
  66. package/build/components/counter/index.d.ts +3 -2
  67. package/build/components/counter/index.js +41 -73
  68. package/build/components/counter/scss/index.scss +1 -1
  69. package/build/components/datalist/index.d.ts +5 -0
  70. package/build/components/datalist/index.js +76 -49
  71. package/build/components/datalist/scss/index.scss +1 -1
  72. package/build/components/dock/index.d.ts +5 -4
  73. package/build/components/dock/index.js +62 -171
  74. package/build/components/dock/scss/index.scss +1 -1
  75. package/build/components/editor/code/changes.d.ts +15 -0
  76. package/build/components/editor/code/changes.js +60 -0
  77. package/build/components/editor/code/clipboard.d.ts +6 -0
  78. package/build/components/editor/code/clipboard.js +50 -0
  79. package/build/components/editor/code/colors.d.ts +11 -0
  80. package/build/components/editor/code/colors.js +172 -0
  81. package/build/components/editor/code/commands.d.ts +22 -0
  82. package/build/components/editor/code/commands.js +556 -0
  83. package/build/components/editor/code/composition.d.ts +23 -0
  84. package/build/components/editor/code/composition.js +67 -0
  85. package/build/components/editor/code/conflicts.d.ts +21 -0
  86. package/build/components/editor/code/conflicts.js +91 -0
  87. package/build/components/editor/code/document.d.ts +127 -0
  88. package/build/components/editor/code/document.js +477 -0
  89. package/build/components/editor/code/editor.d.ts +21 -0
  90. package/build/components/editor/code/editor.js +30 -0
  91. package/build/components/editor/code/features.d.ts +77 -0
  92. package/build/components/editor/code/features.js +833 -0
  93. package/build/components/editor/code/field.d.ts +14 -0
  94. package/build/components/editor/code/field.js +57 -0
  95. package/build/components/editor/code/find.d.ts +83 -0
  96. package/build/components/editor/code/find.js +312 -0
  97. package/build/components/editor/code/folding.d.ts +34 -0
  98. package/build/components/editor/code/folding.js +433 -0
  99. package/build/components/editor/code/goto.d.ts +22 -0
  100. package/build/components/editor/code/goto.js +91 -0
  101. package/build/components/editor/code/gutter.d.ts +5 -0
  102. package/build/components/editor/code/gutter.js +22 -0
  103. package/build/components/editor/code/index.d.ts +17 -0
  104. package/build/components/editor/code/index.js +7 -0
  105. package/build/components/editor/code/keymap.d.ts +30 -0
  106. package/build/components/editor/code/keymap.js +356 -0
  107. package/build/components/editor/code/layout.d.ts +67 -0
  108. package/build/components/editor/code/layout.js +350 -0
  109. package/build/components/editor/code/links.d.ts +8 -0
  110. package/build/components/editor/code/links.js +32 -0
  111. package/build/components/editor/code/minimap.d.ts +46 -0
  112. package/build/components/editor/code/minimap.js +172 -0
  113. package/build/components/editor/code/navigation.d.ts +17 -0
  114. package/build/components/editor/code/navigation.js +49 -0
  115. package/build/components/editor/code/pointer.d.ts +40 -0
  116. package/build/components/editor/code/pointer.js +134 -0
  117. package/build/components/editor/code/projection.d.ts +43 -0
  118. package/build/components/editor/code/projection.js +200 -0
  119. package/build/components/editor/code/rows.d.ts +50 -0
  120. package/build/components/editor/code/rows.js +296 -0
  121. package/build/components/editor/code/search.d.ts +24 -0
  122. package/build/components/editor/code/search.js +231 -0
  123. package/build/components/editor/code/selection.d.ts +2 -0
  124. package/build/components/editor/code/selection.js +53 -0
  125. package/build/components/editor/code/services/completion.d.ts +27 -0
  126. package/build/components/editor/code/services/completion.js +90 -0
  127. package/build/components/editor/code/services/diagnostics.d.ts +28 -0
  128. package/build/components/editor/code/services/diagnostics.js +98 -0
  129. package/build/components/editor/code/services/hover.d.ts +14 -0
  130. package/build/components/editor/code/services/hover.js +66 -0
  131. package/build/components/editor/code/services/index.d.ts +27 -0
  132. package/build/components/editor/code/services/index.js +64 -0
  133. package/build/components/editor/code/services/model.d.ts +35 -0
  134. package/build/components/editor/code/services/model.js +167 -0
  135. package/build/components/editor/code/services/protocol.d.ts +68 -0
  136. package/build/components/editor/code/services/protocol.js +1 -0
  137. package/build/components/editor/code/services/session.d.ts +54 -0
  138. package/build/components/editor/code/services/session.js +496 -0
  139. package/build/components/editor/code/services/transport.d.ts +12 -0
  140. package/build/components/editor/code/services/transport.js +18 -0
  141. package/build/components/editor/code/syntax.d.ts +83 -0
  142. package/build/components/editor/code/syntax.js +1106 -0
  143. package/build/components/editor/code/unicode.d.ts +10 -0
  144. package/build/components/editor/code/unicode.js +117 -0
  145. package/build/components/editor/code/view.d.ts +122 -0
  146. package/build/components/editor/code/view.js +1560 -0
  147. package/build/components/editor/diffs/diff3.d.ts +25 -0
  148. package/build/components/editor/diffs/diff3.js +152 -0
  149. package/build/components/editor/diffs/engine.d.ts +18 -0
  150. package/build/components/editor/diffs/engine.js +110 -0
  151. package/build/components/editor/diffs/hunks.d.ts +41 -0
  152. package/build/components/editor/diffs/hunks.js +96 -0
  153. package/build/components/editor/diffs/index.d.ts +18 -0
  154. package/build/components/editor/diffs/index.js +10 -0
  155. package/build/components/editor/diffs/merge.d.ts +23 -0
  156. package/build/components/editor/diffs/merge.js +324 -0
  157. package/build/components/editor/diffs/render.d.ts +6 -0
  158. package/build/components/editor/diffs/render.js +56 -0
  159. package/build/components/editor/diffs/view.d.ts +44 -0
  160. package/build/components/editor/diffs/view.js +363 -0
  161. package/build/components/editor/diffs/words.d.ts +8 -0
  162. package/build/components/editor/diffs/words.js +47 -0
  163. package/build/components/editor/index.d.ts +21 -0
  164. package/build/components/editor/index.js +11 -0
  165. package/build/components/editor/markdown/editing.d.ts +7 -0
  166. package/build/components/editor/markdown/editing.js +55 -0
  167. package/build/components/editor/markdown/html.d.ts +24 -0
  168. package/build/components/editor/markdown/html.js +108 -0
  169. package/build/components/editor/markdown/index.d.ts +25 -0
  170. package/build/components/editor/markdown/index.js +33 -0
  171. package/build/components/editor/markdown/inline.d.ts +16 -0
  172. package/build/components/editor/markdown/inline.js +259 -0
  173. package/build/components/editor/markdown/layout.d.ts +63 -0
  174. package/build/components/editor/markdown/layout.js +252 -0
  175. package/build/components/editor/markdown/model.d.ts +53 -0
  176. package/build/components/editor/markdown/model.js +463 -0
  177. package/build/components/editor/markdown/render.d.ts +29 -0
  178. package/build/components/editor/markdown/render.js +561 -0
  179. package/build/components/editor/markdown/structure.d.ts +7 -0
  180. package/build/components/editor/markdown/structure.js +87 -0
  181. package/build/components/editor/markdown/view.d.ts +18 -0
  182. package/build/components/editor/markdown/view.js +1841 -0
  183. package/build/components/editor/tree/clipboard.d.ts +12 -0
  184. package/build/components/editor/tree/clipboard.js +48 -0
  185. package/build/components/editor/tree/compact.d.ts +23 -0
  186. package/build/components/editor/tree/compact.js +57 -0
  187. package/build/components/editor/tree/decorations.d.ts +39 -0
  188. package/build/components/editor/tree/decorations.js +126 -0
  189. package/build/components/editor/tree/drag.d.ts +45 -0
  190. package/build/components/editor/tree/drag.js +462 -0
  191. package/build/components/editor/tree/edit.d.ts +43 -0
  192. package/build/components/editor/tree/edit.js +134 -0
  193. package/build/components/editor/tree/filter.d.ts +7 -0
  194. package/build/components/editor/tree/filter.js +47 -0
  195. package/build/components/editor/tree/find.d.ts +55 -0
  196. package/build/components/editor/tree/find.js +291 -0
  197. package/build/components/editor/tree/glob.d.ts +2 -0
  198. package/build/components/editor/tree/glob.js +57 -0
  199. package/build/components/editor/tree/glyph.d.ts +6 -0
  200. package/build/components/editor/tree/glyph.js +31 -0
  201. package/build/components/editor/tree/history.d.ts +61 -0
  202. package/build/components/editor/tree/history.js +172 -0
  203. package/build/components/editor/tree/icons.d.ts +29 -0
  204. package/build/components/editor/tree/icons.js +417 -0
  205. package/build/components/editor/tree/index.d.ts +118 -0
  206. package/build/components/editor/tree/index.js +2227 -0
  207. package/build/components/editor/tree/jump.d.ts +8 -0
  208. package/build/components/editor/tree/jump.js +45 -0
  209. package/build/components/editor/tree/lazy.d.ts +24 -0
  210. package/build/components/editor/tree/lazy.js +71 -0
  211. package/build/components/editor/tree/model.d.ts +33 -0
  212. package/build/components/editor/tree/model.js +128 -0
  213. package/build/components/editor/tree/selection.d.ts +13 -0
  214. package/build/components/editor/tree/selection.js +55 -0
  215. package/build/components/editor/tree/shortcuts.d.ts +6 -0
  216. package/build/components/editor/tree/shortcuts.js +44 -0
  217. package/build/components/editor/tree/sort.d.ts +13 -0
  218. package/build/components/editor/tree/sort.js +53 -0
  219. package/build/components/editor/tree/spoken.d.ts +9 -0
  220. package/build/components/editor/tree/spoken.js +38 -0
  221. package/build/components/editor/tree/sprites.d.ts +4 -0
  222. package/build/components/editor/tree/sprites.js +152 -0
  223. package/build/components/editor/tree/sticky.d.ts +11 -0
  224. package/build/components/editor/tree/sticky.js +102 -0
  225. package/build/components/editor/tree/transfer.d.ts +15 -0
  226. package/build/components/editor/tree/transfer.js +75 -0
  227. package/build/components/editor/workspace/index.d.ts +64 -0
  228. package/build/components/editor/workspace/index.js +1125 -0
  229. package/build/components/editor/workspace/model.d.ts +161 -0
  230. package/build/components/editor/workspace/model.js +690 -0
  231. package/build/components/error/index.d.ts +31 -0
  232. package/build/components/error/index.js +150 -0
  233. package/build/components/error/scss/index.scss +2 -0
  234. package/build/components/filter/index.d.ts +38 -0
  235. package/build/components/filter/index.js +307 -0
  236. package/build/components/filter/scss/index.scss +2 -0
  237. package/build/components/form/action.js +1 -2
  238. package/build/components/form/index.d.ts +10 -1
  239. package/build/components/form/input.d.ts +12 -2
  240. package/build/components/form/input.js +12 -7
  241. package/build/components/form/scss/index.scss +1 -1
  242. package/build/components/frame/scss/index.scss +2 -0
  243. package/build/components/grid/scss/index.scss +1 -1
  244. package/build/components/heatmap/index.d.ts +32 -0
  245. package/build/components/heatmap/index.js +209 -0
  246. package/build/components/heatmap/scss/index.scss +2 -0
  247. package/build/components/highlight/easing.d.ts +2 -0
  248. package/build/components/highlight/easing.js +19 -0
  249. package/build/components/highlight/index.d.ts +6 -0
  250. package/build/components/highlight/index.js +334 -112
  251. package/build/components/highlight/scss/index.scss +1 -1
  252. package/build/components/icon/index.js +1 -1
  253. package/build/components/icon/scss/index.scss +1 -1
  254. package/build/components/image/index.d.ts +17 -12
  255. package/build/components/image/index.js +3 -61
  256. package/build/components/image/lazyload.d.ts +15 -0
  257. package/build/components/image/lazyload.js +72 -0
  258. package/build/components/image/scss/index.scss +1 -1
  259. package/build/components/index.d.ts +15 -79
  260. package/build/components/index.js +15 -79
  261. package/build/components/inline-edit/format.d.ts +29 -0
  262. package/build/components/inline-edit/format.js +112 -0
  263. package/build/components/inline-edit/history.d.ts +14 -0
  264. package/build/components/inline-edit/history.js +40 -0
  265. package/build/components/inline-edit/index.d.ts +13 -7
  266. package/build/components/inline-edit/index.js +44 -38
  267. package/build/components/inline-edit/markdown.d.ts +7 -0
  268. package/build/components/inline-edit/markdown.js +314 -0
  269. package/build/components/inline-edit/model.d.ts +61 -0
  270. package/build/components/inline-edit/model.js +192 -0
  271. package/build/components/inline-edit/rich.d.ts +39 -0
  272. package/build/components/inline-edit/rich.js +1236 -0
  273. package/build/components/inline-edit/scss/index.scss +1 -1
  274. package/build/components/inline-edit/selection.d.ts +7 -0
  275. package/build/components/inline-edit/selection.js +114 -0
  276. package/build/components/inline-edit/status.d.ts +24 -0
  277. package/build/components/inline-edit/status.js +196 -0
  278. package/build/components/inline-edit/utilities.d.ts +4 -0
  279. package/build/components/inline-edit/utilities.js +12 -0
  280. package/build/components/input/field.d.ts +14 -0
  281. package/build/components/input/field.js +34 -0
  282. package/build/components/input/index.d.ts +7 -14
  283. package/build/components/input/index.js +5 -41
  284. package/build/components/input/scrub.d.ts +30 -0
  285. package/build/components/input/scrub.js +221 -0
  286. package/build/components/input/scss/index.scss +1 -1
  287. package/build/components/input/tag.d.ts +24 -0
  288. package/build/components/input/tag.js +288 -0
  289. package/build/components/json/download.js +4 -3
  290. package/build/components/link/scss/index.scss +1 -1
  291. package/build/components/loading/index.d.ts +1 -1
  292. package/build/components/loading/scss/index.scss +1 -1
  293. package/build/components/marquee/index.d.ts +10 -1
  294. package/build/components/marquee/index.js +240 -174
  295. package/build/components/marquee/scss/index.scss +1 -1
  296. package/build/components/marquee/velocity.d.ts +17 -0
  297. package/build/components/marquee/velocity.js +78 -0
  298. package/build/components/metric/flash.d.ts +11 -0
  299. package/build/components/metric/flash.js +116 -0
  300. package/build/components/metric/index.d.ts +33 -0
  301. package/build/components/metric/index.js +271 -0
  302. package/build/components/metric/scss/index.scss +2 -0
  303. package/build/components/nav/index.d.ts +13 -0
  304. package/build/components/nav/index.js +6 -0
  305. package/build/components/nav/scss/index.scss +2 -0
  306. package/build/components/nav/spy.d.ts +9 -0
  307. package/build/components/nav/spy.js +157 -0
  308. package/build/components/nav/toc.d.ts +26 -0
  309. package/build/components/nav/toc.js +22 -0
  310. package/build/components/nav/tree.d.ts +39 -0
  311. package/build/components/nav/tree.js +123 -0
  312. package/build/components/notification/index.d.ts +15 -0
  313. package/build/components/notification/index.js +98 -0
  314. package/build/components/notification/scss/index.scss +2 -0
  315. package/build/components/overlay/index.d.ts +28 -9
  316. package/build/components/overlay/index.js +346 -8
  317. package/build/components/overlay/popup.d.ts +31 -0
  318. package/build/components/overlay/popup.js +150 -0
  319. package/build/components/overlay/scss/index.scss +1 -1
  320. package/build/components/page/scss/index.scss +1 -1
  321. package/build/components/pagination/dots.d.ts +21 -0
  322. package/build/components/pagination/dots.js +110 -0
  323. package/build/components/pagination/index.d.ts +8 -3
  324. package/build/components/pagination/index.js +36 -59
  325. package/build/components/pagination/scss/index.scss +1 -1
  326. package/build/components/progress/index.d.ts +7 -2
  327. package/build/components/progress/index.js +14 -10
  328. package/build/components/progress/scss/index.scss +1 -1
  329. package/build/components/progress/text.d.ts +12 -0
  330. package/build/components/progress/text.js +124 -0
  331. package/build/components/pull-to-refresh/index.d.ts +3 -11
  332. package/build/components/pull-to-refresh/index.js +127 -165
  333. package/build/components/pull-to-refresh/scss/index.scss +1 -1
  334. package/build/components/radio/index.d.ts +2 -2
  335. package/build/components/radio/index.js +2 -2
  336. package/build/components/range/filter.d.ts +22 -0
  337. package/build/components/range/filter.js +322 -0
  338. package/build/components/range/index.d.ts +9 -2
  339. package/build/components/range/index.js +13 -9
  340. package/build/components/range/scss/index.scss +1 -1
  341. package/build/components/relative-time/index.d.ts +15 -8
  342. package/build/components/relative-time/index.js +206 -193
  343. package/build/components/relative-time/scss/index.scss +1 -1
  344. package/build/components/root/scss/index.scss +1 -1
  345. package/build/components/select/index.d.ts +35 -16
  346. package/build/components/select/index.js +358 -92
  347. package/build/components/select/placement.d.ts +15 -0
  348. package/build/components/select/placement.js +31 -0
  349. package/build/components/select/scss/index.scss +1 -1
  350. package/build/components/shortcut-recorder/index.d.ts +7 -2
  351. package/build/components/shortcut-recorder/index.js +107 -99
  352. package/build/components/shortcut-recorder/scss/index.scss +1 -1
  353. package/build/components/sortable/index.d.ts +722 -4
  354. package/build/components/sortable/index.js +329 -213
  355. package/build/components/sortable/scss/index.scss +1 -1
  356. package/build/components/sticky-header/index.d.ts +22 -15
  357. package/build/components/sticky-header/index.js +41 -81
  358. package/build/components/sticky-header/scss/index.scss +1 -1
  359. package/build/components/story/index.d.ts +21 -0
  360. package/build/components/story/index.js +253 -0
  361. package/build/components/story/scss/index.scss +2 -0
  362. package/build/components/surface-field/engine.d.ts +65 -0
  363. package/build/components/surface-field/engine.js +970 -0
  364. package/build/components/surface-field/index.d.ts +2247 -1470
  365. package/build/components/surface-field/index.js +394 -371
  366. package/build/components/surface-field/scss/index.scss +1 -1
  367. package/build/components/surface-field/surface.d.ts +39 -0
  368. package/build/components/surface-field/surface.js +159 -0
  369. package/build/components/surface-field/worker/index.d.ts +9 -0
  370. package/build/components/surface-field/worker/index.js +19 -0
  371. package/build/components/switch/index.d.ts +2 -2
  372. package/build/components/switch/index.js +2 -2
  373. package/build/components/tasklist/index.d.ts +25 -717
  374. package/build/components/tasklist/index.js +151 -97
  375. package/build/components/tasklist/scss/index.scss +1 -1
  376. package/build/components/text/scss/index.scss +1 -1
  377. package/build/components/textarea/index.d.ts +15 -3
  378. package/build/components/textarea/index.js +124 -32
  379. package/build/components/textarea/scss/index.scss +1 -1
  380. package/build/components/toast/index.d.ts +40 -7
  381. package/build/components/toast/index.js +192 -145
  382. package/build/components/toast/scss/index.scss +1 -1
  383. package/build/components/tooltip/index.d.ts +3 -4
  384. package/build/components/tooltip/index.js +3 -4
  385. package/build/components/tooltip/menu.d.ts +47 -21
  386. package/build/components/tooltip/menu.js +525 -18
  387. package/build/components/tooltip/onclick.d.ts +1 -0
  388. package/build/components/tooltip/onclick.js +50 -33
  389. package/build/components/tooltip/onhover.d.ts +721 -10
  390. package/build/components/tooltip/onhover.js +129 -43
  391. package/build/components/tooltip/scss/index.scss +1 -1
  392. package/build/components/tooltip/shared.d.ts +34 -0
  393. package/build/components/tooltip/shared.js +569 -0
  394. package/build/components/tooltip/utilities.d.ts +23 -3
  395. package/build/components/tooltip/utilities.js +46 -21
  396. package/build/components/typewriter/index.d.ts +1439 -10
  397. package/build/components/typewriter/index.js +7 -2
  398. package/build/components/typewriter/retype.d.ts +7 -0
  399. package/build/components/typewriter/retype.js +83 -0
  400. package/build/components/typewriter/rotate.d.ts +13 -0
  401. package/build/components/typewriter/rotate.js +186 -0
  402. package/build/components/typewriter/scss/index.scss +1 -1
  403. package/build/components/uptime/index.js +61 -61
  404. package/build/components/uptime/scss/index.scss +1 -1
  405. package/build/components/usage-meter/index.d.ts +15 -3
  406. package/build/components/usage-meter/index.js +19 -19
  407. package/build/components/usage-meter/scss/index.scss +1 -1
  408. package/build/css-utilities/background/scss/index.scss +1 -1
  409. package/build/css-utilities/border/scss/index.scss +1 -1
  410. package/build/css-utilities/color/scss/index.scss +1 -1
  411. package/build/css-utilities/flex/scss/index.scss +1 -1
  412. package/build/css-utilities/font/geist/scss/index.scss +1 -1
  413. package/build/css-utilities/font/montserrat/scss/index.scss +1 -1
  414. package/build/css-utilities/glass/index.d.ts +10 -0
  415. package/build/css-utilities/glass/index.js +26 -0
  416. package/build/css-utilities/glass/scss/index.scss +1 -1
  417. package/build/css-utilities/index.d.ts +3 -0
  418. package/build/css-utilities/index.js +3 -0
  419. package/build/css-utilities/index.scss +1 -1
  420. package/build/css-utilities/inline/scss/index.scss +1 -1
  421. package/build/css-utilities/scrollbar/index.d.ts +42 -0
  422. package/build/css-utilities/scrollbar/index.js +155 -0
  423. package/build/css-utilities/scrollbar/scss/index.scss +1 -1
  424. package/build/css-utilities/skeleton/scss/index.scss +1 -1
  425. package/build/css-utilities/text/scss/index.scss +1 -1
  426. package/build/css-utilities/theme/index.d.ts +16 -0
  427. package/build/css-utilities/theme/index.js +60 -0
  428. package/build/normalize/scss/index.scss +3 -0
  429. package/build/shared/anchor.d.ts +7 -0
  430. package/build/shared/anchor.js +18 -0
  431. package/build/shared/animation.d.ts +6 -0
  432. package/build/shared/animation.js +57 -0
  433. package/build/shared/clamp.d.ts +2 -0
  434. package/build/shared/clamp.js +4 -0
  435. package/build/shared/deadline.d.ts +2 -0
  436. package/build/shared/deadline.js +94 -0
  437. package/build/shared/dismiss.d.ts +2 -0
  438. package/build/shared/dismiss.js +5 -0
  439. package/build/shared/drag.d.ts +47 -0
  440. package/build/shared/drag.js +189 -0
  441. package/build/shared/fuzzy.d.ts +6 -0
  442. package/build/shared/fuzzy.js +153 -0
  443. package/build/shared/keystep.d.ts +2 -0
  444. package/build/shared/keystep.js +21 -0
  445. package/build/shared/platform.d.ts +2 -0
  446. package/build/shared/platform.js +3 -0
  447. package/build/shared/press.d.ts +15 -0
  448. package/build/shared/press.js +83 -0
  449. package/build/shared/resize.d.ts +18 -0
  450. package/build/shared/resize.js +137 -0
  451. package/build/shared/subscribe.d.ts +3 -0
  452. package/build/shared/subscribe.js +12 -0
  453. package/build/shared/ticker.d.ts +3 -0
  454. package/build/shared/ticker.js +34 -0
  455. package/build/shared/transition.d.ts +11 -0
  456. package/build/shared/transition.js +49 -0
  457. package/build/shared/viewport.d.ts +7 -0
  458. package/build/shared/viewport.js +11 -0
  459. package/build/shared/visible.d.ts +8 -0
  460. package/build/shared/visible.js +79 -0
  461. package/build/themes/dark/input.d.ts +3 -721
  462. package/build/themes/dark/input.js +4 -2
  463. package/build/themes/dark/select.js +2 -1
  464. package/build/themes/dark/textarea.d.ts +15 -3
  465. package/build/themes/dark/textarea.js +1 -0
  466. package/package.json +11 -4
  467. package/pnpm-workspace.yaml +3 -18
  468. package/scripts/animation.test.mjs +45 -0
  469. package/scripts/chat-minimap.test.mjs +53 -0
  470. package/scripts/code-editor-features.test.mjs +287 -0
  471. package/scripts/code-editor-markdown.test.mjs +527 -0
  472. package/scripts/code-editor-services.test.mjs +361 -0
  473. package/scripts/code-editor-workspace.test.mjs +398 -0
  474. package/scripts/code-editor.test.mjs +1615 -0
  475. package/scripts/css-variables.test.mjs +1 -1
  476. package/scripts/deadline.test.mjs +191 -0
  477. package/scripts/diffs.test.mjs +189 -0
  478. package/scripts/file-tree-features.test.mjs +137 -0
  479. package/scripts/file-tree-icons.test.mjs +234 -0
  480. package/scripts/highlight.test.mjs +52 -0
  481. package/scripts/resize.test.mjs +247 -0
  482. package/scripts/resolve.mjs +52 -0
  483. package/scripts/slides.test.mjs +126 -0
  484. package/scripts/subscribe.test.mjs +49 -0
  485. package/scripts/ticker.test.mjs +126 -0
  486. package/scripts/transition.test.mjs +83 -0
  487. package/scripts/viewport.test.mjs +82 -0
  488. package/scripts/visible.test.mjs +186 -0
  489. package/shared.scss +2 -0
  490. package/src/components/accordion/index.ts +71 -12
  491. package/src/components/accordion/scss/index.scss +32 -129
  492. package/src/components/accordion/scss/variables.scss +7 -0
  493. package/src/components/announcement/index.ts +26 -0
  494. package/src/components/announcement/scss/index.scss +47 -0
  495. package/src/components/announcement/scss/variables.scss +23 -0
  496. package/src/components/banner/scss/index.scss +4 -8
  497. package/src/components/banner/scss/variables.scss +6 -0
  498. package/src/components/breadcrumb/index.ts +222 -25
  499. package/src/components/breadcrumb/scss/index.scss +217 -34
  500. package/src/components/breadcrumb/scss/variables.scss +73 -8
  501. package/src/components/button/copy.ts +1 -1
  502. package/src/components/button/faces.ts +1 -2
  503. package/src/components/button/fan.ts +111 -114
  504. package/src/components/button/hold.ts +9 -9
  505. package/src/components/button/icons.ts +15 -32
  506. package/src/components/button/index.ts +13 -1
  507. package/src/components/button/kbd.ts +6 -6
  508. package/src/components/button/loading.ts +1 -1
  509. package/src/components/button/morph.ts +153 -0
  510. package/src/components/button/scss/_kbd.scss +2 -1
  511. package/src/components/button/scss/_morph.scss +119 -0
  512. package/src/components/button/scss/_sidebar.scss +50 -0
  513. package/src/components/button/scss/_split.scss +53 -0
  514. package/src/components/button/scss/index.scss +45 -31
  515. package/src/components/button/scss/variables.scss +85 -34
  516. package/src/components/button/sidebar.ts +60 -0
  517. package/src/components/button/split.ts +60 -0
  518. package/src/components/capslock/index.ts +54 -0
  519. package/src/components/capslock/scss/index.scss +55 -0
  520. package/src/components/capslock/scss/variables.scss +26 -0
  521. package/src/components/card/expand.ts +141 -0
  522. package/src/components/card/index.ts +8 -0
  523. package/src/components/card/scss/_expand.scss +240 -0
  524. package/src/components/card/scss/index.scss +52 -9
  525. package/src/components/card/scss/variables.scss +85 -19
  526. package/src/components/cc/index.ts +558 -0
  527. package/src/components/cc/scss/index.scss +429 -0
  528. package/src/components/cc/scss/variables.scss +68 -0
  529. package/src/components/chat-minimap/index.ts +265 -0
  530. package/src/components/chat-minimap/range.ts +59 -0
  531. package/src/components/chat-minimap/scss/index.scss +140 -0
  532. package/src/components/chat-minimap/scss/variables.scss +97 -0
  533. package/src/components/chat-minimap/spy.ts +151 -0
  534. package/src/components/checkbox/group.ts +216 -0
  535. package/src/components/checkbox/index.ts +3 -41
  536. package/src/components/checkbox/options.ts +55 -0
  537. package/src/components/checkbox/scss/index.scss +69 -17
  538. package/src/components/checkbox/scss/variables.scss +28 -7
  539. package/src/components/clipboard/copy.ts +5 -5
  540. package/src/components/color-picker/index.ts +160 -233
  541. package/src/components/color-picker/scss/index.scss +51 -93
  542. package/src/components/color-picker/scss/variables.scss +68 -10
  543. package/src/components/command/index.ts +788 -206
  544. package/src/components/command/scss/index.scss +168 -158
  545. package/src/components/command/scss/variables.scss +118 -25
  546. package/src/components/copy/index.ts +69 -0
  547. package/src/components/copy/scss/index.scss +52 -0
  548. package/src/components/copy/scss/variables.scss +22 -0
  549. package/src/components/counter/index.ts +69 -94
  550. package/src/components/counter/scss/index.scss +20 -48
  551. package/src/components/counter/scss/variables.scss +24 -35
  552. package/src/components/datalist/index.ts +49 -29
  553. package/src/components/datalist/scss/index.scss +43 -24
  554. package/src/components/datalist/scss/variables.scss +7 -4
  555. package/src/components/dock/index.ts +61 -231
  556. package/src/components/dock/scss/index.scss +73 -39
  557. package/src/components/dock/scss/variables.scss +77 -16
  558. package/src/components/editor/code/changes.ts +111 -0
  559. package/src/components/editor/code/clipboard.ts +81 -0
  560. package/src/components/editor/code/colors.ts +278 -0
  561. package/src/components/editor/code/commands.ts +879 -0
  562. package/src/components/editor/code/composition.ts +85 -0
  563. package/src/components/editor/code/conflicts.ts +160 -0
  564. package/src/components/editor/code/document.ts +789 -0
  565. package/src/components/editor/code/editor.ts +68 -0
  566. package/src/components/editor/code/features.ts +1144 -0
  567. package/src/components/editor/code/field.ts +96 -0
  568. package/src/components/editor/code/find.ts +340 -0
  569. package/src/components/editor/code/folding.ts +689 -0
  570. package/src/components/editor/code/goto.ts +89 -0
  571. package/src/components/editor/code/gutter.ts +47 -0
  572. package/src/components/editor/code/index.ts +29 -0
  573. package/src/components/editor/code/keymap.ts +518 -0
  574. package/src/components/editor/code/layout.ts +565 -0
  575. package/src/components/editor/code/links.ts +55 -0
  576. package/src/components/editor/code/minimap.ts +260 -0
  577. package/src/components/editor/code/navigation.ts +95 -0
  578. package/src/components/editor/code/pointer.ts +199 -0
  579. package/src/components/editor/code/projection.ts +342 -0
  580. package/src/components/editor/code/rows.ts +412 -0
  581. package/src/components/editor/code/scss/_editor.scss +432 -0
  582. package/src/components/editor/code/scss/_features.scss +311 -0
  583. package/src/components/editor/code/scss/_services.scss +154 -0
  584. package/src/components/editor/code/scss/index.scss +6 -0
  585. package/src/components/editor/code/scss/variables.scss +194 -0
  586. package/src/components/editor/code/search.ts +391 -0
  587. package/src/components/editor/code/selection.ts +83 -0
  588. package/src/components/editor/code/services/completion.ts +114 -0
  589. package/src/components/editor/code/services/diagnostics.ts +168 -0
  590. package/src/components/editor/code/services/hover.ts +74 -0
  591. package/src/components/editor/code/services/index.ts +118 -0
  592. package/src/components/editor/code/services/model.ts +270 -0
  593. package/src/components/editor/code/services/protocol.ts +55 -0
  594. package/src/components/editor/code/services/session.ts +721 -0
  595. package/src/components/editor/code/services/transport.ts +36 -0
  596. package/src/components/editor/code/syntax.ts +1673 -0
  597. package/src/components/editor/code/unicode.ts +156 -0
  598. package/src/components/editor/code/view.ts +2139 -0
  599. package/src/components/editor/diffs/diff3.ts +280 -0
  600. package/src/components/editor/diffs/engine.ts +192 -0
  601. package/src/components/editor/diffs/hunks.ts +196 -0
  602. package/src/components/editor/diffs/index.ts +20 -0
  603. package/src/components/editor/diffs/merge.ts +377 -0
  604. package/src/components/editor/diffs/render.ts +95 -0
  605. package/src/components/editor/diffs/scss/_diffs.scss +352 -0
  606. package/src/components/editor/diffs/scss/_merge.scss +121 -0
  607. package/src/components/editor/diffs/scss/index.scss +5 -0
  608. package/src/components/editor/diffs/scss/variables.scss +70 -0
  609. package/src/components/editor/diffs/view.ts +464 -0
  610. package/src/components/editor/diffs/words.ts +85 -0
  611. package/src/components/editor/index.ts +59 -0
  612. package/src/components/editor/markdown/editing.ts +92 -0
  613. package/src/components/editor/markdown/html.ts +192 -0
  614. package/src/components/editor/markdown/index.ts +72 -0
  615. package/src/components/editor/markdown/inline.ts +399 -0
  616. package/src/components/editor/markdown/layout.ts +446 -0
  617. package/src/components/editor/markdown/model.ts +737 -0
  618. package/src/components/editor/markdown/render.ts +461 -0
  619. package/src/components/editor/markdown/scss/index.scss +456 -0
  620. package/src/components/editor/markdown/scss/variables.scss +109 -0
  621. package/src/components/editor/markdown/structure.ts +136 -0
  622. package/src/components/editor/markdown/view.ts +2417 -0
  623. package/src/components/editor/tree/clipboard.ts +80 -0
  624. package/src/components/editor/tree/compact.ts +93 -0
  625. package/src/components/editor/tree/decorations.ts +210 -0
  626. package/src/components/editor/tree/drag.ts +652 -0
  627. package/src/components/editor/tree/edit.ts +234 -0
  628. package/src/components/editor/tree/filter.ts +81 -0
  629. package/src/components/editor/tree/find.ts +500 -0
  630. package/src/components/editor/tree/glob.ts +76 -0
  631. package/src/components/editor/tree/glyph.ts +49 -0
  632. package/src/components/editor/tree/history.ts +282 -0
  633. package/src/components/editor/tree/icons.ts +507 -0
  634. package/src/components/editor/tree/index.ts +3438 -0
  635. package/src/components/editor/tree/jump.ts +78 -0
  636. package/src/components/editor/tree/lazy.ts +111 -0
  637. package/src/components/editor/tree/model.ts +235 -0
  638. package/src/components/editor/tree/scss/index.scss +732 -0
  639. package/src/components/editor/tree/scss/variables.scss +260 -0
  640. package/src/components/editor/tree/selection.ts +85 -0
  641. package/src/components/editor/tree/shortcuts.ts +64 -0
  642. package/src/components/editor/tree/sort.ts +104 -0
  643. package/src/components/editor/tree/spoken.ts +67 -0
  644. package/src/components/editor/tree/sprites.ts +159 -0
  645. package/src/components/editor/tree/sticky.ts +154 -0
  646. package/src/components/editor/tree/transfer.ts +134 -0
  647. package/src/components/editor/workspace/index.ts +1357 -0
  648. package/src/components/editor/workspace/model.ts +1023 -0
  649. package/src/components/editor/workspace/scss/index.scss +547 -0
  650. package/src/components/error/index.ts +189 -0
  651. package/src/components/error/scss/index.scss +89 -0
  652. package/src/components/error/scss/variables.scss +13 -0
  653. package/src/components/filter/index.ts +420 -0
  654. package/src/components/filter/scss/index.scss +6 -0
  655. package/src/components/filter/scss/variables.scss +17 -0
  656. package/src/components/form/action.ts +4 -4
  657. package/src/components/form/input.ts +13 -7
  658. package/src/components/frame/scss/index.scss +107 -0
  659. package/src/components/frame/scss/variables.scss +27 -0
  660. package/src/components/heatmap/index.ts +281 -0
  661. package/src/components/heatmap/scss/index.scss +131 -0
  662. package/src/components/heatmap/scss/variables.scss +58 -0
  663. package/src/components/highlight/easing.ts +33 -0
  664. package/src/components/highlight/index.ts +580 -77
  665. package/src/components/highlight/scss/index.scss +49 -9
  666. package/src/components/highlight/scss/variables.scss +62 -3
  667. package/src/components/icon/scss/index.scss +0 -1
  668. package/src/components/image/index.ts +3 -76
  669. package/src/components/image/lazyload.ts +95 -0
  670. package/src/components/image/scss/index.scss +71 -57
  671. package/src/components/image/scss/variables.scss +39 -14
  672. package/src/components/index.ts +27 -79
  673. package/src/components/inline-edit/format.ts +183 -0
  674. package/src/components/inline-edit/history.ts +71 -0
  675. package/src/components/inline-edit/index.ts +44 -38
  676. package/src/components/inline-edit/markdown.ts +485 -0
  677. package/src/components/inline-edit/model.ts +366 -0
  678. package/src/components/inline-edit/rich.ts +1518 -0
  679. package/src/components/inline-edit/scss/index.scss +431 -41
  680. package/src/components/inline-edit/scss/variables.scss +105 -0
  681. package/src/components/inline-edit/selection.ts +188 -0
  682. package/src/components/inline-edit/status.ts +194 -0
  683. package/src/components/inline-edit/utilities.ts +18 -0
  684. package/src/components/input/field.ts +32 -0
  685. package/src/components/input/index.ts +5 -38
  686. package/src/components/input/scrub.ts +338 -0
  687. package/src/components/input/scss/_field.scss +53 -0
  688. package/src/components/input/scss/_scrub.scss +91 -0
  689. package/src/components/input/scss/_tag.scss +162 -0
  690. package/src/components/input/scss/index.scss +5 -18
  691. package/src/components/input/scss/variables.scss +108 -38
  692. package/src/components/input/tag.ts +403 -0
  693. package/src/components/json/download.ts +9 -6
  694. package/src/components/link/scss/index.scss +9 -4
  695. package/src/components/link/scss/variables.scss +1 -31
  696. package/src/components/loading/index.ts +1 -1
  697. package/src/components/loading/scss/index.scss +3 -6
  698. package/src/components/marquee/index.ts +246 -169
  699. package/src/components/marquee/scss/index.scss +21 -28
  700. package/src/components/marquee/scss/variables.scss +16 -0
  701. package/src/components/marquee/velocity.ts +144 -0
  702. package/src/components/metric/flash.ts +128 -0
  703. package/src/components/metric/index.ts +315 -0
  704. package/src/components/metric/scss/_flash.scss +163 -0
  705. package/src/components/metric/scss/index.scss +163 -0
  706. package/src/components/metric/scss/variables.scss +133 -0
  707. package/src/components/nav/index.ts +13 -0
  708. package/src/components/nav/scss/index.scss +123 -0
  709. package/src/components/nav/scss/variables.scss +60 -0
  710. package/src/components/nav/spy.ts +203 -0
  711. package/src/components/nav/toc.ts +48 -0
  712. package/src/components/nav/tree.ts +181 -0
  713. package/src/components/notification/index.ts +111 -0
  714. package/src/components/notification/scss/index.scss +123 -0
  715. package/src/components/notification/scss/variables.scss +54 -0
  716. package/src/components/overlay/index.ts +487 -5
  717. package/src/components/overlay/popup.ts +214 -0
  718. package/src/components/overlay/scss/index.scss +379 -7
  719. package/src/components/overlay/scss/variables.scss +117 -0
  720. package/src/components/pagination/dots.ts +132 -0
  721. package/src/components/pagination/index.ts +34 -45
  722. package/src/components/pagination/scss/_dots.scss +67 -0
  723. package/src/components/pagination/scss/index.scss +15 -8
  724. package/src/components/pagination/scss/variables.scss +59 -0
  725. package/src/components/progress/index.ts +18 -8
  726. package/src/components/progress/scss/_text.scss +132 -0
  727. package/src/components/progress/scss/index.scss +1 -0
  728. package/src/components/progress/scss/variables.scss +42 -0
  729. package/src/components/progress/text.ts +158 -0
  730. package/src/components/pull-to-refresh/index.ts +126 -248
  731. package/src/components/pull-to-refresh/scss/index.scss +65 -29
  732. package/src/components/pull-to-refresh/scss/variables.scss +24 -1
  733. package/src/components/radio/index.ts +3 -3
  734. package/src/components/range/filter.ts +398 -0
  735. package/src/components/range/index.ts +27 -16
  736. package/src/components/range/scss/_filter.scss +374 -0
  737. package/src/components/range/scss/_slider.scss +140 -0
  738. package/src/components/range/scss/_vertical.scss +22 -0
  739. package/src/components/range/scss/index.scss +26 -14
  740. package/src/components/range/scss/variables.scss +78 -13
  741. package/src/components/relative-time/index.ts +218 -233
  742. package/src/components/relative-time/scss/index.scss +42 -18
  743. package/src/components/relative-time/scss/variables.scss +25 -0
  744. package/src/components/root/scss/index.scss +7 -3
  745. package/src/components/root/scss/variables.scss +21 -12
  746. package/src/components/select/index.ts +506 -153
  747. package/src/components/select/placement.ts +75 -0
  748. package/src/components/select/scss/index.scss +182 -45
  749. package/src/components/select/scss/variables.scss +58 -44
  750. package/src/components/shortcut-recorder/index.ts +145 -106
  751. package/src/components/shortcut-recorder/scss/index.scss +34 -121
  752. package/src/components/shortcut-recorder/scss/variables.scss +27 -39
  753. package/src/components/sortable/index.ts +380 -272
  754. package/src/components/sortable/scss/index.scss +107 -38
  755. package/src/components/sortable/scss/variables.scss +12 -1
  756. package/src/components/sticky-header/index.ts +43 -92
  757. package/src/components/sticky-header/scss/index.scss +76 -86
  758. package/src/components/sticky-header/scss/variables.scss +36 -12
  759. package/src/components/story/index.ts +305 -0
  760. package/src/components/story/scss/index.scss +189 -0
  761. package/src/components/story/scss/variables.scss +28 -0
  762. package/src/components/surface-field/engine.ts +1631 -0
  763. package/src/components/surface-field/index.ts +574 -608
  764. package/src/components/surface-field/scss/index.scss +74 -17
  765. package/src/components/surface-field/scss/variables.scss +23 -0
  766. package/src/components/surface-field/surface.ts +260 -0
  767. package/src/components/surface-field/worker/index.ts +41 -0
  768. package/src/components/switch/index.ts +3 -3
  769. package/src/components/tasklist/index.ts +197 -119
  770. package/src/components/tasklist/scss/index.scss +45 -128
  771. package/src/components/tasklist/scss/variables.scss +97 -70
  772. package/src/components/text/scss/index.scss +2 -15
  773. package/src/components/textarea/index.ts +142 -39
  774. package/src/components/textarea/scss/index.scss +41 -18
  775. package/src/components/textarea/scss/variables.scss +5 -46
  776. package/src/components/toast/index.ts +270 -157
  777. package/src/components/toast/scss/index.scss +244 -225
  778. package/src/components/toast/scss/variables.scss +68 -9
  779. package/src/components/tooltip/index.ts +9 -4
  780. package/src/components/tooltip/menu.ts +599 -37
  781. package/src/components/tooltip/onclick.ts +28 -22
  782. package/src/components/tooltip/onhover.ts +155 -73
  783. package/src/components/tooltip/scss/_menu.scss +352 -0
  784. package/src/components/tooltip/scss/_shared.scss +109 -0
  785. package/src/components/tooltip/scss/_south.scss +0 -1
  786. package/src/components/tooltip/scss/index.scss +16 -97
  787. package/src/components/tooltip/scss/variables.scss +103 -59
  788. package/src/components/tooltip/shared.ts +819 -0
  789. package/src/components/tooltip/utilities.ts +78 -23
  790. package/src/components/typewriter/index.ts +8 -1
  791. package/src/components/typewriter/retype.ts +99 -0
  792. package/src/components/typewriter/rotate.ts +279 -0
  793. package/src/components/typewriter/scss/_caret.scss +34 -0
  794. package/src/components/typewriter/scss/_retype.scss +67 -0
  795. package/src/components/typewriter/scss/_rotate.scss +28 -0
  796. package/src/components/typewriter/scss/index.scss +3 -33
  797. package/src/components/typewriter/scss/variables.scss +60 -10
  798. package/src/components/uptime/index.ts +50 -49
  799. package/src/components/uptime/scss/index.scss +67 -47
  800. package/src/components/uptime/scss/variables.scss +32 -4
  801. package/src/components/usage-meter/index.ts +17 -17
  802. package/src/components/usage-meter/scss/index.scss +19 -31
  803. package/src/components/usage-meter/scss/variables.scss +15 -7
  804. package/src/css-utilities/background/scss/index.scss +1 -1
  805. package/src/css-utilities/background/scss/variables.scss +2 -17
  806. package/src/css-utilities/border/scss/index.scss +1 -1
  807. package/src/css-utilities/border/scss/variables.scss +7 -23
  808. package/src/css-utilities/color/scss/index.scss +1 -1
  809. package/src/css-utilities/color/scss/variables.scss +2 -17
  810. package/src/css-utilities/flex/scss/variables.scss +0 -1
  811. package/src/css-utilities/font/geist/scss/index.scss +2 -2
  812. package/src/css-utilities/font/montserrat/scss/index.scss +2 -2
  813. package/src/css-utilities/glass/index.ts +42 -0
  814. package/src/css-utilities/glass/scss/index.scss +65 -1
  815. package/src/css-utilities/glass/scss/variables.scss +6 -1
  816. package/src/css-utilities/index.scss +0 -5
  817. package/src/css-utilities/index.ts +3 -0
  818. package/src/css-utilities/scrollbar/index.ts +200 -0
  819. package/src/css-utilities/scrollbar/scss/index.scss +300 -36
  820. package/src/css-utilities/scrollbar/scss/variables.scss +38 -3
  821. package/src/css-utilities/text/scss/index.scss +97 -6
  822. package/src/css-utilities/text/scss/variables.scss +22 -0
  823. package/src/css-utilities/theme/index.ts +71 -0
  824. package/src/normalize/scss/index.scss +42 -0
  825. package/src/shared/anchor.ts +34 -0
  826. package/src/shared/animation.ts +106 -0
  827. package/src/shared/clamp.ts +6 -0
  828. package/src/shared/deadline.ts +153 -0
  829. package/src/shared/dismiss.ts +6 -0
  830. package/src/shared/drag.ts +348 -0
  831. package/src/shared/fuzzy.ts +263 -0
  832. package/src/shared/keystep.ts +28 -0
  833. package/src/shared/platform.ts +10 -0
  834. package/src/shared/press.ts +144 -0
  835. package/src/shared/resize.ts +232 -0
  836. package/src/shared/scss/absolute.scss +28 -0
  837. package/src/shared/scss/anchor.scss +63 -0
  838. package/src/shared/scss/background.scss +21 -0
  839. package/src/shared/scss/border.scss +21 -0
  840. package/src/shared/scss/color.scss +21 -0
  841. package/src/shared/scss/drag.scss +7 -0
  842. package/src/shared/scss/hidden.scss +22 -0
  843. package/src/shared/scss/icon.scss +36 -0
  844. package/src/shared/scss/index.scss +16 -0
  845. package/src/shared/scss/layer.scss +20 -0
  846. package/src/shared/scss/list.scss +64 -0
  847. package/src/shared/scss/reset.scss +21 -0
  848. package/src/shared/scss/string.scss +18 -0
  849. package/src/shared/scss/text.scss +31 -0
  850. package/src/shared/subscribe.ts +20 -0
  851. package/src/shared/ticker.ts +56 -0
  852. package/src/shared/transition.ts +61 -0
  853. package/src/shared/viewport.ts +23 -0
  854. package/src/shared/visible.ts +127 -0
  855. package/src/themes/dark/input.ts +6 -2
  856. package/src/themes/dark/select.ts +3 -2
  857. package/src/themes/dark/textarea.ts +1 -0
  858. package/src/tokens/scss/box-shadow.scss +12 -16
  859. package/src/tokens/scss/color.scss +3 -2
  860. package/src/tokens/scss/font-family.scss +5 -0
  861. package/src/tokens/scss/index.scss +10 -0
  862. package/src/tokens/scss/state.scss +10 -8
  863. package/storage/code.md +180 -0
  864. package/storage/editor-features.md +227 -0
  865. package/storage/svg/amex.svg +1 -0
  866. package/storage/svg/arrow-down.svg +1 -0
  867. package/storage/svg/arrow-up.svg +1 -0
  868. package/storage/svg/bold.svg +1 -0
  869. package/storage/svg/caps-lock.svg +1 -0
  870. package/storage/svg/card.svg +1 -0
  871. package/storage/svg/chevron-down.svg +1 -0
  872. package/storage/svg/chevron-left.svg +1 -0
  873. package/storage/svg/chevron-right.svg +1 -0
  874. package/storage/svg/chevron-up.svg +1 -0
  875. package/storage/svg/chevrons-up-down.svg +1 -0
  876. package/storage/svg/chip.svg +1 -0
  877. package/storage/svg/circle.svg +1 -0
  878. package/storage/svg/clear-format.svg +1 -0
  879. package/storage/svg/close.svg +1 -0
  880. package/storage/svg/code.svg +1 -0
  881. package/storage/svg/command.svg +1 -0
  882. package/storage/svg/contrast.svg +1 -0
  883. package/storage/svg/copy.svg +1 -0
  884. package/storage/svg/corner-down-right.svg +1 -0
  885. package/storage/svg/credit-card.svg +1 -0
  886. package/storage/svg/dash.svg +1 -0
  887. package/storage/svg/discover.svg +1 -0
  888. package/storage/svg/document.svg +1 -0
  889. package/storage/svg/dots.svg +1 -0
  890. package/storage/svg/download.svg +1 -0
  891. package/storage/svg/enter.svg +1 -0
  892. package/storage/svg/expand.svg +1 -0
  893. package/storage/svg/external-link.svg +1 -0
  894. package/storage/svg/eye-off.svg +1 -0
  895. package/storage/svg/eye.svg +1 -0
  896. package/storage/svg/file-agents.svg +1 -0
  897. package/storage/svg/file-astro.svg +1 -0
  898. package/storage/svg/file-babel.svg +1 -0
  899. package/storage/svg/file-bash.svg +1 -0
  900. package/storage/svg/file-biome.svg +1 -0
  901. package/storage/svg/file-bootstrap.svg +1 -0
  902. package/storage/svg/file-browserslist.svg +1 -0
  903. package/storage/svg/file-bun.svg +1 -0
  904. package/storage/svg/file-c.svg +1 -0
  905. package/storage/svg/file-claude.svg +1 -0
  906. package/storage/svg/file-css.svg +1 -0
  907. package/storage/svg/file-database.svg +1 -0
  908. package/storage/svg/file-docker.svg +1 -0
  909. package/storage/svg/file-eslint.svg +1 -0
  910. package/storage/svg/file-font.svg +1 -0
  911. package/storage/svg/file-git.svg +1 -0
  912. package/storage/svg/file-go.svg +1 -0
  913. package/storage/svg/file-graphql.svg +1 -0
  914. package/storage/svg/file-html.svg +1 -0
  915. package/storage/svg/file-image.svg +1 -0
  916. package/storage/svg/file-javascript.svg +1 -0
  917. package/storage/svg/file-json.svg +1 -0
  918. package/storage/svg/file-markdown.svg +1 -0
  919. package/storage/svg/file-mcp.svg +1 -0
  920. package/storage/svg/file-nextjs.svg +1 -0
  921. package/storage/svg/file-npm.svg +1 -0
  922. package/storage/svg/file-oxc.svg +1 -0
  923. package/storage/svg/file-package.svg +1 -0
  924. package/storage/svg/file-pnpm.svg +1 -0
  925. package/storage/svg/file-postcss.svg +1 -0
  926. package/storage/svg/file-prettier.svg +1 -0
  927. package/storage/svg/file-python.svg +1 -0
  928. package/storage/svg/file-react.svg +1 -0
  929. package/storage/svg/file-readme.svg +1 -0
  930. package/storage/svg/file-ruby.svg +1 -0
  931. package/storage/svg/file-rust.svg +1 -0
  932. package/storage/svg/file-sass.svg +1 -0
  933. package/storage/svg/file-stylelint.svg +1 -0
  934. package/storage/svg/file-svelte.svg +1 -0
  935. package/storage/svg/file-svg.svg +1 -0
  936. package/storage/svg/file-svgo.svg +1 -0
  937. package/storage/svg/file-swift.svg +1 -0
  938. package/storage/svg/file-table.svg +1 -0
  939. package/storage/svg/file-tailwind.svg +1 -0
  940. package/storage/svg/file-terraform.svg +1 -0
  941. package/storage/svg/file-text.svg +1 -0
  942. package/storage/svg/file-tsconfig.svg +1 -0
  943. package/storage/svg/file-typescript.svg +1 -0
  944. package/storage/svg/file-vite.svg +1 -0
  945. package/storage/svg/file-vscode.svg +1 -0
  946. package/storage/svg/file-vue.svg +1 -0
  947. package/storage/svg/file-wasm.svg +1 -0
  948. package/storage/svg/file-webpack.svg +1 -0
  949. package/storage/svg/file-yml.svg +1 -0
  950. package/storage/svg/file-zig.svg +1 -0
  951. package/storage/svg/file-zip.svg +1 -0
  952. package/storage/svg/file.svg +1 -0
  953. package/storage/svg/folder-assets-open.svg +1 -0
  954. package/storage/svg/folder-assets.svg +1 -0
  955. package/storage/svg/folder-components-open.svg +1 -0
  956. package/storage/svg/folder-components.svg +1 -0
  957. package/storage/svg/folder-docs-open.svg +1 -0
  958. package/storage/svg/folder-docs.svg +1 -0
  959. package/storage/svg/folder-git-open.svg +1 -0
  960. package/storage/svg/folder-git.svg +1 -0
  961. package/storage/svg/folder-open.svg +1 -0
  962. package/storage/svg/folder-output-open.svg +1 -0
  963. package/storage/svg/folder-output.svg +1 -0
  964. package/storage/svg/folder-packages-open.svg +1 -0
  965. package/storage/svg/folder-packages.svg +1 -0
  966. package/storage/svg/folder-public-open.svg +1 -0
  967. package/storage/svg/folder-public.svg +1 -0
  968. package/storage/svg/folder-scripts-open.svg +1 -0
  969. package/storage/svg/folder-scripts.svg +1 -0
  970. package/storage/svg/folder-src-open.svg +1 -0
  971. package/storage/svg/folder-src.svg +1 -0
  972. package/storage/svg/folder-test-open.svg +1 -0
  973. package/storage/svg/folder-test.svg +1 -0
  974. package/storage/svg/folder.svg +1 -0
  975. package/storage/svg/gear.svg +1 -0
  976. package/storage/svg/help.svg +1 -0
  977. package/storage/svg/highlight.svg +1 -0
  978. package/storage/svg/home.svg +1 -0
  979. package/storage/svg/inbox.svg +1 -0
  980. package/storage/svg/italic.svg +1 -0
  981. package/storage/svg/keyboard.svg +1 -0
  982. package/storage/svg/link.svg +1 -0
  983. package/storage/svg/list-checks.svg +1 -0
  984. package/storage/svg/lock.svg +1 -0
  985. package/storage/svg/log-out.svg +1 -0
  986. package/storage/svg/map.svg +1 -0
  987. package/storage/svg/mastercard.svg +1 -0
  988. package/storage/svg/pause.svg +1 -0
  989. package/storage/svg/pencil.svg +1 -0
  990. package/storage/svg/play.svg +1 -0
  991. package/storage/svg/plus.svg +1 -0
  992. package/storage/svg/redo.svg +1 -0
  993. package/storage/svg/save.svg +1 -0
  994. package/storage/svg/sidebar-filled.svg +1 -0
  995. package/storage/svg/sidebar.svg +1 -0
  996. package/storage/svg/slash.svg +1 -0
  997. package/storage/svg/sliders.svg +1 -0
  998. package/storage/svg/strikethrough.svg +1 -0
  999. package/storage/svg/trash.svg +1 -0
  1000. package/storage/svg/triangle.svg +1 -0
  1001. package/storage/svg/undo.svg +1 -0
  1002. package/storage/svg/unlink.svg +1 -0
  1003. package/storage/svg/user.svg +1 -0
  1004. package/storage/svg/visa.svg +1 -0
  1005. package/storage/svg/zoom-in.svg +1 -0
  1006. package/storage/svg/zoom-out.svg +1 -0
  1007. package/tokens.scss +1 -1
  1008. package/vite.config.ts +47 -46
  1009. package/build/components/accordion/more.d.ts +0 -20
  1010. package/build/components/accordion/more.js +0 -76
  1011. package/build/components/anchor/scss/index.scss +0 -2
  1012. package/build/components/announcement-banner/index.d.ts +0 -33
  1013. package/build/components/announcement-banner/index.js +0 -61
  1014. package/build/components/announcement-banner/scss/index.scss +0 -2
  1015. package/build/components/autosave/index.d.ts +0 -12
  1016. package/build/components/autosave/index.js +0 -140
  1017. package/build/components/autosave/scss/index.scss +0 -2
  1018. package/build/components/back-to-top/index.d.ts +0 -16
  1019. package/build/components/back-to-top/index.js +0 -182
  1020. package/build/components/back-to-top/scss/index.scss +0 -2
  1021. package/build/components/bento-grid/index.d.ts +0 -25
  1022. package/build/components/bento-grid/index.js +0 -38
  1023. package/build/components/bento-grid/scss/index.scss +0 -2
  1024. package/build/components/bento-grid-spotlight/index.d.ts +0 -35
  1025. package/build/components/bento-grid-spotlight/index.js +0 -108
  1026. package/build/components/bento-grid-spotlight/scss/index.scss +0 -2
  1027. package/build/components/bookmark-button/index.d.ts +0 -23
  1028. package/build/components/bookmark-button/index.js +0 -120
  1029. package/build/components/bookmark-button/scss/index.scss +0 -2
  1030. package/build/components/breadcrumb/ellipsis.d.ts +0 -12
  1031. package/build/components/breadcrumb/ellipsis.js +0 -11
  1032. package/build/components/breadcrumb/item.d.ts +0 -12
  1033. package/build/components/breadcrumb/item.js +0 -9
  1034. package/build/components/breadcrumb/link.d.ts +0 -15
  1035. package/build/components/breadcrumb/link.js +0 -14
  1036. package/build/components/breadcrumb/list.d.ts +0 -12
  1037. package/build/components/breadcrumb/list.js +0 -9
  1038. package/build/components/breadcrumb/menu.d.ts +0 -13
  1039. package/build/components/breadcrumb/menu.js +0 -16
  1040. package/build/components/breadcrumb/page.d.ts +0 -12
  1041. package/build/components/breadcrumb/page.js +0 -9
  1042. package/build/components/breadcrumb/separator.d.ts +0 -12
  1043. package/build/components/breadcrumb/separator.js +0 -11
  1044. package/build/components/breadcrumb/svg/caret.svg +0 -1
  1045. package/build/components/breadcrumb/svg/chevron.svg +0 -1
  1046. package/build/components/breadcrumb/svg/more.svg +0 -1
  1047. package/build/components/breadcrumbs/index.d.ts +0 -27
  1048. package/build/components/breadcrumbs/index.js +0 -324
  1049. package/build/components/breadcrumbs/scss/index.scss +0 -2
  1050. package/build/components/button/svg/plus.svg +0 -1
  1051. package/build/components/card-input/index.d.ts +0 -31
  1052. package/build/components/card-input/index.js +0 -562
  1053. package/build/components/card-input/scss/index.scss +0 -2
  1054. package/build/components/carousel-3d/index.d.ts +0 -27
  1055. package/build/components/carousel-3d/index.js +0 -248
  1056. package/build/components/carousel-3d/scss/index.scss +0 -2
  1057. package/build/components/checkbox-group/index.d.ts +0 -30
  1058. package/build/components/checkbox-group/index.js +0 -101
  1059. package/build/components/checkbox-group/scss/index.scss +0 -2
  1060. package/build/components/code-morph/index.d.ts +0 -25
  1061. package/build/components/code-morph/index.js +0 -401
  1062. package/build/components/code-morph/scss/index.scss +0 -2
  1063. package/build/components/collapsible-sidebar/index.d.ts +0 -41
  1064. package/build/components/collapsible-sidebar/index.js +0 -105
  1065. package/build/components/collapsible-sidebar/scss/index.scss +0 -2
  1066. package/build/components/command/constants.d.ts +0 -3
  1067. package/build/components/command/constants.js +0 -3
  1068. package/build/components/command-palette/index.d.ts +0 -51
  1069. package/build/components/command-palette/index.js +0 -319
  1070. package/build/components/command-palette/scss/index.scss +0 -2
  1071. package/build/components/composer/index.d.ts +0 -29
  1072. package/build/components/composer/index.js +0 -79
  1073. package/build/components/composer/scss/index.scss +0 -2
  1074. package/build/components/composer/svg/arrow-up.svg +0 -1
  1075. package/build/components/contribution-heatmap/index.d.ts +0 -30
  1076. package/build/components/contribution-heatmap/index.js +0 -236
  1077. package/build/components/contribution-heatmap/scss/index.scss +0 -2
  1078. package/build/components/date-range-picker/index.d.ts +0 -28
  1079. package/build/components/date-range-picker/index.js +0 -443
  1080. package/build/components/date-range-picker/scss/index.scss +0 -2
  1081. package/build/components/dynamic-island/index.d.ts +0 -23
  1082. package/build/components/dynamic-island/index.js +0 -179
  1083. package/build/components/dynamic-island/scss/index.scss +0 -2
  1084. package/build/components/email-typo-fix/index.d.ts +0 -28
  1085. package/build/components/email-typo-fix/index.js +0 -416
  1086. package/build/components/email-typo-fix/scss/index.scss +0 -2
  1087. package/build/components/expanding-card/index.d.ts +0 -26
  1088. package/build/components/expanding-card/index.js +0 -265
  1089. package/build/components/expanding-card/scss/index.scss +0 -2
  1090. package/build/components/feature-spotlight/index.d.ts +0 -37
  1091. package/build/components/feature-spotlight/index.js +0 -248
  1092. package/build/components/feature-spotlight/scss/index.scss +0 -2
  1093. package/build/components/file-tree/index.d.ts +0 -31
  1094. package/build/components/file-tree/index.js +0 -208
  1095. package/build/components/file-tree/scss/index.scss +0 -2
  1096. package/build/components/filter-grid/index.d.ts +0 -23
  1097. package/build/components/filter-grid/index.js +0 -240
  1098. package/build/components/filter-grid/scss/index.scss +0 -2
  1099. package/build/components/gradient-text/index.d.ts +0 -19
  1100. package/build/components/gradient-text/index.js +0 -14
  1101. package/build/components/gradient-text/scss/index.scss +0 -2
  1102. package/build/components/header/index.d.ts +0 -41
  1103. package/build/components/header/index.js +0 -281
  1104. package/build/components/header/scss/index.scss +0 -2
  1105. package/build/components/hover-card/index.d.ts +0 -47
  1106. package/build/components/hover-card/index.js +0 -197
  1107. package/build/components/hover-card/scss/index.scss +0 -2
  1108. package/build/components/kanban-board/index.d.ts +0 -23
  1109. package/build/components/kanban-board/index.js +0 -235
  1110. package/build/components/kanban-board/scss/index.scss +0 -2
  1111. package/build/components/lightbox/index.d.ts +0 -32
  1112. package/build/components/lightbox/index.js +0 -396
  1113. package/build/components/lightbox/scss/index.scss +0 -2
  1114. package/build/components/lightbox/spring.d.ts +0 -16
  1115. package/build/components/lightbox/spring.js +0 -71
  1116. package/build/components/line-shadow-text/index.d.ts +0 -17
  1117. package/build/components/line-shadow-text/index.js +0 -15
  1118. package/build/components/line-shadow-text/scss/index.scss +0 -2
  1119. package/build/components/log/index.d.ts +0 -20
  1120. package/build/components/log/index.js +0 -125
  1121. package/build/components/log/scss/index.scss +0 -2
  1122. package/build/components/long-press/bind.d.ts +0 -21
  1123. package/build/components/long-press/bind.js +0 -136
  1124. package/build/components/long-press/button.d.ts +0 -21
  1125. package/build/components/long-press/button.js +0 -25
  1126. package/build/components/long-press/index.d.ts +0 -2181
  1127. package/build/components/long-press/index.js +0 -4
  1128. package/build/components/long-press/scss/index.scss +0 -2
  1129. package/build/components/modal/index.d.ts +0 -24
  1130. package/build/components/modal/index.js +0 -75
  1131. package/build/components/modal/scss/index.scss +0 -2
  1132. package/build/components/morphing-button/index.d.ts +0 -24
  1133. package/build/components/morphing-button/index.js +0 -127
  1134. package/build/components/morphing-button/scss/index.scss +0 -2
  1135. package/build/components/morphing-nav/index.d.ts +0 -38
  1136. package/build/components/morphing-nav/index.js +0 -342
  1137. package/build/components/morphing-nav/scss/index.scss +0 -2
  1138. package/build/components/multi-step-form/index.d.ts +0 -32
  1139. package/build/components/multi-step-form/index.js +0 -305
  1140. package/build/components/multi-step-form/scss/index.scss +0 -2
  1141. package/build/components/navigation-menu/index.d.ts +0 -28
  1142. package/build/components/navigation-menu/index.js +0 -419
  1143. package/build/components/navigation-menu/scss/index.scss +0 -2
  1144. package/build/components/nested-menu/index.d.ts +0 -27
  1145. package/build/components/nested-menu/index.js +0 -374
  1146. package/build/components/nested-menu/scss/index.scss +0 -2
  1147. package/build/components/normalize/scss/index.scss +0 -3
  1148. package/build/components/notification-bell/index.d.ts +0 -13
  1149. package/build/components/notification-bell/index.js +0 -87
  1150. package/build/components/notification-bell/scss/index.scss +0 -2
  1151. package/build/components/onboarding-checklist/index.d.ts +0 -29
  1152. package/build/components/onboarding-checklist/index.js +0 -196
  1153. package/build/components/onboarding-checklist/scss/index.scss +0 -2
  1154. package/build/components/page-dots/index.d.ts +0 -24
  1155. package/build/components/page-dots/index.js +0 -116
  1156. package/build/components/page-dots/scss/index.scss +0 -2
  1157. package/build/components/pagination/svg/arrow-left.svg +0 -1
  1158. package/build/components/pagination/svg/arrow-right.svg +0 -1
  1159. package/build/components/password/constants.d.ts +0 -2
  1160. package/build/components/password/constants.js +0 -2
  1161. package/build/components/password/index.d.ts +0 -22
  1162. package/build/components/password/index.js +0 -74
  1163. package/build/components/password/scss/index.scss +0 -2
  1164. package/build/components/plan-card/index.d.ts +0 -36
  1165. package/build/components/plan-card/index.js +0 -257
  1166. package/build/components/plan-card/scss/index.scss +0 -2
  1167. package/build/components/radio-cards/index.d.ts +0 -36
  1168. package/build/components/radio-cards/index.js +0 -106
  1169. package/build/components/radio-cards/scss/index.scss +0 -2
  1170. package/build/components/range-filter/index.d.ts +0 -20
  1171. package/build/components/range-filter/index.js +0 -216
  1172. package/build/components/range-filter/scss/index.scss +0 -2
  1173. package/build/components/range-slider/index.d.ts +0 -30
  1174. package/build/components/range-slider/index.js +0 -287
  1175. package/build/components/range-slider/scss/index.scss +0 -2
  1176. package/build/components/reading-progress/index.d.ts +0 -13
  1177. package/build/components/reading-progress/index.js +0 -106
  1178. package/build/components/reading-progress/scss/index.scss +0 -2
  1179. package/build/components/scroll-fade/index.d.ts +0 -39
  1180. package/build/components/scroll-fade/index.js +0 -104
  1181. package/build/components/scroll-fade/scss/index.scss +0 -2
  1182. package/build/components/scroll-spine/index.d.ts +0 -26
  1183. package/build/components/scroll-spine/index.js +0 -204
  1184. package/build/components/scroll-spine/scss/index.scss +0 -2
  1185. package/build/components/scroll-velocity/index.d.ts +0 -22
  1186. package/build/components/scroll-velocity/index.js +0 -160
  1187. package/build/components/scroll-velocity/scss/index.scss +0 -2
  1188. package/build/components/scrub-input/index.d.ts +0 -39
  1189. package/build/components/scrub-input/index.js +0 -221
  1190. package/build/components/scrub-input/scss/index.scss +0 -2
  1191. package/build/components/select-menu/index.d.ts +0 -34
  1192. package/build/components/select-menu/index.js +0 -329
  1193. package/build/components/select-menu/scss/index.scss +0 -2
  1194. package/build/components/selection-toolbar/index.d.ts +0 -36
  1195. package/build/components/selection-toolbar/index.js +0 -442
  1196. package/build/components/selection-toolbar/scss/index.scss +0 -2
  1197. package/build/components/settings/index.d.ts +0 -43
  1198. package/build/components/settings/index.js +0 -147
  1199. package/build/components/settings/scss/index.scss +0 -2
  1200. package/build/components/settings/svg/close.svg +0 -1
  1201. package/build/components/settings/svg/saved.svg +0 -1
  1202. package/build/components/share-button/index.d.ts +0 -29
  1203. package/build/components/share-button/index.js +0 -191
  1204. package/build/components/share-button/scss/index.scss +0 -2
  1205. package/build/components/sheet/index.d.ts +0 -33
  1206. package/build/components/sheet/index.js +0 -110
  1207. package/build/components/sheet/scss/index.scss +0 -2
  1208. package/build/components/shiny-text/index.d.ts +0 -17
  1209. package/build/components/shiny-text/index.js +0 -14
  1210. package/build/components/shiny-text/scss/index.scss +0 -2
  1211. package/build/components/shortcut-sheet/index.d.ts +0 -48
  1212. package/build/components/shortcut-sheet/index.js +0 -304
  1213. package/build/components/shortcut-sheet/scss/index.scss +0 -2
  1214. package/build/components/sidebar/index.d.ts +0 -13
  1215. package/build/components/sidebar/index.js +0 -13
  1216. package/build/components/sidebar/scss/index.scss +0 -2
  1217. package/build/components/slider/index.d.ts +0 -25
  1218. package/build/components/slider/index.js +0 -188
  1219. package/build/components/slider/scss/index.scss +0 -2
  1220. package/build/components/sliding-tabs/index.d.ts +0 -28
  1221. package/build/components/sliding-tabs/index.js +0 -188
  1222. package/build/components/sliding-tabs/scss/index.scss +0 -2
  1223. package/build/components/snap-carousel/index.d.ts +0 -30
  1224. package/build/components/snap-carousel/index.js +0 -233
  1225. package/build/components/snap-carousel/scss/index.scss +0 -2
  1226. package/build/components/sparkline/index.d.ts +0 -26
  1227. package/build/components/sparkline/index.js +0 -173
  1228. package/build/components/sparkline/scss/index.scss +0 -2
  1229. package/build/components/stacked-drawer/index.d.ts +0 -24
  1230. package/build/components/stacked-drawer/index.js +0 -211
  1231. package/build/components/stacked-drawer/scss/index.scss +0 -2
  1232. package/build/components/stat-counter/index.d.ts +0 -32
  1233. package/build/components/stat-counter/index.js +0 -216
  1234. package/build/components/stat-counter/scss/index.scss +0 -2
  1235. package/build/components/status-picker/index.d.ts +0 -32
  1236. package/build/components/status-picker/index.js +0 -198
  1237. package/build/components/status-picker/scss/index.scss +0 -2
  1238. package/build/components/sticky-stack/index.d.ts +0 -33
  1239. package/build/components/sticky-stack/index.js +0 -184
  1240. package/build/components/sticky-stack/scss/index.scss +0 -2
  1241. package/build/components/story-progress/index.d.ts +0 -26
  1242. package/build/components/story-progress/index.js +0 -196
  1243. package/build/components/story-progress/scss/index.scss +0 -2
  1244. package/build/components/swipe-deck/index.d.ts +0 -19
  1245. package/build/components/swipe-deck/index.js +0 -300
  1246. package/build/components/swipe-deck/scss/index.scss +0 -2
  1247. package/build/components/tabs/scss/index.scss +0 -2
  1248. package/build/components/tag-input/index.d.ts +0 -27
  1249. package/build/components/tag-input/index.js +0 -309
  1250. package/build/components/tag-input/scss/index.scss +0 -2
  1251. package/build/components/task-list/index.d.ts +0 -28
  1252. package/build/components/task-list/index.js +0 -107
  1253. package/build/components/task-list/scss/index.scss +0 -2
  1254. package/build/components/tasklist/constants.d.ts +0 -2
  1255. package/build/components/tasklist/constants.js +0 -2
  1256. package/build/components/text-animate/index.d.ts +0 -30
  1257. package/build/components/text-animate/index.js +0 -97
  1258. package/build/components/text-animate/scss/index.scss +0 -2
  1259. package/build/components/text-progress/index.d.ts +0 -13
  1260. package/build/components/text-progress/index.js +0 -114
  1261. package/build/components/text-progress/scss/index.scss +0 -2
  1262. package/build/components/thumbnail/scss/index.scss +0 -2
  1263. package/build/components/toast/manager.d.ts +0 -64
  1264. package/build/components/toast/manager.js +0 -221
  1265. package/build/components/toast/svg/check.svg +0 -1
  1266. package/build/components/toast/svg/chevron.svg +0 -1
  1267. package/build/components/toast/svg/close.svg +0 -1
  1268. package/build/components/toast/svg/copy.svg +0 -1
  1269. package/build/components/toast/svg/info.svg +0 -1
  1270. package/build/components/tooltip/context.d.ts +0 -22
  1271. package/build/components/tooltip/context.js +0 -66
  1272. package/build/components/tooltip/group.d.ts +0 -29
  1273. package/build/components/tooltip/group.js +0 -128
  1274. package/build/components/tooltip/options.d.ts +0 -7
  1275. package/build/components/tooltip/options.js +0 -21
  1276. package/build/components/tree/index.d.ts +0 -28
  1277. package/build/components/tree/index.js +0 -182
  1278. package/build/components/tree/scss/index.scss +0 -2
  1279. package/build/components/tree-view/index.d.ts +0 -25
  1280. package/build/components/tree-view/index.js +0 -205
  1281. package/build/components/tree-view/scss/index.scss +0 -2
  1282. package/build/components/typewriter-retype/index.d.ts +0 -8
  1283. package/build/components/typewriter-retype/index.js +0 -122
  1284. package/build/components/typewriter-retype/scss/index.scss +0 -2
  1285. package/build/components/undo-toast/index.d.ts +0 -30
  1286. package/build/components/undo-toast/index.js +0 -262
  1287. package/build/components/undo-toast/scss/index.scss +0 -2
  1288. package/build/components/value-flash/index.d.ts +0 -12
  1289. package/build/components/value-flash/index.js +0 -106
  1290. package/build/components/value-flash/scss/index.scss +0 -2
  1291. package/build/components/waitlist-join/index.d.ts +0 -34
  1292. package/build/components/waitlist-join/index.js +0 -402
  1293. package/build/components/waitlist-join/scss/index.scss +0 -2
  1294. package/build/components/web-search/brands.d.ts +0 -121
  1295. package/build/components/web-search/brands.js +0 -138
  1296. package/build/components/web-search/index.d.ts +0 -31
  1297. package/build/components/web-search/index.js +0 -245
  1298. package/build/components/web-search/scss/index.scss +0 -2
  1299. package/build/components/word-rotator/index.d.ts +0 -14
  1300. package/build/components/word-rotator/index.js +0 -196
  1301. package/build/components/word-rotator/scss/index.scss +0 -2
  1302. package/build/css-utilities/absolute/scss/index.scss +0 -2
  1303. package/build/css-utilities/disabled/scss/index.scss +0 -2
  1304. package/build/css-utilities/hidden/scss/index.scss +0 -2
  1305. package/build/css-utilities/not-allowed/scss/index.scss +0 -2
  1306. package/build/css-utilities/tabular/scss/index.scss +0 -2
  1307. package/lib.scss +0 -2
  1308. package/src/components/accordion/more.ts +0 -97
  1309. package/src/components/anchor/scss/index.scss +0 -56
  1310. package/src/components/anchor/scss/variables.scss +0 -4
  1311. package/src/components/announcement-banner/index.ts +0 -81
  1312. package/src/components/announcement-banner/scss/index.scss +0 -183
  1313. package/src/components/announcement-banner/scss/variables.scss +0 -18
  1314. package/src/components/autosave/index.ts +0 -113
  1315. package/src/components/autosave/scss/index.scss +0 -155
  1316. package/src/components/autosave/scss/variables.scss +0 -22
  1317. package/src/components/back-to-top/index.ts +0 -293
  1318. package/src/components/back-to-top/scss/index.scss +0 -111
  1319. package/src/components/back-to-top/scss/variables.scss +0 -30
  1320. package/src/components/bento-grid/index.ts +0 -63
  1321. package/src/components/bento-grid/scss/index.scss +0 -175
  1322. package/src/components/bento-grid/scss/variables.scss +0 -19
  1323. package/src/components/bento-grid-spotlight/index.ts +0 -133
  1324. package/src/components/bento-grid-spotlight/scss/index.scss +0 -226
  1325. package/src/components/bento-grid-spotlight/scss/variables.scss +0 -36
  1326. package/src/components/bookmark-button/index.ts +0 -174
  1327. package/src/components/bookmark-button/scss/index.scss +0 -162
  1328. package/src/components/bookmark-button/scss/variables.scss +0 -28
  1329. package/src/components/breadcrumb/ellipsis.ts +0 -17
  1330. package/src/components/breadcrumb/item.ts +0 -10
  1331. package/src/components/breadcrumb/link.ts +0 -21
  1332. package/src/components/breadcrumb/list.ts +0 -10
  1333. package/src/components/breadcrumb/menu.ts +0 -20
  1334. package/src/components/breadcrumb/page.ts +0 -16
  1335. package/src/components/breadcrumb/separator.ts +0 -17
  1336. package/src/components/breadcrumb/svg/caret.svg +0 -1
  1337. package/src/components/breadcrumb/svg/chevron.svg +0 -1
  1338. package/src/components/breadcrumb/svg/more.svg +0 -1
  1339. package/src/components/breadcrumbs/index.ts +0 -479
  1340. package/src/components/breadcrumbs/scss/index.scss +0 -235
  1341. package/src/components/breadcrumbs/scss/variables.scss +0 -30
  1342. package/src/components/button/svg/plus.svg +0 -1
  1343. package/src/components/card-input/index.ts +0 -594
  1344. package/src/components/card-input/scss/index.scss +0 -512
  1345. package/src/components/card-input/scss/variables.scss +0 -29
  1346. package/src/components/carousel-3d/index.ts +0 -405
  1347. package/src/components/carousel-3d/scss/index.scss +0 -155
  1348. package/src/components/carousel-3d/scss/variables.scss +0 -25
  1349. package/src/components/checkbox/svg/check.svg +0 -1
  1350. package/src/components/checkbox-group/index.ts +0 -171
  1351. package/src/components/checkbox-group/scss/index.scss +0 -229
  1352. package/src/components/checkbox-group/scss/variables.scss +0 -28
  1353. package/src/components/code-morph/index.ts +0 -459
  1354. package/src/components/code-morph/scss/index.scss +0 -384
  1355. package/src/components/code-morph/scss/variables.scss +0 -33
  1356. package/src/components/collapsible-sidebar/index.ts +0 -193
  1357. package/src/components/collapsible-sidebar/scss/index.scss +0 -220
  1358. package/src/components/collapsible-sidebar/scss/variables.scss +0 -42
  1359. package/src/components/command/constants.ts +0 -6
  1360. package/src/components/command-palette/index.ts +0 -456
  1361. package/src/components/command-palette/scss/index.scss +0 -235
  1362. package/src/components/command-palette/scss/variables.scss +0 -42
  1363. package/src/components/composer/index.ts +0 -117
  1364. package/src/components/composer/scss/index.scss +0 -105
  1365. package/src/components/composer/scss/variables.scss +0 -82
  1366. package/src/components/composer/svg/arrow-up.svg +0 -1
  1367. package/src/components/contribution-heatmap/index.ts +0 -348
  1368. package/src/components/contribution-heatmap/scss/index.scss +0 -151
  1369. package/src/components/contribution-heatmap/scss/variables.scss +0 -39
  1370. package/src/components/date-range-picker/index.ts +0 -641
  1371. package/src/components/date-range-picker/scss/index.scss +0 -380
  1372. package/src/components/date-range-picker/scss/variables.scss +0 -22
  1373. package/src/components/dynamic-island/index.ts +0 -161
  1374. package/src/components/dynamic-island/scss/index.scss +0 -278
  1375. package/src/components/dynamic-island/scss/variables.scss +0 -39
  1376. package/src/components/email-typo-fix/index.ts +0 -615
  1377. package/src/components/email-typo-fix/scss/index.scss +0 -213
  1378. package/src/components/email-typo-fix/scss/variables.scss +0 -18
  1379. package/src/components/expanding-card/index.ts +0 -377
  1380. package/src/components/expanding-card/scss/index.scss +0 -232
  1381. package/src/components/expanding-card/scss/variables.scss +0 -22
  1382. package/src/components/feature-spotlight/index.ts +0 -437
  1383. package/src/components/feature-spotlight/scss/index.scss +0 -254
  1384. package/src/components/feature-spotlight/scss/variables.scss +0 -36
  1385. package/src/components/file-tree/index.ts +0 -319
  1386. package/src/components/file-tree/scss/index.scss +0 -138
  1387. package/src/components/file-tree/scss/variables.scss +0 -18
  1388. package/src/components/filter-grid/index.ts +0 -344
  1389. package/src/components/filter-grid/scss/index.scss +0 -142
  1390. package/src/components/filter-grid/scss/variables.scss +0 -41
  1391. package/src/components/gradient-text/index.ts +0 -26
  1392. package/src/components/gradient-text/scss/index.scss +0 -20
  1393. package/src/components/gradient-text/scss/variables.scss +0 -6
  1394. package/src/components/header/index.ts +0 -318
  1395. package/src/components/header/scss/index.scss +0 -508
  1396. package/src/components/header/scss/variables.scss +0 -21
  1397. package/src/components/hover-card/index.ts +0 -319
  1398. package/src/components/hover-card/scss/index.scss +0 -117
  1399. package/src/components/hover-card/scss/variables.scss +0 -25
  1400. package/src/components/kanban-board/index.ts +0 -326
  1401. package/src/components/kanban-board/scss/index.scss +0 -126
  1402. package/src/components/kanban-board/scss/variables.scss +0 -39
  1403. package/src/components/lightbox/index.ts +0 -594
  1404. package/src/components/lightbox/scss/index.scss +0 -194
  1405. package/src/components/lightbox/scss/variables.scss +0 -24
  1406. package/src/components/lightbox/spring.ts +0 -118
  1407. package/src/components/line-shadow-text/index.ts +0 -24
  1408. package/src/components/line-shadow-text/scss/index.scss +0 -45
  1409. package/src/components/line-shadow-text/scss/variables.scss +0 -6
  1410. package/src/components/log/index.ts +0 -156
  1411. package/src/components/log/scss/index.scss +0 -269
  1412. package/src/components/log/scss/variables.scss +0 -19
  1413. package/src/components/long-press/bind.ts +0 -159
  1414. package/src/components/long-press/button.ts +0 -46
  1415. package/src/components/long-press/index.ts +0 -6
  1416. package/src/components/long-press/scss/index.scss +0 -60
  1417. package/src/components/long-press/scss/variables.scss +0 -9
  1418. package/src/components/modal/index.ts +0 -91
  1419. package/src/components/modal/scss/index.scss +0 -81
  1420. package/src/components/modal/scss/variables.scss +0 -42
  1421. package/src/components/morphing-button/index.ts +0 -188
  1422. package/src/components/morphing-button/scss/index.scss +0 -154
  1423. package/src/components/morphing-button/scss/variables.scss +0 -21
  1424. package/src/components/morphing-nav/index.ts +0 -496
  1425. package/src/components/morphing-nav/scss/index.scss +0 -284
  1426. package/src/components/morphing-nav/scss/variables.scss +0 -36
  1427. package/src/components/multi-step-form/index.ts +0 -368
  1428. package/src/components/multi-step-form/scss/index.scss +0 -397
  1429. package/src/components/multi-step-form/scss/variables.scss +0 -22
  1430. package/src/components/navigation-menu/index.ts +0 -608
  1431. package/src/components/navigation-menu/scss/index.scss +0 -213
  1432. package/src/components/navigation-menu/scss/variables.scss +0 -24
  1433. package/src/components/nested-menu/index.ts +0 -446
  1434. package/src/components/nested-menu/scss/index.scss +0 -219
  1435. package/src/components/nested-menu/scss/variables.scss +0 -26
  1436. package/src/components/normalize/scss/index.scss +0 -35
  1437. package/src/components/notification-bell/index.ts +0 -102
  1438. package/src/components/notification-bell/scss/index.scss +0 -132
  1439. package/src/components/notification-bell/scss/variables.scss +0 -41
  1440. package/src/components/notification-bell/svg/bell.svg +0 -1
  1441. package/src/components/onboarding-checklist/index.ts +0 -252
  1442. package/src/components/onboarding-checklist/scss/index.scss +0 -414
  1443. package/src/components/onboarding-checklist/scss/variables.scss +0 -17
  1444. package/src/components/page-dots/index.ts +0 -137
  1445. package/src/components/page-dots/scss/index.scss +0 -95
  1446. package/src/components/page-dots/scss/variables.scss +0 -26
  1447. package/src/components/pagination/svg/arrow-left.svg +0 -1
  1448. package/src/components/pagination/svg/arrow-right.svg +0 -1
  1449. package/src/components/password/constants.ts +0 -4
  1450. package/src/components/password/index.ts +0 -97
  1451. package/src/components/password/scss/index.scss +0 -188
  1452. package/src/components/password/scss/variables.scss +0 -50
  1453. package/src/components/plan-card/index.ts +0 -404
  1454. package/src/components/plan-card/scss/index.scss +0 -513
  1455. package/src/components/plan-card/scss/variables.scss +0 -33
  1456. package/src/components/radio-cards/index.ts +0 -145
  1457. package/src/components/radio-cards/scss/index.scss +0 -232
  1458. package/src/components/radio-cards/scss/variables.scss +0 -32
  1459. package/src/components/range-filter/index.ts +0 -295
  1460. package/src/components/range-filter/scss/index.scss +0 -257
  1461. package/src/components/range-filter/scss/variables.scss +0 -20
  1462. package/src/components/range-slider/index.ts +0 -277
  1463. package/src/components/range-slider/scss/index.scss +0 -234
  1464. package/src/components/range-slider/scss/variables.scss +0 -26
  1465. package/src/components/reading-progress/index.ts +0 -160
  1466. package/src/components/reading-progress/scss/index.scss +0 -115
  1467. package/src/components/reading-progress/scss/variables.scss +0 -31
  1468. package/src/components/scroll-fade/index.ts +0 -131
  1469. package/src/components/scroll-fade/scss/index.scss +0 -104
  1470. package/src/components/scroll-fade/scss/variables.scss +0 -10
  1471. package/src/components/scroll-spine/index.ts +0 -355
  1472. package/src/components/scroll-spine/scss/index.scss +0 -209
  1473. package/src/components/scroll-spine/scss/variables.scss +0 -22
  1474. package/src/components/scroll-velocity/index.ts +0 -269
  1475. package/src/components/scroll-velocity/scss/index.scss +0 -29
  1476. package/src/components/scroll-velocity/scss/variables.scss +0 -3
  1477. package/src/components/scrub-input/index.ts +0 -339
  1478. package/src/components/scrub-input/scss/index.scss +0 -105
  1479. package/src/components/scrub-input/scss/variables.scss +0 -23
  1480. package/src/components/select-menu/index.ts +0 -499
  1481. package/src/components/select-menu/scss/index.scss +0 -192
  1482. package/src/components/select-menu/scss/variables.scss +0 -41
  1483. package/src/components/selection-toolbar/index.ts +0 -510
  1484. package/src/components/selection-toolbar/scss/index.scss +0 -221
  1485. package/src/components/selection-toolbar/scss/variables.scss +0 -24
  1486. package/src/components/settings/index.ts +0 -184
  1487. package/src/components/settings/scss/index.scss +0 -327
  1488. package/src/components/settings/scss/variables.scss +0 -50
  1489. package/src/components/settings/svg/close.svg +0 -1
  1490. package/src/components/settings/svg/saved.svg +0 -1
  1491. package/src/components/share-button/index.ts +0 -328
  1492. package/src/components/share-button/scss/index.scss +0 -191
  1493. package/src/components/share-button/scss/variables.scss +0 -24
  1494. package/src/components/sheet/index.ts +0 -170
  1495. package/src/components/sheet/scss/index.scss +0 -65
  1496. package/src/components/sheet/scss/variables.scss +0 -27
  1497. package/src/components/shiny-text/index.ts +0 -19
  1498. package/src/components/shiny-text/scss/index.scss +0 -32
  1499. package/src/components/shiny-text/scss/variables.scss +0 -7
  1500. package/src/components/shortcut-sheet/index.ts +0 -454
  1501. package/src/components/shortcut-sheet/scss/index.scss +0 -306
  1502. package/src/components/shortcut-sheet/scss/variables.scss +0 -36
  1503. package/src/components/sidebar/index.ts +0 -13
  1504. package/src/components/sidebar/scss/index.scss +0 -49
  1505. package/src/components/sidebar/scss/variables.scss +0 -20
  1506. package/src/components/slider/index.ts +0 -232
  1507. package/src/components/slider/scss/index.scss +0 -182
  1508. package/src/components/slider/scss/variables.scss +0 -15
  1509. package/src/components/sliding-tabs/index.ts +0 -291
  1510. package/src/components/sliding-tabs/scss/index.scss +0 -174
  1511. package/src/components/sliding-tabs/scss/variables.scss +0 -34
  1512. package/src/components/snap-carousel/index.ts +0 -324
  1513. package/src/components/snap-carousel/scss/index.scss +0 -174
  1514. package/src/components/snap-carousel/scss/variables.scss +0 -31
  1515. package/src/components/sparkline/index.ts +0 -234
  1516. package/src/components/sparkline/scss/index.scss +0 -169
  1517. package/src/components/sparkline/scss/variables.scss +0 -30
  1518. package/src/components/stacked-drawer/index.ts +0 -272
  1519. package/src/components/stacked-drawer/scss/index.scss +0 -122
  1520. package/src/components/stacked-drawer/scss/variables.scss +0 -20
  1521. package/src/components/stat-counter/index.ts +0 -337
  1522. package/src/components/stat-counter/scss/index.scss +0 -246
  1523. package/src/components/stat-counter/scss/variables.scss +0 -24
  1524. package/src/components/status-picker/index.ts +0 -323
  1525. package/src/components/status-picker/scss/index.scss +0 -290
  1526. package/src/components/status-picker/scss/variables.scss +0 -29
  1527. package/src/components/sticky-stack/index.ts +0 -313
  1528. package/src/components/sticky-stack/scss/index.scss +0 -167
  1529. package/src/components/sticky-stack/scss/variables.scss +0 -50
  1530. package/src/components/story-progress/index.ts +0 -247
  1531. package/src/components/story-progress/scss/index.scss +0 -205
  1532. package/src/components/story-progress/scss/variables.scss +0 -21
  1533. package/src/components/swipe-deck/index.ts +0 -438
  1534. package/src/components/swipe-deck/scss/index.scss +0 -275
  1535. package/src/components/swipe-deck/scss/variables.scss +0 -24
  1536. package/src/components/tabs/scss/index.scss +0 -62
  1537. package/src/components/tabs/scss/variables.scss +0 -4
  1538. package/src/components/tag-input/index.ts +0 -415
  1539. package/src/components/tag-input/scss/index.scss +0 -186
  1540. package/src/components/tag-input/scss/variables.scss +0 -30
  1541. package/src/components/task-list/index.ts +0 -137
  1542. package/src/components/task-list/scss/index.scss +0 -171
  1543. package/src/components/task-list/scss/variables.scss +0 -8
  1544. package/src/components/tasklist/constants.ts +0 -4
  1545. package/src/components/text/scss/variables.scss +0 -9
  1546. package/src/components/text-animate/index.ts +0 -142
  1547. package/src/components/text-animate/scss/index.scss +0 -106
  1548. package/src/components/text-animate/scss/variables.scss +0 -17
  1549. package/src/components/text-progress/index.ts +0 -170
  1550. package/src/components/text-progress/scss/index.scss +0 -148
  1551. package/src/components/text-progress/scss/variables.scss +0 -26
  1552. package/src/components/thumbnail/scss/index.scss +0 -62
  1553. package/src/components/thumbnail/scss/variables.scss +0 -19
  1554. package/src/components/toast/manager.ts +0 -342
  1555. package/src/components/toast/svg/check.svg +0 -1
  1556. package/src/components/toast/svg/chevron.svg +0 -1
  1557. package/src/components/toast/svg/close.svg +0 -1
  1558. package/src/components/toast/svg/copy.svg +0 -1
  1559. package/src/components/toast/svg/error.svg +0 -1
  1560. package/src/components/toast/svg/info.svg +0 -1
  1561. package/src/components/toast/svg/loading.svg +0 -1
  1562. package/src/components/toast/svg/success.svg +0 -1
  1563. package/src/components/toast/svg/warning.svg +0 -1
  1564. package/src/components/tooltip/context.ts +0 -96
  1565. package/src/components/tooltip/group.ts +0 -162
  1566. package/src/components/tooltip/options.ts +0 -33
  1567. package/src/components/tooltip/scss/_group.scss +0 -164
  1568. package/src/components/tree/index.ts +0 -259
  1569. package/src/components/tree/scss/index.scss +0 -105
  1570. package/src/components/tree/scss/variables.scss +0 -48
  1571. package/src/components/tree-view/index.ts +0 -285
  1572. package/src/components/tree-view/scss/index.scss +0 -169
  1573. package/src/components/tree-view/scss/variables.scss +0 -18
  1574. package/src/components/typewriter-retype/index.ts +0 -164
  1575. package/src/components/typewriter-retype/scss/index.scss +0 -142
  1576. package/src/components/typewriter-retype/scss/variables.scss +0 -46
  1577. package/src/components/undo-toast/index.ts +0 -359
  1578. package/src/components/undo-toast/scss/index.scss +0 -216
  1579. package/src/components/undo-toast/scss/variables.scss +0 -20
  1580. package/src/components/value-flash/index.ts +0 -121
  1581. package/src/components/value-flash/scss/index.scss +0 -193
  1582. package/src/components/value-flash/scss/variables.scss +0 -47
  1583. package/src/components/waitlist-join/index.ts +0 -545
  1584. package/src/components/waitlist-join/scss/index.scss +0 -401
  1585. package/src/components/waitlist-join/scss/variables.scss +0 -23
  1586. package/src/components/web-search/brands.ts +0 -155
  1587. package/src/components/web-search/index.ts +0 -316
  1588. package/src/components/web-search/scss/index.scss +0 -270
  1589. package/src/components/web-search/scss/variables.scss +0 -8
  1590. package/src/components/word-rotator/index.ts +0 -296
  1591. package/src/components/word-rotator/scss/index.scss +0 -33
  1592. package/src/components/word-rotator/scss/variables.scss +0 -7
  1593. package/src/css-utilities/absolute/scss/index.scss +0 -36
  1594. package/src/css-utilities/disabled/scss/index.scss +0 -4
  1595. package/src/css-utilities/hidden/scss/index.scss +0 -28
  1596. package/src/css-utilities/not-allowed/scss/index.scss +0 -7
  1597. package/src/css-utilities/tabular/scss/index.scss +0 -3
  1598. package/src/lib/index.scss +0 -7
  1599. package/src/lib/scss/breakpoint.scss +0 -41
  1600. package/src/lib/scss/color.scss +0 -1
  1601. package/src/lib/scss/list.scss +0 -77
  1602. package/src/lib/scss/string.scss +0 -34
  1603. package/src/tokens/index.scss +0 -9
  1604. package/storage/psd/Color Palette.psd +0 -0
  1605. /package/src/{lib → shared}/scss/css-variables.scss +0 -0
  1606. /package/src/{lib → shared}/scss/map.scss +0 -0
  1607. /package/src/{lib → shared}/scss/position.scss +0 -0
  1608. /package/{build/components/notification-bell → storage}/svg/bell.svg +0 -0
  1609. /package/{build/components/checkbox → storage}/svg/check.svg +0 -0
  1610. /package/{build/components/toast/svg/error.svg → storage/svg/circle-alert.svg} +0 -0
  1611. /package/{build/components/toast/svg/success.svg → storage/svg/circle-check.svg} +0 -0
  1612. /package/{build/components/toast/svg/loading.svg → storage/svg/spinner.svg} +0 -0
  1613. /package/{build/components/toast → storage}/svg/warning.svg +0 -0
@@ -0,0 +1,3438 @@
1
+ import { effect, flush, peek, reactive, ReactiveArray, read, signal, untrack, write, type Signal } from '@esportsplus/reactivity';
2
+ import { html, type Attributes, type Renderable } from '@esportsplus/template';
3
+ import { write as writeText } from '~/components/clipboard';
4
+ import highlight from '~/components/highlight';
5
+ import icon from '~/components/icon';
6
+ import tooltip from '~/components/tooltip';
7
+ import fuzzy from '~/shared/fuzzy';
8
+ import chevron from '@esportsplus/ui/svg/chevron-right.svg';
9
+ import symlink from '@esportsplus/ui/svg/corner-down-right.svg';
10
+ import lock from '@esportsplus/ui/svg/lock.svg';
11
+ import Clipboard from './clipboard';
12
+ import segments, { ancestors, caption, holds, lineage, same, SEGMENT, sole, type Segment } from './compact';
13
+ import Decorations, { merge, type Badge, type Decoration, type Status, type Tone } from './decorations';
14
+ import draggable, { type Drag, type Drop } from './drag';
15
+ import Editor, { field, resolve, type Draft, type Kind, type Result } from './edit';
16
+ import filter, { recheck } from './filter';
17
+ import Finder, { type Mode } from './find';
18
+ import glob from './glob';
19
+ import glyph, { renderer } from './glyph';
20
+ import History, { type Entry as HistoryEntry, type Operation, type Options as HistoryOptions, type Place, type Step } from './history';
21
+ import { resolver as createFileTreeIconResolver, resolve as resolveFileTreeIcon, type Name as IconName, type Options as IconOptions, type Resolved as ResolvedIcon } from './icons';
22
+ import { enclosing, flagged, order, seek, type Jump } from './jump';
23
+ import Loader, { placeholder, type Load, type Notice } from './lazy';
24
+ import Elements, { type Change, type Entry } from './model';
25
+ import Selection from './selection';
26
+ import command, { extending, type Command } from './shortcuts';
27
+ import comparator, { type Case, type Options, type Order, type Sort } from './sort';
28
+ import spoken from './spoken';
29
+ import stick from './sticky';
30
+ import type { Export, ImportEntry } from './transfer';
31
+ import '~/components/button/scss/index.scss';
32
+ import './scss/index.scss';
33
+
34
+
35
+ type A = Attributes & {
36
+ // A chain of folders each holding only one folder shows as one row, 'src/main/java', as VS Code's compact
37
+ // folders do; on unless false.
38
+ compact?: boolean;
39
+ // Called once with the tree's commands, for toolbars and shortcuts outside it.
40
+ controller?: (controller: Controller) => void;
41
+ // A name typed into a new item's input. 'a/b.ts' arrives as ['a', 'b.ts'], the folders to create and then the
42
+ // item, under the deepest folder along the path that already exists.
43
+ create?: (parent: Element | null, parts: string[], kind: Kind) => Result;
44
+ // One store per provider, merged by id.
45
+ decorations?: Decorations | Decorations[];
46
+ display?: Display;
47
+ // Rows dragged onto a folder, or onto a file for its folder; the tree reports the drop and moves nothing itself.
48
+ drag?: Drag<Element>;
49
+ editor?: Editor;
50
+ // A store to change the tree live through; a plain array is fixed.
51
+ elements: Element[] | Elements;
52
+ // Shown in place of the rows when there are none, like a message with a button to open a folder.
53
+ empty?: () => Renderable<unknown>;
54
+ // Globs never shown, like VS Code's 'files.exclude': '**/node_modules', 'dist/**', '**/*.{log,tmp}'.
55
+ exclude?: string[];
56
+ // Whether a click on a folder's name opens it, or only a double click does; its chevron always opens on one.
57
+ expand?: 'click' | 'dblclick';
58
+ // Folder ids open on mount; the selected item's folders open as well, unless 'reveal' is off.
59
+ expanded?: string[];
60
+ // What a row dragged out to the desktop or another app leaves there, null for nothing; given, a mouse drags rows
61
+ // the browser's own way, moves within the tree included.
62
+ export?: (element: Element) => Export | null;
63
+ // Ctrl/Cmd+Alt+F opens a find bar over the tree, in this mode until toggled: 'highlight' marks the matches among
64
+ // every row, 'filter' leaves only them and the folders above them, opened while it lasts.
65
+ find?: Mode | 'off';
66
+ // A fuzzy query whose matched characters are marked in each name, like quick open's; a getter keeps them in step.
67
+ highlight?: string | (() => string);
68
+ // Ctrl/Cmd+Z undoes its last entry and Ctrl/Cmd+Shift+Z or Ctrl+Y redoes one; whatever an undo or redo brings
69
+ // back, moves or renames, however it was started, is selected and revealed.
70
+ history?: History;
71
+ // Draws every row's icon in place of the built-in ones; what it returns is drawn as is, nothing for undefined.
72
+ // 'fileTreeIcon' draws the built-in one, for the rows it leaves be.
73
+ icon?: (element: Element, open: boolean) => Renderable<unknown>;
74
+ // Rules mapping names, name fragments, extensions and folders to built-in icons or any sprite, on top of the
75
+ // built-in set; false draws no icons.
76
+ icons?: IconOptions | false;
77
+ // Draws a guide line down each open folder.
78
+ indicator?: Indicator;
79
+ label?: string;
80
+ // Fetches the children of a folder given without any, the first time it opens.
81
+ load?: Load;
82
+ // Right-click, Shift+F10 or the menu key: the caller shows its own menu at 'position'. No elements means the
83
+ // tree's background; 'root' that it opened on a root's header, for commands like removing it from the workspace.
84
+ menu?: (elements: Element[], position: { x: number; y: number }, root: boolean) => void;
85
+ // A file was clicked or entered: the viewer should show it.
86
+ open?: (element: Element, open: Open) => void;
87
+ operations?: Operations;
88
+ // What Shift+Alt+C copies, and Ctrl+Shift+Alt+C as 'relative'; the id by default.
89
+ path?: (element: Element, relative: boolean) => string;
90
+ // Moving the cursor onto a file opens it as a preview once the cursor rests, like JetBrains' autoscroll to source.
91
+ // 'immediate' follows keyboard/typeahead navigation without the resting-cursor delay.
92
+ preview?: boolean | 'immediate';
93
+ // F2 renames the focused item.
94
+ rename?: (element: Element, name: string) => Result;
95
+ // Selection written from outside: 'on' opens the folders down to it and scrolls to it, 'select' opens them
96
+ // without scrolling, 'off' only moves the highlight.
97
+ reveal?: 'off' | 'on' | 'select';
98
+ // The top-level folders are roots, as in a VS Code multi-root workspace: each heads its own tree, in the order
99
+ // given, open unless a snapshot says otherwise. Patterns match paths within each root. The tree never renames,
100
+ // moves or deletes a root; adding and removing them is the store's.
101
+ roots?: boolean;
102
+ // Tints rows by the first scope matching them, or else by their folder's.
103
+ scopes?: Scope[];
104
+ // The query the rows show changed from within the tree, by typing in it, its find bar or Escape; not called for
105
+ // 'Controller.search', so a search field outside can follow it.
106
+ searched?: (query: string) => void;
107
+ select?: (element: Element) => void;
108
+ selected?: string;
109
+ // Alt+N starts a new file and Alt+Shift+N a new folder.
110
+ shortcuts?: boolean;
111
+ // Seeds the open folders and scroll position on mount, in place of 'expanded', and receives every change, so it
112
+ // can be stored and handed back later.
113
+ snapshot?: Snapshot;
114
+ sort?: Sort;
115
+ state?: State;
116
+ // Pins the folders the top rows sit in as the list scrolls, this many deep at most; 'true' is five.
117
+ sticky?: boolean | number;
118
+ // Adds a corner button that opens every folder, or closes them all when any are open.
119
+ toggle?: boolean;
120
+ // Hovering a row shows its full path, with its size and modified date when given.
121
+ tooltip?: boolean;
122
+ // What typing a letter in the tree does: jump to the next name starting with what's typed, or open the find bar
123
+ // with it, as VS Code's 'workbench.list.typeNavigationMode' chooses.
124
+ typing?: 'find' | 'typeahead';
125
+ // Runs once a typed name passes the built-in checks; a message returned blocks the commit and shows under the input.
126
+ validate?: (name: string, parent: Element | null, element: Element | null) => string | void;
127
+ };
128
+
129
+ type Align = 'center' | 'end' | 'start';
130
+
131
+ type Controller = {
132
+ collapseAll: () => void;
133
+ expandAll: () => void;
134
+ // Open the find bar, with 'query' in place of what it last held when given.
135
+ find: (query?: string) => void;
136
+ // Move the cursor to the next or previous file git reports changed, or with errors or warnings, in the order the
137
+ // rows show, wrapping round, and return it; null when there's none. Folders open on the way, and lazy ones load
138
+ // when ids are paths and a decorated id lies inside one.
139
+ next: (kind: Jump) => Promise<Element | null>;
140
+ previous: (kind: Jump) => Promise<Element | null>;
141
+ // Apply a search field's query outside the tree, without opening or focusing the find bar; 'searched' reports
142
+ // what the tree does to it.
143
+ search: (query: string) => void;
144
+ };
145
+
146
+ type Display = {
147
+ // Files git reports deleted are gone from disk, so they're hidden unless asked for, then shown struck through.
148
+ deleted?: boolean;
149
+ // Names starting with a dot; shown unless false.
150
+ dotfiles?: boolean;
151
+ // Files git ignores, dimmed; hidden when false, and shown again as soon as git stops ignoring them.
152
+ ignored?: boolean;
153
+ // Lines added and removed, from each decoration's 'additions' and 'deletions', ahead of the status letter; a
154
+ // folder shows the totals of what's inside it.
155
+ stats?: boolean;
156
+ };
157
+
158
+ type Element = {
159
+ children?: Element[];
160
+ id: string;
161
+ // Read by the 'modified' sort order and the path tooltip.
162
+ modified?: Date | number;
163
+ name: string;
164
+ readonly?: boolean;
165
+ // Shown but inert, like a locked file.
166
+ selectable?: boolean;
167
+ // In bytes.
168
+ size?: number;
169
+ symlink?: boolean;
170
+ type?: 'file' | 'folder';
171
+ };
172
+
173
+ // A row below a folder that folds, where it sat before the list swapped rows; drawn while the edge travels.
174
+ type Ghost = {
175
+ left: number;
176
+ row: Row;
177
+ top: number;
178
+ width: number;
179
+ };
180
+
181
+ // Where guides show: always, only while the pointer is over the tree, or never.
182
+ type Indicator = 'always' | 'hover' | 'never';
183
+
184
+ type Layout = Pick<Row, 'depth' | 'element' | 'gaps' | 'parent' | 'position' | 'scope' | 'segments' | 'size'>;
185
+
186
+ type Mark = {
187
+ // What the row shows and says, flattened, so a refresh writes only when it changed.
188
+ key: string;
189
+ label: string;
190
+ parts: Part[];
191
+ tone: Tone | '';
192
+ };
193
+
194
+ // How a file asked to be opened; the viewer decides what that means for its tabs.
195
+ type Open = {
196
+ // A single click or a resting cursor previews, replacing the last preview; a double or middle click or Enter pins.
197
+ mode: 'pinned' | 'preview';
198
+ // Alt+click or Ctrl+Enter: beside the current file rather than in its place.
199
+ side: boolean;
200
+ };
201
+
202
+ // Reported with the elements they act on; the tree itself never touches a file.
203
+ type Operations = {
204
+ // Asked before a delete; false cancels it.
205
+ confirm?: (elements: Element[], permanent: boolean) => boolean | Promise<boolean>;
206
+ copy?: (elements: Element[]) => void;
207
+ cut?: (elements: Element[]) => void;
208
+ // Delete is meant for the trash, Shift+Delete for good.
209
+ delete?: (elements: Element[], permanent: boolean) => void;
210
+ duplicate?: (elements: Element[]) => void;
211
+ // Files and folders dropped in from outside the browser onto 'target', a folder or null for the top level, every
212
+ // folder walked through; without it such drops are refused.
213
+ import?: (target: Element | null, entries: readonly ImportEntry[]) => void | Promise<void>;
214
+ // Into the focused folder, or the focused file's folder; null is the top level. Cut items stay dimmed until the
215
+ // returned promise settles.
216
+ paste?: (elements: Element[], target: Element | null, cut: boolean) => void | Promise<void>;
217
+ };
218
+
219
+ // Each part of the badge is colored on its own, so a modified file's diff stats read green and red beside its yellow M.
220
+ type Part = {
221
+ color?: string;
222
+ staged?: boolean;
223
+ text: string;
224
+ title?: string;
225
+ tone?: Tone | 'additions' | 'deletions' | 'open' | 'submodule' | 'unsaved';
226
+ };
227
+
228
+ type Rendered = HTMLElement & { [ROW]?: Row };
229
+
230
+ type Row = {
231
+ // Built the first time the folder opens, so a closed folder costs nothing however large.
232
+ children: Row[] | null;
233
+ depth: number;
234
+ element: Element;
235
+ // How many of the row's siblings are hidden, shared by them all; 'position' and 'size' count them in.
236
+ gaps: Signal<number>;
237
+ // Set on a folder folded into a compact row: the row, which is its last folder's. A folded folder is laid out
238
+ // like that row, in its place, and reads as open.
239
+ host?: Row;
240
+ id: string;
241
+ key: number;
242
+ locked: boolean;
243
+ // Set on the row standing in for a lazy folder's children while they load, or after they failed to.
244
+ notice?: Notice;
245
+ open: Signal<boolean> | null;
246
+ parent: Row | null;
247
+ position: number;
248
+ // The tint color, taken from the row's folder when no scope matches the row itself.
249
+ scope: string;
250
+ // Set on a compact row: the folders folded into it, outermost first. 'parent' and 'depth' are the row's on
251
+ // screen, so it sits where the first of them would.
252
+ segments?: Row[];
253
+ size: number;
254
+ };
255
+
256
+ type Scope = {
257
+ color: string;
258
+ // A pattern is tested against the element's path from the tree's root, like 'src/components/index.ts', or from
259
+ // its own root under 'roots'.
260
+ match: RegExp | ((element: Element) => boolean);
261
+ };
262
+
263
+ type Snapshot = {
264
+ expanded?: string[];
265
+ // The viewport's scrollTop, in pixels.
266
+ scroll?: number;
267
+ };
268
+
269
+ type State = {
270
+ // The primary selection: the anchor, and the row the highlight rests on.
271
+ selected: string;
272
+ // Every selected id, primary included; replaced as a whole on each change.
273
+ selection?: ReadonlySet<string>;
274
+ };
275
+
276
+
277
+ // One per unit, made once: a formatter is slow to construct and the tooltip formats a size on every open. Short bytes
278
+ // read '12 byte', so whole bytes are spelled out.
279
+ const BYTES = ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte'].map((unit, i) => new Intl.NumberFormat(undefined, {
280
+ maximumFractionDigits: 1,
281
+ style: 'unit',
282
+ unit,
283
+ unitDisplay: i ? 'short' : 'long'
284
+ }));
285
+
286
+ // Engines cap how many arguments a spread may pass, so very large folders are inserted in slices.
287
+ const CHUNK = 8192;
288
+
289
+ const GUIDES: string[] = [];
290
+
291
+ const LETTERS: Record<Status, string> = {
292
+ added: 'A',
293
+ conflict: '!',
294
+ deleted: 'D',
295
+ ignored: '',
296
+ modified: 'M',
297
+ renamed: 'R',
298
+ untracked: 'U'
299
+ };
300
+
301
+ const PREVIEW: Open = { mode: 'preview', side: false };
302
+
303
+ // Precedence, lowest first: a row shows the highest of its own tone and, for a folder, those of its contents.
304
+ // Ignored stays with the row; a folder of ignored files isn't itself ignored.
305
+ const RANK: Tone[] = ['ignored', 'added', 'modified', 'warning', 'deleted', 'conflict', 'error'];
306
+
307
+ // Long enough that holding an arrow key down opens only the file it stops on.
308
+ const REST = 200;
309
+
310
+ const ROW = Symbol();
311
+
312
+ const TONES: Record<Status, Tone> = {
313
+ added: 'added',
314
+ conflict: 'conflict',
315
+ deleted: 'deleted',
316
+ ignored: 'ignored',
317
+ modified: 'modified',
318
+ renamed: 'added',
319
+ untracked: 'added'
320
+ };
321
+
322
+ // Open delay for the path tooltip, so it stays out of the way of a pointer passing over the tree.
323
+ const TOOLTIP = 600;
324
+
325
+ // Long enough to type "pa" at a normal pace, short enough that a fresh letter a moment later starts a new search.
326
+ const TYPEAHEAD = 500;
327
+
328
+ const dates = new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' });
329
+
330
+
331
+ let uid = 0;
332
+
333
+
334
+ // Problems show in the row's tone alone; the badge carries, in order, the diff stats, the consumer's badges, the
335
+ // git letters (index then working tree, or a folder's dot for what's inside it) and the editor marker. 'rollup' is
336
+ // null for a file.
337
+ function badge(decoration: Decoration | undefined, lines: number[], rollup: Tone | '' | null) {
338
+ let editor = decoration?.editor,
339
+ parts: Part[] = [],
340
+ staged = decoration?.staged,
341
+ status = decoration?.status;
342
+
343
+ if (lines[0]) {
344
+ parts.push({ text: `+${lines[0]}`, tone: 'additions' });
345
+ }
346
+
347
+ if (lines[1]) {
348
+ parts.push({ text: `−${lines[1]}`, tone: 'deletions' });
349
+ }
350
+
351
+ for (let custom of decoration?.badges ?? []) {
352
+ parts.push({ color: custom.color, text: custom.text, title: custom.tooltip });
353
+ }
354
+
355
+ if (rollup === null && staged && LETTERS[staged]) {
356
+ parts.push({ staged: true, text: LETTERS[staged], title: 'Staged', tone: TONES[staged] });
357
+ }
358
+
359
+ if (rollup === null && status && LETTERS[status]) {
360
+ parts.push({ text: LETTERS[status], tone: TONES[status] });
361
+ }
362
+
363
+ if (decoration?.submodule) {
364
+ parts.push({ text: 'S', tone: 'submodule' });
365
+ }
366
+
367
+ if (rollup) {
368
+ parts.push({ text: '●', tone: rollup });
369
+ }
370
+
371
+ if (editor?.unsaved || editor?.open) {
372
+ parts.push({ text: editor.unsaved ? '●' : '○', tone: editor.unsaved ? 'unsaved' : 'open' });
373
+ }
374
+
375
+ return parts;
376
+ }
377
+
378
+ // Steps of 1024, as VS Code reports sizes.
379
+ function bytes(value: number) {
380
+ let unit = 0;
381
+
382
+ while (value >= 1024 && unit < BYTES.length - 1) {
383
+ value /= 1024;
384
+ unit++;
385
+ }
386
+
387
+ return BYTES[unit].format(value);
388
+ }
389
+
390
+ function chip(part: Part) {
391
+ return html`
392
+ <span
393
+ class='file-tree-badge-part ${part.staged && 'file-tree-badge-part--staged'} ${part.tone && `file-tree-badge-part--${part.tone}`}'
394
+ ${{ style: part.color && `color: ${part.color}` }}
395
+ ${!!part.title && { title: part.title }}
396
+ >
397
+ ${part.text}
398
+ </span>
399
+ `;
400
+ }
401
+
402
+ // The name with the characters 'query' matches marked, a run of them to a mark; the bare name when there are none.
403
+ function emphasis(name: string, query: string) {
404
+ let match = query ? fuzzy(query, name) : null;
405
+
406
+ if (!match) {
407
+ return name;
408
+ }
409
+
410
+ let at = 0,
411
+ indices = match.indices,
412
+ out: Renderable<unknown>[] = [];
413
+
414
+ for (let i = 0, n = indices.length; i < n;) {
415
+ let end = indices[i] + 1,
416
+ start = indices[i];
417
+
418
+ while (++i < n && indices[i] === end) {
419
+ end++;
420
+ }
421
+
422
+ if (start > at) {
423
+ out.push(name.slice(at, start));
424
+ }
425
+
426
+ out.push(html`<mark class='file-tree-match'>${name.slice(start, end)}</mark>`);
427
+ at = end;
428
+ }
429
+
430
+ if (at < name.length) {
431
+ out.push(name.slice(at));
432
+ }
433
+
434
+ return out;
435
+ }
436
+
437
+ // A search mark as classes on 'block': every match tinted, the current one outlined as well.
438
+ function found(block: string, mark: string | false) {
439
+ if (!mark) {
440
+ return mark;
441
+ }
442
+
443
+ return mark === 'current' ? `${block}--match ${block}--match-current` : `${block}--match`;
444
+ }
445
+
446
+ function folder(element: Element) {
447
+ return element.type ? element.type === 'folder' : Array.isArray(element.children);
448
+ }
449
+
450
+ // Shadows repeating a row's parent guide under each further ancestor, read by the row's '::before'.
451
+ function guides(depth: number) {
452
+ let out = GUIDES[depth];
453
+
454
+ if (out !== undefined) {
455
+ return out;
456
+ }
457
+
458
+ let parts: string[] = [];
459
+
460
+ for (let i = 1; i < depth; i++) {
461
+ parts.push(`calc(var(--indent) * ${-i} * var(--guide-direction)) 0`);
462
+ }
463
+
464
+ return GUIDES[depth] = parts.join(', ') || 'none';
465
+ }
466
+
467
+ // The rank a row lends its folders: a deleted file is a change inside them, not a loss of them.
468
+ function lift(rank: number) {
469
+ return rank === RANK.indexOf('deleted') ? RANK.indexOf('modified') : rank;
470
+ }
471
+
472
+ // A middle click pins a file rather than starting the browser's autoscroll.
473
+ function middle(event: MouseEvent) {
474
+ if (event.button === 1) {
475
+ event.preventDefault();
476
+ }
477
+ }
478
+
479
+ function path(row: Row) {
480
+ return [...ancestors(row), row].map((node) => node.element.name).join('/');
481
+ }
482
+
483
+ // The folder whose segment of a compact row was pressed, or the row's own.
484
+ function pick(row: Row, event: MouseEvent) {
485
+ return (event.target as HTMLElement).closest<Segment<Row>>('.file-tree-segment')?.[SEGMENT] ?? row;
486
+ }
487
+
488
+ function place(row: Row) {
489
+ let out: number[] = [];
490
+
491
+ for (let node: Row | null = row; node; node = node.parent) {
492
+ out.unshift(node.position);
493
+ }
494
+
495
+ return out;
496
+ }
497
+
498
+ function rank(decoration: Decoration | undefined) {
499
+ if (!decoration) {
500
+ return -1;
501
+ }
502
+
503
+ if (decoration.errors) {
504
+ return RANK.indexOf('error');
505
+ }
506
+
507
+ // The working tree says what's on disk now; the index speaks only when the working tree is clean.
508
+ let value = decoration.status ?? decoration.staged,
509
+ status = value ? RANK.indexOf(TONES[value]) : -1;
510
+
511
+ return decoration.warnings ? Math.max(status, RANK.indexOf('warning')) : status;
512
+ }
513
+
514
+ // The row a reader still sees once the folders above 'row' close: its outermost closed ancestor, or itself.
515
+ function shown(row: Row) {
516
+ let target = row;
517
+
518
+ for (let node = row.parent; node; node = node.parent) {
519
+ if (!peek(node.open!)) {
520
+ target = node;
521
+ }
522
+ }
523
+
524
+ return target;
525
+ }
526
+
527
+ // The folders to open so 'id' is on screen: its ancestors, and itself when it's a folder a click could open.
528
+ function trail(index: Map<string, Entry>, id: string) {
529
+ let entry = index.get(id),
530
+ out: string[] = [];
531
+
532
+ if (!entry) {
533
+ return out;
534
+ }
535
+
536
+ if (folder(entry.element) && entry.element.selectable !== false) {
537
+ out.push(id);
538
+ }
539
+
540
+ for (let parent = entry.parent; parent !== null; parent = index.get(parent)!.parent) {
541
+ out.push(parent);
542
+ }
543
+
544
+ return out;
545
+ }
546
+
547
+ function twistie(event: MouseEvent) {
548
+ return (event.target as HTMLElement).closest('.file-tree-twistie') !== null;
549
+ }
550
+
551
+
552
+ export default ({
553
+ compact = true,
554
+ controller,
555
+ create,
556
+ decorations: providers,
557
+ display = {},
558
+ drag,
559
+ editor,
560
+ elements,
561
+ empty,
562
+ exclude = [],
563
+ expand: unfold = 'click',
564
+ expanded = [],
565
+ export: exporter,
566
+ find = 'highlight',
567
+ highlight: phrase = '',
568
+ history,
569
+ icon: draw,
570
+ icons = {},
571
+ indicator = 'always',
572
+ label = 'Files',
573
+ load,
574
+ menu,
575
+ open: view,
576
+ operations,
577
+ path: address = (element) => element.id,
578
+ preview,
579
+ rename,
580
+ reveal: autoreveal = 'on',
581
+ roots = false,
582
+ scopes = [],
583
+ searched,
584
+ select,
585
+ selected,
586
+ shortcuts,
587
+ snapshot,
588
+ sort = 'folders',
589
+ state = reactive({ selected: selected ?? '', selection: new Set<string>() }),
590
+ sticky = true,
591
+ toggle,
592
+ tooltip: hint = true,
593
+ typing = 'typeahead',
594
+ validate,
595
+ ...attributes
596
+ }: A) => {
597
+ let built = new Map<string, Row>(),
598
+ // Whatever the tree reads while it's built is read untracked: built inside a caller's computation, it would
599
+ // otherwise rebuild the tree on every selection or display change.
600
+ chosen = untrack(() => state.selected),
601
+ clipboard = new Clipboard<Element>(),
602
+ compare = comparator(sort, folder),
603
+ // Descendant tones per folder, one count per rank, so a change walks its ancestors instead of the tree.
604
+ counts = new Map<string, number[]>(),
605
+ // The primary selection as rows read it: each asks about its own id alone, so a change re-renders the row it
606
+ // leaves and the one it reaches rather than every row. Kept in step with 'state.selected' while connected.
607
+ current = signal(chosen),
608
+ decorations = providers && merge([providers].flat()),
609
+ // Lines added and removed per shown row; 'totals' sums them per folder, kept like 'counts'.
610
+ diffs = new Map<string, number[]>(),
611
+ // The open name input, if any; a new item's row lives only in 'rows', never among its folder's children.
612
+ draft = signal<Draft<Row> | null>(null),
613
+ excluded = glob(exclude),
614
+ model = elements instanceof Elements ? elements : new Elements(elements),
615
+ filtered = untrack(() => filter(model.elements, display.dotfiles !== false, excluded, roots)),
616
+ ghosts = new ReactiveArray<Ghost>(),
617
+ hidden = untrack(() => new Set([...filtered, ...(decorations?.keys() ?? [])].filter(gone))),
618
+ id = `file-tree-${++uid}`,
619
+ index = model.index,
620
+ initial = new Set([
621
+ ...(snapshot?.expanded ?? expanded),
622
+ ...(roots && !snapshot?.expanded ? model.elements.map((element) => element.id) : []),
623
+ ...(autoreveal === 'off' ? [] : trail(index, chosen))
624
+ ]),
625
+ key = 0,
626
+ // The primary selection last acted on, so one written while disconnected is revealed on connect.
627
+ known = chosen,
628
+ loader = load ? new Loader(load, loaded) : null,
629
+ marks = new Map<string, Signal<Mark>>(),
630
+ // The row under each empty root saying so, by root id; kept so the list finds the same row every time.
631
+ notes = new Map<string, Row>(),
632
+ opened = 0,
633
+ own = new Map<string, number>(),
634
+ // Per sibling list, how many of its rows are hidden before each place, so a row finds its place in "3 of 5"
635
+ // without walking every row before it; 'at' is the 'shifts' it was counted at.
636
+ places = new WeakMap<Row[], { at: number; before: Int32Array }>(),
637
+ // What 'highlight' asks the names to mark; a getter given for it writes this while connected.
638
+ given = signal(typeof phrase === 'function' ? untrack(phrase) : phrase),
639
+ // The search the rows show, empty while the find bar is closed.
640
+ query = signal(''),
641
+ remap = icons ? icons.remap ?? {} : {},
642
+ render = draw ?? (icons ? renderer(icons) : () => false),
643
+ // The rows a folder is opening onto, by place within it; emptied when the motion settles, so rows scrolled
644
+ // back into view later arrive as they are.
645
+ revealing = new Map<Row, number>(),
646
+ search = find === 'off' ? null : new Finder(find, query, {
647
+ compare,
648
+ // A compact row's selected segment is where the cursor is.
649
+ cursor: () => cursor && segment(cursor).id,
650
+ elements: model.elements,
651
+ folder,
652
+ go: (id) => reveal(id, true),
653
+ gone,
654
+ lazy: !!load,
655
+ leave: () => viewport?.focus({ preventScroll: true }),
656
+ searched,
657
+ shows: (id) => {
658
+ let row = built.get(id);
659
+
660
+ return !!row && !hidden.has(id) && shown(row) === row;
661
+ },
662
+ sift: (folders) => {
663
+ sift(folders);
664
+ slot.flush();
665
+ }
666
+ }),
667
+ // The store's version this tree last caught up with.
668
+ seen = model.version,
669
+ // The display flags last applied, so flags changed while disconnected are applied on connect.
670
+ settings = untrack(modes),
671
+ // Bumped whenever a row is hidden or shown, so the places counted before are counted again.
672
+ shifts = 0,
673
+ // A folder kept out of its compact row while a name input is open in it or on it.
674
+ split: string | null = null,
675
+ // Where a fold motion's layer sits over the viewport, and the folder's bottom edge within it.
676
+ stage = reactive({ edge: 0, height: 0, left: 0, top: 0, width: 0 }),
677
+ // The key of the row a fold motion runs from; 0 while none runs.
678
+ sweep = signal(0),
679
+ top = build(model.elements, 0, null),
680
+ totals = new Map<string, number[]>(),
681
+ // The folders filtering has reached, and whether it opened them, so ending it closes those alone.
682
+ unfolded = new Map<string, boolean>(),
683
+ // Filled before the slot exists: rows inserted at the top of a live slot read as arriving above the reader.
684
+ rows = reactive(visible(top)),
685
+ cursor: Row | null = rows.find((row) => holds(row, (id) => id === chosen)) ?? rows[0] ?? null,
686
+ dragging = (drag || exporter || operations?.import) && draggable<Row>({ drag, export: exporter, import: operations?.import }, {
687
+ // Pressing a selected row drags the whole selection, as in VS Code; any other row goes alone. Roots stay, and
688
+ // a folder selected along with one folded above it in a compact row travels inside it.
689
+ grab: (row) => (selection.has(row.id) ? [...selection.ids].map((id) => built.get(id)) : [row])
690
+ .filter((row): row is Row => row !== undefined && !header(row) && !ancestors(row).some((node) => selection.has(node.id) && !header(node))),
691
+ host: (row) => row.host ?? row,
692
+ // Down through each open folder's last shown row, rather than building the whole box to read its end.
693
+ last: (row) => {
694
+ let out = row;
695
+
696
+ while (out.open && peek(out.open)) {
697
+ let list = branch(out),
698
+ next: Row | undefined;
699
+
700
+ for (let i = list.length - 1; i >= 0; i--) {
701
+ if (!hidden.has(list[i].id)) {
702
+ next = list[i];
703
+ break;
704
+ }
705
+ }
706
+
707
+ if (!next) {
708
+ // Nothing shown inside, so only a new item's input or an empty root's note can follow.
709
+ let inner = visible(list);
710
+
711
+ return inner[inner.length - 1] ?? out;
712
+ }
713
+
714
+ out = next;
715
+ }
716
+
717
+ return out;
718
+ },
719
+ open: (row) => fold(row, true),
720
+ row: (element) => (element as Segment<Row>)[SEGMENT] ?? (element as Rendered)[ROW],
721
+ top: !roots,
722
+ viewport: () => viewport
723
+ }),
724
+ // The key of the cursor's row, read per row like 'current'; 0 with no rows.
725
+ focused = signal(cursor?.key ?? 0),
726
+ // An id the tree itself just made primary: the reveal an outside write gets would pull focus onto it.
727
+ quiet: string | null = null,
728
+ // One tooltip for the whole tree, gliding from row to row; rows come and go as they scroll, so it's bound to
729
+ // the viewport rather than to each row.
730
+ tip = tooltip.shared({ delay: { open: TOOLTIP }, direction: 'e' }),
731
+ typed = '',
732
+ typedAt = 0,
733
+ // 'motion' is a fold motion's direction.
734
+ ui = reactive({ any: opened > 0, motion: '' as '' | 'close' | 'open', motionRows: 0 }),
735
+ selection = new Selection((ids) => {
736
+ state.selection = ids;
737
+ }),
738
+ slot = html.virtual(rows, (row) => {
739
+ if (row.notice) {
740
+ return placeholder(row.notice, {
741
+ 'aria-level': String(row.depth + 1),
742
+ class: [
743
+ () => signal.selector(focused, row.key) && 'file-tree-row--focused',
744
+ () => revealing.has(row) && ui.motion === 'open' && 'file-tree-row--reveal'
745
+ ],
746
+ id: `${id}-${row.key}`,
747
+ onclick: () => {
748
+ focus(row);
749
+ retry(row);
750
+ },
751
+ style: `--depth: ${row.depth}; --guides: ${guides(row.depth)}; --reveal-index: ${revealing.get(row) ?? 0};`
752
+ }, dragging?.row(row) ?? {}, onscreen(row));
753
+ }
754
+
755
+ let mark = decorations ? track(row.id) : null,
756
+ open = row.open;
757
+
758
+ return html`
759
+ <div
760
+ aria-level='${row.depth + 1}'
761
+ class='file-tree-row ${row.locked && '--disabled'} ${header(row) && 'file-tree-row--root'} ${() => active(row) && '--active'} ${() => holds(row, (id) => clipboard.marked.read(id)) && 'file-tree-row--cut'} ${() => holds(row, (id) => selection.read(id)) && !active(row) && 'file-tree-row--selected'}'
762
+ id='${id}-${row.key}'
763
+ role='treeitem'
764
+ style='--depth: ${row.depth}; --guides: ${guides(row.depth)}; --reveal-index: ${revealing.get(row) ?? 0};'
765
+ ${row.locked && { 'aria-disabled': 'true' }}
766
+ ${open && { 'aria-expanded': () => read(open) ? 'true' : 'false' }}
767
+ ${mark && { class: () => read(mark).tone && `file-tree-row--${read(mark).tone}` }}
768
+ ${search && { class: () => found('file-tree-row', matched(row)) }}
769
+ ${!!row.scope && { class: 'file-tree-row--scope', style: `--scope: ${row.scope}` }}
770
+ ${dragging?.row(row)}
771
+ ${onscreen(row)}
772
+ ${{
773
+ 'aria-label': mark ? () => read(mark).label : spoken({ ...row.element, name: caption(row), root: header(row) }),
774
+ 'aria-posinset': () => position(row),
775
+ 'aria-selected': () => holds(row, (id) => selection.read(id)) ? 'true' : 'false',
776
+ 'aria-setsize': () => row.size - read(row.gaps),
777
+ // Each tests its own row first, so only the rows concerned follow the cursor and the motion.
778
+ class: [
779
+ () => signal.selector(focused, row.key) && 'file-tree-row--focused',
780
+ () => signal.selector(sweep, row.key) && ui.motion === 'close' && 'file-tree-row--motion',
781
+ () => revealing.has(row) && ui.motion === 'open' && 'file-tree-row--reveal'
782
+ ],
783
+ onauxclick: (event: MouseEvent) => press(row, event),
784
+ onclick: (event: MouseEvent) => press(row, event),
785
+ ondblclick: (event: MouseEvent) => press(row, event)
786
+ }}
787
+ >
788
+ ${contents(row, mark, false)}
789
+ </div>
790
+ `;
791
+ }),
792
+ // Copies of the pinned folders' rows; the tree's own stay in the list beneath, the highlight with them. The
793
+ // highlight draws under the stack, so a copy shows its own hover and selection.
794
+ pins = stick(rows, sticky, (row) => {
795
+ let mark = decorations ? track(row.id) : null;
796
+
797
+ return html`
798
+ <div
799
+ aria-expanded='true'
800
+ class='file-tree-row file-tree-row--pinned ${row.locked && '--disabled'} ${header(row) && 'file-tree-row--root'} ${() => active(row) && 'file-tree-row--selected'}'
801
+ style='--depth: ${row.depth}; --guides: ${guides(row.depth)};'
802
+ ${mark && { class: () => read(mark).tone && `file-tree-row--${read(mark).tone}` }}
803
+ ${{
804
+ class: () => signal.selector(focused, row.key) && 'file-tree-row--focused',
805
+ onclick: () => unpin(row)
806
+ }}
807
+ >
808
+ ${contents(row, mark, true)}
809
+ </div>
810
+ `;
811
+ }, height),
812
+ anchor: Row | null = null,
813
+ detach: VoidFunction | undefined,
814
+ forget: VoidFunction | undefined,
815
+ // The frame a fold motion starts on; 0 while none runs.
816
+ motion = 0,
817
+ root: HTMLElement | undefined,
818
+ timer: ReturnType<typeof setTimeout> | undefined,
819
+ // The marks a batch of decorations reached, refreshed once each as it ends; null outside one.
820
+ touched: Set<string> | null = null,
821
+ unsubscribe: VoidFunction | undefined,
822
+ unwatch: VoidFunction | undefined,
823
+ viewport: HTMLElement | undefined;
824
+
825
+ selection.replace([...(untrack(() => state.selection) ?? []), ...(chosen ? [chosen] : [])]);
826
+ persist();
827
+
828
+ // The tooltip's content: the full path, which also shows a name cut short in its row, then size and date. Built
829
+ // only once the tooltip opens, since the pointer crossing a row's parts asks for it again and again.
830
+ function about(row: Row) {
831
+ return () => {
832
+ let element = row.element,
833
+ full = path(row),
834
+ meta: string[] = [];
835
+
836
+ if (element.size !== undefined) {
837
+ meta.push(bytes(element.size));
838
+ }
839
+
840
+ if (element.modified !== undefined) {
841
+ meta.push(dates.format(element.modified));
842
+ }
843
+
844
+ return html`
845
+ <span class='file-tree-tooltip-path'>${full.slice(0, full.length - element.name.length)}<strong>${element.name}</strong></span>
846
+ ${meta.length > 0 && html`<span class='file-tree-tooltip-meta'>${meta.join(' · ')}</span>`}
847
+ `;
848
+ };
849
+ }
850
+
851
+ controller?.({
852
+ collapseAll: () => all(false),
853
+ expandAll: () => all(true),
854
+ find: (text) => search?.open(text),
855
+ next: (kind) => jump(kind, 1),
856
+ previous: (kind) => jump(kind, -1),
857
+ search: (text) => search?.set(text)
858
+ });
859
+
860
+ // A folder given 'toggle' false is only selected. 'subject' is what's selected: in a compact row, the folder of
861
+ // the segment pressed, which opening and closing the row leaves be.
862
+ function activate(row: Row, open: Open, toggle = true, subject = segment(row)) {
863
+ if (row.notice) {
864
+ retry(row);
865
+ return;
866
+ }
867
+
868
+ if (row.locked) {
869
+ return;
870
+ }
871
+
872
+ clearTimeout(timer);
873
+ anchor = row;
874
+ selection.replace([subject.id]);
875
+ state.selected = subject.id;
876
+ select?.(subject.element);
877
+
878
+ if (!row.open) {
879
+ view?.(row.element, open);
880
+ }
881
+ else if (toggle) {
882
+ fold(row, !peek(row.open));
883
+ }
884
+ }
885
+
886
+ // Selected itself, or through one of the folders folded into it.
887
+ function active(row: Row) {
888
+ return holds(row, (id) => signal.selector(current, id));
889
+ }
890
+
891
+ // Opens every folder a click could open, or closes them all; within 'scope' and its folders alone when given.
892
+ function all(value: boolean, scope?: Row) {
893
+ let at = scope ? rows.indexOf(scope) : -1;
894
+
895
+ if (scope && (!scope.open || scope.locked || at === -1)) {
896
+ return;
897
+ }
898
+
899
+ settle();
900
+
901
+ let count = scope ? (peek(scope.open!) ? visible(branch(scope)).length : 0) : rows.length,
902
+ stack = scope ? [scope] : [...top];
903
+
904
+ while (stack.length) {
905
+ let row = stack.pop()!;
906
+
907
+ if (!row.open) {
908
+ continue;
909
+ }
910
+
911
+ // Locked folders stay shut, matching how a click on them does nothing. An empty root opens onto its note.
912
+ let open = value && !row.locked && (header(row) || !!row.element.children?.length);
913
+
914
+ if (peek(row.open) !== open) {
915
+ write(row.open, open);
916
+ opened += open ? 1 : -1;
917
+ }
918
+
919
+ if (!open && loader?.forget(row.id)) {
920
+ row.children = null;
921
+ }
922
+
923
+ // Closing never builds a folder that was never opened.
924
+ let children = open ? branch(row) : (row.children ?? []);
925
+
926
+ for (let i = 0, n = children.length; i < n; i++) {
927
+ stack.push(children[i]);
928
+ }
929
+ }
930
+
931
+ // Replaced in place; clearing first would make everything after read as inserted above the reader.
932
+ swap(at + 1, at + 1 + count, scope ? (peek(scope.open!) ? visible(branch(scope)) : []) : visible(top));
933
+ prune();
934
+ ui.any = opened > 0;
935
+
936
+ if (cursor) {
937
+ focus(shown(cursor));
938
+ }
939
+
940
+ persist();
941
+ }
942
+
943
+ // Opens a name input on the target, undefined meaning the focused row: to rename it, or for a new item inside it
944
+ // when it's a folder and beside it otherwise; null puts a new item at the top level.
945
+ function begin(action: Kind | 'rename', target?: string | null) {
946
+ close(false);
947
+
948
+ if (target) {
949
+ reveal(target, true);
950
+ }
951
+
952
+ let row = target === null ? null : target === undefined ? cursor && segment(cursor) : built.get(target);
953
+
954
+ if (row === undefined) {
955
+ return;
956
+ }
957
+
958
+ // A folder in the middle of a compact row leaves it for the edit, so the input and a new item's row sit
959
+ // under a row of its own; renaming a compact row's last folder edits its last segment in place.
960
+ if (row?.host) {
961
+ row = separate(row);
962
+ }
963
+
964
+ if (action === 'rename') {
965
+ if (!rename || !row || row.locked || header(row)) {
966
+ return;
967
+ }
968
+
969
+ write(draft, {
970
+ busy: signal(false),
971
+ element: row.element,
972
+ from: row,
973
+ kind: folder(row.element) ? 'folder' : 'file',
974
+ message: signal(''),
975
+ parent: row.parent,
976
+ range: null,
977
+ row,
978
+ value: row.element.name
979
+ });
980
+ move(rows.indexOf(row), 'end');
981
+ return;
982
+ }
983
+
984
+ if (!create) {
985
+ return;
986
+ }
987
+
988
+ // A file, or a folder a click can't open, takes the new item beside it. Roots hold the top level, so one
989
+ // asked for there lands in the first.
990
+ let parent = row?.open && !row.locked ? row : (row?.parent ?? (roots ? top[0] ?? null : null)),
991
+ stub: Row = {
992
+ children: null,
993
+ depth: parent ? parent.depth + 1 : 0,
994
+ element: { id: `${id}-draft`, name: '', type: action },
995
+ gaps: signal(0),
996
+ id: `${id}-draft`,
997
+ key: ++key,
998
+ locked: false,
999
+ open: action === 'folder' ? signal(false) : null,
1000
+ parent,
1001
+ position: 1,
1002
+ scope: parent?.scope ?? '',
1003
+ size: (parent ? branch(parent) : top).length + 1
1004
+ };
1005
+
1006
+ if (roots && !parent) {
1007
+ return;
1008
+ }
1009
+
1010
+ write(draft, {
1011
+ busy: signal(false),
1012
+ element: null,
1013
+ from: cursor,
1014
+ kind: action,
1015
+ message: signal(''),
1016
+ parent,
1017
+ range: null,
1018
+ row: stub,
1019
+ value: ''
1020
+ });
1021
+
1022
+ // Opening the folder lists the stub along with its rows.
1023
+ if (parent && !peek(parent.open!)) {
1024
+ expand(parent, true);
1025
+ }
1026
+ else {
1027
+ rows.splice(parent ? rows.indexOf(parent) + 1 : 0, 0, stub);
1028
+ }
1029
+
1030
+ move(rows.indexOf(stub), 'end');
1031
+ }
1032
+
1033
+ // The note under an open root holding nothing; made again when the root's row is.
1034
+ function blank(root: Row) {
1035
+ let row = notes.get(root.id);
1036
+
1037
+ if (!row || row.parent !== root) {
1038
+ notes.set(root.id, row = notice(root, { type: 'empty' }));
1039
+ }
1040
+
1041
+ return row;
1042
+ }
1043
+
1044
+ // A folder given without children, when there's a loader, has a notice for them until they arrive.
1045
+ function branch(row: Row) {
1046
+ return row.children ??= loader && !row.element.children
1047
+ ? [notice(row, loader.request(row.element))]
1048
+ : build(row.element.children ?? [], row.depth + 1, row);
1049
+ }
1050
+
1051
+ function build(elements: Element[], depth: number, parent: Row | null) {
1052
+ let arranged = compare && !(roots && !parent) ? [...elements].sort(compare) : elements,
1053
+ gaps = group(arranged, parent),
1054
+ n = arranged.length,
1055
+ out: Row[] = new Array(n),
1056
+ // Paths run from within each root under 'roots', as exclude patterns match; a root has none of its own.
1057
+ prefix = scopes.length && parent ? `${path(parent)}/` : '',
1058
+ unseen = 0;
1059
+
1060
+ if (roots) {
1061
+ prefix = prefix.slice(prefix.indexOf('/') + 1);
1062
+ }
1063
+
1064
+ for (let i = 0; i < n; i++) {
1065
+ let element = arranged[i],
1066
+ full = roots && !parent ? '' : prefix + element.name,
1067
+ merged = false,
1068
+ segments: Row[] = [],
1069
+ tint = scopes.length ? scope(element, full, parent?.scope ?? '') : '';
1070
+
1071
+ if (hidden.has(element.id)) {
1072
+ unseen++;
1073
+ }
1074
+
1075
+ // A folder holding just one folder shares its row with it, and so on down the chain; the row is the last
1076
+ // folder's, in the first one's place.
1077
+ for (let next = joined(element); next; next = joined(element)) {
1078
+ let previous = built.get(element.id);
1079
+
1080
+ merged ||= !!previous?.open && !previous.host && peek(previous.open);
1081
+ segments.push(lay({ depth, element, gaps, parent, position: i + 1, scope: tint, segments: undefined, size: n }, true));
1082
+ element = next;
1083
+ full = `${full}/${element.name}`;
1084
+ tint = scopes.length ? scope(element, full, tint) : '';
1085
+ }
1086
+
1087
+ let fresh = !built.has(element.id),
1088
+ row = out[i] = lay({
1089
+ depth,
1090
+ element,
1091
+ gaps,
1092
+ parent,
1093
+ position: i + 1,
1094
+ scope: tint,
1095
+ segments: segments.length ? segments : undefined,
1096
+ size: n
1097
+ }, false);
1098
+
1099
+ for (let j = 0, m = segments.length; j < m; j++) {
1100
+ segments[j].host = row;
1101
+ }
1102
+
1103
+ // An open folder whose children just arrived as one folder, as a lazy folder's can, would otherwise close
1104
+ // under the reader as it merges into that folder's row.
1105
+ if (merged && fresh && !peek(row.open!)) {
1106
+ write(row.open!, true);
1107
+ opened++;
1108
+ }
1109
+ }
1110
+
1111
+ write(gaps, unseen);
1112
+
1113
+ return out;
1114
+ }
1115
+
1116
+ // A row a rebuild found again. Showing the same element at the same depth, in the same group and tint, with the
1117
+ // same folders folded into it, it's kept and its rendered DOM with it, its place updated through the group's
1118
+ // count. Otherwise it's copied under a new key to render afresh, keeping its open state, and its folder rebuilds
1119
+ // at the new depth when next shown.
1120
+ function carry(row: Row, layout: Layout) {
1121
+ let element = layout.element;
1122
+
1123
+ if (row.element === element && row.depth === layout.depth && row.gaps === layout.gaps && row.scope === layout.scope && same(row.segments, layout.segments)) {
1124
+ row.parent = layout.parent;
1125
+ row.position = layout.position;
1126
+ row.segments = layout.segments;
1127
+ row.size = layout.size;
1128
+
1129
+ return row;
1130
+ }
1131
+
1132
+ let next: Row = {
1133
+ ...row,
1134
+ ...layout,
1135
+ children: null,
1136
+ key: ++key,
1137
+ locked: element.selectable === false
1138
+ };
1139
+
1140
+ built.set(row.id, next);
1141
+ retarget(row, next);
1142
+
1143
+ return next;
1144
+ }
1145
+
1146
+ function change(value: string) {
1147
+ let edit = peek(draft)!;
1148
+
1149
+ edit.value = value;
1150
+ write(edit.message, inspect(edit).message);
1151
+ }
1152
+
1153
+ // Leaves the name input without committing; 'refocus' hands focus back to the tree, as when a key closed it.
1154
+ function close(refocus: boolean) {
1155
+ let edit = peek(draft);
1156
+
1157
+ if (!edit) {
1158
+ return;
1159
+ }
1160
+
1161
+ write(draft, null);
1162
+
1163
+ if (!edit.element) {
1164
+ let at = rows.indexOf(edit.row);
1165
+
1166
+ if (at !== -1) {
1167
+ rows.splice(at, 1);
1168
+ }
1169
+ }
1170
+
1171
+ let back = edit.from ? rows.indexOf(edit.from) : -1;
1172
+
1173
+ move(back === -1 ? 0 : back, 'end');
1174
+
1175
+ if (split) {
1176
+ let rejoin = split;
1177
+
1178
+ split = null;
1179
+ update([rejoin]);
1180
+ }
1181
+
1182
+ if (refocus) {
1183
+ viewport?.focus({ preventScroll: true });
1184
+ }
1185
+ }
1186
+
1187
+ // The callback settles before the input closes; one that refuses, or fails, leaves it open to try again.
1188
+ function commit(refocus: boolean) {
1189
+ let edit = peek(draft);
1190
+
1191
+ if (!edit || peek(edit.busy)) {
1192
+ return;
1193
+ }
1194
+
1195
+ let element = edit.element;
1196
+
1197
+ if (element && edit.value === element.name) {
1198
+ close(refocus);
1199
+ return;
1200
+ }
1201
+
1202
+ let { message, parent, parts } = inspect(edit);
1203
+
1204
+ if (message) {
1205
+ write(edit.message, message);
1206
+ return;
1207
+ }
1208
+
1209
+ write(edit.busy, true);
1210
+
1211
+ Promise.resolve()
1212
+ .then(() => element ? rename!(element, edit.value) : create!(parent, parts, edit.kind))
1213
+ .then(
1214
+ (accepted) => {
1215
+ if (peek(draft) !== edit) {
1216
+ return;
1217
+ }
1218
+
1219
+ write(edit.busy, false);
1220
+
1221
+ if (accepted !== false) {
1222
+ close(refocus);
1223
+ }
1224
+ },
1225
+ (error) => {
1226
+ if (peek(draft) !== edit) {
1227
+ return;
1228
+ }
1229
+
1230
+ write(edit.busy, false);
1231
+ write(edit.message, error instanceof Error ? error.message : String(error));
1232
+ }
1233
+ );
1234
+ }
1235
+
1236
+ function conceal(row: Row) {
1237
+ let at = rows.indexOf(row);
1238
+
1239
+ if (at === -1) {
1240
+ return;
1241
+ }
1242
+
1243
+ rows.splice(at, 1 + (row.open && peek(row.open) ? visible(branch(row)).length : 0));
1244
+ prune();
1245
+
1246
+ if (cursor && rows.indexOf(cursor) === -1 && rows.length) {
1247
+ focus(rows[Math.min(at, rows.length - 1)]);
1248
+ }
1249
+ }
1250
+
1251
+ // A pinned copy keeps its name; the input for a rename lives on the row itself.
1252
+ function contents(row: Row, mark: Signal<Mark> | null, pinned: boolean) {
1253
+ let element = row.element,
1254
+ open = row.open;
1255
+
1256
+ return html`
1257
+ <span aria-hidden='true' class='file-tree-twistie'>
1258
+ ${open && icon({ class: 'file-tree-chevron' }, remap.chevron ?? chevron)}
1259
+ </span>
1260
+ ${() => !header(row) && render(element, open !== null && read(open))}
1261
+ ${() => {
1262
+ let edit = read(draft);
1263
+
1264
+ if (pinned || edit?.row !== row) {
1265
+ return row.segments
1266
+ ? segments(row, (node) => [
1267
+ {
1268
+ class: [
1269
+ () => node !== row && signal.selector(current, node.id) && '--active',
1270
+ search && (() => found('file-tree-segment', search.mark(node.id)))
1271
+ ]
1272
+ },
1273
+ dragging?.segment(node) ?? {}
1274
+ ], (node) => () => emphasis(node.element.name, read(query) || read(given)))
1275
+ : html`<span class='file-tree-name'>${() => emphasis(element.name, read(query) || read(given))}</span>`;
1276
+ }
1277
+
1278
+ return html`
1279
+ ${row.segments && html`<span class='file-tree-name'>${row.segments.map((node) => `${node.element.name}/`).join('')}</span>`}
1280
+ ${field(edit, id, {
1281
+ blur: leave,
1282
+ cancel: () => close(true),
1283
+ input: change,
1284
+ submit: () => commit(true)
1285
+ })}
1286
+ `;
1287
+ }}
1288
+ ${element.symlink && icon({ 'aria-hidden': 'true', class: 'file-tree-marker' }, remap.symlink ?? symlink)}
1289
+ ${element.readonly && icon({ 'aria-hidden': 'true', class: 'file-tree-marker' }, remap.lock ?? lock)}
1290
+ ${mark && html`
1291
+ <span aria-hidden='true' class='file-tree-badge'>
1292
+ ${() => read(mark).parts.map(chip)}
1293
+ </span>
1294
+ `}
1295
+ `;
1296
+ }
1297
+
1298
+ // A full `git status` can reach thousands of ids under the same few folders, so each mark is refreshed once at
1299
+ // the end, and the rows hidden or shown are swapped in one go.
1300
+ function decorate(ids: Iterable<string>) {
1301
+ let outer = touched === null,
1302
+ toggled: string[] = [];
1303
+
1304
+ touched ??= new Set();
1305
+
1306
+ for (let id of ids) {
1307
+ let hide = unseen(id),
1308
+ parent = index.get(id)?.parent ?? null,
1309
+ // A hidden row marks nothing, its folders included; a deleted file is hidden only for being gone from
1310
+ // disk, and is still a change to its folders, unless it's excluded as well. A row a search filters out
1311
+ // is only out of view.
1312
+ silent = gone(id) && (filtered.has(id) || !deleted(id)),
1313
+ after = silent ? -1 : rank(decorations?.get(id)),
1314
+ before = own.get(id) ?? -1;
1315
+
1316
+ if (hide !== hidden.has(id)) {
1317
+ obscure(id, hide);
1318
+ toggled.push(id);
1319
+ }
1320
+
1321
+ if (after !== before) {
1322
+ if (after === -1) {
1323
+ own.delete(id);
1324
+ }
1325
+ else {
1326
+ own.set(id, after);
1327
+ }
1328
+
1329
+ let from = lift(before),
1330
+ to = lift(after);
1331
+
1332
+ if (from !== to) {
1333
+ tally(parent, from, undefined, -1);
1334
+ tally(parent, to, undefined, 1);
1335
+ }
1336
+ }
1337
+
1338
+ let decoration = silent ? undefined : decorations?.get(id),
1339
+ lines = [decoration?.additions ?? 0, decoration?.deletions ?? 0],
1340
+ previous = diffs.get(id),
1341
+ added = lines[0] - (previous?.[0] ?? 0),
1342
+ removed = lines[1] - (previous?.[1] ?? 0);
1343
+
1344
+ if (added || removed) {
1345
+ if (lines[0] || lines[1]) {
1346
+ diffs.set(id, lines);
1347
+ }
1348
+ else {
1349
+ diffs.delete(id);
1350
+ }
1351
+
1352
+ tally(parent, 0, [added, removed], 1);
1353
+ }
1354
+
1355
+ refresh(id);
1356
+ }
1357
+
1358
+ // One row goes or comes back on its own, unless its chain or its folder's joined or split.
1359
+ if (toggled.length === 1) {
1360
+ let id = toggled[0],
1361
+ groups = refold(id),
1362
+ row = built.get(id);
1363
+
1364
+ if (groups.length) {
1365
+ update(groups);
1366
+ }
1367
+ else if (row && hidden.has(id)) {
1368
+ conceal(row);
1369
+ }
1370
+ else if (row) {
1371
+ restore(row);
1372
+ }
1373
+ }
1374
+ else if (toggled.length) {
1375
+ reshow(toggled);
1376
+ }
1377
+
1378
+ if (outer) {
1379
+ let marked = touched;
1380
+
1381
+ touched = null;
1382
+
1383
+ for (let id of marked) {
1384
+ refresh(id);
1385
+ }
1386
+ }
1387
+ }
1388
+
1389
+ function deleted(id: string) {
1390
+ let decoration = decorations?.get(id);
1391
+
1392
+ return (decoration?.status ?? decoration?.staged) === 'deleted';
1393
+ }
1394
+
1395
+ // The rows below 'element' that are on screen, measured where they sit now, to stand in for rows the list is about
1396
+ // to swap out; places the motion layer over the viewport.
1397
+ function copy(element: HTMLElement, limit: number, container: HTMLElement, scroller: HTMLElement) {
1398
+ let edge = element.getBoundingClientRect().bottom,
1399
+ frame = container.getBoundingClientRect(),
1400
+ out: Ghost[] = [],
1401
+ view = scroller.getBoundingClientRect(),
1402
+ left = view.left + scroller.clientLeft,
1403
+ top = view.top + scroller.clientTop,
1404
+ bottom = top + scroller.clientHeight;
1405
+
1406
+ stage.edge = edge - top;
1407
+ stage.height = scroller.clientHeight;
1408
+ stage.left = left - frame.left - container.clientLeft;
1409
+ stage.top = top - frame.top - container.clientTop;
1410
+ stage.width = scroller.clientWidth;
1411
+
1412
+ for (let i = 0, node = element.nextElementSibling as Rendered | null; i < limit && node?.classList.contains('file-tree-row'); i++, node = node.nextElementSibling as Rendered | null) {
1413
+ let rect = node.getBoundingClientRect(),
1414
+ row = node[ROW];
1415
+
1416
+ if (rect.top >= bottom) {
1417
+ break;
1418
+ }
1419
+
1420
+ if (row) {
1421
+ out.push({ left: rect.left - left, row, top: rect.top - edge, width: rect.width });
1422
+ }
1423
+ }
1424
+
1425
+ return out;
1426
+ }
1427
+
1428
+ // Where a paste lands: the focused folder, or the folder holding the focused file; null for the top level.
1429
+ function destination(row: Row) {
1430
+ return row.open ? row.element : (row.parent?.element ?? null);
1431
+ }
1432
+
1433
+ async function discard(elements: Element[], permanent: boolean) {
1434
+ if (!elements.length || (operations?.confirm && !(await operations.confirm(elements, permanent)))) {
1435
+ return;
1436
+ }
1437
+
1438
+ operations?.delete?.(elements, permanent);
1439
+ }
1440
+
1441
+ function expand(row: Row, value: boolean, inner?: Row[]) {
1442
+ if (!row.open || peek(row.open) === value) {
1443
+ return;
1444
+ }
1445
+
1446
+ settle();
1447
+
1448
+ let at = rows.indexOf(row);
1449
+
1450
+ if (value) {
1451
+ write(row.open, true);
1452
+ opened++;
1453
+
1454
+ if (at !== -1) {
1455
+ insert(at + 1, inner ?? visible(branch(row)));
1456
+ }
1457
+ }
1458
+ else {
1459
+ if (at !== -1) {
1460
+ rows.splice(at + 1, (inner ?? visible(branch(row))).length);
1461
+ }
1462
+
1463
+ write(row.open, false);
1464
+ opened--;
1465
+ prune();
1466
+
1467
+ if (loader?.forget(row.id)) {
1468
+ row.children = null;
1469
+ }
1470
+
1471
+ if (cursor) {
1472
+ focus(shown(cursor));
1473
+ }
1474
+ }
1475
+
1476
+ ui.any = opened > 0;
1477
+ persist();
1478
+ }
1479
+
1480
+ // Ctrl+click and Ctrl+Space add a row to the selection or take it out; it becomes the anchor either way.
1481
+ function flip(row: Row) {
1482
+ if (row.locked) {
1483
+ return;
1484
+ }
1485
+
1486
+ anchor = row;
1487
+
1488
+ if (!selection.has(row.id)) {
1489
+ selection.replace([...selection.ids, row.id]);
1490
+ primary(row.id);
1491
+ // The primary it replaces may sit in a closed folder, kept only while it was primary.
1492
+ prune();
1493
+ return;
1494
+ }
1495
+
1496
+ let rest = [...selection.ids].filter((id) => id !== row.id);
1497
+
1498
+ selection.replace(rest);
1499
+
1500
+ if (state.selected === row.id) {
1501
+ primary(rest[rest.length - 1] ?? '');
1502
+ }
1503
+ }
1504
+
1505
+ // Opens or closes a folder the way the tree view does: an edge sweeps over its rows while the rows below ride on
1506
+ // it. The list swaps rows at once, so copies stand in for rows no longer rendered: the folder's own on the way
1507
+ // closed, and on the way open whichever rows below were pushed out of the rendered window.
1508
+ function fold(row: Row, value: boolean) {
1509
+ if (!row.open || peek(row.open) === value) {
1510
+ return;
1511
+ }
1512
+
1513
+ settle();
1514
+
1515
+ let container = root,
1516
+ element = node(row),
1517
+ inner = visible(branch(row)),
1518
+ scroller = viewport;
1519
+
1520
+ if (!container || !element || !inner.length || !scroller) {
1521
+ expand(row, value);
1522
+ return;
1523
+ }
1524
+
1525
+ if (value) {
1526
+ for (let i = 0, n = inner.length; i < n; i++) {
1527
+ revealing.set(inner[i], i);
1528
+ }
1529
+ }
1530
+
1531
+ let measured = copy(element, value ? Infinity : inner.length, container, scroller);
1532
+
1533
+ expand(row, value, inner);
1534
+
1535
+ // Started once the list has rendered the swapped rows, ahead of their first paint.
1536
+ motion = requestAnimationFrame(() => {
1537
+ let out: Ghost[] = [];
1538
+
1539
+ // A row still rendered rides the edge itself, so the highlight on it moves with it.
1540
+ for (let i = 0, n = measured.length; i < n; i++) {
1541
+ let current = lookup(measured[i].row.id);
1542
+
1543
+ if (!current || !node(current)) {
1544
+ out.push(measured[i]);
1545
+ }
1546
+ }
1547
+
1548
+ ghosts.push(...out);
1549
+ write(sweep, row.key);
1550
+ ui.motion = value ? 'open' : 'close';
1551
+ ui.motionRows = inner.length;
1552
+ });
1553
+ }
1554
+
1555
+ function focus(row: Row) {
1556
+ cursor = row;
1557
+ write(focused, row.key);
1558
+ }
1559
+
1560
+ function follow(row: Row) {
1561
+ clearTimeout(timer);
1562
+
1563
+ if (preview && !row.open && !row.locked) {
1564
+ if (preview === 'immediate') {
1565
+ activate(row, PREVIEW);
1566
+ }
1567
+ else {
1568
+ timer = setTimeout(() => activate(row, PREVIEW), REST);
1569
+ }
1570
+ }
1571
+ }
1572
+
1573
+ // Drawn like the row it stands in for, its marks kept live; laid out by its measured box, so the depth margin
1574
+ // would count twice.
1575
+ function ghost({ left, row, top, width }: Ghost) {
1576
+ let style = `--depth: ${row.depth}; --guides: ${guides(row.depth)}; left: ${left}px; margin: 0; position: absolute; top: ${top}px; width: ${width}px;`;
1577
+
1578
+ if (row.notice) {
1579
+ return placeholder(row.notice, { style });
1580
+ }
1581
+
1582
+ let mark = decorations ? track(row.id) : null,
1583
+ open = row.open;
1584
+
1585
+ return html`
1586
+ <div
1587
+ class='file-tree-row ${row.locked && '--disabled'} ${header(row) && 'file-tree-row--root'} ${() => active(row) && '--active'} ${() => holds(row, (id) => clipboard.marked.read(id)) && 'file-tree-row--cut'} ${() => holds(row, (id) => selection.read(id)) && !active(row) && 'file-tree-row--selected'}'
1588
+ style='${style}'
1589
+ ${open && { 'aria-expanded': () => read(open) ? 'true' : 'false' }}
1590
+ ${mark && { class: () => read(mark).tone && `file-tree-row--${read(mark).tone}` }}
1591
+ ${search && { class: () => found('file-tree-row', matched(row)) }}
1592
+ ${!!row.scope && { class: 'file-tree-row--scope', style: `--scope: ${row.scope}` }}
1593
+ ${{ class: () => signal.selector(focused, row.key) && 'file-tree-row--focused' }}
1594
+ >
1595
+ ${contents(row, mark, true)}
1596
+ </div>
1597
+ `;
1598
+ }
1599
+
1600
+ function gone(id: string) {
1601
+ return filtered.has(id) || (deleted(id) && !display.deleted) || (display.ignored === false && decorations?.get(id)?.status === 'ignored');
1602
+ }
1603
+
1604
+ // The sibling group's shared count of hidden rows, kept across rebuilds so the rows already rendered go on reading
1605
+ // the one being written. Every write notifies, even of the same count, since a rebuild also moves kept rows to new
1606
+ // places the template reads alongside it.
1607
+ function group(elements: Element[], parent: Row | null) {
1608
+ let owner = parent?.id ?? null;
1609
+
1610
+ for (let i = 0, n = elements.length; i < n; i++) {
1611
+ let row = built.get(elements[i].id);
1612
+
1613
+ if (row && (row.parent?.id ?? null) === owner) {
1614
+ return row.gaps;
1615
+ }
1616
+ }
1617
+
1618
+ return signal(0, () => false);
1619
+ }
1620
+
1621
+ // A root's own row, heading its tree.
1622
+ function header(row: Row) {
1623
+ return roots && row.parent === null;
1624
+ }
1625
+
1626
+ // Every row is the same height, so any row on screen measures them all.
1627
+ function height() {
1628
+ return viewport?.querySelector<HTMLElement>('.file-tree-row')?.offsetHeight ?? 0;
1629
+ }
1630
+
1631
+ // Whether the path tooltip tells more than the row shows: a size or date, the folders above it, or a name cut
1632
+ // short. A root-level name shown in full would only be repeated.
1633
+ function informative(row: Row, target: HTMLElement) {
1634
+ let element = row.element,
1635
+ name = target.querySelector<HTMLElement>('.file-tree-name');
1636
+
1637
+ if (element.size !== undefined || element.modified !== undefined || !name) {
1638
+ return true;
1639
+ }
1640
+
1641
+ return name.scrollWidth > name.clientWidth || path(row) !== name.textContent?.trim();
1642
+ }
1643
+
1644
+ function insert(at: number, items: Row[]) {
1645
+ for (let i = 0, n = items.length; i < n; i += CHUNK) {
1646
+ rows.splice(at + i, 0, ...items.slice(i, i + CHUNK));
1647
+ }
1648
+ }
1649
+
1650
+ function inspect(edit: Draft<Row>) {
1651
+ let parent = edit.parent?.element ?? null,
1652
+ result = resolve(edit.value, parent, edit.element, siblings, folder);
1653
+
1654
+ if (!result.message && validate) {
1655
+ result.message = validate(edit.value, parent, edit.element) || '';
1656
+ }
1657
+
1658
+ return result;
1659
+ }
1660
+
1661
+ // The folder 'element' shares its row with, when compacting. A hidden folder has no row to share, the one split
1662
+ // out for a name input keeps its own, and a root heads its tree alone, though a chain may start below it.
1663
+ function joined(element: Element) {
1664
+ if (!compact || element.id === split || hidden.has(element.id) || !folder(element) || (roots && index.get(element.id)?.parent === null)) {
1665
+ return null;
1666
+ }
1667
+
1668
+ return sole(element, hidden, folder);
1669
+ }
1670
+
1671
+ // Moves the cursor to the next or previous file 'kind' marks, in tree order, opening the folders down to it.
1672
+ async function jump(kind: Jump, step: 1 | -1) {
1673
+ if (!decorations) {
1674
+ return null;
1675
+ }
1676
+
1677
+ if (loader) {
1678
+ await uncover(kind);
1679
+ }
1680
+
1681
+ let found: { place: number[]; row: Row }[] = [];
1682
+
1683
+ for (let id of decorations.keys()) {
1684
+ let entry = index.get(id);
1685
+
1686
+ if (!entry || folder(entry.element) || hidden.has(id) || !flagged(decorations.get(id), kind)) {
1687
+ continue;
1688
+ }
1689
+
1690
+ let row = locate(id)!;
1691
+
1692
+ found.push({ place: place(row), row });
1693
+ }
1694
+
1695
+ found.sort((a, b) => order(a.place, b.place));
1696
+
1697
+ let at = seek(found.map((item) => item.place), cursor ? place(cursor) : null, step);
1698
+
1699
+ if (at === -1) {
1700
+ return null;
1701
+ }
1702
+
1703
+ let target = found[at].row;
1704
+
1705
+ reveal(target.id, true);
1706
+ follow(target);
1707
+
1708
+ return target.element;
1709
+ }
1710
+
1711
+ // The row for 'layout', the one built before for its element when there is one. A folder folded into a compact
1712
+ // row reads as open but counts among the open folders only while it has a row of its own; folding in or out, its
1713
+ // children, built for where it stood, rebuild when it next shows them.
1714
+ function lay(layout: Layout, folded: boolean) {
1715
+ let element = layout.element,
1716
+ previous = built.get(element.id);
1717
+
1718
+ if (!previous) {
1719
+ let open = folder(element) ? folded || initial.has(element.id) : null,
1720
+ row: Row = {
1721
+ ...layout,
1722
+ children: null,
1723
+ id: element.id,
1724
+ key: ++key,
1725
+ locked: element.selectable === false,
1726
+ open: open === null ? null : signal(open)
1727
+ };
1728
+
1729
+ if (open && !folded) {
1730
+ opened++;
1731
+ }
1732
+
1733
+ built.set(element.id, row);
1734
+
1735
+ return row;
1736
+ }
1737
+
1738
+ let was = !!previous.host,
1739
+ row = carry(previous, layout);
1740
+
1741
+ // Set again by the build that folds it.
1742
+ row.host = undefined;
1743
+
1744
+ if (was !== folded) {
1745
+ row.children = null;
1746
+
1747
+ // Unfolded, it counts only while open: a search ending shuts one it opened, folded or not.
1748
+ if (!folded) {
1749
+ opened += peek(row.open!) ? 1 : 0;
1750
+ }
1751
+ else if (peek(row.open!)) {
1752
+ opened--;
1753
+ }
1754
+ else {
1755
+ write(row.open!, true);
1756
+ }
1757
+ }
1758
+
1759
+ // A compact row's spoken name reads its folders' names, which the store may have just changed.
1760
+ if (row !== previous) {
1761
+ refresh(element.id);
1762
+ }
1763
+
1764
+ return row;
1765
+ }
1766
+
1767
+ // Clicking away commits a good name and drops a bad one, as VS Code does.
1768
+ function leave() {
1769
+ let edit = peek(draft);
1770
+
1771
+ if (!edit || peek(edit.busy)) {
1772
+ return;
1773
+ }
1774
+
1775
+ if (peek(edit.message) || inspect(edit).message) {
1776
+ close(false);
1777
+ }
1778
+ else {
1779
+ commit(false);
1780
+ }
1781
+ }
1782
+
1783
+ // Loaded children join the store, reaching every tree showing it; a failure shows on this tree alone. A folder
1784
+ // removed meanwhile drops them, and one another tree already filled keeps what it has.
1785
+ function loaded(id: string, children: Element[] | null) {
1786
+ let element = model.get(id);
1787
+
1788
+ if (!element) {
1789
+ return;
1790
+ }
1791
+
1792
+ if (children && !element.children) {
1793
+ model.add(children, id);
1794
+ }
1795
+ else {
1796
+ update([id]);
1797
+ }
1798
+ }
1799
+
1800
+ // The row for 'id', building the folders above it without opening them.
1801
+ function locate(id: string) {
1802
+ let chain: string[] = [];
1803
+
1804
+ for (let node = index.get(id)?.parent ?? null; node !== null; node = index.get(node)!.parent) {
1805
+ chain.push(node);
1806
+ }
1807
+
1808
+ // A folder folded into a compact row lists nothing itself; the row's last folder lists what it shows.
1809
+ for (let i = chain.length - 1; i >= 0; i--) {
1810
+ let row = built.get(chain[i])!;
1811
+
1812
+ if (!row.host) {
1813
+ branch(row);
1814
+ }
1815
+ }
1816
+
1817
+ let row = built.get(id);
1818
+
1819
+ return row?.host ?? row;
1820
+ }
1821
+
1822
+ function look(id: string): Mark {
1823
+ let entry = index.get(id),
1824
+ inside = -1,
1825
+ list = counts.get(id);
1826
+
1827
+ if (list) {
1828
+ for (let i = list.length - 1; i > 0; i--) {
1829
+ if (list[i]) {
1830
+ inside = i;
1831
+ break;
1832
+ }
1833
+ }
1834
+ }
1835
+
1836
+ let decoration = decorations?.get(id),
1837
+ highest = Math.max(own.get(id) ?? -1, inside),
1838
+ mine = diffs.get(id),
1839
+ total = totals.get(id),
1840
+ lines = display.stats ? [(mine?.[0] ?? 0) + (total?.[0] ?? 0), (mine?.[1] ?? 0) + (total?.[1] ?? 0)] : [0, 0],
1841
+ row = built.get(id),
1842
+ subject = entry?.element ?? { name: id },
1843
+ label = spoken(
1844
+ { ...subject, name: row?.segments ? caption(row) : subject.name, root: roots && entry?.parent === null },
1845
+ decoration,
1846
+ lines,
1847
+ inside > 0 ? RANK[inside] : undefined
1848
+ ),
1849
+ parts = badge(decoration, lines, entry && folder(entry.element) ? (highest > 0 ? RANK[highest] : '') : null),
1850
+ tone: Mark['tone'] = highest === -1 ? '' : RANK[highest];
1851
+
1852
+ return { key: JSON.stringify([label, parts]), label, parts, tone };
1853
+ }
1854
+
1855
+ // A notice row isn't among the built rows; a drag over one aims at its folder.
1856
+ function lookup(id: string) {
1857
+ return built.get(id) ?? rows.find((row) => row.notice && row.id === id);
1858
+ }
1859
+
1860
+ // The search's mark for a row, from any of its folders: the current match wherever it sits in a compact row.
1861
+ function matched(row: Row) {
1862
+ let out: string | false = false;
1863
+
1864
+ for (let node of lineage(row)) {
1865
+ let mark = search!.mark(node.id);
1866
+
1867
+ if (mark === 'current') {
1868
+ return mark;
1869
+ }
1870
+
1871
+ out ||= mark;
1872
+ }
1873
+
1874
+ return out;
1875
+ }
1876
+
1877
+ function modes() {
1878
+ return [display.deleted, display.dotfiles, display.ignored, display.stats].join();
1879
+ }
1880
+
1881
+ function move(index: number, align: Align) {
1882
+ let row = rows[index];
1883
+
1884
+ if (!row || !viewport) {
1885
+ return;
1886
+ }
1887
+
1888
+ focus(row);
1889
+
1890
+ let element = node(row);
1891
+
1892
+ // Outside the rendered window; the slot scrolls it in and renders it straight away. Aligned to the top, it
1893
+ // starts the view at the rows its pinned folders will cover, one each.
1894
+ if (!element) {
1895
+ slot.scrollTo(align === 'start' ? index - pins.cover(row) : index, align);
1896
+ return;
1897
+ }
1898
+
1899
+ let r = element.getBoundingClientRect(),
1900
+ v = viewport.getBoundingClientRect(),
1901
+ top = v.top + pins.cover(row) * r.height;
1902
+
1903
+ if (r.top < top) {
1904
+ viewport.scrollTop -= top - r.top;
1905
+ }
1906
+ else if (r.bottom > v.bottom) {
1907
+ viewport.scrollTop += r.bottom - v.bottom;
1908
+ }
1909
+ }
1910
+
1911
+ function notice(parent: Row, value: Notice): Row {
1912
+ let at = ++key,
1913
+ self = `${id}-${at}`;
1914
+
1915
+ return {
1916
+ children: null,
1917
+ depth: parent.depth + 1,
1918
+ // Nameless, so type-ahead passes over it.
1919
+ element: { id: self, name: '' },
1920
+ gaps: signal(0),
1921
+ id: self,
1922
+ key: at,
1923
+ locked: true,
1924
+ notice: value,
1925
+ open: null,
1926
+ parent,
1927
+ position: 1,
1928
+ scope: parent.scope,
1929
+ size: 1
1930
+ };
1931
+ }
1932
+
1933
+ // A row's element while it is rendered; the rest are virtualized away. Found by id, so a row rendered by a flush
1934
+ // earlier in this task is found before its onconnect has run.
1935
+ function node(row: Row) {
1936
+ return document.getElementById(`${id}-${row.key}`);
1937
+ }
1938
+
1939
+ // Every row hidden or shown goes through here: its group's count moves ahead of any rebuild, which counts the
1940
+ // group afresh, and the places counted from what was hidden are counted again.
1941
+ function obscure(id: string, value: boolean) {
1942
+ let row = built.get(id);
1943
+
1944
+ if (value) {
1945
+ hidden.add(id);
1946
+ }
1947
+ else {
1948
+ hidden.delete(id);
1949
+ }
1950
+
1951
+ shifts++;
1952
+
1953
+ if (row) {
1954
+ write(row.gaps, peek(row.gaps) + (value ? 1 : -1));
1955
+ }
1956
+ }
1957
+
1958
+ function onscreen(row: Row): Attributes {
1959
+ return {
1960
+ onconnect: (element: Rendered) => {
1961
+ element[ROW] = row;
1962
+ }
1963
+ };
1964
+ }
1965
+
1966
+ // The row 'element' draws, among the built ones: notices stand in for rows and pinned copies draw none.
1967
+ function owner(element: Rendered | null) {
1968
+ let row = element?.[ROW];
1969
+
1970
+ return row && !row.notice ? row : null;
1971
+ }
1972
+
1973
+ function page() {
1974
+ let size = height();
1975
+
1976
+ return size && viewport ? Math.max(1, Math.floor(viewport.clientHeight / size)) : 1;
1977
+ }
1978
+
1979
+ // False when the tree has nothing to do with the command, leaving the key to the page.
1980
+ function perform(name: Command, row: Row) {
1981
+ switch (name) {
1982
+ case 'all': {
1983
+ let ids: string[] = [];
1984
+
1985
+ for (let i = 0, n = rows.length; i < n; i++) {
1986
+ if (!rows[i].locked) {
1987
+ ids.push(rows[i].id);
1988
+ }
1989
+ }
1990
+
1991
+ selection.replace(ids);
1992
+
1993
+ if (!selection.has(state.selected) && !row.locked) {
1994
+ primary(row.id);
1995
+ }
1996
+
1997
+ return true;
1998
+ }
1999
+ case 'clear': {
2000
+ // Down to the focused row, or the primary when the focused row can't be selected. With nothing to
2001
+ // clear, Escape is left to whatever holds the tree, like a dialog closing.
2002
+ let cut = clipboard.cancel(),
2003
+ lead = row.locked ? built.get(state.selected) : row;
2004
+
2005
+ if (!cut && selection.ids.size < 2) {
2006
+ return false;
2007
+ }
2008
+
2009
+ selection.replace(lead ? [lead.id] : []);
2010
+
2011
+ if (lead) {
2012
+ anchor = lead;
2013
+ primary(lead.id);
2014
+ }
2015
+
2016
+ return true;
2017
+ }
2018
+ case 'copy':
2019
+ case 'cut': {
2020
+ let elements = targets(row, true);
2021
+
2022
+ if (!operations || !elements.length) {
2023
+ return false;
2024
+ }
2025
+
2026
+ clipboard.hold(elements, name === 'cut');
2027
+ operations[name]?.(elements);
2028
+ return true;
2029
+ }
2030
+ case 'delete':
2031
+ case 'trash':
2032
+ if (!operations?.delete) {
2033
+ return false;
2034
+ }
2035
+
2036
+ void discard(targets(row, true), name === 'delete');
2037
+ return true;
2038
+ case 'duplicate': {
2039
+ let elements = targets(row, true);
2040
+
2041
+ if (!operations?.duplicate || !elements.length) {
2042
+ return false;
2043
+ }
2044
+
2045
+ operations.duplicate(elements);
2046
+ return true;
2047
+ }
2048
+ case 'paste': {
2049
+ let paste = operations?.paste,
2050
+ target = destination(segment(row));
2051
+
2052
+ if (!paste) {
2053
+ return false;
2054
+ }
2055
+
2056
+ void clipboard.paste((elements, cut) => paste(elements, target, cut));
2057
+ return true;
2058
+ }
2059
+ case 'path':
2060
+ case 'relative': {
2061
+ let elements = targets(row, false);
2062
+
2063
+ if (!elements.length) {
2064
+ return false;
2065
+ }
2066
+
2067
+ void writeText(elements.map((element) => address(element, name === 'relative')).join('\n'));
2068
+ return true;
2069
+ }
2070
+ case 'redo':
2071
+ case 'undo':
2072
+ if (!history || !(name === 'undo' ? history.canUndo : history.canRedo)) {
2073
+ return false;
2074
+ }
2075
+
2076
+ void history[name]();
2077
+ return true;
2078
+ case 'toggle':
2079
+ flip(row);
2080
+ return true;
2081
+ }
2082
+ }
2083
+
2084
+ // The folders open here, and those still to open once they're shown or loaded.
2085
+ function persist() {
2086
+ if (!snapshot) {
2087
+ return;
2088
+ }
2089
+
2090
+ let out: string[] = [];
2091
+
2092
+ for (let [id, row] of built) {
2093
+ if (row.open && peek(row.open) && !unfolded.get(id)) {
2094
+ out.push(id);
2095
+ }
2096
+ }
2097
+
2098
+ for (let id of initial) {
2099
+ if (!built.has(id) && (loader || index.has(id))) {
2100
+ out.push(id);
2101
+ }
2102
+ }
2103
+
2104
+ snapshot.expanded = out;
2105
+ }
2106
+
2107
+ // Counted among the siblings still shown, so hidden rows leave no hole in "3 of 5".
2108
+ function position(row: Row) {
2109
+ // A row still rendered as its folder folds into a compact row has no list left; it's on its way out.
2110
+ let siblings = row.parent ? row.parent.children : top;
2111
+
2112
+ if (!read(row.gaps) || !siblings) {
2113
+ return row.position;
2114
+ }
2115
+
2116
+ let counted = places.get(siblings);
2117
+
2118
+ if (!counted || counted.at !== shifts) {
2119
+ let before = new Int32Array(siblings.length + 1);
2120
+
2121
+ for (let i = 0, n = siblings.length; i < n; i++) {
2122
+ before[i + 1] = before[i] + +hidden.has(siblings[i].id);
2123
+ }
2124
+
2125
+ places.set(siblings, counted = { at: shifts, before });
2126
+ }
2127
+
2128
+ return row.position - counted.before[row.position - 1];
2129
+ }
2130
+
2131
+ // A click previews a file and a double or middle click pins it, beside the current one with Alt. Alt+click opens
2132
+ // or closes a folder with everything in it. Shift+click selects a range and Ctrl/Cmd+click toggles one row.
2133
+ function press(row: Row, event: MouseEvent) {
2134
+ let from = cursor,
2135
+ subject = pick(row, event),
2136
+ type = event.type;
2137
+
2138
+ // Right clicks belong to the context menu.
2139
+ if (type === 'auxclick' && event.button !== 1) {
2140
+ return;
2141
+ }
2142
+
2143
+ focus(row);
2144
+
2145
+ if (type === 'click' && event.shiftKey) {
2146
+ span(from ?? row, row);
2147
+ return;
2148
+ }
2149
+
2150
+ if (type === 'click' && (event.ctrlKey || event.metaKey)) {
2151
+ flip(subject);
2152
+ return;
2153
+ }
2154
+
2155
+ if (!row.open) {
2156
+ activate(row, { mode: type === 'click' ? 'preview' : 'pinned', side: event.altKey });
2157
+ return;
2158
+ }
2159
+
2160
+ // Whether a single click opens it; a double click does whenever that doesn't.
2161
+ let single = unfold === 'click' || twistie(event);
2162
+
2163
+ if (type === 'click' && event.altKey) {
2164
+ activate(row, PREVIEW, false, subject);
2165
+ all(!peek(row.open), row);
2166
+ }
2167
+ else if (type === 'click') {
2168
+ activate(row, PREVIEW, single, subject);
2169
+ }
2170
+ else if (type === 'dblclick' && !single && !event.altKey && !row.locked) {
2171
+ fold(row, !peek(row.open));
2172
+ }
2173
+ }
2174
+
2175
+ function primary(id: string) {
2176
+ quiet = id;
2177
+ state.selected = id;
2178
+ }
2179
+
2180
+ // Rows hidden as their folder closes leave the selection, as in VS Code. The primary stays: it's the file the
2181
+ // editor shows, and the highlight finds it again once the folder reopens.
2182
+ function prune() {
2183
+ selection.replace([...selection.ids].filter((id) => {
2184
+ let row = built.get(id);
2185
+
2186
+ return id === state.selected || (!!row && !hidden.has(id) && shown(row) === row);
2187
+ }));
2188
+ }
2189
+
2190
+ function purge(ids: string[]) {
2191
+ for (let i = 0, n = ids.length; i < n; i++) {
2192
+ let id = ids[i],
2193
+ row = built.get(id);
2194
+
2195
+ if (row?.open && peek(row.open) && !row.host) {
2196
+ opened--;
2197
+ }
2198
+
2199
+ if (anchor?.id === id) {
2200
+ anchor = null;
2201
+ }
2202
+
2203
+ built.delete(id);
2204
+ counts.delete(id);
2205
+ diffs.delete(id);
2206
+ filtered.delete(id);
2207
+ hidden.delete(id);
2208
+ initial.delete(id);
2209
+ marks.delete(id);
2210
+ notes.delete(id);
2211
+ own.delete(id);
2212
+ totals.delete(id);
2213
+ }
2214
+ }
2215
+
2216
+ // Keeps the cursor on its row through a change: on the folder it went into when that's closed, or where it stood
2217
+ // once the row is gone.
2218
+ function recover(at: number) {
2219
+ if (cursor && rows.includes(cursor)) {
2220
+ return;
2221
+ }
2222
+
2223
+ let row: Row | undefined;
2224
+
2225
+ for (let node = cursor && index.has(cursor.id) ? cursor.id : null; node !== null; node = index.get(node)!.parent) {
2226
+ let found = built.get(node),
2227
+ candidate = found?.host ?? found;
2228
+
2229
+ if (candidate && rows.includes(candidate)) {
2230
+ row = candidate;
2231
+ break;
2232
+ }
2233
+ }
2234
+
2235
+ if (row) {
2236
+ focus(row);
2237
+ }
2238
+ else if (rows.length) {
2239
+ focus(rows[Math.min(Math.max(at, 0), rows.length - 1)]);
2240
+ }
2241
+ else {
2242
+ cursor = null;
2243
+ write(focused, 0);
2244
+ }
2245
+ }
2246
+
2247
+ // 'force' rebuilds the rows even when none was hidden or shown, as when folders opened or closed. What the
2248
+ // patterns hide is left as it is: only the display settings change it, and a search redisplays on every key.
2249
+ function redisplay(force = false) {
2250
+ settle();
2251
+
2252
+ let changed: string[] = [];
2253
+
2254
+ for (let id of index.keys()) {
2255
+ rehide(id, changed);
2256
+ }
2257
+
2258
+ for (let id of decorations?.keys() ?? []) {
2259
+ if (!index.has(id)) {
2260
+ rehide(id, changed);
2261
+ }
2262
+ }
2263
+
2264
+ // Hidden is already in step, so this only moves the folder marks; the rows are swapped below in one go.
2265
+ decorate(changed);
2266
+
2267
+ for (let id of marks.keys()) {
2268
+ refresh(id);
2269
+ }
2270
+
2271
+ if (changed.length || force) {
2272
+ reshow(changed);
2273
+ }
2274
+ }
2275
+
2276
+ // Chains count only what's shown, so hiding or showing 'id' can join or split its own and its folder's: the
2277
+ // folders to rebuild for it, each listing a row that no longer compacts as it would now.
2278
+ function refold(id: string) {
2279
+ let out: (string | null)[] = [];
2280
+
2281
+ for (let node of [id, index.get(id)?.parent ?? null]) {
2282
+ let row = node === null ? undefined : built.get(node);
2283
+
2284
+ if (row && stale(row)) {
2285
+ out.push((row.host ?? row).parent?.id ?? null);
2286
+ }
2287
+ }
2288
+
2289
+ return out;
2290
+ }
2291
+
2292
+ function refresh(id: string) {
2293
+ let mark = marks.get(id);
2294
+
2295
+ if (!mark) {
2296
+ return;
2297
+ }
2298
+
2299
+ if (touched) {
2300
+ touched.add(id);
2301
+ return;
2302
+ }
2303
+
2304
+ let current = peek(mark),
2305
+ next = look(id);
2306
+
2307
+ if (current.key !== next.key || current.tone !== next.tone) {
2308
+ write(mark, next);
2309
+ }
2310
+ }
2311
+
2312
+ // The folder to rebuild for a change inside 'id'. Folded into a compact row, or folding differently now, its rows
2313
+ // are the folder's listing that row.
2314
+ function regroup(id: string | null) {
2315
+ let row = id === null ? undefined : built.get(id);
2316
+
2317
+ return row && (row.host || stale(row)) ? (row.host ?? row).parent?.id ?? null : id;
2318
+ }
2319
+
2320
+ function rehide(id: string, changed: string[]) {
2321
+ let hide = unseen(id);
2322
+
2323
+ if (hide !== hidden.has(id)) {
2324
+ obscure(id, hide);
2325
+ changed.push(id);
2326
+ }
2327
+ }
2328
+
2329
+ // Swaps in the rows once 'changed' were hidden or shown, many at a time: one pass over the rows rather than a
2330
+ // search and a splice for each.
2331
+ function reshow(changed: string[]) {
2332
+ settle();
2333
+
2334
+ // Chains count only what's shown, so those the change joined or split are rebuilt before the rows are swapped.
2335
+ for (let group of new Set(changed.flatMap(refold))) {
2336
+ sync(group);
2337
+ }
2338
+
2339
+ if (cursor?.host) {
2340
+ focus(cursor.host);
2341
+ }
2342
+
2343
+ let next = visible(top),
2344
+ kept = new Set(next),
2345
+ // A hidden cursor moves to the first row after it still shown, as it does when a single row goes.
2346
+ target = cursor && !kept.has(cursor)
2347
+ ? rows.slice(rows.indexOf(cursor)).find((row) => kept.has(row)) ?? next[next.length - 1]
2348
+ : undefined;
2349
+
2350
+ swap(0, rows.length, next);
2351
+ prune();
2352
+
2353
+ if (target) {
2354
+ focus(target);
2355
+ }
2356
+
2357
+ ui.any = opened > 0;
2358
+ persist();
2359
+ }
2360
+
2361
+ // Puts a row back after its previous visible sibling's subtree, when its folder is open and on screen.
2362
+ function restore(row: Row) {
2363
+ let parent = row.parent,
2364
+ at = parent ? rows.indexOf(parent) + 1 : 0;
2365
+
2366
+ if (parent && (!peek(parent.open!) || at === 0)) {
2367
+ return;
2368
+ }
2369
+
2370
+ let siblings = parent ? branch(parent) : top;
2371
+
2372
+ for (let i = row.position - 2; i >= 0; i--) {
2373
+ let sibling = siblings[i];
2374
+
2375
+ if (!hidden.has(sibling.id)) {
2376
+ at = rows.indexOf(sibling) + 1 + (sibling.open && peek(sibling.open) ? visible(branch(sibling)).length : 0);
2377
+ break;
2378
+ }
2379
+ }
2380
+
2381
+ insert(at, [row, ...(row.open && peek(row.open) ? visible(branch(row)) : [])]);
2382
+ }
2383
+
2384
+ // A change from the store, applied to the folders it touched.
2385
+ function restructure({ elements, from = null, ids, parent, type }: Change) {
2386
+ let groups: (string | null)[] = [];
2387
+
2388
+ seen = model.version;
2389
+
2390
+ if (type === 'remove') {
2391
+ let edit = peek(draft),
2392
+ removed = new Set(ids);
2393
+
2394
+ if (edit && ((edit.element && removed.has(edit.element.id)) || (edit.parent && removed.has(edit.parent.id)))) {
2395
+ close(false);
2396
+ }
2397
+
2398
+ shift(ids, parent, null);
2399
+ purge(ids);
2400
+
2401
+ // The rest of the selection takes over from a removed primary.
2402
+ if (removed.has(state.selected)) {
2403
+ primary([...selection.ids].find((id) => !removed.has(id)) ?? '');
2404
+ }
2405
+ }
2406
+ else {
2407
+ // Exclude and dotfile patterns match paths, so whatever was added, moved or renamed is checked again,
2408
+ // before the rows are built so a new row that's hidden is never inserted.
2409
+ for (let id of ids) {
2410
+ filtered.delete(id);
2411
+ }
2412
+
2413
+ for (let i = 0, n = elements.length; i < n; i++) {
2414
+ recheck(elements[i], index, display.dotfiles !== false, excluded, roots, filtered);
2415
+ }
2416
+
2417
+ for (let id of ids) {
2418
+ // A root added live opens, as those given at first do.
2419
+ if (roots && type === 'add' && index.get(id)?.parent === null) {
2420
+ initial.add(id);
2421
+ }
2422
+
2423
+ if (unseen(id) === hidden.has(id)) {
2424
+ continue;
2425
+ }
2426
+
2427
+ obscure(id, !hidden.has(id));
2428
+ // Deeper in, a folder kept as it was can still hold a chain the change joined or split.
2429
+ groups.push(...refold(id));
2430
+ }
2431
+
2432
+ if (type === 'move') {
2433
+ shift(ids, from, parent);
2434
+ }
2435
+
2436
+ // Hidden is already in step, so this only moves the folder marks.
2437
+ if (decorations) {
2438
+ decorate(ids);
2439
+ }
2440
+ }
2441
+
2442
+ update([...(type === 'move' && from !== parent ? [from, parent] : [parent]), ...groups]);
2443
+ search?.refresh();
2444
+ }
2445
+
2446
+ // Catches up on changes made while disconnected, which went unseen: every folder rebuilds when next shown.
2447
+ function resync() {
2448
+ close(false);
2449
+
2450
+ for (let [id, row] of built) {
2451
+ if (index.has(id)) {
2452
+ row.children = null;
2453
+ }
2454
+ else {
2455
+ purge([id]);
2456
+ }
2457
+ }
2458
+
2459
+ filtered = filter(model.elements, display.dotfiles !== false, excluded, roots);
2460
+ hidden = new Set([...filtered, ...(decorations?.keys() ?? [])].filter(gone));
2461
+ shifts++;
2462
+
2463
+ // Rolled up again from scratch by the decorations catching up on connect.
2464
+ if (decorations) {
2465
+ counts.clear();
2466
+ diffs.clear();
2467
+ own.clear();
2468
+ totals.clear();
2469
+
2470
+ for (let id of marks.keys()) {
2471
+ refresh(id);
2472
+ }
2473
+ }
2474
+
2475
+ seen = model.version;
2476
+ update([null]);
2477
+ }
2478
+
2479
+ // Points whatever held a row at the copy replacing it.
2480
+ function retarget(row: Row, next: Row) {
2481
+ let edit = peek(draft);
2482
+
2483
+ if (anchor === row) {
2484
+ anchor = next;
2485
+ }
2486
+
2487
+ if (cursor === row) {
2488
+ focus(next);
2489
+ }
2490
+
2491
+ if (!edit) {
2492
+ return;
2493
+ }
2494
+
2495
+ if (edit.from === row) {
2496
+ edit.from = next;
2497
+ }
2498
+
2499
+ if (edit.parent === row) {
2500
+ edit.parent = next;
2501
+
2502
+ if (!edit.element) {
2503
+ edit.row.parent = next;
2504
+ }
2505
+ }
2506
+
2507
+ if (edit.row === row) {
2508
+ edit.element = next.element;
2509
+ edit.row = next;
2510
+ }
2511
+ }
2512
+
2513
+ // Selects what an undo or redo brought back, moved or renamed, in tree order, revealing the first; one that only
2514
+ // took items away selects the folder they left.
2515
+ function retrace({ operations }: Step) {
2516
+ let ids = new Set<string>(),
2517
+ left: string | null = null;
2518
+
2519
+ for (let i = 0, n = operations.length; i < n; i++) {
2520
+ let operation = operations[i];
2521
+
2522
+ if (operation.type === 'remove') {
2523
+ left ??= operation.parent;
2524
+ }
2525
+ else {
2526
+ ids.add(operation.element.id);
2527
+ }
2528
+ }
2529
+
2530
+ if (!ids.size && left !== null) {
2531
+ ids.add(left);
2532
+ }
2533
+
2534
+ // By id, since a folder folded into a compact row is selected as its segment, on the row that shows it.
2535
+ let found: { id: string; place: number[]; row: Row }[] = [];
2536
+
2537
+ for (let id of ids) {
2538
+ let row = locate(id);
2539
+
2540
+ if (row && !row.locked && !hidden.has(id)) {
2541
+ found.push({ id, place: place(row), row });
2542
+ }
2543
+ }
2544
+
2545
+ if (!found.length) {
2546
+ return;
2547
+ }
2548
+
2549
+ found.sort((a, b) => order(a.place, b.place));
2550
+ anchor = found[0].row;
2551
+ selection.replace(found.map((item) => item.id));
2552
+ primary(found[0].id);
2553
+ reveal(found[0].id, true);
2554
+ }
2555
+
2556
+ // The row under a folder that failed to load tries again; the loading row does nothing.
2557
+ function retry(row: Row) {
2558
+ if (row.notice?.type === 'error' && loader?.forget(row.parent!.id)) {
2559
+ update([row.parent!.id]);
2560
+ }
2561
+ }
2562
+
2563
+ function reveal(id: string, scroll: boolean) {
2564
+ let row = locate(id);
2565
+
2566
+ if (!row) {
2567
+ return;
2568
+ }
2569
+
2570
+ for (let node = row.parent; node; node = node.parent) {
2571
+ expand(node, true);
2572
+ }
2573
+
2574
+ let at = rows.indexOf(row);
2575
+
2576
+ if (at === -1) {
2577
+ return;
2578
+ }
2579
+
2580
+ if (scroll) {
2581
+ move(at, 'center');
2582
+ }
2583
+ else {
2584
+ focus(row);
2585
+ }
2586
+ }
2587
+
2588
+ // 'full' is the element's path from the tree's root, or from its own root under 'roots'; 'inherited' its
2589
+ // folder's tint.
2590
+ function scope(element: Element, full: string, inherited: string) {
2591
+ for (let i = 0, n = scopes.length; i < n; i++) {
2592
+ let match = scopes[i].match;
2593
+
2594
+ if (typeof match === 'function' ? match(element) : match.test(full)) {
2595
+ return scopes[i].color;
2596
+ }
2597
+ }
2598
+
2599
+ return inherited;
2600
+ }
2601
+
2602
+ // What a command on 'row' acts on: the folder of a compact row's selected segment, or the row's own.
2603
+ function segment(row: Row) {
2604
+ return row.segments?.find((node) => node.id === state.selected) ?? row;
2605
+ }
2606
+
2607
+ // Splits a compact row at 'row', which shows as the last folder of what's left of it; the chain joins again once
2608
+ // the name input closes.
2609
+ function separate(row: Row) {
2610
+ split = row.id;
2611
+ update([row.id]);
2612
+
2613
+ return built.get(row.id)!;
2614
+ }
2615
+
2616
+ function settle() {
2617
+ if (!motion) {
2618
+ return;
2619
+ }
2620
+
2621
+ cancelAnimationFrame(motion);
2622
+ motion = 0;
2623
+ ghosts.splice(0, ghosts.length);
2624
+ revealing.clear();
2625
+ write(sweep, 0);
2626
+ ui.motion = '';
2627
+ // Off now, before a fold that follows measures its rows, so its own motion restarts the animation.
2628
+ flush();
2629
+ }
2630
+
2631
+ // Moves the rollup that 'ids' carry, their tones and their lines, from one chain of folders to another; null ends
2632
+ // a chain.
2633
+ function shift(ids: string[], from: string | null, to: string | null) {
2634
+ for (let i = 0, n = ids.length; i < n; i++) {
2635
+ let lines = diffs.get(ids[i]),
2636
+ value = lift(own.get(ids[i]) ?? -1);
2637
+
2638
+ if (value > 0 || lines) {
2639
+ tally(from, value, lines, -1);
2640
+ tally(to, value, lines, 1);
2641
+ }
2642
+ }
2643
+ }
2644
+
2645
+ // The names a new or renamed item can clash with. Deleted files are gone from disk, even shown, so theirs are free.
2646
+ function siblings(parent: Element | null) {
2647
+ return (parent ? parent.children ?? [] : model.elements).filter((element) => decorations?.get(element.id)?.status !== 'deleted');
2648
+ }
2649
+
2650
+ // Filter mode's view: the rows the search keeps stay, and the folders down to its matches open while it lasts;
2651
+ // null ends it. Each folder opens once, so one the reader closes meanwhile stays closed. Ending closes only the
2652
+ // folders it opened, bar those down to the cursor and the primary, which would otherwise drop out of view.
2653
+ //
2654
+ // Chains follow the view as they follow anything else hiding rows, so its rows are laid out first and the
2655
+ // folders opened on the chains it makes. A closed folder it folds into a compact row reads as open there, so it
2656
+ // counts as opened by the search, and closes again once the chain splits.
2657
+ function sift(folders: string[] | null) {
2658
+ let changed = false,
2659
+ next = new Set(folders),
2660
+ shut: string[] = [],
2661
+ spared = new Set<string>();
2662
+
2663
+ if (compact) {
2664
+ for (let row of built.values()) {
2665
+ if (row.open && !row.host && !peek(row.open)) {
2666
+ shut.push(row.id);
2667
+ }
2668
+ }
2669
+ }
2670
+
2671
+ redisplay();
2672
+
2673
+ for (let i = 0, n = shut.length; i < n; i++) {
2674
+ if (built.get(shut[i])?.host && !unfolded.has(shut[i])) {
2675
+ unfolded.set(shut[i], true);
2676
+ }
2677
+ }
2678
+
2679
+ if (!folders) {
2680
+ for (let row of [cursor, built.get(state.selected)]) {
2681
+ for (let node of row ? ancestors(row) : []) {
2682
+ spared.add(node.id);
2683
+ }
2684
+ }
2685
+ }
2686
+
2687
+ for (let [id, mine] of unfolded) {
2688
+ if (next.has(id)) {
2689
+ continue;
2690
+ }
2691
+
2692
+ let row = built.get(id);
2693
+
2694
+ unfolded.delete(id);
2695
+
2696
+ if (!mine || spared.has(id) || !row?.open || !peek(row.open)) {
2697
+ continue;
2698
+ }
2699
+
2700
+ // One still folded counts among the open folders only once it shows its own row, closed now.
2701
+ write(row.open, false);
2702
+ opened -= row.host ? 0 : 1;
2703
+ changed = true;
2704
+ }
2705
+
2706
+ for (let id of folders ?? []) {
2707
+ if (unfolded.has(id)) {
2708
+ continue;
2709
+ }
2710
+
2711
+ // Built with the folders above it.
2712
+ locate(id);
2713
+
2714
+ let row = built.get(id),
2715
+ open = !!row?.open && !row.host && !row.locked && !peek(row.open);
2716
+
2717
+ unfolded.set(id, open);
2718
+
2719
+ if (open) {
2720
+ write(row!.open!, true);
2721
+ opened++;
2722
+ changed = true;
2723
+ }
2724
+ }
2725
+
2726
+ redisplay(changed);
2727
+ ui.any = opened > 0;
2728
+ persist();
2729
+ }
2730
+
2731
+ // Shift+click and Shift+arrows: the rows from the anchor to 'to' become the selection. Without an anchor still on
2732
+ // screen, the range starts where the cursor was.
2733
+ function span(from: Row, to: Row) {
2734
+ if (!anchor || rows.indexOf(anchor) === -1) {
2735
+ anchor = from.locked ? to : from;
2736
+ }
2737
+
2738
+ let a = rows.indexOf(anchor),
2739
+ b = rows.indexOf(to),
2740
+ ids: string[] = [];
2741
+
2742
+ for (let i = Math.min(a, b), n = Math.max(a, b); i <= n; i++) {
2743
+ if (!rows[i].locked) {
2744
+ ids.push(rows[i].id);
2745
+ }
2746
+ }
2747
+
2748
+ selection.replace(ids);
2749
+ primary(anchor.locked ? (ids[0] ?? '') : anchor.id);
2750
+ }
2751
+
2752
+ // Whether the row compacts, as built, other than it would now.
2753
+ function stale(row: Row) {
2754
+ let now = joined(index.get(row.id)?.element ?? row.element),
2755
+ was = row.host ? lineage(row.host)[lineage(row).length] : undefined;
2756
+
2757
+ return (now?.id ?? null) !== (was?.id ?? null);
2758
+ }
2759
+
2760
+ // Replaces rows 'at' to 'end' with 'next', splicing only the stretch that differs so the rest stay rendered.
2761
+ function swap(at: number, end: number, next: Row[]) {
2762
+ let head = 0,
2763
+ n = next.length,
2764
+ tail = 0;
2765
+
2766
+ while (head < n && at + head < end && rows[at + head] === next[head]) {
2767
+ head++;
2768
+ }
2769
+
2770
+ while (tail < n - head && tail < end - at - head && rows[end - tail - 1] === next[n - tail - 1]) {
2771
+ tail++;
2772
+ }
2773
+
2774
+ let items = next.slice(head, n - tail),
2775
+ removed = end - at - head - tail;
2776
+
2777
+ if (!items.length && !removed) {
2778
+ return;
2779
+ }
2780
+
2781
+ rows.splice(at + head, removed, ...items.slice(0, CHUNK));
2782
+ insert(at + head + CHUNK, items.slice(CHUNK));
2783
+ }
2784
+
2785
+ // Rebuilds a folder's rows from its element's children, or the top level's for null.
2786
+ function sync(target: string | null) {
2787
+ let row = target === null ? null : built.get(target);
2788
+
2789
+ // Never built, so it builds fresh when it opens.
2790
+ if (row === undefined || (row && !row.children)) {
2791
+ return;
2792
+ }
2793
+
2794
+ let next: Row[];
2795
+
2796
+ if (row) {
2797
+ row.children = null;
2798
+ next = branch(row);
2799
+ }
2800
+ else {
2801
+ next = top = build(model.elements, 0, null);
2802
+ }
2803
+
2804
+ let at = row ? rows.indexOf(row) + 1 : 0,
2805
+ end = row ? at : rows.length;
2806
+
2807
+ if (row && (at === 0 || !peek(row.open!))) {
2808
+ return;
2809
+ }
2810
+
2811
+ while (row && end < rows.length && rows[end].depth > row.depth) {
2812
+ end++;
2813
+ }
2814
+
2815
+ swap(at, end, visible(next));
2816
+ }
2817
+
2818
+ // Adds or takes away one row's tone and lines along a chain of folders.
2819
+ function tally(start: string | null, value: number, lines: number[] | undefined, sign: 1 | -1) {
2820
+ if (value <= 0 && !lines) {
2821
+ return;
2822
+ }
2823
+
2824
+ for (let parent = start; parent !== null; parent = index.get(parent)?.parent ?? null) {
2825
+ if (value > 0) {
2826
+ let list = counts.get(parent);
2827
+
2828
+ if (!list) {
2829
+ counts.set(parent, list = new Array(RANK.length).fill(0));
2830
+ }
2831
+
2832
+ list[value] += sign;
2833
+ }
2834
+
2835
+ if (lines) {
2836
+ let total = totals.get(parent);
2837
+
2838
+ if (!total) {
2839
+ totals.set(parent, total = [0, 0]);
2840
+ }
2841
+
2842
+ total[0] += sign * lines[0];
2843
+ total[1] += sign * lines[1];
2844
+ }
2845
+
2846
+ refresh(parent);
2847
+ }
2848
+ }
2849
+
2850
+ // What a command acts on: the selection when the focused row is part of it, else the focused row alone, as in
2851
+ // VS Code. Moving a selected folder carries its contents, so 'distinct' drops selected rows inside one. Roots
2852
+ // never move, so 'distinct' drops them instead, leaving what's selected inside them.
2853
+ function targets(row: Row, distinct: boolean) {
2854
+ let subject = segment(row);
2855
+
2856
+ if (!selection.has(subject.id)) {
2857
+ return subject.locked || (distinct && header(subject)) ? [] : [subject.element];
2858
+ }
2859
+
2860
+ let out: Element[] = [];
2861
+
2862
+ for (let i = 0, n = rows.length; i < n; i++) {
2863
+ // Any of a compact row's folders can be selected.
2864
+ for (let candidate of lineage(rows[i])) {
2865
+ if (!selection.has(candidate.id)) {
2866
+ continue;
2867
+ }
2868
+
2869
+ if (distinct && (header(candidate) || ancestors(candidate).some((node) => selection.has(node.id) && !header(node)))) {
2870
+ continue;
2871
+ }
2872
+
2873
+ out.push(candidate.element);
2874
+ }
2875
+ }
2876
+
2877
+ return out;
2878
+ }
2879
+
2880
+ // Created when a row first renders; every later change is a single write the row alone reacts to.
2881
+ function track(id: string) {
2882
+ let mark = marks.get(id);
2883
+
2884
+ if (!mark) {
2885
+ marks.set(id, mark = signal(look(id)));
2886
+ }
2887
+
2888
+ return mark;
2889
+ }
2890
+
2891
+ function typeahead(character: string, from: number) {
2892
+ let now = performance.now(),
2893
+ next = (now - typedAt > TYPEAHEAD ? '' : typed) + character.toLowerCase(),
2894
+ // Repeating one letter cycles through the rows that start with it.
2895
+ repeat = [...next].every((c) => c === next[0]),
2896
+ start = repeat ? from + 1 : from;
2897
+
2898
+ typed = repeat ? next[0] : next;
2899
+ typedAt = now;
2900
+
2901
+ for (let i = 0, n = rows.length; i < n; i++) {
2902
+ let index = (start + i) % n;
2903
+
2904
+ if (caption(rows[index]).toLowerCase().startsWith(typed)) {
2905
+ return index;
2906
+ }
2907
+ }
2908
+
2909
+ return -1;
2910
+ }
2911
+
2912
+ // Decorated files the tree doesn't know yet, under ids that are paths: the deepest folder known along each one's
2913
+ // path loads, then the next one down inside what arrived, each at most once.
2914
+ async function uncover(kind: Jump) {
2915
+ let asked = new Set<string>();
2916
+
2917
+ for (;;) {
2918
+ let folders: Element[] = [];
2919
+
2920
+ for (let id of decorations!.keys()) {
2921
+ if (index.has(id) || !flagged(decorations!.get(id), kind)) {
2922
+ continue;
2923
+ }
2924
+
2925
+ let parent = enclosing(id).find((candidate) => index.has(candidate)),
2926
+ element = parent === undefined ? undefined : index.get(parent)!.element;
2927
+
2928
+ if (!element || element.children || asked.has(element.id) || hidden.has(element.id) || !folder(element)) {
2929
+ continue;
2930
+ }
2931
+
2932
+ asked.add(element.id);
2933
+ folders.push(element);
2934
+ }
2935
+
2936
+ if (!folders.length) {
2937
+ return;
2938
+ }
2939
+
2940
+ // One at a time, so a jump across a large unloaded tree doesn't fire off every request at once.
2941
+ for (let i = 0, n = folders.length; i < n; i++) {
2942
+ await loader!.wait(folders[i]);
2943
+ }
2944
+ }
2945
+ }
2946
+
2947
+ // A pinned folder's own row is scrolled back to where its copy sits, then clicked, so a folder that closes stays
2948
+ // under the pointer with the rows after it following on.
2949
+ function unpin(row: Row) {
2950
+ move(rows.indexOf(row), 'start');
2951
+ // Once the list has rendered the rows it scrolled to, so the folder closes with its motion.
2952
+ requestAnimationFrame(() => activate(row, PREVIEW));
2953
+ }
2954
+
2955
+ // Out of view: hidden for good, or left out by a search filtering the rows.
2956
+ function unseen(id: string) {
2957
+ return gone(id) || !!search?.hides(id);
2958
+ }
2959
+
2960
+ // Rebuilds the folders a change touched, then finds the cursor again.
2961
+ function update(folders: (string | null)[]) {
2962
+ settle();
2963
+
2964
+ let at = cursor ? rows.indexOf(cursor) : 0;
2965
+
2966
+ for (let i = 0, n = folders.length; i < n; i++) {
2967
+ sync(regroup(folders[i]));
2968
+ }
2969
+
2970
+ prune();
2971
+ clipboard.retain((id) => model.get(id));
2972
+ recover(at);
2973
+ ui.any = opened > 0;
2974
+ persist();
2975
+ }
2976
+
2977
+ // The rows a reader can see: every row not inside a closed folder.
2978
+ function visible(list: Row[], out: Row[] = []) {
2979
+ let edit = peek(draft);
2980
+
2981
+ // A new item's input sits first in its folder.
2982
+ if (edit && !edit.element && list === (edit.parent ? edit.parent.children : top)) {
2983
+ out.push(edit.row);
2984
+ }
2985
+
2986
+ // Only a root with no children at all has a note, so one row hiding or showing never adds or drops it.
2987
+ if (roots && !list.length && list !== top) {
2988
+ let root = top.find((row) => row.children === list);
2989
+
2990
+ if (root) {
2991
+ out.push(blank(root));
2992
+ }
2993
+ }
2994
+
2995
+ for (let i = 0, n = list.length; i < n; i++) {
2996
+ let row = list[i];
2997
+
2998
+ if (hidden.has(row.id)) {
2999
+ continue;
3000
+ }
3001
+
3002
+ out.push(row);
3003
+
3004
+ if (row.open && peek(row.open)) {
3005
+ visible(branch(row), out);
3006
+ }
3007
+ }
3008
+
3009
+ return out;
3010
+ }
3011
+
3012
+ return html`
3013
+ <div
3014
+ class='file-tree ${indicator !== 'never' && 'file-tree--indicator'} ${indicator === 'hover' && 'file-tree--indicator-hover'}'
3015
+ ${attributes}
3016
+ ${dragging?.root}
3017
+ ${{
3018
+ class: () => ui.motion && `file-tree--motion file-tree--motion-${ui.motion}`,
3019
+ onanimationend: (event: AnimationEvent) => {
3020
+ if (event.target === root) {
3021
+ settle();
3022
+ }
3023
+ },
3024
+ onconnect: (element: HTMLElement) => {
3025
+ root = element;
3026
+ forget = history?.subscribe(retrace);
3027
+ unwatch = model.subscribe(restructure);
3028
+
3029
+ if (seen !== model.version) {
3030
+ resync();
3031
+ }
3032
+
3033
+ // These effects are made on connect rather than while building, where they would belong to whatever
3034
+ // computation built the tree and rerun it; the connection owns them and they end with it.
3035
+
3036
+ // Selection written from outside, like an editor switching tabs, becomes the whole selection and
3037
+ // opens the folders down to it.
3038
+ effect(() => state.selected, (value) => {
3039
+ write(current, value);
3040
+
3041
+ if (value === known) {
3042
+ return;
3043
+ }
3044
+
3045
+ known = value;
3046
+
3047
+ if (!selection.has(value)) {
3048
+ anchor = built.get(value) ?? null;
3049
+ selection.replace(value ? [value] : []);
3050
+ }
3051
+
3052
+ if (value !== quiet && autoreveal !== 'off') {
3053
+ reveal(value, autoreveal === 'on');
3054
+ }
3055
+
3056
+ quiet = null;
3057
+ });
3058
+
3059
+ effect(() => state.selection, (value) => {
3060
+ if (!value || value === selection.ids) {
3061
+ return;
3062
+ }
3063
+
3064
+ selection.replace(value);
3065
+
3066
+ if (!value.has(state.selected)) {
3067
+ primary(value.values().next().value ?? '');
3068
+ }
3069
+ });
3070
+
3071
+ // Display written from outside, like a settings toggle, hides and shows rows in place.
3072
+ effect(modes, (value) => {
3073
+ if (value !== settings) {
3074
+ settings = value;
3075
+ filtered = filter(model.elements, display.dotfiles !== false, excluded, roots);
3076
+ redisplay();
3077
+ search?.refresh();
3078
+ }
3079
+ });
3080
+
3081
+ if (typeof phrase === 'function') {
3082
+ effect(phrase, (value) => {
3083
+ write(given, value);
3084
+ });
3085
+ }
3086
+
3087
+ // Changes made while disconnected went unsearched.
3088
+ search?.refresh();
3089
+
3090
+ if (snapshot?.scroll) {
3091
+ let offset = snapshot.scroll;
3092
+
3093
+ requestAnimationFrame(() => {
3094
+ viewport!.scrollTop = offset;
3095
+ });
3096
+ }
3097
+
3098
+ detach = editor?.subscribe((request) => {
3099
+ if (request.action === 'cancel') {
3100
+ close(!!viewport?.contains(document.activeElement));
3101
+ }
3102
+ else {
3103
+ begin(request.action, request.target);
3104
+ }
3105
+ });
3106
+
3107
+ if (!decorations) {
3108
+ return;
3109
+ }
3110
+
3111
+ // A file shown again, no longer ignored or deleted, may match.
3112
+ unsubscribe = decorations.subscribe((ids) => {
3113
+ decorate(ids);
3114
+ search?.refresh();
3115
+ });
3116
+ // Catches up on whatever changed while disconnected, including ids since cleared.
3117
+ decorate(new Set([...own.keys(), ...decorations.keys()]));
3118
+ },
3119
+ ondisconnect: () => {
3120
+ clearTimeout(timer);
3121
+ search?.dispose();
3122
+ detach?.();
3123
+ detach = undefined;
3124
+
3125
+ forget?.();
3126
+ forget = undefined;
3127
+ unsubscribe?.();
3128
+ unsubscribe = undefined;
3129
+ unwatch?.();
3130
+ unwatch = undefined;
3131
+ },
3132
+ style: () => ui.motion && `--motion-rows: ${ui.motionRows}`
3133
+ }}
3134
+ >
3135
+ <div
3136
+ aria-label='${label}'
3137
+ aria-multiselectable='true'
3138
+ class='file-tree-viewport'
3139
+ id='${id}'
3140
+ role='tree'
3141
+ tabindex='0'
3142
+ ${dragging?.viewport}
3143
+ ${{
3144
+ 'aria-activedescendant': () => read(focused) > 0 && `${id}-${read(focused)}`,
3145
+ onconnect: (element: HTMLElement) => {
3146
+ viewport = element;
3147
+ },
3148
+ oncontextmenu: (event: MouseEvent) => {
3149
+ if (!menu || !viewport) {
3150
+ return;
3151
+ }
3152
+
3153
+ event.preventDefault();
3154
+
3155
+ let item = (event.target as HTMLElement).closest<Rendered>('.file-tree-row'),
3156
+ // Shift+F10 and the menu key fire on the tree itself, with no pointer to place the menu at.
3157
+ keyboard = !item && event.button !== 2,
3158
+ row = keyboard ? cursor : owner(item);
3159
+
3160
+ if (!row) {
3161
+ menu([], { x: event.clientX, y: event.clientY }, false);
3162
+ return;
3163
+ }
3164
+
3165
+ let subject = keyboard ? segment(row) : pick(row, event);
3166
+
3167
+ if (!subject.locked && !selection.has(subject.id)) {
3168
+ anchor = row;
3169
+ selection.replace([subject.id]);
3170
+ primary(subject.id);
3171
+ }
3172
+
3173
+ focus(row);
3174
+
3175
+ let box = keyboard ? (node(row) ?? viewport).getBoundingClientRect() : null;
3176
+
3177
+ menu(targets(row, false), box ? { x: box.left, y: box.bottom } : { x: event.clientX, y: event.clientY }, header(row));
3178
+ },
3179
+ onkeydown: (event: KeyboardEvent) => {
3180
+ if (search?.key(event)) {
3181
+ event.preventDefault();
3182
+ return;
3183
+ }
3184
+
3185
+ let index = cursor ? rows.indexOf(cursor) : -1,
3186
+ row = rows[index];
3187
+
3188
+ if (!row || !viewport) {
3189
+ return;
3190
+ }
3191
+
3192
+ let name = command(event);
3193
+
3194
+ if (name && perform(name, row)) {
3195
+ event.preventDefault();
3196
+ return;
3197
+ }
3198
+
3199
+ let align: Align = 'end',
3200
+ target = -1;
3201
+
3202
+ switch (event.key) {
3203
+ // Opens every folder beside the cursor's row, one level deep.
3204
+ case '*': {
3205
+ let siblings = row.parent ? branch(row.parent) : top;
3206
+
3207
+ for (let i = 0, n = siblings.length; i < n; i++) {
3208
+ if (!siblings[i].locked) {
3209
+ expand(siblings[i], true);
3210
+ }
3211
+ }
3212
+
3213
+ break;
3214
+ }
3215
+ case 'ArrowDown':
3216
+ target = index + 1;
3217
+ break;
3218
+ case 'ArrowUp':
3219
+ align = 'start';
3220
+ target = index - 1;
3221
+ break;
3222
+ case 'End':
3223
+ target = rows.length - 1;
3224
+ break;
3225
+ case 'Enter':
3226
+ case ' ':
3227
+ activate(row, event.key === ' ' ? PREVIEW : { mode: 'pinned', side: event.ctrlKey || event.metaKey });
3228
+ break;
3229
+ // Next and previous change, as in VS Code's editor.
3230
+ case 'F5':
3231
+ if (!event.altKey || event.ctrlKey || event.metaKey) {
3232
+ return;
3233
+ }
3234
+
3235
+ void jump('change', event.shiftKey ? -1 : 1);
3236
+ break;
3237
+ // Next and previous problem.
3238
+ case 'F8':
3239
+ if (event.altKey || event.ctrlKey || event.metaKey) {
3240
+ return;
3241
+ }
3242
+
3243
+ void jump('problem', event.shiftKey ? -1 : 1);
3244
+ break;
3245
+ case 'F2':
3246
+ begin('rename');
3247
+ break;
3248
+ case 'Home':
3249
+ align = 'start';
3250
+ target = 0;
3251
+ break;
3252
+ case 'PageDown':
3253
+ target = Math.min(rows.length - 1, index + page());
3254
+ break;
3255
+ case 'PageUp':
3256
+ align = 'start';
3257
+ target = Math.max(0, index - page());
3258
+ break;
3259
+ case 'ArrowLeft':
3260
+ case 'ArrowRight': {
3261
+ // Arrows point into and out of folders; flipped for right-to-left layouts.
3262
+ let inward = (event.key === 'ArrowRight') !== (getComputedStyle(viewport).direction === 'rtl'),
3263
+ open = row.open && peek(row.open);
3264
+
3265
+ // Alt opens or closes the folder with everything in it.
3266
+ if (event.altKey && row.open && (inward || open)) {
3267
+ all(inward, row);
3268
+ }
3269
+ else if (inward && row.open && !row.locked) {
3270
+ if (!open) {
3271
+ fold(row, true);
3272
+ }
3273
+ else if (row.element.children?.length) {
3274
+ target = index + 1;
3275
+ }
3276
+ }
3277
+ else if (!inward && open) {
3278
+ fold(row, false);
3279
+ }
3280
+ else if (!inward && row.parent) {
3281
+ align = 'start';
3282
+ target = rows.indexOf(row.parent);
3283
+ }
3284
+ break;
3285
+ }
3286
+ default:
3287
+ // By code, since macOS turns Alt+N into a symbol.
3288
+ if (shortcuts && event.altKey && event.code === 'KeyN' && !event.ctrlKey && !event.metaKey) {
3289
+ begin(event.shiftKey ? 'folder' : 'file');
3290
+ break;
3291
+ }
3292
+
3293
+ if (event.key.length !== 1 || event.altKey || event.ctrlKey || event.metaKey) {
3294
+ return;
3295
+ }
3296
+
3297
+ if (search && typing === 'find') {
3298
+ search.type(event.key);
3299
+ }
3300
+ else {
3301
+ target = typeahead(event.key, index);
3302
+ }
3303
+ }
3304
+
3305
+ event.preventDefault();
3306
+
3307
+ if (target !== -1) {
3308
+ if (rows[target] && extending(event)) {
3309
+ span(row, rows[target]);
3310
+ }
3311
+
3312
+ move(target, align);
3313
+
3314
+ if (cursor && cursor !== row) {
3315
+ follow(cursor);
3316
+ }
3317
+ }
3318
+ },
3319
+ onmousedown: middle,
3320
+ onscroll: () => {
3321
+ // The copies are laid out against the rows as they stood; once scrolled they no longer line up.
3322
+ settle();
3323
+ pins.update();
3324
+
3325
+ if (snapshot) {
3326
+ snapshot.scroll = viewport!.scrollTop;
3327
+ }
3328
+ }
3329
+ }}
3330
+ ${hint && {
3331
+ onpointerleave: (event: PointerEvent) => {
3332
+ if (event.pointerType !== 'touch') {
3333
+ tip.release();
3334
+ }
3335
+ },
3336
+ onpointerover: (event: PointerEvent) => {
3337
+ let scroller = event.currentTarget as HTMLElement,
3338
+ target = (event.target as HTMLElement).closest<Rendered>('.file-tree-row'),
3339
+ row = owner(target);
3340
+
3341
+ // Between rows, in the space beside a nested one, the tooltip stays on the last row.
3342
+ if (!target || !row) {
3343
+ return;
3344
+ }
3345
+
3346
+ if (!informative(row, target)) {
3347
+ tip.release();
3348
+ return;
3349
+ }
3350
+
3351
+ // Past the tree's edge, in line with the row, so it glides straight up and down between rows.
3352
+ tip.request(target, about(row), () => {
3353
+ let box = scroller.getBoundingClientRect(),
3354
+ rect = target.getBoundingClientRect();
3355
+
3356
+ return new DOMRect(box.left, rect.top, box.width, rect.height);
3357
+ });
3358
+ }
3359
+ }}
3360
+ >
3361
+ ${highlight({ class: 'file-tree-highlight', target: '.file-tree-row' })}
3362
+ ${pins.render()}
3363
+ ${slot.fragment}
3364
+ </div>
3365
+
3366
+ <div
3367
+ aria-hidden='true'
3368
+ class='file-tree-motion'
3369
+ inert
3370
+ style='${() => `height: ${stage.height}px; left: ${stage.left}px; top: ${stage.top}px; width: ${stage.width}px;`}'
3371
+ ${{ class: () => ui.motion && '--active' }}
3372
+ >
3373
+ <div
3374
+ class='file-tree-motion-layer'
3375
+ style='${() => `top: ${stage.edge}px;`}'
3376
+ ${{ class: () => ui.motion && `file-tree-motion-layer--${ui.motion}` }}
3377
+ >
3378
+ ${html.reactive(ghosts, ghost)}
3379
+ </div>
3380
+ </div>
3381
+
3382
+ ${() => empty && !rows.length && !search?.filtering() && html`<div class='file-tree-empty'>${empty()}</div>`}
3383
+
3384
+ ${search?.render(id)}
3385
+
3386
+ ${hint && tip.render({ 'aria-hidden': 'true', class: 'file-tree-tooltip' })}
3387
+
3388
+ ${toggle && html`
3389
+ <button
3390
+ class='button file-tree-toggle'
3391
+ onclick='${() => all(!ui.any)}'
3392
+ type='button'
3393
+ >
3394
+ ${() => ui.any ? 'Collapse all' : 'Expand all'}
3395
+ </button>
3396
+ `}
3397
+
3398
+ ${dragging?.ghost}
3399
+ </div>
3400
+ `;
3401
+ };
3402
+
3403
+ export { Decorations as FileTreeDecorations, Editor as FileTreeEditor, Elements as FileTreeElements, History as FileTreeHistory };
3404
+ export { createFileTreeIconResolver, glyph as fileTreeIcon, resolveFileTreeIcon };
3405
+ export type {
3406
+ Badge as FileTreeBadge,
3407
+ Change as FileTreeChange,
3408
+ Controller as FileTreeController,
3409
+ Decoration as FileTreeDecoration,
3410
+ Drag as FileTreeDrag,
3411
+ Drop as FileTreeDrop,
3412
+ Element as FileTreeElement,
3413
+ Export as FileTreeExport,
3414
+ HistoryEntry as FileTreeHistoryEntry,
3415
+ Operation as FileTreeHistoryOperation,
3416
+ HistoryOptions as FileTreeHistoryOptions,
3417
+ Place as FileTreeHistoryPlace,
3418
+ Step as FileTreeHistoryStep,
3419
+ IconName as FileTreeIconName,
3420
+ IconOptions as FileTreeIconOptions,
3421
+ ImportEntry as FileTreeImportEntry,
3422
+ Indicator as FileTreeIndicator,
3423
+ Jump as FileTreeJump,
3424
+ Kind as FileTreeKind,
3425
+ Load as FileTreeLoad,
3426
+ Open as FileTreeOpen,
3427
+ Operations as FileTreeOperations,
3428
+ ResolvedIcon as FileTreeResolvedIcon,
3429
+ Result as FileTreeResult,
3430
+ Scope as FileTreeScope,
3431
+ Snapshot as FileTreeSnapshot,
3432
+ Sort as FileTreeSort,
3433
+ Case as FileTreeSortCase,
3434
+ Options as FileTreeSortOptions,
3435
+ Order as FileTreeSortOrder,
3436
+ State as FileTreeState,
3437
+ Status as FileTreeStatus
3438
+ };