language.tsx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { createEffect } from "solid-js"
  2. import { createStore } from "solid-js/store"
  3. import { getRequestEvent } from "solid-js/web"
  4. import { createSimpleContext } from "@opencode-ai/ui/context"
  5. import {
  6. LOCALES,
  7. type Locale,
  8. clearCookie,
  9. cookie,
  10. detectFromLanguages,
  11. dir as localeDir,
  12. label as localeLabel,
  13. localeFromCookieHeader,
  14. localeFromRequest,
  15. parseLocale,
  16. route as localeRoute,
  17. tag as localeTag,
  18. } from "~/lib/language"
  19. function initial() {
  20. const evt = getRequestEvent()
  21. if (evt) return localeFromRequest(evt.request)
  22. if (typeof document === "object") {
  23. const fromDom = parseLocale(document.documentElement.dataset.locale)
  24. if (fromDom) return fromDom
  25. const fromCookie = localeFromCookieHeader(document.cookie)
  26. if (fromCookie) return fromCookie
  27. }
  28. if (typeof navigator !== "object") return "en" satisfies Locale
  29. const languages = navigator.languages?.length ? navigator.languages : [navigator.language]
  30. return detectFromLanguages(languages)
  31. }
  32. export const { use: useLanguage, provider: LanguageProvider } = createSimpleContext({
  33. name: "Language",
  34. init: () => {
  35. const [store, setStore] = createStore({
  36. locale: initial(),
  37. })
  38. createEffect(() => {
  39. if (typeof document !== "object") return
  40. document.documentElement.lang = localeTag(store.locale)
  41. document.documentElement.dir = localeDir(store.locale)
  42. document.documentElement.dataset.locale = store.locale
  43. })
  44. return {
  45. locale: () => store.locale,
  46. locales: LOCALES,
  47. label: localeLabel,
  48. tag: localeTag,
  49. dir: localeDir,
  50. route(pathname: string) {
  51. return localeRoute(store.locale, pathname)
  52. },
  53. setLocale(next: Locale) {
  54. setStore("locale", next)
  55. if (typeof document !== "object") return
  56. document.cookie = cookie(next)
  57. },
  58. clear() {
  59. if (typeof document !== "object") return
  60. document.cookie = clearCookie()
  61. },
  62. }
  63. },
  64. })