@opencode/ui 0.0.0-reserved → 2.0.1

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 (520) hide show
  1. package/LICENSE +21 -0
  2. package/dist/actions/button/button.d.ts +10 -0
  3. package/dist/actions/icon-button/icon-button.d.ts +11 -0
  4. package/dist/actions/split-button/split-button.d.ts +5 -0
  5. package/dist/components/animated-number.d.ts +4 -0
  6. package/dist/components/app-icon.d.ts +6 -0
  7. package/dist/components/app-icons/types.d.ts +2 -0
  8. package/dist/components/card.d.ts +22 -0
  9. package/dist/components/collapsible.d.ts +17 -0
  10. package/dist/components/context-menu.d.ts +80 -0
  11. package/dist/components/dock-surface.d.ts +7 -0
  12. package/dist/components/favicon.d.ts +1 -0
  13. package/dist/components/file-icon.d.ts +12 -0
  14. package/dist/components/file-icons/types.d.ts +2 -0
  15. package/dist/components/font.d.ts +1 -0
  16. package/dist/components/hover-card.d.ts +9 -0
  17. package/dist/components/image-preview.d.ts +5 -0
  18. package/dist/components/list.d.ts +45 -0
  19. package/dist/components/logo.d.ts +8 -0
  20. package/dist/components/motion-spring.d.ts +4 -0
  21. package/dist/components/popover.d.ts +14 -0
  22. package/dist/components/progress.d.ts +7 -0
  23. package/dist/components/provider-icon.d.ts +5 -0
  24. package/dist/components/provider-icons/types.d.ts +2 -0
  25. package/dist/components/resize-handle.d.ts +14 -0
  26. package/dist/components/scroll-view.d.ts +42 -0
  27. package/dist/components/spinner.d.ts +6 -0
  28. package/dist/components/sticky-accordion-header.d.ts +5 -0
  29. package/dist/components/text-field.d.ts +13 -0
  30. package/dist/components/text-reveal.d.ts +13 -0
  31. package/dist/components/text-strikethrough.d.ts +11 -0
  32. package/dist/components/typewriter.d.ts +6 -0
  33. package/dist/context/dialog.d.ts +18 -0
  34. package/dist/context/file.d.ts +5 -0
  35. package/dist/context/helper.d.ts +14 -0
  36. package/dist/context/i18n.d.ts +24 -0
  37. package/dist/context/index.d.ts +4 -0
  38. package/dist/context/marked-base.d.ts +3 -0
  39. package/dist/context/marked-parser.d.ts +1 -0
  40. package/dist/context/marked-theme-register.d.ts +1 -0
  41. package/dist/context/marked-theme.d.ts +2 -0
  42. package/dist/context/marked.d.ts +2 -0
  43. package/dist/context/worker-pool.d.ts +9 -0
  44. package/dist/data-display/accordion/accordion.d.ts +24 -0
  45. package/dist/data-display/avatar/avatar.d.ts +11 -0
  46. package/dist/data-display/badge/badge.d.ts +7 -0
  47. package/dist/data-display/diff-changes/diff-changes.d.ts +12 -0
  48. package/dist/data-display/keybind/keybind.d.ts +7 -0
  49. package/dist/data-display/line-comment/line-comment.d.ts +32 -0
  50. package/dist/data-display/project-avatar/project-avatar.d.ts +12 -0
  51. package/dist/feedback/loader/loader.d.ts +3 -0
  52. package/dist/feedback/progress-circle/progress-circle.d.ts +9 -0
  53. package/dist/feedback/toast/toast.d.ts +57 -0
  54. package/dist/forms/checkbox/checkbox.d.ts +8 -0
  55. package/dist/forms/field/field.d.ts +22 -0
  56. package/dist/forms/inline-input/inline-input.d.ts +5 -0
  57. package/dist/forms/radio/radio.d.ts +16 -0
  58. package/dist/forms/select/select.d.ts +23 -0
  59. package/dist/forms/switch/switch.d.ts +9 -0
  60. package/dist/forms/text-input/text-input.d.ts +24 -0
  61. package/dist/forms/textarea/textarea.d.ts +7 -0
  62. package/dist/hooks/create-auto-scroll.d.ts +17 -0
  63. package/dist/hooks/index.d.ts +2 -0
  64. package/dist/hooks/use-filtered-list.d.ts +48 -0
  65. package/dist/i18n/am.d.ts +1 -0
  66. package/dist/i18n/ar.d.ts +209 -0
  67. package/dist/i18n/az.d.ts +1 -0
  68. package/dist/i18n/bg.d.ts +193 -0
  69. package/dist/i18n/bn.d.ts +1 -0
  70. package/dist/i18n/br.d.ts +197 -0
  71. package/dist/i18n/bs.d.ts +197 -0
  72. package/dist/i18n/ca.d.ts +1 -0
  73. package/dist/i18n/cs.d.ts +1 -0
  74. package/dist/i18n/da.d.ts +193 -0
  75. package/dist/i18n/de.d.ts +193 -0
  76. package/dist/i18n/dv.d.ts +1 -0
  77. package/dist/i18n/dz.d.ts +1 -0
  78. package/dist/i18n/el.d.ts +1 -0
  79. package/dist/i18n/en.d.ts +251 -0
  80. package/dist/i18n/es.d.ts +197 -0
  81. package/dist/i18n/et.d.ts +1 -0
  82. package/dist/i18n/fa.d.ts +1 -0
  83. package/dist/i18n/fi.d.ts +1 -0
  84. package/dist/i18n/fo.d.ts +1 -0
  85. package/dist/i18n/fr.d.ts +197 -0
  86. package/dist/i18n/he.d.ts +197 -0
  87. package/dist/i18n/hi.d.ts +1 -0
  88. package/dist/i18n/hr.d.ts +1 -0
  89. package/dist/i18n/hu.d.ts +1 -0
  90. package/dist/i18n/hy.d.ts +1 -0
  91. package/dist/i18n/id.d.ts +1 -0
  92. package/dist/i18n/is.d.ts +1 -0
  93. package/dist/i18n/it.d.ts +1 -0
  94. package/dist/i18n/ja.d.ts +193 -0
  95. package/dist/i18n/ka.d.ts +1 -0
  96. package/dist/i18n/km.d.ts +193 -0
  97. package/dist/i18n/ko.d.ts +193 -0
  98. package/dist/i18n/lo.d.ts +193 -0
  99. package/dist/i18n/lt.d.ts +1 -0
  100. package/dist/i18n/lv.d.ts +1 -0
  101. package/dist/i18n/mk.d.ts +193 -0
  102. package/dist/i18n/mn.d.ts +193 -0
  103. package/dist/i18n/ms.d.ts +1 -0
  104. package/dist/i18n/my.d.ts +193 -0
  105. package/dist/i18n/ne.d.ts +1 -0
  106. package/dist/i18n/nl.d.ts +1 -0
  107. package/dist/i18n/no.d.ts +4 -0
  108. package/dist/i18n/pa.d.ts +1 -0
  109. package/dist/i18n/pl.d.ts +201 -0
  110. package/dist/i18n/ro.d.ts +1 -0
  111. package/dist/i18n/ru.d.ts +201 -0
  112. package/dist/i18n/si.d.ts +1 -0
  113. package/dist/i18n/sk.d.ts +1 -0
  114. package/dist/i18n/sl.d.ts +1 -0
  115. package/dist/i18n/sq.d.ts +1 -0
  116. package/dist/i18n/sr.d.ts +197 -0
  117. package/dist/i18n/sv.d.ts +1 -0
  118. package/dist/i18n/tg.d.ts +193 -0
  119. package/dist/i18n/th.d.ts +193 -0
  120. package/dist/i18n/tk.d.ts +1 -0
  121. package/dist/i18n/tr.d.ts +193 -0
  122. package/dist/i18n/uk.d.ts +1 -0
  123. package/dist/i18n/ur.d.ts +1 -0
  124. package/dist/i18n/uz.d.ts +1 -0
  125. package/dist/i18n/vi.d.ts +1 -0
  126. package/dist/i18n/zh.d.ts +193 -0
  127. package/dist/i18n/zht.d.ts +193 -0
  128. package/dist/icons/icon/additional-icons.d.ts +105 -0
  129. package/dist/icons/icon/icon.d.ts +228 -0
  130. package/dist/layout/divider/divider.d.ts +5 -0
  131. package/dist/navigation/menu/menu.d.ts +59 -0
  132. package/dist/navigation/segmented-control/segmented-control.d.ts +21 -0
  133. package/dist/navigation/tab-state-indicator.d.ts +2 -0
  134. package/dist/navigation/tabs/tabs.d.ts +39 -0
  135. package/dist/overlays/dialog/dialog.d.ts +26 -0
  136. package/dist/overlays/tooltip/tooltip.d.ts +15 -0
  137. package/dist/storybook/fixtures.d.ts +19 -0
  138. package/dist/storybook/scaffold.d.ts +16 -0
  139. package/dist/theme/color.d.ts +30 -0
  140. package/dist/theme/context.d.ts +21 -0
  141. package/dist/theme/default-themes.d.ts +39 -0
  142. package/dist/theme/index.d.ts +7 -0
  143. package/dist/theme/loader.d.ts +6 -0
  144. package/dist/theme/resolve.d.ts +7 -0
  145. package/dist/theme/types.d.ts +56 -0
  146. package/dist/theme/v2/avatar.d.ts +5 -0
  147. package/dist/theme/v2/default-primitives.d.ts +3 -0
  148. package/dist/theme/v2/foreground.d.ts +2 -0
  149. package/dist/theme/v2/mapping.d.ts +3 -0
  150. package/dist/theme/v2/resolve.d.ts +9 -0
  151. package/dist/typography/text-shimmer/text-shimmer.d.ts +9 -0
  152. package/dist/typography/wordmark/wordmark.d.ts +5 -0
  153. package/package.json +252 -6
  154. package/src/actions/button/button.css +294 -0
  155. package/src/actions/button/button.tsx +42 -0
  156. package/src/actions/icon-button/icon-button.css +124 -0
  157. package/src/actions/icon-button/icon-button.tsx +32 -0
  158. package/src/actions/split-button/split-button.css +95 -0
  159. package/src/actions/split-button/split-button.tsx +48 -0
  160. package/src/actions/submit.css +74 -0
  161. package/src/assets/audio/alert-01.aac +0 -0
  162. package/src/assets/audio/alert-01.mp3 +0 -0
  163. package/src/assets/audio/alert-02.aac +0 -0
  164. package/src/assets/audio/alert-02.mp3 +0 -0
  165. package/src/assets/audio/alert-03.aac +0 -0
  166. package/src/assets/audio/alert-03.mp3 +0 -0
  167. package/src/assets/audio/alert-04.aac +0 -0
  168. package/src/assets/audio/alert-04.mp3 +0 -0
  169. package/src/assets/audio/alert-05.aac +0 -0
  170. package/src/assets/audio/alert-05.mp3 +0 -0
  171. package/src/assets/audio/alert-06.aac +0 -0
  172. package/src/assets/audio/alert-06.mp3 +0 -0
  173. package/src/assets/audio/alert-07.aac +0 -0
  174. package/src/assets/audio/alert-07.mp3 +0 -0
  175. package/src/assets/audio/alert-08.aac +0 -0
  176. package/src/assets/audio/alert-08.mp3 +0 -0
  177. package/src/assets/audio/alert-09.aac +0 -0
  178. package/src/assets/audio/alert-09.mp3 +0 -0
  179. package/src/assets/audio/alert-10.aac +0 -0
  180. package/src/assets/audio/alert-10.mp3 +0 -0
  181. package/src/assets/audio/bip-bop-01.aac +0 -0
  182. package/src/assets/audio/bip-bop-01.mp3 +0 -0
  183. package/src/assets/audio/bip-bop-02.aac +0 -0
  184. package/src/assets/audio/bip-bop-02.mp3 +0 -0
  185. package/src/assets/audio/bip-bop-03.aac +0 -0
  186. package/src/assets/audio/bip-bop-03.mp3 +0 -0
  187. package/src/assets/audio/bip-bop-04.aac +0 -0
  188. package/src/assets/audio/bip-bop-04.mp3 +0 -0
  189. package/src/assets/audio/bip-bop-05.aac +0 -0
  190. package/src/assets/audio/bip-bop-05.mp3 +0 -0
  191. package/src/assets/audio/bip-bop-06.aac +0 -0
  192. package/src/assets/audio/bip-bop-06.mp3 +0 -0
  193. package/src/assets/audio/bip-bop-07.aac +0 -0
  194. package/src/assets/audio/bip-bop-07.mp3 +0 -0
  195. package/src/assets/audio/bip-bop-08.aac +0 -0
  196. package/src/assets/audio/bip-bop-08.mp3 +0 -0
  197. package/src/assets/audio/bip-bop-09.aac +0 -0
  198. package/src/assets/audio/bip-bop-09.mp3 +0 -0
  199. package/src/assets/audio/bip-bop-10.aac +0 -0
  200. package/src/assets/audio/bip-bop-10.mp3 +0 -0
  201. package/src/assets/audio/nope-01.aac +0 -0
  202. package/src/assets/audio/nope-01.mp3 +0 -0
  203. package/src/assets/audio/nope-02.aac +0 -0
  204. package/src/assets/audio/nope-02.mp3 +0 -0
  205. package/src/assets/audio/nope-03.aac +0 -0
  206. package/src/assets/audio/nope-03.mp3 +0 -0
  207. package/src/assets/audio/nope-04.aac +0 -0
  208. package/src/assets/audio/nope-04.mp3 +0 -0
  209. package/src/assets/audio/nope-05.aac +0 -0
  210. package/src/assets/audio/nope-05.mp3 +0 -0
  211. package/src/assets/audio/nope-06.aac +0 -0
  212. package/src/assets/audio/nope-06.mp3 +0 -0
  213. package/src/assets/audio/nope-07.aac +0 -0
  214. package/src/assets/audio/nope-07.mp3 +0 -0
  215. package/src/assets/audio/nope-08.aac +0 -0
  216. package/src/assets/audio/nope-08.mp3 +0 -0
  217. package/src/assets/audio/nope-09.aac +0 -0
  218. package/src/assets/audio/nope-09.mp3 +0 -0
  219. package/src/assets/audio/nope-10.aac +0 -0
  220. package/src/assets/audio/nope-10.mp3 +0 -0
  221. package/src/assets/audio/nope-11.aac +0 -0
  222. package/src/assets/audio/nope-11.mp3 +0 -0
  223. package/src/assets/audio/nope-12.aac +0 -0
  224. package/src/assets/audio/nope-12.mp3 +0 -0
  225. package/src/assets/audio/staplebops-01.aac +0 -0
  226. package/src/assets/audio/staplebops-01.mp3 +0 -0
  227. package/src/assets/audio/staplebops-02.aac +0 -0
  228. package/src/assets/audio/staplebops-02.mp3 +0 -0
  229. package/src/assets/audio/staplebops-03.aac +0 -0
  230. package/src/assets/audio/staplebops-03.mp3 +0 -0
  231. package/src/assets/audio/staplebops-04.aac +0 -0
  232. package/src/assets/audio/staplebops-04.mp3 +0 -0
  233. package/src/assets/audio/staplebops-05.aac +0 -0
  234. package/src/assets/audio/staplebops-05.mp3 +0 -0
  235. package/src/assets/audio/staplebops-06.aac +0 -0
  236. package/src/assets/audio/staplebops-06.mp3 +0 -0
  237. package/src/assets/audio/staplebops-07.aac +0 -0
  238. package/src/assets/audio/staplebops-07.mp3 +0 -0
  239. package/src/assets/audio/yup-01.aac +0 -0
  240. package/src/assets/audio/yup-01.mp3 +0 -0
  241. package/src/assets/audio/yup-02.aac +0 -0
  242. package/src/assets/audio/yup-02.mp3 +0 -0
  243. package/src/assets/audio/yup-03.aac +0 -0
  244. package/src/assets/audio/yup-03.mp3 +0 -0
  245. package/src/assets/audio/yup-04.aac +0 -0
  246. package/src/assets/audio/yup-04.mp3 +0 -0
  247. package/src/assets/audio/yup-05.aac +0 -0
  248. package/src/assets/audio/yup-05.mp3 +0 -0
  249. package/src/assets/audio/yup-06.aac +0 -0
  250. package/src/assets/audio/yup-06.mp3 +0 -0
  251. package/src/assets/fonts/Inter.ttf +0 -0
  252. package/src/assets/fonts/JetBrainsMonoNerdFontMono-Regular.woff2 +0 -0
  253. package/src/assets/icons/app/android-studio.svg +369 -0
  254. package/src/assets/icons/app/antigravity.svg +97 -0
  255. package/src/assets/icons/app/cursor.svg +16 -0
  256. package/src/assets/icons/app/file-explorer.svg +20 -0
  257. package/src/assets/icons/app/finder.png +0 -0
  258. package/src/assets/icons/app/ghostty.svg +13 -0
  259. package/src/assets/icons/app/iterm2.svg +13 -0
  260. package/src/assets/icons/app/powershell.svg +14 -0
  261. package/src/assets/icons/app/sublimetext.svg +17 -0
  262. package/src/assets/icons/app/terminal.png +0 -0
  263. package/src/assets/icons/app/textmate.png +0 -0
  264. package/src/assets/icons/app/vscode.svg +39 -0
  265. package/src/assets/icons/app/warp.png +0 -0
  266. package/src/assets/icons/app/xcode.png +0 -0
  267. package/src/assets/icons/app/zed-dark.svg +15 -0
  268. package/src/assets/icons/app/zed.svg +15 -0
  269. package/src/components/animated-number.css +93 -0
  270. package/src/components/animated-number.tsx +109 -0
  271. package/src/components/app-icon.css +5 -0
  272. package/src/components/app-icon.tsx +85 -0
  273. package/src/components/app-icons/sprite.svg +114 -0
  274. package/src/components/app-icons/types.ts +21 -0
  275. package/src/components/card.css +94 -0
  276. package/src/components/card.tsx +123 -0
  277. package/src/components/collapsible.css +154 -0
  278. package/src/components/collapsible.tsx +48 -0
  279. package/src/components/context-menu.css +134 -0
  280. package/src/components/context-menu.tsx +308 -0
  281. package/src/components/dock-surface.css +30 -0
  282. package/src/components/dock-surface.tsx +54 -0
  283. package/src/components/favicon.tsx +13 -0
  284. package/src/components/file-icon.css +26 -0
  285. package/src/components/file-icon.tsx +588 -0
  286. package/src/components/file-icons/sprite.svg +11707 -0
  287. package/src/components/file-icons/types.ts +1095 -0
  288. package/src/components/font.tsx +1 -0
  289. package/src/components/hover-card.css +61 -0
  290. package/src/components/hover-card.tsx +32 -0
  291. package/src/components/image-preview.css +63 -0
  292. package/src/components/image-preview.tsx +33 -0
  293. package/src/components/list.css +331 -0
  294. package/src/components/list.tsx +396 -0
  295. package/src/components/logo.css +4 -0
  296. package/src/components/logo.tsx +62 -0
  297. package/src/components/motion-spring.tsx +58 -0
  298. package/src/components/popover.css +98 -0
  299. package/src/components/popover.tsx +154 -0
  300. package/src/components/progress.css +63 -0
  301. package/src/components/progress.tsx +39 -0
  302. package/src/components/provider-icon.css +5 -0
  303. package/src/components/provider-icon.tsx +25 -0
  304. package/src/components/provider-icons/sprite.svg +1110 -0
  305. package/src/components/provider-icons/types.ts +105 -0
  306. package/src/components/resize-handle.css +70 -0
  307. package/src/components/resize-handle.tsx +102 -0
  308. package/src/components/scroll-view.css +99 -0
  309. package/src/components/scroll-view.tsx +453 -0
  310. package/src/components/spinner.css +6 -0
  311. package/src/components/spinner.tsx +52 -0
  312. package/src/components/sticky-accordion-header.css +6 -0
  313. package/src/components/sticky-accordion-header.tsx +18 -0
  314. package/src/components/text-field.css +134 -0
  315. package/src/components/text-field.tsx +136 -0
  316. package/src/components/text-reveal.css +150 -0
  317. package/src/components/text-reveal.tsx +143 -0
  318. package/src/components/text-strikethrough.css +27 -0
  319. package/src/components/text-strikethrough.tsx +84 -0
  320. package/src/components/typewriter.css +14 -0
  321. package/src/components/typewriter.tsx +55 -0
  322. package/src/context/dialog.tsx +198 -0
  323. package/src/context/file.tsx +10 -0
  324. package/src/context/helper.tsx +38 -0
  325. package/src/context/i18n.tsx +77 -0
  326. package/src/context/index.ts +4 -0
  327. package/src/context/marked-base.tsx +55 -0
  328. package/src/context/marked-parser.tsx +58 -0
  329. package/src/context/marked-theme-register.tsx +10 -0
  330. package/src/context/marked-theme.tsx +372 -0
  331. package/src/context/marked.tsx +28 -0
  332. package/src/context/worker-pool.tsx +20 -0
  333. package/src/custom-elements.d.ts +17 -0
  334. package/src/data-display/accordion/accordion.css +121 -0
  335. package/src/data-display/accordion/accordion.tsx +92 -0
  336. package/src/data-display/avatar/avatar.css +70 -0
  337. package/src/data-display/avatar/avatar.tsx +59 -0
  338. package/src/data-display/badge/badge.css +52 -0
  339. package/src/data-display/badge/badge.tsx +25 -0
  340. package/src/data-display/diff-changes/diff-changes.css +47 -0
  341. package/src/data-display/diff-changes/diff-changes.tsx +33 -0
  342. package/src/data-display/keybind/keybind.css +76 -0
  343. package/src/data-display/keybind/keybind.tsx +30 -0
  344. package/src/data-display/line-comment/line-comment.css +258 -0
  345. package/src/data-display/line-comment/line-comment.tsx +308 -0
  346. package/src/data-display/project-avatar/project-avatar.css +132 -0
  347. package/src/data-display/project-avatar/project-avatar.tsx +66 -0
  348. package/src/feedback/loader/loader.css +32 -0
  349. package/src/feedback/loader/loader.tsx +31 -0
  350. package/src/feedback/progress-circle/progress-circle.css +28 -0
  351. package/src/feedback/progress-circle/progress-circle.tsx +64 -0
  352. package/src/feedback/toast/toast.css +225 -0
  353. package/src/feedback/toast/toast.tsx +283 -0
  354. package/src/forms/checkbox/checkbox.css +125 -0
  355. package/src/forms/checkbox/checkbox.tsx +43 -0
  356. package/src/forms/field/field.css +94 -0
  357. package/src/forms/field/field.tsx +263 -0
  358. package/src/forms/inline-input/inline-input.css +17 -0
  359. package/src/forms/inline-input/inline-input.tsx +22 -0
  360. package/src/forms/radio/radio.css +202 -0
  361. package/src/forms/radio/radio.tsx +82 -0
  362. package/src/forms/select/select.css +290 -0
  363. package/src/forms/select/select.tsx +219 -0
  364. package/src/forms/switch/switch.css +272 -0
  365. package/src/forms/switch/switch.tsx +34 -0
  366. package/src/forms/text-input/text-input.css +181 -0
  367. package/src/forms/text-input/text-input.tsx +99 -0
  368. package/src/forms/textarea/textarea.css +78 -0
  369. package/src/forms/textarea/textarea.tsx +31 -0
  370. package/src/hooks/create-auto-scroll.tsx +257 -0
  371. package/src/hooks/index.ts +2 -0
  372. package/src/hooks/use-filtered-list.tsx +134 -0
  373. package/src/i18n/am.ts +194 -0
  374. package/src/i18n/ar.ts +231 -0
  375. package/src/i18n/az.ts +195 -0
  376. package/src/i18n/bg.ts +195 -0
  377. package/src/i18n/bn.ts +197 -0
  378. package/src/i18n/br.ts +219 -0
  379. package/src/i18n/bs.ts +223 -0
  380. package/src/i18n/ca.ts +199 -0
  381. package/src/i18n/cs.ts +203 -0
  382. package/src/i18n/da.ts +214 -0
  383. package/src/i18n/de.ts +219 -0
  384. package/src/i18n/dv.ts +196 -0
  385. package/src/i18n/dz.ts +197 -0
  386. package/src/i18n/el.ts +195 -0
  387. package/src/i18n/en.ts +276 -0
  388. package/src/i18n/es.ts +219 -0
  389. package/src/i18n/et.ts +195 -0
  390. package/src/i18n/fa.ts +195 -0
  391. package/src/i18n/fi.ts +195 -0
  392. package/src/i18n/fo.ts +195 -0
  393. package/src/i18n/fr.ts +221 -0
  394. package/src/i18n/he.ts +199 -0
  395. package/src/i18n/hi.ts +197 -0
  396. package/src/i18n/hr.ts +200 -0
  397. package/src/i18n/hu.ts +197 -0
  398. package/src/i18n/hy.ts +195 -0
  399. package/src/i18n/id.ts +217 -0
  400. package/src/i18n/is.ts +195 -0
  401. package/src/i18n/it.ts +200 -0
  402. package/src/i18n/ja.ts +214 -0
  403. package/src/i18n/ka.ts +195 -0
  404. package/src/i18n/km.ts +196 -0
  405. package/src/i18n/ko.ts +216 -0
  406. package/src/i18n/lo.ts +195 -0
  407. package/src/i18n/lt.ts +203 -0
  408. package/src/i18n/lv.ts +199 -0
  409. package/src/i18n/mk.ts +195 -0
  410. package/src/i18n/mn.ts +195 -0
  411. package/src/i18n/ms.ts +195 -0
  412. package/src/i18n/my.ts +196 -0
  413. package/src/i18n/ne.ts +197 -0
  414. package/src/i18n/nl.ts +195 -0
  415. package/src/i18n/no.ts +219 -0
  416. package/src/i18n/pa.ts +196 -0
  417. package/src/i18n/pl.ts +223 -0
  418. package/src/i18n/ro.ts +199 -0
  419. package/src/i18n/ru.ts +222 -0
  420. package/src/i18n/si.ts +195 -0
  421. package/src/i18n/sk.ts +203 -0
  422. package/src/i18n/sl.ts +204 -0
  423. package/src/i18n/sq.ts +195 -0
  424. package/src/i18n/sr.ts +200 -0
  425. package/src/i18n/sv.ts +195 -0
  426. package/src/i18n/tg.ts +195 -0
  427. package/src/i18n/th.ts +215 -0
  428. package/src/i18n/tk.ts +195 -0
  429. package/src/i18n/tr.ts +221 -0
  430. package/src/i18n/uk.ts +226 -0
  431. package/src/i18n/ur.ts +196 -0
  432. package/src/i18n/uz.ts +198 -0
  433. package/src/i18n/vi.ts +195 -0
  434. package/src/i18n/zh.ts +217 -0
  435. package/src/i18n/zht.ts +217 -0
  436. package/src/icons/icon/additional-icons.ts +115 -0
  437. package/src/icons/icon/icon.css +3 -0
  438. package/src/icons/icon/icon.tsx +305 -0
  439. package/src/layout/divider/divider.css +11 -0
  440. package/src/layout/divider/divider.tsx +20 -0
  441. package/src/navigation/menu/menu.css +311 -0
  442. package/src/navigation/menu/menu.tsx +289 -0
  443. package/src/navigation/segmented-control/segmented-control.css +80 -0
  444. package/src/navigation/segmented-control/segmented-control.tsx +209 -0
  445. package/src/navigation/tab-state-indicator.tsx +37 -0
  446. package/src/navigation/tabs/tabs-current.css +239 -0
  447. package/src/navigation/tabs/tabs.css +710 -0
  448. package/src/navigation/tabs/tabs.tsx +194 -0
  449. package/src/overlays/dialog/dialog.css +180 -0
  450. package/src/overlays/dialog/dialog.tsx +115 -0
  451. package/src/overlays/tooltip/tooltip.css +102 -0
  452. package/src/overlays/tooltip/tooltip.tsx +154 -0
  453. package/src/storybook/fixtures.ts +51 -0
  454. package/src/storybook/scaffold.tsx +62 -0
  455. package/src/styles/animations.css +141 -0
  456. package/src/styles/base.css +409 -0
  457. package/src/styles/colors.css +772 -0
  458. package/src/styles/file-tree.css +202 -0
  459. package/src/styles/index.css +37 -0
  460. package/src/styles/tailwind/colors.css +288 -0
  461. package/src/styles/tailwind/index.css +95 -0
  462. package/src/styles/tailwind/utilities.css +131 -0
  463. package/src/styles/theme.css +631 -0
  464. package/src/styles/tokens/colors.css +172 -0
  465. package/src/styles/tokens/index.css +2 -0
  466. package/src/styles/tokens/theme.css +510 -0
  467. package/src/styles/utilities.css +118 -0
  468. package/src/theme/color.ts +299 -0
  469. package/src/theme/context.tsx +381 -0
  470. package/src/theme/default-themes.ts +116 -0
  471. package/src/theme/index.ts +78 -0
  472. package/src/theme/loader.ts +112 -0
  473. package/src/theme/resolve.ts +540 -0
  474. package/src/theme/themes/amoled.json +49 -0
  475. package/src/theme/themes/aura.json +51 -0
  476. package/src/theme/themes/ayu.json +51 -0
  477. package/src/theme/themes/carbonfox.json +53 -0
  478. package/src/theme/themes/catppuccin-frappe.json +85 -0
  479. package/src/theme/themes/catppuccin-macchiato.json +85 -0
  480. package/src/theme/themes/catppuccin.json +45 -0
  481. package/src/theme/themes/cobalt2.json +87 -0
  482. package/src/theme/themes/cursor.json +91 -0
  483. package/src/theme/themes/dracula.json +49 -0
  484. package/src/theme/themes/everforest.json +89 -0
  485. package/src/theme/themes/flexoki.json +86 -0
  486. package/src/theme/themes/github.json +85 -0
  487. package/src/theme/themes/gruvbox.json +45 -0
  488. package/src/theme/themes/kanagawa.json +89 -0
  489. package/src/theme/themes/lucent-orng.json +87 -0
  490. package/src/theme/themes/material.json +87 -0
  491. package/src/theme/themes/matrix.json +113 -0
  492. package/src/theme/themes/mercury.json +86 -0
  493. package/src/theme/themes/monokai.json +49 -0
  494. package/src/theme/themes/nightowl.json +46 -0
  495. package/src/theme/themes/nord.json +46 -0
  496. package/src/theme/themes/oc-2.json +507 -0
  497. package/src/theme/themes/one-dark.json +89 -0
  498. package/src/theme/themes/onedarkpro.json +45 -0
  499. package/src/theme/themes/opencode.json +89 -0
  500. package/src/theme/themes/orng.json +87 -0
  501. package/src/theme/themes/osaka-jade.json +88 -0
  502. package/src/theme/themes/palenight.json +85 -0
  503. package/src/theme/themes/rosepine.json +85 -0
  504. package/src/theme/themes/shadesofpurple.json +51 -0
  505. package/src/theme/themes/solarized.json +49 -0
  506. package/src/theme/themes/synthwave84.json +87 -0
  507. package/src/theme/themes/tokyonight.json +47 -0
  508. package/src/theme/themes/vercel.json +90 -0
  509. package/src/theme/themes/vesper.json +51 -0
  510. package/src/theme/themes/zenburn.json +87 -0
  511. package/src/theme/types.ts +75 -0
  512. package/src/theme/v2/avatar.ts +48 -0
  513. package/src/theme/v2/default-primitives.ts +114 -0
  514. package/src/theme/v2/foreground.ts +61 -0
  515. package/src/theme/v2/mapping.ts +176 -0
  516. package/src/theme/v2/resolve.ts +153 -0
  517. package/src/typography/text-shimmer/text-shimmer.css +120 -0
  518. package/src/typography/text-shimmer/text-shimmer.tsx +63 -0
  519. package/src/typography/wordmark/wordmark.tsx +39 -0
  520. package/README.md +0 -5
