diff --git a/.github/ISSUE_TEMPLATE/BUGS.yml b/.github/ISSUE_TEMPLATE/BUGS.yml index 64dab21b75..18358ff125 100644 --- a/.github/ISSUE_TEMPLATE/BUGS.yml +++ b/.github/ISSUE_TEMPLATE/BUGS.yml @@ -1,13 +1,10 @@ name: "Bug Report 🪲" description: Report an issue or possible bug with the functionality of the Solid docs website. (Not related to the content of the site.) title: "[Bug]: " -labels: [ - "bug", - "pending review" -] -assignees: -- danieljcafonso -- atilafassina +labels: ["bug", "pending review"] +assignees: + - danieljcafonso + - atilafassina body: - type: textarea @@ -25,13 +22,13 @@ body: description: Please indicate on which page(s) the issue occurs. placeholder: https://docs.solidjs.com/concepts/intro-to-reactivity validations: - required: true + required: true - type: textarea id: expected attributes: label: "🤔 Expected Behavior" description: Please describe what the expected behavior should be. - placeholder: When on this page, I expected . . . + placeholder: When on this page, I expected . . . validations: required: true - type: textarea @@ -39,7 +36,7 @@ body: attributes: label: "👀 Current Behavior" description: Please describe what the current behavior is. - placeholder: But instead, on this page I'm noticing . . . + placeholder: But instead, on this page I'm noticing . . . validations: required: true - type: input diff --git a/.github/ISSUE_TEMPLATE/CONTENT.yml b/.github/ISSUE_TEMPLATE/CONTENT.yml index 477a961eee..1b1ebe748d 100644 --- a/.github/ISSUE_TEMPLATE/CONTENT.yml +++ b/.github/ISSUE_TEMPLATE/CONTENT.yml @@ -1,11 +1,9 @@ name: "Content Report 📄" title: "[Content]:" description: Report an issue with existing content. -labels: [ - "improve documentation", "pending review" -] -assignees: -- ladybluenotes +labels: ["improve documentation", "pending review"] +assignees: + - ladybluenotes body: - type: markdown attributes: @@ -25,7 +23,7 @@ body: description: Please provide the URL of the page(s) affected. placeholder: https://docs.solidjs.com/concepts/intro-to-reactivity validations: - required: true + required: true - type: textarea id: generalDesc attributes: @@ -33,11 +31,11 @@ body: description: Let us know what's wrong! placeholder: "..." validations: - required: true + required: true - type: textarea id: incorrectContent attributes: label: "🖥️ Reproduction in StackBlitz (if reporting incorrect content or code samples)" description: If you are reporting incorrect content or code samples, you can also attach a reproduction in stackblitz. validations: - required: false + required: false diff --git a/.github/ISSUE_TEMPLATE/REQUEST.yml b/.github/ISSUE_TEMPLATE/REQUEST.yml index 55479fe1e9..f1aef4ba5a 100644 --- a/.github/ISSUE_TEMPLATE/REQUEST.yml +++ b/.github/ISSUE_TEMPLATE/REQUEST.yml @@ -1,11 +1,9 @@ name: "Request 💡" title: "[Request]:" description: Share an idea. -labels: [ - "request", "pending review" -] +labels: ["request", "pending review"] assignees: -- ladybluenotes + - ladybluenotes body: - type: markdown attributes: @@ -14,7 +12,7 @@ body: id: request-topic attributes: label: "What is this request related to?" - options: + options: - Request - Styling - Feature @@ -27,7 +25,7 @@ body: description: Please provide the URL of the page(s) or section this idea is related to. placeholder: https://docs.solidjs.com/concepts/intro-to-reactivity validations: - required: false + required: false - type: textarea id: generalDesc attributes: @@ -35,7 +33,7 @@ body: description: Please provide a general description or bullet points about what you would like to see added. placeholder: "..." validations: - required: true + required: true - type: textarea id: example attributes: @@ -43,4 +41,4 @@ body: description: If you would like to suggest code samples please attach a working reproduction. placeholder: "..." validations: - required: false + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index b105304437..06c2280099 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,4 +2,4 @@ blank_issues_enabled: true contact_links: - name: Support & Community 💁 url: https://discord.com/invite/solidjs - about: 'This issue tracker is not for support questions. Our Discord server hosts the community of Solid users. Come join us to discuss Solid or find assistance!' + about: "This issue tracker is not for support questions. Our Discord server hosts the community of Solid users. Come join us to discuss Solid or find assistance!" diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1a6d7de3ac..b9f88f0cc9 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,6 +4,7 @@ - [ ] This PR references an issue (except for typos, broken links, or other minor problems) ### Description(required) + ### Related issues & labels diff --git a/.github/actions/install/action.yml b/.github/actions/install/action.yml index 17ced68c17..049f92fbd4 100644 --- a/.github/actions/install/action.yml +++ b/.github/actions/install/action.yml @@ -5,9 +5,7 @@ runs: using: composite steps: - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: 10 + uses: pnpm/action-setup@v6 - name: Setup Node.js uses: actions/setup-node@v6 diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml new file mode 100644 index 0000000000..08192d60e4 --- /dev/null +++ b/.github/workflows/autofix.yml @@ -0,0 +1,31 @@ +name: autofix.ci + +on: + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: write + +jobs: + autofix: + name: autofix + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v7.0.0 + with: + fetch-depth: 0 + - name: Setup Tools + uses: ./.github/actions/install + - name: Fix lint issues + run: pnpm lint:fix + - name: Fix formatting + run: pnpm format + - name: Apply fixes + uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 + with: + commit-message: "ci: apply automated fixes" diff --git a/.github/workflows/orama_sync.yml b/.github/workflows/orama_sync.yml index 30d83ee15e..510d513518 100644 --- a/.github/workflows/orama_sync.yml +++ b/.github/workflows/orama_sync.yml @@ -17,14 +17,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v3 - with: - version: 9 + uses: actions/checkout@v7 + - uses: pnpm/action-setup@v6 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 20.x + node-version: 24.x cache: pnpm - name: Install dependencies run: pnpm i @@ -32,4 +30,5 @@ jobs: run: pnpm sync:orama env: ORAMA_PRIVATE_API_KEY: ${{ secrets.ORAMA_PRIVATE_API_KEY }} - ORAMA_PRIVATE_INDEX_ID: ${{ secrets.ORAMA_PRIVATE_INDEX_ID }} + ORAMA_DATASOURCE_ID: ${{ secrets.ORAMA_DATASOURCE_ID }} + ORAMA_PROJECT_ID: ${{ secrets.ORAMA_PROJECT_ID }} diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml index c71be85632..da45c4712c 100644 --- a/.github/workflows/static_checks.yml +++ b/.github/workflows/static_checks.yml @@ -18,14 +18,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out code - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Install tools & dependencies uses: ./.github/actions/install - - name: Generate virtual modules - run: pnpm sync - - name: TypeScript check run: pnpm check:types @@ -33,10 +30,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out code - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Install tools & dependencies uses: ./.github/actions/install - name: Lint code run: pnpm check:lint + + - name: Check formatting + run: pnpm exec prettier . --check diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..474a57d70d --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +ignore-workspace-root-check=true +auto-install-peers=false diff --git a/.prettierignore b/.prettierignore index 97ea5f2502..44ceb5a9c5 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ .solid dist *.min.* -package-lock.json \ No newline at end of file +package-lock.json +.github diff --git a/.prettierrc b/.prettierrc index 1d91c6a999..bfe5b02fa8 100644 --- a/.prettierrc +++ b/.prettierrc @@ -4,5 +4,5 @@ "semi": true, "singleQuote": false, "useTabs": true, - "plugins": ["prettier-plugin-tailwindcss"] + "plugins": ["prettier-plugin-tailwindcss"] } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 26b11b8c7d..1e94e9a229 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -133,13 +133,13 @@ Though it is not a hard requirement, we'd deeply appreciate if you could recomme 1. Create a dictionary file in `src/i18n/dictionaries/{locale}/ui.ts`. The name should follow our locale convention. - - language (ISO 639-1 - set 1): https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes - - country code(optional) (ISO 3166-1 alpha-2): https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 - - E.g.: Canadian French would be: `fr-ca` +- language (ISO 639-1 - set 1): https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes +- country code(optional) (ISO 3166-1 alpha-2): https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 +- E.g.: Canadian French would be: `fr-ca` 2. Add the `import` and language information to the objects in the barrel file: `./src/i18n/dictionaries/index.ts`. So it will be identified by the routing system, and an entry its added to the language dropdown. 3. Add the language to the `array` in `./scripts/collections/index.mjs` so internal files are created. -4. Add the important UI translations to `./src/i18n/dictionaries/{locale}/ui.ts` +4. Add the important UI translations to `./src/i18n/dictionaries/{locale}/ui.ts` 5. Add at least the index page `./src/routes/{locale}/index.mdx`, so others and yourself could see things in action. #### Adding translations to a supported language diff --git a/README.md b/README.md index 04cb6e1eb1..3a195a4352 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,9 @@ Solid Documentation

