diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml
index 9c4e09ba8..398328ef5 100644
--- a/.github/workflows/static_checks.yml
+++ b/.github/workflows/static_checks.yml
@@ -23,9 +23,6 @@ jobs:
- name: Install tools & dependencies
uses: ./.github/actions/install
- - name: Generate virtual modules
- run: pnpm sync
-
- name: TypeScript check
run: pnpm check:types
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 000000000..474a57d70
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1,2 @@
+ignore-workspace-root-check=true
+auto-install-peers=false
diff --git a/README.md b/README.md
index 035aea0fd..3a195a435 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
Welcome to Solid's documentation!
-This is the repo for [docs.solidjs.com](https://docs.solidjs.com/). This repo
+This is the repo for [docs.solidjs.com](https://docs.solidjs.com/). This repo
contains all the source code that we use to build our docs.
[](https://gitpod.io/#https://github.com/solidjs/solid-docs-next)
@@ -37,9 +37,9 @@ Have you noticed something is missing, confusing, or is wrong in our
documentation?
Check to see if it has
-[already been mentioned ](https://github.com/solidjs/solid-docs-next/issues)
+[already been mentioned ](https://github.com/solidjs/solid-docs/issues)
and, if not,
-[create an issue](https://github.com/solidjs/solid-docs-next/issues/new/choose)
+[create an issue](https://github.com/solidjs/solid-docs/issues/new/choose)
to bring it to our attention!
## Share an idea
@@ -51,7 +51,7 @@ Discussion threads are where you can offer feedback on things that might not be
problems that need addressing, but are ideas to be explored.
Join us in the
-[Discussions section](https://github.com/solidjs/solid-docs-next/discussions/280)
+[Discussions section](https://github.com/solidjs/solid-docs/discussions/280)
where we can brainstorm these ideas, ask questions, and share goals!
## Suggest a fix or contribute
@@ -62,19 +62,19 @@ If you can see what the problem is, and you know how to fix it, you can make a
PR (pull request) with the change and contribute to the docs repo yourself.
If you're looking to make a larger contribution, please see our
-[CONTRIBUTING.md](https://github.com/solidjs/solid-docs-next/blob/main/CONTRIBUTING.md)
+[CONTRIBUTING.md](https://github.com/solidjs/solid-docs/blob/main/CONTRIBUTING.md)
first!
## Running the Site Locally
At the moment, we recommend running the site locally through either
-[CodeSandbox](https://codesandbox.io/p/github/solidjs/solid-docs-next/),
-[Gitpod](https://gitpod.io/#https://github.com/solidjs/solid-docs-next), or
-[StackBlitz](https://stackblitz.com/github/solidjs/solid-docs-next). These are
+[CodeSandbox](https://codesandbox.io/p/github/solidjs/solid-docs/),
+[Gitpod](https://gitpod.io/#https://github.com/solidjs/solid-docs), or
+[StackBlitz](https://stackblitz.com/github/solidjs/solid-docs). These are
the quickest and easiest way to browse and edit the project files and run the
site locally.
-The app uses [pnpm](https://pnpm.io) as the package manager and it runs on Node.js `v18+`.
+The app uses [pnpm](https://pnpm.io) as the package manager and it runs on Node.js `v22+`.
Install dependencies:
@@ -90,9 +90,8 @@ pnpm dev
This will start your the app at [localhost:3000](http://localhost:3000) or the next available port.
-### Collections and virtual modules
+### Framework and Theme
-The builds an [Astro](https://docs.astro.build/en/guides/content-collections/) inspired collection navigation, it will bring all routes and generate a couple of files at `/.solid`.
-These files are exposed to your app via [Vite virtual modules](https://vitejs.dev/guide/api-plugin#virtual-modules-convention). This task is perform via our `sync` script (`pnpm sync`), ran before every build.
+The docs are built on [SolidBase](https://solidbase.dev) and uses the [Osmium Theme](./osmium).
-If changes are made to the navigation (new entry, or repositioning entry), it is necessary to restart the server for changes to take effect.
+This repo should only contain content as mdx files, features should be implemented upstream and UI changes in the theme.
diff --git a/app.config.ts b/app.config.ts
deleted file mode 100644
index 3313de230..000000000
--- a/app.config.ts
+++ /dev/null
@@ -1,177 +0,0 @@
-import { defineConfig } from "@solidjs/start/config";
-
-import { createWithSolidBase, defineTheme } from "@kobalte/solidbase/config";
-
-import tree from "./.solid/tree";
-import entries from "./.solid/flat-entries";
-import solidstartEntries from "./.solid/solid-start-flat-entries";
-import solidrouterEntries from "./.solid/solid-router-flat-entries";
-import solidMetaEntries from "./.solid/solid-meta-flat-entries";
-import solidrouterTree from "./.solid/solid-router-tree";
-import solidStartTree from "./.solid/solid-start-tree";
-import solidMetaTree from "./.solid/solid-meta-tree";
-
-function docsData() {
- const virtualModuleId = "solid:collection";
- const resolveVirtualModuleId = "\0" + virtualModuleId;
-
- return {
- name: virtualModuleId,
- resolveId(id: string) {
- if (id === virtualModuleId) {
- return resolveVirtualModuleId;
- }
- },
- async load(id: string) {
- if (id === resolveVirtualModuleId) {
- return `
- export const coreEntries = ${JSON.stringify(entries, null, 2)}
- export const routerEntries = ${JSON.stringify(solidrouterEntries, null, 2)}
- export const startEntries = ${JSON.stringify(solidstartEntries, null, 2)}
- export const metaEntries = ${JSON.stringify(solidMetaEntries, null, 2)}
- export const coreTree = ${JSON.stringify(tree, null, 2)}
- export const routerTree = ${JSON.stringify(solidrouterTree, null, 2)}
- export const startTree = ${JSON.stringify(solidStartTree, null, 2)}
- export const metaTree = ${JSON.stringify(solidMetaTree, null, 2)}
- `;
- }
- },
- };
-}
-
-const theme = defineTheme({
- componentsPath: import.meta.resolve("./src/solidbase-theme"),
-});
-export default defineConfig(
- createWithSolidBase(theme)(
- {
- ssr: true,
- middleware: "src/middleware/index.ts",
- server: {
- preset: "netlify",
- prerender: {
- crawlLinks: true,
- autoSubfolderIndex: false,
- failOnError: true,
- // eslint-disable-next-line no-useless-escape
- ignore: [/\{\getPath}/, /.*?emojiSvg\(.*/],
- },
- },
- vite: {
- plugins: [docsData(), heroCodeSnippet()],
- },
- },
- {
- title: "Solid Docs",
- description:
- "Documentation for SolidJS, the signals-powered UI framework",
- editPath: "https://github.com/solidjs/solid-docs/edit/main/:path",
- markdown: {
- expressiveCode: {
- themes: ["min-light", "material-theme-ocean"],
- themeCssSelector: (theme) => `[data-theme="${theme.type}"]`,
- frames: false,
- styleOverrides: {
- twoSlash: {
- cursorColor: "var(--twoslash-cursor)",
- },
- },
- },
- toc: {
- minDepth: 2,
- },
- packageManagers: {
- presets: {
- npm: {
- install: "npm i :content",
- "install-dev": "npm i :content -D",
- "install-global": "npm i :content -g",
- "install-local": "npm i",
- remove: "npm remove :content",
- update: "npm update :content",
- run: "npm run :content",
- exec: "npx :content",
- create: "npm init :content",
- },
- pnpm: {
- install: "pnpm i :content",
- "install-dev": "pnpm i :content -D",
- "install-global": "pnpm i :content -g",
- "install-local": "pnpm i",
- remove: "pnpm remove :content",
- update: "pnpm update :content",
- run: "pnpm :content",
- exec: "pnpx :content",
- create: "pnpm create :content",
- },
- yarn: {
- install: "yarn add :content",
- "install-dev": "yarn add :content -D",
- "install-global": "yarn add :content -g",
- "install-local": "yarn i",
- remove: "yarn remove :content",
- update: "yarn upgrade :content",
- run: "yarn :content",
- exec: "yarn dlx :content",
- create: "yarn create :content",
- },
- bun: {
- install: "bun i :content",
- "install-dev": "bun i :content -d",
- "install-global": "bun i :content -g",
- "install-local": "bun i",
- remove: "bun remove :content",
- update: "bun update :content",
- run: "bun run :content",
- exec: "bunx :content",
- create: "bun create :content",
- },
- deno: {
- install: "deno add npm::content",
- "install-dev": "deno add npm::content -D",
- "install-global": "deno add npm::content -g",
- "install-local": "deno i",
- remove: "deno remove npm::content",
- update: "deno update npm::content",
- run: "deno run :content",
- exec: "dpx :content",
- create: "deno init --npm :content",
- },
- },
- },
- },
- }
- )
-);
-
-import { readFile } from "node:fs/promises";
-import { codeToHtml } from "shiki";
-
-function heroCodeSnippet() {
- const virtualModuleId = "solid:hero-code-snippet";
- const resolveVirtualModuleId = "\0" + virtualModuleId;
-
- return {
- name: virtualModuleId,
- resolveId(id: string) {
- if (id === virtualModuleId) {
- return resolveVirtualModuleId;
- }
- },
- async load(id: string) {
- if (id === resolveVirtualModuleId) {
- const snippet = await readFile(
- "./src/ui/layout/hero-code-snippet.code",
- "utf-8"
- );
-
- const highlightedCode = await codeToHtml(snippet.trim(), {
- lang: "tsx",
- theme: "material-theme-ocean",
- });
-
- return `export const highlightedCode = \`${highlightedCode}\``;
- }
- },
- };
-}
diff --git a/env.d.ts b/env.d.ts
index eaa53030d..d92c7e41c 100644
--- a/env.d.ts
+++ b/env.d.ts
@@ -16,13 +16,3 @@ declare namespace NodeJS {
readonly ORAMA_PRIVATE_API_KEY: string;
}
}
-
-declare module "solid:collection" {
- // eslint-disable-next-line
- const component: any;
- export default component;
-}
-
-declare module "solid:hero-code-snippet" {
- export const highlightedCode: string;
-}
diff --git a/eslint.config.ts b/eslint.config.ts
index 6497c04d0..2a56d00b7 100644
--- a/eslint.config.ts
+++ b/eslint.config.ts
@@ -40,6 +40,7 @@ export default tseslint.config(
rules: {
quotes: ["error", "double"],
semi: "warn",
+ "@typescript-eslint/no-empty-object-type": ["off"],
"@typescript-eslint/no-unused-vars": [
"error",
{
diff --git a/global.d.ts b/global.d.ts
deleted file mode 100644
index fd182f46a..000000000
--- a/global.d.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-declare module "solid:collection" {
- import coreTree from ".solid/tree";
- import startTree from ".solid/solid-router-tree";
- import routerTree from ".solid/solid-start-tree";
- import metaTree from ".solid/solid-meta-tree";
- import coreEntries from ".solid/flat-entries";
- import routerEntries from ".solid/solid-start-flat-entries";
- import startEntries from ".solid/solid-router-flat-entries";
- import metaEntries from ".solid/solid-meta-flat-entries";
-
- export {
- coreEntries,
- routerEntries,
- startEntries,
- metaEntries,
- coreTree,
- routerTree,
- startTree,
- metaTree,
- };
-}
diff --git a/osmium/README.md b/osmium/README.md
new file mode 100644
index 000000000..453b8b80f
--- /dev/null
+++ b/osmium/README.md
@@ -0,0 +1,26 @@
+# Osmium
+
+Official SolidJS docs theme for SolidBase.
+
+## Installation
+
+```sh
+npm i solidbase-osmium
+```
+
+In your `vite.config.ts`:
+
+```ts
+import { osmium } from "solidbase-osmium";
+
+const solidBase = createSolidBase(osmium);
+
+export default defineConfig({
+ ...solidBase.startConfig({
+ ...
+ }),
+ plugins: [solidBase.plugin({ ... })],
+})
+```
+
+More information in the [SolidBase docs for consuming a theme.](https://solidbase.dev/guide/customization/custom-themes#consuming-a-theme)
diff --git a/osmium/package.json b/osmium/package.json
new file mode 100644
index 000000000..41ab180af
--- /dev/null
+++ b/osmium/package.json
@@ -0,0 +1,50 @@
+{
+ "name": "solidbase-osmium",
+ "version": "0.0.0-dev",
+ "description": "Official SolidJS docs theme for SolidBase.",
+ "type": "module",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "url": "https://github.com/solidjs/solid-docs"
+ },
+ "keywords": [
+ "solid",
+ "solidjs",
+ "solidbase",
+ "theme"
+ ],
+ "files": [
+ "src"
+ ],
+ "exports": {
+ ".": {
+ "solid": "./src/index.ts",
+ "import": "./src/index.ts",
+ "types": "./src/index.ts"
+ },
+ "./style": "./src/index.css"
+ },
+ "license": "MIT",
+ "dependencies": {
+ "@fontsource-variable/geist": "^5.2.8",
+ "@fontsource-variable/geist-mono": "^5.2.7",
+ "@kobalte/core": "^0.13.11",
+ "@kobalte/solidbase": "catalog:",
+ "@orama/core": "^1.2.19",
+ "@solid-primitives/context": "^0.3.2",
+ "@solid-primitives/event-listener": "^2.4.5",
+ "@solid-primitives/marker": "^0.2.2",
+ "@solid-primitives/platform": "^0.2.1",
+ "@solidjs/router": "0.15.3",
+ "solid-heroicons": "^3.2.4",
+ "solid-js": "^1.9.11",
+ "tailwindcss": "^4.2.2",
+ "@kobalte/tailwindcss": "^0.9.0",
+ "@tailwindcss/typography": "^0.5.19"
+ },
+ "peerDependencies": {
+ "tailwindcss": "^4.2.2"
+ }
+}
diff --git a/osmium/src/Layout.tsx b/osmium/src/Layout.tsx
new file mode 100644
index 000000000..15046315a
--- /dev/null
+++ b/osmium/src/Layout.tsx
@@ -0,0 +1,25 @@
+import { ErrorBoundary } from "solid-js";
+
+import { Layout } from "./ui/layout";
+import { NotFound } from "./ui/not-found";
+import { SidebarProvider, useThemeListener } from "@kobalte/solidbase/client";
+import { usePace } from "@kobalte/solidbase/default-theme/pace.js";
+import { useRouteConfig } from "./utils";
+import { OsmiumThemeStateProvider } from "./context";
+import { ParentProps } from "solid-js";
+
+export default function (props: ParentProps) {
+ const config = useRouteConfig();
+ useThemeListener();
+ usePace();
+
+ return (
+
+
+ }>
+ {props.children}
+
+
+
+ );
+}
diff --git a/osmium/src/context.ts b/osmium/src/context.ts
new file mode 100644
index 000000000..b92ee6ec6
--- /dev/null
+++ b/osmium/src/context.ts
@@ -0,0 +1,34 @@
+import { createSignal } from "solid-js";
+import { createContextProvider } from "@solid-primitives/context";
+import { useOsmiumThemeFrontmatter } from "./frontmatter";
+
+const [OsmiumThemeStateProvider, useOsmiumThemeStateContext] =
+ createContextProvider(() => {
+ const [sidebarOpen, setSidebarOpen] = createSignal(false);
+ const [tocOpen, setTocOpen] = createSignal(false);
+ const [navOpen, setNavOpen] = createSignal(false);
+ const frontmatter = useOsmiumThemeFrontmatter();
+
+ return {
+ sidebarOpen,
+ setSidebarOpen,
+ tocOpen,
+ setTocOpen,
+ navOpen,
+ setNavOpen,
+ frontmatter,
+ };
+ });
+
+export function useOsmiumThemeState() {
+ return (
+ useOsmiumThemeStateContext() ??
+ (() => {
+ throw new Error(
+ "useOsmiumThemeState must be used within a OsmiumThemeStateProvider"
+ );
+ })()
+ );
+}
+
+export { OsmiumThemeStateProvider };
diff --git a/osmium/src/env.d.ts b/osmium/src/env.d.ts
new file mode 100644
index 000000000..c3c9c552c
--- /dev/null
+++ b/osmium/src/env.d.ts
@@ -0,0 +1,8 @@
+interface ImportMetaEnv {
+ readonly VITE_ORAMA_PROJECT_ID?: string;
+ readonly VITE_ORAMA_PUBLIC_API_KEY?: string;
+}
+
+interface ImportMeta {
+ readonly env: ImportMetaEnv;
+}
diff --git a/osmium/src/frontmatter.ts b/osmium/src/frontmatter.ts
new file mode 100644
index 000000000..6f4b0aef0
--- /dev/null
+++ b/osmium/src/frontmatter.ts
@@ -0,0 +1,78 @@
+import { BaseFrontmatter, useFrontmatter } from "@kobalte/solidbase/client";
+import { createMemo } from "solid-js";
+
+export function useOsmiumThemeFrontmatter() {
+ const frontmatter = useFrontmatter();
+
+ return createMemo(() => {
+ const data = frontmatter();
+ if (!data) return data;
+
+ data.editLink ??= true;
+ data.lastUpdated ??= true;
+
+ if (data?.layout === "home") {
+ data.sidebar = false;
+ data.footer = false;
+ data.toc = false;
+ data.prev = false;
+ data.next = false;
+ data.editLink = false;
+ data.lastUpdated = false;
+ }
+
+ return data;
+ });
+}
+
+export type RelativePageConfig =
+ | string
+ | false
+ | {
+ text?: string;
+ link?: string;
+ };
+
+interface OsmiumThemeBaseFrontmatter {
+ category?: string;
+ sidebar?: boolean;
+ footer?: boolean;
+ toc?: boolean;
+ prev?: RelativePageConfig;
+ next?: RelativePageConfig;
+ editLink?: boolean;
+ lastUpdated?: boolean;
+}
+
+interface HeroActionConfig {
+ theme?: string;
+ text?: string;
+ link?: string;
+}
+
+export interface HeroConfig {
+ name?: string;
+ text?: string;
+ tagline?: string;
+ image?: {
+ src: string;
+ alt?: string;
+ };
+ actions?: Array;
+}
+
+export interface FeaturesConfig {
+ icon?: string;
+ title?: string;
+ details?: string;
+}
+
+interface HomeLayoutFrontmatter {
+ layout?: "home";
+ hero?: HeroConfig;
+ features?: Array;
+}
+
+export type OsmiumThemeFrontmatter = (BaseFrontmatter &
+ OsmiumThemeBaseFrontmatter) &
+ HomeLayoutFrontmatter;
diff --git a/src/i18n/dictionaries/en/ui.ts b/osmium/src/i18n/dictionaries/en/ui.ts
similarity index 100%
rename from src/i18n/dictionaries/en/ui.ts
rename to osmium/src/i18n/dictionaries/en/ui.ts
diff --git a/src/styles.css b/osmium/src/index.css
similarity index 91%
rename from src/styles.css
rename to osmium/src/index.css
index 282bd6dae..b9744cada 100644
--- a/src/styles.css
+++ b/osmium/src/index.css
@@ -1,9 +1,7 @@
-@import "tailwindcss/base";
+@import "./tailwind.css";
+
@import "./styles/prism.css";
@import "./styles/expressive-code.css";
-@import "tailwindcss/components";
-@import "tailwindcss/utilities";
-@import "./styles/fonts.css";
@layer base {
html {
@@ -90,7 +88,7 @@
@layer utilities {
a[data-auto-heading] {
- @apply text-slate-900 shadow-none dark:text-white !important;
+ @apply text-slate-900! shadow-none! dark:text-white!;
}
a[data-auto-heading]:hover::after {
@@ -125,7 +123,10 @@
/* pace from solidbase */
:root {
- --bprogress-color: theme("colors.blue.500") !important;
+ --bprogress-color: var(--color-blue-500) !important;
+
+ --font-geist: "Geist Variable", sans-serif;
+ --font-geist-mono: "Geist Mono Variable", monospace;
}
/* twoslash from solidbase */
diff --git a/osmium/src/index.ts b/osmium/src/index.ts
new file mode 100644
index 000000000..32a6ebf1f
--- /dev/null
+++ b/osmium/src/index.ts
@@ -0,0 +1,85 @@
+import { defineTheme } from "@kobalte/solidbase/config";
+import type { SidebarConfig } from "@kobalte/solidbase/config/sidebar";
+import { fileURLToPath } from "node:url";
+
+export interface OsmiumThemeConfig {
+ sidebar?: SidebarConfig;
+ reportPagePath?: string;
+ missingPagePath?: string;
+ discord?: string;
+ github?: string;
+ fonts?: { [K in keyof typeof allFonts]?: false } | false;
+}
+
+type Font = { cssPath: string; preloadFontPath: string; fontType: string };
+
+const allFonts = {
+ geist: {
+ cssPath: import.meta.resolve("@fontsource-variable/geist"),
+ preloadFontPath: import.meta
+ .resolve("@fontsource-variable/geist/files/geist-latin-wght-normal.woff2"),
+ fontType: "woff2",
+ },
+ geistMono: {
+ cssPath: import.meta.resolve("@fontsource-variable/geist-mono"),
+ preloadFontPath: import.meta
+ .resolve("@fontsource-variable/geist-mono/files/geist-mono-latin-wght-normal.woff2"),
+ fontType: "woff2",
+ },
+} satisfies Record;
+
+export const osmium = defineTheme({
+ componentsPath: import.meta.resolve("."),
+ vite(config) {
+ const filteredFonts: Array = [];
+
+ if (config?.themeConfig?.fonts !== false) {
+ const fonts = config?.themeConfig?.fonts;
+ for (const [font, paths] of Object.entries(allFonts)) {
+ if (fonts?.[font as keyof typeof fonts] !== false)
+ filteredFonts.push(paths);
+ }
+ }
+
+ return [
+ {
+ name: "solidbase-osmium-fonts",
+ resolveId(id) {
+ if (id.startsWith("virtual:solidbase-osmium/fonts.css"))
+ return "\0virtual:solidbase-osmium/fonts.css";
+ if (id.startsWith("virtual:solidbase-osmium/fonts"))
+ return "\0virtual:solidbase-osmium/fonts";
+ },
+ load(id) {
+ if (id.startsWith("\0virtual:solidbase-osmium/fonts.css"))
+ return filteredFonts
+ .map(
+ (font) =>
+ `@import url(${fileURLToPath(font.cssPath, { windows: false })});`
+ )
+ .join("\n");
+ if (id.startsWith("\0virtual:solidbase-osmium/fonts")) {
+ const preloadFonts = filteredFonts.map((font, i) => {
+ const pathIdent = `font_${i}`;
+ return {
+ pathIdent,
+ import: `import ${pathIdent} from "${fileURLToPath(font.preloadFontPath, { windows: false })}?url";`,
+ type: font.fontType,
+ };
+ });
+
+ return `
+ ${preloadFonts.map((f) => f.import).join("\n")}
+
+ export const preloadFonts = [
+ ${preloadFonts
+ .map((f) => `{ path: ${f.pathIdent}, type: "${f.type}" }`)
+ .join(",")}
+ ];
+ `;
+ }
+ },
+ },
+ ];
+ },
+});
diff --git a/src/solidbase-theme/mdx-components.tsx b/osmium/src/mdx-components.tsx
similarity index 76%
rename from src/solidbase-theme/mdx-components.tsx
rename to osmium/src/mdx-components.tsx
index b00b7f05b..bee8c1775 100644
--- a/src/solidbase-theme/mdx-components.tsx
+++ b/osmium/src/mdx-components.tsx
@@ -9,18 +9,14 @@ import {
} from "solid-js";
import { isServer } from "solid-js/web";
-import { A } from "~/ui/i18n-anchor";
import { clientOnly } from "@solidjs/start";
-import { Callout } from "~/ui/callout";
-import { Tabs, TabList, TabPanel, Tab } from "~/ui/tabs";
+import { Callout } from "./ui/callout";
+import { Tabs, TabList, TabPanel, Tab } from "./ui/tabs";
-export { EditPageLink } from "~/ui/edit-page-link";
-export { PageIssueLink } from "~/ui/page-issue-link";
-export { Callout } from "~/ui/callout";
-export { QuickLinks } from "~/ui/quick-links";
-export { ImageLinks } from "~/ui/image-links";
+export { Callout } from "./ui/callout";
+export { QuickLinks } from "./ui/quick-links";
-const EraserLinkImpl = clientOnly(() => import("../ui/eraser-link"));
+const EraserLinkImpl = clientOnly(() => import("./ui/eraser-link"));
type CalloutType = "note" | "tip" | "advanced" | "caution" | "danger";
@@ -82,7 +78,7 @@ export const EraserLink = (
aria-hidden={true}
tabIndex="-1"
href={props.href}
- class="font-semibold text-blue-700 no-underline shadow-[inset_0_-2px_0_0_var(--tw-prose-background,#38bdf8),inset_0_calc(-1*(var(--tw-prose-underline-size,2px)+2px))_0_0_var(--tw-prose-underline,theme(colors.blue.400))] hover:[--tw-prose-underline-size:4px] dark:text-blue-400 dark:shadow-[inset_0_calc(-1*var(--tw-prose-underline-size,2px))_0_0_var(--tw-prose-underline,theme(colors.blue.800))] dark:[--tw-prose-background:theme(colors.slate.900)] dark:hover:[--tw-prose-underline-size:6px]"
+ class="font-semibold text-blue-700 no-underline shadow-[inset_0_-2px_0_0_var(--tw-prose-background,#38bdf8),inset_0_calc(-1*(var(--tw-prose-underline-size,2px)+2px))_0_0_var(--tw-prose-underline,var(--color-blue-400))] hover:[--tw-prose-underline-size:4px] dark:text-blue-400 dark:shadow-[inset_0_calc(-1*var(--tw-prose-underline-size,2px))_0_0_var(--tw-prose-underline,var(--color-blue-800))] dark:[--tw-prose-background:var(--color-slate-900)] dark:hover:[--tw-prose-underline-size:6px]"
rel="noopener noreferrer"
>
View on Eraser
@@ -96,7 +92,7 @@ export const spa = () => <>>;
export const h1 = (props: ParentProps) => (
@@ -104,10 +100,10 @@ export const h1 = (props: ParentProps) => (
export const h2 = (props: ParentProps) => {
return (
<>
-
+
@@ -118,7 +114,7 @@ export const h3 = (props: ParentProps) => {
return (
@@ -128,7 +124,7 @@ export const h4 = (props: ParentProps) => {
return (
@@ -138,7 +134,7 @@ export const h5 = (props: ParentProps) => {
return (
@@ -147,7 +143,7 @@ export const h5 = (props: ParentProps) => {
export const h6 = (props: ParentProps) => (
@@ -172,23 +168,21 @@ export const a = (props: ParentProps & { href: string }) => {
resolvedArray[0].nodeName === "CODE")
) {
return (
-
{resolved()}
-
+
);
} else {
return (
-
{resolved()}
-
+
);
}
};
@@ -215,17 +209,12 @@ export const ol = (props: ParentProps) => (
export const nav = (props: ParentProps) => (
);
-export const TesterComponent = () => (
-
- Remove This Now!!! If you see this it means that markdown custom components
- does work
-
-);
+
export const pre = (props: ParentProps) => {
return (
{props.children}
@@ -234,7 +223,7 @@ export const pre = (props: ParentProps) => {
export const code = (props: ParentProps) => {
return (
{props.children}
@@ -252,9 +241,6 @@ export const hr = (props: ParentProps) => {
export const response = (props: ParentProps) => {
return {props.children};
};
-// export const void = (props: ParentProps) => {
-// return {props.children};
-// }
export const unknown = (props: ParentProps) => {
return {props.children};
};
diff --git a/src/styles/expressive-code.css b/osmium/src/styles/expressive-code.css
similarity index 96%
rename from src/styles/expressive-code.css
rename to osmium/src/styles/expressive-code.css
index bbb58b687..947113dfa 100644
--- a/src/styles/expressive-code.css
+++ b/osmium/src/styles/expressive-code.css
@@ -1,3 +1,5 @@
+@reference "../tailwind.css"
+
.expressive-code-overrides .expressive-code {
@apply my-4 font-mono;
}
@@ -7,7 +9,7 @@
}
.expressive-code-overrides .expressive-code .frame.is-terminal .header {
- @apply border-x-0 border-b border-t-0 border-solid border-slate-600/20;
+ @apply border-x-0 border-t-0 border-b border-solid border-slate-600/20;
}
html .expressive-code-overrides .expressive-code pre {
diff --git a/src/styles/prism.css b/osmium/src/styles/prism.css
similarity index 62%
rename from src/styles/prism.css
rename to osmium/src/styles/prism.css
index e38bc887c..6dcd53f71 100644
--- a/src/styles/prism.css
+++ b/osmium/src/styles/prism.css
@@ -1,5 +1,7 @@
+@reference "../tailwind.css"
+
pre[class*="language-"] {
- color: theme("colors.slate.50");
+ color: var(--color-slate-50);
}
.token.tag,
@@ -8,7 +10,7 @@ pre[class*="language-"] {
.token.selector .class,
.token.selector.class,
.token.function {
- color: theme("colors.pink.400");
+ color: var(--color-pink-400);
}
.token.attr-name,
@@ -16,32 +18,32 @@ pre[class*="language-"] {
.token.rule,
.token.pseudo-class,
.token.important {
- color: theme("colors.slate.300");
+ color: var(--color-slate-300);
}
.token.module {
- color: theme("colors.pink.400");
+ color: var(--color-pink-400);
}
.token.attr-value,
.token.class,
.token.string,
.token.property {
- color: theme("colors.sky.300");
+ color: var(--color-sky-300);
}
.token.punctuation,
.token.attr-equals {
- color: theme("colors.slate.500");
+ color: var(--color-slate-500);
}
.token.unit,
.language-css .token.function {
- color: theme("colors.teal.200");
+ color: var(--color-teal-200);
}
.token.comment,
.token.operator,
.token.combinator {
- color: theme("colors.slate.400");
+ color: var(--color-slate-400);
}
diff --git a/osmium/src/tailwind.css b/osmium/src/tailwind.css
new file mode 100644
index 000000000..2816c3267
--- /dev/null
+++ b/osmium/src/tailwind.css
@@ -0,0 +1,61 @@
+@plugin "@tailwindcss/typography";
+@plugin "@kobalte/tailwindcss" {
+ prefix: kb;
+}
+
+@custom-variant dark (&:where([data-theme*='dark'], [data-theme*='dark'] *));
+
+@theme {
+ --text-xs: 0.75rem;
+ --text-xs--line-height: 1rem;
+
+ --text-sm: 0.875rem;
+ --text-sm--line-height: 1.5rem;
+
+ --text-base: 1rem;
+ --text-base--line-height: 2rem;
+
+ --text-lg: 1.125rem;
+ --text-lg--line-height: 1.75rem;
+
+ --text-xl: 1.25rem;
+ --text-xl--line-height: 2rem;
+
+ --text-2xl: 1.5rem;
+ --text-2xl--line-height: 2.5rem;
+
+ --text-3xl: 2rem;
+ --text-3xl--line-height: 2.5rem;
+
+ --text-4xl: 2.5rem;
+ --text-4xl--line-height: 3rem;
+
+ --text-5xl: 3rem;
+ --text-5xl--line-height: 3.5rem;
+
+ --text-6xl: 3.75rem;
+ --text-6xl--line-height: 1;
+
+ --text-7xl: 4.5rem;
+ --text-7xl--line-height: 1;
+
+ --text-8xl: 6rem;
+ --text-8xl--line-height: 1;
+
+ --text-9xl: 8rem;
+ --text-9xl--line-height: 1;
+
+ --font-sans: var(--font-geist);
+ --font-mono: var(--font-geist-mono);
+
+ --font-display: var(--font-geist);
+
+ --container-8xl: 88rem;
+}
+
+@layer utilities {
+ .font-display {
+ font-family: var(--font-geist);
+ font-feature-settings: "ss01";
+ }
+}
diff --git a/src/ui/button-link.tsx b/osmium/src/ui/button-link.tsx
similarity index 82%
rename from src/ui/button-link.tsx
rename to osmium/src/ui/button-link.tsx
index 5bfe0d0b5..fb123291a 100644
--- a/src/ui/button-link.tsx
+++ b/osmium/src/ui/button-link.tsx
@@ -1,7 +1,6 @@
-import { splitProps } from "solid-js";
-import { A, type RouterLinkProps } from "./i18n-anchor";
+import { ComponentProps, splitProps } from "solid-js";
-type ButtonLinkProps = RouterLinkProps & {
+type ButtonLinkProps = ComponentProps<"a"> & {
variant: "primary" | "secondary";
};
@@ -9,8 +8,7 @@ export const ButtonLink = (props: ButtonLinkProps) => {
const [localProps, otherProps] = splitProps(props, ["variant"]);
return (
-
{mergedProps.title}
-
diff --git a/osmium/src/ui/docs-layout.tsx b/osmium/src/ui/docs-layout.tsx
new file mode 100644
index 000000000..fadf427fb
--- /dev/null
+++ b/osmium/src/ui/docs-layout.tsx
@@ -0,0 +1,62 @@
+import { Show, JSX, createMemo } from "solid-js";
+import { Pagination } from "./pagination";
+import { EditPageLink } from "./edit-page-link";
+import { PageIssueLink } from "./page-issue-link";
+import { useOsmiumThemeFrontmatter } from "../frontmatter";
+import { useRouteConfig } from "../utils";
+import { useCurrentPageData } from "@kobalte/solidbase/client";
+
+interface DocsLayoutProps {
+ children: JSX.Element;
+}
+
+export const DocsLayout = (props: DocsLayoutProps) => {
+ const frontmatter = useOsmiumThemeFrontmatter();
+
+ const pageData = useCurrentPageData();
+ const config = useRouteConfig();
+
+ const formatter = createMemo(
+ () => new Intl.DateTimeFormat(undefined, config()?.lastUpdated || undefined)
+ );
+
+ const date = createMemo(
+ () =>
+ new Date(
+ Number.isNaN(pageData()?.lastUpdated)
+ ? 0
+ : (pageData()?.lastUpdated ?? 0)
+ )
+ );
+
+ return (
+
+
+ {(t) => (
+
+ {t()}
+
+ )}
+
+
+ {frontmatter()?.title}
+
+ {props.children}
+
+
+ Last updated:{" "}
+
+ {formatter().format(date())}
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/ui/edit-page-link.tsx b/osmium/src/ui/edit-page-link.tsx
similarity index 61%
rename from src/ui/edit-page-link.tsx
rename to osmium/src/ui/edit-page-link.tsx
index 094d5579b..a5c64c28b 100644
--- a/src/ui/edit-page-link.tsx
+++ b/osmium/src/ui/edit-page-link.tsx
@@ -3,22 +3,19 @@ import { Icon } from "solid-heroicons";
import { pencilSquare } from "solid-heroicons/outline";
import { useCurrentPageData } from "@kobalte/solidbase/client";
-import { useI18n } from "~/i18n/i18n-context";
-
export const EditPageLink: Component = () => {
- const i18n = useI18n();
const data = useCurrentPageData();
return (
{(editLink) => (
-
- {i18n.t("contribute.edit")}
+
+ Edit this page
)}
diff --git a/src/ui/eraser-link/eraser-link.css b/osmium/src/ui/eraser-link/eraser-link.css
similarity index 100%
rename from src/ui/eraser-link/eraser-link.css
rename to osmium/src/ui/eraser-link/eraser-link.css
diff --git a/src/ui/eraser-link/index.tsx b/osmium/src/ui/eraser-link/index.tsx
similarity index 90%
rename from src/ui/eraser-link/index.tsx
rename to osmium/src/ui/eraser-link/index.tsx
index f0e3bfcc0..453edf2c9 100644
--- a/src/ui/eraser-link/index.tsx
+++ b/osmium/src/ui/eraser-link/index.tsx
@@ -55,7 +55,7 @@ const EraserLink = (
fallback={
{props.children}
@@ -101,7 +101,7 @@ export default function EraserOrAnchor(props: ParentProps<{ href: string }>) {
fallback={
{props.children}
diff --git a/osmium/src/ui/layout.tsx b/osmium/src/ui/layout.tsx
new file mode 100644
index 000000000..19dfe81a9
--- /dev/null
+++ b/osmium/src/ui/layout.tsx
@@ -0,0 +1,48 @@
+import { ParentComponent, Show } from "solid-js";
+
+import { MainNavigation } from "./layout/main-navigation";
+import { MainHeader } from "./layout/main-header";
+import { Hero } from "./layout/hero";
+import { DocsLayout } from "./docs-layout";
+import { SidePanel } from "./layout/side-panel";
+import { useOsmiumThemeFrontmatter } from "../frontmatter";
+
+export const Layout: ParentComponent<{ isError?: boolean }> = (props) => {
+ const frontmatter = useOsmiumThemeFrontmatter();
+
+ return (
+
+ );
+};
diff --git a/src/ui/layout/contribute.tsx b/osmium/src/ui/layout/contribute.tsx
similarity index 60%
rename from src/ui/layout/contribute.tsx
rename to osmium/src/ui/layout/contribute.tsx
index ad9ea2d56..25dcd63e8 100644
--- a/src/ui/layout/contribute.tsx
+++ b/osmium/src/ui/layout/contribute.tsx
@@ -1,27 +1,24 @@
import { Component } from "solid-js";
-import { useI18n } from "~/i18n/i18n-context";
import { EditPageLink } from "../edit-page-link";
import { PageIssueLink } from "../page-issue-link";
export const Contribute: Component = () => {
- const i18n = useI18n();
-
return (
<>
- {i18n.t("contribute.title")}
+ Contribute
-
-
+
-
-
+
diff --git a/osmium/src/ui/layout/hero-code-snippet.tsx b/osmium/src/ui/layout/hero-code-snippet.tsx
new file mode 100644
index 000000000..cd4e623be
--- /dev/null
+++ b/osmium/src/ui/layout/hero-code-snippet.tsx
@@ -0,0 +1,3 @@
+export default function CodeSnippet() {
+ return TODO
;
+}
diff --git a/osmium/src/ui/layout/hero.tsx b/osmium/src/ui/layout/hero.tsx
new file mode 100644
index 000000000..78545b5f4
--- /dev/null
+++ b/osmium/src/ui/layout/hero.tsx
@@ -0,0 +1,5 @@
+import { Component } from "solid-js";
+
+export const Hero: Component = () => {
+ return ;
+};
diff --git a/osmium/src/ui/layout/language-selector.tsx b/osmium/src/ui/layout/language-selector.tsx
new file mode 100644
index 000000000..845d04f29
--- /dev/null
+++ b/osmium/src/ui/layout/language-selector.tsx
@@ -0,0 +1,60 @@
+import { Component, Show } from "solid-js";
+import { Icon } from "solid-heroicons";
+import { language } from "solid-heroicons/solid";
+import { ResolvedLocale, useLocale } from "@kobalte/solidbase/client";
+import { Select } from "@kobalte/core/select";
+import { OsmiumThemeConfig } from "../..";
+
+export const LanguageSelector: Component = () => {
+ const { locales, currentLocale, setLocale } = useLocale();
+
+ return (
+ 1}>
+ {(_) => {
+ return (
+
+ );
+ }}
+
+ );
+};
diff --git a/osmium/src/ui/layout/main-header.tsx b/osmium/src/ui/layout/main-header.tsx
new file mode 100644
index 000000000..c532810c9
--- /dev/null
+++ b/osmium/src/ui/layout/main-header.tsx
@@ -0,0 +1,141 @@
+import {
+ ComponentProps,
+ For,
+ Show,
+ createSignal,
+ onCleanup,
+ onMount,
+} from "solid-js";
+import { isServer } from "solid-js/web";
+
+import { ProjectLogo, GitHubIcon, DiscordIcon } from "../logo";
+import { ThemeSelector } from "./theme-selector";
+import { MobileNavigation } from "./mobile-navigation";
+import { LanguageSelector } from "./language-selector";
+
+import { clientOnly } from "@solidjs/start";
+import { useProject, useRouteConfig } from "../../utils";
+import { useOsmiumThemeState } from "../../context";
+
+const ClientSearch = clientOnly(() =>
+ import("../search").then((m) => ({ default: m.Search }))
+);
+
+interface NavLinkProps extends ComponentProps<"a"> {
+ active?: boolean;
+}
+
+function NavLink(props: NavLinkProps) {
+ return (
+
+ {props.children}
+
+ );
+}
+
+interface MainHeaderProps {}
+
+export function MainHeader(_props: MainHeaderProps) {
+ const [isScrolled, setIsScrolled] = createSignal(false);
+
+ const config = useRouteConfig();
+
+ const project = useProject();
+
+ console.log(project());
+
+ const { setNavOpen } = useOsmiumThemeState();
+
+ if (!isServer) {
+ const onScroll = () => {
+ setIsScrolled(window.scrollY > 0);
+ };
+
+ onMount(() => {
+ onScroll();
+ window.addEventListener("scroll", onScroll, { passive: true });
+ });
+
+ onCleanup(() => {
+ window.removeEventListener("scroll", onScroll);
+ });
+ }
+
+ return (
+
+
+
+
+
+ {(projects) => (
+
+
+ {([p, conf]) => {
+ return (
+ -
+ setNavOpen(false)}
+ active={project()?.current === p}
+ >
+ {conf.label}
+
+
+ );
+ }}
+
+
+ )}
+
+
+
+
+
+ );
+}
diff --git a/osmium/src/ui/layout/main-navigation.tsx b/osmium/src/ui/layout/main-navigation.tsx
new file mode 100644
index 000000000..7242742b5
--- /dev/null
+++ b/osmium/src/ui/layout/main-navigation.tsx
@@ -0,0 +1,165 @@
+import { createMemo, createSignal, For, Show } from "solid-js";
+import { useBeforeLeave, useLocation, useMatch } from "@solidjs/router";
+import { Icon } from "solid-heroicons";
+import { chevronDown } from "solid-heroicons/solid";
+import { setIsOpen } from "./mobile-navigation";
+import {
+ SidebarItem,
+ SidebarItemLink,
+ useLocale,
+ useSidebar,
+} from "@kobalte/solidbase/client";
+import { Collapsible } from "@kobalte/core/collapsible";
+import { Tabs } from "@kobalte/core/tabs";
+
+interface MainNavigationProps {}
+
+function ListItemLink(props: { item: SidebarItemLink; prefix?: string }) {
+ const location = useLocation();
+ const locale = useLocale();
+
+ const linkStyles = () =>
+ location.pathname === props.item.link.replace(/\\/g, "/")
+ ? "font-semibold text-blue-700 before:bg-blue-700 dark:before:bg-blue-200 dark:text-blue-300 before:block"
+ : "text-slate-700 before:hidden before:bg-blue-600 before:dark:bg-blue-200 hover:text-blue-700 hover:before:block dark:text-slate-300 ";
+ return (
+ -
+ setIsOpen(false)}
+ href={locale.applyPathPrefix(
+ `${props.prefix === "/" ? "" : (props.prefix ?? "")}${props.item.link === "/" ? "" : props.item.link}`
+ )}
+ class={`block w-full pl-3.5 before:pointer-events-none before:absolute before:top-1/2 before:-left-1 before:h-1.5 before:w-1.5 before:-translate-y-1/2 before:rounded-full hover:text-blue-700 lg:text-sm dark:hover:text-blue-300 ${linkStyles()}`}
+ >
+ {props.item.title}
+
+
+ );
+}
+
+function DirList(props: { items: SidebarItem[] }) {
+ return (
+
+ {(child) => {
+ if ("items" in child) {
+ return (
+ <>
+ -
+
+
+
+ {child.title}
+
+
+
+
+
+
+
+
+ >
+ );
+ }
+
+ if ("link" in child) {
+ return ;
+ }
+
+ return "";
+ }}
+
+ );
+}
+
+export function MainNavigation(_props: MainNavigationProps) {
+ const isReference = useMatch(() => "*/reference/*?");
+
+ const initialTab = () => (isReference() ? "reference" : "learn");
+
+ const [selectedTab, setSelectedTab] = createSignal(initialTab());
+
+ const sidebar = useSidebar();
+
+ const sidebarEntries = createMemo(() => {
+ return sidebar().items.sort((a, b) => {
+ // @ts-expect-error: shorthand
+ return !!a.items - !!b.items;
+ });
+ });
+
+ /**
+ * Re-syncs the selected tab with the chosen route.
+ */
+ useBeforeLeave(({ to }) => {
+ if (typeof to === "number") return;
+
+ if (to.includes("/reference/")) {
+ setSelectedTab("reference");
+ } else {
+ setSelectedTab("learn");
+ }
+ });
+
+ return (
+
}
+ >
+
+ e.title !== "Reference")}
+ />
+
+
+
+
+ No routes found}
+ >
+
+
+ e.title === "Reference" && "items" in e ? e.items : []
+ )}
+ />
+
+
+
+
+
+ );
+}
diff --git a/src/ui/layout/mobile-navigation.tsx b/osmium/src/ui/layout/mobile-navigation.tsx
similarity index 73%
rename from src/ui/layout/mobile-navigation.tsx
rename to osmium/src/ui/layout/mobile-navigation.tsx
index e1714da87..fc10c5e33 100644
--- a/src/ui/layout/mobile-navigation.tsx
+++ b/osmium/src/ui/layout/mobile-navigation.tsx
@@ -4,41 +4,28 @@ import { bars_3, xMark } from "solid-heroicons/solid";
import { MainNavigation } from "./main-navigation";
import { createSignal } from "solid-js";
-interface Entry {
- title: string;
- path: string;
- children?: Entry[];
- mainNavExclude: boolean;
- isTranslated?: boolean;
-}
-
-interface NavProps {
- tree: {
- learn: Entry[];
- reference: Entry[];
- };
-}
+interface MobileNavigationProps {}
export const [isOpen, setIsOpen] = createSignal(false);
-export const MobileNavigation = (props: NavProps) => {
+export const MobileNavigation = (_props: MobileNavigationProps) => {
return (
-
+
-
+
-
+
diff --git a/src/ui/layout/side-panel.tsx b/osmium/src/ui/layout/side-panel.tsx
similarity index 100%
rename from src/ui/layout/side-panel.tsx
rename to osmium/src/ui/layout/side-panel.tsx
diff --git a/src/ui/layout/table-of-contents.tsx b/osmium/src/ui/layout/table-of-contents.tsx
similarity index 81%
rename from src/ui/layout/table-of-contents.tsx
rename to osmium/src/ui/layout/table-of-contents.tsx
index e8181b503..6b8509de0 100644
--- a/src/ui/layout/table-of-contents.tsx
+++ b/osmium/src/ui/layout/table-of-contents.tsx
@@ -6,14 +6,10 @@ import {
import { createEventListener } from "@solid-primitives/event-listener";
import { isServer } from "solid-js/web";
-import { useI18n } from "~/i18n/i18n-context";
-
export const TableOfContents = () => {
const data = useCurrentPageData();
const toc = () => data()?.toc;
- const i18n = useI18n();
-
const [currentSection, setCurrentSection] = createSignal();
const [headingElements, setHeadingElements] = createSignal<
@@ -53,13 +49,10 @@ export const TableOfContents = () => {
return (