header.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import logoLight from "../asset/logo-ornate-light.svg"
  2. import logoDark from "../asset/logo-ornate-dark.svg"
  3. import { A, createAsync } from "@solidjs/router"
  4. import { createMemo, Match, Show, Switch } from "solid-js"
  5. import { createStore } from "solid-js/store"
  6. import { github } from "~/lib/github"
  7. export function Header(props: { zen?: boolean }) {
  8. const githubData = createAsync(() => github())
  9. const starCount = createMemo(() =>
  10. githubData()?.stars
  11. ? new Intl.NumberFormat("en-US", {
  12. notation: "compact",
  13. compactDisplay: "short",
  14. }).format(githubData()?.stars!)
  15. : "25K",
  16. )
  17. const [store, setStore] = createStore({
  18. mobileMenuOpen: false,
  19. })
  20. return (
  21. <section data-component="top">
  22. <A href="/">
  23. <img data-slot="logo light" src={logoLight} alt="opencode logo light" />
  24. <img data-slot="logo dark" src={logoDark} alt="opencode logo dark" />
  25. </A>
  26. <nav data-component="nav-desktop">
  27. <ul>
  28. <li>
  29. <A href="https://github.com/sst/opencode" target="_blank">
  30. GitHub <span>[{starCount()}]</span>
  31. </A>
  32. </li>
  33. <li>
  34. <a href="/docs">Docs</a>
  35. </li>
  36. <li>
  37. <Switch>
  38. <Match when={props.zen}>
  39. <A href="/auth">Login</A>
  40. </Match>
  41. <Match when={!props.zen}>
  42. <A href="/zen">Zen</A>
  43. </Match>
  44. </Switch>
  45. </li>
  46. </ul>
  47. </nav>
  48. <nav data-component="nav-mobile">
  49. <button
  50. type="button"
  51. data-component="nav-mobile-toggle"
  52. aria-expanded="false"
  53. aria-controls="nav-mobile-menu"
  54. class="nav-toggle"
  55. onClick={() => setStore("mobileMenuOpen", !store.mobileMenuOpen)}
  56. >
  57. <span class="sr-only">Open menu</span>
  58. <Switch>
  59. <Match when={store.mobileMenuOpen}>
  60. <svg
  61. class="icon icon-close"
  62. width="24"
  63. height="24"
  64. viewBox="0 0 24 24"
  65. fill="none"
  66. aria-hidden="true"
  67. xmlns="http://www.w3.org/2000/svg"
  68. >
  69. <path
  70. d="M12.7071 11.9993L18.0104 17.3026L17.3033 18.0097L12 12.7064L6.6967 18.0097L5.98959 17.3026L11.2929 11.9993L5.98959 6.69595L6.6967 5.98885L12 11.2921L17.3033 5.98885L18.0104 6.69595L12.7071 11.9993Z"
  71. fill="currentColor"
  72. />
  73. </svg>
  74. </Match>
  75. <Match when={!store.mobileMenuOpen}>
  76. <svg
  77. class="icon icon-hamburger"
  78. width="24"
  79. height="24"
  80. viewBox="0 0 24 24"
  81. fill="none"
  82. aria-hidden="true"
  83. xmlns="http://www.w3.org/2000/svg"
  84. >
  85. <path d="M19 17H5V16H19V17Z" fill="currentColor" />
  86. <path d="M19 8H5V7H19V8Z" fill="currentColor" />
  87. </svg>
  88. </Match>
  89. </Switch>
  90. </button>
  91. <Show when={store.mobileMenuOpen}>
  92. <div id="nav-mobile-menu" data-component="nav-mobile">
  93. <nav data-component="nav-mobile-menu-list">
  94. <ul>
  95. <li>
  96. <A href="/">Home</A>
  97. </li>
  98. <li>
  99. <A href="https://github.com/sst/opencode" target="_blank">
  100. GitHub <span>[{starCount()}]</span>
  101. </A>
  102. </li>
  103. <li>
  104. <A href="/docs">Docs</A>
  105. </li>
  106. <li>
  107. <Switch>
  108. <Match when={props.zen}>
  109. <A href="/auth">Login</A>
  110. </Match>
  111. <Match when={!props.zen}>
  112. <A href="/zen">Zen</A>
  113. </Match>
  114. </Switch>
  115. </li>
  116. </ul>
  117. </nav>
  118. </div>
  119. </Show>
  120. </nav>
  121. </section>
  122. )
  123. }