termcast 1.3.21 → 1.3.25

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 (429) hide show
  1. package/dist/ai.d.ts +104 -0
  2. package/dist/ai.d.ts.map +1 -0
  3. package/dist/ai.js +135 -0
  4. package/dist/ai.js.map +1 -0
  5. package/dist/apis/browser-extension.d.ts +18 -0
  6. package/dist/apis/browser-extension.d.ts.map +1 -0
  7. package/dist/apis/browser-extension.js +14 -0
  8. package/dist/apis/browser-extension.js.map +1 -0
  9. package/dist/apis/localstorage.d.ts.map +1 -1
  10. package/dist/apis/localstorage.js +4 -7
  11. package/dist/apis/localstorage.js.map +1 -1
  12. package/dist/apis/oauth.d.ts.map +1 -1
  13. package/dist/apis/oauth.js +5 -1
  14. package/dist/apis/oauth.js.map +1 -1
  15. package/dist/apis/preferences.d.ts.map +1 -1
  16. package/dist/apis/preferences.js +38 -19
  17. package/dist/apis/preferences.js.map +1 -1
  18. package/dist/apis/toast.d.ts +5 -0
  19. package/dist/apis/toast.d.ts.map +1 -1
  20. package/dist/apis/toast.js +7 -43
  21. package/dist/apis/toast.js.map +1 -1
  22. package/dist/build.d.ts.map +1 -1
  23. package/dist/build.js +3 -1
  24. package/dist/build.js.map +1 -1
  25. package/dist/cache.d.ts +32 -0
  26. package/dist/cache.d.ts.map +1 -0
  27. package/dist/cache.js +205 -0
  28. package/dist/cache.js.map +1 -0
  29. package/dist/cli.d.ts.map +1 -1
  30. package/dist/cli.js +87 -41
  31. package/dist/cli.js.map +1 -1
  32. package/dist/clipboard.d.ts +36 -0
  33. package/dist/clipboard.d.ts.map +1 -0
  34. package/dist/clipboard.js +154 -0
  35. package/dist/clipboard.js.map +1 -0
  36. package/dist/compile.d.ts +2 -1
  37. package/dist/compile.d.ts.map +1 -1
  38. package/dist/compile.js +31 -12
  39. package/dist/compile.js.map +1 -1
  40. package/dist/components/actions.d.ts.map +1 -1
  41. package/dist/components/actions.js +56 -30
  42. package/dist/components/actions.js.map +1 -1
  43. package/dist/components/detail.d.ts.map +1 -1
  44. package/dist/components/detail.js +4 -0
  45. package/dist/components/detail.js.map +1 -1
  46. package/dist/components/dropdown.d.ts.map +1 -1
  47. package/dist/components/dropdown.js +38 -15
  48. package/dist/components/dropdown.js.map +1 -1
  49. package/dist/components/extension-preferences.d.ts.map +1 -1
  50. package/dist/components/extension-preferences.js +40 -13
  51. package/dist/components/extension-preferences.js.map +1 -1
  52. package/dist/components/form/checkbox.d.ts.map +1 -1
  53. package/dist/components/form/checkbox.js +5 -3
  54. package/dist/components/form/checkbox.js.map +1 -1
  55. package/dist/components/form/date-picker.d.ts.map +1 -1
  56. package/dist/components/form/date-picker.js +5 -3
  57. package/dist/components/form/date-picker.js.map +1 -1
  58. package/dist/components/form/description.d.ts.map +1 -1
  59. package/dist/components/form/description.js +2 -2
  60. package/dist/components/form/description.js.map +1 -1
  61. package/dist/components/form/dropdown.d.ts.map +1 -1
  62. package/dist/components/form/dropdown.js +84 -80
  63. package/dist/components/form/dropdown.js.map +1 -1
  64. package/dist/components/form/file-autocomplete.d.ts +3 -6
  65. package/dist/components/form/file-autocomplete.d.ts.map +1 -1
  66. package/dist/components/form/file-autocomplete.js +61 -66
  67. package/dist/components/form/file-autocomplete.js.map +1 -1
  68. package/dist/components/form/file-picker.d.ts.map +1 -1
  69. package/dist/components/form/file-picker.js +33 -30
  70. package/dist/components/form/file-picker.js.map +1 -1
  71. package/dist/components/form/form-end.d.ts.map +1 -1
  72. package/dist/components/form/form-end.js +21 -1
  73. package/dist/components/form/form-end.js.map +1 -1
  74. package/dist/components/form/form-type-only.d.ts +174 -0
  75. package/dist/components/form/form-type-only.d.ts.map +1 -0
  76. package/dist/components/form/form-type-only.js +2 -0
  77. package/dist/components/form/form-type-only.js.map +1 -0
  78. package/dist/components/form/index.d.ts +3 -1
  79. package/dist/components/form/index.d.ts.map +1 -1
  80. package/dist/components/form/index.js +104 -30
  81. package/dist/components/form/index.js.map +1 -1
  82. package/dist/components/form/password-field.d.ts.map +1 -1
  83. package/dist/components/form/password-field.js +5 -3
  84. package/dist/components/form/password-field.js.map +1 -1
  85. package/dist/components/form/text-area.d.ts.map +1 -1
  86. package/dist/components/form/text-area.js +5 -3
  87. package/dist/components/form/text-area.js.map +1 -1
  88. package/dist/components/form/text-field.d.ts.map +1 -1
  89. package/dist/components/form/text-field.js +6 -4
  90. package/dist/components/form/text-field.js.map +1 -1
  91. package/dist/components/form/types.d.ts +5 -0
  92. package/dist/components/form/types.d.ts.map +1 -1
  93. package/dist/components/form/use-form-handling.d.ts +4 -0
  94. package/dist/components/form/use-form-handling.d.ts.map +1 -0
  95. package/dist/components/form/use-form-handling.js +37 -0
  96. package/dist/components/form/use-form-handling.js.map +1 -0
  97. package/dist/components/form/with-left-border.d.ts +2 -1
  98. package/dist/components/form/with-left-border.d.ts.map +1 -1
  99. package/dist/components/form/with-left-border.js +27 -3
  100. package/dist/components/form/with-left-border.js.map +1 -1
  101. package/dist/components/icon.d.ts +1 -0
  102. package/dist/components/icon.d.ts.map +1 -1
  103. package/dist/components/icon.js +24 -8
  104. package/dist/components/icon.js.map +1 -1
  105. package/dist/components/list.d.ts +2 -2
  106. package/dist/components/list.d.ts.map +1 -1
  107. package/dist/components/list.js +155 -70
  108. package/dist/components/list.js.map +1 -1
  109. package/dist/components/loading-bar.d.ts.map +1 -1
  110. package/dist/components/loading-bar.js +2 -2
  111. package/dist/components/loading-bar.js.map +1 -1
  112. package/dist/components/loading-text.d.ts +8 -0
  113. package/dist/components/loading-text.d.ts.map +1 -0
  114. package/dist/components/loading-text.js +58 -0
  115. package/dist/components/loading-text.js.map +1 -0
  116. package/dist/descendants.js +1 -1
  117. package/dist/descendants.js.map +1 -1
  118. package/dist/dev-ui.d.ts +7 -0
  119. package/dist/dev-ui.d.ts.map +1 -0
  120. package/dist/dev-ui.js +118 -0
  121. package/dist/dev-ui.js.map +1 -0
  122. package/dist/environment.d.ts +63 -0
  123. package/dist/environment.d.ts.map +1 -0
  124. package/dist/environment.js +189 -0
  125. package/dist/environment.js.map +1 -0
  126. package/dist/examples/datepicker.d.ts +2 -0
  127. package/dist/examples/datepicker.d.ts.map +1 -0
  128. package/dist/examples/datepicker.js +344 -0
  129. package/dist/examples/datepicker.js.map +1 -0
  130. package/dist/examples/file-autocomplete.vitest.d.ts +2 -0
  131. package/dist/examples/file-autocomplete.vitest.d.ts.map +1 -0
  132. package/dist/examples/file-autocomplete.vitest.js +223 -0
  133. package/dist/examples/file-autocomplete.vitest.js.map +1 -0
  134. package/dist/examples/form-basic-arrow-keys.vitest.d.ts +2 -0
  135. package/dist/examples/form-basic-arrow-keys.vitest.d.ts.map +1 -0
  136. package/dist/examples/form-basic-arrow-keys.vitest.js +46 -0
  137. package/dist/examples/form-basic-arrow-keys.vitest.js.map +1 -0
  138. package/dist/examples/form-basic.vitest.d.ts +2 -0
  139. package/dist/examples/form-basic.vitest.d.ts.map +1 -0
  140. package/dist/examples/form-basic.vitest.js +630 -0
  141. package/dist/examples/form-basic.vitest.js.map +1 -0
  142. package/dist/examples/form-dropdown-with-sections.d.ts +2 -0
  143. package/dist/examples/form-dropdown-with-sections.d.ts.map +1 -0
  144. package/dist/examples/form-dropdown-with-sections.js +13 -0
  145. package/dist/examples/form-dropdown-with-sections.js.map +1 -0
  146. package/dist/examples/form-dropdown-with-sections.vitest.d.ts +2 -0
  147. package/dist/examples/form-dropdown-with-sections.vitest.d.ts.map +1 -0
  148. package/dist/examples/form-dropdown-with-sections.vitest.js +75 -0
  149. package/dist/examples/form-dropdown-with-sections.vitest.js.map +1 -0
  150. package/dist/examples/form-dropdown.vitest.d.ts +2 -0
  151. package/dist/examples/form-dropdown.vitest.d.ts.map +1 -0
  152. package/dist/examples/form-dropdown.vitest.js +854 -0
  153. package/dist/examples/form-dropdown.vitest.js.map +1 -0
  154. package/dist/examples/form-multiselect-dropdown.d.ts +2 -0
  155. package/dist/examples/form-multiselect-dropdown.d.ts.map +1 -0
  156. package/dist/examples/form-multiselect-dropdown.js +13 -0
  157. package/dist/examples/form-multiselect-dropdown.js.map +1 -0
  158. package/dist/examples/form-scroll.d.ts.map +1 -1
  159. package/dist/examples/form-scroll.js +7 -1
  160. package/dist/examples/form-scroll.js.map +1 -1
  161. package/dist/examples/form-scroll.vitest.d.ts +2 -0
  162. package/dist/examples/form-scroll.vitest.d.ts.map +1 -0
  163. package/dist/examples/form-scroll.vitest.js +211 -0
  164. package/dist/examples/form-scroll.vitest.js.map +1 -0
  165. package/dist/examples/form-tagpicker.vitest.d.ts +2 -0
  166. package/dist/examples/form-tagpicker.vitest.d.ts.map +1 -0
  167. package/dist/examples/form-tagpicker.vitest.js +736 -0
  168. package/dist/examples/form-tagpicker.vitest.js.map +1 -0
  169. package/dist/examples/internal/descendants-filtering.js +1 -1
  170. package/dist/examples/internal/descendants-filtering.js.map +1 -1
  171. package/dist/examples/internal/descendants.js +1 -1
  172. package/dist/examples/internal/descendants.js.map +1 -1
  173. package/dist/examples/internal/nested-boxes.d.ts +2 -0
  174. package/dist/examples/internal/nested-boxes.d.ts.map +1 -0
  175. package/dist/examples/internal/nested-boxes.js +7 -0
  176. package/dist/examples/internal/nested-boxes.js.map +1 -0
  177. package/dist/examples/internal/rhf-custom-ref.js +2 -2
  178. package/dist/examples/internal/rhf-custom-ref.js.map +1 -1
  179. package/dist/examples/internal/scrollbox-demo.js +3 -22
  180. package/dist/examples/internal/scrollbox-demo.js.map +1 -1
  181. package/dist/examples/internal/scrollbox-descendants.d.ts +2 -0
  182. package/dist/examples/internal/scrollbox-descendants.d.ts.map +1 -0
  183. package/dist/examples/internal/scrollbox-descendants.js +83 -0
  184. package/dist/examples/internal/scrollbox-descendants.js.map +1 -0
  185. package/dist/examples/internal/scrollbox-with-descendants.js +4 -8
  186. package/dist/examples/internal/scrollbox-with-descendants.js.map +1 -1
  187. package/dist/examples/internal/simple-scrollbox.vitest.d.ts +2 -0
  188. package/dist/examples/internal/simple-scrollbox.vitest.d.ts.map +1 -0
  189. package/dist/examples/internal/simple-scrollbox.vitest.js +96 -0
  190. package/dist/examples/internal/simple-scrollbox.vitest.js.map +1 -0
  191. package/dist/examples/internal/unicode-square-repro.d.ts +2 -0
  192. package/dist/examples/internal/unicode-square-repro.d.ts.map +1 -0
  193. package/dist/examples/internal/unicode-square-repro.js +7 -0
  194. package/dist/examples/internal/unicode-square-repro.js.map +1 -0
  195. package/dist/examples/list-detail-metadata.d.ts +2 -0
  196. package/dist/examples/list-detail-metadata.d.ts.map +1 -0
  197. package/dist/examples/list-detail-metadata.js +8 -0
  198. package/dist/examples/list-detail-metadata.js.map +1 -0
  199. package/dist/examples/list-dropdown-default.vitest.d.ts +2 -0
  200. package/dist/examples/list-dropdown-default.vitest.d.ts.map +1 -0
  201. package/dist/examples/list-dropdown-default.vitest.js +234 -0
  202. package/dist/examples/list-dropdown-default.vitest.js.map +1 -0
  203. package/dist/examples/list-fetch-data.vitest.d.ts +2 -0
  204. package/dist/examples/list-fetch-data.vitest.d.ts.map +1 -0
  205. package/dist/examples/list-fetch-data.vitest.js +111 -0
  206. package/dist/examples/list-fetch-data.vitest.js.map +1 -0
  207. package/dist/examples/list-filter-navigation.d.ts +2 -0
  208. package/dist/examples/list-filter-navigation.d.ts.map +1 -0
  209. package/dist/examples/list-filter-navigation.js +8 -0
  210. package/dist/examples/list-filter-navigation.js.map +1 -0
  211. package/dist/examples/list-scrollbox.vitest.d.ts +2 -0
  212. package/dist/examples/list-scrollbox.vitest.d.ts.map +1 -0
  213. package/dist/examples/list-scrollbox.vitest.js +93 -0
  214. package/dist/examples/list-scrollbox.vitest.js.map +1 -0
  215. package/dist/examples/list-with-detail-long.d.ts +2 -0
  216. package/dist/examples/list-with-detail-long.d.ts.map +1 -0
  217. package/dist/examples/list-with-detail-long.js +53 -0
  218. package/dist/examples/list-with-detail-long.js.map +1 -0
  219. package/dist/examples/list-with-detail.vitest.d.ts +2 -0
  220. package/dist/examples/list-with-detail.vitest.d.ts.map +1 -0
  221. package/dist/examples/list-with-detail.vitest.js +434 -0
  222. package/dist/examples/list-with-detail.vitest.js.map +1 -0
  223. package/dist/examples/list-with-dropdown.vitest.d.ts +2 -0
  224. package/dist/examples/list-with-dropdown.vitest.d.ts.map +1 -0
  225. package/dist/examples/list-with-dropdown.vitest.js +337 -0
  226. package/dist/examples/list-with-dropdown.vitest.js.map +1 -0
  227. package/dist/examples/list-with-sections.js +5 -1
  228. package/dist/examples/list-with-sections.js.map +1 -1
  229. package/dist/examples/list-with-sections.vitest.d.ts +2 -0
  230. package/dist/examples/list-with-sections.vitest.d.ts.map +1 -0
  231. package/dist/examples/list-with-sections.vitest.js +601 -0
  232. package/dist/examples/list-with-sections.vitest.js.map +1 -0
  233. package/dist/examples/scrollbox-vertical-centering.d.ts +6 -0
  234. package/dist/examples/scrollbox-vertical-centering.d.ts.map +1 -0
  235. package/dist/examples/scrollbox-vertical-centering.js +17 -0
  236. package/dist/examples/scrollbox-vertical-centering.js.map +1 -0
  237. package/dist/examples/simple-file-picker.vitest.d.ts +2 -0
  238. package/dist/examples/simple-file-picker.vitest.d.ts.map +1 -0
  239. package/dist/examples/simple-file-picker.vitest.js +678 -0
  240. package/dist/examples/simple-file-picker.vitest.js.map +1 -0
  241. package/dist/examples/simple-grid.vitest.d.ts +2 -0
  242. package/dist/examples/simple-grid.vitest.d.ts.map +1 -0
  243. package/dist/examples/simple-grid.vitest.js +521 -0
  244. package/dist/examples/simple-grid.vitest.js.map +1 -0
  245. package/dist/examples/simple-navigation.js +10 -4
  246. package/dist/examples/simple-navigation.js.map +1 -1
  247. package/dist/examples/simple-navigation.vitest.d.ts +2 -0
  248. package/dist/examples/simple-navigation.vitest.d.ts.map +1 -0
  249. package/dist/examples/simple-navigation.vitest.js +718 -0
  250. package/dist/examples/simple-navigation.vitest.js.map +1 -0
  251. package/dist/examples/store.vitest.d.ts +2 -0
  252. package/dist/examples/store.vitest.d.ts.map +1 -0
  253. package/dist/examples/store.vitest.js +69 -0
  254. package/dist/examples/store.vitest.js.map +1 -0
  255. package/dist/examples/toast-variations.d.ts +2 -0
  256. package/dist/examples/toast-variations.d.ts.map +1 -0
  257. package/dist/examples/toast-variations.js +122 -0
  258. package/dist/examples/toast-variations.js.map +1 -0
  259. package/dist/extensions/dev.d.ts +4 -2
  260. package/dist/extensions/dev.d.ts.map +1 -1
  261. package/dist/extensions/dev.js +61 -10
  262. package/dist/extensions/dev.js.map +1 -1
  263. package/dist/extensions/dev.vitest.d.ts +2 -0
  264. package/dist/extensions/dev.vitest.d.ts.map +1 -0
  265. package/dist/extensions/dev.vitest.js +197 -0
  266. package/dist/extensions/dev.vitest.js.map +1 -0
  267. package/dist/extensions/home.d.ts.map +1 -1
  268. package/dist/extensions/home.js +3 -0
  269. package/dist/extensions/home.js.map +1 -1
  270. package/dist/home-command.d.ts +8 -0
  271. package/dist/home-command.d.ts.map +1 -0
  272. package/dist/home-command.js +181 -0
  273. package/dist/home-command.js.map +1 -0
  274. package/dist/hover-repro.d.ts +2 -0
  275. package/dist/hover-repro.d.ts.map +1 -0
  276. package/dist/hover-repro.js +20 -0
  277. package/dist/hover-repro.js.map +1 -0
  278. package/dist/index.d.ts +1 -0
  279. package/dist/index.d.ts.map +1 -1
  280. package/dist/index.js +2 -0
  281. package/dist/index.js.map +1 -1
  282. package/dist/internal/dialog.d.ts +1 -0
  283. package/dist/internal/dialog.d.ts.map +1 -1
  284. package/dist/internal/dialog.js +27 -18
  285. package/dist/internal/dialog.js.map +1 -1
  286. package/dist/internal/navigation.d.ts +9 -1
  287. package/dist/internal/navigation.d.ts.map +1 -1
  288. package/dist/internal/navigation.js +5 -5
  289. package/dist/internal/navigation.js.map +1 -1
  290. package/dist/internal/offscreen.d.ts +6 -0
  291. package/dist/internal/offscreen.d.ts.map +1 -0
  292. package/dist/internal/offscreen.js +10 -0
  293. package/dist/internal/offscreen.js.map +1 -0
  294. package/dist/internal/providers.d.ts.map +1 -1
  295. package/dist/internal/providers.js +2 -2
  296. package/dist/internal/providers.js.map +1 -1
  297. package/dist/internal/scrollbox.d.ts +1 -10
  298. package/dist/internal/scrollbox.d.ts.map +1 -1
  299. package/dist/internal/scrollbox.js +2 -1
  300. package/dist/internal/scrollbox.js.map +1 -1
  301. package/dist/localstorage.d.ts +13 -0
  302. package/dist/localstorage.d.ts.map +1 -0
  303. package/dist/localstorage.js +190 -0
  304. package/dist/localstorage.js.map +1 -0
  305. package/dist/oauth.d.ts +142 -0
  306. package/dist/oauth.d.ts.map +1 -0
  307. package/dist/oauth.js +551 -0
  308. package/dist/oauth.js.map +1 -0
  309. package/dist/preferences.d.ts +23 -0
  310. package/dist/preferences.d.ts.map +1 -0
  311. package/dist/preferences.js +105 -0
  312. package/dist/preferences.js.map +1 -0
  313. package/dist/release.d.ts +1 -1
  314. package/dist/release.d.ts.map +1 -1
  315. package/dist/release.js +29 -33
  316. package/dist/release.js.map +1 -1
  317. package/dist/state.d.ts +2 -0
  318. package/dist/state.d.ts.map +1 -1
  319. package/dist/state.js +3 -0
  320. package/dist/state.js.map +1 -1
  321. package/dist/store.d.ts +21 -0
  322. package/dist/store.d.ts.map +1 -0
  323. package/dist/store.js +84 -0
  324. package/dist/store.js.map +1 -0
  325. package/dist/swift-loader.d.ts +3 -0
  326. package/dist/swift-loader.d.ts.map +1 -0
  327. package/dist/swift-loader.js +193 -0
  328. package/dist/swift-loader.js.map +1 -0
  329. package/dist/swift-runtime.d.ts +2 -0
  330. package/dist/swift-runtime.d.ts.map +1 -0
  331. package/dist/swift-runtime.js +27 -0
  332. package/dist/swift-runtime.js.map +1 -0
  333. package/dist/toast.d.ts +44 -0
  334. package/dist/toast.d.ts.map +1 -0
  335. package/dist/toast.js +221 -0
  336. package/dist/toast.js.map +1 -0
  337. package/dist/utils/file-system.d.ts +9 -0
  338. package/dist/utils/file-system.d.ts.map +1 -1
  339. package/dist/utils/file-system.js +49 -0
  340. package/dist/utils/file-system.js.map +1 -1
  341. package/dist/utils/run-command.d.ts +26 -1
  342. package/dist/utils/run-command.d.ts.map +1 -1
  343. package/dist/utils/run-command.js +53 -4
  344. package/dist/utils/run-command.js.map +1 -1
  345. package/dist/window.d.ts +12 -0
  346. package/dist/window.d.ts.map +1 -0
  347. package/dist/window.js +48 -0
  348. package/dist/window.js.map +1 -0
  349. package/package.json +12 -12
  350. package/src/apis/browser-extension.tsx +29 -0
  351. package/src/apis/localstorage.test.ts +14 -6
  352. package/src/apis/localstorage.tsx +8 -5
  353. package/src/apis/oauth.tsx +5 -1
  354. package/src/apis/preferences.tsx +48 -22
  355. package/src/apis/toast.tsx +37 -62
  356. package/src/build.test.tsx +52 -0
  357. package/src/build.tsx +3 -1
  358. package/src/cli.tsx +99 -48
  359. package/src/compile.tsx +32 -11
  360. package/src/components/actions.tsx +94 -32
  361. package/src/components/detail.tsx +4 -0
  362. package/src/components/dropdown.tsx +47 -14
  363. package/src/components/extension-preferences.tsx +44 -16
  364. package/src/components/form/checkbox.tsx +12 -6
  365. package/src/components/form/date-picker.tsx +12 -6
  366. package/src/components/form/description.tsx +7 -2
  367. package/src/components/form/dropdown.tsx +131 -119
  368. package/src/components/form/file-autocomplete.tsx +90 -108
  369. package/src/components/form/file-picker.tsx +54 -43
  370. package/src/components/form/form-end.tsx +23 -2
  371. package/src/components/form/index.tsx +168 -41
  372. package/src/components/form/password-field.tsx +12 -6
  373. package/src/components/form/text-area.tsx +13 -6
  374. package/src/components/form/text-field.tsx +13 -6
  375. package/src/components/form/types.tsx +6 -0
  376. package/src/components/form/with-left-border.tsx +41 -8
  377. package/src/components/icon.tsx +27 -8
  378. package/src/components/list.tsx +243 -101
  379. package/src/components/loading-bar.tsx +3 -2
  380. package/src/components/loading-text.tsx +79 -0
  381. package/src/descendants.tsx +1 -0
  382. package/src/examples/file-autocomplete.vitest.tsx +130 -125
  383. package/src/examples/form-basic.vitest.tsx +376 -176
  384. package/src/examples/form-dropdown.vitest.tsx +126 -126
  385. package/src/examples/form-scroll.tsx +2 -0
  386. package/src/examples/form-scroll.vitest.tsx +58 -58
  387. package/src/examples/form-tagpicker.vitest.tsx +99 -99
  388. package/src/examples/internal/descendants-filtering.tsx +1 -0
  389. package/src/examples/internal/descendants.tsx +1 -0
  390. package/src/examples/internal/rhf-custom-ref.tsx +2 -0
  391. package/src/examples/internal/scrollbox-demo.tsx +3 -27
  392. package/src/examples/internal/scrollbox-with-descendants.tsx +4 -7
  393. package/src/examples/internal/simple-scrollbox.vitest.tsx +7 -5
  394. package/src/examples/list-detail-metadata.tsx +49 -0
  395. package/src/examples/list-detail-metadata.vitest.tsx +88 -0
  396. package/src/examples/list-dropdown-default.vitest.tsx +51 -51
  397. package/src/examples/list-fetch-data.vitest.tsx +4 -4
  398. package/src/examples/list-scrollbox.vitest.tsx +73 -14
  399. package/src/examples/list-with-detail-long.tsx +70 -0
  400. package/src/examples/list-with-detail.vitest.tsx +191 -85
  401. package/src/examples/list-with-dropdown.vitest.tsx +53 -53
  402. package/src/examples/list-with-sections.tsx +1 -0
  403. package/src/examples/list-with-sections.vitest.tsx +221 -97
  404. package/src/examples/list-with-toast.vitest.tsx +16 -16
  405. package/src/examples/simple-file-picker.vitest.tsx +63 -469
  406. package/src/examples/simple-grid.vitest.tsx +238 -233
  407. package/src/examples/simple-navigation.tsx +15 -7
  408. package/src/examples/simple-navigation.vitest.tsx +130 -219
  409. package/src/examples/store.vitest.tsx +1 -1
  410. package/src/examples/swift-extension.vitest.tsx +148 -0
  411. package/src/examples/synonyms.vitest.tsx +159 -0
  412. package/src/examples/toast-variations.tsx +150 -0
  413. package/src/examples/toast-variations.vitest.tsx +370 -0
  414. package/src/extensions/dev.tsx +74 -7
  415. package/src/extensions/dev.vitest.tsx +102 -34
  416. package/src/extensions/home.tsx +6 -0
  417. package/src/index.tsx +3 -0
  418. package/src/internal/dialog.tsx +43 -30
  419. package/src/internal/navigation.tsx +3 -1
  420. package/src/internal/offscreen.tsx +15 -0
  421. package/src/internal/providers.tsx +4 -2
  422. package/src/internal/scrollbox.tsx +4 -8
  423. package/src/keyboard.test.tsx +69 -0
  424. package/src/release.tsx +32 -38
  425. package/src/state.tsx +7 -0
  426. package/src/swift-loader.tsx +239 -0
  427. package/src/swift-runtime.tsx +36 -0
  428. package/src/utils/file-system.ts +61 -0
  429. package/src/utils/run-command.tsx +82 -6