@@ -0,0 +1,453 @@
1
+ import { createEffect, mergeProps, onCleanup, onMount, Show, splitProps, type ComponentProps } from "solid-js"
2
+ import { Portal } from "solid-js/web"
3
+ import { createResizeObserver } from "@solid-primitives/resize-observer"
4
+ import { createStore } from "solid-js/store"
5
+ import { useI18n } from "../context/i18n"
6
+
7
+ export type ScrollViewThumbVisibility = "hover" | "scroll"
8
+
9
+ export interface ScrollViewProps extends ComponentProps<"div"> {
10
+ viewportRef?: (el: HTMLDivElement) => void
11
+ orientation?: "vertical" | "horizontal" | "both"
12
+ /**
13
+ * `hover`: show while hovered or scrolling. `scroll`: show only while scrolling.
14
+ *
15
+ * In most cases, scrolling a container = hovering over it, so this change has no effect.
16
+ * This is a special case to account for the home page scroll, where scrolling a container != hovering over it
17
+ * */
18
+ thumbVisibility?: ScrollViewThumbVisibility
19
+ /** Mount the thumb into an external track. Scroll metrics still come from this ScrollView. */
20
+ thumbContainer?: HTMLElement
21
+ /** Element whose hover reveals the thumb. Defaults to the ScrollView root when unset. */
22
+ thumbHoverTarget?: HTMLElement
23
+ }
24
+
25
+ export const scrollKey = (event: Pick<KeyboardEvent, "key" | "altKey" | "ctrlKey" | "metaKey" | "shiftKey">) => {
26
+ if (event.altKey || event.ctrlKey || event.metaKey) return
27
+ if (event.shiftKey && event.key !== " ") return
28
+
29
+ switch (event.key) {
30
+ case "PageDown":
31
+ return "page-down"
32
+ case "PageUp":
33
+ return "page-up"
34
+ case "Home":
35
+ return "home"
36
+ case "End":
37
+ return "end"
38
+ case "ArrowUp":
39
+ return "up"
40
+ case "ArrowDown":
41
+ return "down"
42
+ case " ":
43
+ return event.shiftKey ? "page-up" : "page-down"
44
+ }
45
+ }
46
+
47
+ export function canScrollKey(element: HTMLElement, key: NonNullable<ReturnType<typeof scrollKey>>) {
48
+ const up = key === "up" || key === "page-up" || key === "home"
49
+ return up ? element.scrollTop > 0 : element.scrollTop + element.clientHeight < element.scrollHeight
50
+ }
51
+
52
+ export function scrollKeyOwner(
53
+ root: HTMLElement,
54
+ target: EventTarget | null,
55
+ key: NonNullable<ReturnType<typeof scrollKey>>,
56
+ ) {
57
+ const element = target instanceof Element ? target : undefined
58
+ const owner = element?.closest<HTMLElement>("[data-scrollable]")
59
+ if (!owner || owner === root) return root
60
+ if (!root.contains(owner)) return owner
61
+ return canScrollKey(owner, key) ? owner : root
62
+ }
63
+
64
+ export function isScrollKeyTarget(target: EventTarget | null, key: NonNullable<ReturnType<typeof scrollKey>>) {
65
+ const element = target instanceof HTMLElement ? target : undefined
66
+ if (!element) return true
67
+ if (["INPUT", "TEXTAREA", "SELECT"].includes(element.tagName) || element.isContentEditable) return false
68
+ if ((key === "page-up" || key === "page-down") && element.closest('button, a[href], [role="button"]')) return false
69
+ return true
70
+ }
71
+
72
+ export function scrollTopFromThumbPointer(input: {
73
+ pointer: number
74
+ viewportTop: number
75
+ grabOffset: number
76
+ clientHeight: number
77
+ scrollHeight: number
78
+ thumbHeight: number
79
+ /** Viewport height used for max scroll. Defaults to `clientHeight` (track == viewport). */
80
+ scrollClientHeight?: number
81
+ }) {
82
+ return scrollOffsetFromThumbPointer({
83
+ pointer: input.pointer,
84
+ viewportStart: input.viewportTop,
85
+ grabOffset: input.grabOffset,
86
+ clientSize: input.clientHeight,
87
+ scrollSize: input.scrollHeight,
88
+ thumbSize: input.thumbHeight,
89
+ scrollClientSize: input.scrollClientHeight,
90
+ })
91
+ }
92
+
93
+ export function scrollOffsetFromThumbPointer(input: {
94
+ pointer: number
95
+ viewportStart: number
96
+ grabOffset: number
97
+ clientSize: number
98
+ scrollSize: number
99
+ thumbSize: number
100
+ scrollClientSize?: number
101
+ reverse?: boolean
102
+ }) {
103
+ const padding = 8
104
+ const maxThumbStart = input.clientSize - padding * 2 - input.thumbSize
105
+ if (maxThumbStart <= 0) return 0
106
+ const thumbStart = Math.max(
107
+ 0,
108
+ Math.min(input.pointer - input.viewportStart - padding - input.grabOffset, maxThumbStart),
109
+ )
110
+ const progress = input.reverse ? 1 - thumbStart / maxThumbStart : thumbStart / maxThumbStart
111
+ return progress * Math.max(0, input.scrollSize - (input.scrollClientSize ?? input.clientSize))
112
+ }
113
+
114
+ export function ScrollView(props: ScrollViewProps) {
115
+ const i18n = useI18n()
116
+ const merged = mergeProps({ orientation: "vertical", thumbVisibility: "hover" }, props)
117
+ const [local, events, rest] = splitProps(
118
+ merged,
119
+ [
120
+ "class",
121
+ "children",
122
+ "viewportRef",
123
+ "orientation",
124
+ "thumbVisibility",
125
+ "thumbContainer",
126
+ "thumbHoverTarget",
127
+ "style",
128
+ ],
129
+ [
130
+ "onScroll",
131
+ "onWheel",
132
+ "onTouchStart",
133
+ "onTouchMove",
134
+ "onTouchEnd",
135
+ "onTouchCancel",
136
+ "onPointerDown",
137
+ "onClick",
138
+ "onKeyDown",
139
+ ],
140
+ )
141
+
142
+ let rootRef!: HTMLDivElement
143
+ let viewportRef!: HTMLDivElement
144
+ let verticalThumbRef!: HTMLDivElement
145
+ let horizontalThumbRef!: HTMLDivElement
146
+
147
+ const thumbMount = () => local.thumbContainer
148
+ const thumbHover = () => local.thumbHoverTarget
149
+ const hoverRoot = () => !local.thumbHoverTarget && !local.thumbContainer
150
+
151
+ const [state, setState] = createStore({
152
+ isHovered: false,
153
+ dragging: undefined as "vertical" | "horizontal" | undefined,
154
+ isScrolling: false,
155
+ verticalThumbSize: 0,
156
+ verticalThumbStart: 0,
157
+ showVerticalThumb: false,
158
+ horizontalThumbSize: 0,
159
+ horizontalThumbStart: 0,
160
+ showHorizontalThumb: false,
161
+ })
162
+ const isHovered = () => state.isHovered
163
+ const isDragging = () => state.dragging !== undefined
164
+ const isScrolling = () => state.isScrolling
165
+ const vertical = () => local.orientation === "vertical" || local.orientation === "both"
166
+ const horizontal = () => local.orientation === "horizontal" || local.orientation === "both"
167
+
168
+ let scrollIdleTimer: ReturnType<typeof setTimeout> | undefined
169
+
170
+ const markScrolling = () => {
171
+ setState("isScrolling", true)
172
+ if (scrollIdleTimer !== undefined) clearTimeout(scrollIdleTimer)
173
+ scrollIdleTimer = setTimeout(() => setState("isScrolling", false), 800)
174
+ }
175
+
176
+ const thumbVisible = () => {
177
+ if (isDragging()) return true
178
+ if (isScrolling()) return true
179
+ return local.thumbVisibility === "hover" && isHovered()
180
+ }
181
+
182
+ onCleanup(() => {
183
+ if (scrollIdleTimer !== undefined) clearTimeout(scrollIdleTimer)
184
+ })
185
+
186
+ const updateThumb = () => {
187
+ if (!viewportRef) return
188
+ const trackPadding = 8
189
+ const minThumbSize = 32
190
+
191
+ if (vertical()) {
192
+ const trackSize = Math.max(0, (thumbMount()?.clientHeight || viewportRef.clientHeight) - trackPadding * 2)
193
+ const size = trackSize
194
+ ? Math.min(trackSize, Math.max((viewportRef.clientHeight / viewportRef.scrollHeight) * trackSize, minThumbSize))
195
+ : 0
196
+ const maxScroll = viewportRef.scrollHeight - viewportRef.clientHeight
197
+ const maxStart = trackSize - size
198
+ setState("showVerticalThumb", maxScroll > 0)
199
+ setState("verticalThumbSize", size)
200
+ setState(
201
+ "verticalThumbStart",
202
+ trackPadding + (maxScroll > 0 ? (viewportRef.scrollTop / maxScroll) * maxStart : 0),
203
+ )
204
+ } else {
205
+ setState("showVerticalThumb", false)
206
+ }
207
+
208
+ if (horizontal()) {
209
+ const trackSize = Math.max(0, (thumbMount()?.clientWidth || viewportRef.clientWidth) - trackPadding * 2)
210
+ const size = trackSize
211
+ ? Math.min(trackSize, Math.max((viewportRef.clientWidth / viewportRef.scrollWidth) * trackSize, minThumbSize))
212
+ : 0
213
+ const maxScroll = viewportRef.scrollWidth - viewportRef.clientWidth
214
+ const maxStart = trackSize - size
215
+ const rtl = getComputedStyle(viewportRef).direction === "rtl"
216
+ const offset = Math.max(0, Math.min(rtl ? -viewportRef.scrollLeft : viewportRef.scrollLeft, maxScroll))
217
+ const start = maxScroll > 0 ? (offset / maxScroll) * maxStart : 0
218
+ setState("showHorizontalThumb", maxScroll > 0)
219
+ setState("horizontalThumbSize", size)
220
+ setState("horizontalThumbStart", trackPadding + (rtl ? maxStart - start : start))
221
+ } else {
222
+ setState("showHorizontalThumb", false)
223
+ }
224
+ }
225
+
226
+ onMount(() => {
227
+ if (local.viewportRef) {
228
+ local.viewportRef(viewportRef)
229
+ }
230
+
231
+ createResizeObserver(
232
+ () => [viewportRef, viewportRef.firstElementChild, thumbMount()].filter(Boolean) as HTMLElement[],
233
+ updateThumb,
234
+ )
235
+
236
+ updateThumb()
237
+ })
238
+
239
+ createEffect(() => {
240
+ thumbMount()
241
+ updateThumb()
242
+ })
243
+
244
+ createEffect(() => {
245
+ if (!horizontal() || !viewportRef) return
246
+ const observer = new MutationObserver(updateThumb)
247
+ observer.observe(viewportRef, { childList: true, subtree: true, characterData: true })
248
+ onCleanup(() => observer.disconnect())
249
+ })
250
+
251
+ createEffect(() => {
252
+ const target = thumbHover()
253
+ if (!target) return
254
+
255
+ const enter = () => setState("isHovered", true)
256
+ const leave = () => setState("isHovered", false)
257
+ target.addEventListener("pointerenter", enter)
258
+ target.addEventListener("pointerleave", leave)
259
+ onCleanup(() => {
260
+ target.removeEventListener("pointerenter", enter)
261
+ target.removeEventListener("pointerleave", leave)
262
+ setState("isHovered", false)
263
+ })
264
+ })
265
+
266
+ const onThumbPointerDown = (axis: "vertical" | "horizontal", e: PointerEvent) => {
267
+ e.preventDefault()
268
+ e.stopPropagation()
269
+ setState("dragging", axis)
270
+ const thumb = axis === "vertical" ? verticalThumbRef : horizontalThumbRef
271
+ const grabOffset =
272
+ axis === "vertical"
273
+ ? e.clientY - thumb.getBoundingClientRect().top
274
+ : e.clientX - thumb.getBoundingClientRect().left
275
+ const track = thumbMount() ?? viewportRef
276
+
277
+ thumb.setPointerCapture(e.pointerId)
278
+
279
+ const onPointerMove = (e: PointerEvent) => {
280
+ const vertical = axis === "vertical"
281
+ const rtl = !vertical && getComputedStyle(viewportRef).direction === "rtl"
282
+ const offset = scrollOffsetFromThumbPointer({
283
+ pointer: vertical ? e.clientY : e.clientX,
284
+ viewportStart: vertical ? track.getBoundingClientRect().top : track.getBoundingClientRect().left,
285
+ grabOffset,
286
+ clientSize: vertical ? track.clientHeight : track.clientWidth,
287
+ scrollClientSize: vertical ? viewportRef.clientHeight : viewportRef.clientWidth,
288
+ scrollSize: vertical ? viewportRef.scrollHeight : viewportRef.scrollWidth,
289
+ thumbSize: vertical ? state.verticalThumbSize : state.horizontalThumbSize,
290
+ reverse: rtl,
291
+ })
292
+ if (vertical) {
293
+ viewportRef.scrollTop = offset
294
+ return
295
+ }
296
+ viewportRef.scrollLeft = rtl ? -offset : offset
297
+ }
298
+
299
+ const done = (e: PointerEvent) => {
300
+ setState("dragging", undefined)
301
+ thumb.releasePointerCapture(e.pointerId)
302
+ thumb.removeEventListener("pointermove", onPointerMove)
303
+ thumb.removeEventListener("pointerup", done)
304
+ thumb.removeEventListener("pointercancel", done)
305
+ }
306
+
307
+ thumb.addEventListener("pointermove", onPointerMove)
308
+ thumb.addEventListener("pointerup", done)
309
+ thumb.addEventListener("pointercancel", done)
310
+ }
311
+
312
+ const renderVerticalThumb = () => (
313
+ <div
314
+ ref={(el) => {
315
+ verticalThumbRef = el
316
+ }}
317
+ onPointerDown={(event) => onThumbPointerDown("vertical", event)}
318
+ class="scroll-view__thumb"
319
+ data-orientation="vertical"
320
+ data-visible={thumbVisible()}
321
+ data-dragging={state.dragging === "vertical"}
322
+ style={{
323
+ height: `${state.verticalThumbSize}px`,
324
+ transform: `translateY(${state.verticalThumbStart}px)`,
325
+ "z-index": 100, // ensure it displays over content
326
+ }}
327
+ />
328
+ )
329
+
330
+ const renderHorizontalThumb = () => (
331
+ <div
332
+ ref={(el) => {
333
+ horizontalThumbRef = el
334
+ }}
335
+ onPointerDown={(event) => onThumbPointerDown("horizontal", event)}
336
+ class="scroll-view__thumb"
337
+ data-orientation="horizontal"
338
+ data-visible={thumbVisible()}
339
+ data-dragging={state.dragging === "horizontal"}
340
+ style={{
341
+ width: `${state.horizontalThumbSize}px`,
342
+ transform: `translateX(${state.horizontalThumbStart}px)`,
343
+ "z-index": 100,
344
+ }}
345
+ />
346
+ )
347
+
348
+ // Keybinds implementation
349
+ // We ensure the viewport has a tabindex so it can receive focus
350
+ // We can also explicitly catch PageUp/Down if we want smooth scroll or specific behavior,
351
+ // but native usually handles this perfectly. Let's explicitly ensure it behaves well.
352
+ const onKeyDown = (e: KeyboardEvent) => {
353
+ // If user is focused on an input inside the scroll view, don't hijack keys
354
+ if (document.activeElement && ["INPUT", "TEXTAREA", "SELECT"].includes(document.activeElement.tagName)) {
355
+ return
356
+ }
357
+ const next = scrollKey(e)
358
+ if (!next) return
359
+ if (!isScrollKeyTarget(e.target, next)) return
360
+ if (scrollKeyOwner(viewportRef, e.target, next) !== viewportRef) return
361
+
362
+ const scrollAmount = viewportRef.clientHeight * 0.8
363
+ const lineAmount = 40
364
+
365
+ switch (next) {
366
+ case "page-down":
367
+ e.preventDefault()
368
+ viewportRef.scrollBy({ top: scrollAmount, behavior: "smooth" })
369
+ break
370
+ case "page-up":
371
+ e.preventDefault()
372
+ viewportRef.scrollBy({ top: -scrollAmount, behavior: "smooth" })
373
+ break
374
+ case "home":
375
+ e.preventDefault()
376
+ viewportRef.scrollTo({ top: 0, behavior: "smooth" })
377
+ break
378
+ case "end":
379
+ e.preventDefault()
380
+ viewportRef.scrollTo({ top: viewportRef.scrollHeight, behavior: "smooth" })
381
+ break
382
+ case "up":
383
+ e.preventDefault()
384
+ viewportRef.scrollBy({ top: -lineAmount, behavior: "smooth" })
385
+ break
386
+ case "down":
387
+ e.preventDefault()
388
+ viewportRef.scrollBy({ top: lineAmount, behavior: "smooth" })
389
+ break
390
+ }
391
+ }
392
+
393
+ return (
394
+ <div
395
+ ref={rootRef}
396
+ class={`scroll-view ${local.class || ""}`}
397
+ data-orientation={local.orientation}
398
+ style={local.style}
399
+ onPointerEnter={() => {
400
+ if (hoverRoot()) setState("isHovered", true)
401
+ }}
402
+ onPointerLeave={() => {
403
+ if (hoverRoot()) setState("isHovered", false)
404
+ }}
405
+ {...rest}
406
+ >
407
+ {/* Viewport */}
408
+ <div
409
+ ref={viewportRef}
410
+ class="scroll-view__viewport"
411
+ data-scrollable
412
+ onScroll={(e) => {
413
+ updateThumb()
414
+ markScrolling()
415
+ if (typeof events.onScroll === "function") events.onScroll(e as any)
416
+ }}
417
+ onWheel={(e) => {
418
+ markScrolling()
419
+ const handler = events.onWheel
420
+ if (typeof handler === "function") handler(e as any)
421
+ if (Array.isArray(handler)) handler[0](handler[1], e as any)
422
+ }}
423
+ onTouchStart={events.onTouchStart as any}
424
+ onTouchMove={events.onTouchMove as any}
425
+ onTouchEnd={events.onTouchEnd as any}
426
+ onTouchCancel={events.onTouchCancel as any}
427
+ onPointerDown={events.onPointerDown as any}
428
+ onClick={events.onClick as any}
429
+ tabIndex={0}
430
+ role="region"
431
+ aria-label={i18n.t("ui.scrollView.ariaLabel")}
432
+ onKeyDown={(e) => {
433
+ onKeyDown(e)
434
+ if (typeof events.onKeyDown === "function") events.onKeyDown(e as any)
435
+ }}
436
+ >
437
+ {local.children}
438
+ </div>
439
+
440
+ {/* Thumb Overlay — optionally portaled into an external track */}
441
+ <Show when={state.showVerticalThumb}>
442
+ <Show when={thumbMount()} fallback={renderVerticalThumb()}>
443
+ {(mount) => <Portal mount={mount()}>{renderVerticalThumb()}</Portal>}
444
+ </Show>
445
+ </Show>
446
+ <Show when={state.showHorizontalThumb}>
447
+ <Show when={thumbMount()} fallback={renderHorizontalThumb()}>
448
+ {(mount) => <Portal mount={mount()}>{renderHorizontalThumb()}</Portal>}
449
+ </Show>
450
+ </Show>
451
+ </div>
452
+ )
453
+ }
@@ -0,0 +1,6 @@
1
+ [data-component="spinner"] {
2
+ color: inherit;
3
+ flex-shrink: 0;
4
+ width: 18px;
5
+ aspect-ratio: 1;
6
+ }
@@ -0,0 +1,52 @@
1
+ import { ComponentProps, For } from "solid-js"
2
+
3
+ const outerIndices = new Set([1, 2, 4, 7, 8, 11, 13, 14])
4
+ const cornerIndices = new Set([0, 3, 12, 15])
5
+ const squares = Array.from({ length: 16 }, (_, i) => ({
6
+ id: i,
7
+ x: (i % 4) * 4,
8
+ y: Math.floor(i / 4) * 4,
9
+ delay: Math.random() * 1.5,
10
+ duration: 1 + Math.random() * 1,
11
+ outer: outerIndices.has(i),
12
+ corner: cornerIndices.has(i),
13
+ }))
14
+
15
+ export function Spinner(props: {
16
+ class?: string
17
+ classList?: ComponentProps<"div">["classList"]
18
+ style?: ComponentProps<"div">["style"]
19
+ }) {
20
+ return (
21
+ <svg
22
+ {...props}
23
+ viewBox="0 0 15 15"
24
+ data-component="spinner"
25
+ classList={{
26
+ ...props.classList,
27
+ [props.class ?? ""]: !!props.class,
28
+ }}
29
+ fill="currentColor"
30
+ >
31
+ <For each={squares}>
32
+ {(square) => (
33
+ <rect
34
+ x={square.x}
35
+ y={square.y}
36
+ width="3"
37
+ height="3"
38
+ rx="1"
39
+ style={{
40
+ opacity: square.corner ? 0 : undefined,
41
+ animation: square.corner
42
+ ? undefined
43
+ : `${square.outer ? "pulse-opacity-dim" : "pulse-opacity"} ${square.duration}s ease-in-out infinite`,
44
+ "animation-fill-mode": square.corner ? undefined : "both",
45
+ "animation-delay": square.corner ? undefined : `${square.delay}s`,
46
+ }}
47
+ />
48
+ )}
49
+ </For>
50
+ </svg>
51
+ )
52
+ }
@@ -0,0 +1,6 @@
1
+ [data-component="sticky-accordion-header"] {
2
+ position: sticky;
3
+ top: calc(var(--sticky-accordion-top, 0px) + var(--sticky-accordion-offset, 0px));
4
+ z-index: 10;
5
+ background-color: var(--background-stronger);
6
+ }
@@ -0,0 +1,18 @@
1
+ import { Accordion } from "@opencode/ui/accordion"
2
+ import { ParentProps } from "solid-js"
3
+
4
+ export function StickyAccordionHeader(
5
+ props: ParentProps<{ class?: string; classList?: Record<string, boolean | undefined> }>,
6
+ ) {
7
+ return (
8
+ <Accordion.Header
9
+ data-component="sticky-accordion-header"
10
+ classList={{
11
+ ...props.classList,
12
+ [props.class ?? ""]: !!props.class,
13
+ }}
14
+ >
15
+ {props.children}
16
+ </Accordion.Header>
17
+ )
18
+ }
@@ -0,0 +1,134 @@
1
+ [data-component="input"] {
2
+ width: 100%;
3
+
4
+ [data-slot="input-input"] {
5
+ width: 100%;
6
+ color: var(--text-strong);
7
+
8
+ /* text-14-regular */
9
+ font-family: var(--font-family-sans);
10
+ font-size: 14px;
11
+ font-style: normal;
12
+ font-weight: var(--font-weight-regular);
13
+ line-height: var(--line-height-large); /* 142.857% */
14
+ letter-spacing: var(--letter-spacing-normal);
15
+
16
+ &:focus {
17
+ outline: none;
18
+ }
19
+
20
+ &::placeholder {
21
+ color: var(--text-weak);
22
+ }
23
+ }
24
+
25
+ &[data-variant="normal"] {
26
+ display: flex;
27
+ flex-direction: column;
28
+ align-items: flex-start;
29
+ gap: 8px;
30
+
31
+ [data-slot="input-label"] {
32
+ color: var(--text-weak);
33
+
34
+ /* text-12-medium */
35
+ font-family: var(--font-family-sans);
36
+ font-size: var(--font-size-small);
37
+ font-style: normal;
38
+ font-weight: var(--font-weight-medium);
39
+ line-height: 18px; /* 150% */
40
+ letter-spacing: var(--letter-spacing-normal);
41
+ }
42
+
43
+ [data-slot="input-wrapper"] {
44
+ display: flex;
45
+ align-items: start;
46
+ justify-content: space-between;
47
+ width: 100%;
48
+ padding-inline-end: 4px;
49
+
50
+ border-radius: var(--radius-md);
51
+ border: 1px solid var(--border-weak-base);
52
+ background: var(--input-base);
53
+
54
+ &:focus-within:not(:has([data-readonly])) {
55
+ border-color: transparent;
56
+ /* border/shadow-xs/select */
57
+ box-shadow:
58
+ 0 0 0 3px var(--border-weak-selected),
59
+ 0 0 0 1px var(--border-selected),
60
+ 0 1px 2px -1px rgba(19, 16, 16, 0.25),
61
+ 0 1px 2px 0 rgba(19, 16, 16, 0.08),
62
+ 0 1px 3px 0 rgba(19, 16, 16, 0.12);
63
+ }
64
+
65
+ &:has([data-invalid]) {
66
+ background: var(--surface-critical-weak);
67
+ border: 1px solid var(--border-critical-selected);
68
+ }
69
+
70
+ &:not(:has([data-slot="input-copy-button"])) {
71
+ padding-inline-end: 0;
72
+ }
73
+ }
74
+
75
+ [data-slot="input-input"] {
76
+ color: var(--text-strong);
77
+
78
+ display: flex;
79
+ height: 32px;
80
+ padding: 2px 12px;
81
+ align-items: center;
82
+ flex: 1;
83
+ min-width: 0;
84
+
85
+ background: transparent;
86
+ border: none;
87
+
88
+ /* text-14-regular */
89
+ font-family: var(--font-family-sans);
90
+ font-size: 14px;
91
+ font-style: normal;
92
+ font-weight: var(--font-weight-regular);
93
+ line-height: var(--line-height-large); /* 142.857% */
94
+ letter-spacing: var(--letter-spacing-normal);
95
+
96
+ &:focus {
97
+ outline: none;
98
+ }
99
+
100
+ &::placeholder {
101
+ color: var(--text-weak);
102
+ }
103
+ }
104
+
105
+ textarea[data-slot="input-input"] {
106
+ height: auto;
107
+ min-height: 32px;
108
+ padding: 6px 12px;
109
+ resize: none;
110
+ }
111
+
112
+ [data-slot="input-copy-button"] {
113
+ flex-shrink: 0;
114
+ margin-top: 4px;
115
+ color: var(--icon-base);
116
+
117
+ &:hover {
118
+ color: var(--icon-strong-base);
119
+ }
120
+ }
121
+
122
+ [data-slot="input-error"] {
123
+ color: var(--text-on-critical-base);
124
+
125
+ /* text-12-medium */
126
+ font-family: var(--font-family-sans);
127
+ font-size: var(--font-size-small);
128
+ font-style: normal;
129
+ font-weight: var(--font-weight-medium);
130
+ line-height: 18px; /* 150% */
131
+ letter-spacing: var(--letter-spacing-normal);
132
+ }
133
+ }
134
+ }