squash and nuke dev
This commit is contained in:
parent
b2d43ad425
commit
f26e76c114
93 changed files with 33827 additions and 7831 deletions
2
.env.development
Normal file
2
.env.development
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
VERSION_FILE_PATH="./versions.json"
|
||||||
|
BASE_URL="localhost:4321"
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -27,4 +27,7 @@ modules/
|
||||||
modules_old/
|
modules_old/
|
||||||
|
|
||||||
# env
|
# env
|
||||||
.env*
|
.env.production
|
||||||
|
|
||||||
|
# module archive
|
||||||
|
*.tar.gz
|
||||||
|
|
|
||||||
19608
.pnp.cjs
generated
Executable file
19608
.pnp.cjs
generated
Executable file
File diff suppressed because one or more lines are too long
3022
.pnp.loader.mjs
generated
Normal file
3022
.pnp.loader.mjs
generated
Normal file
File diff suppressed because it is too large
Load diff
4
.vim/coc-settings.json
Normal file
4
.vim/coc-settings.json
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"workspace.workspaceFolderCheckCwd": false,
|
||||||
|
"tsserver.tsdk": ".yarn/sdks/typescript/lib"
|
||||||
|
}
|
||||||
1
.yarnrc.yml
Normal file
1
.yarnrc.yml
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
nodeLinker: pnp
|
||||||
58
README.md
58
README.md
|
|
@ -1,18 +1,62 @@
|
||||||
# Quickshell Docs
|
Quickshell Docs
|
||||||
|
===============
|
||||||
|
|
||||||
Documentation for [quickshell](https://git.outfoxxed.me/outfoxxed/quickshell)
|
Documentation for [quickshell](https://git.outfoxxed.me/outfoxxed/quickshell) Hosted version at [quickshell.org](https://quickshell.outfoxxed.me)
|
||||||
Hosted version at [quickshell.outfoxxed.me](https://quickshell.outfoxxed.me)
|
|
||||||
|
|
||||||
Frontend rewritten by [Xanazf](https://github.com/Xanazf)
|
Frontend rewritten by [Xanazf](https://github.com/Xanazf)
|
||||||
|
|
||||||
## Notes for future updates
|
---
|
||||||
|
|
||||||
|
Development
|
||||||
|
-----------
|
||||||
|
|
||||||
|
### Install language server attribution
|
||||||
|
|
||||||
|
> [!INFO] Yarn
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> yarn dlx @yarnpkg/sdks base
|
||||||
|
> ```
|
||||||
|
|
||||||
|
======
|
||||||
|
|
||||||
|
> [!INFO] NPM
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> npx @yarnpkg/sdks base
|
||||||
|
> ```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Enable the language server to use yarn sdks
|
||||||
|
|
||||||
|
> [!NOTE] Example for Neovim
|
||||||
|
>
|
||||||
|
> ```lua
|
||||||
|
> {
|
||||||
|
> -- ...
|
||||||
|
> typescript = {
|
||||||
|
> -- ...
|
||||||
|
> tsdk = "./.yarn/sdks/typescript/lib",
|
||||||
|
> -- ...
|
||||||
|
> },
|
||||||
|
> -- or whatever language server you're using
|
||||||
|
> vtsls = {
|
||||||
|
> autoUseWorkspaceTsdk = true,
|
||||||
|
> }
|
||||||
|
> }
|
||||||
|
> ```
|
||||||
|
|
||||||
|
Notes for future updates
|
||||||
|
------------------------
|
||||||
|
|
||||||
~- improve Head~
|
~- improve Head~
|
||||||
|
|
||||||
- improve light theme
|
- improve light theme
|
||||||
- QtQML docs search
|
- QtQML docs search
|
||||||
- page metadata:
|
- page metadata:
|
||||||
- lastUpdatedAt
|
- `min_version`
|
||||||
- prevUpdate?
|
- `max_version`
|
||||||
- editURL
|
- `edit_URL`
|
||||||
- typedocs clearer borders between layout parts
|
- typedocs clearer borders between layout parts
|
||||||
|
- better front page styling
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig, envField } from "astro/config";
|
||||||
import solidJs from "@astrojs/solid-js";
|
import solidJs from "@astrojs/solid-js";
|
||||||
import mdx from "@astrojs/mdx";
|
import mdx from "@astrojs/mdx";
|
||||||
import icon from "astro-icon";
|
import icon from "astro-icon";
|
||||||
|
|
@ -10,14 +10,32 @@ import { markdownConfig } from "./src/config/io/markdown.ts";
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
markdown: markdownConfig,
|
markdown: markdownConfig,
|
||||||
site: "https://quickshell.outfoxxed.me",
|
site: "https://quickshell.org",
|
||||||
integrations: [
|
integrations: [
|
||||||
solidJs({
|
solidJs({
|
||||||
devtools: true,
|
devtools: false,
|
||||||
}),
|
}),
|
||||||
mdx(),
|
mdx(),
|
||||||
pagefind(),
|
pagefind(),
|
||||||
icon(),
|
icon(),
|
||||||
sitemap(),
|
sitemap(),
|
||||||
],
|
],
|
||||||
|
env: {
|
||||||
|
schema: {
|
||||||
|
VERSION_FILE_PATH: envField.string({
|
||||||
|
context: "server",
|
||||||
|
access: "secret",
|
||||||
|
default: "./versions.json",
|
||||||
|
}),
|
||||||
|
BASE_URL: envField.number({
|
||||||
|
context: "server",
|
||||||
|
access: "public",
|
||||||
|
}),
|
||||||
|
PRODUCTION: envField.string({
|
||||||
|
context: "server",
|
||||||
|
access: "secret",
|
||||||
|
optional: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://biomejs.dev/schemas/2.0.4/schema.json",
|
"$schema": "https://biomejs.dev/schemas/2.4.1/schema.json",
|
||||||
|
"files": {
|
||||||
|
"includes": ["**", "!!**/dist", "!**/node_modules", "!**/.yarn"]
|
||||||
|
},
|
||||||
"formatter": {
|
"formatter": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"formatWithErrors": true,
|
"formatWithErrors": true,
|
||||||
"indentStyle": "space",
|
"indentStyle": "space",
|
||||||
"indentWidth": 2,
|
"indentWidth": 2,
|
||||||
"lineEnding": "lf",
|
"lineEnding": "lf",
|
||||||
"lineWidth": 66,
|
"lineWidth": 80,
|
||||||
"attributePosition": "multiline"
|
"attributePosition": "auto"
|
||||||
},
|
},
|
||||||
"plugins": [],
|
"plugins": [],
|
||||||
"linter": {
|
"linter": {
|
||||||
|
|
@ -25,6 +28,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"html": {
|
||||||
|
"formatter": {
|
||||||
|
"enabled": true,
|
||||||
|
"indentScriptAndStyle": true,
|
||||||
|
"lineWidth": 80
|
||||||
|
},
|
||||||
|
"experimentalFullSupportEnabled": true
|
||||||
|
},
|
||||||
"javascript": {
|
"javascript": {
|
||||||
"formatter": {
|
"formatter": {
|
||||||
"jsxQuoteStyle": "double",
|
"jsxQuoteStyle": "double",
|
||||||
|
|
@ -51,12 +62,18 @@
|
||||||
"cssModules": true
|
"cssModules": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"json": {
|
||||||
|
"formatter": {
|
||||||
|
"enabled": true,
|
||||||
|
"lineWidth": 80,
|
||||||
|
"lineEnding": "lf",
|
||||||
|
"indentStyle": "space",
|
||||||
|
"indentWidth": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"includes": [
|
"includes": ["**/*.ts", "**/*.tsx"],
|
||||||
"**/*.ts",
|
|
||||||
"**/*.tsx"
|
|
||||||
],
|
|
||||||
"linter": {
|
"linter": {
|
||||||
"rules": {
|
"rules": {
|
||||||
"complexity": {
|
"complexity": {
|
||||||
|
|
@ -78,19 +95,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"includes": [
|
|
||||||
"*.astro"
|
|
||||||
],
|
|
||||||
"linter": {
|
|
||||||
"rules": {
|
|
||||||
"style": {
|
|
||||||
"useConst": "off",
|
|
||||||
"useImportType": "off"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
8446
package-lock.json
generated
8446
package-lock.json
generated
File diff suppressed because it is too large
Load diff
58
package.json
58
package.json
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "quickshell-docs",
|
"name": "quickshell-docs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.0.1",
|
"version": "0.1.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"start": "astro dev",
|
"start": "astro dev",
|
||||||
|
|
@ -10,33 +10,45 @@
|
||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ark-ui/solid": "^3.5.0",
|
"@astrojs/check": "0.9.6",
|
||||||
"@astrojs/check": "^0.9.4",
|
"@astrojs/markdown-remark": "6.3.10",
|
||||||
"@astrojs/markdown-remark": "^6.3.1",
|
"@astrojs/mdx": "4.3.13",
|
||||||
"@astrojs/mdx": "^4.2.6",
|
"@astrojs/sitemap": "3.7.0",
|
||||||
"@astrojs/sitemap": "^3.4.0",
|
"@astrojs/solid-js": "^5.1.3",
|
||||||
"@astrojs/solid-js": "^5.0.10",
|
"@fontsource-variable/rubik": "^5.2.8",
|
||||||
"@fontsource-variable/rubik": "^5.1.0",
|
|
||||||
"@hbsnow/rehype-sectionize": "^1.0.7",
|
"@hbsnow/rehype-sectionize": "^1.0.7",
|
||||||
"@pagefind/default-ui": "^1.1.1",
|
"@pagefind/default-ui": "^1.4.0",
|
||||||
"@shikijs/rehype": "^3.4.2",
|
"@shikijs/rehype": "^3.22.0",
|
||||||
"@types/node": "^20.14.11",
|
"astro": "5.17.2",
|
||||||
"astro": "^5.7.13",
|
"astro-breadcrumbs": "^3.3.3",
|
||||||
"astro-breadcrumbs": "^3.3.1",
|
|
||||||
"astro-icon": "^1.1.5",
|
"astro-icon": "^1.1.5",
|
||||||
"hast": "^1.0.0",
|
|
||||||
"hast-util-from-html": "^2.0.3",
|
"hast-util-from-html": "^2.0.3",
|
||||||
"remark-github-blockquote-alert": "^1.2.1",
|
"hastscript": "^9.0.1",
|
||||||
"solid-devtools": "^0.30.1",
|
"jsdom": "^28.1.0",
|
||||||
"solid-js": "^1.8.18",
|
"rehype": "^13.0.2",
|
||||||
"typescript": "^5.5.3",
|
"remark-github-blockquote-alert": "^2.0.1",
|
||||||
|
"solid-js": "^1.9.11",
|
||||||
"unified": "^11.0.5",
|
"unified": "^11.0.5",
|
||||||
"unist-util-visit": "^5.0.0"
|
"unist-util-visit": "^5.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@astrojs/ts-plugin": "^1.10.3",
|
"@astrojs/ts-plugin": "1.10.6",
|
||||||
"@biomejs/biome": "^1.8.3",
|
"@babel/core": "^7.29.0",
|
||||||
"pagefind": "^1.1.1"
|
"@babel/plugin-syntax-typescript": "^7.28.6",
|
||||||
|
"@biomejs/biome": "^2.3.15",
|
||||||
|
"@types/babel__core": "^7.20.5",
|
||||||
|
"@types/hast": "^3.0.4",
|
||||||
|
"@types/jsdom": "^27.0.0",
|
||||||
|
"@types/mdast": "^4.0.4",
|
||||||
|
"@types/node": "^25.2.3",
|
||||||
|
"@types/unist": "^3.0.3",
|
||||||
|
"baseline-browser-mapping": "^2.9.19",
|
||||||
|
"jsonc-parser": "^3.3.1",
|
||||||
|
"pagefind": "^1.4.0",
|
||||||
|
"shiki": "^3.22.0",
|
||||||
|
"tsx": "^4.21.0",
|
||||||
|
"typescript": "^5.9.3",
|
||||||
|
"vite": "^7.3.1"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@4.5.0"
|
"packageManager": "yarn@4.12.0"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,11 @@ export default function pagefind(): AstroIntegration {
|
||||||
const cwd = dirname(fileURLToPath(import.meta.url));
|
const cwd = dirname(fileURLToPath(import.meta.url));
|
||||||
const relativeDir = relative(cwd, targetDir);
|
const relativeDir = relative(cwd, targetDir);
|
||||||
return new Promise<void>(resolve => {
|
return new Promise<void>(resolve => {
|
||||||
spawn(
|
spawn("yarn", ["pagefind", "--site", relativeDir], {
|
||||||
"yarn",
|
|
||||||
["pagefind", "--site", relativeDir],
|
|
||||||
{
|
|
||||||
stdio: "inherit",
|
stdio: "inherit",
|
||||||
shell: true,
|
shell: true,
|
||||||
cwd,
|
cwd,
|
||||||
}
|
}).on("close", () => resolve());
|
||||||
).on("close", () => resolve());
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
---
|
---
|
||||||
import "@styles/components/accordion.css";
|
import "@styles/components/accordion.css";
|
||||||
---
|
---
|
||||||
<details class=`accordion ${Astro.props.class ?? ""}` {...Astro.props}>
|
|
||||||
<summary>
|
<details class={`accordion ${Astro.props.class ?? ""}`} {...Astro.props}>
|
||||||
<slot name="header"/>
|
<summary><slot name="header" /></summary>
|
||||||
</summary>
|
|
||||||
<div class="accordion-container">
|
<div class="accordion-container">
|
||||||
<div>
|
<div><slot /></div>
|
||||||
<slot/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -16,7 +13,9 @@ import "@styles/components/accordion.css";
|
||||||
document.querySelectorAll(".accordion").forEach(element => {
|
document.querySelectorAll(".accordion").forEach(element => {
|
||||||
const accordion = element as HTMLDetailsElement;
|
const accordion = element as HTMLDetailsElement;
|
||||||
const summary = accordion.querySelector("summary")!;
|
const summary = accordion.querySelector("summary")!;
|
||||||
const body = accordion.querySelector(".accordion-container") as HTMLDivElement;
|
const body = accordion.querySelector(
|
||||||
|
".accordion-container"
|
||||||
|
) as HTMLDivElement;
|
||||||
|
|
||||||
summary.addEventListener("click", event => {
|
summary.addEventListener("click", event => {
|
||||||
if ((event.target as Element).tagName === "A") return;
|
if ((event.target as Element).tagName === "A") return;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
const production = import.meta.env.PRODUCTION;
|
const production = import.meta.env.PRODUCTION;
|
||||||
---
|
---
|
||||||
|
|
||||||
{production && <script is:inline defer data-domain="quickshell.outfoxxed.me" src="https://z.outfoxxed.me/z.js"></script>}
|
{production && <script is:inline defer data-domain="quickshell.outfoxxed.me" src="https://z.outfoxxed.me/z.js"></script>}
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,13 @@ export interface Props {
|
||||||
|
|
||||||
const { badgeText, withIcon = true, badgeIconName } = Astro.props;
|
const { badgeText, withIcon = true, badgeIconName } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<span class="badge">
|
<span class="badge">
|
||||||
{withIcon &&
|
{withIcon &&
|
||||||
(
|
(
|
||||||
badgeIconName ?
|
badgeIconName ?
|
||||||
<Icon name={badgeIconName}/>
|
<Icon name={badgeIconName}/>
|
||||||
: <Icon name={"flag"}/>
|
: <Icon name={"flag"}/>
|
||||||
)
|
)}
|
||||||
}
|
|
||||||
<span class="badge-text">{badgeText}</span>
|
<span class="badge-text">{badgeText}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,11 @@ interface Props {
|
||||||
}
|
}
|
||||||
const { title } = Astro.props;
|
const { title } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<Accordion class="docs-collapsible">
|
<Accordion class="docs-collapsible">
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
<Fragment set:html={collapsibleMarker}/>
|
<Fragment set :html={collapsibleMarker} />
|
||||||
{title}
|
{title}
|
||||||
</div>
|
</div>
|
||||||
<slot>
|
<slot />
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import matrixLogo from "@icons/matrix-logo.svg?raw";
|
import matrixLogo from "@icons/matrix-logo.svg?raw";
|
||||||
import discordLogo from "@icons/discord-logo.svg?raw";
|
import discordLogo from "@icons/discord-logo.svg?raw";
|
||||||
import gitLogo from "@icons/git-logo.svg?raw";
|
import gitLogo from "@icons/git-logo.svg?raw";
|
||||||
|
import ThemeToggle from "./ThemeToggle.astro";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
class?: string;
|
class?: string;
|
||||||
|
|
@ -9,6 +10,7 @@ interface Props {
|
||||||
|
|
||||||
const props = Astro.props;
|
const props = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<footer class=`${props.class ?? ""}`>
|
<footer class=`${props.class ?? ""}`>
|
||||||
<div class="credits">
|
<div class="credits">
|
||||||
<p class="hint">Brought to you by:</p>
|
<p class="hint">Brought to you by:</p>
|
||||||
|
|
@ -18,6 +20,7 @@ const props = Astro.props;
|
||||||
and our contributors
|
and our contributors
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
<ThemeToggle />
|
||||||
<div class="socials-changelog">
|
<div class="socials-changelog">
|
||||||
<section class="socials">
|
<section class="socials">
|
||||||
<a href="https://matrix.to/#/#quickshell:outfoxxed.me" target="_blank" aria-label="Join our matrix space">
|
<a href="https://matrix.to/#/#quickshell:outfoxxed.me" target="_blank" aria-label="Join our matrix space">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
import { ThemeSelect } from "@components/hooks/ThemeSwitch";
|
import ThemeToggle from "./ThemeToggle.astro";
|
||||||
import type { TypeData } from "@config/io/types";
|
import type { TypeData } from "@config/_types";
|
||||||
import Nav from "@components/navigation/sidebars/nav/index.astro";
|
import Nav from "@components/navigation/sidebars/nav/index.astro";
|
||||||
import TOC from "@components/navigation/sidebars/TOC.astro";
|
import TOC from "@components/navigation/sidebars/TOC.astro";
|
||||||
import type { ConfigHeading } from "@components/navigation/sidebars/types";
|
import type { ConfigHeading } from "@components/navigation/sidebars/types";
|
||||||
|
|
@ -14,16 +14,15 @@ interface Props {
|
||||||
|
|
||||||
const { title, headings, type } = Astro.props;
|
const { title, headings, type } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="header-item header-left">
|
<div class="header-item header-left">
|
||||||
<Nav mobile={true}/>
|
<Nav mobile={true} />
|
||||||
<h3 class="header-title">
|
<h3 class="header-title"><a href="/">Quickshell</a></h3>
|
||||||
<a href="/">Quickshell</a>
|
|
||||||
</h3>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="header-item header-right">
|
<div class="header-item header-right">
|
||||||
<Search/>
|
<Search />
|
||||||
<ThemeSelect client:load />
|
<ThemeToggle />
|
||||||
<TOC title={title} headings={headings} type={type} mobile={true}/>
|
<TOC title={title} headings={headings} type={type} mobile={true} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
50
src/components/ThemeToggle.astro
Normal file
50
src/components/ThemeToggle.astro
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
---
|
||||||
|
import { Icon } from "astro-icon/components";
|
||||||
|
---
|
||||||
|
|
||||||
|
<label
|
||||||
|
class="theme-toggle icon-button standard"
|
||||||
|
title="Toggle theme"
|
||||||
|
for="theme-manual-toggle"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
name="moon"
|
||||||
|
class="light-icon"
|
||||||
|
style="width: 24px; height: 24px;"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
name="sun"
|
||||||
|
class="dark-icon"
|
||||||
|
style="width: 24px; height: 24px;"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
<div class="state-layer"></div>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.theme-toggle {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.light-icon {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.dark-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html:has(input#theme-manual-toggle:checked)) .light-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html:has(input#theme-manual-toggle:checked)) .dark-icon {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle:focus-within {
|
||||||
|
outline: 2px solid var(--accent-600);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
---
|
---
|
||||||
import { processMarkdown } from "@config/io/markdown";
|
import { processMarkdown } from "@config/io/markdown";
|
||||||
|
|
||||||
const codeDesktop = await processMarkdown("N/A", `\`\`\`qml
|
const codeDesktop = await processMarkdown(
|
||||||
|
"N/A",
|
||||||
|
`\`\`\`qml
|
||||||
// a standard desktop window
|
// a standard desktop window
|
||||||
FloatingWindow {
|
FloatingWindow {
|
||||||
Timer {
|
Timer {
|
||||||
|
|
@ -19,9 +21,12 @@ FloatingWindow {
|
||||||
// change the window's color when timer.invert changes
|
// change the window's color when timer.invert changes
|
||||||
color: timer.invert ? "purple" : "green"
|
color: timer.invert ? "purple" : "green"
|
||||||
}
|
}
|
||||||
\`\`\``);
|
\`\`\``
|
||||||
|
);
|
||||||
|
|
||||||
const codeMobile = await processMarkdown("N/A", `\`\`\`qml
|
const codeMobile = await processMarkdown(
|
||||||
|
"N/A",
|
||||||
|
`\`\`\`qml
|
||||||
// a standard desktop window
|
// a standard desktop window
|
||||||
FloatingWindow {
|
FloatingWindow {
|
||||||
Timer {
|
Timer {
|
||||||
|
|
@ -47,19 +52,22 @@ FloatingWindow {
|
||||||
? "purple"
|
? "purple"
|
||||||
: "green"
|
: "green"
|
||||||
}
|
}
|
||||||
\`\`\``);
|
\`\`\``
|
||||||
|
);
|
||||||
---
|
---
|
||||||
|
|
||||||
<ul class="featurelist">
|
<ul class="featurelist">
|
||||||
<li class="featurelist-item hot-reloading left">
|
<li class="featurelist-item hot-reloading left">
|
||||||
<section class="feature-text">
|
<section class="feature-text">
|
||||||
<h3 class="feature-title">See your changes in real time</h3>
|
<h3 class="feature-title">See your changes in real time</h3>
|
||||||
<span class="feature-subtitle">
|
<span class="feature-subtitle">
|
||||||
Quickshell loads changes as soon as they're saved, letting you iterate as fast as you can type.
|
Quickshell loads changes as soon as they're saved, letting you iterate
|
||||||
|
as fast as you can type.
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
<section class="feature-showcase">
|
<section class="feature-showcase">
|
||||||
<video preload="metadata" controls={false} autoplay loop>
|
<video preload="metadata" controls={false} autoplay loop>
|
||||||
<source src="/assets/simple-shell-livereload.mp4" type="video/mp4"/>
|
<source src="/assets/simple-shell-livereload.mp4" type="video/mp4">
|
||||||
</video>
|
</video>
|
||||||
</section>
|
</section>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -67,46 +75,69 @@ FloatingWindow {
|
||||||
<section class="feature-text">
|
<section class="feature-text">
|
||||||
<h3 class="feature-title">Easy to use language</h3>
|
<h3 class="feature-title">Easy to use language</h3>
|
||||||
<span class="feature-subtitle">
|
<span class="feature-subtitle">
|
||||||
Quickshell is configured in QML, a simple language designed for creating flexible user interfaces.
|
Quickshell is configured in QML, a simple language designed for creating
|
||||||
It also has LSP support.
|
flexible user interfaces. It also has LSP support.
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
<section class="feature-showcase" id="qml-showcase">
|
<section class="feature-showcase" id="qml-showcase">
|
||||||
<div class="showcase-desktop">
|
<div class="showcase-desktop"><Fragment set :html={codeDesktop} /></div>
|
||||||
<Fragment set:html={codeDesktop}/>
|
<div class="showcase-mobile"><Fragment set :html={codeMobile} /></div>
|
||||||
</div>
|
|
||||||
<div class="showcase-mobile">
|
|
||||||
<Fragment set:html={codeMobile}/>
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
</li>
|
</li>
|
||||||
<li class="featurelist-item cloud-li left">
|
<li class="featurelist-item cloud-li left">
|
||||||
<section class="feature-text">
|
<section class="feature-text">
|
||||||
<h3 class="feature-title">Extensive integrations</h3>
|
<h3 class="feature-title">Extensive integrations</h3>
|
||||||
<span class="feature-subtitle">
|
<span class="feature-subtitle">
|
||||||
Quickshell comes with a large set of integrations, with new ones arriving all the time.
|
Quickshell comes with a large set of integrations, with new ones
|
||||||
|
arriving all the time.
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
<section class="feature-showcase cloud">
|
<section class="feature-showcase cloud">
|
||||||
<section class="feature-cloud">
|
<section class="feature-cloud">
|
||||||
<div class="cloud-center">
|
<div class="cloud-center">
|
||||||
<img src="/favicon.svg" alt="Quickshell" />
|
<img src="/favicon.svg" alt="Quickshell">
|
||||||
</div>
|
</div>
|
||||||
<div class="cloud-items-wrapper">
|
<div class="cloud-items-wrapper">
|
||||||
<span class="cloud-item wayland">
|
<span class="cloud-item wayland">
|
||||||
<div><img class="feature-icon" src="/assets/logos/wayland.svg" alt="Wayland" /></div>
|
<div>
|
||||||
|
<img
|
||||||
|
class="feature-icon"
|
||||||
|
src="/assets/logos/wayland.svg"
|
||||||
|
alt="Wayland"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<span class="cloud-item hyprland">
|
<span class="cloud-item hyprland">
|
||||||
<div><img class="feature-icon" src="/assets/logos/hyprland.svg" alt="Hyprland" /></div>
|
<div>
|
||||||
|
<img
|
||||||
|
class="feature-icon"
|
||||||
|
src="/assets/logos/hyprland.svg"
|
||||||
|
alt="Hyprland"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<span class="cloud-item pipewire">
|
<span class="cloud-item pipewire">
|
||||||
<div><img class="feature-icon" src="/assets/logos/pipewire.svg" alt="Pipewire" /></div>
|
<div>
|
||||||
|
<img
|
||||||
|
class="feature-icon"
|
||||||
|
src="/assets/logos/pipewire.svg"
|
||||||
|
alt="Pipewire"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<span class="cloud-item x-org">
|
<span class="cloud-item x-org">
|
||||||
<div><img class="feature-icon" src="/assets/logos/xorg.svg" alt="X.Org" /></div>
|
<div>
|
||||||
|
<img
|
||||||
|
class="feature-icon"
|
||||||
|
src="/assets/logos/xorg.svg"
|
||||||
|
alt="X.Org"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<span class="cloud-item sway">
|
<span class="cloud-item sway">
|
||||||
<div><img class="feature-icon" src="/assets/logos/sway.svg" alt="Sway" /></div>
|
<div>
|
||||||
|
<img class="feature-icon" src="/assets/logos/sway.svg" alt="Sway">
|
||||||
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<script>
|
|
||||||
setTimeout(() => {
|
|
||||||
// code copy
|
|
||||||
let blocks = document.querySelectorAll("pre");
|
|
||||||
if (blocks.length > 0) {
|
|
||||||
blocks.forEach((block) => {
|
|
||||||
let button = document.createElement("button");
|
|
||||||
button.className = "copy-button";
|
|
||||||
button.innerHTML = `<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="1em"
|
|
||||||
height="1em"
|
|
||||||
viewBox="0 0 256 256"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M200 32h-36.26a47.92 47.92 0 0 0-71.48 0H56a16 16 0 0 0-16 16v168a16 16 0 0 0 16 16h144a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16m-72 0a32 32 0 0 1 32 32H96a32 32 0 0 1 32-32m72 184H56V48h26.75A47.9 47.9 0 0 0 80 64v8a8 8 0 0 0 8 8h80a8 8 0 0 0 8-8v-8a47.9 47.9 0 0 0-2.75-16H200Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
`;
|
|
||||||
button.onclick = () => {
|
|
||||||
let snippet = block.innerText ?? "";
|
|
||||||
navigator.clipboard.writeText(snippet);
|
|
||||||
button.classList.toggle("copied");
|
|
||||||
setTimeout(() => button.classList.remove("copied"), 1000);
|
|
||||||
};
|
|
||||||
block.appendChild(button);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 3001)
|
|
||||||
|
|
||||||
// heading copy
|
|
||||||
let headings = document.getElementsByClassName("heading")
|
|
||||||
if (headings.length > 0) {
|
|
||||||
for (const heading of headings) {
|
|
||||||
let button = heading.querySelector("span")
|
|
||||||
if (button) {
|
|
||||||
button.onclick = () => {
|
|
||||||
let link = window.location.href.split("#")[0];
|
|
||||||
link += `#-${heading.textContent?.slice(10).trimEnd().replaceAll(" ", "-").toLowerCase()}`;
|
|
||||||
window.location.href = link
|
|
||||||
navigator.clipboard.writeText(link);
|
|
||||||
heading.classList.toggle("copied")
|
|
||||||
setTimeout(() => heading.classList.remove("copied"), 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
---
|
|
||||||
---
|
|
||||||
<script>
|
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const observer = new IntersectionObserver(entries => {
|
|
||||||
entries.forEach(entry => {
|
|
||||||
const heading = entry.target.querySelector('h1, h2, h3, h4, h5, h6')
|
|
||||||
if(heading) {
|
|
||||||
const id = heading.id
|
|
||||||
if (entry.intersectionRatio > 0) {
|
|
||||||
const desktopElement = document.querySelector(`.toc-wrapper li a[href="#${id}"]`);
|
|
||||||
const mobileElement = document.querySelector(`.toc-wrapper-mobile li a[href="#${id}"]`);
|
|
||||||
const element = mobileElement?.checkVisibility() ? mobileElement : desktopElement;
|
|
||||||
element?.parentElement?.classList.add('active')
|
|
||||||
} else {
|
|
||||||
const desktopElement = document.querySelector(`.toc-wrapper li a[href="#${id}"]`);
|
|
||||||
const mobileElement = document.querySelector(`.toc-wrapper-mobile li a[href="#${id}"]`);
|
|
||||||
const element = mobileElement?.checkVisibility() ? mobileElement : desktopElement;
|
|
||||||
element?.parentElement?.classList.remove('active')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelectorAll('section[data-heading-rank]').forEach((section) => {
|
|
||||||
observer.observe(section);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
import {
|
|
||||||
createSignal,
|
|
||||||
createEffect,
|
|
||||||
onCleanup,
|
|
||||||
onMount,
|
|
||||||
type VoidComponent,
|
|
||||||
} from "solid-js";
|
|
||||||
|
|
||||||
import Sun from "@icons/sun.svg?raw";
|
|
||||||
import Moon from "@icons/moon.svg?raw";
|
|
||||||
|
|
||||||
export interface ThemeProps {
|
|
||||||
theme: "light" | "dark";
|
|
||||||
system: "light" | "dark";
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getCurrentTheme = (): ThemeProps => {
|
|
||||||
if (
|
|
||||||
typeof localStorage !== "undefined" &&
|
|
||||||
(localStorage.theme === "dark" ||
|
|
||||||
(!("theme" in localStorage) &&
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)")
|
|
||||||
.matches))
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
theme: "dark",
|
|
||||||
system: window.matchMedia("(prefers-color-scheme: dark)")
|
|
||||||
.matches
|
|
||||||
? "dark"
|
|
||||||
: "light",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
theme: "light",
|
|
||||||
system: window.matchMedia("(prefers-color-scheme: dark)")
|
|
||||||
.matches
|
|
||||||
? "dark"
|
|
||||||
: "light",
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateTheme = () => {
|
|
||||||
document.documentElement.classList.add("changing-theme");
|
|
||||||
if (
|
|
||||||
localStorage.theme === "dark" ||
|
|
||||||
(!("theme" in localStorage) &&
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").matches)
|
|
||||||
) {
|
|
||||||
document.documentElement.classList.add("dark");
|
|
||||||
} else {
|
|
||||||
document.documentElement.classList.remove("dark");
|
|
||||||
}
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
document.documentElement.classList.remove("changing-theme");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ThemeSelect: VoidComponent = () => {
|
|
||||||
const [currentTheme, setCurrentTheme] =
|
|
||||||
createSignal<ThemeProps>({
|
|
||||||
theme: "dark",
|
|
||||||
system: "dark",
|
|
||||||
});
|
|
||||||
const [mounted, setMounted] = createSignal(false);
|
|
||||||
|
|
||||||
const toggleTheme = () => {
|
|
||||||
if (!mounted()) return;
|
|
||||||
setCurrentTheme(getCurrentTheme());
|
|
||||||
if (currentTheme()!.theme !== currentTheme()!.system) {
|
|
||||||
localStorage.removeItem("theme");
|
|
||||||
} else {
|
|
||||||
localStorage.theme =
|
|
||||||
currentTheme()!.theme === "dark" ? "light" : "dark";
|
|
||||||
}
|
|
||||||
updateTheme();
|
|
||||||
setCurrentTheme(getCurrentTheme());
|
|
||||||
};
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
setMounted(true);
|
|
||||||
setCurrentTheme(getCurrentTheme());
|
|
||||||
});
|
|
||||||
|
|
||||||
createEffect(() => {
|
|
||||||
const mediaQuery = window.matchMedia(
|
|
||||||
"(prefers-color-scheme: dark)"
|
|
||||||
);
|
|
||||||
mediaQuery.addEventListener("change", updateTheme);
|
|
||||||
window.addEventListener("storage", updateTheme);
|
|
||||||
|
|
||||||
onCleanup(() => {
|
|
||||||
mediaQuery.removeEventListener("change", updateTheme);
|
|
||||||
window.removeEventListener("storage", updateTheme);
|
|
||||||
setMounted(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
onclick={toggleTheme}
|
|
||||||
class="theme-toggle"
|
|
||||||
innerHTML={
|
|
||||||
(mounted() && currentTheme().theme === "light") ||
|
|
||||||
currentTheme().system === "light"
|
|
||||||
? Sun
|
|
||||||
: Moon
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,145 +1,18 @@
|
||||||
---
|
---
|
||||||
import { Icon } from "astro-icon/components";
|
import { Icon } from "astro-icon/components";
|
||||||
|
import MarqueeContent from "./MarqueeContent.astro";
|
||||||
const videos = [
|
|
||||||
{
|
|
||||||
author: '<a href="https://github.com/soramanew">soramane</a>',
|
|
||||||
source: "https://github.com/caelestia-dots/shell",
|
|
||||||
path: "/assets/showcase/soramane.mp4",
|
|
||||||
installable: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
author: '<a href="https://github.com/end-4">end_4</a>',
|
|
||||||
source: "https://github.com/end-4/dots-hyprland",
|
|
||||||
path: "/assets/showcase/end4.mp4",
|
|
||||||
installable: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
author: '<a href="https://outfoxxed.me">outfoxxed</a>',
|
|
||||||
source: "https://git.outfoxxed.me/outfoxxed/nixnew/src/branch/master/modules/user/modules/quickshell",
|
|
||||||
path: "/assets/showcase/outfoxxed.mp4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
author: '<a href="https://github.com/pfaj/">pfaj</a> and <a href="https://github.com/bdebiase">bdebiase</a>',
|
|
||||||
path: "/assets/showcase/pfaj-bdeblase.mp4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
author: '<a href="https://github.com/flickowoa">flicko</a>',
|
|
||||||
source: "https://github.com/flickowoa/zephyr",
|
|
||||||
path: "/assets/showcase/flicko.mp4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
author: '<a href="https://vaxry.net">vaxry</a>',
|
|
||||||
path: "/assets/showcase/vaxry.mp4",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="marquee">
|
<div class="marquee">
|
||||||
<div class="marquee-scroll">
|
<div class="marquee-scroll">
|
||||||
<div id="marquee-scroll-left" class="marquee-scroll-arrow">
|
<div id="marquee-scroll-left" class="marquee-scroll-arrow">
|
||||||
<div><Icon name="caret-left"/></div>
|
<div><Icon name="caret-left" /></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="marquee-scroll-right" class="marquee-scroll-arrow">
|
<div id="marquee-scroll-right" class="marquee-scroll-arrow">
|
||||||
<div><Icon name="caret-right"/></div>
|
<div><Icon name="caret-right" /></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="marquee-content" class="marquee-content" data-scroll="0" data-media-index="0">
|
<MarqueeContent />
|
||||||
{videos.map(({ author, source, installable, path }, index) => <div class="marquee-item">
|
|
||||||
<div>
|
|
||||||
<video
|
|
||||||
data-media-index={index}
|
|
||||||
data-media-author={author}
|
|
||||||
id="showcase-video"
|
|
||||||
class="marquee-item-spacing marquee-item-content"
|
|
||||||
muted
|
|
||||||
controls
|
|
||||||
playsinline
|
|
||||||
preload="metadata"
|
|
||||||
>
|
|
||||||
<source src={path} type="video/mp4"/>
|
|
||||||
</video>
|
|
||||||
<p>
|
|
||||||
Configuration by <Fragment set:html={author}/>
|
|
||||||
{source && !installable && <>(<a href={source}>source code</a>)</>}
|
|
||||||
{source && installable && <>(<a href={source}>install</a>)</>}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script src="@config/styling/marquee.ts" />
|
||||||
const videoCount = 6; // last array index
|
|
||||||
const marquee = document.getElementById("marquee-content")!;
|
|
||||||
marquee.style.setProperty("--scroll", "0")
|
|
||||||
|
|
||||||
window.addEventListener("load", autoplayInit, false);
|
|
||||||
const videos = document.getElementsByClassName("marquee-item-content") as HTMLCollectionOf<HTMLVideoElement>;
|
|
||||||
let currentVideoIndex = 0;
|
|
||||||
let currentVideo: HTMLVideoElement | null = null;
|
|
||||||
|
|
||||||
function autoplayInit() {
|
|
||||||
setActiveVideo(0);
|
|
||||||
currentVideo!.play();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setActiveVideo(index: number) {
|
|
||||||
currentVideo?.pause();
|
|
||||||
|
|
||||||
currentVideoIndex = index;
|
|
||||||
currentVideo = videos[currentVideoIndex];
|
|
||||||
currentVideo.currentTime = 0;
|
|
||||||
marquee.style.setProperty("--scroll", `-${currentVideoIndex*100}%`)
|
|
||||||
}
|
|
||||||
|
|
||||||
function offsetCarousel(offset: number) {
|
|
||||||
let nextIndex = currentVideoIndex + offset;
|
|
||||||
if (nextIndex < 0) nextIndex += videoCount;
|
|
||||||
nextIndex = nextIndex % videoCount;
|
|
||||||
setActiveVideo(nextIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
const intersectionOptions = {
|
|
||||||
root: marquee,
|
|
||||||
rootMargin: "0px",
|
|
||||||
threshold: 0.0,
|
|
||||||
};
|
|
||||||
|
|
||||||
const observer = new IntersectionObserver((entries) => {
|
|
||||||
entries.forEach((entry) => {
|
|
||||||
const video = entry.target as HTMLVideoElement;
|
|
||||||
if (!entry.isIntersecting) {
|
|
||||||
video.pause();
|
|
||||||
} else if (video === currentVideo) {
|
|
||||||
video.play();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, intersectionOptions);
|
|
||||||
|
|
||||||
for (const video of videos) {
|
|
||||||
observer.observe(video);
|
|
||||||
|
|
||||||
video.addEventListener("ended", () => {
|
|
||||||
// The "ended" event might just mean its buffering.
|
|
||||||
if (video == currentVideo && video.duration !== 0 && video.currentTime === video.duration) {
|
|
||||||
offsetCarousel(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let wasPaused = false;
|
|
||||||
document.addEventListener("visibilitychange", () => {
|
|
||||||
if (currentVideo) {
|
|
||||||
if (document.hidden) {
|
|
||||||
wasPaused = currentVideo.paused;
|
|
||||||
currentVideo.pause();
|
|
||||||
} else if (!wasPaused) {
|
|
||||||
currentVideo.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// left-right buttons
|
|
||||||
document.getElementById("marquee-scroll-left")!.addEventListener("mousedown", () => offsetCarousel(-1));
|
|
||||||
document.getElementById("marquee-scroll-right")!.addEventListener("mousedown", () => offsetCarousel(1));
|
|
||||||
</script>
|
|
||||||
|
|
|
||||||
66
src/components/marquee/MarqueeContent.astro
Normal file
66
src/components/marquee/MarqueeContent.astro
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
const videos = [
|
||||||
|
{
|
||||||
|
author: '<a href="https://github.com/soramanew">soramane</a>',
|
||||||
|
source: "https://github.com/caelestia-dots/shell",
|
||||||
|
path: "/assets/showcase/soramane.mp4",
|
||||||
|
installable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
author: '<a href="https://github.com/end-4">end_4</a>',
|
||||||
|
source: "https://github.com/end-4/dots-hyprland",
|
||||||
|
path: "/assets/showcase/end4.mp4",
|
||||||
|
installable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
author: '<a href="https://outfoxxed.me">outfoxxed</a>',
|
||||||
|
source:
|
||||||
|
"https://git.outfoxxed.me/outfoxxed/nixnew/src/branch/master/modules/user/modules/quickshell",
|
||||||
|
path: "/assets/showcase/outfoxxed.mp4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
author:
|
||||||
|
'<a href="https://github.com/pfaj/">pfaj</a> and <a href="https://github.com/bdebiase">bdebiase</a>',
|
||||||
|
path: "/assets/showcase/pfaj-bdeblase.mp4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
author: '<a href="https://github.com/flickowoa">flicko</a>',
|
||||||
|
source: "https://github.com/flickowoa/zephyr",
|
||||||
|
path: "/assets/showcase/flicko.mp4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
author: '<a href="https://vaxry.net">vaxry</a>',
|
||||||
|
path: "/assets/showcase/vaxry.mp4",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
---
|
||||||
|
|
||||||
|
<div
|
||||||
|
id="marquee-content"
|
||||||
|
class="marquee-content"
|
||||||
|
data-scroll="0"
|
||||||
|
data-media-index="0"
|
||||||
|
>
|
||||||
|
{videos.map(({ author, source, installable, path }, index) => {
|
||||||
|
return (
|
||||||
|
<div class=`marquee-item`>
|
||||||
|
<video
|
||||||
|
data-media-index={index}
|
||||||
|
data-media-author={author}
|
||||||
|
id="showcase-video"
|
||||||
|
class="marquee-item-spacing marquee-item-content"
|
||||||
|
muted
|
||||||
|
controls
|
||||||
|
playsinline
|
||||||
|
preload="metadata"
|
||||||
|
>
|
||||||
|
<source src={path} type="video/mp4"/>
|
||||||
|
</video>
|
||||||
|
<p>
|
||||||
|
Configuration by <Fragment set:html={author}/>
|
||||||
|
{source && !installable && <>(<a href={source}>source code</a>)</>}
|
||||||
|
{source && installable && <>(<a href={source}>install</a>)</>}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)})}
|
||||||
|
</div>
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
---
|
---
|
||||||
import "@pagefind/default-ui/css/ui.css";
|
import "@pagefind/default-ui/css/ui.css";
|
||||||
import magnifierIcon from "@icons/magnifier.svg?raw"
|
import magnifierIcon from "@icons/magnifier.svg?raw";
|
||||||
---
|
---
|
||||||
|
|
||||||
<site-search class="search-wrapper">
|
<site-search class="search-wrapper">
|
||||||
<button
|
<button
|
||||||
data-open-modal
|
data-open-modal
|
||||||
|
|
@ -10,58 +11,60 @@ import magnifierIcon from "@icons/magnifier.svg?raw"
|
||||||
aria-keyshortcuts="Control+K"
|
aria-keyshortcuts="Control+K"
|
||||||
class="search-button"
|
class="search-button"
|
||||||
>
|
>
|
||||||
<Fragment set:html={magnifierIcon}/>
|
<Fragment set :html={magnifierIcon} />
|
||||||
<span class="search-label" aria-hidden="true">Search</span>
|
<span class="search-label" aria-hidden="true">Search</span>
|
||||||
<kbd class="search-kbd">
|
<kbd class="search-kbd"> <kbd>Ctrl</kbd><kbd>K</kbd> </kbd>
|
||||||
<kbd>Ctrl</kbd><kbd>K</kbd>
|
|
||||||
</kbd>
|
|
||||||
</button>
|
</button>
|
||||||
<dialog aria-label="Search" class="search-dialog">
|
<dialog aria-label="Search" class="search-dialog">
|
||||||
<div class="dialog-frame">
|
<div class="dialog-frame">
|
||||||
<button data-close-modal class="search-cancel">
|
<button data-close-modal class="search-cancel">Cancel</button>
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
<div class="search-container">
|
<div class="search-container">
|
||||||
<div id="qs_search"/>
|
<div id="qs_search" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
</site-search>
|
</site-search>
|
||||||
{
|
{/**
|
||||||
/**
|
|
||||||
* NOTE: YOINKED FROM STARLIGHT
|
* NOTE: YOINKED FROM STARLIGHT
|
||||||
* This is intentionally inlined to avoid briefly showing an invalid shortcut.
|
* This is intentionally inlined to avoid briefly showing an invalid shortcut.
|
||||||
* Purposely using the deprecated `navigator.platform` property to detect Apple devices, as the
|
* Purposely using the deprecated `navigator.platform` property to detect Apple devices, as the
|
||||||
* user agent is spoofed by some browsers when opening the devtools.
|
* user agent is spoofed by some browsers when opening the devtools.
|
||||||
*/
|
*/}
|
||||||
}
|
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
(() => {
|
(() => {
|
||||||
const openBtn = document.querySelector('button[data-open-modal]');
|
const openBtn = document.querySelector("button[data-open-modal]");
|
||||||
const shortcut = openBtn?.querySelector('kbd');
|
const shortcut = openBtn?.querySelector("kbd");
|
||||||
if (!openBtn || !(shortcut instanceof HTMLElement)) return;
|
if (!openBtn || !(shortcut instanceof HTMLElement)) return;
|
||||||
const platformKey = shortcut.querySelector('kbd');
|
const platformKey = shortcut.querySelector("kbd");
|
||||||
if (platformKey && /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {
|
if (platformKey && /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {
|
||||||
platformKey.textContent = '⌘';
|
platformKey.textContent = "⌘";
|
||||||
openBtn.setAttribute('aria-keyshortcuts', 'Meta+K');
|
openBtn.setAttribute("aria-keyshortcuts", "Meta+K");
|
||||||
}
|
}
|
||||||
shortcut.style.display = '';
|
shortcut.style.display = "";
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getQMLTypeLinkObject, getQMLTypeLink, getIconForLink } from '@src/config/io/helpers';
|
import {
|
||||||
|
getQMLTypeLinkObject,
|
||||||
|
getQMLTypeLink,
|
||||||
|
getIconForLink,
|
||||||
|
} from "@src/config/io/helpers";
|
||||||
class SiteSearch extends HTMLElement {
|
class SiteSearch extends HTMLElement {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
const openBtn = this.querySelector<HTMLButtonElement>('button[data-open-modal]')!;
|
const openBtn = this.querySelector<HTMLButtonElement>(
|
||||||
const closeBtn = this.querySelector<HTMLButtonElement>('button[data-close-modal]')!;
|
"button[data-open-modal]"
|
||||||
const dialog = this.querySelector('dialog')!;
|
)!;
|
||||||
const dialogFrame = this.querySelector('.dialog-frame')!;
|
const closeBtn = this.querySelector<HTMLButtonElement>(
|
||||||
|
"button[data-close-modal]"
|
||||||
|
)!;
|
||||||
|
const dialog = this.querySelector("dialog")!;
|
||||||
|
const dialogFrame = this.querySelector(".dialog-frame")!;
|
||||||
|
|
||||||
/** Close the modal if a user clicks on a link or outside of the modal. */
|
/** Close the modal if a user clicks on a link or outside of the modal. */
|
||||||
const onClick = (event: MouseEvent) => {
|
const onClick = (event: MouseEvent) => {
|
||||||
const isLink = 'href' in (event.target || {});
|
const isLink = "href" in (event.target || {});
|
||||||
if (
|
if (
|
||||||
isLink ||
|
isLink ||
|
||||||
(document.body.contains(event.target as Node) &&
|
(document.body.contains(event.target as Node) &&
|
||||||
|
|
@ -73,71 +76,89 @@ import { getQMLTypeLinkObject, getQMLTypeLink, getIconForLink } from '@src/confi
|
||||||
|
|
||||||
const openModal = (event?: MouseEvent) => {
|
const openModal = (event?: MouseEvent) => {
|
||||||
dialog.showModal();
|
dialog.showModal();
|
||||||
document.body.toggleAttribute('data-search-modal-open', true);
|
document.body.toggleAttribute("data-search-modal-open", true);
|
||||||
this.querySelector('input')?.focus();
|
this.querySelector("input")?.focus();
|
||||||
event?.stopPropagation();
|
event?.stopPropagation();
|
||||||
window.addEventListener('click', onClick);
|
window.addEventListener("click", onClick);
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeModal = () => dialog.close();
|
const closeModal = () => dialog.close();
|
||||||
|
|
||||||
openBtn.addEventListener('click', openModal);
|
openBtn.addEventListener("click", openModal);
|
||||||
openBtn.disabled = false;
|
openBtn.disabled = false;
|
||||||
closeBtn.addEventListener('click', closeModal);
|
closeBtn.addEventListener("click", closeModal);
|
||||||
|
|
||||||
dialog.addEventListener('close', () => {
|
dialog.addEventListener("close", () => {
|
||||||
document.body.toggleAttribute('data-search-modal-open', false);
|
document.body.toggleAttribute("data-search-modal-open", false);
|
||||||
window.removeEventListener('click', onClick);
|
window.removeEventListener("click", onClick);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Listen for `ctrl + k` and `cmd + k` keyboard shortcuts.
|
// Listen for `ctrl + k` and `cmd + k` keyboard shortcuts.
|
||||||
window.addEventListener('keydown', (e) => {
|
window.addEventListener("keydown", e => {
|
||||||
if ((e.metaKey === true || e.ctrlKey === true) && e.key === 'k') {
|
if ((e.metaKey === true || e.ctrlKey === true) && e.key === "k") {
|
||||||
dialog.open ? closeModal() : openModal();
|
dialog.open ? closeModal() : openModal();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const processExcerpt = (sub_resultExcerpt:string):string => {
|
const processExcerpt = (sub_resultExcerpt: string): string => {
|
||||||
const linkRegex = /TYPE99(\w+.)99TYPE/g;
|
const linkRegex = /TYPE99(\w+.)99TYPE/g;
|
||||||
let excerpt = sub_resultExcerpt;
|
let excerpt = sub_resultExcerpt;
|
||||||
const match = [...excerpt.matchAll(linkRegex)];
|
const match = [...excerpt.matchAll(linkRegex)];
|
||||||
if (match.length > 0){
|
if (match.length > 0) {
|
||||||
for (const matching of match) {
|
for (const matching of match) {
|
||||||
const linkObject = getQMLTypeLinkObject(matching[1]);
|
const linkObject = getQMLTypeLinkObject(matching[1]);
|
||||||
const link = getQMLTypeLink("NOVERSION", linkObject);
|
const link = getQMLTypeLink("NOVERSION", linkObject);
|
||||||
const icon = linkObject.mtype ? getIconForLink(linkObject.mtype, false) : null;
|
const icon = linkObject.mtype
|
||||||
|
? getIconForLink(linkObject.mtype, false)
|
||||||
|
: null;
|
||||||
|
|
||||||
// for signal
|
// for signal
|
||||||
const bracketString = getIconForLink("func", false)
|
const bracketString = getIconForLink("func", false);
|
||||||
|
|
||||||
const newLink = `<span class="type${linkObject.mtype}-link typedata-link">${icon ? icon : ""}<a href=${link}>${linkObject.mname || linkObject.name}</a>${linkObject.mtype === "signal" ? bracketString : ""}</span>`;
|
const newLink = `<span class="type${linkObject.mtype}-link typedata-link">${icon ? icon : ""}<a href=${link}>${linkObject.mname || linkObject.name}</a>${linkObject.mtype === "signal" ? bracketString : ""}</span>`;
|
||||||
excerpt = excerpt.replace(matching[0], newLink)
|
excerpt = excerpt.replace(matching[0], newLink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return excerpt
|
return excerpt;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
const formatURL = (path: string) => path;
|
const formatURL = (path: string) => path;
|
||||||
|
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
window.addEventListener("DOMContentLoaded", () => {
|
||||||
const onIdle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1));
|
const onIdle = window.requestIdleCallback || (cb => setTimeout(cb, 1));
|
||||||
onIdle(async () => {
|
onIdle(async () => {
|
||||||
// @ts-expect-error — Missing types for @pagefind/default-ui package.
|
const { PagefindUI } = await import(
|
||||||
const { PagefindUI } = await import('@pagefind/default-ui');
|
//@ts-expect-error — Missing types for @pagefind/default-ui package.
|
||||||
|
"@pagefind/default-ui"
|
||||||
|
);
|
||||||
new PagefindUI({
|
new PagefindUI({
|
||||||
element: '#qs_search',
|
element: "#qs_search",
|
||||||
baseUrl: import.meta.env.BASE_URL,
|
baseUrl: import.meta.env.BASE_URL,
|
||||||
bundlePath: import.meta.env.BASE_URL.replace(/\/$/, '') + '/pagefind/',
|
bundlePath:
|
||||||
|
import.meta.env.BASE_URL.replace(/\/$/, "") + "/pagefind/",
|
||||||
showImages: false,
|
showImages: false,
|
||||||
showSubResults: true,
|
showSubResults: true,
|
||||||
processResult: (result: { url: string; excerpt:string; sub_results: Array<{ url: string, excerpt:string }> }) => {
|
processResult: (result: {
|
||||||
|
url: string;
|
||||||
|
excerpt: string;
|
||||||
|
meta: {
|
||||||
|
source: string;
|
||||||
|
};
|
||||||
|
extra_class: string;
|
||||||
|
sub_results: Array<{
|
||||||
|
url: string;
|
||||||
|
excerpt: string;
|
||||||
|
}>;
|
||||||
|
}) => {
|
||||||
|
if (result.meta.source === "Qt Framework") {
|
||||||
|
result.extra_class = "qt-result-badge";
|
||||||
|
}
|
||||||
result.url = formatURL(result.url);
|
result.url = formatURL(result.url);
|
||||||
result.excerpt = processExcerpt(result.excerpt)
|
result.excerpt = processExcerpt(result.excerpt);
|
||||||
result.sub_results = result.sub_results.map((sub_result) => {
|
result.sub_results = result.sub_results.map(sub_result => {
|
||||||
sub_result.url = formatURL(sub_result.url);
|
sub_result.url = formatURL(sub_result.url);
|
||||||
sub_result.excerpt = processExcerpt(sub_result.excerpt)
|
sub_result.excerpt = processExcerpt(sub_result.excerpt);
|
||||||
return sub_result;
|
return sub_result;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -146,5 +167,5 @@ import { getQMLTypeLinkObject, getQMLTypeLink, getIconForLink } from '@src/confi
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('site-search', SiteSearch);
|
customElements.define("site-search", SiteSearch);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
---
|
---
|
||||||
import TableOfContents from "./toc";
|
import TableOfContents from "./toc";
|
||||||
import type { ConfigHeading, TypeTOC } from "./types.d.ts";
|
import type { ConfigHeading, TypeTOC } from "./types.d.ts";
|
||||||
import type { TypeData } from "@config/io/types";
|
import type {
|
||||||
|
TypeData,
|
||||||
|
QuickshellFunction,
|
||||||
|
// QuickshellSignal,
|
||||||
|
// QuickshellVariant,
|
||||||
|
// QuickshellProps,
|
||||||
|
} from "@config/_types";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
@ -12,13 +18,16 @@ export interface Props {
|
||||||
|
|
||||||
const { title, headings, type, mobile } = Astro.props;
|
const { title, headings, type, mobile } = Astro.props;
|
||||||
|
|
||||||
const types: TypeTOC | null = type ? {
|
const types: TypeTOC | null = type
|
||||||
|
? {
|
||||||
properties: Object.keys(type.properties ?? {}),
|
properties: Object.keys(type.properties ?? {}),
|
||||||
functions: (type.functions ?? []).map(f => f.name),
|
functions: (type.functions ?? []).map((f: QuickshellFunction) => f.name),
|
||||||
signals: Object.keys(type.signals ?? {}),
|
signals: Object.keys(type.signals ?? {}),
|
||||||
variants: Object.keys(type.variants ?? {}),
|
variants: Object.keys(type.variants ?? {}),
|
||||||
} : null;
|
}
|
||||||
|
: null;
|
||||||
---
|
---
|
||||||
|
|
||||||
{((headings?.length ?? 0) != 0 || types) &&
|
{((headings?.length ?? 0) != 0 || types) &&
|
||||||
<div id="toc" aria-mobile={mobile} class=`toc-wrapper${mobile ? "-mobile":""}`>
|
<div id="toc" aria-mobile={mobile} class=`toc-wrapper${mobile ? "-mobile":""}`>
|
||||||
<TableOfContents
|
<TableOfContents
|
||||||
|
|
@ -28,5 +37,4 @@ const types: TypeTOC | null = type ? {
|
||||||
mobile={mobile}
|
mobile={mobile}
|
||||||
client:idle
|
client:idle
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ interface Props {
|
||||||
|
|
||||||
const { title, link, current, showIcon } = Astro.props;
|
const { title, link, current, showIcon } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<a class=`nav-component nav-item nav-link ${current ? "nav-current" : ""}` href={link}>
|
<a class=`nav-component nav-item nav-link ${current ? "nav-current" : ""}` href={link}>
|
||||||
{ showIcon ? (
|
{ showIcon ? (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ interface Props {
|
||||||
}
|
}
|
||||||
const { title, link, current } = Astro.props;
|
const { title, link, current } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<Accordion class=`nav-component nav-collapsible ${current ? "nav-current" : ""}` {...(current ? { open: "_" } : {})}>
|
<Accordion class=`nav-component nav-collapsible ${current ? "nav-current" : ""}` {...(current ? { open: "_" } : {})}>
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
<a class=`nav-link ${current ? "nav-current" : ""}` href={link}>{title}</a>
|
<a class=`nav-link ${current ? "nav-current" : ""}` href={link}>{title}</a>
|
||||||
|
|
@ -16,5 +17,5 @@ const { title, link, current } = Astro.props;
|
||||||
<Fragment set:html={navMarker}/>
|
<Fragment set:html={navMarker}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<slot>
|
<slot />
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,25 @@ import Link from "./Link.astro";
|
||||||
|
|
||||||
const versions = await getVersionsData();
|
const versions = await getVersionsData();
|
||||||
const versionName = Astro.params.version;
|
const versionName = Astro.params.version;
|
||||||
const modules = versions.versions.find(version => version.name === versionName)?.modules;
|
const modules = versions.versions.find(
|
||||||
|
version => version.name === versionName
|
||||||
|
)?.modules;
|
||||||
|
|
||||||
const currentPath = Astro.url.pathname.split('/').filter(s => s !== "");
|
const currentPath = Astro.url.pathname.split("/").filter(s => s !== "");
|
||||||
|
|
||||||
const guidePages = await getGuideCollection(versionName ?? "");
|
const guidePages = await getGuideCollection(versionName ?? "");
|
||||||
|
|
||||||
interface NavTree {
|
interface NavTree {
|
||||||
title: string,
|
title: string;
|
||||||
slug: string,
|
slug: string;
|
||||||
entries?: NavTree[],
|
entries?: NavTree[];
|
||||||
}
|
}
|
||||||
|
|
||||||
function mkTree(mount: string, pathIdx: number, { title, slug, entries }: NavTree): TreeEntry {
|
function mkTree(
|
||||||
|
mount: string,
|
||||||
|
pathIdx: number,
|
||||||
|
{ title, slug, entries }: NavTree
|
||||||
|
): TreeEntry {
|
||||||
const link = `${mount}/${slug}`;
|
const link = `${mount}/${slug}`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -38,7 +44,9 @@ function mkTree(mount: string, pathIdx: number, { title, slug, entries }: NavTre
|
||||||
|
|
||||||
function genGuideNav(base: string): NavTree[] | undefined {
|
function genGuideNav(base: string): NavTree[] | undefined {
|
||||||
const pages = guidePages
|
const pages = guidePages
|
||||||
.filter(page => page.id.match(`^${base}[^/]*$`) !== null && page.id !== "index")
|
.filter(
|
||||||
|
page => page.id.match(`^${base}[^/]*$`) !== null && page.id !== "index"
|
||||||
|
)
|
||||||
.sort((a, b) => a.data.index - b.data.index)
|
.sort((a, b) => a.data.index - b.data.index)
|
||||||
.map(page => ({
|
.map(page => ({
|
||||||
title: page.data.title,
|
title: page.data.title,
|
||||||
|
|
@ -68,8 +76,8 @@ if (versionName) {
|
||||||
entries: module.types.map(type => ({
|
entries: module.types.map(type => ({
|
||||||
title: type.name,
|
title: type.name,
|
||||||
slug: type.name,
|
slug: type.name,
|
||||||
}))
|
})),
|
||||||
}))
|
})),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -84,6 +92,7 @@ if (versionName) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<nav class="navtree">
|
<nav class="navtree">
|
||||||
<Link
|
<Link
|
||||||
title="About"
|
title="About"
|
||||||
|
|
@ -95,9 +104,9 @@ if (versionName) {
|
||||||
link="/changelog"
|
link="/changelog"
|
||||||
current={currentPath.length === 1 && currentPath[0] === "changelog"}
|
current={currentPath.length === 1 && currentPath[0] === "changelog"}
|
||||||
/>
|
/>
|
||||||
{ versionedEntries && <Tree {...versionsTree as TreeEntry}/>}
|
{versionedEntries && <Tree {...versionsTree as TreeEntry}/>}
|
||||||
<hr/>
|
<hr>
|
||||||
{ versionedEntries && (
|
{versionedEntries && (
|
||||||
<Tree {...versionedEntries.guide}/>
|
<Tree {...versionedEntries.guide}/>
|
||||||
<Tree {...versionedEntries.types}/>
|
<Tree {...versionedEntries.types}/>
|
||||||
<Link
|
<Link
|
||||||
|
|
@ -111,7 +120,7 @@ if (versionName) {
|
||||||
showIcon={true}
|
showIcon={true}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{ !versionedEntries && versions.versions.map(version => (
|
{!versionedEntries && versions.versions.map(version => (
|
||||||
<Link
|
<Link
|
||||||
title={`Quickshell Documentation (${version.name})`}
|
title={`Quickshell Documentation (${version.name})`}
|
||||||
link={`/docs/${version.name}/guide`}
|
link={`/docs/${version.name}/guide`}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ const NavComponent: Component<SidebarContent> = props => {
|
||||||
if (
|
if (
|
||||||
isLink ||
|
isLink ||
|
||||||
!isInBody ||
|
!isInBody ||
|
||||||
|
//@ts-expect-error
|
||||||
(isInBody && !navRef.contains(event.target as Node))
|
(isInBody && !navRef.contains(event.target as Node))
|
||||||
) {
|
) {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ interface Props extends TreeEntry {}
|
||||||
|
|
||||||
const { title, link, entries, current } = Astro.props;
|
const { title, link, entries, current } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<NavCollapsible title={title} link={link} current={current ?? false}>
|
<NavCollapsible title={title} link={link} current={current ?? false}>
|
||||||
{entries?.map(entry => entry.entries ? (
|
{entries?.map(entry => entry.entries ? (
|
||||||
<Self {...entry}/>
|
<Self {...entry}/>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ export interface Props {
|
||||||
|
|
||||||
const { mobile } = Astro.props;
|
const { mobile } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<aside class=`nav-wrapper${mobile ? "-mobile" : ""} id="nav"`>
|
<aside class=`nav-wrapper${mobile ? "-mobile" : ""} id="nav"`>
|
||||||
{ mobile ? (
|
{ mobile ? (
|
||||||
<SidebarWrapper client:load>
|
<SidebarWrapper client:load>
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,12 @@ export const Table: Component<{
|
||||||
if (configTOC) {
|
if (configTOC) {
|
||||||
return (
|
return (
|
||||||
<div class="toc-content">
|
<div class="toc-content">
|
||||||
{title && <>
|
{title && (
|
||||||
|
<>
|
||||||
<p>{title}</p>
|
<p>{title}</p>
|
||||||
<hr/>
|
<hr />
|
||||||
</>}
|
</>
|
||||||
|
)}
|
||||||
<For each={configTOC}>
|
<For each={configTOC}>
|
||||||
{heading => (
|
{heading => (
|
||||||
<Heading
|
<Heading
|
||||||
|
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
import { createSignal, type Component } from "solid-js";
|
|
||||||
|
|
||||||
import { Article } from "@icons";
|
|
||||||
import { Table } from "./Table";
|
|
||||||
import type {
|
|
||||||
TOCProps,
|
|
||||||
TypeTOC,
|
|
||||||
ConfigHeading,
|
|
||||||
} from "../types";
|
|
||||||
import { buildHierarchy } from "@config/io/helpers";
|
|
||||||
|
|
||||||
const TableOfContents: Component<TOCProps> = props => {
|
|
||||||
const [open, setOpen] = createSignal<boolean>(false);
|
|
||||||
const [typeProps] = createSignal<TypeTOC | undefined>(
|
|
||||||
props.type
|
|
||||||
);
|
|
||||||
const [configProps] = createSignal<
|
|
||||||
ConfigHeading[] | undefined
|
|
||||||
>(props.config);
|
|
||||||
|
|
||||||
function toggle(e: MouseEvent) {
|
|
||||||
e.preventDefault();
|
|
||||||
setOpen(!open());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!props.mobile) {
|
|
||||||
return typeProps() ? (
|
|
||||||
<Table typeTOC={typeProps()} />
|
|
||||||
) : (
|
|
||||||
<Table configTOC={buildHierarchy(configProps()!)} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class="menu-toggle">
|
|
||||||
<div onclick={e => toggle(e)}>
|
|
||||||
<Article />
|
|
||||||
</div>
|
|
||||||
<div class={`menu-items ${open() ? "shown" : ""}`}>
|
|
||||||
{typeProps() ? (
|
|
||||||
<Table typeTOC={typeProps()} />
|
|
||||||
) : (
|
|
||||||
<Table
|
|
||||||
configTOC={buildHierarchy(configProps()!)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TableOfContents;
|
|
||||||
|
|
@ -6,7 +6,7 @@ import {
|
||||||
type Component,
|
type Component,
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
|
|
||||||
import { Article } from "@icons";
|
import { Article, MenuToX } from "@icons";
|
||||||
import { Table } from "./Table";
|
import { Table } from "./Table";
|
||||||
import type { TOCProps } from "../types";
|
import type { TOCProps } from "../types";
|
||||||
import { buildHierarchy } from "@config/io/helpers";
|
import { buildHierarchy } from "@config/io/helpers";
|
||||||
|
|
@ -27,7 +27,10 @@ const TableOfContents: Component<TOCProps> = props => {
|
||||||
return type ? (
|
return type ? (
|
||||||
<Table typeTOC={type} />
|
<Table typeTOC={type} />
|
||||||
) : (
|
) : (
|
||||||
<Table title={title} configTOC={buildHierarchy(config!)} />
|
<Table
|
||||||
|
title={title}
|
||||||
|
configTOC={buildHierarchy(config!)}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,6 +40,7 @@ const TableOfContents: Component<TOCProps> = props => {
|
||||||
if (
|
if (
|
||||||
isLink ||
|
isLink ||
|
||||||
!isInBody ||
|
!isInBody ||
|
||||||
|
//@ts-expect-error
|
||||||
(isInBody && !tocRef.contains(event.target as Node))
|
(isInBody && !tocRef.contains(event.target as Node))
|
||||||
) {
|
) {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
|
|
@ -92,13 +96,17 @@ const TableOfContents: Component<TOCProps> = props => {
|
||||||
id="toc-toggle"
|
id="toc-toggle"
|
||||||
>
|
>
|
||||||
<div onclick={e => toggle(e)}>
|
<div onclick={e => toggle(e)}>
|
||||||
<Article />
|
<Article class={`toc-icon ${!open() ? "active" : ""}`} />
|
||||||
|
<MenuToX class={`toc-icon ${open() ? "active" : ""}`} />
|
||||||
</div>
|
</div>
|
||||||
<div class={`toc-mobile ${open() ? "shown" : ""}`}>
|
<div class={`toc-mobile ${open() ? "shown" : ""}`}>
|
||||||
{type ? (
|
{type ? (
|
||||||
<Table typeTOC={type} />
|
<Table typeTOC={type} />
|
||||||
) : (
|
) : (
|
||||||
<Table title={title} configTOC={buildHierarchy(config!)} />
|
<Table
|
||||||
|
title={title}
|
||||||
|
configTOC={buildHierarchy(config!)}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
---
|
---
|
||||||
import type {
|
import type { QMLTypeLinkObject, QuickshellFunction } from "@config/_types";
|
||||||
QMLTypeLinkObject,
|
|
||||||
QuickshellFunction,
|
|
||||||
} from "@config/io/types";
|
|
||||||
import { getQMLTypeLink } from "@config/io/helpers";
|
import { getQMLTypeLink } from "@config/io/helpers";
|
||||||
import { Tag } from "@icons";
|
import { Tag } from "@icons";
|
||||||
import TypeDetails from "./TypeDetails.astro";
|
import TypeDetails from "./TypeDetails.astro";
|
||||||
|
|
@ -15,9 +12,9 @@ export interface Props {
|
||||||
const { funcData } = Astro.props;
|
const { funcData } = Astro.props;
|
||||||
const { version } = Astro.params;
|
const { version } = Astro.params;
|
||||||
---
|
---
|
||||||
|
|
||||||
<ul class="typedata typefuncs">
|
<ul class="typedata typefuncs">
|
||||||
{
|
{funcData.map((item:QuickshellFunction) => {
|
||||||
funcData.map(item => {
|
|
||||||
const functionParams = item.params.length > 0 ? item.params.map((funcparam,index) => `${funcparam.name}${index !== item.params.length -1 ? ", ":""}`) : undefined
|
const functionParams = item.params.length > 0 ? item.params.map((funcparam,index) => `${funcparam.name}${index !== item.params.length -1 ? ", ":""}`) : undefined
|
||||||
const retTypeLink = getQMLTypeLink(version!, item.ret as unknown as QMLTypeLinkObject)
|
const retTypeLink = getQMLTypeLink(version!, item.ret as unknown as QMLTypeLinkObject)
|
||||||
let genericType:string|undefined;
|
let genericType:string|undefined;
|
||||||
|
|
@ -57,6 +54,5 @@ const { version } = Astro.params;
|
||||||
<TypeDetails markdown={item.details} />
|
<TypeDetails markdown={item.details} />
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@ import { getQMLTypeLink } from "@config/io/helpers";
|
||||||
import type {
|
import type {
|
||||||
QMLTypeLinkObject,
|
QMLTypeLinkObject,
|
||||||
QuickshellProps,
|
QuickshellProps,
|
||||||
} from "@config/io/types";
|
QuickshellInstance,
|
||||||
|
} from "@config/_types";
|
||||||
import { Tag } from "@icons";
|
import { Tag } from "@icons";
|
||||||
import TypeTitle from "./TypeTitle.astro";
|
import TypeTitle from "./TypeTitle.astro";
|
||||||
|
|
||||||
|
|
@ -16,13 +17,14 @@ export interface Props {
|
||||||
const { props } = Astro.props;
|
const { props } = Astro.props;
|
||||||
const { version } = Astro.params;
|
const { version } = Astro.params;
|
||||||
---
|
---
|
||||||
|
|
||||||
<ul class="typedata typeprops">
|
<ul class="typedata typeprops">
|
||||||
{
|
{Object.keys(props).map((name) => {
|
||||||
Object.entries(props).map(([name, propData]) => {
|
const propData:QuickshellInstance = props[name];
|
||||||
let typeLink:string;
|
let typeLink: string;
|
||||||
let linkText:string;
|
let linkText: string;
|
||||||
let genericType:string|undefined;
|
let genericType: string|undefined;
|
||||||
let genericTypeLink:string|undefined;
|
let genericTypeLink: string|undefined;
|
||||||
const gadget = propData.type.gadget;
|
const gadget = propData.type.gadget;
|
||||||
if (gadget) {
|
if (gadget) {
|
||||||
typeLink = "#"
|
typeLink = "#"
|
||||||
|
|
@ -39,7 +41,7 @@ const { version } = Astro.params;
|
||||||
<li id={ name } class="typedata-root typeprop-root">
|
<li id={ name } class="typedata-root typeprop-root">
|
||||||
<TypeTitle
|
<TypeTitle
|
||||||
typekind="prop"
|
typekind="prop"
|
||||||
typename={name}
|
typename={ name }
|
||||||
typelink={typeLink}
|
typelink={typeLink}
|
||||||
typelink_text={linkText}
|
typelink_text={linkText}
|
||||||
typename_generic={genericType}
|
typename_generic={genericType}
|
||||||
|
|
@ -66,6 +68,5 @@ const { version } = Astro.params;
|
||||||
<TypeDetails markdown={propData.details} />
|
<TypeDetails markdown={propData.details} />
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
import { getQMLTypeLink } from "@config/io/helpers";
|
import { getQMLTypeLink } from "@config/io/helpers";
|
||||||
import type { QuickshellSignal } from "@config/io/types";
|
import type { QuickshellSignal } from "@config/_types";
|
||||||
import { Tag } from "@icons";
|
import { Tag } from "@icons";
|
||||||
import TypeDetails from "./TypeDetails.astro";
|
import TypeDetails from "./TypeDetails.astro";
|
||||||
import TypeTitle from "./TypeTitle.astro";
|
import TypeTitle from "./TypeTitle.astro";
|
||||||
|
|
@ -12,17 +12,25 @@ export interface Props {
|
||||||
const { signals } = Astro.props;
|
const { signals } = Astro.props;
|
||||||
const { version } = Astro.params;
|
const { version } = Astro.params;
|
||||||
---
|
---
|
||||||
|
|
||||||
<ul class="typedata typesignals">
|
<ul class="typedata typesignals">
|
||||||
{
|
{(Object.entries(signals) as [
|
||||||
Object.entries(signals).map(([name, signalData]) => {
|
keyof QuickshellSignal,
|
||||||
const paramKeys = signalData.params.length > 0 ? signalData.params.map((param,index) => `${param.name}${index !== signalData.params.length -1 ? ", ":""}`) : []
|
QuickshellSignal[keyof QuickshellSignal],
|
||||||
|
][]).map(([name, signalData]) => {
|
||||||
|
const paramKeys = signalData.params.length > 0
|
||||||
|
? signalData.params.map((param,index) => `${param.name}${
|
||||||
|
index !== signalData.params.length -1
|
||||||
|
? ", "
|
||||||
|
:""
|
||||||
|
}`): []
|
||||||
let genericType:string|undefined;
|
let genericType:string|undefined;
|
||||||
let genericTypeLink:string|undefined;
|
let genericTypeLink:string|undefined;
|
||||||
return (
|
return (
|
||||||
<li id={ name } class="typedata-root typesignal-root">
|
<li id={ name.toString() } class="typedata-root typesignal-root">
|
||||||
<TypeTitle
|
<TypeTitle
|
||||||
typekind="signal"
|
typekind="signal"
|
||||||
typename={name}
|
typename={ name.toString() }
|
||||||
typelink="/docs/configuration/qml-overview#-signals"
|
typelink="/docs/configuration/qml-overview#-signals"
|
||||||
typelink_text=""
|
typelink_text=""
|
||||||
typename_generic={genericType}
|
typename_generic={genericType}
|
||||||
|
|
@ -50,6 +58,5 @@ const { version } = Astro.params;
|
||||||
<TypeDetails markdown={signalData.details} />
|
<TypeDetails markdown={signalData.details} />
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ const { version } = Astro.params;
|
||||||
|
|
||||||
const html = markdown ? await processMarkdown(version!, markdown) : null;
|
const html = markdown ? await processMarkdown(version!, markdown) : null;
|
||||||
---
|
---
|
||||||
|
|
||||||
<section class="typedata-details">
|
<section class="typedata-details">
|
||||||
{html ? <div class="typedata-detailsdata" set:html={html} /> : <em>No details provided</em>}
|
{html ? <div class="typedata-detailsdata" set:html={html} /> : <em>No details provided</em>}
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,17 @@ const iconSelector: { [key: string]: string } = {
|
||||||
variant: "fourdiamonds",
|
variant: "fourdiamonds",
|
||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class={`typedata-title type${typekind}-title`}>
|
<div class={`typedata-title type${typekind}-title`}>
|
||||||
<section class={`typedata-name type${typekind}-name`}>
|
<section class={`typedata-name type${typekind}-name`}>
|
||||||
{typekind !== "func" && <Icon name={iconSelector[typekind]}/>}
|
{typekind !== "func" && <Icon name={iconSelector[typekind]}/>}
|
||||||
<span>{ typename }{ (typekind === "func" || typekind === "signal") ?
|
<span
|
||||||
|
>{typename}
|
||||||
|
{(typekind === "func" || typekind === "signal") ?
|
||||||
(<span>(</span><span class="typedata-param">{typedata_params}</span><span>)</span>)
|
(<span>(</span><span class="typedata-param">{typedata_params}</span><span>)</span>)
|
||||||
:""}
|
:""}
|
||||||
</span>
|
</span>
|
||||||
{ typekind !== "variant" &&
|
{typekind !== "variant" &&
|
||||||
<span class=`type-datatype ${typekind === "signal" && "typesignal-doclink"}`>{typekind !== "signal" &&":"}
|
<span class=`type-datatype ${typekind === "signal" && "typesignal-doclink"}`>{typekind !== "signal" &&":"}
|
||||||
<a href={typelink}>{ typelink_text }</a>
|
<a href={typelink}>{ typelink_text }</a>
|
||||||
{typename_generic &&
|
{typename_generic &&
|
||||||
|
|
@ -46,12 +49,11 @@ const iconSelector: { [key: string]: string } = {
|
||||||
<span class="type-generic"><span class="type-datatype"><</span><a href={typelink_generic}>{typename_generic}</a><span class="type-datatype">></span></span>
|
<span class="type-generic"><span class="type-datatype"><</span><a href={typelink_generic}>{typename_generic}</a><span class="type-datatype">></span></span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</span>
|
</span>}
|
||||||
}
|
|
||||||
</section>
|
</section>
|
||||||
<section class="type-badges">
|
<section class="type-badges">
|
||||||
{badges && badges.length > 0 ? (
|
{badges && badges.length > 0 ? (
|
||||||
badges.map(badgeText => <Badge badgeText={badgeText}/>)
|
badges.map((badgeText:string) => <Badge badgeText={badgeText}/>)
|
||||||
) : null}
|
) : null}
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
import type { QuickshellVariant } from "@config/io/types";
|
import type { QuickshellVariant } from "@config/_types";
|
||||||
import TypeDetails from "./TypeDetails.astro";
|
import TypeDetails from "./TypeDetails.astro";
|
||||||
import TypeTitle from "./TypeTitle.astro";
|
import TypeTitle from "./TypeTitle.astro";
|
||||||
|
|
||||||
|
|
@ -9,17 +9,20 @@ export interface Props {
|
||||||
|
|
||||||
const { variants } = Astro.props;
|
const { variants } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<ul class="typedata typevariants">
|
<ul class="typedata typevariants">
|
||||||
{
|
{(Object.entries(variants) as [
|
||||||
Object.entries(variants).map(([name, variantData]) => {
|
keyof QuickshellVariant,
|
||||||
|
QuickshellVariant[keyof QuickshellVariant],
|
||||||
|
][]).map(([name, variantData]) => {
|
||||||
const paramKeys = variantData.params && variantData.params.length > 0
|
const paramKeys = variantData.params && variantData.params.length > 0
|
||||||
? variantData.params.map(param => param.name)
|
? variantData.params.map(param => param.name)
|
||||||
: [];
|
: [];
|
||||||
return (
|
return (
|
||||||
<li id={ name } class="typedata-root typevariant-root">
|
<li id={ name.toString() } class="typedata-root typevariant-root">
|
||||||
<TypeTitle
|
<TypeTitle
|
||||||
typekind="variant"
|
typekind="variant"
|
||||||
typename={name}
|
typename={ name.toString() }
|
||||||
typelink=""
|
typelink=""
|
||||||
typelink_text=""
|
typelink_text=""
|
||||||
/>
|
/>
|
||||||
|
|
@ -36,7 +39,5 @@ const { variants } = Astro.props;
|
||||||
<TypeDetails markdown={variantData.details} />
|
<TypeDetails markdown={variantData.details} />
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,30 +12,48 @@ interface Props {
|
||||||
const { title, description } = Astro.props;
|
const { title, description } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="generator" content={Astro.generator} />
|
<meta name="generator" content={Astro.generator}>
|
||||||
<link rel="canonical" href={Astro.url} />
|
<link rel="canonical" href={Astro.url}>
|
||||||
<link rel="sitemap" href="/sitemap-index.xml" />
|
<link rel="sitemap" href="/sitemap-index.xml">
|
||||||
|
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
<meta name="description" content={description} />
|
<meta name="description" content={description}>
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||||
|
|
||||||
|
<script is:inline>
|
||||||
|
const theme = (() => {
|
||||||
|
if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) {
|
||||||
|
return localStorage.getItem("theme");
|
||||||
|
}
|
||||||
|
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||||
|
return "dark";
|
||||||
|
}
|
||||||
|
return "light";
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (theme === "dark") {
|
||||||
|
document.documentElement.classList.add("dark");
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove("dark");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<!-- Open Graph Meta Tags -->
|
<!-- Open Graph Meta Tags -->
|
||||||
<meta name="og:type" content="website" />
|
<meta name="og:type" content="website">
|
||||||
<meta name="og:site_name" content="quickshell" />
|
<meta name="og:site_name" content="quickshell">
|
||||||
<meta name="og:url" content={Astro.url} />
|
<meta name="og:url" content={Astro.url}>
|
||||||
<meta name="og:title" content={title} />
|
<meta name="og:title" content={title}>
|
||||||
<meta name="og:description" content={description} />
|
<meta name="og:description" content={description}>
|
||||||
<!-- <meta name="og:image" content={image} /> -->
|
<!-- <meta name="og:image" content={image} /> -->
|
||||||
|
|
||||||
<!-- Twitter Meta Tags -->
|
<!-- Twitter Meta Tags -->
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
<meta name="twitter:domain" content="quickshell.outfoxxed.me" />
|
<meta name="twitter:domain" content="quickshell.outfoxxed.me">
|
||||||
<meta name="twitter:url" content={Astro.url} />
|
<meta name="twitter:url" content={Astro.url}>
|
||||||
<meta name="twitter:title" content={title} />
|
<meta name="twitter:title" content={title}>
|
||||||
<meta name="twitter:description" content={description} />
|
<meta name="twitter:description" content={description}>
|
||||||
<!-- <meta name="twitter:image" content={image} /> -->
|
<!-- <meta name="twitter:image" content={image} /> -->
|
||||||
|
|
||||||
<Analytics/>
|
<Analytics />
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
function updateTheme() {
|
|
||||||
if (
|
|
||||||
localStorage.theme === "dark" ||
|
|
||||||
(!("theme" in localStorage) &&
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").matches)
|
|
||||||
) {
|
|
||||||
document.documentElement.classList.add("dark");
|
|
||||||
} else {
|
|
||||||
document.documentElement.classList.remove("dark");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run on initial load
|
|
||||||
updateTheme();
|
|
||||||
|
|
||||||
// Run on view transitions
|
|
||||||
document.addEventListener("astro:after-swap", updateTheme);
|
|
||||||
</script>
|
|
||||||
9
src/config/_types/codeblock.ts
Normal file
9
src/config/_types/codeblock.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
interface CopyButtonOptions {
|
||||||
|
duration?: number;
|
||||||
|
copyIcon?: string;
|
||||||
|
successIcon?: string;
|
||||||
|
display?: "hover" | "ready";
|
||||||
|
cssVariables?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { CopyButtonOptions };
|
||||||
9
src/config/_types/helper.ts
Normal file
9
src/config/_types/helper.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
interface QMLTypeLinkObject {
|
||||||
|
type: string;
|
||||||
|
module?: string;
|
||||||
|
name?: string;
|
||||||
|
mtype?: string;
|
||||||
|
mname?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { QMLTypeLinkObject };
|
||||||
33
src/config/_types/index.ts
Normal file
33
src/config/_types/index.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
import type { QMLTypeLinkObject } from "./helper";
|
||||||
|
import type {
|
||||||
|
ModuleData,
|
||||||
|
QuickshellBase,
|
||||||
|
QuickshellFunction,
|
||||||
|
QuickshellGadget,
|
||||||
|
QuickshellInstance,
|
||||||
|
QuickshellProps,
|
||||||
|
QuickshellSignal,
|
||||||
|
QuickshellVariant,
|
||||||
|
TypeData,
|
||||||
|
VersionData,
|
||||||
|
VersionsData,
|
||||||
|
} from "./module";
|
||||||
|
import type { SearchLists } from "./search";
|
||||||
|
import type { CopyButtonOptions } from "./codeblock";
|
||||||
|
|
||||||
|
export type {
|
||||||
|
QMLTypeLinkObject,
|
||||||
|
QuickshellBase,
|
||||||
|
QuickshellInstance,
|
||||||
|
QuickshellGadget,
|
||||||
|
QuickshellProps,
|
||||||
|
QuickshellFunction,
|
||||||
|
QuickshellSignal,
|
||||||
|
QuickshellVariant,
|
||||||
|
TypeData,
|
||||||
|
ModuleData,
|
||||||
|
VersionData,
|
||||||
|
VersionsData,
|
||||||
|
SearchLists,
|
||||||
|
CopyButtonOptions,
|
||||||
|
};
|
||||||
|
|
@ -1,15 +1,3 @@
|
||||||
//#FIXME fuseConfig.ts
|
|
||||||
// --
|
|
||||||
|
|
||||||
// generateSearchLists.ts
|
|
||||||
interface SearchLists {
|
|
||||||
slug: string;
|
|
||||||
link: string;
|
|
||||||
summary: string;
|
|
||||||
}
|
|
||||||
// --
|
|
||||||
|
|
||||||
// generateTypeData.ts
|
|
||||||
interface QuickshellBase {
|
interface QuickshellBase {
|
||||||
type: string;
|
type: string;
|
||||||
module: string;
|
module: string;
|
||||||
|
|
@ -53,7 +41,7 @@ interface QuickshellSignal {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QuickshellVariant {
|
interface QuickshellVariant {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
name?: string;
|
name?: string;
|
||||||
details: string;
|
details: string;
|
||||||
|
|
@ -61,7 +49,7 @@ export interface QuickshellVariant {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TypeData {
|
interface TypeData {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
details: string;
|
details: string;
|
||||||
|
|
@ -72,37 +60,27 @@ export interface TypeData {
|
||||||
functions?: QuickshellFunction[];
|
functions?: QuickshellFunction[];
|
||||||
signals?: QuickshellSignal;
|
signals?: QuickshellSignal;
|
||||||
variants?: QuickshellVariant;
|
variants?: QuickshellVariant;
|
||||||
subtypes?: QuickshellData[];
|
// FIXME: QuickshellData[]
|
||||||
|
subtypes?: any[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ModuleData {
|
interface ModuleData {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
details: string;
|
details: string;
|
||||||
types: TypeData[];
|
types: TypeData[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VersionData {
|
interface VersionData {
|
||||||
name: string;
|
name: string;
|
||||||
changelog?: string;
|
changelog?: string;
|
||||||
modules: ModuleData[];
|
modules: ModuleData[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VersionsData {
|
interface VersionsData {
|
||||||
default: string;
|
default: string;
|
||||||
versions: VersionData[];
|
versions: VersionData[];
|
||||||
}
|
}
|
||||||
// --
|
|
||||||
|
|
||||||
// helpers.ts
|
|
||||||
interface QMLTypeLinkObject {
|
|
||||||
type: string;
|
|
||||||
module?: string;
|
|
||||||
name?: string;
|
|
||||||
mtype?: string;
|
|
||||||
mname?: string;
|
|
||||||
}
|
|
||||||
// --
|
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
QuickshellBase,
|
QuickshellBase,
|
||||||
|
|
@ -116,5 +94,4 @@ export type {
|
||||||
ModuleData,
|
ModuleData,
|
||||||
VersionData,
|
VersionData,
|
||||||
VersionsData,
|
VersionsData,
|
||||||
QMLTypeLinkObject,
|
|
||||||
};
|
};
|
||||||
7
src/config/_types/search.ts
Normal file
7
src/config/_types/search.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
interface SearchLists {
|
||||||
|
slug: string;
|
||||||
|
link: string;
|
||||||
|
summary: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { SearchLists };
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
import { promises as fs } from "node:fs";
|
import { promises as fs } from "node:fs";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
||||||
import type { VersionsData, ModuleData } from "./types";
|
import type { VersionsData, ModuleData } from "@_types";
|
||||||
|
|
||||||
async function readModulesData(basePath: string): Promise<ModuleData[]> {
|
async function readModulesData(
|
||||||
|
basePath: string
|
||||||
|
): Promise<ModuleData[]> {
|
||||||
const moduleDirs = await fs.readdir(basePath);
|
const moduleDirs = await fs.readdir(basePath);
|
||||||
|
|
||||||
const modules = await Promise.all(moduleDirs.map(async moduleDir => {
|
const modules = await Promise.all(
|
||||||
|
moduleDirs.map(async moduleDir => {
|
||||||
const modulePath = path.join(basePath, moduleDir);
|
const modulePath = path.join(basePath, moduleDir);
|
||||||
|
|
||||||
const indexPromise = async () => {
|
const indexPromise = async () => {
|
||||||
|
|
@ -15,22 +18,28 @@ async function readModulesData(basePath: string): Promise<ModuleData[]> {
|
||||||
return JSON.parse(indexContent);
|
return JSON.parse(indexContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
const typeNames = (await fs.readdir(modulePath)).filter(name => name !== "index.json");
|
const typeNames = (await fs.readdir(modulePath)).filter(
|
||||||
|
name => name !== "index.json"
|
||||||
|
);
|
||||||
const typePromises = typeNames.map(async fileName => {
|
const typePromises = typeNames.map(async fileName => {
|
||||||
const typePath = path.join(modulePath, fileName);
|
const typePath = path.join(modulePath, fileName);
|
||||||
const fileContent = await fs.readFile(typePath, "utf8");
|
const fileContent = await fs.readFile(typePath, "utf8");
|
||||||
return JSON.parse(fileContent);
|
return JSON.parse(fileContent);
|
||||||
});
|
});
|
||||||
|
|
||||||
const [index, ...types] = await Promise.all([indexPromise(), ...typePromises]);
|
const [index, ...types] = await Promise.all([
|
||||||
|
indexPromise(),
|
||||||
|
...typePromises,
|
||||||
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: index.name,
|
name: index.name,
|
||||||
description: index.description,
|
description: index.description,
|
||||||
details: index.details,
|
details: index.details,
|
||||||
types,
|
types,
|
||||||
}
|
};
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
return modules;
|
return modules;
|
||||||
}
|
}
|
||||||
|
|
@ -44,19 +53,31 @@ async function readVersionsData(): Promise<VersionsData> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const resolvedPath = path.join(process.cwd(), versionsPath);
|
||||||
|
console.log(resolvedPath);
|
||||||
const content = await fs.readFile(versionsPath, "utf8");
|
const content = await fs.readFile(versionsPath, "utf8");
|
||||||
const data = JSON.parse(content);
|
const data = JSON.parse(content);
|
||||||
|
|
||||||
const versions = await Promise.all(data.versions.map(async (d: { name: string, changelog?: string, types: any }) => ({
|
const versions = await Promise.all(
|
||||||
|
data.versions.map(
|
||||||
|
async (d: {
|
||||||
|
name: string;
|
||||||
|
changelog?: string;
|
||||||
|
types: any;
|
||||||
|
}) => ({
|
||||||
name: d.name,
|
name: d.name,
|
||||||
changelog: d.changelog ? await fs.readFile(d.changelog, "utf8") : undefined,
|
changelog: d.changelog
|
||||||
|
? await fs.readFile(d.changelog, "utf8")
|
||||||
|
: undefined,
|
||||||
modules: await readModulesData(d.types),
|
modules: await readModulesData(d.types),
|
||||||
})));
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
versions,
|
versions,
|
||||||
default: data.default,
|
default: data.default,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let globalVersionsData: Promise<VersionsData>;
|
let globalVersionsData: Promise<VersionsData>;
|
||||||
|
|
@ -71,5 +92,6 @@ export function getVersionsData(): Promise<VersionsData> {
|
||||||
|
|
||||||
export async function getModulesData(): Promise<ModuleData[]> {
|
export async function getModulesData(): Promise<ModuleData[]> {
|
||||||
const versions = await getVersionsData();
|
const versions = await getVersionsData();
|
||||||
return versions.versions.find(v => v.name === versions.default)!.modules;
|
return versions.versions.find(v => v.name === versions.default)!
|
||||||
|
.modules;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,22 @@
|
||||||
import { type CollectionEntry, getCollection } from "astro:content";
|
import {
|
||||||
|
type CollectionEntry,
|
||||||
|
getCollection,
|
||||||
|
} from "astro:content";
|
||||||
import { getVersionsData } from "@config/io/generateTypeData";
|
import { getVersionsData } from "@config/io/generateTypeData";
|
||||||
|
|
||||||
// load latest version of each page for version
|
// load latest version of each page for version
|
||||||
async function buildGuideCollection(version: string): Promise<CollectionEntry<'guide'>[]> {
|
async function buildGuideCollection(
|
||||||
|
version: string
|
||||||
|
): Promise<CollectionEntry<"guide">[]> {
|
||||||
const { versions } = await getVersionsData();
|
const { versions } = await getVersionsData();
|
||||||
const guidePages = await getCollection("guide");
|
const guidePages = await getCollection("guide");
|
||||||
|
|
||||||
const pages: { [key: string]: CollectionEntry<'guide'> } = {};
|
const pages: { [key: string]: CollectionEntry<"guide"> } = {};
|
||||||
|
|
||||||
for (const currentVersion of versions.toReversed()) {
|
for (const currentVersion of versions.toReversed()) {
|
||||||
for (const page of guidePages) {
|
for (const page of guidePages) {
|
||||||
let [guideVersion, id] = page.id.split('/');
|
let [guideVersion, id] = page.id.split("/");
|
||||||
guideVersion = guideVersion.replaceAll('_', '.');
|
guideVersion = guideVersion.replaceAll("_", ".");
|
||||||
id = id ?? "index";
|
id = id ?? "index";
|
||||||
if (guideVersion !== currentVersion.name) continue;
|
if (guideVersion !== currentVersion.name) continue;
|
||||||
|
|
||||||
|
|
@ -24,12 +29,18 @@ async function buildGuideCollection(version: string): Promise<CollectionEntry<'g
|
||||||
return Object.values(pages);
|
return Object.values(pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
let guideCollections: { [key: string]: Promise<CollectionEntry<'guide'>[]> } = {};
|
let guideCollections: {
|
||||||
|
[key: string]: Promise<CollectionEntry<"guide">[]>;
|
||||||
|
} = {};
|
||||||
|
|
||||||
export async function getGuideCollection(version: string): Promise<CollectionEntry<'guide'>[]> {
|
async function getGuideCollection(
|
||||||
|
version: string
|
||||||
|
): Promise<CollectionEntry<"guide">[]> {
|
||||||
if (!(version in guideCollections)) {
|
if (!(version in guideCollections)) {
|
||||||
guideCollections[version] = buildGuideCollection(version);
|
guideCollections[version] = buildGuideCollection(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
return guideCollections[version];
|
return guideCollections[version];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export { getGuideCollection };
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import type {
|
||||||
ConfigHeading,
|
ConfigHeading,
|
||||||
ConfigTOC,
|
ConfigTOC,
|
||||||
} from "@components/navigation/sidebars/types";
|
} from "@components/navigation/sidebars/types";
|
||||||
import type { QMLTypeLinkObject } from "./types";
|
import type { QMLTypeLinkObject } from "@_types";
|
||||||
|
|
||||||
export function buildHierarchy(headings: ConfigHeading[]) {
|
export function buildHierarchy(headings: ConfigHeading[]) {
|
||||||
const toc: ConfigTOC[] = [];
|
const toc: ConfigTOC[] = [];
|
||||||
|
|
@ -30,7 +30,7 @@ export function buildHierarchy(headings: ConfigHeading[]) {
|
||||||
let depth = heading.depth - 1;
|
let depth = heading.depth - 1;
|
||||||
let parent = null;
|
let parent = null;
|
||||||
|
|
||||||
while (!parent && depth != 0) {
|
while (!parent && depth !== 0) {
|
||||||
parent = parentHeadings.get(depth);
|
parent = parentHeadings.get(depth);
|
||||||
depth -= 1;
|
depth -= 1;
|
||||||
}
|
}
|
||||||
|
|
@ -96,13 +96,10 @@ export function getQMLTypeLinkObject(unparsed: string) {
|
||||||
return hashMap[index]();
|
return hashMap[index]();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getQMLTypeLink(version: string, {
|
export function getQMLTypeLink(
|
||||||
type,
|
version: string,
|
||||||
module,
|
{ type, module, name, mtype, mname }: QMLTypeLinkObject
|
||||||
name,
|
) {
|
||||||
mtype,
|
|
||||||
mname,
|
|
||||||
}: QMLTypeLinkObject) {
|
|
||||||
if (type === "unknown") {
|
if (type === "unknown") {
|
||||||
return "#unknown";
|
return "#unknown";
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +113,9 @@ export function getQMLTypeLink(version: string, {
|
||||||
return localLink;
|
return localLink;
|
||||||
},
|
},
|
||||||
qt: () => {
|
qt: () => {
|
||||||
const isSpecific = mname ? `#${mname}-${mtype === "func" ? "method" : mtype}` : "";
|
const isSpecific = mname
|
||||||
|
? `#${mname}-${mtype === "func" ? "method" : mtype}`
|
||||||
|
: "";
|
||||||
const qtLink = `${qtStart}${module!.toLowerCase().replace(".", "-")}-${name!.toLowerCase()}.html${isSpecific}`;
|
const qtLink = `${qtStart}${module!.toLowerCase().replace(".", "-")}-${name!.toLowerCase()}.html${isSpecific}`;
|
||||||
return qtLink;
|
return qtLink;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,20 @@ import { remarkAlert } from "remark-github-blockquote-alert";
|
||||||
import rehypeShiki from "@shikijs/rehype";
|
import rehypeShiki from "@shikijs/rehype";
|
||||||
import sectionize from "@hbsnow/rehype-sectionize";
|
import sectionize from "@hbsnow/rehype-sectionize";
|
||||||
import type { ShikiTransformer } from "shiki";
|
import type { ShikiTransformer } from "shiki";
|
||||||
|
import { h } from "hastscript";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getQMLTypeLinkObject,
|
getQMLTypeLinkObject,
|
||||||
getQMLTypeLink,
|
getQMLTypeLink,
|
||||||
getIconForLink,
|
getIconForLink,
|
||||||
} from "./helpers.ts";
|
} from "./helpers.ts";
|
||||||
|
import type { CopyButtonOptions } from "@_types";
|
||||||
|
|
||||||
let currentVersion = "NOVERSION";
|
let currentVersion = "NOVERSION";
|
||||||
|
|
||||||
const remarkParseAtTypes: RemarkPlugin<[]> = () => (root: Md.Root): Md.Root => {
|
const remarkParseAtTypes: RemarkPlugin<[]> =
|
||||||
|
() =>
|
||||||
|
(root: Md.Root): Md.Root => {
|
||||||
visit(root as Unist.Parent, (rawNode: Unist.Node) => {
|
visit(root as Unist.Parent, (rawNode: Unist.Node) => {
|
||||||
if (
|
if (
|
||||||
rawNode.type === "text" ||
|
rawNode.type === "text" ||
|
||||||
|
|
@ -31,7 +35,6 @@ const remarkParseAtTypes: RemarkPlugin<[]> = () => (root: Md.Root): Md.Root => {
|
||||||
(rawNode as Md.Code).lang === "qml")
|
(rawNode as Md.Code).lang === "qml")
|
||||||
) {
|
) {
|
||||||
const node = rawNode as Md.Literal;
|
const node = rawNode as Md.Literal;
|
||||||
|
|
||||||
node.value = node.value.replace(
|
node.value = node.value.replace(
|
||||||
/@@(?<path>([A-Z]\w*\.)*([A-Z]\w*))?((?<member>[a-z]\w*)((?<function>\(\))|(?<signal>\(s\)))?)?(?=[$.,;:)\s]|$)/g,
|
/@@(?<path>([A-Z]\w*\.)*([A-Z]\w*))?((?<member>[a-z]\w*)((?<function>\(\))|(?<signal>\(s\)))?)?(?=[$.,;:)\s]|$)/g,
|
||||||
(_full, ...args) => {
|
(_full, ...args) => {
|
||||||
|
|
@ -43,9 +46,11 @@ const remarkParseAtTypes: RemarkPlugin<[]> = () => (root: Md.Root): Md.Root => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const groups = args.pop() as Capture;
|
const groups = args.pop() as Capture;
|
||||||
const pathp = (groups.path ?? "").split('.').filter(Boolean);
|
const pathp = (groups.path ?? "")
|
||||||
let type = (pathp.length >= 1 ? pathp.pop() : "");
|
.split(".")
|
||||||
let module = pathp.join('_');
|
.filter(Boolean);
|
||||||
|
let type = pathp.length >= 1 ? pathp.pop() : "";
|
||||||
|
let module = pathp.join("_");
|
||||||
|
|
||||||
if (module) {
|
if (module) {
|
||||||
const isQs = module.startsWith("Quickshell");
|
const isQs = module.startsWith("Quickshell");
|
||||||
|
|
@ -65,9 +70,11 @@ const remarkParseAtTypes: RemarkPlugin<[]> = () => (root: Md.Root): Md.Root => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return root;
|
return root;
|
||||||
};
|
};
|
||||||
|
|
||||||
const rehypeRewriteTypelinks: RehypePlugin<[]> = () => (root: Html.Root): Html.Root => {
|
const rehypeRewriteTypelinks: RehypePlugin<[]> =
|
||||||
|
() =>
|
||||||
|
(root: Html.Root): Html.Root => {
|
||||||
visit(
|
visit(
|
||||||
root as Unist.Parent,
|
root as Unist.Parent,
|
||||||
"text",
|
"text",
|
||||||
|
|
@ -80,7 +87,10 @@ const rehypeRewriteTypelinks: RehypePlugin<[]> = () => (root: Html.Root): Html.R
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
const linkObject = getQMLTypeLinkObject(match);
|
const linkObject = getQMLTypeLinkObject(match);
|
||||||
const link = getQMLTypeLink(currentVersion, linkObject);
|
const link = getQMLTypeLink(
|
||||||
|
currentVersion,
|
||||||
|
linkObject
|
||||||
|
);
|
||||||
const icon =
|
const icon =
|
||||||
linkObject.mtype && linkObject.mtype !== "func"
|
linkObject.mtype && linkObject.mtype !== "func"
|
||||||
? getIconForLink(linkObject.mtype, false)
|
? getIconForLink(linkObject.mtype, false)
|
||||||
|
|
@ -101,28 +111,30 @@ const rehypeRewriteTypelinks: RehypePlugin<[]> = () => (root: Html.Root): Html.R
|
||||||
parent.children.splice(index, 1, ...fragment.children);
|
parent.children.splice(index, 1, ...fragment.children);
|
||||||
return SKIP;
|
return SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CONTINUE;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
};
|
};
|
||||||
|
|
||||||
const rehypeRewriteVersionedDoclinks: RehypePlugin<[]> = () => (root: Html.Root): Html.Root => {
|
const rehypeRewriteVersionedDoclinks: RehypePlugin<[]> =
|
||||||
|
() =>
|
||||||
|
(root: Html.Root): Html.Root => {
|
||||||
visit(
|
visit(
|
||||||
root as Unist.Parent,
|
root as Unist.Parent,
|
||||||
"element",
|
"element",
|
||||||
({ tagName, properties }: Html.Element) => {
|
({ tagName, properties }: Html.Element) => {
|
||||||
if (tagName !== "a") return CONTINUE;
|
if (tagName !== "a") return CONTINUE;
|
||||||
if (!(properties.href as string ?? "").startsWith("@docs")) return CONTINUE;
|
if (
|
||||||
|
!((properties.href as string) ?? "").startsWith("@docs")
|
||||||
|
)
|
||||||
|
return CONTINUE;
|
||||||
properties.href = `/docs/${currentVersion}/${(properties.href as string).slice(6)}`;
|
properties.href = `/docs/${currentVersion}/${(properties.href as string).slice(6)}`;
|
||||||
return CONTINUE;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
};
|
};
|
||||||
|
|
||||||
const shikiRewriteTypelinks: ShikiTransformer = {
|
const shikiRewriteTypelinks: ShikiTransformer = {
|
||||||
name: "rewrite-typelinks",
|
name: "rewrite-typelinks",
|
||||||
|
|
@ -141,7 +153,69 @@ const shikiRewriteTypelinks: ShikiTransformer = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const markdownConfig: AstroMarkdownOptions = {
|
const shikiCopyButton: ShikiTransformer = {
|
||||||
|
name: "copy-button",
|
||||||
|
pre(node) {
|
||||||
|
const options: CopyButtonOptions = {
|
||||||
|
duration: 3000,
|
||||||
|
};
|
||||||
|
const button = h(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
class: "copy-button",
|
||||||
|
role: "button",
|
||||||
|
"aria-label": "Copy to clipboard",
|
||||||
|
"alia-live": "polite",
|
||||||
|
"data-code": this.source,
|
||||||
|
onclick: `
|
||||||
|
navigator.clipboard.writeText(this.dataset.code);
|
||||||
|
this.classList.add('copied');
|
||||||
|
this.setAttribute('aria-pressed', 'true');
|
||||||
|
setTimeout(() => { this.classList.remove('copied'); this.setAttribute('aria-pressed', 'false');}, ${options.duration})
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
[
|
||||||
|
h(
|
||||||
|
"svg",
|
||||||
|
{
|
||||||
|
class: "copy-icon",
|
||||||
|
role: "icon",
|
||||||
|
xmlns: "http://www.w3.org/2000/svg",
|
||||||
|
width: "1em",
|
||||||
|
height: "1em",
|
||||||
|
viewBox: "0 0 256 256",
|
||||||
|
},
|
||||||
|
[
|
||||||
|
h("path", {
|
||||||
|
fill: "currentColor",
|
||||||
|
d: "M200 32h-36.26a47.92 47.92 0 0 0-71.48 0H56a16 16 0 0 0-16 16v168a16 16 0 0 0 16 16h144a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16m-72 0a32 32 0 0 1 32 32H96a32 32 0 0 1 32-32m72 184H56V48h26.75A47.9 47.9 0 0 0 80 64v8a8 8 0 0 0 8 8h80a8 8 0 0 0 8-8v-8a47.9 47.9 0 0 0-2.75-16H200Z",
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
"svg",
|
||||||
|
{
|
||||||
|
class: "check-icon",
|
||||||
|
role: "icon",
|
||||||
|
xmlns: "http://www.w3.org/2000/svg",
|
||||||
|
width: "1em",
|
||||||
|
height: "1em",
|
||||||
|
viewBox: "0 0 256 256",
|
||||||
|
},
|
||||||
|
[
|
||||||
|
h("path", {
|
||||||
|
fill: "currentColor",
|
||||||
|
d: "M229.66 77.66l-128 128a8 8 0 0 1-11.32 0l-56-56a8 8 0 0 1 11.32-11.32L96 188.69L218.34 66.34a8 8 0 0 1 11.32 11.32Z",
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
node.children.splice(0, 0, button);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const markdownConfig: AstroMarkdownOptions = {
|
||||||
syntaxHighlight: false,
|
syntaxHighlight: false,
|
||||||
remarkPlugins: [
|
remarkPlugins: [
|
||||||
remarkParseAtTypes,
|
remarkParseAtTypes,
|
||||||
|
|
@ -168,7 +242,7 @@ export const markdownConfig: AstroMarkdownOptions = {
|
||||||
},
|
},
|
||||||
defaultColor: false,
|
defaultColor: false,
|
||||||
wrap: true,
|
wrap: true,
|
||||||
transformers: [shikiRewriteTypelinks],
|
transformers: [shikiRewriteTypelinks, shikiCopyButton],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// FIXME: incompatible types between unified/Plugin and Astro/RehypePlugin
|
// FIXME: incompatible types between unified/Plugin and Astro/RehypePlugin
|
||||||
|
|
@ -185,18 +259,23 @@ let globalMarkdownProcessor: Promise<MarkdownProcessor>;
|
||||||
|
|
||||||
async function getMarkdownProcessor(): Promise<MarkdownProcessor> {
|
async function getMarkdownProcessor(): Promise<MarkdownProcessor> {
|
||||||
if (!globalMarkdownProcessor) {
|
if (!globalMarkdownProcessor) {
|
||||||
globalMarkdownProcessor = createMarkdownProcessor(markdownConfig);
|
globalMarkdownProcessor =
|
||||||
|
createMarkdownProcessor(markdownConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
return globalMarkdownProcessor;
|
return globalMarkdownProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function processMarkdown(
|
async function processMarkdown(
|
||||||
version: string,
|
version: string,
|
||||||
markdown: string,
|
markdown: string
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
currentVersion = version;
|
currentVersion = version;
|
||||||
const r = (await (await getMarkdownProcessor()).render(markdown)).code;
|
const r = (
|
||||||
|
await (await getMarkdownProcessor()).render(markdown)
|
||||||
|
).code;
|
||||||
currentVersion = "NOVERSION";
|
currentVersion = "NOVERSION";
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export { markdownConfig, processMarkdown };
|
||||||
|
|
|
||||||
69
src/config/styling/animations_helper.ts
Normal file
69
src/config/styling/animations_helper.ts
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
export function initAnimations() {
|
||||||
|
const observerOptions = {
|
||||||
|
root: null,
|
||||||
|
rootMargin: "0px",
|
||||||
|
threshold: 0.1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
(entries, observer) => {
|
||||||
|
entries.forEach(entry => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
entry.target.classList.add("visible");
|
||||||
|
observer.unobserve(entry.target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
observerOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
const animatedElements = document.querySelectorAll(
|
||||||
|
".animate-fade-up, .stagger-parent"
|
||||||
|
);
|
||||||
|
animatedElements.forEach(el => observer.observe(el));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initTOCHighlighting() {
|
||||||
|
const observer = new IntersectionObserver(entries => {
|
||||||
|
entries.forEach(entry => {
|
||||||
|
const heading = entry.target.querySelector(
|
||||||
|
"h1, h2, h3, h4, h5, h6"
|
||||||
|
);
|
||||||
|
if (heading) {
|
||||||
|
const id = heading.id;
|
||||||
|
const desktopElement = document.querySelector(
|
||||||
|
`.toc-wrapper li a[href="#${id}"]`
|
||||||
|
);
|
||||||
|
const mobileElement = document.querySelector(
|
||||||
|
`.toc-wrapper-mobile li a[href="#${id}"]`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
desktopElement?.parentElement?.classList.add("active");
|
||||||
|
mobileElement?.parentElement?.classList.add("active");
|
||||||
|
} else {
|
||||||
|
desktopElement?.parentElement?.classList.remove(
|
||||||
|
"active"
|
||||||
|
);
|
||||||
|
mobileElement?.parentElement?.classList.remove(
|
||||||
|
"active"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelectorAll("section[data-heading-rank]")
|
||||||
|
.forEach(section => {
|
||||||
|
observer.observe(section);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// auto-init on DOMContentLoaded
|
||||||
|
if (typeof document !== "undefined") {
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
initAnimations();
|
||||||
|
initTOCHighlighting();
|
||||||
|
});
|
||||||
|
}
|
||||||
260
src/config/styling/marquee.ts
Normal file
260
src/config/styling/marquee.ts
Normal file
|
|
@ -0,0 +1,260 @@
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
const container = document.querySelector(
|
||||||
|
".marquee"
|
||||||
|
) as HTMLDivElement;
|
||||||
|
const scroller = document.querySelector(
|
||||||
|
".marquee-content"
|
||||||
|
) as HTMLDivElement;
|
||||||
|
const btnLeft = document.getElementById("marquee-scroll-left");
|
||||||
|
const btnRight = document.getElementById(
|
||||||
|
"marquee-scroll-right"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!container || !scroller) return;
|
||||||
|
|
||||||
|
const bufferSize = 2;
|
||||||
|
let items = Array.from(
|
||||||
|
scroller.querySelectorAll(".marquee-item")
|
||||||
|
) as HTMLDivElement[];
|
||||||
|
const originalCount = items.length;
|
||||||
|
if (originalCount === 0) return;
|
||||||
|
|
||||||
|
let itemWidth = 0;
|
||||||
|
let sequenceWidth = 0;
|
||||||
|
let targetScrollX = 0;
|
||||||
|
let currentScrollX = 0;
|
||||||
|
let isAnimating = false;
|
||||||
|
let isDown = false;
|
||||||
|
let lastTouchX = 0;
|
||||||
|
let touchVelocity = 0;
|
||||||
|
let lastTouchTime = 0;
|
||||||
|
const smoothFactor = 0.1;
|
||||||
|
const snapThreshold = 0.1;
|
||||||
|
|
||||||
|
// setup clones
|
||||||
|
const setupClones = () => {
|
||||||
|
// remove existing clones
|
||||||
|
scroller.querySelectorAll(".clone").forEach(c => c.remove());
|
||||||
|
|
||||||
|
const originals = Array.from(
|
||||||
|
scroller.querySelectorAll(".marquee-item")
|
||||||
|
) as HTMLDivElement[];
|
||||||
|
|
||||||
|
// add clones after
|
||||||
|
for (let i = 0; i < bufferSize; i++) {
|
||||||
|
originals.forEach(item => {
|
||||||
|
const clone = item.cloneNode(true) as HTMLDivElement;
|
||||||
|
clone.classList.add("clone");
|
||||||
|
scroller.appendChild(clone);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// add clones before
|
||||||
|
const beforeContainer = document.createDocumentFragment();
|
||||||
|
for (let i = 0; i < bufferSize; i++) {
|
||||||
|
originals.forEach(item => {
|
||||||
|
const clone = item.cloneNode(true) as HTMLDivElement;
|
||||||
|
clone.classList.add("clone");
|
||||||
|
beforeContainer.appendChild(clone);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
scroller.insertBefore(beforeContainer, scroller.firstChild);
|
||||||
|
|
||||||
|
items = Array.from(
|
||||||
|
scroller.querySelectorAll(".marquee-item")
|
||||||
|
) as HTMLDivElement[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateDimensions = () => {
|
||||||
|
itemWidth = container.clientWidth;
|
||||||
|
if (itemWidth === 0) return;
|
||||||
|
|
||||||
|
sequenceWidth = originalCount * itemWidth;
|
||||||
|
|
||||||
|
// standardize width
|
||||||
|
scroller.style.width = `${items.length * itemWidth}px`;
|
||||||
|
items.forEach(item => {
|
||||||
|
item.style.width = `${itemWidth}px`;
|
||||||
|
item.style.flex = `0 0 ${itemWidth}px`;
|
||||||
|
item.style.maxWidth = `${itemWidth}px`;
|
||||||
|
});
|
||||||
|
|
||||||
|
targetScrollX =
|
||||||
|
bufferSize * sequenceWidth +
|
||||||
|
(targetScrollX % sequenceWidth);
|
||||||
|
currentScrollX = targetScrollX;
|
||||||
|
scroller.style.transform = `translateX(-${currentScrollX}px)`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const lerp = (start: number, end: number, factor: number) =>
|
||||||
|
start + (end - start) * factor;
|
||||||
|
|
||||||
|
const animate = () => {
|
||||||
|
if (!isDown && Math.abs(touchVelocity) < 0.1) {
|
||||||
|
// snap to nearest item if not interacting and close to one
|
||||||
|
const nearestItemScroll =
|
||||||
|
Math.round(targetScrollX / itemWidth) * itemWidth;
|
||||||
|
if (
|
||||||
|
Math.abs(targetScrollX - nearestItemScroll) <
|
||||||
|
itemWidth * 0.5
|
||||||
|
) {
|
||||||
|
targetScrollX = lerp(
|
||||||
|
targetScrollX,
|
||||||
|
nearestItemScroll,
|
||||||
|
0.1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentScrollX = lerp(
|
||||||
|
currentScrollX,
|
||||||
|
targetScrollX,
|
||||||
|
smoothFactor
|
||||||
|
);
|
||||||
|
|
||||||
|
// boundary reset
|
||||||
|
if (currentScrollX > (bufferSize + 1) * sequenceWidth) {
|
||||||
|
currentScrollX -= sequenceWidth;
|
||||||
|
targetScrollX -= sequenceWidth;
|
||||||
|
} else if (
|
||||||
|
currentScrollX <
|
||||||
|
(bufferSize - 1) * sequenceWidth
|
||||||
|
) {
|
||||||
|
currentScrollX += sequenceWidth;
|
||||||
|
targetScrollX += sequenceWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
scroller.style.transform = `translateX(-${currentScrollX}px)`;
|
||||||
|
|
||||||
|
// fade in-out and scale items based on distance from center
|
||||||
|
items.forEach((item, index) => {
|
||||||
|
const itemCenter = index * itemWidth;
|
||||||
|
const distance = Math.abs(currentScrollX - itemCenter);
|
||||||
|
const progress = Math.min(distance / itemWidth, 1); // 0 at center, 1 at edge
|
||||||
|
|
||||||
|
const opacity = 1 - progress;
|
||||||
|
const scale = 1 - progress * 0.1; // scale down as it leaves
|
||||||
|
const yOffset = progress * 20; // slide down as it leaves
|
||||||
|
|
||||||
|
item.style.opacity = opacity.toString();
|
||||||
|
// NOTE: apply transform to the video container specifically
|
||||||
|
// to keep layout stable
|
||||||
|
const content = item.querySelector(
|
||||||
|
".marquee-item-content"
|
||||||
|
) as HTMLElement;
|
||||||
|
if (content) {
|
||||||
|
content.style.transform = `scale(${scale}) translateY(${yOffset}px)`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const diff = Math.abs(targetScrollX - currentScrollX);
|
||||||
|
const interaction = isDown || Math.abs(touchVelocity) > 0.1;
|
||||||
|
|
||||||
|
if (diff > snapThreshold || interaction) {
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
} else {
|
||||||
|
isAnimating = false;
|
||||||
|
currentScrollX = targetScrollX;
|
||||||
|
scroller.style.transform = `translateX(-${currentScrollX}px)`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const startAnimation = () => {
|
||||||
|
if (!isAnimating) {
|
||||||
|
isAnimating = true;
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// video handling
|
||||||
|
const videos = scroller.querySelectorAll("video");
|
||||||
|
const observerOptions = {
|
||||||
|
root: container,
|
||||||
|
threshold: 0.5,
|
||||||
|
};
|
||||||
|
|
||||||
|
const videoObserver = new IntersectionObserver(entries => {
|
||||||
|
entries.forEach(entry => {
|
||||||
|
const video = entry.target as HTMLVideoElement;
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
video.play().catch(() => {}); // Handle potential autoplay blocks
|
||||||
|
} else {
|
||||||
|
video.pause();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, observerOptions);
|
||||||
|
|
||||||
|
videos.forEach(v => {
|
||||||
|
videoObserver.observe(v);
|
||||||
|
v.addEventListener("ended", () => {
|
||||||
|
targetScrollX += itemWidth;
|
||||||
|
startAnimation();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// events
|
||||||
|
btnLeft?.addEventListener("click", () => {
|
||||||
|
targetScrollX -= itemWidth;
|
||||||
|
startAnimation();
|
||||||
|
});
|
||||||
|
|
||||||
|
btnRight?.addEventListener("click", () => {
|
||||||
|
targetScrollX += itemWidth;
|
||||||
|
startAnimation();
|
||||||
|
});
|
||||||
|
|
||||||
|
container.addEventListener(
|
||||||
|
"wheel",
|
||||||
|
e => {
|
||||||
|
e.preventDefault();
|
||||||
|
targetScrollX += e.deltaY;
|
||||||
|
startAnimation();
|
||||||
|
},
|
||||||
|
{ passive: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
container.addEventListener("touchstart", e => {
|
||||||
|
isDown = true;
|
||||||
|
lastTouchX = e.touches[0].clientX;
|
||||||
|
lastTouchTime = Date.now();
|
||||||
|
touchVelocity = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
container.addEventListener("touchmove", e => {
|
||||||
|
if (!isDown) return;
|
||||||
|
const currentTouchX = e.touches[0].clientX;
|
||||||
|
const deltaX = lastTouchX - currentTouchX;
|
||||||
|
targetScrollX += deltaX * 1.5;
|
||||||
|
|
||||||
|
const now = Date.now();
|
||||||
|
const dt = now - lastTouchTime;
|
||||||
|
if (dt > 0) touchVelocity = deltaX / dt;
|
||||||
|
|
||||||
|
lastTouchX = currentTouchX;
|
||||||
|
lastTouchTime = now;
|
||||||
|
startAnimation();
|
||||||
|
});
|
||||||
|
|
||||||
|
container.addEventListener("touchend", () => {
|
||||||
|
isDown = false;
|
||||||
|
targetScrollX += touchVelocity * 100; // Momentum
|
||||||
|
touchVelocity = 0;
|
||||||
|
startAnimation();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("resize", updateDimensions);
|
||||||
|
|
||||||
|
document.addEventListener("visibilitychange", () => {
|
||||||
|
if (document.hidden) {
|
||||||
|
videos.forEach(v => v.pause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// init
|
||||||
|
setupClones();
|
||||||
|
setTimeout(() => {
|
||||||
|
updateDimensions();
|
||||||
|
container.classList.add("initialized");
|
||||||
|
startAnimation();
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
89
src/config/styling/theme_persistence.ts
Normal file
89
src/config/styling/theme_persistence.ts
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
interface ThemeProps {
|
||||||
|
theme: "light" | "dark";
|
||||||
|
system: "light" | "dark";
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getCurrentTheme = (): ThemeProps => {
|
||||||
|
const isDarkSystem = window.matchMedia(
|
||||||
|
"(prefers-color-scheme: dark)"
|
||||||
|
).matches;
|
||||||
|
const systemTheme = isDarkSystem ? "dark" : "light";
|
||||||
|
|
||||||
|
if (typeof localStorage !== "undefined") {
|
||||||
|
if (localStorage.theme === "dark") {
|
||||||
|
return { theme: "dark", system: systemTheme };
|
||||||
|
}
|
||||||
|
if (localStorage.theme === "light") {
|
||||||
|
return { theme: "light", system: systemTheme };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { theme: systemTheme, system: systemTheme };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateTheme = (transition = true) => {
|
||||||
|
const theme = getCurrentTheme();
|
||||||
|
const toggle = document.getElementById(
|
||||||
|
"theme-manual-toggle"
|
||||||
|
) as HTMLInputElement;
|
||||||
|
|
||||||
|
if (transition) {
|
||||||
|
document.documentElement.classList.add("changing-theme");
|
||||||
|
document.documentElement.style.setProperty(
|
||||||
|
"--theme-transition",
|
||||||
|
"0.3s var(--ease-in-out)"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
document.documentElement.style.removeProperty(
|
||||||
|
"--theme-transition"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theme.theme === "dark") {
|
||||||
|
document.documentElement.classList.add("dark");
|
||||||
|
if (toggle) toggle.checked = true;
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove("dark");
|
||||||
|
if (toggle) toggle.checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transition) {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
document.documentElement.classList.remove(
|
||||||
|
"changing-theme"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const initTheme = () => {
|
||||||
|
const toggle = document.getElementById(
|
||||||
|
"theme-manual-toggle"
|
||||||
|
) as HTMLInputElement;
|
||||||
|
|
||||||
|
if (toggle) {
|
||||||
|
toggle.addEventListener("change", () => {
|
||||||
|
localStorage.theme = toggle.checked ? "dark" : "light";
|
||||||
|
updateTheme();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window
|
||||||
|
.matchMedia("(prefers-color-scheme: dark)")
|
||||||
|
.addEventListener("change", () => updateTheme());
|
||||||
|
window.addEventListener("storage", () => updateTheme());
|
||||||
|
|
||||||
|
// initial sync
|
||||||
|
updateTheme(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// auto-init on client
|
||||||
|
if (typeof document !== "undefined") {
|
||||||
|
if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", initTheme);
|
||||||
|
} else {
|
||||||
|
initTheme();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ import { defineCollection, z } from "astro:content";
|
||||||
import { glob } from "astro/loaders";
|
import { glob } from "astro/loaders";
|
||||||
|
|
||||||
const guide = defineCollection({
|
const guide = defineCollection({
|
||||||
loader: glob({ pattern: "**/*.md", base: "src/guide" }),
|
loader: glob({ pattern: "**/*.{md,mdx}", base: "src/guide" }),
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
index: z.number(),
|
index: z.number(),
|
||||||
|
|
|
||||||
46
src/env.d.ts
vendored
46
src/env.d.ts
vendored
|
|
@ -1,2 +1,46 @@
|
||||||
/// <reference path="../.astro/types.d.ts" />
|
|
||||||
/// <reference types="astro/client" />
|
/// <reference types="astro/client" />
|
||||||
|
/// <reference path="../.astro/types.d.ts" />
|
||||||
|
/// <reference types="astro-icon/empty-types" />
|
||||||
|
|
||||||
|
declare module "astro-icon/components" {
|
||||||
|
export const Icon: typeof import("astro-icon/components").Icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImportMetaEnv {
|
||||||
|
readonly VERSION_FILE_PATH: string;
|
||||||
|
readonly BASE_URL: string;
|
||||||
|
readonly PRODUCTION: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImportMeta {
|
||||||
|
readonly env: ImportMetaEnv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix astro-breadcrumbs
|
||||||
|
declare module "astro-breadcrumbs" {
|
||||||
|
interface BreadcrumbsProps {
|
||||||
|
indexText?: string;
|
||||||
|
mainText?: string;
|
||||||
|
crumbs: {
|
||||||
|
text: string;
|
||||||
|
href: string;
|
||||||
|
}[];
|
||||||
|
linkTextFormat?: string;
|
||||||
|
truncated?: boolean;
|
||||||
|
case?:
|
||||||
|
| "lower"
|
||||||
|
| "upper"
|
||||||
|
| "capitalize"
|
||||||
|
| "title"
|
||||||
|
| "original";
|
||||||
|
// Add other props you use here
|
||||||
|
}
|
||||||
|
export const Breadcrumbs: (props: BreadcrumbsProps) => any;
|
||||||
|
export default Breadcrumbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix for "?raw" imports
|
||||||
|
declare module "*?raw" {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,11 +75,11 @@ To start with, let's make a clock. To get the time, we'll use the `date` command
|
||||||
> [!note/Note]
|
> [!note/Note]
|
||||||
> Quickshell can do more than just run processes. Read until the end for more information.
|
> Quickshell can do more than just run processes. Read until the end for more information.
|
||||||
|
|
||||||
We can use a [Process](@docs/types/quickshell.io/process) object to run commands
|
We can use a [Process](@docs/types/Quickshell.Io/Process) object to run commands
|
||||||
and a @@Quickshell.Io.StdioCollector to read their output.
|
and a @@Quickshell.Io.StdioCollector to read their output.
|
||||||
|
|
||||||
We'll listen to the @@Quickshell.Io.StdioCollector.streamFinished(s) signal with
|
We'll listen to the @@Quickshell.Io.StdioCollector.streamFinished(s) signal with
|
||||||
a [signal handler](@docs/guide/qml-language/#signal-handlers)
|
a [signal handler](@docs/guide/qml-language#signal-handlers)
|
||||||
to update the text on the clock.
|
to update the text on the clock.
|
||||||
|
|
||||||
> [!note/Note]
|
> [!note/Note]
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ Name {
|
||||||
|
|
||||||
Every object can contain [properties](#properties), [functions](#functions),
|
Every object can contain [properties](#properties), [functions](#functions),
|
||||||
and [signals](#signals). You can find out what properties are available for a type
|
and [signals](#signals). You can find out what properties are available for a type
|
||||||
by looking it up in the [Type Reference](@docs/types/).
|
by looking it up in the [Type Reference](@docs/types).
|
||||||
|
|
||||||
#### Properties
|
#### Properties
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
title: "QML Language"
|
title: "QML Language"
|
||||||
index: 10
|
index: 10
|
||||||
---
|
---
|
||||||
|
import Collapsible from "@components/Collapsible.astro";
|
||||||
|
|
||||||
Quickshell is configured using the Qt Modeling Language, or QML.
|
Quickshell is configured using the Qt Modeling Language, or QML.
|
||||||
This page explains what you need to know about QML to start using Quickshell.
|
This page explains what you need to know about QML to start using Quickshell.
|
||||||
|
|
@ -186,7 +187,7 @@ Name {
|
||||||
|
|
||||||
Every object can contain [properties](#properties), [functions](#functions),
|
Every object can contain [properties](#properties), [functions](#functions),
|
||||||
and [signals](#signals). You can find out what properties are available for a type
|
and [signals](#signals). You can find out what properties are available for a type
|
||||||
by looking it up in the [Type Reference](@docs/types/).
|
by looking it up in the [Type Reference](@docs/types).
|
||||||
|
|
||||||
#### Properties
|
#### Properties
|
||||||
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
//import Header from "@components/Header.astro";
|
//import Header from "@components/Header.astro";
|
||||||
import Head from "@config/Head.astro";
|
import Head from "@config/Head.astro";
|
||||||
import PreTheme from "@config/PreTheme.astro";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
|
|
@ -14,10 +13,20 @@ const { title, description } = Astro.props;
|
||||||
<html lang="en" class="dark">
|
<html lang="en" class="dark">
|
||||||
<head>
|
<head>
|
||||||
<Head description={description} title={title} />
|
<Head description={description} title={title} />
|
||||||
<PreTheme />
|
|
||||||
</head>
|
</head>
|
||||||
<body class="baselayout">
|
<body class="baselayout">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="theme-manual-toggle"
|
||||||
|
class="theme-toggle-input"
|
||||||
|
style="display: none;"
|
||||||
|
aria-label="Toggle theme (light/dark)"
|
||||||
|
>
|
||||||
<!--<Header />-->
|
<!--<Header />-->
|
||||||
<slot />
|
<slot />
|
||||||
|
<script>
|
||||||
|
import "@config/styling/animations_helper.ts";
|
||||||
|
import "@config/styling/theme_persistence.ts";
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -2,29 +2,29 @@
|
||||||
import { Breadcrumbs } from "astro-breadcrumbs";
|
import { Breadcrumbs } from "astro-breadcrumbs";
|
||||||
import "astro-breadcrumbs/breadcrumbs.css";
|
import "astro-breadcrumbs/breadcrumbs.css";
|
||||||
|
|
||||||
import CreateCopyButtons from "@components/hooks/CreateCopyButtons.astro";
|
|
||||||
import PreTheme from "@config/PreTheme.astro";
|
|
||||||
import Header from "@components/Header.astro";
|
import Header from "@components/Header.astro";
|
||||||
import Head from "@config/Head.astro";
|
import Head from "@config/Head.astro";
|
||||||
import Nav from "@components/navigation/sidebars/nav/index.astro";
|
import Nav from "@components/navigation/sidebars/nav/index.astro";
|
||||||
import type { ConfigHeading } from "@src/components/navigation/sidebars/types";
|
import type { ConfigHeading } from "@src/components/navigation/sidebars/types";
|
||||||
import Footer from "@src/components/Footer.astro";
|
import Footer from "@src/components/Footer.astro";
|
||||||
import type { TypeData } from "@config/io/types";
|
import type { TypeData } from "@config/_types";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
headings?: ConfigHeading[];
|
headings?: ConfigHeading[];
|
||||||
type?: TypeData
|
type?: TypeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { title, description, headings, type } = Astro.props;
|
const { title, description, headings, type } = Astro.props;
|
||||||
let url = Astro.url.pathname.split("/").filter(s => s !== "");
|
let url = Astro.url.pathname.split("/").filter((s: string) => s !== "");
|
||||||
|
|
||||||
const breadcrumbs = [{
|
const breadcrumbs = [
|
||||||
|
{
|
||||||
text: "custom",
|
text: "custom",
|
||||||
href: "/",
|
href: "/",
|
||||||
}];
|
},
|
||||||
|
];
|
||||||
|
|
||||||
let linkPath = "";
|
let linkPath = "";
|
||||||
if (url[0] === "docs") {
|
if (url[0] === "docs") {
|
||||||
|
|
@ -49,16 +49,27 @@ for (const segment of url) {
|
||||||
<html lang="en" class="dark">
|
<html lang="en" class="dark">
|
||||||
<head>
|
<head>
|
||||||
<Head description={description} title={title} />
|
<Head description={description} title={title} />
|
||||||
<PreTheme />
|
|
||||||
<CreateCopyButtons />
|
|
||||||
</head>
|
</head>
|
||||||
<body class="docslayout">
|
<body class="docslayout">
|
||||||
<Header title={title} headings={headings} type={type}/>
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="theme-manual-toggle"
|
||||||
|
class="theme-toggle-input"
|
||||||
|
aria-label="Toggle theme (light/dark)"
|
||||||
|
style="display: none;"
|
||||||
|
>
|
||||||
|
<Header title={title} headings={headings} type={type} />
|
||||||
<div class="docslayout-root">
|
<div class="docslayout-root">
|
||||||
<Nav mobile={false}/>
|
<Nav mobile={false} />
|
||||||
<div class="docslayout-inner" data-pagefind-body>
|
<div class="docslayout-inner" data-pagefind-body>
|
||||||
<Breadcrumbs crumbs={breadcrumbs} linkTextFormat="sentence" truncated={true} data-pagefind-ignore>
|
<Breadcrumbs
|
||||||
|
crumbs={breadcrumbs}
|
||||||
|
linkTextFormat="sentence"
|
||||||
|
truncated={true}
|
||||||
|
data-pagefind-ignore
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
|
<!-- @ts-expect-error -->
|
||||||
slot="index"
|
slot="index"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="1em"
|
width="1em"
|
||||||
|
|
@ -69,25 +80,61 @@ for (const segment of url) {
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
d="m219.31 108.68l-80-80a16 16 0 0 0-22.62 0l-80 80A15.87 15.87 0 0 0 32 120v96a8 8 0 0 0 8 8h64a8 8 0 0 0 8-8v-56h32v56a8 8 0 0 0 8 8h64a8 8 0 0 0 8-8v-96a15.87 15.87 0 0 0-4.69-11.32M208 208h-48v-56a8 8 0 0 0-8-8h-48a8 8 0 0 0-8 8v56H48v-88l80-80l80 80Z"
|
d="m219.31 108.68l-80-80a16 16 0 0 0-22.62 0l-80 80A15.87 15.87 0 0 0 32 120v96a8 8 0 0 0 8 8h64a8 8 0 0 0 8-8v-56h32v56a8 8 0 0 0 8 8h64a8 8 0 0 0 8-8v-96a15.87 15.87 0 0 0-4.69-11.32M208 208h-48v-56a8 8 0 0 0-8-8h-48a8 8 0 0 0-8 8v56H48v-88l80-80l80 80Z"
|
||||||
></path></svg
|
></path>
|
||||||
>
|
</svg>
|
||||||
<svg
|
<svg
|
||||||
|
<!-- @ts-expect-error -->
|
||||||
slot="separator"
|
slot="separator"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="1em"
|
width="1em"
|
||||||
height="1em"
|
height="1em"
|
||||||
viewBox="0 0 256 256"
|
viewBox="0 0 256 256"
|
||||||
><path
|
>
|
||||||
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
d="m181.66 133.66l-80 80a8 8 0 0 1-11.32-11.32L164.69 128L90.34 53.66a8 8 0 0 1 11.32-11.32l80 80a8 8 0 0 1 0 11.32"
|
d="m181.66 133.66l-80 80a8 8 0 0 1-11.32-11.32L164.69 128L90.34 53.66a8 8 0 0 1 11.32-11.32l80 80a8 8 0 0 1 0 11.32"
|
||||||
></path></svg
|
></path>
|
||||||
>
|
</svg>
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
<slot/>
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
<slot name="alongside-content"/>
|
<slot name="alongside-content" />
|
||||||
</div>
|
</div>
|
||||||
<Footer/>
|
<Footer />
|
||||||
|
<script>
|
||||||
|
import "@config/styling/animations_helper.ts";
|
||||||
|
import "@config/styling/theme_persistence.ts";
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
<script>
|
||||||
|
// FIXME: need to make this work properly, or fold into the markdown processor
|
||||||
|
let headings = document.getElementsByClassName("heading");
|
||||||
|
if (headings.length > 0) {
|
||||||
|
//@ts-expect-error
|
||||||
|
for (const heading of headings) {
|
||||||
|
let button = heading.querySelector("h2");
|
||||||
|
if (button) {
|
||||||
|
button.onclick = () => {
|
||||||
|
let link = window.location.href.split("#")[0];
|
||||||
|
link += `#${button.textContent?.trimEnd().replaceAll(" ", "-").toLowerCase()}`;
|
||||||
|
window.location.href = link;
|
||||||
|
navigator.clipboard.writeText(link);
|
||||||
|
heading.classList.toggle("copied");
|
||||||
|
setTimeout(() => heading.classList.remove("copied"), 1000);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let spanButton = heading.querySelector("span");
|
||||||
|
if (spanButton) {
|
||||||
|
spanButton.onclick = () => {
|
||||||
|
let link = window.location.href.split("#")[0];
|
||||||
|
link += `#${spanButton.textContent?.trim().replaceAll(" ", "-").toLowerCase()}`;
|
||||||
|
window.location.href = link;
|
||||||
|
navigator.clipboard.writeText(link);
|
||||||
|
spanButton.classList.toggle("copied");
|
||||||
|
setTimeout(() => heading.classList.remove("copied"), 1000);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
import DocsLayout from "@layouts/DocsLayout.astro";
|
import DocsLayout from "@layouts/DocsLayout.astro";
|
||||||
import TOC from "@components/navigation/sidebars/TOC.astro";
|
import TOC from "@components/navigation/sidebars/TOC.astro";
|
||||||
import TOCIntersectionObserver from "@src/components/hooks/TOCIntersectionObserver.astro";
|
|
||||||
import type { ConfigHeading } from "@src/components/navigation/sidebars/types";
|
import type { ConfigHeading } from "@src/components/navigation/sidebars/types";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
|
|
@ -12,15 +11,20 @@ export interface Props {
|
||||||
|
|
||||||
const { title, description, headings } = Astro.props;
|
const { title, description, headings } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<DocsLayout title={title} description={description} headings={headings}>
|
<DocsLayout title={title} description={description} headings={headings}>
|
||||||
<div class="docs">
|
<div class="docs">
|
||||||
<div class="docs-content">
|
<div class="docs-content">
|
||||||
<hr/>
|
<hr>
|
||||||
<h1>{title}</h1>
|
<h1>{title}</h1>
|
||||||
<slot/>
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<TOC slot="alongside-content" mobile={false} title={title} headings={headings} data-pagefind-ignore/>
|
<TOC
|
||||||
|
slot="alongside-content"
|
||||||
|
mobile={false}
|
||||||
|
title={title}
|
||||||
|
headings={headings}
|
||||||
|
data-pagefind-ignore
|
||||||
|
/>
|
||||||
</DocsLayout>
|
</DocsLayout>
|
||||||
|
|
||||||
<TOCIntersectionObserver/>
|
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,15 @@ export interface Props {
|
||||||
frontmatter: {
|
frontmatter: {
|
||||||
title: string;
|
title: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const { headings, frontmatter: { title, description } } = Astro.props;
|
const {
|
||||||
|
headings,
|
||||||
|
frontmatter: { title, description },
|
||||||
|
} = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<GuideLayout title={title} description={description ?? ""} headings={headings}>
|
<GuideLayout title={title} description={description ?? ""} headings={headings}>
|
||||||
<slot/>
|
<slot />
|
||||||
</GuideLayout>
|
</GuideLayout>
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,14 @@ import { processMarkdown } from "@config/io/markdown";
|
||||||
|
|
||||||
const { versions } = await getVersionsData();
|
const { versions } = await getVersionsData();
|
||||||
|
|
||||||
const versionsMd = await Promise.all(versions.filter(version => version.changelog).map(async version => ({
|
const versionsMd = await Promise.all(
|
||||||
|
versions
|
||||||
|
.filter(version => version.changelog)
|
||||||
|
.map(async version => ({
|
||||||
version,
|
version,
|
||||||
changelog: await processMarkdown(version.name, version.changelog!)
|
changelog: await processMarkdown(version.name, version.changelog ?? ""),
|
||||||
})));
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
const headings = versionsMd.map(({ version }) => ({
|
const headings = versionsMd.map(({ version }) => ({
|
||||||
text: version.name,
|
text: version.name,
|
||||||
|
|
@ -16,6 +20,7 @@ const headings = versionsMd.map(({ version }) => ({
|
||||||
depth: 1,
|
depth: 1,
|
||||||
}));
|
}));
|
||||||
---
|
---
|
||||||
|
|
||||||
<GuideLayout title="Changelog" description="" headings={headings}>
|
<GuideLayout title="Changelog" description="" headings={headings}>
|
||||||
{versionsMd.map(({ version, changelog }) => (
|
{versionsMd.map(({ version, changelog }) => (
|
||||||
<div style="display: flex; justify-content: space-between">
|
<div style="display: flex; justify-content: space-between">
|
||||||
|
|
|
||||||
|
|
@ -2,31 +2,39 @@
|
||||||
import GuideLayout from "@layouts/GuideLayout.astro";
|
import GuideLayout from "@layouts/GuideLayout.astro";
|
||||||
import { getVersionsData } from "@config/io/generateTypeData";
|
import { getVersionsData } from "@config/io/generateTypeData";
|
||||||
import { getGuideCollection } from "@config/io/guides";
|
import { getGuideCollection } from "@config/io/guides";
|
||||||
import { processMarkdown } from "@config/io/markdown";
|
|
||||||
|
|
||||||
import { render } from "astro:content";
|
import { render } from "astro:content";
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const { versions } = await getVersionsData();
|
const { versions } = await getVersionsData();
|
||||||
|
|
||||||
let pages = await Promise.all(versions.map(async version => {
|
const pages = await Promise.all(
|
||||||
|
versions.map(async version => {
|
||||||
const pages = await getGuideCollection(version.name);
|
const pages = await getGuideCollection(version.name);
|
||||||
|
|
||||||
return pages.map(page => ({
|
return pages.map(page => ({
|
||||||
params: { version: version.name, id: page.id === "index" ? "/" : page.id },
|
params: {
|
||||||
|
version: version.name,
|
||||||
|
id: page.id === "index" ? "/" : page.id,
|
||||||
|
},
|
||||||
props: { version, page },
|
props: { version, page },
|
||||||
}));
|
}));
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
return pages.flat();
|
return pages.flat();
|
||||||
}
|
}
|
||||||
|
|
||||||
const { version, page } = Astro.props;
|
const { page } = Astro.props;
|
||||||
const { headings } = await render(page);
|
const { headings, Content } = await render(page);
|
||||||
|
|
||||||
|
// xnzf: version is decided before these pages get processed
|
||||||
|
// V
|
||||||
// we can't use 'Content' because there isn't a way to pass in a version
|
// we can't use 'Content' because there isn't a way to pass in a version
|
||||||
const html = await processMarkdown(version.name, page.body!);
|
|
||||||
|
// const html = await processMarkdown(version.name, page.body!);
|
||||||
---
|
---
|
||||||
|
|
||||||
<GuideLayout title={page.data.title} description="" headings={headings}>
|
<GuideLayout title={page.data.title} description="" headings={headings}>
|
||||||
<Fragment set:html={html}/>
|
<Content />
|
||||||
</GuideLayout>
|
</GuideLayout>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ export async function getStaticPaths() {
|
||||||
|
|
||||||
const { version } = Astro.props;
|
const { version } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<DocsLayout title="Quickshell Docs" description="Quickshell Documentation">
|
<DocsLayout title="Quickshell Docs" description="Quickshell Documentation">
|
||||||
<h2>Docs</h2>
|
<h2>Docs</h2>
|
||||||
<div class="root-nav">
|
<div class="root-nav">
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,25 @@ import Functions from "@components/type/Functions.astro";
|
||||||
import Signals from "@components/type/Signals.astro";
|
import Signals from "@components/type/Signals.astro";
|
||||||
import Variants from "@components/type/Variants.astro";
|
import Variants from "@components/type/Variants.astro";
|
||||||
import Badge from "@components/Badge.astro";
|
import Badge from "@components/Badge.astro";
|
||||||
|
import type { ModuleData, TypeData } from "@_types";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
version: {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
module: ModuleData;
|
||||||
|
type: TypeData;
|
||||||
|
}
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
return (await getVersionsData()).versions.flatMap(version => {
|
return (await getVersionsData()).versions.flatMap(version => {
|
||||||
return version.modules.flatMap(module => {
|
return version.modules.flatMap(module => {
|
||||||
return module.types.map(type => ({
|
return module.types.map(type => ({
|
||||||
params: { version: version.name, module: module.name, type: type.name },
|
params: {
|
||||||
|
version: version.name,
|
||||||
|
module: module.name,
|
||||||
|
type: type.name,
|
||||||
|
},
|
||||||
props: { version, module, type },
|
props: { version, module, type },
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
@ -29,10 +42,15 @@ const details = type.details
|
||||||
? await processMarkdown(version.name, type.details)
|
? await processMarkdown(version.name, type.details)
|
||||||
: null;
|
: null;
|
||||||
---
|
---
|
||||||
<DocsLayout title={`${module.name} - ${type.name}`} description={type.description ?? ""} type={type}>
|
|
||||||
|
<DocsLayout
|
||||||
|
title={`${module.name} - ${type.name}`}
|
||||||
|
description={type.description ?? ""}
|
||||||
|
type={type}
|
||||||
|
>
|
||||||
<div class="docs">
|
<div class="docs">
|
||||||
<div class="docs-content typedocs-content">
|
<div class="docs-content typedocs-content">
|
||||||
<hr />
|
<hr>
|
||||||
<section class="typedocs-title">
|
<section class="typedocs-title">
|
||||||
<h2 class="typedocs-title-text" data-pagefind-weight="10">
|
<h2 class="typedocs-title-text" data-pagefind-weight="10">
|
||||||
{type.name}:
|
{type.name}:
|
||||||
|
|
@ -45,11 +63,10 @@ const details = type.details
|
||||||
</a>
|
</a>
|
||||||
):(
|
):(
|
||||||
<span class="type-datatype" data-pagefind-ignore>{type.name}</span>
|
<span class="type-datatype" data-pagefind-ignore>{type.name}</span>
|
||||||
)
|
)}
|
||||||
}
|
|
||||||
</h2>
|
</h2>
|
||||||
{type.flags && (
|
{type.flags && (
|
||||||
<div class="type-flags" data-pagefind-ignore>{type.flags.map(flag => (
|
<div class="type-flags" data-pagefind-ignore>{type.flags.map((flag:string) => (
|
||||||
<Badge badgeText={flag}/>
|
<Badge badgeText={flag}/>
|
||||||
))}</div>
|
))}</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -59,23 +76,23 @@ const details = type.details
|
||||||
<subheading class="typedocs-subheading">
|
<subheading class="typedocs-subheading">
|
||||||
{details ? <span class="parsedMD" set:html={details}/> : (<span class="toparse">{type.description}</span>)}
|
{details ? <span class="parsedMD" set:html={details}/> : (<span class="toparse">{type.description}</span>)}
|
||||||
</subheading>
|
</subheading>
|
||||||
{ Object.keys(type.properties ?? {}).length != 0 && (
|
{Object.keys(type.properties ?? {}).length != 0 && (
|
||||||
<h2>Properties <a href={`/docs/${version.name}/guide/qml-language#properties`}>[?]</a></h2>
|
<h2>Properties <a href={`/docs/${version.name}/guide/qml-language#properties`}>[?]</a></h2>
|
||||||
<Properties props={type.properties!}/>
|
<Properties props={type.properties!}/>
|
||||||
)}
|
)}
|
||||||
{ (type.functions?.length ?? 0) != 0 && (
|
{(type.functions?.length ?? 0) != 0 && (
|
||||||
<h2>Functions <a href={`/docs/${version.name}guide/qml-language#functions`}>[?]</a></h2>
|
<h2>Functions <a href={`/docs/${version.name}/guide/qml-language#functions`}>[?]</a></h2>
|
||||||
<Functions
|
<Functions
|
||||||
funcData={type.functions!}
|
funcData={type.functions!}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{ Object.keys(type.signals ?? {}).length != 0 && (
|
{Object.keys(type.signals ?? {}).length != 0 && (
|
||||||
<h2>Signals <a href={`/docs/${version.name}guide/qml-language#signals`}>[?]</a></h2>
|
<h2>Signals <a href={`/docs/${version.name}/guide/qml-language#signals`}>[?]</a></h2>
|
||||||
<Signals
|
<Signals
|
||||||
signals={type.signals!}
|
signals={type.signals!}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{ Object.keys(type.variants ?? {}).length != 0 && (
|
{Object.keys(type.variants ?? {}).length != 0 && (
|
||||||
<h2>Variants</h2>
|
<h2>Variants</h2>
|
||||||
<Variants
|
<Variants
|
||||||
variants={type.variants!}
|
variants={type.variants!}
|
||||||
|
|
@ -83,7 +100,6 @@ const details = type.details
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<TOC mobile={false} type={type} data-pagefind-ignore/>
|
<TOC mobile={false} type={type} data-pagefind-ignore />
|
||||||
</div>
|
</div>
|
||||||
</DocsLayout>
|
</DocsLayout>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import DocsLayout from "@layouts/DocsLayout.astro";
|
import DocsLayout from "@layouts/DocsLayout.astro";
|
||||||
import { getVersionsData } from "@config/io/generateTypeData";
|
import { getVersionsData } from "@config/io/generateTypeData";
|
||||||
import { processMarkdown } from "@src/config/io/markdown";
|
import { processMarkdown } from "@src/config/io/markdown";
|
||||||
|
import type { TypeData } from "@_types";
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
return (await getVersionsData()).versions.flatMap(version => {
|
return (await getVersionsData()).versions.flatMap(version => {
|
||||||
|
|
@ -23,12 +24,12 @@ const details = module.details
|
||||||
description="Quickshell Type Documentation"
|
description="Quickshell Type Documentation"
|
||||||
>
|
>
|
||||||
<div class="docs-content">
|
<div class="docs-content">
|
||||||
<hr />
|
<hr>
|
||||||
<h2 class="typedocs-title">{module.name} Definitions</h2>
|
<h2 class="typedocs-title">{module.name} Definitions</h2>
|
||||||
<section>
|
<section>
|
||||||
<span>{module.description}</span>
|
<span>{module.description}</span>
|
||||||
<div class="root-nav" data-pagefind-ignore>
|
<div class="root-nav" data-pagefind-ignore>
|
||||||
{module.types.map(type =>
|
{module.types.map((type: TypeData) =>
|
||||||
(
|
(
|
||||||
<div class="root-nav-entry">
|
<div class="root-nav-entry">
|
||||||
<a class="root-nav-link" href={`/docs/${version.name}/types/${module.name}/${type.name}`}>
|
<a class="root-nav-link" href={`/docs/${version.name}/types/${module.name}/${type.name}`}>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
import DocsLayout from "@layouts/DocsLayout.astro";
|
import DocsLayout from "@layouts/DocsLayout.astro";
|
||||||
import { getVersionsData } from "@config/io/generateTypeData";
|
import { getVersionsData } from "@config/io/generateTypeData";
|
||||||
|
import type { ModuleData } from "@_types";
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
return (await getVersionsData()).versions.map(version => ({
|
return (await getVersionsData()).versions.map(version => ({
|
||||||
|
|
@ -11,14 +12,18 @@ export async function getStaticPaths() {
|
||||||
|
|
||||||
const { version } = Astro.props;
|
const { version } = Astro.props;
|
||||||
---
|
---
|
||||||
<DocsLayout title="Quickshell Module Listing" description="Quickshell Type Documentation">
|
|
||||||
|
<DocsLayout
|
||||||
|
title="Quickshell Module Listing"
|
||||||
|
description="Quickshell Type Documentation"
|
||||||
|
>
|
||||||
<div class="docs-content">
|
<div class="docs-content">
|
||||||
<hr/>
|
<hr>
|
||||||
<h2>Module Listing</h2>
|
<h2>Module Listing</h2>
|
||||||
<section>
|
<section>
|
||||||
<span>All modules included with Quickshell</span>
|
<span>All modules included with Quickshell</span>
|
||||||
<div class="root-nav" data-pagefind-ignore>
|
<div class="root-nav" data-pagefind-ignore>
|
||||||
{version.modules.map(module => (
|
{version.modules.map((module: ModuleData) => (
|
||||||
<div class="root-nav-entry">
|
<div class="root-nav-entry">
|
||||||
<a class="root-nav-link" href={`/docs/${version.name}/types/${module.name}`}>
|
<a class="root-nav-link" href={`/docs/${version.name}/types/${module.name}`}>
|
||||||
{module.name}
|
{module.name}
|
||||||
|
|
|
||||||
|
|
@ -8,42 +8,52 @@ const defaultVersion = (await getVersionsData()).default;
|
||||||
|
|
||||||
const title = "Quickshell";
|
const title = "Quickshell";
|
||||||
---
|
---
|
||||||
<BaseLayout title={title} description="A fully user customizable desktop shell" image="/quickshell.png">
|
|
||||||
|
<BaseLayout
|
||||||
|
title={title}
|
||||||
|
description="A fully user customizable desktop shell"
|
||||||
|
image="/quickshell.png"
|
||||||
|
>
|
||||||
<!--<a class="main-page-banner" href="/changelog">
|
<!--<a class="main-page-banner" href="/changelog">
|
||||||
Quickshell 0.2.1 has been released! | 2025-10-11
|
Quickshell 0.2.1 has been released! | 2025-10-11
|
||||||
</a>-->
|
</a>-->
|
||||||
<div class="main-page_hero" data-pagefind-ignore>
|
<div class="main-page_hero" data-pagefind-ignore>
|
||||||
<div class="titlebox">
|
<div class="titlebox">
|
||||||
<img src="/favicon.svg" alt="Quickshell"/>
|
<img src="/favicon.svg" alt="Quickshell">
|
||||||
<h1 class="gradient-text">Quickshell</h1>
|
<h1 class="gradient-text">Quickshell</h1>
|
||||||
</div>
|
</div>
|
||||||
<section class="main-page_hero-text">
|
<section class="main-page_hero-text">
|
||||||
<h2>building blocks for your desktop</h2>
|
<h2>building blocks for your desktop</h2>
|
||||||
</section>
|
</section>
|
||||||
<Marquee/>
|
<Marquee />
|
||||||
<section class="about">
|
<section class="about">
|
||||||
<div class="about-txt">
|
<div class="about-txt">
|
||||||
<p>
|
<p>
|
||||||
Quickshell is a toolkit for building status bars, widgets, lockscreens,
|
Quickshell is a toolkit for building status bars, widgets,
|
||||||
and other desktop components using QtQuick. It can be used alongside your
|
lockscreens, and other desktop components using QtQuick. It can be
|
||||||
wayland compositor or window manager to build a complete desktop environment.
|
used alongside your wayland compositor or window manager to build a
|
||||||
|
complete desktop environment.
|
||||||
<br class="about-break">
|
<br class="about-break">
|
||||||
<br class="about-break">
|
<br class="about-break">
|
||||||
<a href="/about">More information</a>
|
<a href="/about">More information</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="about-buttons">
|
<div class="about-buttons">
|
||||||
<a href={`/docs/${defaultVersion}/guide/install-setup`} class="main-page_link-card">
|
<a
|
||||||
|
href={`/docs/${defaultVersion}/guide/install-setup`}
|
||||||
|
class="main-page_link-card"
|
||||||
|
>
|
||||||
<h3>Install</h3>
|
<h3>Install</h3>
|
||||||
</a>
|
</a>
|
||||||
<a href={`/docs/${defaultVersion}/types`} class="main-page_link-card main-page_bluecard">
|
<a
|
||||||
|
href={`/docs/${defaultVersion}/types`}
|
||||||
|
class="main-page_link-card main-page_bluecard"
|
||||||
|
>
|
||||||
<h3>Documentation</h3>
|
<h3>Documentation</h3>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="featurelist-section">
|
<section class="featurelist-section"><FeatureList /></section>
|
||||||
<FeatureList/>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
<Footer class="frontpage-footer"/>
|
<Footer class="frontpage-footer" />
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
.accordion {
|
.accordion {
|
||||||
& summary {
|
& summary {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
transition: background-color 0.15s ease-out;
|
transition: background-color var(--theme-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
& .accordion-container {
|
& .accordion-container {
|
||||||
|
|
@ -12,7 +12,9 @@
|
||||||
|
|
||||||
& .accordion-container.animate {
|
& .accordion-container.animate {
|
||||||
/* this somehow breaks if both min AND max aren't animated */
|
/* this somehow breaks if both min AND max aren't animated */
|
||||||
transition: min-height 0.3s ease, max-height 0.3s ease;
|
transition:
|
||||||
|
min-height 0.3s ease,
|
||||||
|
max-height 0.3s ease;
|
||||||
min-height: var(--height);
|
min-height: var(--height);
|
||||||
max-height: var(--height);
|
max-height: var(--height);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,18 +12,22 @@
|
||||||
.featurelist-item {
|
.featurelist-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.618rem;
|
gap: var(--xs);
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-block: 0.618rem;
|
margin-block: var(--xs);
|
||||||
border-radius: 9px;
|
border-radius: var(--radius-md);
|
||||||
background-color: hsl(var(--blue) 60% 98%);
|
background-color: hsl(var(--blue) 60% 98%);
|
||||||
padding: 0.618rem;
|
padding: 0.618rem;
|
||||||
border: 1px solid hsl(var(--blue) 9% 75%);
|
border: 1px solid hsl(var(--blue) 9% 75%);
|
||||||
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
border-color var(--theme-transition);
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0.618rem;
|
inset: var(--xs);
|
||||||
background-image: radial-gradient(
|
background-image: radial-gradient(
|
||||||
hsl(var(--blue) 9% 75%) 1px,
|
hsl(var(--blue) 9% 75%) 1px,
|
||||||
transparent 1px
|
transparent 1px
|
||||||
|
|
@ -33,7 +37,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark .featurelist-item {
|
html.dark .featurelist-item,
|
||||||
|
html:has(input#theme-manual-toggle:checked) .featurelist-item {
|
||||||
background-color: hsl(var(--blue) 100% 81% / 0.05);
|
background-color: hsl(var(--blue) 100% 81% / 0.05);
|
||||||
border-color: hsl(0deg 0% 100% / 0.05);
|
border-color: hsl(0deg 0% 100% / 0.05);
|
||||||
|
|
||||||
|
|
@ -46,18 +51,22 @@ html.dark .featurelist-item {
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature-text {
|
.feature-text {
|
||||||
margin: 1rem 0;
|
margin: var(--sm) 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2em;
|
||||||
|
|
||||||
& .feature-title {
|
& .feature-title {
|
||||||
margin-bottom: 0.517rem;
|
margin-bottom: 0.517rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
& .feature-subtitle {
|
& .feature-subtitle {
|
||||||
color: #303030;
|
color: #303030;
|
||||||
|
transition: color var(--theme-transition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark .feature-text {
|
html.dark .feature-text,
|
||||||
|
html:has(input#theme-manual-toggle:checked) .feature-text {
|
||||||
& .feature-subtitle {
|
& .feature-subtitle {
|
||||||
color: #afafaf;
|
color: #afafaf;
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +81,8 @@ html.dark .feature-text {
|
||||||
& video {
|
& video {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
aspect-ratio: 16 / 9;
|
aspect-ratio: 16 / 9;
|
||||||
border-radius: 0.681rem;
|
border-radius: var(--radius-sm);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
& .shiki {
|
& .shiki {
|
||||||
|
|
@ -80,6 +90,7 @@ html.dark .feature-text {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
/*font-size: 0.55rem;*/
|
/*font-size: 0.55rem;*/
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
& .showcase-desktop {
|
& .showcase-desktop {
|
||||||
|
|
@ -98,8 +109,13 @@ html.dark .feature-text {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html:not(.dark) .feature-showcase .shiki,
|
html:not(.dark):not(:has(input#theme-manual-toggle:checked))
|
||||||
html:not(.dark) .feature-showcase .shiki span {
|
.feature-showcase
|
||||||
|
.shiki,
|
||||||
|
html:not(.dark):not(:has(input#theme-manual-toggle:checked))
|
||||||
|
.feature-showcase
|
||||||
|
.shiki
|
||||||
|
span {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,6 +134,7 @@ html:not(.dark) .feature-showcase .shiki span {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
& .cloud-center img {
|
& .cloud-center img {
|
||||||
width: 80px;
|
width: 80px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
|
|
@ -140,6 +157,7 @@ html:not(.dark) .feature-showcase .shiki span {
|
||||||
& > div {
|
& > div {
|
||||||
transform: rotate(0deg);
|
transform: rotate(0deg);
|
||||||
animation: counter-spin 40s linear infinite;
|
animation: counter-spin 40s linear infinite;
|
||||||
|
|
||||||
& .feature-icon {
|
& .feature-icon {
|
||||||
width: 80px;
|
width: 80px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
|
|
@ -149,26 +167,34 @@ html:not(.dark) .feature-showcase .shiki span {
|
||||||
&.wayland {
|
&.wayland {
|
||||||
transform: translate(-50%, 0) rotate(0deg);
|
transform: translate(-50%, 0) rotate(0deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.hyprland {
|
&.hyprland {
|
||||||
transform: translate(-50%, 0) rotate(72deg);
|
transform: translate(-50%, 0) rotate(72deg);
|
||||||
|
|
||||||
& .feature-icon {
|
& .feature-icon {
|
||||||
transform: rotate(-72deg);
|
transform: rotate(-72deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.pipewire {
|
&.pipewire {
|
||||||
transform: translate(-50%, 0) rotate(144deg);
|
transform: translate(-50%, 0) rotate(144deg);
|
||||||
|
|
||||||
& .feature-icon {
|
& .feature-icon {
|
||||||
transform: rotate(-144deg);
|
transform: rotate(-144deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.x-org {
|
&.x-org {
|
||||||
transform: translate(-50%, 0) rotate(216deg);
|
transform: translate(-50%, 0) rotate(216deg);
|
||||||
|
|
||||||
& .feature-icon {
|
& .feature-icon {
|
||||||
transform: rotate(-216deg);
|
transform: rotate(-216deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.sway {
|
&.sway {
|
||||||
transform: translate(-50%, 0) rotate(288deg);
|
transform: translate(-50%, 0) rotate(288deg);
|
||||||
|
|
||||||
& .feature-icon {
|
& .feature-icon {
|
||||||
transform: rotate(-288deg);
|
transform: rotate(-288deg);
|
||||||
}
|
}
|
||||||
|
|
@ -180,6 +206,7 @@ html:not(.dark) .feature-showcase .shiki span {
|
||||||
from {
|
from {
|
||||||
transform: rotate(0deg);
|
transform: rotate(0deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
transform: rotate(360deg);
|
transform: rotate(360deg);
|
||||||
}
|
}
|
||||||
|
|
@ -189,6 +216,7 @@ html:not(.dark) .feature-showcase .shiki span {
|
||||||
from {
|
from {
|
||||||
transform: rotate(0deg);
|
transform: rotate(0deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
transform: rotate(-360deg);
|
transform: rotate(-360deg);
|
||||||
}
|
}
|
||||||
|
|
@ -213,33 +241,42 @@ html:not(.dark) .feature-showcase .shiki span {
|
||||||
width: auto;
|
width: auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature-text {
|
.feature-text {
|
||||||
margin: 0 2.218rem;
|
margin: 0 2.218rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.featurelist-item {
|
.featurelist-item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 1.217rem;
|
padding: 1.217rem;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
.featurelist-item.right {
|
.featurelist-item.right {
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature-showcase {
|
.feature-showcase {
|
||||||
height: 22rem;
|
height: 22rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature-text {
|
.feature-text {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature-showcase {
|
.feature-showcase {
|
||||||
width: auto;
|
width: auto;
|
||||||
aspect-ratio: 16 / 9;
|
aspect-ratio: 16 / 9;
|
||||||
|
|
||||||
& video {
|
& video {
|
||||||
scale: 1;
|
scale: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
& .shiki {
|
& .shiki {
|
||||||
font-size: 0.93rem;
|
font-size: 0.93rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature-cloud {
|
.feature-cloud {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 2.217rem;
|
gap: var(--xl);
|
||||||
font-size: 1.874rem;
|
font-size: var(--lg);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin-inline: 0.618rem;
|
margin-inline: var(--sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
.marquee-button {
|
.marquee-button {
|
||||||
|
|
@ -20,36 +20,63 @@
|
||||||
left: 2px;
|
left: 2px;
|
||||||
right: 2px;
|
right: 2px;
|
||||||
height: 3px;
|
height: 3px;
|
||||||
background-color: hsl(var(--accent-400) / 0.3);
|
background-color: hsla(var(--accent-400) / 0.3);
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.marquee {
|
.marquee {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-block: 1.618rem;
|
margin-block: var(--xl);
|
||||||
justify-content: center;
|
justify-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
overflow: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.6s ease;
|
||||||
|
min-height: 200px; /* placeholder height */
|
||||||
|
|
||||||
|
&.initialized {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.marquee-content {
|
.marquee-content {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
will-change: transform;
|
||||||
|
transform: translateX(0);
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
|
.initialized & {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.marquee-item {
|
.marquee-item {
|
||||||
flex: 1 0 100%;
|
position: relative;
|
||||||
transition: transform 0.3s cubic-bezier(0.46, 0.03, 0.52, 0.96);
|
|
||||||
transform: translateX(var(--scroll));
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--md);
|
||||||
padding-inline: 0.5rem;
|
padding-inline: 0.5rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
will-change: opacity;
|
||||||
|
|
||||||
& > div {
|
& > * {
|
||||||
|
z-index: 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
& video {
|
||||||
|
position: relative;
|
||||||
max-width: 75rem;
|
max-width: 75rem;
|
||||||
width: 100%;
|
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,34 +85,38 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.marquee-item-content {
|
.marquee-item-content {
|
||||||
border-radius: 6px;
|
border-radius: var(--radius-sm);
|
||||||
|
will-change: transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
.marquee-scroll {
|
.marquee-scroll {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 85rem;
|
max-width: 85rem;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
|
||||||
transition:
|
|
||||||
background-color 0.3s,
|
|
||||||
opacity 0.3s;
|
|
||||||
z-index: 10;
|
|
||||||
user-select: none;
|
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
opacity var(--theme-transition);
|
||||||
|
z-index: 20;
|
||||||
|
user-select: none;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
padding-inline: 1rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.marquee-scroll-arrow {
|
.marquee-scroll-arrow {
|
||||||
max-width: 8rem;
|
width: 8rem;
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
width: 2.5rem;
|
width: 2.5rem;
|
||||||
|
|
@ -95,10 +126,12 @@
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
transition: opacity 0.3s ease;
|
transition: opacity 0.3s ease;
|
||||||
|
backdrop-filter: blur(var(--2xs));
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
}
|
}
|
||||||
|
|
@ -132,14 +165,10 @@
|
||||||
@media not (min-width: 83rem) {
|
@media not (min-width: 83rem) {
|
||||||
.marquee-scroll-arrow {
|
.marquee-scroll-arrow {
|
||||||
height: unset;
|
height: unset;
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
background-color: #55555580;
|
background-color: #55555580;
|
||||||
border-radius: 0.2rem;
|
border-radius: var(--radius-xs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.marquee-scroll {
|
|
||||||
width: 92%;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -116,3 +116,61 @@
|
||||||
--percent-nav-root_filled: 65%;
|
--percent-nav-root_filled: 65%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes ping {
|
||||||
|
75%,
|
||||||
|
100% {
|
||||||
|
transform: scale(2);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
50% {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounce {
|
||||||
|
0% {
|
||||||
|
transform: none;
|
||||||
|
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: translateY(-12%);
|
||||||
|
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
||||||
|
color: hsla(var(--green) 100 69 / 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: none;
|
||||||
|
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade {
|
||||||
|
0% {
|
||||||
|
transform: scale(0.75);
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--animate-spin: spin 1s linear infinite;
|
||||||
|
--animate-ping: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
|
||||||
|
--animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||||
|
--animate-bounce: bounce 0.6s var(--ease-out) forwards;
|
||||||
|
--animate-fade: fade 0.3s cubic-bezier(0.4, 0, 0.6, 1);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,129 +1,18 @@
|
||||||
html {
|
html {
|
||||||
font-family: "Rubik Variable", Inter, system-ui, Avenir, Helvetica, Arial,
|
font-family:
|
||||||
sans-serif;
|
"Rubik Variable", Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.272;
|
line-height: 1.272;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
||||||
height: 100svh;
|
height: 100svh;
|
||||||
|
/* width: 100svw; causes horizontal overflow due to the scrollbar*/
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
font-synthesis: none;
|
font-synthesis: none;
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
color-scheme: light dark;
|
|
||||||
/* accent */
|
|
||||||
--green: 141deg;
|
|
||||||
--accent-400: var(--green) 90% 57%;
|
|
||||||
--accent-500: var(--green) 90% 47%;
|
|
||||||
--accent-600: var(--green) 88% 40%;
|
|
||||||
--accent-700: var(--green) 70% 40%;
|
|
||||||
|
|
||||||
/* secondary */
|
|
||||||
--blue: 224deg;
|
|
||||||
--secondary-400: var(--blue) 100% 68%;
|
|
||||||
--secondary-500: var(--blue) 100% 58%;
|
|
||||||
--secondary-600: var(--blue) 53% 41%;
|
|
||||||
--secondary-700: var(--blue) 43% 31%;
|
|
||||||
--secondary-800: var(--blue) 23% 21%;
|
|
||||||
--secondary-900: var(--blue) 44% 7%;
|
|
||||||
|
|
||||||
/* primary */
|
|
||||||
--white: 194deg;
|
|
||||||
--bg-400: var(--white) 10% 95%;
|
|
||||||
--bg-500: var(--white) 5% 90%;
|
|
||||||
--bg-600: var(--white) 5% 76%;
|
|
||||||
--bg-700: var(--white) 5% 56%;
|
|
||||||
--bg-800: var(--white) 5% 36%;
|
|
||||||
--bg-900: var(--white) 5% 16%;
|
|
||||||
|
|
||||||
/* docs */
|
|
||||||
--background: var(--bg-500);
|
|
||||||
--text: var(--white) 0% 0%;
|
|
||||||
--text-dark: var(--white) 0% 18%;
|
|
||||||
--text-darker: var(--white) 0% 30%;
|
|
||||||
--link: var(--green) 48% 40%;
|
|
||||||
--toc-link: var(--green) 74% 30%;
|
|
||||||
--toc-link-active: var(--green) 80% 38%;
|
|
||||||
--prop-color: 350deg 78% 70%;
|
|
||||||
--prop-link-color: 350deg 78% 60%;
|
|
||||||
--func-color: 50deg 68% 50%;
|
|
||||||
--func-link-color: 50deg 58% 55%;
|
|
||||||
--signal-color: 270deg 78% 70%;
|
|
||||||
--signal-link-color: 270deg 85% 60%;
|
|
||||||
--var-color: 190deg 78% 70%;
|
|
||||||
--var-link-color: 190deg 85% 60%;
|
|
||||||
--inner-param-color: 215deg 80% 27%;
|
|
||||||
--inner-param-border-color: 215deg 50% 50%;
|
|
||||||
--nav-hovered-bkg: var(--blue) 100% 87%;
|
|
||||||
--nav-hovered-weak-bkg: var(--blue) 100% 91%;
|
|
||||||
--nav-selected-bkg: var(--blue) 100% 90%;
|
|
||||||
--nav-selected-hovered-bkg: var(--blue) 100% 85%;
|
|
||||||
--nav-selected-text: var(--blue) 60% 60%;
|
|
||||||
--nav-indicator-bkg: var(--blue) 45% 80%;
|
|
||||||
--toc-hovered-bkg: 0deg 0% 0% / 0.1;
|
|
||||||
--overlay-bkg: var(--blue) 25% 93%;
|
|
||||||
--overlay-bkg-border: var(--blue) 10% 75%;
|
|
||||||
--footer-bkg: var(--blue) 8% 87%;
|
|
||||||
--footer-bkg-border: var(--blue) 32% 84%;
|
|
||||||
}
|
|
||||||
|
|
||||||
html.dark {
|
|
||||||
/* accent */
|
|
||||||
--green: 141deg;
|
|
||||||
--accent-400: var(--green) 100% 67%;
|
|
||||||
--accent-500: var(--green) 95% 55%;
|
|
||||||
--accent-600: var(--green) 90% 40%;
|
|
||||||
--accent-700: var(--green) 80% 30%;
|
|
||||||
|
|
||||||
/* secondary */
|
|
||||||
--white: 194deg;
|
|
||||||
--secondary-400: var(--white) 33% 100%;
|
|
||||||
--secondary-500: var(--white) 33% 96%;
|
|
||||||
--secondary-600: var(--white) 33% 76%;
|
|
||||||
--secondary-700: var(--white) 33% 56%;
|
|
||||||
--secondary-800: var(--white) 35% 36%;
|
|
||||||
--secondary-900: var(--white) 44% 7%;
|
|
||||||
|
|
||||||
/* primary */
|
|
||||||
--blue: 224deg;
|
|
||||||
--bg-400: var(--blue) 90% 65%;
|
|
||||||
--bg-500: var(--blue) 83% 45%;
|
|
||||||
--bg-700: var(--blue) 82% 25%;
|
|
||||||
--bg-800: var(--blue) 82% 15%;
|
|
||||||
--bg-900: var(--blue) 82% 3%;
|
|
||||||
|
|
||||||
/* docs */
|
|
||||||
--background: var(--bg-900);
|
|
||||||
--text: var(--white) 0% 100%;
|
|
||||||
--text-dark: var(--white) 0% 70%;
|
|
||||||
--text-darker: var(--white) 0% 40%;
|
|
||||||
--link: var(--green) 60% 44%;
|
|
||||||
--toc-link: var(--green) 74% 40%;
|
|
||||||
--toc-link-active: var(--green) 80% 60%;
|
|
||||||
--prop-color: 350deg 78% 70%;
|
|
||||||
--prop-link-color: 350deg 78% 60%;
|
|
||||||
--func-color: 50deg 78% 70%;
|
|
||||||
--func-link-color: 50deg 78% 60%;
|
|
||||||
--signal-color: 270deg 78% 70%;
|
|
||||||
--signal-link-color: 270deg 85% 60%;
|
|
||||||
--var-color: 190deg 78% 70%;
|
|
||||||
--var-link-color: 190deg 85% 60%;
|
|
||||||
--inner-param-color: 215deg 60% 70%;
|
|
||||||
--inner-param-border-color: 215deg 26% 46%;
|
|
||||||
--inner-param-color: 215deg 60% 70%;
|
|
||||||
--nav-hovered-bkg: var(--blue) 40% 10%;
|
|
||||||
--nav-hovered-weak-bkg: var(--blue) 35% 8%;
|
|
||||||
--nav-selected-bkg: var(--blue) 40% 13%;
|
|
||||||
--nav-selected-hovered-bkg: var(--blue) 40% 17%;
|
|
||||||
--nav-selected-text: var(--blue) 100% 70%;
|
|
||||||
--nav-indicator-bkg: var(--blue) 30% 30%;
|
|
||||||
--toc-hovered-bkg: 0deg 0% 100% / 0.07;
|
|
||||||
--overlay-bkg: var(--blue) 75% 5%;
|
|
||||||
--overlay-bkg-border: var(--blue) 45% 15%;
|
|
||||||
--footer-bkg: var(--blue) 66% 5%;
|
|
||||||
--footer-bkg-border: var(--blue) 75% 21%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
|
@ -131,6 +20,7 @@ html.dark {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
/* transition: all 0.15s var(--ease-in-out); */
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
pre.shiki {
|
pre.shiki {
|
||||||
margin-block: 1.618rem;
|
margin-block: var(--lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
:where(p, li):has(> code) code {
|
:where(p, li):has(> code) code {
|
||||||
padding-inline: 0.272rem;
|
padding-inline: var(--sm);
|
||||||
border-radius: 0.272rem;
|
border-radius: var(--radius-xs);
|
||||||
color: hsl(var(--blue) 100% 69%);
|
color: hsl(var(--blue) 100 69);
|
||||||
background-color: hsl(var(--blue) 85% 35% / 0.1);
|
background-color: hsla(var(--blue) 85 35 / 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.shiki,
|
.shiki,
|
||||||
|
|
@ -16,7 +16,9 @@ pre.shiki {
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark .shiki,
|
html.dark .shiki,
|
||||||
html.dark .shiki span {
|
html.dark .shiki span,
|
||||||
|
html:has(input#theme-manual-toggle:checked) .shiki,
|
||||||
|
html:has(input#theme-manual-toggle:checked) .shiki span {
|
||||||
color: var(--shiki-dark);
|
color: var(--shiki-dark);
|
||||||
background-color: var(--shiki-dark-bg);
|
background-color: var(--shiki-dark-bg);
|
||||||
}
|
}
|
||||||
|
|
@ -26,8 +28,11 @@ pre {
|
||||||
border-radius: 0.618rem;
|
border-radius: 0.618rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-wrap: wrap;
|
text-wrap: wrap;
|
||||||
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
color var(--theme-transition);
|
||||||
|
|
||||||
& > button {
|
& .copy-button {
|
||||||
all: unset;
|
all: unset;
|
||||||
width: 2rem;
|
width: 2rem;
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
|
|
@ -41,17 +46,51 @@ pre {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
color: hsl(var(--blue) 100% 69%);
|
color: hsla(var(--blue) 100 69 / 0.33);
|
||||||
background-color: hsl(var(--blue) 85% 35% / 0.1);
|
background-color: hsla(var(--blue) 85 35 / 0.01);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: color 0.25s;
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
color var(--theme-transition);
|
||||||
|
z-index: 10;
|
||||||
|
|
||||||
|
& svg {
|
||||||
|
position: absolute;
|
||||||
|
transition:
|
||||||
|
transform 0.3s var(--ease-in-out),
|
||||||
|
opacity 0.3s var(--ease-in-out);
|
||||||
|
}
|
||||||
|
|
||||||
|
& .check-icon {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.5);
|
||||||
|
color: hsl(var(--green) 100 69);
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: hsl(var(--blue) 100% 75%);
|
color: hsla(var(--blue) 100 75 / 0.75);
|
||||||
|
background-color: hsla(var(--blue) 85 35 / 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.copied {
|
&.copied {
|
||||||
animation: pulseGreen 0.5s cubic-bezier(0, 1, 0.6, 1);
|
& .copy-icon {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
& .check-icon {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.shiki {
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
|
||||||
|
&:hover .copy-button {
|
||||||
|
transition: background-color var(--theme-transition);
|
||||||
|
background-color: hsla(var(--blue) 85 35 / 0.07);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,118 @@
|
||||||
|
html:not(.dark):not(:has(input#theme-manual-toggle:checked)) {
|
||||||
|
color-scheme: light dark;
|
||||||
|
/* accent */
|
||||||
|
--green: 141deg;
|
||||||
|
--accent-400: var(--green) 90% 57%;
|
||||||
|
--accent-500: var(--green) 90% 47%;
|
||||||
|
--accent-600: var(--green) 88% 40%;
|
||||||
|
--accent-700: var(--green) 70% 35%;
|
||||||
|
|
||||||
|
/* secondary */
|
||||||
|
--blue: 224deg;
|
||||||
|
--secondary-400: var(--blue) 100% 68%;
|
||||||
|
--secondary-500: var(--blue) 100% 58%;
|
||||||
|
--secondary-600: var(--blue) 53% 41%;
|
||||||
|
--secondary-700: var(--blue) 43% 31%;
|
||||||
|
--secondary-800: var(--blue) 23% 21%;
|
||||||
|
--secondary-900: var(--blue) 44% 7%;
|
||||||
|
|
||||||
|
/* primary */
|
||||||
|
--white: 194deg;
|
||||||
|
--bg-400: var(--white) 10% 98%;
|
||||||
|
--bg-500: var(--white) 10% 95%;
|
||||||
|
--bg-600: var(--white) 8% 88%;
|
||||||
|
--bg-700: var(--white) 8% 78%;
|
||||||
|
--bg-800: var(--white) 5% 56%;
|
||||||
|
--bg-900: var(--white) 5% 16%;
|
||||||
|
|
||||||
|
/* docs */
|
||||||
|
--background: var(--bg-400);
|
||||||
|
--text: var(--white) 0% 10%;
|
||||||
|
--text-dark: var(--white) 0% 25%;
|
||||||
|
--text-darker: var(--white) 0% 40%;
|
||||||
|
--link: var(--green) 60% 35%;
|
||||||
|
--toc-link: var(--white) 0% 40%;
|
||||||
|
--toc-link-active: var(--green) 60% 35%;
|
||||||
|
--prop-color: 350deg 78% 65%;
|
||||||
|
--prop-link-color: 350deg 78% 45%;
|
||||||
|
--func-color: 50deg 78% 45%;
|
||||||
|
--func-link-color: 50deg 85% 30%;
|
||||||
|
--signal-color: 270deg 60% 65%;
|
||||||
|
--signal-link-color: 270deg 75% 45%;
|
||||||
|
--var-color: 190deg 78% 65%;
|
||||||
|
--var-link-color: 190deg 85% 40%;
|
||||||
|
--inner-param-color: 215deg 80% 27%;
|
||||||
|
--inner-param-border-color: 215deg 50% 50%;
|
||||||
|
--nav-hovered-bkg: var(--blue) 100% 94%;
|
||||||
|
--nav-hovered-weak-bkg: var(--blue) 100% 96%;
|
||||||
|
--nav-selected-bkg: var(--blue) 100% 92%;
|
||||||
|
--nav-selected-hovered-bkg: var(--blue) 100% 88%;
|
||||||
|
--nav-selected-text: var(--blue) 70% 45%;
|
||||||
|
--nav-indicator-bkg: var(--blue) 45% 80%;
|
||||||
|
--toc-hovered-bkg: 0deg 0% 0% / 0.05;
|
||||||
|
--overlay-bkg: var(--white) 10% 98%;
|
||||||
|
--overlay-bkg-border: var(--white) 10% 85%;
|
||||||
|
--footer-bkg: var(--white) 10% 95%;
|
||||||
|
--footer-bkg-border: var(--white) 10% 88%;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark,
|
||||||
|
html:has(input#theme-manual-toggle:checked) {
|
||||||
|
/* accent */
|
||||||
|
--green: 141deg;
|
||||||
|
--accent-400: var(--green) 100% 67%;
|
||||||
|
--accent-500: var(--green) 95% 55%;
|
||||||
|
--accent-600: var(--green) 90% 40%;
|
||||||
|
--accent-700: var(--green) 80% 30%;
|
||||||
|
|
||||||
|
/* secondary */
|
||||||
|
--white: 194deg;
|
||||||
|
--secondary-400: var(--white) 33% 100%;
|
||||||
|
--secondary-500: var(--white) 33% 96%;
|
||||||
|
--secondary-600: var(--white) 33% 76%;
|
||||||
|
--secondary-700: var(--white) 33% 56%;
|
||||||
|
--secondary-800: var(--white) 35% 36%;
|
||||||
|
--secondary-900: var(--white) 44% 7%;
|
||||||
|
|
||||||
|
/* primary */
|
||||||
|
--blue: 224deg;
|
||||||
|
--bg-400: var(--blue) 90% 65%;
|
||||||
|
--bg-500: var(--blue) 83% 45%;
|
||||||
|
--bg-700: var(--blue) 82% 25%;
|
||||||
|
--bg-800: var(--blue) 82% 15%;
|
||||||
|
--bg-900: var(--blue) 82% 3%;
|
||||||
|
|
||||||
|
/* docs */
|
||||||
|
--background: var(--bg-900);
|
||||||
|
--text: var(--white) 0% 100%;
|
||||||
|
--text-dark: var(--white) 0% 70%;
|
||||||
|
--text-darker: var(--white) 0% 40%;
|
||||||
|
--link: var(--green) 60% 44%;
|
||||||
|
--toc-link: var(--green) 74% 40%;
|
||||||
|
--toc-link-active: var(--green) 80% 60%;
|
||||||
|
--prop-color: 350deg 78% 70%;
|
||||||
|
--prop-link-color: 350deg 78% 60%;
|
||||||
|
--func-color: 50deg 78% 70%;
|
||||||
|
--func-link-color: 50deg 78% 60%;
|
||||||
|
--signal-color: 270deg 78% 70%;
|
||||||
|
--signal-link-color: 270deg 85% 60%;
|
||||||
|
--var-color: 190deg 78% 70%;
|
||||||
|
--var-link-color: 190deg 85% 60%;
|
||||||
|
--inner-param-color: 215deg 60% 70%;
|
||||||
|
--inner-param-border-color: 215deg 26% 46%;
|
||||||
|
--nav-hovered-bkg: var(--blue) 40% 10%;
|
||||||
|
--nav-hovered-weak-bkg: var(--blue) 35% 8%;
|
||||||
|
--nav-selected-bkg: var(--blue) 40% 13%;
|
||||||
|
--nav-selected-hovered-bkg: var(--blue) 40% 17%;
|
||||||
|
--nav-selected-text: var(--blue) 100% 70%;
|
||||||
|
--nav-indicator-bkg: var(--blue) 30% 30%;
|
||||||
|
--toc-hovered-bkg: 0deg 0% 100% / 0.07;
|
||||||
|
--overlay-bkg: var(--blue) 75% 5%;
|
||||||
|
--overlay-bkg-border: var(--blue) 45% 15%;
|
||||||
|
--footer-bkg: var(--blue) 66% 5%;
|
||||||
|
--footer-bkg-border: var(--blue) 75% 21%;
|
||||||
|
}
|
||||||
|
|
||||||
.typeprop-link {
|
.typeprop-link {
|
||||||
color: hsl(var(--prop-link-color));
|
color: hsl(var(--prop-link-color));
|
||||||
|
|
||||||
|
|
|
||||||
6
src/styles/css-config/entry.css
Normal file
6
src/styles/css-config/entry.css
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
@import "normalize.css";
|
||||||
|
@import "vars.css";
|
||||||
|
@import "animations.css";
|
||||||
|
@import "base.css";
|
||||||
|
@import "code.css";
|
||||||
|
@import "colors.css";
|
||||||
475
src/styles/css-config/normalize.css
vendored
Normal file
475
src/styles/css-config/normalize.css
vendored
Normal file
|
|
@ -0,0 +1,475 @@
|
||||||
|
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
|
||||||
|
/**
|
||||||
|
* 1. Set default font family to sans-serif.
|
||||||
|
* 2. Prevent iOS and IE text size adjust after device orientation change,
|
||||||
|
* without disabling user zoom.
|
||||||
|
*/
|
||||||
|
html {
|
||||||
|
font-family: "Inter", sans-serif;
|
||||||
|
/* 1 */
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
/* 2 */
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
/* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove default margin.
|
||||||
|
*/
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HTML5 display definitions
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* Correct `block` display not defined for any HTML5 element in IE 8/9.
|
||||||
|
* Correct `block` display not defined for `details` or `summary` in IE 10/11
|
||||||
|
* and Firefox.
|
||||||
|
* Correct `block` display not defined for `main` in IE 11.
|
||||||
|
*/
|
||||||
|
/* article, */
|
||||||
|
/* aside, */
|
||||||
|
details,
|
||||||
|
/* figcaption, */
|
||||||
|
/* figure, */
|
||||||
|
/* footer, */
|
||||||
|
/* header, */
|
||||||
|
/* hgroup, */
|
||||||
|
/* main, */
|
||||||
|
/* menu, */
|
||||||
|
/* nav, */
|
||||||
|
/* section, */
|
||||||
|
summary {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct `inline-block` display not defined in IE 8/9.
|
||||||
|
* 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
|
||||||
|
*/
|
||||||
|
audio,
|
||||||
|
canvas,
|
||||||
|
progress,
|
||||||
|
video {
|
||||||
|
display: inline-block;
|
||||||
|
/* 1 */
|
||||||
|
vertical-align: baseline;
|
||||||
|
/* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent modern browsers from displaying `audio` without controls.
|
||||||
|
* Remove excess height in iOS 5 devices.
|
||||||
|
*/
|
||||||
|
audio:not([controls]) {
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address `[hidden]` styling not present in IE 8/9/10.
|
||||||
|
* Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
|
||||||
|
*/
|
||||||
|
[hidden],
|
||||||
|
template {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Links
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* Remove the gray background color from active links in IE 10.
|
||||||
|
*/
|
||||||
|
a {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Improve readability of focused elements when they are also in an
|
||||||
|
* active/hover state.
|
||||||
|
*/
|
||||||
|
a:active,
|
||||||
|
a:hover {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text-level semantics
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* Address styling not present in IE 8/9/10/11, Safari, and Chrome.
|
||||||
|
*/
|
||||||
|
abbr[title] {
|
||||||
|
border-bottom: 1px dotted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
|
||||||
|
*/
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address styling not present in Safari and Chrome.
|
||||||
|
*/
|
||||||
|
dfn {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address variable `h1` font-size and margin within `section` and `article`
|
||||||
|
* contexts in Firefox 4+, Safari, and Chrome.
|
||||||
|
*/
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
margin: 0.67em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address styling not present in IE 8/9.
|
||||||
|
*/
|
||||||
|
mark {
|
||||||
|
background: #ff0;
|
||||||
|
color: var(--hl-onbackground);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address inconsistent and variable font size in all browsers.
|
||||||
|
*/
|
||||||
|
small {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
|
||||||
|
*/
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
font-size: 75%;
|
||||||
|
line-height: 0;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Embedded content
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* Remove border when inside `a` element in IE 8/9/10.
|
||||||
|
*/
|
||||||
|
img {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct overflow not hidden in IE 9/10/11.
|
||||||
|
*/
|
||||||
|
svg:not(:root) {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grouping content
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* Address margin not present in IE 8/9 and Safari.
|
||||||
|
*/
|
||||||
|
figure {
|
||||||
|
margin: 1em 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address differences between Firefox and other browsers.
|
||||||
|
*/
|
||||||
|
hr {
|
||||||
|
box-sizing: content-box;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contain overflow in all browsers.
|
||||||
|
*/
|
||||||
|
pre {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address odd `em`-unit font size rendering in all browsers.
|
||||||
|
*/
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
pre,
|
||||||
|
samp {
|
||||||
|
font-family: monospace, monospace;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forms
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* Known limitation: by default, Chrome and Safari on OS X allow very limited
|
||||||
|
* styling of `select`, unless a `border` property is set.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* 1. Correct color not being inherited.
|
||||||
|
* Known issue: affects color of disabled elements.
|
||||||
|
* 2. Correct font properties not being inherited.
|
||||||
|
* 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
|
||||||
|
*/
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
optgroup,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
color: inherit;
|
||||||
|
/* 1 */
|
||||||
|
font: inherit;
|
||||||
|
/* 2 */
|
||||||
|
margin: 0;
|
||||||
|
/* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address `overflow` set to `hidden` in IE 8/9/10/11.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address inconsistent `text-transform` inheritance for `button` and `select`.
|
||||||
|
* All other form control elements do not inherit `text-transform` values.
|
||||||
|
* Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
|
||||||
|
* Correct `select` style inheritance in Firefox.
|
||||||
|
*/
|
||||||
|
button,
|
||||||
|
select {
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||||
|
* and `video` controls.
|
||||||
|
* 2. Correct inability to style clickable `input` types in iOS.
|
||||||
|
* 3. Improve usability and consistency of cursor style between image-type
|
||||||
|
* `input` and others.
|
||||||
|
* 4. CUSTOM FOR WEBFLOW: Removed the input[type="submit"] selector to reduce
|
||||||
|
* specificity and defer to the .w-button selector
|
||||||
|
*/
|
||||||
|
button,
|
||||||
|
html input[type="button"],
|
||||||
|
input[type="reset"] {
|
||||||
|
-webkit-appearance: button;
|
||||||
|
/* 2 */
|
||||||
|
cursor: pointer;
|
||||||
|
/* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-set default cursor for disabled elements.
|
||||||
|
*/
|
||||||
|
button[disabled],
|
||||||
|
html input[disabled] {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove inner padding and border in Firefox 4+.
|
||||||
|
*/
|
||||||
|
button::-moz-focus-inner,
|
||||||
|
input::-moz-focus-inner {
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
|
||||||
|
* the UA stylesheet.
|
||||||
|
*/
|
||||||
|
input {
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It's recommended that you don't attempt to style these elements.
|
||||||
|
* Firefox's implementation doesn't respect box-sizing, padding, or width.
|
||||||
|
*
|
||||||
|
* 1. Address box sizing set to `content-box` in IE 8/9/10.
|
||||||
|
* 2. Remove excess padding in IE 8/9/10.
|
||||||
|
*/
|
||||||
|
input[type="checkbox"],
|
||||||
|
input[type="radio"] {
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* 1 */
|
||||||
|
padding: 0;
|
||||||
|
/* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix the cursor style for Chrome's increment/decrement buttons. For certain
|
||||||
|
* `font-size` values of the `input`, it causes the cursor style of the
|
||||||
|
* decrement button to change from `default` to `text`.
|
||||||
|
*/
|
||||||
|
input[type="number"]::-webkit-inner-spin-button,
|
||||||
|
input[type="number"]::-webkit-outer-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. CUSTOM FOR WEBFLOW: changed from `textfield` to `none` to normalize iOS rounded input
|
||||||
|
* 2. CUSTOM FOR WEBFLOW: box-sizing: content-box rule removed
|
||||||
|
* (similar to normalize.css >=4.0.0)
|
||||||
|
*/
|
||||||
|
input[type="search"] {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
/* 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove inner padding and search cancel button in Safari and Chrome on OS X.
|
||||||
|
* Safari (but not Chrome) clips the cancel button when the search input has
|
||||||
|
* padding (and `textfield` appearance).
|
||||||
|
*/
|
||||||
|
input[type="search"]::-webkit-search-cancel-button,
|
||||||
|
input[type="search"]::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define consistent border, margin, and padding.
|
||||||
|
*/
|
||||||
|
fieldset {
|
||||||
|
border: 1px solid #c0c0c0;
|
||||||
|
margin: 0 2px;
|
||||||
|
padding: 0.35em 0.625em 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct `color` not being inherited in IE 8/9/10/11.
|
||||||
|
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||||
|
*/
|
||||||
|
legend {
|
||||||
|
border: 0;
|
||||||
|
/* 1 */
|
||||||
|
padding: 0;
|
||||||
|
/* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove default vertical scrollbar in IE 8/9/10/11.
|
||||||
|
*/
|
||||||
|
textarea {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Don't inherit the `font-weight` (applied by a rule above).
|
||||||
|
* NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
|
||||||
|
*/
|
||||||
|
optgroup {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tables
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* Remove most spacing between table cells.
|
||||||
|
*/
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove default margins and padding on all basic HTML elements */
|
||||||
|
body,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
p,
|
||||||
|
blockquote,
|
||||||
|
pre,
|
||||||
|
a,
|
||||||
|
abbr,
|
||||||
|
acronym,
|
||||||
|
address,
|
||||||
|
big,
|
||||||
|
cite,
|
||||||
|
code,
|
||||||
|
del,
|
||||||
|
dfn,
|
||||||
|
em,
|
||||||
|
img,
|
||||||
|
ins,
|
||||||
|
kbd,
|
||||||
|
q,
|
||||||
|
s,
|
||||||
|
samp,
|
||||||
|
small,
|
||||||
|
strike,
|
||||||
|
strong,
|
||||||
|
sub,
|
||||||
|
sup,
|
||||||
|
tt,
|
||||||
|
var,
|
||||||
|
b,
|
||||||
|
u,
|
||||||
|
i,
|
||||||
|
center,
|
||||||
|
dl,
|
||||||
|
dt,
|
||||||
|
dd,
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
li,
|
||||||
|
fieldset,
|
||||||
|
form,
|
||||||
|
label,
|
||||||
|
legend,
|
||||||
|
table,
|
||||||
|
caption,
|
||||||
|
tbody,
|
||||||
|
tfoot,
|
||||||
|
thead,
|
||||||
|
tr,
|
||||||
|
th,
|
||||||
|
td,
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
canvas,
|
||||||
|
details,
|
||||||
|
embed,
|
||||||
|
figure,
|
||||||
|
figcaption,
|
||||||
|
footer,
|
||||||
|
header,
|
||||||
|
hgroup,
|
||||||
|
menu,
|
||||||
|
nav,
|
||||||
|
output,
|
||||||
|
ruby,
|
||||||
|
section,
|
||||||
|
summary,
|
||||||
|
time,
|
||||||
|
mark,
|
||||||
|
audio,
|
||||||
|
video {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
82
src/styles/css-config/vars.css
Normal file
82
src/styles/css-config/vars.css
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
html {
|
||||||
|
--scaleFactor: 1.618;
|
||||||
|
--wholestep: 1.618;
|
||||||
|
--halfstep: 1.272;
|
||||||
|
--quarterstep: 1.128;
|
||||||
|
--eighthstep: 1.062;
|
||||||
|
|
||||||
|
--wholestep-dec: 0.618;
|
||||||
|
--halfstep-dec: 0.272;
|
||||||
|
--quarterstep-dec: 0.128;
|
||||||
|
--eighthstep-dec: 0.062;
|
||||||
|
|
||||||
|
--md: 1em;
|
||||||
|
--sm: calc(1em / var(--scaleFactor));
|
||||||
|
--xs: calc(var(--sm) / var(--scaleFactor));
|
||||||
|
--2xs: calc(var(--xs) / var(--scaleFactor));
|
||||||
|
--3xs: calc(var(--2xs) / var(--scaleFactor));
|
||||||
|
--lg: calc(1em * var(--scaleFactor));
|
||||||
|
--xl: calc(var(--lg) * var(--scaleFactor));
|
||||||
|
--2xl: calc(var(--xl) * var(--scaleFactor));
|
||||||
|
--3xl: calc(var(--2xl) * var(--scaleFactor));
|
||||||
|
--4xl: calc(var(--3xl) * var(--scaleFactor));
|
||||||
|
|
||||||
|
/* INFO: Unitless sizes;
|
||||||
|
required for adhoc calculations
|
||||||
|
(division and multiplication in calc() require unitless numbers)
|
||||||
|
*/
|
||||||
|
/* NOTE:
|
||||||
|
in calc() with (x*y) or (x/y) the "y" must be a unitless number
|
||||||
|
*/
|
||||||
|
|
||||||
|
--sm-unitless: calc(1 / var(--scaleFactor));
|
||||||
|
--xs-unitless: calc(var(--sm-unitless) / var(--scaleFactor));
|
||||||
|
--2xs-unitless: calc(var(--xs-unitless) / var(--scaleFactor));
|
||||||
|
--lg-unitless: calc(1 * var(--scaleFactor));
|
||||||
|
--xl-unitless: calc(var(--lg-unitless) * var(--scaleFactor));
|
||||||
|
--2xl-unitless: calc(var(--xl-unitless) * var(--scaleFactor));
|
||||||
|
|
||||||
|
--radius-xs: var(--xs);
|
||||||
|
--radius-sm: var(--sm);
|
||||||
|
--radius-md: var(--md);
|
||||||
|
--radius-lg: var(--lg);
|
||||||
|
--radius-xl: var(--xl);
|
||||||
|
|
||||||
|
--shadow-sm-units: 0 0 1px 0;
|
||||||
|
--shadow-md-units-1: 0 4px 6px;
|
||||||
|
--shadow-md-units-2: 0 2px 4px;
|
||||||
|
--shadow-md-units-3: 0 0 1px;
|
||||||
|
--shadow-lg-units-1: 0 11px 15px -3px;
|
||||||
|
--shadow-lg-units-2: 0 2px 6px;
|
||||||
|
--shadow-lg-units-3: 0 0 1px;
|
||||||
|
--shadow-xl-units-1: 0 20px 25px;
|
||||||
|
--shadow-xl-units-2: 0 5px 11px;
|
||||||
|
--shadow-xl-units-3: 0 5px 11px;
|
||||||
|
--shadow-2xl-units-1: 0 25px 50px;
|
||||||
|
--shadow-2xl-units-2: 0 9px 18px;
|
||||||
|
--shadow-2xl-units-3: 0 0 1px;
|
||||||
|
|
||||||
|
--shadow-sm: var(--shadow-sm-units) rgba(0, 0, 0, 0.11);
|
||||||
|
--shadow-md:
|
||||||
|
var(--shadow-md-units-1) rgba(0, 0, 0, 0.08),
|
||||||
|
var(--shadow-md-units-2) rgba(0, 0, 0, 0.11),
|
||||||
|
var(--shadow-md-units-3) rgba(0, 0, 0, 0.4);
|
||||||
|
--shadow-lg:
|
||||||
|
var(--shadow-lg-units-1) rgba(0, 0, 0, 0.11),
|
||||||
|
var(--shadow-lg-units-2) rgba(0, 0, 0, 0.07),
|
||||||
|
var(--shadow-lg-units-3) rgba(0, 0, 0, 0.4);
|
||||||
|
--shadow-xl:
|
||||||
|
var(--shadow-xl-units-1) rgba(0, 0, 0, 0.09),
|
||||||
|
var(--shadow-xl-units-2) rgba(0, 0, 0, 0.12),
|
||||||
|
var(--shadow-xl-units-3) rgba(0, 0, 0, 0.4);
|
||||||
|
--shadow-2xl:
|
||||||
|
var(--shadow-2xl-units-1) rgba(0, 0, 0, 0.23),
|
||||||
|
var(--shadow-2xl-units-2) rgba(0, 0, 0, 0.1),
|
||||||
|
var(--shadow-2xl-units-3) rgba(0, 0, 0, 0.4);
|
||||||
|
|
||||||
|
--ease-in: cubic-bezier(0.4, 0, 1, 1);
|
||||||
|
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
||||||
|
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
|
||||||
|
--theme-transition: 0s var(--ease-in-out);
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
[data-scope="collapsible"][data-part="content"] {
|
[data-scope="collapsible"][data-part="content"] {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
transition: all 300ms;
|
transition: all var(--theme-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-scope="collapsible"][data-part="content"][data-state="open"] {
|
[data-scope="collapsible"][data-part="content"][data-state="open"] {
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,9 @@
|
||||||
margin-bottom: 0.618rem;
|
margin-bottom: 0.618rem;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 0.8rem;
|
padding: 0.8rem;
|
||||||
transition: border 0.3s;
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
border-color var(--theme-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
& .typedata-details {
|
& .typedata-details {
|
||||||
|
|
@ -164,6 +166,9 @@
|
||||||
.typeprops {
|
.typeprops {
|
||||||
& .typeprop-root {
|
& .typeprop-root {
|
||||||
border: 1px solid hsl(var(--prop-color) / 0.6);
|
border: 1px solid hsl(var(--prop-color) / 0.6);
|
||||||
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
border-color var(--theme-transition);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border: 1px solid hsl(var(--prop-color));
|
border: 1px solid hsl(var(--prop-color));
|
||||||
|
|
@ -175,11 +180,13 @@
|
||||||
|
|
||||||
& .typeprop-name {
|
& .typeprop-name {
|
||||||
color: hsl(var(--prop-link-color));
|
color: hsl(var(--prop-link-color));
|
||||||
|
transition: color var(--theme-transition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark .typeprops {
|
html.dark .typeprops,
|
||||||
|
html:has(input#theme-manual-toggle:checked) .typeprops {
|
||||||
& .typeprop-root {
|
& .typeprop-root {
|
||||||
border: 1px solid hsl(var(--prop-color) / 0.3);
|
border: 1px solid hsl(var(--prop-color) / 0.3);
|
||||||
|
|
||||||
|
|
@ -193,6 +200,9 @@ html.dark .typeprops {
|
||||||
.typefuncs {
|
.typefuncs {
|
||||||
& .typefunc-root {
|
& .typefunc-root {
|
||||||
border: 1px solid hsl(var(--func-color) / 0.6);
|
border: 1px solid hsl(var(--func-color) / 0.6);
|
||||||
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
border-color var(--theme-transition);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border: 1px solid hsl(var(--func-color));
|
border: 1px solid hsl(var(--func-color));
|
||||||
|
|
@ -204,6 +214,7 @@ html.dark .typeprops {
|
||||||
|
|
||||||
& .typefunc-name {
|
& .typefunc-name {
|
||||||
color: hsl(var(--func-link-color));
|
color: hsl(var(--func-link-color));
|
||||||
|
transition: color var(--theme-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
& .typefunc-params {
|
& .typefunc-params {
|
||||||
|
|
@ -222,7 +233,8 @@ html.dark .typeprops {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark .typefuncs {
|
html.dark .typefuncs,
|
||||||
|
html:has(input#theme-manual-toggle:checked) .typefuncs {
|
||||||
& .typefunc-root {
|
& .typefunc-root {
|
||||||
border: 1px solid hsl(var(--func-color) / 0.3);
|
border: 1px solid hsl(var(--func-color) / 0.3);
|
||||||
|
|
||||||
|
|
@ -236,6 +248,9 @@ html.dark .typefuncs {
|
||||||
.typesignals {
|
.typesignals {
|
||||||
& .typesignal-root {
|
& .typesignal-root {
|
||||||
border: 1px solid hsl(var(--signal-color) / 0.6);
|
border: 1px solid hsl(var(--signal-color) / 0.6);
|
||||||
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
border-color var(--theme-transition);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border: 1px solid hsl(var(--signal-color));
|
border: 1px solid hsl(var(--signal-color));
|
||||||
|
|
@ -249,6 +264,7 @@ html.dark .typefuncs {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
color: hsl(var(--signal-link-color));
|
color: hsl(var(--signal-link-color));
|
||||||
|
transition: color var(--theme-transition);
|
||||||
|
|
||||||
& .typesignal-doclink {
|
& .typesignal-doclink {
|
||||||
top: -12px;
|
top: -12px;
|
||||||
|
|
@ -274,7 +290,8 @@ html.dark .typefuncs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark .typesignals {
|
html.dark .typesignals,
|
||||||
|
html:has(input#theme-manual-toggle:checked) .typesignals {
|
||||||
& .typesignal-root {
|
& .typesignal-root {
|
||||||
border: 1px solid hsl(var(--signal-color) / 0.3);
|
border: 1px solid hsl(var(--signal-color) / 0.3);
|
||||||
|
|
||||||
|
|
@ -288,6 +305,9 @@ html.dark .typesignals {
|
||||||
.typevariants {
|
.typevariants {
|
||||||
& .typevariant-root {
|
& .typevariant-root {
|
||||||
border: 1px solid hsl(var(--var-color) / 0.6);
|
border: 1px solid hsl(var(--var-color) / 0.6);
|
||||||
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
border-color var(--theme-transition);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border: 1px solid hsl(var(--var-color));
|
border: 1px solid hsl(var(--var-color));
|
||||||
|
|
@ -301,6 +321,7 @@ html.dark .typesignals {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
color: hsl(var(--var-link-color));
|
color: hsl(var(--var-link-color));
|
||||||
|
transition: color var(--theme-transition);
|
||||||
|
|
||||||
& .typevariant-doclink {
|
& .typevariant-doclink {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -313,7 +334,8 @@ html.dark .typesignals {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark .typevariants {
|
html.dark .typevariants,
|
||||||
|
html:has(input#theme-manual-toggle:checked) .typevariants {
|
||||||
& .typevariant-root {
|
& .typevariant-root {
|
||||||
border: 1px solid hsl(var(--var-color) / 0.3);
|
border: 1px solid hsl(var(--var-color) / 0.3);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
@import "./docs-types.css";
|
@import "./docs-types.css";
|
||||||
|
|
||||||
.docslayout {
|
.docslayout {
|
||||||
transition: background-color 0.3s;
|
transition: background-color var(--theme-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
.docslayout-root {
|
.docslayout-root {
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
justify-content: safe center;
|
justify-content: safe center;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
transition: filter 0.3s;
|
transition: filter var(--theme-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
.docslayout-inner {
|
.docslayout-inner {
|
||||||
|
|
@ -31,8 +31,9 @@
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
:not(html.dark) > .dim-content-toc,
|
html:not(.dark):not(:has(input#theme-manual-toggle:checked)) > .dim-content-toc,
|
||||||
:not(html.dark) > .dim-content-nav {
|
html:not(.dark):not(:has(input#theme-manual-toggle:checked))
|
||||||
|
> .dim-content-nav {
|
||||||
background-color: #909090;
|
background-color: #909090;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,7 +67,7 @@
|
||||||
--color-link-breadcrumbs: hsl(var(--link));
|
--color-link-breadcrumbs: hsl(var(--link));
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
margin-bottom: 0.318rem;
|
margin-bottom: 0.318rem;
|
||||||
max-width: 100svw;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heading {
|
.heading {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,9 @@
|
||||||
.nav-item {
|
.nav-item {
|
||||||
display: block;
|
display: block;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
transition: background-color 0.2s ease;
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
color var(--theme-transition);
|
||||||
padding: 0.4em;
|
padding: 0.4em;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
|
|
||||||
|
|
@ -39,11 +41,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade {
|
.fade {
|
||||||
-webkit-mask-image: linear-gradient(
|
mask-image: linear-gradient(to right, #000 80%, transparent);
|
||||||
to right,
|
-webkit-mask-image: linear-gradient(to right, #000 80%, transparent);
|
||||||
#000 80%,
|
|
||||||
transparent
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-collapsible {
|
.nav-collapsible {
|
||||||
|
|
@ -55,7 +54,9 @@
|
||||||
& > div {
|
& > div {
|
||||||
& > .nav-collapse-marker,
|
& > .nav-collapse-marker,
|
||||||
a {
|
a {
|
||||||
transition: background-color 0.2s ease;
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
color var(--theme-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .nav-collapse-marker {
|
& > .nav-collapse-marker {
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,16 @@
|
||||||
|
|
||||||
.nav-icon {
|
.nav-icon {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
transform: scale(0.5);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
transition: opacity 0.6s;
|
transition:
|
||||||
|
opacity var(--theme-transition),
|
||||||
|
transform var(--theme-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-icon.active {
|
.nav-icon.active {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,7 +54,9 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
transition: left 0.3s ease, padding 0.3s ease;
|
transition:
|
||||||
|
left 0.3s ease,
|
||||||
|
padding 0.3s ease;
|
||||||
|
|
||||||
&.shown {
|
&.shown {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@
|
||||||
--search-corners: calc(0.3125rem * var(--pagefind-ui-scale));
|
--search-corners: calc(0.3125rem * var(--pagefind-ui-scale));
|
||||||
--search-page-icon-size: calc(1.875rem * var(--pagefind-ui-scale));
|
--search-page-icon-size: calc(1.875rem * var(--pagefind-ui-scale));
|
||||||
--search-page-icon-inline-start: calc(
|
--search-page-icon-inline-start: calc(
|
||||||
(var(--search-result-pad-inline-start) - var(--search-page-icon-size)) / 2
|
(var(--search-result-pad-inline-start) - var(--search-page-icon-size)) /
|
||||||
|
2
|
||||||
);
|
);
|
||||||
--search-tree-diagram-size: calc(2.5rem * var(--pagefind-ui-scale));
|
--search-tree-diagram-size: calc(2.5rem * var(--pagefind-ui-scale));
|
||||||
--search-tree-diagram-inline-start: calc(
|
--search-tree-diagram-inline-start: calc(
|
||||||
|
|
@ -57,9 +58,11 @@
|
||||||
|
|
||||||
#qs_search .pagefind-ui__search-clear::before {
|
#qs_search .pagefind-ui__search-clear::before {
|
||||||
content: "";
|
content: "";
|
||||||
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m13.41 12 6.3-6.29a1 1 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1 1 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 .33 1.64 1 1 0 0 0 1.09-.22l6.29-6.3 6.29 6.3a1 1 0 0 0 1.64-.33 1 1 0 0 0-.22-1.09L13.41 12Z'/%3E%3C/svg%3E")
|
-webkit-mask:
|
||||||
|
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m13.41 12 6.3-6.29a1 1 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1 1 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 .33 1.64 1 1 0 0 0 1.09-.22l6.29-6.3 6.29 6.3a1 1 0 0 0 1.64-.33 1 1 0 0 0-.22-1.09L13.41 12Z'/%3E%3C/svg%3E")
|
||||||
center / 50% no-repeat;
|
center / 50% no-repeat;
|
||||||
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m13.41 12 6.3-6.29a1 1 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1 1 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 .33 1.64 1 1 0 0 0 1.09-.22l6.29-6.3 6.29 6.3a1 1 0 0 0 1.64-.33 1 1 0 0 0-.22-1.09L13.41 12Z'/%3E%3C/svg%3E")
|
mask:
|
||||||
|
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m13.41 12 6.3-6.29a1 1 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1 1 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 .33 1.64 1 1 0 0 0 1.09-.22l6.29-6.3 6.29 6.3a1 1 0 0 0 1.64-.33 1 1 0 0 0-.22-1.09L13.41 12Z'/%3E%3C/svg%3E")
|
||||||
center / 50% no-repeat;
|
center / 50% no-repeat;
|
||||||
background-color: hsl(0deg 25% 45%);
|
background-color: hsl(0deg 25% 45%);
|
||||||
display: block;
|
display: block;
|
||||||
|
|
@ -166,9 +169,11 @@
|
||||||
inset-inline-start: var(--search-tree-diagram-inline-start);
|
inset-inline-start: var(--search-tree-diagram-inline-start);
|
||||||
width: var(--search-tree-diagram-size);
|
width: var(--search-tree-diagram-size);
|
||||||
background: hsl(var(--blue) 10% 30%);
|
background: hsl(var(--blue) 10% 30%);
|
||||||
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m6-988H8'/%3E%3C/svg%3E")
|
-webkit-mask:
|
||||||
|
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m6-988H8'/%3E%3C/svg%3E")
|
||||||
0% 0% / 100% no-repeat;
|
0% 0% / 100% no-repeat;
|
||||||
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m6-988H8'/%3E%3C/svg%3E")
|
mask:
|
||||||
|
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m6-988H8'/%3E%3C/svg%3E")
|
||||||
0% 0% / 100% no-repeat;
|
0% 0% / 100% no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,9 +209,11 @@
|
||||||
inset-inline-start: var(--search-tree-diagram-inline-start);
|
inset-inline-start: var(--search-tree-diagram-inline-start);
|
||||||
width: var(--search-tree-diagram-size);
|
width: var(--search-tree-diagram-size);
|
||||||
background: hsl(var(--blue) 10% 30%);
|
background: hsl(var(--blue) 10% 30%);
|
||||||
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m'/%3E%3C/svg%3E")
|
-webkit-mask:
|
||||||
|
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m'/%3E%3C/svg%3E")
|
||||||
0% 0% / 100% no-repeat;
|
0% 0% / 100% no-repeat;
|
||||||
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m'/%3E%3C/svg%3E")
|
mask:
|
||||||
|
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m'/%3E%3C/svg%3E")
|
||||||
0% 0% / 100% no-repeat;
|
0% 0% / 100% no-repeat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -219,7 +226,8 @@
|
||||||
|
|
||||||
/* default styles */
|
/* default styles */
|
||||||
site-search {
|
site-search {
|
||||||
--shadow-lg: 0px 25px 7px hsl(0deg, 0%, 0%, 0.03),
|
--shadow-lg:
|
||||||
|
0px 25px 7px hsl(0deg, 0%, 0%, 0.03),
|
||||||
0px 16px 6px hsl(0deg, 0%, 0%, 0.1), 0px 9px 5px hsl(223deg, 13%, 10%, 0.33),
|
0px 16px 6px hsl(0deg, 0%, 0%, 0.1), 0px 9px 5px hsl(223deg, 13%, 10%, 0.33),
|
||||||
0px 4px 4px hsl(0deg, 0%, 0%, 0.75), 0px 4px 2px hsl(0deg, 0%, 0%, 0.25);
|
0px 4px 4px hsl(0deg, 0%, 0%, 0.75), 0px 4px 2px hsl(0deg, 0%, 0%, 0.25);
|
||||||
display: contents;
|
display: contents;
|
||||||
|
|
@ -275,7 +283,8 @@ button > kbd {
|
||||||
background-color: hsl(var(--blue) 15% 80%);
|
background-color: hsl(var(--blue) 15% 80%);
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark button > kbd {
|
html.dark button > kbd,
|
||||||
|
html:has(input#theme-manual-toggle:checked) button > kbd {
|
||||||
background-color: hsl(var(--blue) 5% 20% / 0.5);
|
background-color: hsl(var(--blue) 5% 20% / 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -368,7 +377,8 @@ button[data-close-modal] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark button[data-open-modal] {
|
html.dark button[data-open-modal],
|
||||||
|
html:has(input#theme-manual-toggle:checked) button[data-open-modal] {
|
||||||
background-color: hsla(var(--blue) 15% 15% / 0.5);
|
background-color: hsla(var(--blue) 15% 15% / 0.5);
|
||||||
color: hsl(var(--blue) 40% 65%);
|
color: hsl(var(--blue) 40% 65%);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,28 @@
|
||||||
font-size: 1.614rem;
|
font-size: 1.614rem;
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .toc-icon {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.5);
|
||||||
|
position: absolute;
|
||||||
|
transition:
|
||||||
|
opacity var(--theme-transition),
|
||||||
|
transform var(--theme-transition);
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
& > svg {
|
& > svg {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
|
|
@ -61,7 +83,9 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
transition: width 0.3s ease, padding 0.3s ease;
|
transition:
|
||||||
|
width 0.3s ease,
|
||||||
|
padding 0.3s ease;
|
||||||
|
|
||||||
&.shown {
|
&.shown {
|
||||||
& .toc-content {
|
& .toc-content {
|
||||||
|
|
@ -115,7 +139,7 @@
|
||||||
margin-right: 1.272rem;
|
margin-right: 1.272rem;
|
||||||
|
|
||||||
& .toc_a {
|
& .toc_a {
|
||||||
transition: color 0.33s;
|
transition: color var(--theme-transition);
|
||||||
color: hsl(var(--toc-link));
|
color: hsl(var(--toc-link));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
@import "remark-github-blockquote-alert/alert.css";
|
@import "remark-github-blockquote-alert/alert.css";
|
||||||
@import "./css-config/base.css";
|
|
||||||
@import "./css-config/animations.css";
|
|
||||||
@import "./css-config/code.css";
|
|
||||||
@import "./css-config/colors.css";
|
|
||||||
|
|
||||||
|
@import "./css-config/entry.css";
|
||||||
@import "./main-page.css";
|
@import "./main-page.css";
|
||||||
|
|
||||||
@import "./docs/nav/nav.css";
|
@import "./docs/nav/nav.css";
|
||||||
|
|
@ -15,42 +12,69 @@
|
||||||
@import "./components/featurelist.css";
|
@import "./components/featurelist.css";
|
||||||
@import "./components/marquee.css";
|
@import "./components/marquee.css";
|
||||||
|
|
||||||
.changing-theme * {
|
.theme-toggle {
|
||||||
transition: none !important;
|
height: 24px;
|
||||||
|
font-size: 1.614rem;
|
||||||
|
color: hsla(var(--signal-color) / 0.7);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
color: hsla(var(--signal-color) / 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* color styling */
|
/* color styling */
|
||||||
.header {
|
.header {
|
||||||
background-color: hsl(var(--bg-400));
|
background-color: hsl(var(--bg-400));
|
||||||
box-shadow: 0 1px 1px 1px hsla(var(--white) 100 0 / 0.1);
|
box-shadow: 0 1px 1px 1px hsla(var(--white) 100 0 / 0.1);
|
||||||
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
color var(--theme-transition),
|
||||||
|
box-shadow var(--theme-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
.baselayout,
|
.baselayout,
|
||||||
.docslayout {
|
.docslayout {
|
||||||
background-color: hsl(var(--background));
|
background-color: hsl(var(--background));
|
||||||
color: hsl(var(--secondary-900));
|
color: hsl(var(--secondary-900));
|
||||||
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
color var(--theme-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: hsl(var(--link));
|
color: hsl(var(--link));
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
transition: color var(--theme-transition);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark .baselayout,
|
html.dark .baselayout,
|
||||||
html.dark .docslayout {
|
html.dark .docslayout,
|
||||||
|
html:has(input#theme-manual-toggle:checked) .baselayout,
|
||||||
|
html:has(input#theme-manual-toggle:checked) .docslayout {
|
||||||
background-color: hsl(var(--bg-900));
|
background-color: hsl(var(--bg-900));
|
||||||
color: hsl(var(--secondary-400));
|
color: hsl(var(--secondary-400));
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark {
|
html.dark,
|
||||||
|
html:has(input#theme-manual-toggle:checked) {
|
||||||
& .header {
|
& .header {
|
||||||
background-color: hsl(var(--secondary-900));
|
background-color: hsl(var(--secondary-900));
|
||||||
color: hsl(var(--secondary-500));
|
color: hsl(var(--secondary-500));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& .theme-toggle {
|
||||||
|
color: hsla(var(--func-color) / 0.7);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: hsla(var(--func-color) / 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* layout and positioning */
|
/* layout and positioning */
|
||||||
|
|
@ -65,6 +89,7 @@ html.dark {
|
||||||
transparent
|
transparent
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
.unset {
|
.unset {
|
||||||
all: unset;
|
all: unset;
|
||||||
}
|
}
|
||||||
|
|
@ -133,47 +158,63 @@ body.overflow-toc {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-toggle {
|
|
||||||
height: 24px;
|
|
||||||
font-size: 1.614rem;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
margin-top: var(--2xl);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 1rem 2rem;
|
padding: 1rem 2rem;
|
||||||
overflow: hidden;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
background: hsl(var(--footer-bkg));
|
background: hsl(var(--footer-bkg));
|
||||||
|
transition:
|
||||||
|
background-color var(--theme-transition),
|
||||||
|
color var(--theme-transition);
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: -1rem;
|
left: 0;
|
||||||
|
right: calc(50% + 1.25rem);
|
||||||
height: 1px;
|
height: 1px;
|
||||||
width: calc(100% + 1rem);
|
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
90deg,
|
90deg,
|
||||||
transparent 0%,
|
transparent 0%,
|
||||||
hsl(var(--footer-bkg-border)) 50%,
|
hsl(var(--footer-bkg-border)) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
left: calc(50% + 1.25rem);
|
||||||
|
height: 1px;
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
hsl(var(--footer-bkg-border)) 0%,
|
||||||
transparent 100%
|
transparent 100%
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& .theme-toggle {
|
||||||
|
position: absolute;
|
||||||
|
top: -12px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: max-content;
|
||||||
|
height: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
& a {
|
& a {
|
||||||
color: hsl(var(--text-dark));
|
color: hsl(var(--text-dark));
|
||||||
transition: color 0.3s ease;
|
transition: color var(--theme-transition);
|
||||||
|
|
||||||
& .hint {
|
& .hint {
|
||||||
transition: color 0.3s ease;
|
transition: color var(--theme-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(2) .hint {
|
&:nth-child(2) .hint {
|
||||||
|
|
@ -223,10 +264,11 @@ footer {
|
||||||
gap: 0.373rem;
|
gap: 0.373rem;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
font-size: 2.5rem;
|
font-size: 2.5rem;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
& .changelog {
|
& .changelog {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
& a {
|
& a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
margin-inline: auto;
|
margin-inline: auto;
|
||||||
|
|
|
||||||
|
|
@ -45,16 +45,15 @@ h1.gradient-text {
|
||||||
hsl(var(--green) 80% 42%),
|
hsl(var(--green) 80% 42%),
|
||||||
hsl(var(--blue) 80% 49%)
|
hsl(var(--blue) 80% 49%)
|
||||||
);
|
);
|
||||||
|
background-clip: text;
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark h1.gradient-text {
|
html.dark h1.gradient-text,
|
||||||
background: linear-gradient(
|
html:has(input#theme-manual-toggle:checked) h1.gradient-text {
|
||||||
30deg,
|
background: linear-gradient(30deg, #42b96b, #4281b9);
|
||||||
#42b96b,
|
background-clip: text;
|
||||||
#4281b9
|
|
||||||
);
|
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
@ -76,7 +75,8 @@ html.dark h1.gradient-text {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark .main-page_hero-text {
|
html.dark .main-page_hero-text,
|
||||||
|
html:has(input#theme-manual-toggle:checked) .main-page_hero-text {
|
||||||
& h2 {
|
& h2 {
|
||||||
color: hsl(var(--blue) 100% 83%);
|
color: hsl(var(--blue) 100% 83%);
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +95,9 @@ html.dark .main-page_hero-text {
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.about-break { display: none }
|
.about-break {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.about-buttons {
|
.about-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -130,12 +132,13 @@ html.dark .main-page_hero-text {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 3.67rem;
|
height: 3.67rem;
|
||||||
border-radius: 9px;
|
border-radius: var(--radius-sm);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 1px solid hsl(var(--green) 10% 10%);
|
box-shadow: var(--shadow-md);
|
||||||
transition:
|
transition:
|
||||||
background-color 0.3s,
|
background-color var(--theme-transition),
|
||||||
border-color 0.3s;
|
box-shadow var(--theme-transition),
|
||||||
|
border-color var(--theme-transition);
|
||||||
|
|
||||||
background-color: hsl(var(--green) 38% 30%);
|
background-color: hsl(var(--green) 38% 30%);
|
||||||
color: hsl(194deg 0% 100%);
|
color: hsl(194deg 0% 100%);
|
||||||
|
|
@ -143,17 +146,22 @@ html.dark .main-page_hero-text {
|
||||||
&:hover {
|
&:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-color: hsl(var(--green) 20% 20%);
|
|
||||||
background-color: hsl(var(--green) 48% 40%);
|
background-color: hsl(var(--green) 48% 40%);
|
||||||
|
box-shadow:
|
||||||
|
var(--shadow-md-units-1) hsla(var(--green) 48 45 / 0.08),
|
||||||
|
var(--shadow-md-units-2) hsla(var(--green) 48 45 / 0.11),
|
||||||
|
var(--shadow-md-units-3) hsla(var(--green) 48 45 / 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.main-page_bluecard {
|
&.main-page_bluecard {
|
||||||
border-color: hsl(var(--blue) 10% 10%);
|
|
||||||
background-color: hsl(var(--blue) 38% 30%);
|
background-color: hsl(var(--blue) 38% 30%);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: hsl(var(--blue) 20% 20%);
|
|
||||||
background-color: hsl(var(--blue) 48% 40%);
|
background-color: hsl(var(--blue) 48% 40%);
|
||||||
|
box-shadow:
|
||||||
|
var(--shadow-md-units-1) hsla(var(--blue) 48 45 / 0.08),
|
||||||
|
var(--shadow-md-units-2) hsla(var(--blue) 48 45 / 0.11),
|
||||||
|
var(--shadow-md-units-3) hsla(var(--blue) 48 45 / 0.4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,7 +170,8 @@ html.dark .main-page_hero-text {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark .main-page_link-card {
|
html.dark .main-page_link-card,
|
||||||
|
html:has(input#theme-manual-toggle:checked) .main-page_link-card {
|
||||||
background-color: hsl(var(--green) 38% 25%);
|
background-color: hsl(var(--green) 38% 25%);
|
||||||
color: hsl(194deg 0% 100%);
|
color: hsl(194deg 0% 100%);
|
||||||
|
|
||||||
|
|
@ -226,7 +235,15 @@ html.dark .main-page_link-card {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
.about-txt { max-width: 70% }
|
.about-txt {
|
||||||
.about-break { display: unset }
|
max-width: 70%;
|
||||||
.about-buttons { flex-direction: column }
|
}
|
||||||
|
|
||||||
|
.about-break {
|
||||||
|
display: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.about-buttons {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
{
|
{
|
||||||
"extends": "astro/tsconfigs/strict",
|
"extends": "astro/tsconfigs/strict",
|
||||||
|
"include": ["src/**/*", "**/**.d.ts", "pagefind.ts"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"lib": ["es2023"],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "@astrojs/ts-plugin"
|
"name": "@astrojs/ts-plugin"
|
||||||
|
|
@ -9,32 +11,25 @@
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
"jsxImportSource": "solid-js",
|
"jsxImportSource": "solid-js",
|
||||||
"verbatimModuleSyntax": true,
|
"verbatimModuleSyntax": true,
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@*": [
|
"@*": ["./*"],
|
||||||
"./*"
|
"@/*": ["./src/*"],
|
||||||
],
|
"@config/*": ["./src/config/*"],
|
||||||
"@/*": [
|
"@icons": ["./src/components/icons.tsx"],
|
||||||
"./src/*"
|
"@icons/*": ["./src/icons/*"],
|
||||||
],
|
"@components/*": ["./src/components/*"],
|
||||||
"@config/*": [
|
"@layouts/*": ["./src/layouts/*"],
|
||||||
"./src/config/*"
|
"@styles/*": ["./src/styles/*"],
|
||||||
],
|
"@_types": ["./src/config/_types/index.ts"],
|
||||||
"@icons": [
|
"@_types/*": ["./src/config/_types/*"]
|
||||||
"./src/components/icons.tsx"
|
},
|
||||||
],
|
"types": ["astro/client"]
|
||||||
"@icons/*": [
|
|
||||||
"./src/icons/*"
|
|
||||||
],
|
|
||||||
"@components/*": [
|
|
||||||
"./src/components/*"
|
|
||||||
],
|
|
||||||
"@layouts/*": [
|
|
||||||
"./src/layouts/*"
|
|
||||||
],
|
|
||||||
"@styles/*": [
|
|
||||||
"./src/styles/*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue