docs-i18n 0.6.3 → 0.7.0

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 (169) hide show
  1. package/{src/admin/ui → admin/app}/components/JobDialog.tsx +21 -2
  2. package/{src/admin/ui → admin/app}/components/JobPanel.tsx +1 -1
  3. package/{src/admin/ui → admin/app}/components/Preview.tsx +2 -5
  4. package/{src/admin/ui → admin/app}/lib/api.ts +18 -39
  5. package/admin/app/routeTree.gen.ts +68 -0
  6. package/admin/app/router.tsx +23 -0
  7. package/admin/app/routes/__root.tsx +55 -0
  8. package/admin/app/routes/index.tsx +416 -0
  9. package/{src/admin/ui → admin/app}/styles.css +36 -3
  10. package/admin/package.json +27 -0
  11. package/admin/server/functions/jobs.ts +53 -0
  12. package/admin/server/functions/misc.ts +84 -0
  13. package/{src/admin/server/routes → admin/server/functions}/models.ts +16 -29
  14. package/admin/server/functions/status.ts +61 -0
  15. package/admin/server/index.ts +35 -0
  16. package/admin/server/init.ts +46 -0
  17. package/{src/admin → admin}/server/services/job-manager.ts +39 -10
  18. package/{src/admin → admin}/server/services/status.ts +6 -6
  19. package/admin/tsconfig.json +19 -0
  20. package/{src/admin → admin}/vite.config.ts +8 -2
  21. package/dist/{assemble-7H4QCW35.js → assemble-CP2BRYQJ.js} +6 -4
  22. package/dist/{chunk-A3YQNPKZ.js → chunk-CLYUAWZE.js} +1 -1
  23. package/dist/{chunk-YN4VJHCQ.js → chunk-JHBSHTXC.js} +1 -1
  24. package/dist/chunk-L64GJ4OB.js +32 -0
  25. package/dist/{chunk-SKKZIV3L.js → chunk-PNKVD2UK.js} +1 -29
  26. package/dist/{chunk-XEOYZUHS.js → chunk-QKIR7RKQ.js} +4 -31
  27. package/dist/chunk-TRURQFP4.js +31 -0
  28. package/dist/cli.js +108 -7
  29. package/dist/index.d.ts +41 -1
  30. package/dist/index.js +92 -3
  31. package/dist/{rescan-O5D3CYC2.js → rescan-HXMWFAOC.js} +5 -3
  32. package/dist/{status-F4MYIAAY.js → status-AGZDXOTZ.js} +4 -2
  33. package/dist/{translate-ZIVKNAC4.js → translate-A5X6MX4Y.js} +14 -7
  34. package/dist/upload-XL6KG6S2.js +132 -0
  35. package/package.json +17 -15
  36. package/template/app/components/BlogArticle.tsx +159 -0
  37. package/template/app/components/BlogList.tsx +88 -0
  38. package/template/app/components/Breadcrumbs.tsx +81 -0
  39. package/template/app/components/Card.tsx +31 -0
  40. package/template/app/components/Doc.tsx +191 -0
  41. package/template/app/components/DocBreadcrumb.tsx +60 -0
  42. package/template/app/components/DocContainer.tsx +13 -0
  43. package/template/app/components/DocTitle.tsx +11 -0
  44. package/template/app/components/DocsLayout.tsx +715 -0
  45. package/template/app/components/Dropdown.tsx +116 -0
  46. package/template/app/components/FallbackBanner.tsx +36 -0
  47. package/template/app/components/Footer.tsx +29 -0
  48. package/template/app/components/FrameworkSelect.tsx +150 -0
  49. package/template/app/components/LibraryCard.tsx +178 -0
  50. package/template/app/components/LocaleSwitcher.tsx +43 -0
  51. package/template/app/components/Navbar.tsx +430 -0
  52. package/template/app/components/PostNotFound.tsx +20 -0
  53. package/template/app/components/SearchButton.tsx +32 -0
  54. package/template/app/components/Select.tsx +103 -0
  55. package/template/app/components/Spinner.tsx +18 -0
  56. package/template/app/components/ThemeProvider.tsx +141 -0
  57. package/template/app/components/ThemeToggle.tsx +31 -0
  58. package/template/app/components/Toc.tsx +86 -0
  59. package/template/app/components/VersionSelect.tsx +118 -0
  60. package/template/app/components/icons/BSkyIcon.tsx +27 -0
  61. package/template/app/components/icons/BaseballCapIcon.tsx +25 -0
  62. package/template/app/components/icons/BrandXIcon.tsx +28 -0
  63. package/template/app/components/icons/CheckCircleIcon.tsx +28 -0
  64. package/template/app/components/icons/CogsIcon.tsx +25 -0
  65. package/template/app/components/icons/DiscordIcon.tsx +24 -0
  66. package/template/app/components/icons/GithubIcon.tsx +24 -0
  67. package/template/app/components/icons/GoogleIcon.tsx +24 -0
  68. package/template/app/components/icons/InstagramIcon.tsx +24 -0
  69. package/template/app/components/icons/NpmIcon.tsx +26 -0
  70. package/template/app/components/icons/YinYangIcon.tsx +26 -0
  71. package/template/app/components/icons/YouTubeIcon.tsx +24 -0
  72. package/template/app/components/markdown/CodeBlock.tsx +254 -0
  73. package/template/app/components/markdown/FileTabs.tsx +58 -0
  74. package/template/app/components/markdown/FrameworkContent.tsx +76 -0
  75. package/template/app/components/markdown/Markdown.tsx +216 -0
  76. package/template/app/components/markdown/MarkdownContent.tsx +89 -0
  77. package/template/app/components/markdown/MarkdownFrameworkHandler.tsx +66 -0
  78. package/template/app/components/markdown/MarkdownHeadingContext.tsx +35 -0
  79. package/template/app/components/markdown/MarkdownLink.tsx +46 -0
  80. package/template/app/components/markdown/MarkdownTabsHandler.tsx +109 -0
  81. package/template/app/components/markdown/PackageManagerTabs.tsx +95 -0
  82. package/template/app/components/markdown/Tabs.tsx +139 -0
  83. package/template/app/components/markdown/index.ts +15 -0
  84. package/template/app/components/ui/Button.tsx +141 -0
  85. package/template/app/components/ui/InlineCode.tsx +16 -0
  86. package/template/app/components/ui/MarkdownImg.tsx +21 -0
  87. package/template/app/config/frameworks.ts +93 -0
  88. package/template/app/contexts/SearchContext.tsx +36 -0
  89. package/template/app/db/index.ts +17 -0
  90. package/template/app/db/schema.ts +74 -0
  91. package/template/app/hooks/useClickOutside.ts +106 -0
  92. package/template/app/routeTree.gen.ts +584 -0
  93. package/template/app/router.tsx +29 -0
  94. package/template/app/routes/$lang.$project.$version.docs.$.tsx +128 -0
  95. package/template/app/routes/$lang.$project.$version.docs.framework.$framework.$.tsx +106 -0
  96. package/template/app/routes/$lang.$project.$version.docs.framework.$framework.index.tsx +27 -0
  97. package/template/app/routes/$lang.$project.$version.docs.framework.index.tsx +44 -0
  98. package/template/app/routes/$lang.$project.$version.docs.index.tsx +27 -0
  99. package/template/app/routes/$lang.$project.$version.docs.tsx +70 -0
  100. package/template/app/routes/$lang.$project.$version.tsx +69 -0
  101. package/template/app/routes/$lang.$project.docs.$.tsx +104 -0
  102. package/template/app/routes/$lang.$project.docs.index.tsx +20 -0
  103. package/template/app/routes/$lang.$project.docs.tsx +79 -0
  104. package/template/app/routes/$lang.$project.tsx +89 -0
  105. package/template/app/routes/$lang.blog.$.tsx +82 -0
  106. package/template/app/routes/$lang.blog.index.tsx +56 -0
  107. package/template/app/routes/$lang.blog.tsx +26 -0
  108. package/template/app/routes/$lang.docs.$.tsx +100 -0
  109. package/template/app/routes/$lang.docs.framework.$framework.$.tsx +104 -0
  110. package/template/app/routes/$lang.docs.framework.$framework.index.tsx +32 -0
  111. package/template/app/routes/$lang.docs.framework.index.tsx +47 -0
  112. package/template/app/routes/$lang.docs.index.tsx +20 -0
  113. package/template/app/routes/$lang.docs.tsx +90 -0
  114. package/template/app/routes/$lang.tsx +16 -0
  115. package/template/app/routes/__root.tsx +180 -0
  116. package/template/app/routes/index.tsx +89 -0
  117. package/template/app/site.config.ts +182 -0
  118. package/template/app/styles/app.css +1029 -0
  119. package/template/app/types/index.ts +77 -0
  120. package/template/app/utils/blog.server.ts +193 -0
  121. package/template/app/utils/blog.ts +42 -0
  122. package/template/app/utils/config.ts +120 -0
  123. package/template/app/utils/content-loader.ts +400 -0
  124. package/template/app/utils/dates.ts +29 -0
  125. package/template/app/utils/docs.server.ts +150 -0
  126. package/template/app/utils/markdown/filterFrameworkContent.ts +233 -0
  127. package/template/app/utils/markdown/index.ts +2 -0
  128. package/template/app/utils/markdown/installCommand.ts +143 -0
  129. package/template/app/utils/markdown/plugins/collectHeadings.ts +104 -0
  130. package/template/app/utils/markdown/plugins/extractCodeMeta.ts +57 -0
  131. package/template/app/utils/markdown/plugins/helpers.ts +33 -0
  132. package/template/app/utils/markdown/plugins/index.ts +8 -0
  133. package/template/app/utils/markdown/plugins/parseCommentComponents.ts +103 -0
  134. package/template/app/utils/markdown/plugins/transformCommentComponents.ts +23 -0
  135. package/template/app/utils/markdown/plugins/transformFrameworkComponent.ts +217 -0
  136. package/template/app/utils/markdown/plugins/transformTabsComponent.ts +359 -0
  137. package/template/app/utils/markdown/processor.ts +75 -0
  138. package/template/app/utils/site-config.tsx +11 -0
  139. package/template/app/utils/upload.ts +232 -0
  140. package/template/app/utils/useLocalStorage.ts +65 -0
  141. package/template/app/utils/utils.ts +23 -0
  142. package/template/package.json +54 -0
  143. package/template/public/favicon.svg +1 -0
  144. package/template/public/fonts/Inter-latin-ext.woff2 +0 -0
  145. package/template/public/fonts/Inter-latin.woff2 +0 -0
  146. package/template/public/images/frameworks/angular-logo.svg +1 -0
  147. package/template/public/images/frameworks/js-logo.svg +1 -0
  148. package/template/public/images/frameworks/lit-logo.svg +1 -0
  149. package/template/public/images/frameworks/preact-logo.svg +6 -0
  150. package/template/public/images/frameworks/qwik-logo.svg +1 -0
  151. package/template/public/images/frameworks/react-logo.svg +1 -0
  152. package/template/public/images/frameworks/solid-logo.svg +1 -0
  153. package/template/public/images/frameworks/svelte-logo.svg +1 -0
  154. package/template/public/images/frameworks/vue-logo.svg +4 -0
  155. package/template/tsconfig.json +24 -0
  156. package/template/vite.config.ts +43 -0
  157. package/template/wrangler.jsonc +16 -0
  158. package/README.md +0 -161
  159. package/dist/server-73AVSOL5.js +0 -598
  160. package/src/admin/index.html +0 -13
  161. package/src/admin/server/index.ts +0 -138
  162. package/src/admin/server/routes/jobs.ts +0 -113
  163. package/src/admin/server/routes/status.ts +0 -57
  164. package/src/admin/ui/App.tsx +0 -332
  165. package/src/admin/ui/main.tsx +0 -19
  166. /package/{src/admin/ui → admin/app}/components/FileList.tsx +0 -0
  167. /package/{src/admin/ui → admin/app}/components/LangGrid.tsx +0 -0
  168. /package/{src/admin/ui → admin/app}/components/ProgressBar.tsx +0 -0
  169. /package/{src/admin/ui → admin/app}/lib/flags.ts +0 -0
