header.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. <A href="/enterprise">Enterprise</A>
  38. </li>
  39. <li>
  40. <Switch>
  41. <Match when={props.zen}>
  42. <a href="/auth">Login</a>
  43. </Match>
  44. <Match when={!props.zen}>
  45. <A href="/zen">Zen</A>
  46. </Match>
  47. </Switch>
  48. </li>
  49. </ul>
  50. </nav>
  51. <nav data-component="nav-mobile">
  52. <button
  53. type="button"
  54. data-component="nav-mobile-toggle"
  55. aria-expanded="false"
  56. aria-controls="nav-mobile-menu"
  57. class="nav-toggle"
  58. onClick={() => setStore("mobileMenuOpen", !store.mobileMenuOpen)}
  59. >
  60. <span class="sr-only">Open menu</span>
  61. <Switch>
  62. <Match when={store.mobileMenuOpen}>
  63. <svg
  64. class="icon icon-close"
  65. width="24"
  66. height="24"
  67. viewBox="0 0 24 24"
  68. fill="none"
  69. aria-hidden="true"
  70. xmlns="http://www.w3.org/2000/svg"
  71. >
  72. <path
  73. 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"
  74. fill="currentColor"
  75. />
  76. </svg>
  77. </Match>
  78. <Match when={!store.mobileMenuOpen}>
  79. <svg
  80. class="icon icon-hamburger"
  81. width="24"
  82. height="24"
  83. viewBox="0 0 24 24"
  84. fill="none"
  85. aria-hidden="true"
  86. xmlns="http://www.w3.org/2000/svg"
  87. >
  88. <path d="M19 17H5V16H19V17Z" fill="currentColor" />
  89. <path d="M19 8H5V7H19V8Z" fill="currentColor" />
  90. </svg>
  91. </Match>
  92. </Switch>
  93. </button>
  94. <Show when={store.mobileMenuOpen}>
  95. <div id="nav-mobile-menu" data-component="nav-mobile">
  96. <nav data-component="nav-mobile-menu-list">
  97. <ul>
  98. <li>
  99. <A href="/">Home</A>
  100. </li>
  101. <li>
  102. <a href="https://github.com/sst/opencode" target="_blank">
  103. GitHub <span>[{starCount()}]</span>
  104. </a>
  105. </li>
  106. <li>
  107. <a href="/docs">Docs</a>
  108. </li>
  109. <li>
  110. <A href="/enterprise">Enterprise</A>
  111. </li>
  112. <li>
  113. <Switch>
  114. <Match when={props.zen}>
  115. <a href="/auth">Login</a>
  116. </Match>
  117. <Match when={!props.zen}>
  118. <A href="/zen">Zen</A>
  119. </Match>
  120. </Switch>
  121. </li>
  122. </ul>
  123. </nav>
  124. </div>
  125. </Show>
  126. </nav>
  127. </section>
  128. )
  129. }