@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,381 @@
1
+ // @refresh reload
2
+
3
+ import { createEffect, onMount } from "solid-js"
4
+ import { createStore } from "solid-js/store"
5
+ import { makeEventListener } from "@solid-primitives/event-listener"
6
+ import { createSimpleContext } from "../context/helper"
7
+ import oc2ThemeJson from "./themes/oc-2.json"
8
+ import { resolveThemeVariant, themeToCss } from "./resolve"
9
+ import { resolveThemeVariantV2, themeV2ToCss } from "./v2/resolve"
10
+ import type { DesktopTheme } from "./types"
11
+
12
+ export type ColorScheme = "light" | "dark" | "system"
13
+
14
+ const STORAGE_KEYS = {
15
+ THEME_ID: "opencode-theme-id",
16
+ COLOR_SCHEME: "opencode-color-scheme",
17
+ THEME_CSS_LIGHT: "opencode-theme-css-light",
18
+ THEME_CSS_DARK: "opencode-theme-css-dark",
19
+ } as const
20
+
21
+ const THEME_STYLE_ID = "oc-theme"
22
+ let files: Record<string, () => Promise<{ default: DesktopTheme }>> | undefined
23
+ let ids: string[] | undefined
24
+ let known: Set<string> | undefined
25
+
26
+ function getFiles() {
27
+ if (files) return files
28
+ files = import.meta.glob<{ default: DesktopTheme }>("./themes/*.json")
29
+ return files
30
+ }
31
+
32
+ function themeIDs() {
33
+ if (ids) return ids
34
+ ids = Object.keys(getFiles())
35
+ .map((path) => path.slice("./themes/".length, -".json".length))
36
+ .sort()
37
+ return ids
38
+ }
39
+
40
+ function knownThemes() {
41
+ if (known) return known
42
+ known = new Set(themeIDs())
43
+ return known
44
+ }
45
+
46
+ const names: Record<string, string> = {
47
+ "oc-2": "OC-2",
48
+ amoled: "AMOLED",
49
+ aura: "Aura",
50
+ ayu: "Ayu",
51
+ carbonfox: "Carbonfox",
52
+ catppuccin: "Catppuccin",
53
+ "catppuccin-frappe": "Catppuccin Frappe",
54
+ "catppuccin-macchiato": "Catppuccin Macchiato",
55
+ cobalt2: "Cobalt2",
56
+ cursor: "Cursor",
57
+ dracula: "Dracula",
58
+ everforest: "Everforest",
59
+ flexoki: "Flexoki",
60
+ github: "GitHub",
61
+ gruvbox: "Gruvbox",
62
+ kanagawa: "Kanagawa",
63
+ "lucent-orng": "Lucent Orng",
64
+ material: "Material",
65
+ matrix: "Matrix",
66
+ mercury: "Mercury",
67
+ monokai: "Monokai",
68
+ nightowl: "Night Owl",
69
+ nord: "Nord",
70
+ "one-dark": "One Dark",
71
+ onedarkpro: "One Dark Pro",
72
+ opencode: "OpenCode",
73
+ orng: "Orng",
74
+ "osaka-jade": "Osaka Jade",
75
+ palenight: "Palenight",
76
+ rosepine: "Rose Pine",
77
+ shadesofpurple: "Shades of Purple",
78
+ solarized: "Solarized",
79
+ synthwave84: "Synthwave '84",
80
+ tokyonight: "Tokyonight",
81
+ vercel: "Vercel",
82
+ vesper: "Vesper",
83
+ zenburn: "Zenburn",
84
+ }
85
+ const oc2Theme = oc2ThemeJson as DesktopTheme
86
+
87
+ function resolveStoredTheme(id: string | null | undefined, registered?: Record<string, DesktopTheme>) {
88
+ if (id === "oc-2" || (id && (knownThemes().has(id) || registered?.[id]))) return id
89
+ return "oc-2"
90
+ }
91
+
92
+ function read(key: string) {
93
+ if (typeof localStorage !== "object") return null
94
+ try {
95
+ return localStorage.getItem(key)
96
+ } catch {
97
+ return null
98
+ }
99
+ }
100
+
101
+ function write(key: string, value: string) {
102
+ if (typeof localStorage !== "object") return
103
+ try {
104
+ localStorage.setItem(key, value)
105
+ } catch {}
106
+ }
107
+
108
+ function drop(key: string) {
109
+ if (typeof localStorage !== "object") return
110
+ try {
111
+ localStorage.removeItem(key)
112
+ } catch {}
113
+ }
114
+
115
+ function clear() {
116
+ drop(STORAGE_KEYS.THEME_CSS_LIGHT)
117
+ drop(STORAGE_KEYS.THEME_CSS_DARK)
118
+ }
119
+
120
+ function ensureThemeStyleElement(): HTMLStyleElement {
121
+ const existing = document.getElementById(THEME_STYLE_ID) as HTMLStyleElement | null
122
+ if (existing) return existing
123
+ const element = document.createElement("style")
124
+ element.id = THEME_STYLE_ID
125
+ document.head.appendChild(element)
126
+ return element
127
+ }
128
+
129
+ function getSystemMode(): "light" | "dark" {
130
+ if (typeof window !== "object") return "light"
131
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"
132
+ }
133
+
134
+ function applyThemeCss(theme: DesktopTheme, themeId: string, mode: "light" | "dark") {
135
+ const isDark = mode === "dark"
136
+ const variant = isDark ? theme.dark : theme.light
137
+ const tokens = resolveThemeVariant(variant, isDark)
138
+ const css = themeToCss(tokens)
139
+ const v2 = themeV2ToCss(resolveThemeVariantV2(variant, isDark))
140
+
141
+ if (themeId !== "oc-2") {
142
+ write(isDark ? STORAGE_KEYS.THEME_CSS_DARK : STORAGE_KEYS.THEME_CSS_LIGHT, `${css}\n ${v2}`)
143
+ }
144
+
145
+ const fullCss = `:root {
146
+ color-scheme: ${mode};
147
+ --text-mix-blend-mode: ${isDark ? "plus-lighter" : "multiply"};
148
+ ${css}
149
+ ${v2}
150
+ }`
151
+
152
+ document.getElementById("oc-theme-preload")?.remove()
153
+ ensureThemeStyleElement().textContent = fullCss
154
+ document.documentElement.dataset.theme = themeId
155
+ document.documentElement.dataset.colorScheme = mode
156
+ document.documentElement.style.backgroundColor = isDark ? "#080808" : "#fafafa"
157
+
158
+ // Update theme-color meta tag to match light/dark mode
159
+ const meta = document.querySelector('meta[name="theme-color"]')
160
+ if (meta) meta.setAttribute("content", isDark ? "#080808" : "#fafafa")
161
+ }
162
+
163
+ function cacheThemeVariants(theme: DesktopTheme, themeId: string) {
164
+ if (themeId === "oc-2") return
165
+ for (const mode of ["light", "dark"] as const) {
166
+ const isDark = mode === "dark"
167
+ const variant = isDark ? theme.dark : theme.light
168
+ const tokens = resolveThemeVariant(variant, isDark)
169
+ const css = themeToCss(tokens)
170
+ const v2 = themeV2ToCss(resolveThemeVariantV2(variant, isDark))
171
+ write(isDark ? STORAGE_KEYS.THEME_CSS_DARK : STORAGE_KEYS.THEME_CSS_LIGHT, `${css}\n ${v2}`)
172
+ }
173
+ }
174
+
175
+ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
176
+ name: "Theme",
177
+ init: (props: {
178
+ defaultTheme?: string
179
+ onThemeApplied?: (theme: DesktopTheme, mode: "light" | "dark", scheme: ColorScheme) => void
180
+ }) => {
181
+ const rawTheme = read(STORAGE_KEYS.THEME_ID) ?? props.defaultTheme
182
+ const themeId = resolveStoredTheme(rawTheme)
183
+ if (rawTheme && rawTheme !== themeId) {
184
+ write(STORAGE_KEYS.THEME_ID, themeId)
185
+ clear()
186
+ }
187
+ const colorScheme = (read(STORAGE_KEYS.COLOR_SCHEME) as ColorScheme | null) ?? "system"
188
+ const mode = colorScheme === "system" ? getSystemMode() : colorScheme
189
+ const [store, setStore] = createStore({
190
+ themes: {
191
+ "oc-2": oc2Theme,
192
+ } as Record<string, DesktopTheme>,
193
+ themeId,
194
+ colorScheme,
195
+ mode,
196
+ previewThemeId: null as string | null,
197
+ previewScheme: null as ColorScheme | null,
198
+ })
199
+
200
+ const loads = new Map<string, Promise<DesktopTheme | undefined>>()
201
+
202
+ const load = (id: string) => {
203
+ const next = id
204
+ if (!next) return Promise.resolve(undefined)
205
+ const hit = store.themes[next]
206
+ if (hit) return Promise.resolve(hit)
207
+ const pending = loads.get(next)
208
+ if (pending) return pending
209
+ const file = getFiles()[`./themes/${next}.json`]
210
+ if (!file) return Promise.resolve(undefined)
211
+ const task = file()
212
+ .then((mod) => {
213
+ const theme = mod.default
214
+ setStore("themes", next, theme)
215
+ return theme
216
+ })
217
+ .finally(() => {
218
+ loads.delete(next)
219
+ })
220
+ loads.set(next, task)
221
+ return task
222
+ }
223
+
224
+ const applyTheme = (theme: DesktopTheme, themeId: string, mode: "light" | "dark", scheme: ColorScheme) => {
225
+ applyThemeCss(theme, themeId, mode)
226
+ props.onThemeApplied?.(theme, mode, scheme)
227
+ }
228
+
229
+ const ids = () => {
230
+ const extra = Object.keys(store.themes)
231
+ .filter((id) => !knownThemes().has(id))
232
+ .sort()
233
+ const all = themeIDs()
234
+ if (extra.length === 0) return all
235
+ return [...all, ...extra]
236
+ }
237
+
238
+ const loadThemes = () => Promise.all(themeIDs().map(load)).then(() => store.themes)
239
+
240
+ const onStorage = (e: StorageEvent) => {
241
+ if (e.key === STORAGE_KEYS.THEME_ID && e.newValue) {
242
+ const next = resolveStoredTheme(e.newValue, store.themes)
243
+ if (next !== e.newValue) {
244
+ write(STORAGE_KEYS.THEME_ID, next)
245
+ clear()
246
+ }
247
+ setStore("themeId", next)
248
+ if (next === "oc-2") {
249
+ clear()
250
+ return
251
+ }
252
+ void load(next).then((theme) => {
253
+ if (!theme || store.themeId !== next) return
254
+ cacheThemeVariants(theme, next)
255
+ })
256
+ }
257
+ if (e.key === STORAGE_KEYS.COLOR_SCHEME && e.newValue) {
258
+ setStore("colorScheme", e.newValue as ColorScheme)
259
+ setStore("mode", e.newValue === "system" ? getSystemMode() : (e.newValue as "light" | "dark"))
260
+ }
261
+ }
262
+
263
+ onMount(() => {
264
+ makeEventListener(window, "storage", onStorage)
265
+
266
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
267
+ const onMedia = () => {
268
+ if (store.colorScheme !== "system") return
269
+ setStore("mode", getSystemMode())
270
+ }
271
+ makeEventListener(mediaQuery, "change", onMedia)
272
+
273
+ const rawTheme = read(STORAGE_KEYS.THEME_ID) ?? props.defaultTheme
274
+ const savedTheme = resolveStoredTheme(rawTheme, store.themes)
275
+ const savedScheme = (read(STORAGE_KEYS.COLOR_SCHEME) as ColorScheme | null) ?? "system"
276
+ if (rawTheme && rawTheme !== savedTheme) {
277
+ write(STORAGE_KEYS.THEME_ID, savedTheme)
278
+ clear()
279
+ }
280
+ if (savedTheme !== store.themeId) setStore("themeId", savedTheme)
281
+ if (savedScheme !== store.colorScheme) setStore("colorScheme", savedScheme)
282
+ setStore("mode", savedScheme === "system" ? getSystemMode() : savedScheme)
283
+ void load(savedTheme).then((theme) => {
284
+ if (!theme || store.themeId !== savedTheme) return
285
+ cacheThemeVariants(theme, savedTheme)
286
+ })
287
+ })
288
+
289
+ createEffect(() => {
290
+ const theme = store.themes[store.themeId]
291
+ if (!theme) return
292
+ applyTheme(theme, store.themeId, store.mode, store.colorScheme)
293
+ })
294
+
295
+ const setTheme = (id: string) => {
296
+ const next = id
297
+ if (!next) {
298
+ console.warn(`Theme "${id}" not found`)
299
+ return
300
+ }
301
+ if (next !== "oc-2" && !knownThemes().has(next) && !store.themes[next]) {
302
+ console.warn(`Theme "${id}" not found`)
303
+ return
304
+ }
305
+ setStore("themeId", next)
306
+ if (next === "oc-2") {
307
+ write(STORAGE_KEYS.THEME_ID, next)
308
+ clear()
309
+ return
310
+ }
311
+ void load(next).then((theme) => {
312
+ if (!theme || store.themeId !== next) return
313
+ cacheThemeVariants(theme, next)
314
+ write(STORAGE_KEYS.THEME_ID, next)
315
+ })
316
+ }
317
+
318
+ const setColorScheme = (scheme: ColorScheme) => {
319
+ setStore("colorScheme", scheme)
320
+ write(STORAGE_KEYS.COLOR_SCHEME, scheme)
321
+ setStore("mode", scheme === "system" ? getSystemMode() : scheme)
322
+ }
323
+
324
+ return {
325
+ themeId: () => store.themeId,
326
+ colorScheme: () => store.colorScheme,
327
+ mode: () => store.mode,
328
+ ids,
329
+ name: (id: string) => store.themes[id]?.name ?? names[id] ?? id,
330
+ loadThemes,
331
+ themes: () => store.themes,
332
+ setTheme,
333
+ setColorScheme,
334
+ registerTheme: (theme: DesktopTheme) => setStore("themes", theme.id, theme),
335
+ previewTheme: (id: string) => {
336
+ const next = id
337
+ if (!next) return
338
+ if (next !== "oc-2" && !knownThemes().has(next) && !store.themes[next]) return
339
+ setStore("previewThemeId", next)
340
+ void load(next).then((theme) => {
341
+ if (!theme || store.previewThemeId !== next) return
342
+ const mode = store.previewScheme
343
+ ? store.previewScheme === "system"
344
+ ? getSystemMode()
345
+ : store.previewScheme
346
+ : store.mode
347
+ applyTheme(theme, next, mode, store.previewScheme ?? store.colorScheme)
348
+ })
349
+ },
350
+ previewColorScheme: (scheme: ColorScheme) => {
351
+ setStore("previewScheme", scheme)
352
+ const mode = scheme === "system" ? getSystemMode() : scheme
353
+ const id = store.previewThemeId ?? store.themeId
354
+ void load(id).then((theme) => {
355
+ if (!theme) return
356
+ if ((store.previewThemeId ?? store.themeId) !== id) return
357
+ if (store.previewScheme !== scheme) return
358
+ applyTheme(theme, id, mode, scheme)
359
+ })
360
+ },
361
+ commitPreview: () => {
362
+ if (store.previewThemeId) {
363
+ setTheme(store.previewThemeId)
364
+ }
365
+ if (store.previewScheme) {
366
+ setColorScheme(store.previewScheme)
367
+ }
368
+ setStore("previewThemeId", null)
369
+ setStore("previewScheme", null)
370
+ },
371
+ cancelPreview: () => {
372
+ setStore("previewThemeId", null)
373
+ setStore("previewScheme", null)
374
+ void load(store.themeId).then((theme) => {
375
+ if (!theme) return
376
+ applyTheme(theme, store.themeId, store.mode, store.colorScheme)
377
+ })
378
+ },
379
+ }
380
+ },
381
+ })
@@ -0,0 +1,116 @@
1
+ import type { DesktopTheme } from "./types"
2
+ import oc2ThemeJson from "./themes/oc-2.json"
3
+ import amoledThemeJson from "./themes/amoled.json"
4
+ import auraThemeJson from "./themes/aura.json"
5
+ import ayuThemeJson from "./themes/ayu.json"
6
+ import carbonfoxThemeJson from "./themes/carbonfox.json"
7
+ import catppuccinThemeJson from "./themes/catppuccin.json"
8
+ import catppuccinFrappeThemeJson from "./themes/catppuccin-frappe.json"
9
+ import catppuccinMacchiatoThemeJson from "./themes/catppuccin-macchiato.json"
10
+ import cobalt2ThemeJson from "./themes/cobalt2.json"
11
+ import cursorThemeJson from "./themes/cursor.json"
12
+ import draculaThemeJson from "./themes/dracula.json"
13
+ import everforestThemeJson from "./themes/everforest.json"
14
+ import flexokiThemeJson from "./themes/flexoki.json"
15
+ import githubThemeJson from "./themes/github.json"
16
+ import gruvboxThemeJson from "./themes/gruvbox.json"
17
+ import kanagawaThemeJson from "./themes/kanagawa.json"
18
+ import lucentOrngThemeJson from "./themes/lucent-orng.json"
19
+ import materialThemeJson from "./themes/material.json"
20
+ import matrixThemeJson from "./themes/matrix.json"
21
+ import mercuryThemeJson from "./themes/mercury.json"
22
+ import monokaiThemeJson from "./themes/monokai.json"
23
+ import nightowlThemeJson from "./themes/nightowl.json"
24
+ import nordThemeJson from "./themes/nord.json"
25
+ import oneDarkThemeJson from "./themes/one-dark.json"
26
+ import oneDarkProThemeJson from "./themes/onedarkpro.json"
27
+ import opencodeThemeJson from "./themes/opencode.json"
28
+ import orngThemeJson from "./themes/orng.json"
29
+ import osakaJadeThemeJson from "./themes/osaka-jade.json"
30
+ import palenightThemeJson from "./themes/palenight.json"
31
+ import rosepineThemeJson from "./themes/rosepine.json"
32
+ import shadesOfPurpleThemeJson from "./themes/shadesofpurple.json"
33
+ import solarizedThemeJson from "./themes/solarized.json"
34
+ import synthwave84ThemeJson from "./themes/synthwave84.json"
35
+ import tokyonightThemeJson from "./themes/tokyonight.json"
36
+ import vercelThemeJson from "./themes/vercel.json"
37
+ import vesperThemeJson from "./themes/vesper.json"
38
+ import zenburnThemeJson from "./themes/zenburn.json"
39
+
40
+ export const oc2Theme = oc2ThemeJson as DesktopTheme
41
+ export const amoledTheme = amoledThemeJson as DesktopTheme
42
+ export const auraTheme = auraThemeJson as DesktopTheme
43
+ export const ayuTheme = ayuThemeJson as DesktopTheme
44
+ export const carbonfoxTheme = carbonfoxThemeJson as DesktopTheme
45
+ export const catppuccinTheme = catppuccinThemeJson as DesktopTheme
46
+ export const catppuccinFrappeTheme = catppuccinFrappeThemeJson as DesktopTheme
47
+ export const catppuccinMacchiatoTheme = catppuccinMacchiatoThemeJson as DesktopTheme
48
+ export const cobalt2Theme = cobalt2ThemeJson as DesktopTheme
49
+ export const cursorTheme = cursorThemeJson as DesktopTheme
50
+ export const draculaTheme = draculaThemeJson as DesktopTheme
51
+ export const everforestTheme = everforestThemeJson as DesktopTheme
52
+ export const flexokiTheme = flexokiThemeJson as DesktopTheme
53
+ export const githubTheme = githubThemeJson as DesktopTheme
54
+ export const gruvboxTheme = gruvboxThemeJson as DesktopTheme
55
+ export const kanagawaTheme = kanagawaThemeJson as DesktopTheme
56
+ export const lucentOrngTheme = lucentOrngThemeJson as DesktopTheme
57
+ export const materialTheme = materialThemeJson as DesktopTheme
58
+ export const matrixTheme = matrixThemeJson as DesktopTheme
59
+ export const mercuryTheme = mercuryThemeJson as DesktopTheme
60
+ export const monokaiTheme = monokaiThemeJson as DesktopTheme
61
+ export const nightowlTheme = nightowlThemeJson as DesktopTheme
62
+ export const nordTheme = nordThemeJson as DesktopTheme
63
+ export const oneDarkTheme = oneDarkThemeJson as DesktopTheme
64
+ export const oneDarkProTheme = oneDarkProThemeJson as DesktopTheme
65
+ export const opencodeTheme = opencodeThemeJson as DesktopTheme
66
+ export const orngTheme = orngThemeJson as DesktopTheme
67
+ export const osakaJadeTheme = osakaJadeThemeJson as DesktopTheme
68
+ export const palenightTheme = palenightThemeJson as DesktopTheme
69
+ export const rosepineTheme = rosepineThemeJson as DesktopTheme
70
+ export const shadesOfPurpleTheme = shadesOfPurpleThemeJson as DesktopTheme
71
+ export const solarizedTheme = solarizedThemeJson as DesktopTheme
72
+ export const synthwave84Theme = synthwave84ThemeJson as DesktopTheme
73
+ export const tokyonightTheme = tokyonightThemeJson as DesktopTheme
74
+ export const vercelTheme = vercelThemeJson as DesktopTheme
75
+ export const vesperTheme = vesperThemeJson as DesktopTheme
76
+ export const zenburnTheme = zenburnThemeJson as DesktopTheme
77
+
78
+ export const DEFAULT_THEMES: Record<string, DesktopTheme> = {
79
+ "oc-2": oc2Theme,
80
+ amoled: amoledTheme,
81
+ aura: auraTheme,
82
+ ayu: ayuTheme,
83
+ carbonfox: carbonfoxTheme,
84
+ catppuccin: catppuccinTheme,
85
+ "catppuccin-frappe": catppuccinFrappeTheme,
86
+ "catppuccin-macchiato": catppuccinMacchiatoTheme,
87
+ cobalt2: cobalt2Theme,
88
+ cursor: cursorTheme,
89
+ dracula: draculaTheme,
90
+ everforest: everforestTheme,
91
+ flexoki: flexokiTheme,
92
+ github: githubTheme,
93
+ gruvbox: gruvboxTheme,
94
+ kanagawa: kanagawaTheme,
95
+ "lucent-orng": lucentOrngTheme,
96
+ material: materialTheme,
97
+ matrix: matrixTheme,
98
+ mercury: mercuryTheme,
99
+ monokai: monokaiTheme,
100
+ nightowl: nightowlTheme,
101
+ nord: nordTheme,
102
+ "one-dark": oneDarkTheme,
103
+ onedarkpro: oneDarkProTheme,
104
+ opencode: opencodeTheme,
105
+ orng: orngTheme,
106
+ "osaka-jade": osakaJadeTheme,
107
+ palenight: palenightTheme,
108
+ rosepine: rosepineTheme,
109
+ shadesofpurple: shadesOfPurpleTheme,
110
+ solarized: solarizedTheme,
111
+ synthwave84: synthwave84Theme,
112
+ tokyonight: tokyonightTheme,
113
+ vercel: vercelTheme,
114
+ vesper: vesperTheme,
115
+ zenburn: zenburnTheme,
116
+ }
@@ -0,0 +1,78 @@
1
+ export type {
2
+ DesktopTheme,
3
+ ThemePaletteColors,
4
+ ThemeSeedColors,
5
+ ThemeVariant,
6
+ HexColor,
7
+ OklchColor,
8
+ ResolvedTheme,
9
+ ColorValue,
10
+ CssVarRef,
11
+ V2ColorValue,
12
+ ResolvedV2Theme,
13
+ } from "./types"
14
+
15
+ export {
16
+ hexToRgb,
17
+ rgbToHex,
18
+ hexToOklch,
19
+ oklchToHex,
20
+ rgbToOklch,
21
+ oklchToRgb,
22
+ generateScale,
23
+ generateNeutralScale,
24
+ generateAlphaScale,
25
+ fitOklch,
26
+ blend,
27
+ mixColors,
28
+ shift,
29
+ lighten,
30
+ darken,
31
+ withAlpha,
32
+ } from "./color"
33
+
34
+ export { resolveThemeVariant, resolveTheme, themeToCss } from "./resolve"
35
+ export { resolveThemeVariantV2, resolveThemeV2, themeV2ToCss, generateV2Primitives } from "./v2/resolve"
36
+ export { applyTheme, loadThemeFromUrl, getActiveTheme, removeTheme, setColorScheme } from "./loader"
37
+ export { ThemeProvider, useTheme, type ColorScheme } from "./context"
38
+
39
+ export {
40
+ DEFAULT_THEMES,
41
+ oc2Theme,
42
+ amoledTheme,
43
+ auraTheme,
44
+ ayuTheme,
45
+ carbonfoxTheme,
46
+ catppuccinTheme,
47
+ catppuccinFrappeTheme,
48
+ catppuccinMacchiatoTheme,
49
+ cobalt2Theme,
50
+ cursorTheme,
51
+ draculaTheme,
52
+ everforestTheme,
53
+ flexokiTheme,
54
+ githubTheme,
55
+ gruvboxTheme,
56
+ kanagawaTheme,
57
+ lucentOrngTheme,
58
+ materialTheme,
59
+ matrixTheme,
60
+ mercuryTheme,
61
+ monokaiTheme,
62
+ nightowlTheme,
63
+ nordTheme,
64
+ oneDarkTheme,
65
+ oneDarkProTheme,
66
+ opencodeTheme,
67
+ orngTheme,
68
+ osakaJadeTheme,
69
+ palenightTheme,
70
+ rosepineTheme,
71
+ shadesOfPurpleTheme,
72
+ solarizedTheme,
73
+ synthwave84Theme,
74
+ tokyonightTheme,
75
+ vercelTheme,
76
+ vesperTheme,
77
+ zenburnTheme,
78
+ } from "./default-themes"
@@ -0,0 +1,112 @@
1
+ import type { DesktopTheme, ResolvedTheme, ResolvedV2Theme } from "./types"
2
+ import { resolveThemeVariant, themeToCss } from "./resolve"
3
+ import { resolveThemeVariantV2, themeV2ToCss } from "./v2/resolve"
4
+
5
+ let activeTheme: DesktopTheme | null = null
6
+ const THEME_STYLE_ID = "opencode-theme"
7
+
8
+ function ensureLoaderStyleElement(): HTMLStyleElement {
9
+ const existing = document.getElementById(THEME_STYLE_ID) as HTMLStyleElement | null
10
+ if (existing) {
11
+ return existing
12
+ }
13
+ const element = document.createElement("style")
14
+ element.id = THEME_STYLE_ID
15
+ document.head.appendChild(element)
16
+ return element
17
+ }
18
+
19
+ export function applyTheme(theme: DesktopTheme, themeId?: string): void {
20
+ activeTheme = theme
21
+ const lightTokens = resolveThemeVariant(theme.light, false)
22
+ const darkTokens = resolveThemeVariant(theme.dark, true)
23
+ const lightV2Tokens = resolveThemeVariantV2(theme.light, false)
24
+ const darkV2Tokens = resolveThemeVariantV2(theme.dark, true)
25
+ const targetThemeId = themeId ?? theme.id
26
+ const css = buildThemeCss(lightTokens, darkTokens, lightV2Tokens, darkV2Tokens, targetThemeId)
27
+ const themeStyleElement = ensureLoaderStyleElement()
28
+ themeStyleElement.textContent = css
29
+ document.documentElement.setAttribute("data-theme", targetThemeId)
30
+ }
31
+
32
+ function buildThemeCss(
33
+ light: ResolvedTheme,
34
+ dark: ResolvedTheme,
35
+ lightV2: ResolvedV2Theme,
36
+ darkV2: ResolvedV2Theme,
37
+ themeId: string,
38
+ ): string {
39
+ const isDefaultTheme = themeId === "oc-2"
40
+ const lightCss = `${themeToCss(light)}\n ${themeV2ToCss(lightV2)}`
41
+ const darkCss = `${themeToCss(dark)}\n ${themeV2ToCss(darkV2)}`
42
+
43
+ if (isDefaultTheme) {
44
+ return `
45
+ :root {
46
+ color-scheme: light;
47
+ --text-mix-blend-mode: multiply;
48
+
49
+ ${lightCss}
50
+
51
+ @media (prefers-color-scheme: dark) {
52
+ color-scheme: dark;
53
+ --text-mix-blend-mode: plus-lighter;
54
+
55
+ ${darkCss}
56
+ }
57
+ }
58
+ `
59
+ }
60
+
61
+ return `
62
+ html[data-theme="${themeId}"] {
63
+ color-scheme: light;
64
+ --text-mix-blend-mode: multiply;
65
+
66
+ ${lightCss}
67
+
68
+ @media (prefers-color-scheme: dark) {
69
+ color-scheme: dark;
70
+ --text-mix-blend-mode: plus-lighter;
71
+
72
+ ${darkCss}
73
+ }
74
+ }
75
+ `
76
+ }
77
+
78
+ export async function loadThemeFromUrl(url: string): Promise<DesktopTheme> {
79
+ const response = await fetch(url)
80
+ if (!response.ok) {
81
+ throw new Error(`Failed to load theme from ${url}: ${response.statusText}`)
82
+ }
83
+ return response.json()
84
+ }
85
+
86
+ export function getActiveTheme(): DesktopTheme | null {
87
+ const activeId = document.documentElement.getAttribute("data-theme")
88
+ if (!activeId) {
89
+ return null
90
+ }
91
+ if (activeTheme?.id === activeId) {
92
+ return activeTheme
93
+ }
94
+ return null
95
+ }
96
+
97
+ export function removeTheme(): void {
98
+ activeTheme = null
99
+ const existingElement = document.getElementById(THEME_STYLE_ID)
100
+ if (existingElement) {
101
+ existingElement.remove()
102
+ }
103
+ document.documentElement.removeAttribute("data-theme")
104
+ }
105
+
106
+ export function setColorScheme(scheme: "light" | "dark" | "auto"): void {
107
+ if (scheme === "auto") {
108
+ document.documentElement.style.removeProperty("color-scheme")
109
+ } else {
110
+ document.documentElement.style.setProperty("color-scheme", scheme)
111
+ }
112
+ }