@@ -0,0 +1,141 @@
1
+ import * as React from 'react'
2
+ import { createContext, ReactNode, useEffect, useState } from 'react'
3
+
4
+ const themeKey = 'theme'
5
+
6
+ type ThemeMode = 'light' | 'dark' | 'auto'
7
+ type ResolvedTheme = 'light' | 'dark'
8
+
9
+ const THEME_COLORS = {
10
+ light: '#f9fafb',
11
+ dark: '#101828',
12
+ } as const
13
+
14
+ function isValidThemeMode(value: unknown): value is ThemeMode {
15
+ return value === 'light' || value === 'dark' || value === 'auto'
16
+ }
17
+
18
+ function getStoredThemeMode(): ThemeMode {
19
+ if (typeof window === 'undefined') return 'auto'
20
+ try {
21
+ const storedTheme = localStorage.getItem(themeKey)
22
+ return isValidThemeMode(storedTheme) ? storedTheme : 'auto'
23
+ } catch {
24
+ return 'auto'
25
+ }
26
+ }
27
+
28
+ function setStoredThemeMode(theme: ThemeMode): void {
29
+ if (typeof window === 'undefined') return
30
+ try {
31
+ if (isValidThemeMode(theme)) {
32
+ localStorage.setItem(themeKey, theme)
33
+ }
34
+ } catch {}
35
+ }
36
+
37
+ function getSystemTheme(): ResolvedTheme {
38
+ if (typeof window === 'undefined') return 'light'
39
+ return window.matchMedia('(prefers-color-scheme: dark)').matches
40
+ ? 'dark'
41
+ : 'light'
42
+ }
43
+
44
+ function updateThemeClass(themeMode: ThemeMode): void {
45
+ if (typeof document === 'undefined') return
46
+ const root = document.documentElement
47
+ root.classList.remove('light', 'dark', 'auto')
48
+ const newTheme = themeMode === 'auto' ? getSystemTheme() : themeMode
49
+ root.classList.add(newTheme)
50
+
51
+ if (themeMode === 'auto') {
52
+ root.classList.add('auto')
53
+ }
54
+
55
+ const metaThemeColor = document.querySelector('meta[name="theme-color"]')
56
+ if (metaThemeColor) {
57
+ metaThemeColor.setAttribute(
58
+ 'content',
59
+ newTheme === 'dark' ? THEME_COLORS.dark : THEME_COLORS.light,
60
+ )
61
+ }
62
+ }
63
+
64
+ function getNextTheme(current: ThemeMode): ThemeMode {
65
+ if (typeof window === 'undefined') return 'auto'
66
+ const themes: ThemeMode[] =
67
+ getSystemTheme() === 'dark'
68
+ ? ['auto', 'light', 'dark']
69
+ : ['auto', 'dark', 'light']
70
+ return themes[(themes.indexOf(current) + 1) % themes.length]
71
+ }
72
+
73
+ type ThemeContextProps = {
74
+ themeMode: ThemeMode
75
+ resolvedTheme: ResolvedTheme
76
+ setTheme: (theme: ThemeMode) => void
77
+ toggleMode: () => void
78
+ }
79
+ const ThemeContext = createContext<ThemeContextProps | undefined>(undefined)
80
+
81
+ type ThemeProviderProps = {
82
+ children: ReactNode
83
+ }
84
+
85
+ function getResolvedThemeFromDOM(): ResolvedTheme {
86
+ if (typeof document === 'undefined') return 'light'
87
+ return document.documentElement.classList.contains('dark') ? 'dark' : 'light'
88
+ }
89
+
90
+ export function ThemeProvider({ children }: ThemeProviderProps) {
91
+ const [themeMode, setThemeMode] = useState<ThemeMode>(getStoredThemeMode)
92
+ const [resolvedTheme, setResolvedTheme] = useState<ResolvedTheme>(
93
+ getResolvedThemeFromDOM,
94
+ )
95
+
96
+ // Listen for system theme changes when in auto mode
97
+ useEffect(() => {
98
+ if (themeMode !== 'auto') return
99
+ const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
100
+ const handler = () => {
101
+ updateThemeClass('auto')
102
+ setResolvedTheme(getSystemTheme())
103
+ }
104
+ mediaQuery.addEventListener('change', handler)
105
+ return () => mediaQuery.removeEventListener('change', handler)
106
+ }, [themeMode])
107
+
108
+ const setTheme = (newTheme: ThemeMode) => {
109
+ setThemeMode(newTheme)
110
+ setStoredThemeMode(newTheme)
111
+ updateThemeClass(newTheme)
112
+ setResolvedTheme(newTheme === 'auto' ? getSystemTheme() : newTheme)
113
+ }
114
+
115
+ const toggleMode = () => {
116
+ setTheme(getNextTheme(themeMode))
117
+ }
118
+
119
+ return (
120
+ <ThemeContext.Provider
121
+ value={{ themeMode, resolvedTheme, setTheme, toggleMode }}
122
+ >
123
+ {children}
124
+ </ThemeContext.Provider>
125
+ )
126
+ }
127
+
128
+ export const useTheme = () => {
129
+ const context = React.useContext(ThemeContext)
130
+ if (!context) {
131
+ throw new Error('useTheme must be used within a ThemeProvider')
132
+ }
133
+ return context
134
+ }
135
+
136
+ // Returns the class string for <html> element
137
+ // Reads from DOM on client (matches what head script set), empty on server
138
+ export function useHtmlClass(): string {
139
+ if (typeof document === 'undefined') return ''
140
+ return document.documentElement.className
141
+ }
@@ -0,0 +1,31 @@
1
+ import * as React from 'react'
2
+ import { useTheme } from './ThemeProvider'
3
+ import { Moon, Sun, SunMoon } from 'lucide-react'
4
+ import { Button } from './ui/Button'
5
+
6
+ export function ThemeToggle() {
7
+ const { themeMode, toggleMode } = useTheme()
8
+
9
+ const handleToggleMode = (e: React.MouseEvent<HTMLButtonElement>) => {
10
+ e.preventDefault()
11
+ e.stopPropagation()
12
+ toggleMode()
13
+ }
14
+
15
+ const label =
16
+ themeMode === 'auto' ? 'Auto' : themeMode === 'light' ? 'Light' : 'Dark'
17
+
18
+ return (
19
+ <Button variant="ghost" size="xs" onClick={handleToggleMode}>
20
+ {themeMode === 'auto' ? (
21
+ <SunMoon className="w-3.5 h-3.5" />
22
+ ) : (
23
+ <>
24
+ <Sun className="w-3.5 h-3.5 hidden light:block" />
25
+ <Moon className="w-3.5 h-3.5 hidden dark:block" />
26
+ </>
27
+ )}
28
+ <span className="hidden sm:inline">{label}</span>
29
+ </Button>
30
+ )
31
+ }
@@ -0,0 +1,86 @@
1
+ import { Link } from '@tanstack/react-router'
2
+ import * as React from 'react'
3
+ import { twMerge } from 'tailwind-merge'
4
+ import type { MarkdownHeading } from '~/types'
5
+
6
+ const headingLevels: Record<number, string> = {
7
+ 1: '',
8
+ 2: '',
9
+ 3: 'pl-2',
10
+ 4: 'pl-4',
11
+ 5: 'pl-6',
12
+ 6: 'pl-8',
13
+ }
14
+
15
+ type TocProps = {
16
+ headings: MarkdownHeading[]
17
+ colorFrom?: string
18
+ colorTo?: string
19
+ textColor?: string
20
+ activeHeadings: Array<string>
21
+ currentFramework?: string
22
+ }
23
+
24
+ export function Toc({
25
+ headings,
26
+ textColor,
27
+ activeHeadings,
28
+ currentFramework,
29
+ }: TocProps) {
30
+ // Filter headings based on framework scope
31
+ const visibleHeadings = React.useMemo(() => {
32
+ return headings.filter((heading) => {
33
+ if (heading.framework) {
34
+ return (
35
+ currentFramework &&
36
+ heading.framework === currentFramework.toLowerCase()
37
+ )
38
+ }
39
+ // If no framework attribute, always show (not framework-scoped)
40
+ return true
41
+ })
42
+ }, [headings, currentFramework])
43
+ return (
44
+ <nav className="flex flex-col sticky top-[var(--navbar-height)] max-h-[calc(100dvh-var(--navbar-height))] overflow-hidden">
45
+ <div className="py-1">
46
+ <h3 className="text-[.8em] lg:text-[.825em] xl:text-[.875em] 2xl:text-[.9em] font-bold">
47
+ On this page
48
+ </h3>
49
+ </div>
50
+ <ul
51
+ className={twMerge(
52
+ 'py-1 flex flex-col overflow-y-auto text-[.6em] lg:text-[.65em] xl:text-[.7em] 2xl:text-[.75em]',
53
+ )}
54
+ >
55
+ {visibleHeadings?.map((heading) => (
56
+ <li
57
+ key={heading.id}
58
+ className={twMerge('w-full', headingLevels[heading.level])}
59
+ >
60
+ <Link
61
+ to="."
62
+ title={heading.id}
63
+ hash={heading.id}
64
+ aria-current={activeHeadings.includes(heading.id) && 'location'}
65
+ className={twMerge(
66
+ 'block py-1 pl-2 border-l-2 rounded-r transition-colors duration-200 opacity-60 hover:opacity-100 hover:bg-gray-500/10',
67
+ activeHeadings.includes(heading.id)
68
+ ? `opacity-100 border-current ${textColor}`
69
+ : 'border-transparent',
70
+ )}
71
+ resetScroll={false}
72
+ hashScrollIntoView={{
73
+ behavior: 'smooth',
74
+ }}
75
+ >
76
+ <span
77
+ className="block break-words overflow-hidden"
78
+ dangerouslySetInnerHTML={{ __html: heading.text }}
79
+ />
80
+ </Link>
81
+ </li>
82
+ ))}
83
+ </ul>
84
+ </nav>
85
+ )
86
+ }
@@ -0,0 +1,118 @@
1
+ import * as React from 'react'
2
+ import { create } from 'zustand'
3
+ import { useNavigate, useParams } from '@tanstack/react-router'
4
+ import { Tag } from 'lucide-react'
5
+ import { Select, SelectOption } from './Select'
6
+
7
+ export function VersionSelect({ versions }: { versions: string[] }) {
8
+ const versionConfig = useVersionConfig({
9
+ versions,
10
+ })
11
+ return (
12
+ <Select
13
+ className="w-full"
14
+ icon={<Tag className="w-3.5 h-3.5 opacity-60" />}
15
+ selected={versionConfig.selected}
16
+ available={versionConfig.available}
17
+ onSelect={versionConfig.onSelect}
18
+ />
19
+ )
20
+ }
21
+
22
+ // Let's use zustand to wrap the local storage logic. This way
23
+ // we'll get subscriptions for free and we can use it in other
24
+ // components if we need to.
25
+ const useLocalCurrentVersion = create<{
26
+ currentVersion?: string
27
+ setCurrentVersion: (version: string) => void
28
+ }>((set) => ({
29
+ currentVersion:
30
+ typeof document !== 'undefined'
31
+ ? localStorage.getItem('version') || undefined
32
+ : undefined,
33
+ setCurrentVersion: (version: string) => {
34
+ localStorage.setItem('version', version)
35
+ set({ currentVersion: version })
36
+ },
37
+ }))
38
+
39
+ /**
40
+ * Use version in URL path
41
+ * Otherwise use version in localStorage if it exists
42
+ * Otherwise fallback to latest
43
+ */
44
+ function useCurrentVersion(versions: string[]) {
45
+ const navigate = useNavigate()
46
+
47
+ const { version: paramsVersion } = useParams({
48
+ strict: false,
49
+ })
50
+
51
+ const localCurrentVersion = useLocalCurrentVersion()
52
+
53
+ let version = paramsVersion || localCurrentVersion.currentVersion || 'latest'
54
+
55
+ version = versions.includes(version) ? version : 'latest'
56
+
57
+ const setVersion = React.useCallback(
58
+ (version: string) => {
59
+ navigate({
60
+ params: { version } as never,
61
+ })
62
+ localCurrentVersion.setCurrentVersion(version)
63
+ },
64
+ [localCurrentVersion, navigate],
65
+ )
66
+
67
+ React.useEffect(() => {
68
+ // Set the version in localStorage if it doesn't exist
69
+ if (!localCurrentVersion.currentVersion) {
70
+ localCurrentVersion.setCurrentVersion(version)
71
+ }
72
+
73
+ // Set the version in localStorage if it doesn't match the URL
74
+ if (paramsVersion && paramsVersion !== localCurrentVersion.currentVersion) {
75
+ localCurrentVersion.setCurrentVersion(paramsVersion)
76
+ }
77
+ })
78
+
79
+ return {
80
+ version,
81
+ setVersion,
82
+ }
83
+ }
84
+
85
+ function useVersionConfig({ versions }: { versions: string[] }) {
86
+ const currentVersion = useCurrentVersion(versions)
87
+
88
+ const versionConfig = React.useMemo(() => {
89
+ const available = versions.reduce(
90
+ (acc: SelectOption[], version) => {
91
+ acc.push({
92
+ label: version,
93
+ value: version,
94
+ })
95
+ return acc
96
+ },
97
+ [
98
+ {
99
+ label: 'Latest',
100
+ value: 'latest',
101
+ },
102
+ ],
103
+ )
104
+
105
+ return {
106
+ label: 'Version',
107
+ selected: versions.includes(currentVersion.version)
108
+ ? currentVersion.version
109
+ : 'latest',
110
+ available,
111
+ onSelect: (option: { label: string; value: string }) => {
112
+ currentVersion.setVersion(option.value)
113
+ },
114
+ }
115
+ }, [currentVersion, versions])
116
+
117
+ return versionConfig
118
+ }
@@ -0,0 +1,27 @@
1
+ import * as React from 'react'
2
+
3
+ export function BSkyIcon({
4
+ className,
5
+ width = '1em',
6
+ height = '1em',
7
+ ...props
8
+ }: React.SVGProps<SVGSVGElement>) {
9
+ return (
10
+ <svg
11
+ viewBox="0 0 24 24"
12
+ fill="none"
13
+ stroke="currentColor"
14
+ strokeWidth={2}
15
+ strokeLinecap="round"
16
+ strokeLinejoin="round"
17
+ width={width}
18
+ height={height}
19
+ role="img"
20
+ aria-hidden={props['aria-label'] ? undefined : true}
21
+ className={className}
22
+ {...props}
23
+ >
24
+ <path d="M6.335 5.144c-1.654 -1.199 -4.335 -2.127 -4.335 .826c0 .59 .35 4.953 .556 5.661c.713 2.463 3.13 2.75 5.444 2.369c-4.045 .665 -4.889 3.208 -2.667 5.41c1.03 1.018 1.913 1.59 2.667 1.59c2 0 3.134 -2.769 3.5 -3.5c.333 -.667 .5 -1.167 .5 -1.5c0 .333 .167 .833 .5 1.5c.366 .731 1.5 3.5 3.5 3.5c.754 0 1.637 -.571 2.667 -1.59c2.222 -2.203 1.378 -4.746 -2.667 -5.41c2.314 .38 4.73 .094 5.444 -2.369c.206 -.708 .556 -5.072 .556 -5.661c0 -2.953 -2.68 -2.025 -4.335 -.826c-2.293 1.662 -4.76 5.048 -5.665 6.856c-.905 -1.808 -3.372 -5.194 -5.665 -6.856z"></path>
25
+ </svg>
26
+ )
27
+ }
@@ -0,0 +1,25 @@
1
+ import * as React from 'react'
2
+
3
+ export function BaseballCapIcon({
4
+ className,
5
+ width = '1em',
6
+ height = '1em',
7
+ ...props
8
+ }: React.SVGProps<SVGSVGElement>) {
9
+ return (
10
+ <svg
11
+ viewBox="0 0 256 256"
12
+ stroke="currentColor"
13
+ fill="currentColor"
14
+ strokeWidth={2}
15
+ width={width}
16
+ height={height}
17
+ role="img"
18
+ aria-hidden={props['aria-label'] ? undefined : true}
19
+ className={className}
20
+ {...props}
21
+ >
22
+ <path d="M128,20A108.12,108.12,0,0,0,20,128v56a27.86,27.86,0,0,0,15.26,24.93,28,28,0,0,0,29.28-2.34C76.2,198.11,96.68,188,128,188s51.8,10.1,63.46,18.58A28,28,0,0,0,236,184V128A108.12,108.12,0,0,0,128,20Zm84,108v1.87a170,170,0,0,0-33.29-14.3,170.81,170.81,0,0,0-23.45-67A84.14,84.14,0,0,1,212,128Zm-58.46-18.12a174.42,174.42,0,0,0-51.08,0A150,150,0,0,1,128,50.94,150.07,150.07,0,0,1,153.54,109.88Zm-52.8-61.31a170.81,170.81,0,0,0-23.45,67A170,170,0,0,0,44,129.87V128A84.14,84.14,0,0,1,100.74,48.57Zm109.11,139a4,4,0,0,1-4.28-.36C191,176.61,165.77,164,128,164s-63,12.61-77.57,23.18a4,4,0,0,1-4.28.36A3.76,3.76,0,0,1,44,184V158.14a148,148,0,0,1,168,0V184A3.76,3.76,0,0,1,209.85,187.54Z"></path>
23
+ </svg>
24
+ )
25
+ }
@@ -0,0 +1,28 @@
1
+ import * as React from 'react'
2
+
3
+ export function BrandXIcon({
4
+ className,
5
+ width = '1em',
6
+ height = '1em',
7
+ ...props
8
+ }: React.SVGProps<SVGSVGElement>) {
9
+ return (
10
+ <svg
11
+ viewBox="0 0 24 24"
12
+ fill="none"
13
+ stroke="currentColor"
14
+ strokeWidth={2}
15
+ strokeLinecap="round"
16
+ strokeLinejoin="round"
17
+ width={width}
18
+ height={height}
19
+ role="img"
20
+ aria-hidden={props['aria-label'] ? undefined : true}
21
+ className={className}
22
+ {...props}
23
+ >
24
+ <path d="M4 4l11.733 16h4.267l-11.733 -16z"></path>
25
+ <path d="M4 20l6.768 -6.768m2.46 -2.46l6.772 -6.772"></path>
26
+ </svg>
27
+ )
28
+ }
@@ -0,0 +1,28 @@
1
+ import * as React from 'react'
2
+
3
+ export function CheckCircleIcon({
4
+ className,
5
+ width = '1em',
6
+ height = '1em',
7
+ ...props
8
+ }: React.SVGProps<SVGSVGElement>) {
9
+ return (
10
+ <svg
11
+ viewBox="0 0 24 24"
12
+ fill="none"
13
+ stroke="currentColor"
14
+ strokeWidth={2}
15
+ strokeLinecap="round"
16
+ strokeLinejoin="round"
17
+ width={width}
18
+ height={height}
19
+ role="img"
20
+ aria-hidden={props['aria-label'] ? undefined : true}
21
+ className={className}
22
+ {...props}
23
+ >
24
+ <circle cx="12" cy="12" r="10" />
25
+ <path d="m9 12 2 2 4-4" />
26
+ </svg>
27
+ )
28
+ }
@@ -0,0 +1,25 @@
1
+ import * as React from 'react'
2
+
3
+ export function CogsIcon({
4
+ className,
5
+ width = '1em',
6
+ height = '1em',
7
+ ...props
8
+ }: React.SVGProps<SVGSVGElement>) {
9
+ return (
10
+ <svg
11
+ stroke="currentColor"
12
+ fill="currentColor"
13
+ strokeWidth="0"
14
+ viewBox="0 0 640 512"
15
+ aria-hidden={props['aria-label'] ? undefined : true}
16
+ className={className}
17
+ height={height}
18
+ width={width}
19
+ role="img"
20
+ xmlns="http://www.w3.org/2000/svg"
21
+ >
22
+ <path d="M512.1 191l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0L552 6.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zm-10.5-58.8c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.7-82.4 14.3-52.8 52.8zM386.3 286.1l33.7 16.8c10.1 5.8 14.5 18.1 10.5 29.1-8.9 24.2-26.4 46.4-42.6 65.8-7.4 8.9-20.2 11.1-30.3 5.3l-29.1-16.8c-16 13.7-34.6 24.6-54.9 31.7v33.6c0 11.6-8.3 21.6-19.7 23.6-24.6 4.2-50.4 4.4-75.9 0-11.5-2-20-11.9-20-23.6V418c-20.3-7.2-38.9-18-54.9-31.7L74 403c-10 5.8-22.9 3.6-30.3-5.3-16.2-19.4-33.3-41.6-42.2-65.7-4-10.9.4-23.2 10.5-29.1l33.3-16.8c-3.9-20.9-3.9-42.4 0-63.4L12 205.8c-10.1-5.8-14.6-18.1-10.5-29 8.9-24.2 26-46.4 42.2-65.8 7.4-8.9 20.2-11.1 30.3-5.3l29.1 16.8c16-13.7 34.6-24.6 54.9-31.7V57.1c0-11.5 8.2-21.5 19.6-23.5 24.6-4.2 50.5-4.4 76-.1 11.5 2 20 11.9 20 23.6v33.6c20.3 7.2 38.9 18 54.9 31.7l29.1-16.8c10-5.8 22.9-3.6 30.3 5.3 16.2 19.4 33.2 41.6 42.1 65.8 4 10.9.1 23.2-10 29.1l-33.7 16.8c3.9 21 3.9 42.5 0 63.5zm-117.6 21.1c59.2-77-28.7-164.9-105.7-105.7-59.2 77 28.7 164.9 105.7 105.7zm243.4 182.7l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0l8.2-14.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zM501.6 431c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.6-82.4 14.3-52.8 52.8z"></path>
23
+ </svg>
24
+ )
25
+ }
@@ -0,0 +1,24 @@
1
+ import * as React from 'react'
2
+
3
+ export function DiscordIcon({
4
+ className,
5
+ width = '1em',
6
+ height = '1em',
7
+ ...props
8
+ }: React.SVGProps<SVGSVGElement>) {
9
+ return (
10
+ <svg
11
+ viewBox="0 0 640 512"
12
+ fill="currentColor"
13
+ width={width}
14
+ height={height}
15
+ role="img"
16
+ aria-hidden={props['aria-label'] ? undefined : true}
17
+ className={className}
18
+ {...props}
19
+ xmlns="http://www.w3.org/2000/svg"
20
+ >
21
+ <path d="M524.531,69.836a1.5,1.5,0,0,0-.764-.7A485.065,485.065,0,0,0,404.081,32.03a1.816,1.816,0,0,0-1.923.91,337.461,337.461,0,0,0-14.9,30.6,447.848,447.848,0,0,0-134.426,0,309.541,309.541,0,0,0-15.135-30.6,1.89,1.89,0,0,0-1.924-.91A483.689,483.689,0,0,0,116.085,69.137a1.712,1.712,0,0,0-.788.676C39.068,183.651,18.186,294.69,28.43,404.354a2.016,2.016,0,0,0,.765,1.375A487.666,487.666,0,0,0,176.02,479.918a1.9,1.9,0,0,0,2.063-.676A348.2,348.2,0,0,0,208.12,430.4a1.86,1.86,0,0,0-1.019-2.588,321.173,321.173,0,0,1-45.868-21.853,1.885,1.885,0,0,1-.185-3.126c3.082-2.309,6.166-4.711,9.109-7.137a1.819,1.819,0,0,1,1.9-.256c96.229,43.917,200.41,43.917,295.5,0a1.812,1.812,0,0,1,1.924.233c2.944,2.426,6.027,4.851,9.132,7.16a1.884,1.884,0,0,1-.162,3.126,301.407,301.407,0,0,1-45.89,21.83,1.875,1.875,0,0,0-1,2.611,391.055,391.055,0,0,0,30.014,48.815,1.864,1.864,0,0,0,2.063.7A486.048,486.048,0,0,0,610.7,405.729a1.882,1.882,0,0,0,.765-1.352C623.729,277.594,590.933,167.465,524.531,69.836ZM222.491,337.58c-28.972,0-52.844-26.587-52.844-59.239S193.056,219.1,222.491,219.1c29.665,0,53.306,26.82,52.843,59.239C275.334,310.993,251.924,337.58,222.491,337.58Zm195.38,0c-28.971,0-52.843-26.587-52.843-59.239S388.437,219.1,417.871,219.1c29.667,0,53.307,26.82,52.844,59.239C470.715,310.993,447.538,337.58,417.871,337.58Z"></path>
22
+ </svg>
23
+ )
24
+ }
@@ -0,0 +1,24 @@
1
+ import * as React from 'react'
2
+
3
+ export function GithubIcon({
4
+ className,
5
+ width = '1em',
6
+ height = '1em',
7
+ ...props
8
+ }: React.SVGProps<SVGSVGElement>) {
9
+ return (
10
+ <svg
11
+ viewBox="0 0 496 512"
12
+ fill="currentColor"
13
+ width={width}
14
+ height={height}
15
+ role="img"
16
+ aria-hidden={props['aria-label'] ? undefined : true}
17
+ className={className}
18
+ {...props}
19
+ xmlns="http://www.w3.org/2000/svg"
20
+ >
21
+ <path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"></path>
22
+ </svg>
23
+ )
24
+ }
@@ -0,0 +1,24 @@
1
+ import * as React from 'react'
2
+
3
+ export function GoogleIcon({
4
+ className,
5
+ width = '1em',
6
+ height = '1em',
7
+ ...props
8
+ }: React.SVGProps<SVGSVGElement>) {
9
+ return (
10
+ <svg
11
+ viewBox="0 0 496 512"
12
+ fill="currentColor"
13
+ width={width}
14
+ height={height}
15
+ role="img"
16
+ aria-hidden={props['aria-label'] ? undefined : true}
17
+ className={className}
18
+ {...props}
19
+ xmlns="http://www.w3.org/2000/svg"
20
+ >
21
+ <path d="M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"></path>
22
+ </svg>
23
+ )
24
+ }
@@ -0,0 +1,24 @@
1
+ import * as React from 'react'
2
+
3
+ export function InstagramIcon({
4
+ className,
5
+ width = '1em',
6
+ height = '1em',
7
+ ...props
8
+ }: React.SVGProps<SVGSVGElement>) {
9
+ return (
10
+ <svg
11
+ viewBox="0 0 448 512"
12
+ fill="currentColor"
13
+ width={width}
14
+ height={height}
15
+ role="img"
16
+ aria-hidden={props['aria-label'] ? undefined : true}
17
+ className={className}
18
+ {...props}
19
+ xmlns="http://www.w3.org/2000/svg"
20
+ >
21
+ <path d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"></path>
22
+ </svg>
23
+ )
24
+ }
@@ -0,0 +1,26 @@
1
+ import * as React from 'react'
2
+
3
+ export function NpmIcon({
4
+ className,
5
+ width = '1em',
6
+ height = '1em',
7
+ ...props
8
+ }: React.SVGProps<SVGSVGElement>) {
9
+ return (
10
+ <svg
11
+ viewBox="0 0 576 512"
12
+ strokeWidth="0"
13
+ fill="currentColor"
14
+ stroke="currentColor"
15
+ width={width}
16
+ height={height}
17
+ role="img"
18
+ aria-hidden={props['aria-label'] ? undefined : true}
19
+ className={className}
20
+ {...props}
21
+ xmlns="http://www.w3.org/2000/svg"
22
+ >
23
+ <path d="M288 288h-32v-64h32v64zm288-128v192H288v32H160v-32H0V160h576zm-416 32H32v128h64v-96h32v96h32V192zm160 0H192v160h64v-32h64V192zm224 0H352v128h64v-96h32v96h32v-96h32v96h32V192z"></path>
24
+ </svg>
25
+ )
26
+ }
@@ -0,0 +1,26 @@
1
+ import * as React from 'react'
2
+
3
+ export function YinYangIcon({
4
+ className,
5
+ width = '1em',
6
+ height = '1em',
7
+ ...props
8
+ }: React.SVGProps<SVGSVGElement>) {
9
+ return (
10
+ <svg
11
+ stroke="currentColor"
12
+ fill="currentColor"
13
+ strokeWidth="0"
14
+ viewBox="0 0 496 512"
15
+ width={width}
16
+ height={height}
17
+ role="img"
18
+ aria-hidden={props['aria-label'] ? undefined : true}
19
+ className={className}
20
+ {...props}
21
+ xmlns="http://www.w3.org/2000/svg"
22
+ >
23
+ <path d="M248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm0 376c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm0-128c-53.02 0-96 42.98-96 96s42.98 96 96 96c-106.04 0-192-85.96-192-192S141.96 64 248 64c53.02 0 96 42.98 96 96s-42.98 96-96 96zm0-128c-17.67 0-32 14.33-32 32s14.33 32 32 32 32-14.33 32-32-14.33-32-32-32z"></path>
24
+ </svg>
25
+ )
26
+ }