- 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. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/solidjs/solid-docs-next) @@ -38,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 @@ -52,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 @@ -63,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: @@ -91,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/WRITING.md b/WRITING.md index f1e371efc5..2f0473a138 100644 --- a/WRITING.md +++ b/WRITING.md @@ -188,6 +188,27 @@ Do: Check the [Solid homepage](https://www.solidjs.com) Don't: Click [here](https://www.solidjs.com) to go to the Solid homepage. ``` +## Reference pages + +Reference pages document the API surface. +Keep them concise and easy to scan. + +Include: + +- Imports +- Signatures +- Parameters +- Return values +- Short examples + +Avoid: + +- Narrative context or “why” +- Usage guidance (“when to use”, best practices) +- Long notes + +If explanation is needed, link to a guide or how-to page. + ## Voice and tone So far, we've dealt with how your contributions should look and function. diff --git a/app.config.ts b/app.config.ts deleted file mode 100644 index 24f7049e4e..0000000000 --- a/app.config.ts +++ /dev/null @@ -1,167 +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", - 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", - 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", - 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", - 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", - 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 df07a81008..d92c7e41c0 100644 --- a/env.d.ts +++ b/env.d.ts @@ -10,17 +10,9 @@ interface ImportMeta { declare namespace NodeJS { interface ProcessEnv { + readonly ORAMA_PROJECT_ID: string; + readonly ORAMA_DATASOURCE_ID: string; + readonly ORAMA_PUBLIC_API_KEY: string; readonly ORAMA_PRIVATE_API_KEY: string; - readonly ORAMA_PRIVATE_INDEX_ID: 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 6497c04d0e..2a56d00b79 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 fd182f46af..0000000000 --- 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 0000000000..453b8b80fe --- /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 0000000000..d7bb4025cd --- /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.8", + "@kobalte/core": "^0.13.11", + "@kobalte/solidbase": "catalog:", + "@kobalte/tailwindcss": "^0.9.0", + "@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.16.1", + "@tailwindcss/typography": "^0.5.19", + "solid-heroicons": "^3.2.4", + "solid-js": "^1.9.12", + "tailwindcss": "^4.3.0" + }, + "peerDependencies": { + "tailwindcss": "^4.3.0" + } +} diff --git a/osmium/src/Layout.tsx b/osmium/src/Layout.tsx new file mode 100644 index 0000000000..15046315a8 --- /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 0000000000..b92ee6ec6d --- /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 0000000000..c3c9c552ca --- /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 0000000000..6f4b0aef03 --- /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 282bd6dae1..b9744cada8 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 0000000000..32a6ebf1fc --- /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 b00b7f05b9..c669e0853f 100644 --- a/src/solidbase-theme/mdx-components.tsx +++ b/osmium/src/mdx-components.tsx @@ -9,18 +9,15 @@ 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"; +export { ImageLink } from "./ui/image-link"; -const EraserLinkImpl = clientOnly(() => import("../ui/eraser-link")); +const EraserLinkImpl = clientOnly(() => import("./ui/eraser-link")); type CalloutType = "note" | "tip" | "advanced" | "caution" | "danger"; @@ -82,7 +79,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 +93,7 @@ export const spa = () => <>; export const h1 = (props: ParentProps) => (

{props.children}

@@ -104,10 +101,10 @@ export const h1 = (props: ParentProps) => ( export const h2 = (props: ParentProps) => { return ( <> -
+

{props.children}

@@ -118,7 +115,7 @@ export const h3 = (props: ParentProps) => { return (

{props.children}

@@ -128,7 +125,7 @@ export const h4 = (props: ParentProps) => { return (

{props.children}

@@ -138,7 +135,7 @@ export const h5 = (props: ParentProps) => { return (
{props.children}
@@ -147,7 +144,7 @@ export const h5 = (props: ParentProps) => { export const h6 = (props: ParentProps) => (
{props.children}
@@ -172,23 +169,21 @@ export const a = (props: ParentProps & { href: string }) => { resolvedArray[0].nodeName === "CODE") ) { return ( - {resolved()} - + ); } else { return ( - {resolved()} - + ); } }; @@ -215,17 +210,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 +224,7 @@ export const pre = (props: ParentProps) => { export const code = (props: ParentProps) => { return ( {props.children} @@ -252,9 +242,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 bbb58b687f..947113dfa2 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 e38bc887c9..6dcd53f713 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 0000000000..2816c32676 --- /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 68% rename from src/ui/button-link.tsx rename to osmium/src/ui/button-link.tsx index e9058e12d7..fb123291ad 100644 --- a/src/ui/button-link.tsx +++ b/osmium/src/ui/button-link.tsx @@ -1,20 +1,21 @@ -import { A, type RouterLinkProps } from "./i18n-anchor"; +import { ComponentProps, splitProps } from "solid-js"; -type ButtonLinkProps = RouterLinkProps & { +type ButtonLinkProps = ComponentProps<"a"> & { variant: "primary" | "secondary"; }; export const ButtonLink = (props: ButtonLinkProps) => { + const [localProps, otherProps] = splitProps(props, ["variant"]); + return ( - ); }; diff --git a/src/ui/callout.tsx b/osmium/src/ui/callout.tsx similarity index 95% rename from src/ui/callout.tsx rename to osmium/src/ui/callout.tsx index 9878c4266a..1554e84d73 100644 --- a/src/ui/callout.tsx +++ b/osmium/src/ui/callout.tsx @@ -1,4 +1,3 @@ -import { Alert } from "@kobalte/core"; import { Icon } from "solid-heroicons"; import { mergeProps, type JSX, Show, untrack } from "solid-js"; import { @@ -91,7 +90,7 @@ export function Callout(props: CalloutProps) { const IconComponent = icons[iconType]; return ( - {mergedProps.title} -
+
{mergedProps.children}
-
+ ); } diff --git a/osmium/src/ui/docs-layout.tsx b/osmium/src/ui/docs-layout.tsx new file mode 100644 index 0000000000..fadf427fbc --- /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 094d5579bf..a5c64c28bb 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) => (
- )} 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 88% rename from src/ui/eraser-link/index.tsx rename to osmium/src/ui/eraser-link/index.tsx index 76bdd6f46c..453edf2c98 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} @@ -67,6 +67,7 @@ const EraserLink = ( class="relative inline-block" target="_blank" rel="noopener noreferrer" + aria-label="View diagram on Eraser.io" > {""} setIsLoaded(true)} /> {isLoaded() ? ( @@ -100,7 +101,7 @@ export default function EraserOrAnchor(props: ParentProps<{ href: string }>) { fallback={ {props.children} diff --git a/src/ui/image-links.tsx b/osmium/src/ui/image-link.tsx similarity index 60% rename from src/ui/image-links.tsx rename to osmium/src/ui/image-link.tsx index d287ce897d..e878fdcc92 100644 --- a/src/ui/image-links.tsx +++ b/osmium/src/ui/image-link.tsx @@ -1,5 +1,5 @@ -import { ParentComponent, Show, untrack } from "solid-js"; -import { A } from "~/ui/i18n-anchor"; +import { useLocale } from "@kobalte/solidbase/client"; +import { ParentComponent, untrack } from "solid-js"; /** * @todo @@ -24,19 +24,21 @@ export const logos: { [key: string]: { file: string; style?: string } } = { uno: { file: "uno.svg" }, }; -export type ImageLinksProps = { +export type ImageLinkProps = { title: string; logo: keyof typeof logos; href: string; }; -export const ImageLinks: ParentComponent = (props) => { +export const ImageLink: ParentComponent = (props) => { + const locale = useLocale(); + const logoImage = untrack(() => props.logo); const { file, style } = logos[logoImage]; return (
-