@@ -16,6 +16,7 @@ import {
16
16
  import { Theme } from 'termcast/src/theme'
17
17
  import { logger } from 'termcast/src/logger'
18
18
  import { useIsInFocus } from 'termcast/src/internal/focus-context'
19
+ import { useIsOffscreen } from 'termcast/src/internal/offscreen'
19
20
  import { CommonProps } from 'termcast/src/utils'
20
21
  import { createDescendants } from 'termcast/src/descendants'
21
22
  import { ScrollBox } from 'termcast/src/internal/scrollbox'
@@ -107,6 +108,7 @@ const Dropdown: DropdownType = (props) => {
107
108
  throttle,
108
109
  } = props
109
110
 
111
+ const isOffscreen = useIsOffscreen()
110
112
  const [selected, setSelected] = useState(0)
111
113
  const [searchText, setSearchTextState] = useState('')
112
114
  const [currentValue, setCurrentValue] = useState<string | undefined>(
@@ -122,7 +124,14 @@ const Dropdown: DropdownType = (props) => {
122
124
  const setSearchText = (text: string) => {
123
125
  inputRef.current?.setText(text)
124
126
  setSearchTextState(text)
125
- setSelected(0)
127
+ // TODO: use flushSync when available to force descendants to update visibility
128
+ const items = Object.values(descendantsContext.map.current)
129
+ .filter((item: any) => item.index !== -1 && !item.props?.hidden)
130
+ .sort((a: any, b: any) => a.index - b.index)
131
+
132
+ if (items.length > 0 && items[0]) {
133
+ setSelected(items[0].index)
134
+ }
126
135
  }
127
136
 
128
137
  const scrollToItem = (item: { props?: DropdownItemDescendant }) => {
@@ -132,19 +141,13 @@ const Dropdown: DropdownType = (props) => {
132
141
 
133
142
  const contentY = scrollBox.content?.y || 0
134
143
  const viewportHeight = scrollBox.viewport?.height || 10
135
- const currentScrollTop = scrollBox.scrollTop || 0
136
144
 
145
+ // Calculate item position relative to content
137
146
  const itemTop = elementRef.y - contentY
138
- const itemBottom = itemTop + elementRef.height
139
147
 
140
- const visibleTop = currentScrollTop
141
- const visibleBottom = currentScrollTop + viewportHeight
142
-
143
- if (itemTop < visibleTop) {
144
- scrollBox.scrollTo(itemTop)
145
- } else if (itemBottom > visibleBottom) {
146
- scrollBox.scrollTo(itemBottom - viewportHeight)
147
- }
148
+ // Scroll so the top of the item is centered in the viewport
149
+ const targetScrollTop = itemTop - viewportHeight / 2
150
+ scrollBox.scrollTo(Math.max(0, targetScrollTop))
148
151
  }
149
152
 
150
153
  // Create context value for children
@@ -173,9 +176,16 @@ const Dropdown: DropdownType = (props) => {
173
176
  const handleSearchTextChange = (text: string) => {
174
177
  if (!inFocus) return
175
178
 
176
- // Update state for context and reset selection
179
+ // Update state for context
177
180
  setSearchTextState(text)
178
- setSelected(0)
181
+ // TODO: use flushSync when available to force descendants to update visibility
182
+ const items = Object.values(descendantsContext.map.current)
183
+ .filter((item: any) => item.index !== -1 && !item.props?.hidden)
184
+ .sort((a: any, b: any) => a.index - b.index)
185
+
186
+ if (items.length > 0 && items[0]) {
187
+ setSelected(items[0].index)
188
+ }
179
189
 
180
190
  if (onSearchTextChange) {
181
191
  if (throttle) {
@@ -244,18 +254,36 @@ const Dropdown: DropdownType = (props) => {
244
254
  if (evt.name === 'down') {
245
255
  move(1)
246
256
  }
257
+ // Tab and shift+tab for navigation
258
+ if (evt.name === 'tab' && !evt.shift) {
259
+ move(1)
260
+ }
261
+ if (evt.name === 'tab' && evt.shift) {
262
+ move(-1)
263
+ }
247
264
  if (evt.name === 'return') {
248
265
  const items = Object.values(descendantsContext.map.current)
249
266
  .filter((item: any) => item.index !== -1)
250
267
  .sort((a: any, b: any) => a.index - b.index)
251
268
 
252
- const currentItem = items[selected]
269
+ const currentItem = items.find((item) => item.index === selected)
253
270
  if (currentItem?.props) {
254
271
  selectItem((currentItem.props as DropdownItemDescendant).value)
255
272
  }
256
273
  }
257
274
  })
258
275
 
276
+ // When offscreen, just render children to collect descendants without UI
277
+ if (isOffscreen) {
278
+ return (
279
+ <DropdownDescendantsProvider value={descendantsContext}>
280
+ <DropdownContext.Provider value={contextValue}>
281
+ {children}
282
+ </DropdownContext.Provider>
283
+ </DropdownDescendantsProvider>
284
+ )
285
+ }
286
+
259
287
  return (
260
288
  <DropdownDescendantsProvider value={descendantsContext}>
261
289
  <DropdownContext.Provider value={contextValue}>
@@ -275,6 +303,7 @@ const Dropdown: DropdownType = (props) => {
275
303
  <textarea
276
304
  ref={inputRef}
277
305
  height={1}
306
+ wrapMode='none'
278
307
  keyBindings={[
279
308
  { name: 'return', action: 'submit' },
280
309
  { name: 'linefeed', action: 'submit' },
@@ -419,7 +448,11 @@ function ItemOption(props: {
419
448
  const DropdownItem: (props: DropdownItemProps) => any = (props) => {
420
449
  const context = useContext(DropdownContext)
421
450
  const elementRef = useRef<{ y: number; height: number } | null>(null)
451
+ const isOffscreen = useIsOffscreen()
422
452
  if (!context) return null
453
+
454
+ // Don't render UI when offscreen (used for collecting action descendants)
455
+ if (isOffscreen) return null
423
456
 
424
457
  const { searchText, filtering, currentSection, selectedIndex, currentValue } =
425
458
  context
@@ -9,6 +9,7 @@ import { LocalStorage } from 'termcast/src/apis/localstorage'
9
9
  import { useNavigation } from 'termcast/src/internal/navigation'
10
10
  import { logger } from 'termcast/src/logger'
11
11
  import { getStoreDirectory } from 'termcast/src/utils'
12
+ import { useStore } from 'termcast/src/state'
12
13
  import type { RaycastPackageJson } from 'termcast/src/package-json'
13
14
 
14
15
  interface ExtensionPreferencesProps {
@@ -46,17 +47,26 @@ export function ExtensionPreferences({
46
47
  queryKey: ['extension-preferences', extensionName, commandName],
47
48
  queryFn: async () => {
48
49
  try {
49
- const storeDir = getStoreDirectory()
50
- const extensionDir = path.join(storeDir, extensionName)
51
- const packageJsonPath = path.join(extensionDir, 'package.json')
50
+ // First check extensionPath from state (dev mode), then fall back to store directory
51
+ const { extensionPath, extensionPackageJson } = useStore.getState()
52
52
 
53
- if (!fs.existsSync(packageJsonPath)) {
54
- throw new Error(`Extension ${extensionName} not found`)
55
- }
53
+ let packageJson: RaycastPackageJson
54
+
55
+ if (extensionPath && extensionPackageJson?.name === extensionName) {
56
+ // Dev mode - use package.json from state or read from extensionPath
57
+ packageJson = extensionPackageJson
58
+ } else {
59
+ // Store extension - read from store directory
60
+ const storeDir = getStoreDirectory()
61
+ const extensionDir = path.join(storeDir, extensionName)
62
+ const packageJsonPath = path.join(extensionDir, 'package.json')
56
63
 
57
- const packageJson: RaycastPackageJson = JSON.parse(
58
- fs.readFileSync(packageJsonPath, 'utf-8'),
59
- )
64
+ if (!fs.existsSync(packageJsonPath)) {
65
+ throw new Error(`Extension ${extensionName} not found`)
66
+ }
67
+
68
+ packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))
69
+ }
60
70
 
61
71
  let prefsToUse: PreferenceManifest[] = []
62
72
 
@@ -103,11 +113,29 @@ export function ExtensionPreferences({
103
113
 
104
114
  const handleSubmit = async (values: Record<string, any>) => {
105
115
  try {
116
+ // Transform file/directory values from arrays to strings
117
+ // Form.FilePicker returns string[] but Raycast preferences expect string for file/directory types
118
+ const transformedValues: Record<string, any> = {}
119
+ for (const pref of preferences) {
120
+ const value = values[pref.name]
121
+ if (
122
+ (pref.type === 'file' ||
123
+ pref.type === 'directory' ||
124
+ pref.type === 'appPicker') &&
125
+ Array.isArray(value)
126
+ ) {
127
+ // Extract first element from array, or empty string if empty
128
+ transformedValues[pref.name] = value[0] || ''
129
+ } else {
130
+ transformedValues[pref.name] = value
131
+ }
132
+ }
133
+
106
134
  // Save preferences to LocalStorage
107
135
  const preferencesKey = commandName
108
136
  ? `preferences.${extensionName}.${commandName}`
109
137
  : `preferences.${extensionName}`
110
- await LocalStorage.setItem(preferencesKey, JSON.stringify(values))
138
+ await LocalStorage.setItem(preferencesKey, JSON.stringify(transformedValues))
111
139
 
112
140
  await showToast({
113
141
  style: Toast.Style.Success,
@@ -118,7 +146,7 @@ export function ExtensionPreferences({
118
146
  })
119
147
 
120
148
  if (onSubmit) {
121
- onSubmit(values)
149
+ onSubmit(transformedValues)
122
150
  } else {
123
151
  pop()
124
152
  }
@@ -136,11 +164,11 @@ export function ExtensionPreferences({
136
164
  }
137
165
 
138
166
  if (preferences.length === 0) {
139
- // If no preferences but onSubmit provided, call it immediately
140
- if (onSubmit) {
141
- onSubmit({})
142
- return null
143
- }
167
+ // TODO this causes an infinite loop, because initially prefs are zero
168
+ // if (onSubmit) {
169
+ // onSubmit({})
170
+ // return null
171
+ // }
144
172
 
145
173
  return (
146
174
  <Form
@@ -9,6 +9,7 @@ import { Theme } from 'termcast/src/theme'
9
9
  import { WithLeftBorder } from './with-left-border'
10
10
  import { useFormNavigation } from './use-form-navigation'
11
11
  import { useIsInFocus } from 'termcast/src/internal/focus-context'
12
+ import { LoadingText } from 'termcast/src/components/loading-text'
12
13
 
13
14
  export interface CheckboxProps extends FormItemProps<boolean> {
14
15
  label: string
@@ -18,7 +19,8 @@ export type CheckboxRef = FormItemRef
18
19
 
19
20
  export const Checkbox = (props: CheckboxProps): any => {
20
21
  const { control, setValue, getValues } = useFormContext()
21
- const { focusedField, setFocusedField } = useFocusContext()
22
+ const focusContext = useFocusContext()
23
+ const { focusedField, setFocusedField } = focusContext
22
24
  const isFocused = focusedField === props.id
23
25
  const isInFocus = useIsInFocus()
24
26
 
@@ -57,9 +59,8 @@ export const Checkbox = (props: CheckboxProps): any => {
57
59
  render={({ field, fieldState, formState }) => {
58
60
  return (
59
61
  <box ref={elementRef} flexDirection='column'>
60
- <WithLeftBorder withDiamond isFocused={isFocused}>
61
- <text
62
- fg={isFocused ? Theme.primary : Theme.text}
62
+ <WithLeftBorder withDiamond isFocused={isFocused} isLoading={focusContext.isLoading}>
63
+ <box
63
64
  onMouseDown={() => {
64
65
  // Always focus the field when clicked
65
66
  if (!isFocused) {
@@ -69,8 +70,13 @@ export const Checkbox = (props: CheckboxProps): any => {
69
70
  handleToggle()
70
71
  }}
71
72
  >
72
- {props.title}
73
- </text>
73
+ <LoadingText
74
+ isLoading={isFocused && focusContext.isLoading}
75
+ color={isFocused ? Theme.primary : Theme.text}
76
+ >
77
+ {props.title || ''}
78
+ </LoadingText>
79
+ </box>
74
80
  </WithLeftBorder>
75
81
  <WithLeftBorder isFocused={isFocused}>
76
82
  <text
@@ -9,6 +9,7 @@ import { WithLeftBorder } from './with-left-border'
9
9
  import { DatePickerWidget } from 'termcast/src/internal/date-picker-widget'
10
10
  import { useIsInFocus } from 'termcast/src/internal/focus-context'
11
11
  import { useFormNavigationHelpers } from './use-form-navigation'
12
+ import { LoadingText } from 'termcast/src/components/loading-text'
12
13
 
13
14
  export enum DatePickerType {
14
15
  Date = 'date',
@@ -30,7 +31,8 @@ interface DatePickerComponentType {
30
31
 
31
32
  const DatePickerComponent = (props: DatePickerProps): any => {
32
33
  const { control } = useFormContext()
33
- const { focusedField, setFocusedField } = useFocusContext()
34
+ const focusContext = useFocusContext()
35
+ const { focusedField, setFocusedField } = focusContext
34
36
  const isFocused = focusedField === props.id
35
37
  const isInFocus = useIsInFocus()
36
38
 
@@ -65,15 +67,19 @@ const DatePickerComponent = (props: DatePickerProps): any => {
65
67
  render={({ field, fieldState, formState }) => {
66
68
  return (
67
69
  <box ref={elementRef} flexDirection='column'>
68
- <WithLeftBorder withDiamond isFocused={isFocused}>
69
- <text
70
- fg={isFocused ? Theme.primary : Theme.text}
70
+ <WithLeftBorder withDiamond isFocused={isFocused} isLoading={focusContext.isLoading}>
71
+ <box
71
72
  onMouseDown={() => {
72
73
  setFocusedField(props.id)
73
74
  }}
74
75
  >
75
- {props.title}
76
- </text>
76
+ <LoadingText
77
+ isLoading={isFocused && focusContext.isLoading}
78
+ color={isFocused ? Theme.primary : Theme.text}
79
+ >
80
+ {props.title || ''}
81
+ </LoadingText>
82
+ </box>
77
83
  </WithLeftBorder>
78
84
  <WithLeftBorder isFocused={isFocused}>
79
85
  <DatePickerWidget
@@ -4,6 +4,7 @@ import { Theme } from 'termcast/src/theme'
4
4
  import { WithLeftBorder } from './with-left-border'
5
5
  import { useFocusContext, useFormFieldDescendant } from './index'
6
6
  import { useFormNavigation } from './use-form-navigation'
7
+ import { LoadingText } from 'termcast/src/components/loading-text'
7
8
 
8
9
  export interface DescriptionProps {
9
10
  id?: string
@@ -44,10 +45,14 @@ export const Description = (props: DescriptionProps): any => {
44
45
  <WithLeftBorder
45
46
  customCharacter={{ focused: '■', unfocused: '▪︎' }}
46
47
  isFocused={isFocused}
48
+ isLoading={focusContext.isLoading}
47
49
  >
48
- <text fg={Theme.text} attributes={TextAttributes.BOLD}>
50
+ <LoadingText
51
+ isLoading={isFocused && focusContext.isLoading}
52
+ color={isFocused ? Theme.primary : Theme.text}
53
+ >
49
54
  {props.title}
50
- </text>
55
+ </LoadingText>
51
56
  </WithLeftBorder>
52
57
  )}
53
58
  <WithLeftBorder isFocused={isFocused}>