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/
|
||||
|
||||
# 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)
|
||||
Hosted version at [quickshell.outfoxxed.me](https://quickshell.outfoxxed.me)
|
||||
Documentation for [quickshell](https://git.outfoxxed.me/outfoxxed/quickshell) Hosted version at [quickshell.org](https://quickshell.outfoxxed.me)
|
||||
|
||||
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 light theme
|
||||
- QtQML docs search
|
||||
- page metadata:
|
||||
- lastUpdatedAt
|
||||
- prevUpdate?
|
||||
- editURL
|
||||
- `min_version`
|
||||
- `max_version`
|
||||
- `edit_URL`
|
||||
- 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 mdx from "@astrojs/mdx";
|
||||
import icon from "astro-icon";
|
||||
|
|
@ -10,14 +10,32 @@ import { markdownConfig } from "./src/config/io/markdown.ts";
|
|||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
markdown: markdownConfig,
|
||||
site: "https://quickshell.outfoxxed.me",
|
||||
site: "https://quickshell.org",
|
||||
integrations: [
|
||||
solidJs({
|
||||
devtools: true,
|
||||
devtools: false,
|
||||
}),
|
||||
mdx(),
|
||||
pagefind(),
|
||||
icon(),
|
||||
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": {
|
||||
"enabled": true,
|
||||
"formatWithErrors": true,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 2,
|
||||
"lineEnding": "lf",
|
||||
"lineWidth": 66,
|
||||
"attributePosition": "multiline"
|
||||
"lineWidth": 80,
|
||||
"attributePosition": "auto"
|
||||
},
|
||||
"plugins": [],
|
||||
"linter": {
|
||||
|
|
@ -25,6 +28,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"html": {
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentScriptAndStyle": true,
|
||||
"lineWidth": 80
|
||||
},
|
||||
"experimentalFullSupportEnabled": true
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"jsxQuoteStyle": "double",
|
||||
|
|
@ -51,12 +62,18 @@
|
|||
"cssModules": true
|
||||
}
|
||||
},
|
||||
"json": {
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"lineWidth": 80,
|
||||
"lineEnding": "lf",
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 2
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"includes": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx"
|
||||
],
|
||||
"includes": ["**/*.ts", "**/*.tsx"],
|
||||
"linter": {
|
||||
"rules": {
|
||||
"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",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"version": "0.1.1",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
|
|
@ -10,33 +10,45 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ark-ui/solid": "^3.5.0",
|
||||
"@astrojs/check": "^0.9.4",
|
||||
"@astrojs/markdown-remark": "^6.3.1",
|
||||
"@astrojs/mdx": "^4.2.6",
|
||||
"@astrojs/sitemap": "^3.4.0",
|
||||
"@astrojs/solid-js": "^5.0.10",
|
||||
"@fontsource-variable/rubik": "^5.1.0",
|
||||
"@astrojs/check": "0.9.6",
|
||||
"@astrojs/markdown-remark": "6.3.10",
|
||||
"@astrojs/mdx": "4.3.13",
|
||||
"@astrojs/sitemap": "3.7.0",
|
||||
"@astrojs/solid-js": "^5.1.3",
|
||||
"@fontsource-variable/rubik": "^5.2.8",
|
||||
"@hbsnow/rehype-sectionize": "^1.0.7",
|
||||
"@pagefind/default-ui": "^1.1.1",
|
||||
"@shikijs/rehype": "^3.4.2",
|
||||
"@types/node": "^20.14.11",
|
||||
"astro": "^5.7.13",
|
||||
"astro-breadcrumbs": "^3.3.1",
|
||||
"@pagefind/default-ui": "^1.4.0",
|
||||
"@shikijs/rehype": "^3.22.0",
|
||||
"astro": "5.17.2",
|
||||
"astro-breadcrumbs": "^3.3.3",
|
||||
"astro-icon": "^1.1.5",
|
||||
"hast": "^1.0.0",
|
||||
"hast-util-from-html": "^2.0.3",
|
||||
"remark-github-blockquote-alert": "^1.2.1",
|
||||
"solid-devtools": "^0.30.1",
|
||||
"solid-js": "^1.8.18",
|
||||
"typescript": "^5.5.3",
|
||||
"hastscript": "^9.0.1",
|
||||
"jsdom": "^28.1.0",
|
||||
"rehype": "^13.0.2",
|
||||
"remark-github-blockquote-alert": "^2.0.1",
|
||||
"solid-js": "^1.9.11",
|
||||
"unified": "^11.0.5",
|
||||
"unist-util-visit": "^5.0.0"
|
||||
"unist-util-visit": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/ts-plugin": "^1.10.3",
|
||||
"@biomejs/biome": "^1.8.3",
|
||||
"pagefind": "^1.1.1"
|
||||
"@astrojs/ts-plugin": "1.10.6",
|
||||
"@babel/core": "^7.29.0",
|
||||
"@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 relativeDir = relative(cwd, targetDir);
|
||||
return new Promise<void>(resolve => {
|
||||
spawn(
|
||||
"yarn",
|
||||
["pagefind", "--site", relativeDir],
|
||||
{
|
||||
spawn("yarn", ["pagefind", "--site", relativeDir], {
|
||||
stdio: "inherit",
|
||||
shell: true,
|
||||
cwd,
|
||||
}
|
||||
).on("close", () => resolve());
|
||||
}).on("close", () => resolve());
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
---
|
||||
import "@styles/components/accordion.css";
|
||||
---
|
||||
<details class=`accordion ${Astro.props.class ?? ""}` {...Astro.props}>
|
||||
<summary>
|
||||
<slot name="header"/>
|
||||
</summary>
|
||||
|
||||
<details class={`accordion ${Astro.props.class ?? ""}`} {...Astro.props}>
|
||||
<summary><slot name="header" /></summary>
|
||||
<div class="accordion-container">
|
||||
<div>
|
||||
<slot/>
|
||||
</div>
|
||||
<div><slot /></div>
|
||||
</div>
|
||||
</details>
|
||||
<script>
|
||||
|
|
@ -16,7 +13,9 @@ import "@styles/components/accordion.css";
|
|||
document.querySelectorAll(".accordion").forEach(element => {
|
||||
const accordion = element as HTMLDetailsElement;
|
||||
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 => {
|
||||
if ((event.target as Element).tagName === "A") return;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
---
|
||||
const production = import.meta.env.PRODUCTION;
|
||||
---
|
||||
|
||||
{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;
|
||||
---
|
||||
|
||||
<span class="badge">
|
||||
{withIcon &&
|
||||
(
|
||||
badgeIconName ?
|
||||
<Icon name={badgeIconName}/>
|
||||
: <Icon name={"flag"}/>
|
||||
)
|
||||
}
|
||||
)}
|
||||
<span class="badge-text">{badgeText}</span>
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ interface Props {
|
|||
}
|
||||
const { title } = Astro.props;
|
||||
---
|
||||
|
||||
<Accordion class="docs-collapsible">
|
||||
<div slot="header">
|
||||
<Fragment set :html={collapsibleMarker} />
|
||||
{title}
|
||||
</div>
|
||||
<slot>
|
||||
<slot />
|
||||
</Accordion>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import matrixLogo from "@icons/matrix-logo.svg?raw";
|
||||
import discordLogo from "@icons/discord-logo.svg?raw";
|
||||
import gitLogo from "@icons/git-logo.svg?raw";
|
||||
import ThemeToggle from "./ThemeToggle.astro";
|
||||
|
||||
interface Props {
|
||||
class?: string;
|
||||
|
|
@ -9,6 +10,7 @@ interface Props {
|
|||
|
||||
const props = Astro.props;
|
||||
---
|
||||
|
||||
<footer class=`${props.class ?? ""}`>
|
||||
<div class="credits">
|
||||
<p class="hint">Brought to you by:</p>
|
||||
|
|
@ -18,6 +20,7 @@ const props = Astro.props;
|
|||
and our contributors
|
||||
</a>
|
||||
</div>
|
||||
<ThemeToggle />
|
||||
<div class="socials-changelog">
|
||||
<section class="socials">
|
||||
<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 type { TypeData } from "@config/io/types";
|
||||
import ThemeToggle from "./ThemeToggle.astro";
|
||||
import type { TypeData } from "@config/_types";
|
||||
import Nav from "@components/navigation/sidebars/nav/index.astro";
|
||||
import TOC from "@components/navigation/sidebars/TOC.astro";
|
||||
import type { ConfigHeading } from "@components/navigation/sidebars/types";
|
||||
|
|
@ -14,16 +14,15 @@ interface Props {
|
|||
|
||||
const { title, headings, type } = Astro.props;
|
||||
---
|
||||
|
||||
<div class="header">
|
||||
<div class="header-item header-left">
|
||||
<Nav mobile={true} />
|
||||
<h3 class="header-title">
|
||||
<a href="/">Quickshell</a>
|
||||
</h3>
|
||||
<h3 class="header-title"><a href="/">Quickshell</a></h3>
|
||||
</div>
|
||||
<div class="header-item header-right">
|
||||
<Search />
|
||||
<ThemeSelect client:load />
|
||||
<ThemeToggle />
|
||||
<TOC title={title} headings={headings} type={type} mobile={true} />
|
||||
</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";
|
||||
|
||||
const codeDesktop = await processMarkdown("N/A", `\`\`\`qml
|
||||
const codeDesktop = await processMarkdown(
|
||||
"N/A",
|
||||
`\`\`\`qml
|
||||
// a standard desktop window
|
||||
FloatingWindow {
|
||||
Timer {
|
||||
|
|
@ -19,9 +21,12 @@ FloatingWindow {
|
|||
// change the window's color when timer.invert changes
|
||||
color: timer.invert ? "purple" : "green"
|
||||
}
|
||||
\`\`\``);
|
||||
\`\`\``
|
||||
);
|
||||
|
||||
const codeMobile = await processMarkdown("N/A", `\`\`\`qml
|
||||
const codeMobile = await processMarkdown(
|
||||
"N/A",
|
||||
`\`\`\`qml
|
||||
// a standard desktop window
|
||||
FloatingWindow {
|
||||
Timer {
|
||||
|
|
@ -47,19 +52,22 @@ FloatingWindow {
|
|||
? "purple"
|
||||
: "green"
|
||||
}
|
||||
\`\`\``);
|
||||
\`\`\``
|
||||
);
|
||||
---
|
||||
|
||||
<ul class="featurelist">
|
||||
<li class="featurelist-item hot-reloading left">
|
||||
<section class="feature-text">
|
||||
<h3 class="feature-title">See your changes in real time</h3>
|
||||
<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>
|
||||
</section>
|
||||
<section class="feature-showcase">
|
||||
<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>
|
||||
</section>
|
||||
</li>
|
||||
|
|
@ -67,46 +75,69 @@ FloatingWindow {
|
|||
<section class="feature-text">
|
||||
<h3 class="feature-title">Easy to use language</h3>
|
||||
<span class="feature-subtitle">
|
||||
Quickshell is configured in QML, a simple language designed for creating flexible user interfaces.
|
||||
It also has LSP support.
|
||||
Quickshell is configured in QML, a simple language designed for creating
|
||||
flexible user interfaces. It also has LSP support.
|
||||
</span>
|
||||
</section>
|
||||
<section class="feature-showcase" id="qml-showcase">
|
||||
<div class="showcase-desktop">
|
||||
<Fragment set:html={codeDesktop}/>
|
||||
</div>
|
||||
<div class="showcase-mobile">
|
||||
<Fragment set:html={codeMobile}/>
|
||||
</div>
|
||||
<div class="showcase-desktop"><Fragment set :html={codeDesktop} /></div>
|
||||
<div class="showcase-mobile"><Fragment set :html={codeMobile} /></div>
|
||||
</section>
|
||||
</li>
|
||||
<li class="featurelist-item cloud-li left">
|
||||
<section class="feature-text">
|
||||
<h3 class="feature-title">Extensive integrations</h3>
|
||||
<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>
|
||||
</section>
|
||||
<section class="feature-showcase cloud">
|
||||
<section class="feature-cloud">
|
||||
<div class="cloud-center">
|
||||
<img src="/favicon.svg" alt="Quickshell" />
|
||||
<img src="/favicon.svg" alt="Quickshell">
|
||||
</div>
|
||||
<div class="cloud-items-wrapper">
|
||||
<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 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 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 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 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>
|
||||
</div>
|
||||
</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,39 +1,8 @@
|
|||
---
|
||||
import { Icon } from "astro-icon/components";
|
||||
|
||||
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",
|
||||
},
|
||||
];
|
||||
import MarqueeContent from "./MarqueeContent.astro";
|
||||
---
|
||||
|
||||
<div class="marquee">
|
||||
<div class="marquee-scroll">
|
||||
<div id="marquee-scroll-left" class="marquee-scroll-arrow">
|
||||
|
|
@ -43,103 +12,7 @@ const videos = [
|
|||
<div><Icon name="caret-right" /></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="marquee-content" class="marquee-content" data-scroll="0" data-media-index="0">
|
||||
{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>
|
||||
<MarqueeContent />
|
||||
</div>
|
||||
|
||||
<script>
|
||||
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>
|
||||
<script src="@config/styling/marquee.ts" />
|
||||
|
|
|
|||
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 magnifierIcon from "@icons/magnifier.svg?raw"
|
||||
import magnifierIcon from "@icons/magnifier.svg?raw";
|
||||
---
|
||||
|
||||
<site-search class="search-wrapper">
|
||||
<button
|
||||
data-open-modal
|
||||
|
|
@ -12,56 +13,58 @@ import magnifierIcon from "@icons/magnifier.svg?raw"
|
|||
>
|
||||
<Fragment set :html={magnifierIcon} />
|
||||
<span class="search-label" aria-hidden="true">Search</span>
|
||||
<kbd class="search-kbd">
|
||||
<kbd>Ctrl</kbd><kbd>K</kbd>
|
||||
</kbd>
|
||||
<kbd class="search-kbd"> <kbd>Ctrl</kbd><kbd>K</kbd> </kbd>
|
||||
</button>
|
||||
<dialog aria-label="Search" class="search-dialog">
|
||||
<div class="dialog-frame">
|
||||
<button data-close-modal class="search-cancel">
|
||||
Cancel
|
||||
</button>
|
||||
<button data-close-modal class="search-cancel">Cancel</button>
|
||||
<div class="search-container">
|
||||
<div id="qs_search" />
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
</site-search>
|
||||
{
|
||||
/**
|
||||
{/**
|
||||
* NOTE: YOINKED FROM STARLIGHT
|
||||
* This is intentionally inlined to avoid briefly showing an invalid shortcut.
|
||||
* Purposely using the deprecated `navigator.platform` property to detect Apple devices, as the
|
||||
* user agent is spoofed by some browsers when opening the devtools.
|
||||
*/
|
||||
}
|
||||
*/}
|
||||
<script is:inline>
|
||||
(() => {
|
||||
const openBtn = document.querySelector('button[data-open-modal]');
|
||||
const shortcut = openBtn?.querySelector('kbd');
|
||||
const openBtn = document.querySelector("button[data-open-modal]");
|
||||
const shortcut = openBtn?.querySelector("kbd");
|
||||
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)) {
|
||||
platformKey.textContent = '⌘';
|
||||
openBtn.setAttribute('aria-keyshortcuts', 'Meta+K');
|
||||
platformKey.textContent = "⌘";
|
||||
openBtn.setAttribute("aria-keyshortcuts", "Meta+K");
|
||||
}
|
||||
shortcut.style.display = '';
|
||||
shortcut.style.display = "";
|
||||
})();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { getQMLTypeLinkObject, getQMLTypeLink, getIconForLink } from '@src/config/io/helpers';
|
||||
import {
|
||||
getQMLTypeLinkObject,
|
||||
getQMLTypeLink,
|
||||
getIconForLink,
|
||||
} from "@src/config/io/helpers";
|
||||
class SiteSearch extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
const openBtn = this.querySelector<HTMLButtonElement>('button[data-open-modal]')!;
|
||||
const closeBtn = this.querySelector<HTMLButtonElement>('button[data-close-modal]')!;
|
||||
const dialog = this.querySelector('dialog')!;
|
||||
const dialogFrame = this.querySelector('.dialog-frame')!;
|
||||
const openBtn = this.querySelector<HTMLButtonElement>(
|
||||
"button[data-open-modal]"
|
||||
)!;
|
||||
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. */
|
||||
const onClick = (event: MouseEvent) => {
|
||||
const isLink = 'href' in (event.target || {});
|
||||
const isLink = "href" in (event.target || {});
|
||||
if (
|
||||
isLink ||
|
||||
(document.body.contains(event.target as Node) &&
|
||||
|
|
@ -73,26 +76,26 @@ import { getQMLTypeLinkObject, getQMLTypeLink, getIconForLink } from '@src/confi
|
|||
|
||||
const openModal = (event?: MouseEvent) => {
|
||||
dialog.showModal();
|
||||
document.body.toggleAttribute('data-search-modal-open', true);
|
||||
this.querySelector('input')?.focus();
|
||||
document.body.toggleAttribute("data-search-modal-open", true);
|
||||
this.querySelector("input")?.focus();
|
||||
event?.stopPropagation();
|
||||
window.addEventListener('click', onClick);
|
||||
window.addEventListener("click", onClick);
|
||||
};
|
||||
|
||||
const closeModal = () => dialog.close();
|
||||
|
||||
openBtn.addEventListener('click', openModal);
|
||||
openBtn.addEventListener("click", openModal);
|
||||
openBtn.disabled = false;
|
||||
closeBtn.addEventListener('click', closeModal);
|
||||
closeBtn.addEventListener("click", closeModal);
|
||||
|
||||
dialog.addEventListener('close', () => {
|
||||
document.body.toggleAttribute('data-search-modal-open', false);
|
||||
window.removeEventListener('click', onClick);
|
||||
dialog.addEventListener("close", () => {
|
||||
document.body.toggleAttribute("data-search-modal-open", false);
|
||||
window.removeEventListener("click", onClick);
|
||||
});
|
||||
|
||||
// Listen for `ctrl + k` and `cmd + k` keyboard shortcuts.
|
||||
window.addEventListener('keydown', (e) => {
|
||||
if ((e.metaKey === true || e.ctrlKey === true) && e.key === 'k') {
|
||||
window.addEventListener("keydown", e => {
|
||||
if ((e.metaKey === true || e.ctrlKey === true) && e.key === "k") {
|
||||
dialog.open ? closeModal() : openModal();
|
||||
e.preventDefault();
|
||||
}
|
||||
|
|
@ -106,38 +109,56 @@ import { getQMLTypeLinkObject, getQMLTypeLink, getIconForLink } from '@src/confi
|
|||
for (const matching of match) {
|
||||
const linkObject = getQMLTypeLinkObject(matching[1]);
|
||||
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
|
||||
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>`;
|
||||
excerpt = excerpt.replace(matching[0], newLink)
|
||||
excerpt = excerpt.replace(matching[0], newLink);
|
||||
}
|
||||
}
|
||||
return excerpt
|
||||
}
|
||||
|
||||
return excerpt;
|
||||
};
|
||||
|
||||
const formatURL = (path: string) => path;
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const onIdle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1));
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const onIdle = window.requestIdleCallback || (cb => setTimeout(cb, 1));
|
||||
onIdle(async () => {
|
||||
const { PagefindUI } = await import(
|
||||
//@ts-expect-error — Missing types for @pagefind/default-ui package.
|
||||
const { PagefindUI } = await import('@pagefind/default-ui');
|
||||
"@pagefind/default-ui"
|
||||
);
|
||||
new PagefindUI({
|
||||
element: '#qs_search',
|
||||
element: "#qs_search",
|
||||
baseUrl: import.meta.env.BASE_URL,
|
||||
bundlePath: import.meta.env.BASE_URL.replace(/\/$/, '') + '/pagefind/',
|
||||
bundlePath:
|
||||
import.meta.env.BASE_URL.replace(/\/$/, "") + "/pagefind/",
|
||||
showImages: false,
|
||||
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.excerpt = processExcerpt(result.excerpt)
|
||||
result.sub_results = result.sub_results.map((sub_result) => {
|
||||
result.excerpt = processExcerpt(result.excerpt);
|
||||
result.sub_results = result.sub_results.map(sub_result => {
|
||||
sub_result.url = formatURL(sub_result.url);
|
||||
sub_result.excerpt = processExcerpt(sub_result.excerpt)
|
||||
sub_result.excerpt = processExcerpt(sub_result.excerpt);
|
||||
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>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
---
|
||||
import TableOfContents from "./toc";
|
||||
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 {
|
||||
title?: string;
|
||||
|
|
@ -12,13 +18,16 @@ export interface Props {
|
|||
|
||||
const { title, headings, type, mobile } = Astro.props;
|
||||
|
||||
const types: TypeTOC | null = type ? {
|
||||
const types: TypeTOC | null = type
|
||||
? {
|
||||
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 ?? {}),
|
||||
variants: Object.keys(type.variants ?? {}),
|
||||
} : null;
|
||||
}
|
||||
: null;
|
||||
---
|
||||
|
||||
{((headings?.length ?? 0) != 0 || types) &&
|
||||
<div id="toc" aria-mobile={mobile} class=`toc-wrapper${mobile ? "-mobile":""}`>
|
||||
<TableOfContents
|
||||
|
|
@ -28,5 +37,4 @@ const types: TypeTOC | null = type ? {
|
|||
mobile={mobile}
|
||||
client:idle
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
</div>}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ interface Props {
|
|||
|
||||
const { title, link, current, showIcon } = Astro.props;
|
||||
---
|
||||
|
||||
<a class=`nav-component nav-item nav-link ${current ? "nav-current" : ""}` href={link}>
|
||||
{ showIcon ? (
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ interface Props {
|
|||
}
|
||||
const { title, link, current } = Astro.props;
|
||||
---
|
||||
|
||||
<Accordion class=`nav-component nav-collapsible ${current ? "nav-current" : ""}` {...(current ? { open: "_" } : {})}>
|
||||
<div slot="header">
|
||||
<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}/>
|
||||
</div>
|
||||
</div>
|
||||
<slot>
|
||||
<slot />
|
||||
</Accordion>
|
||||
|
|
|
|||
|
|
@ -13,19 +13,25 @@ import Link from "./Link.astro";
|
|||
|
||||
const versions = await getVersionsData();
|
||||
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 ?? "");
|
||||
|
||||
interface NavTree {
|
||||
title: string,
|
||||
slug: string,
|
||||
entries?: NavTree[],
|
||||
title: string;
|
||||
slug: string;
|
||||
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}`;
|
||||
|
||||
return {
|
||||
|
|
@ -38,7 +44,9 @@ function mkTree(mount: string, pathIdx: number, { title, slug, entries }: NavTre
|
|||
|
||||
function genGuideNav(base: string): NavTree[] | undefined {
|
||||
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)
|
||||
.map(page => ({
|
||||
title: page.data.title,
|
||||
|
|
@ -68,8 +76,8 @@ if (versionName) {
|
|||
entries: module.types.map(type => ({
|
||||
title: type.name,
|
||||
slug: type.name,
|
||||
}))
|
||||
}))
|
||||
})),
|
||||
})),
|
||||
}),
|
||||
};
|
||||
|
||||
|
|
@ -84,6 +92,7 @@ if (versionName) {
|
|||
};
|
||||
}
|
||||
---
|
||||
|
||||
<nav class="navtree">
|
||||
<Link
|
||||
title="About"
|
||||
|
|
@ -96,7 +105,7 @@ if (versionName) {
|
|||
current={currentPath.length === 1 && currentPath[0] === "changelog"}
|
||||
/>
|
||||
{versionedEntries && <Tree {...versionsTree as TreeEntry}/>}
|
||||
<hr/>
|
||||
<hr>
|
||||
{versionedEntries && (
|
||||
<Tree {...versionedEntries.guide}/>
|
||||
<Tree {...versionedEntries.types}/>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ const NavComponent: Component<SidebarContent> = props => {
|
|||
if (
|
||||
isLink ||
|
||||
!isInBody ||
|
||||
//@ts-expect-error
|
||||
(isInBody && !navRef.contains(event.target as Node))
|
||||
) {
|
||||
setOpen(false);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ interface Props extends TreeEntry {}
|
|||
|
||||
const { title, link, entries, current } = Astro.props;
|
||||
---
|
||||
|
||||
<NavCollapsible title={title} link={link} current={current ?? false}>
|
||||
{entries?.map(entry => entry.entries ? (
|
||||
<Self {...entry}/>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ export interface Props {
|
|||
|
||||
const { mobile } = Astro.props;
|
||||
---
|
||||
|
||||
<aside class=`nav-wrapper${mobile ? "-mobile" : ""} id="nav"`>
|
||||
{ mobile ? (
|
||||
<SidebarWrapper client:load>
|
||||
|
|
|
|||
|
|
@ -20,10 +20,12 @@ export const Table: Component<{
|
|||
if (configTOC) {
|
||||
return (
|
||||
<div class="toc-content">
|
||||
{title && <>
|
||||
{title && (
|
||||
<>
|
||||
<p>{title}</p>
|
||||
<hr />
|
||||
</>}
|
||||
</>
|
||||
)}
|
||||
<For each={configTOC}>
|
||||
{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,
|
||||
} from "solid-js";
|
||||
|
||||
import { Article } from "@icons";
|
||||
import { Article, MenuToX } from "@icons";
|
||||
import { Table } from "./Table";
|
||||
import type { TOCProps } from "../types";
|
||||
import { buildHierarchy } from "@config/io/helpers";
|
||||
|
|
@ -27,7 +27,10 @@ const TableOfContents: Component<TOCProps> = props => {
|
|||
return 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 (
|
||||
isLink ||
|
||||
!isInBody ||
|
||||
//@ts-expect-error
|
||||
(isInBody && !tocRef.contains(event.target as Node))
|
||||
) {
|
||||
setOpen(false);
|
||||
|
|
@ -92,13 +96,17 @@ const TableOfContents: Component<TOCProps> = props => {
|
|||
id="toc-toggle"
|
||||
>
|
||||
<div onclick={e => toggle(e)}>
|
||||
<Article />
|
||||
<Article class={`toc-icon ${!open() ? "active" : ""}`} />
|
||||
<MenuToX class={`toc-icon ${open() ? "active" : ""}`} />
|
||||
</div>
|
||||
<div class={`toc-mobile ${open() ? "shown" : ""}`}>
|
||||
{type ? (
|
||||
<Table typeTOC={type} />
|
||||
) : (
|
||||
<Table title={title} configTOC={buildHierarchy(config!)} />
|
||||
<Table
|
||||
title={title}
|
||||
configTOC={buildHierarchy(config!)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
---
|
||||
import type {
|
||||
QMLTypeLinkObject,
|
||||
QuickshellFunction,
|
||||
} from "@config/io/types";
|
||||
import type { QMLTypeLinkObject, QuickshellFunction } from "@config/_types";
|
||||
import { getQMLTypeLink } from "@config/io/helpers";
|
||||
import { Tag } from "@icons";
|
||||
import TypeDetails from "./TypeDetails.astro";
|
||||
|
|
@ -15,9 +12,9 @@ export interface Props {
|
|||
const { funcData } = Astro.props;
|
||||
const { version } = Astro.params;
|
||||
---
|
||||
|
||||
<ul class="typedata typefuncs">
|
||||
{
|
||||
funcData.map(item => {
|
||||
{funcData.map((item:QuickshellFunction) => {
|
||||
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)
|
||||
let genericType:string|undefined;
|
||||
|
|
@ -57,6 +54,5 @@ const { version } = Astro.params;
|
|||
<TypeDetails markdown={item.details} />
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
})}
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ import { getQMLTypeLink } from "@config/io/helpers";
|
|||
import type {
|
||||
QMLTypeLinkObject,
|
||||
QuickshellProps,
|
||||
} from "@config/io/types";
|
||||
QuickshellInstance,
|
||||
} from "@config/_types";
|
||||
import { Tag } from "@icons";
|
||||
import TypeTitle from "./TypeTitle.astro";
|
||||
|
||||
|
|
@ -16,9 +17,10 @@ export interface Props {
|
|||
const { props } = Astro.props;
|
||||
const { version } = Astro.params;
|
||||
---
|
||||
|
||||
<ul class="typedata typeprops">
|
||||
{
|
||||
Object.entries(props).map(([name, propData]) => {
|
||||
{Object.keys(props).map((name) => {
|
||||
const propData:QuickshellInstance = props[name];
|
||||
let typeLink: string;
|
||||
let linkText: string;
|
||||
let genericType: string|undefined;
|
||||
|
|
@ -66,6 +68,5 @@ const { version } = Astro.params;
|
|||
<TypeDetails markdown={propData.details} />
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
})}
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import { getQMLTypeLink } from "@config/io/helpers";
|
||||
import type { QuickshellSignal } from "@config/io/types";
|
||||
import type { QuickshellSignal } from "@config/_types";
|
||||
import { Tag } from "@icons";
|
||||
import TypeDetails from "./TypeDetails.astro";
|
||||
import TypeTitle from "./TypeTitle.astro";
|
||||
|
|
@ -12,17 +12,25 @@ export interface Props {
|
|||
const { signals } = Astro.props;
|
||||
const { version } = Astro.params;
|
||||
---
|
||||
|
||||
<ul class="typedata typesignals">
|
||||
{
|
||||
Object.entries(signals).map(([name, signalData]) => {
|
||||
const paramKeys = signalData.params.length > 0 ? signalData.params.map((param,index) => `${param.name}${index !== signalData.params.length -1 ? ", ":""}`) : []
|
||||
{(Object.entries(signals) as [
|
||||
keyof QuickshellSignal,
|
||||
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 genericTypeLink:string|undefined;
|
||||
return (
|
||||
<li id={ name } class="typedata-root typesignal-root">
|
||||
<li id={ name.toString() } class="typedata-root typesignal-root">
|
||||
<TypeTitle
|
||||
typekind="signal"
|
||||
typename={name}
|
||||
typename={ name.toString() }
|
||||
typelink="/docs/configuration/qml-overview#-signals"
|
||||
typelink_text=""
|
||||
typename_generic={genericType}
|
||||
|
|
@ -50,6 +58,5 @@ const { version } = Astro.params;
|
|||
<TypeDetails markdown={signalData.details} />
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
})}
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ const { version } = Astro.params;
|
|||
|
||||
const html = markdown ? await processMarkdown(version!, markdown) : null;
|
||||
---
|
||||
|
||||
<section class="typedata-details">
|
||||
{html ? <div class="typedata-detailsdata" set:html={html} /> : <em>No details provided</em>}
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -31,10 +31,13 @@ const iconSelector: { [key: string]: string } = {
|
|||
variant: "fourdiamonds",
|
||||
};
|
||||
---
|
||||
|
||||
<div class={`typedata-title type${typekind}-title`}>
|
||||
<section class={`typedata-name type${typekind}-name`}>
|
||||
{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>
|
||||
|
|
@ -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>
|
||||
}
|
||||
</span>}
|
||||
</section>
|
||||
<section class="type-badges">
|
||||
{badges && badges.length > 0 ? (
|
||||
badges.map(badgeText => <Badge badgeText={badgeText}/>)
|
||||
badges.map((badgeText:string) => <Badge badgeText={badgeText}/>)
|
||||
) : null}
|
||||
</section>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import type { QuickshellVariant } from "@config/io/types";
|
||||
import type { QuickshellVariant } from "@config/_types";
|
||||
import TypeDetails from "./TypeDetails.astro";
|
||||
import TypeTitle from "./TypeTitle.astro";
|
||||
|
||||
|
|
@ -9,17 +9,20 @@ export interface Props {
|
|||
|
||||
const { variants } = Astro.props;
|
||||
---
|
||||
|
||||
<ul class="typedata typevariants">
|
||||
{
|
||||
Object.entries(variants).map(([name, variantData]) => {
|
||||
{(Object.entries(variants) as [
|
||||
keyof QuickshellVariant,
|
||||
QuickshellVariant[keyof QuickshellVariant],
|
||||
][]).map(([name, variantData]) => {
|
||||
const paramKeys = variantData.params && variantData.params.length > 0
|
||||
? variantData.params.map(param => param.name)
|
||||
: [];
|
||||
return (
|
||||
<li id={ name } class="typedata-root typevariant-root">
|
||||
<li id={ name.toString() } class="typedata-root typevariant-root">
|
||||
<TypeTitle
|
||||
typekind="variant"
|
||||
typename={name}
|
||||
typename={ name.toString() }
|
||||
typelink=""
|
||||
typelink_text=""
|
||||
/>
|
||||
|
|
@ -36,7 +39,5 @@ const { variants } = Astro.props;
|
|||
<TypeDetails markdown={variantData.details} />
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
})}
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
|
|
@ -12,30 +12,48 @@ interface Props {
|
|||
const { title, description } = Astro.props;
|
||||
---
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<link rel="canonical" href={Astro.url} />
|
||||
<link rel="sitemap" href="/sitemap-index.xml" />
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="generator" content={Astro.generator}>
|
||||
<link rel="canonical" href={Astro.url}>
|
||||
<link rel="sitemap" href="/sitemap-index.xml">
|
||||
|
||||
<title>{title}</title>
|
||||
<meta name="description" content={description} />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="description" content={description}>
|
||||
<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 -->
|
||||
<meta name="og:type" content="website" />
|
||||
<meta name="og:site_name" content="quickshell" />
|
||||
<meta name="og:url" content={Astro.url} />
|
||||
<meta name="og:title" content={title} />
|
||||
<meta name="og:description" content={description} />
|
||||
<meta name="og:type" content="website">
|
||||
<meta name="og:site_name" content="quickshell">
|
||||
<meta name="og:url" content={Astro.url}>
|
||||
<meta name="og:title" content={title}>
|
||||
<meta name="og:description" content={description}>
|
||||
<!-- <meta name="og:image" content={image} /> -->
|
||||
|
||||
<!-- Twitter Meta Tags -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:domain" content="quickshell.outfoxxed.me" />
|
||||
<meta name="twitter:url" content={Astro.url} />
|
||||
<meta name="twitter:title" content={title} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:domain" content="quickshell.outfoxxed.me">
|
||||
<meta name="twitter:url" content={Astro.url}>
|
||||
<meta name="twitter:title" content={title}>
|
||||
<meta name="twitter:description" content={description}>
|
||||
<!-- <meta name="twitter:image" content={image} /> -->
|
||||
|
||||
<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 {
|
||||
type: string;
|
||||
module: string;
|
||||
|
|
@ -53,7 +41,7 @@ interface QuickshellSignal {
|
|||
};
|
||||
}
|
||||
|
||||
export interface QuickshellVariant {
|
||||
interface QuickshellVariant {
|
||||
[key: string]: {
|
||||
name?: string;
|
||||
details: string;
|
||||
|
|
@ -61,7 +49,7 @@ export interface QuickshellVariant {
|
|||
};
|
||||
}
|
||||
|
||||
export interface TypeData {
|
||||
interface TypeData {
|
||||
name: string;
|
||||
description: string;
|
||||
details: string;
|
||||
|
|
@ -72,37 +60,27 @@ export interface TypeData {
|
|||
functions?: QuickshellFunction[];
|
||||
signals?: QuickshellSignal;
|
||||
variants?: QuickshellVariant;
|
||||
subtypes?: QuickshellData[];
|
||||
// FIXME: QuickshellData[]
|
||||
subtypes?: any[];
|
||||
}
|
||||
|
||||
export interface ModuleData {
|
||||
interface ModuleData {
|
||||
name: string;
|
||||
description: string;
|
||||
details: string;
|
||||
types: TypeData[];
|
||||
}
|
||||
|
||||
export interface VersionData {
|
||||
interface VersionData {
|
||||
name: string;
|
||||
changelog?: string;
|
||||
modules: ModuleData[];
|
||||
}
|
||||
|
||||
export interface VersionsData {
|
||||
interface VersionsData {
|
||||
default: string;
|
||||
versions: VersionData[];
|
||||
}
|
||||
// --
|
||||
|
||||
// helpers.ts
|
||||
interface QMLTypeLinkObject {
|
||||
type: string;
|
||||
module?: string;
|
||||
name?: string;
|
||||
mtype?: string;
|
||||
mname?: string;
|
||||
}
|
||||
// --
|
||||
|
||||
export type {
|
||||
QuickshellBase,
|
||||
|
|
@ -116,5 +94,4 @@ export type {
|
|||
ModuleData,
|
||||
VersionData,
|
||||
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 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 modules = await Promise.all(moduleDirs.map(async moduleDir => {
|
||||
const modules = await Promise.all(
|
||||
moduleDirs.map(async moduleDir => {
|
||||
const modulePath = path.join(basePath, moduleDir);
|
||||
|
||||
const indexPromise = async () => {
|
||||
|
|
@ -15,22 +18,28 @@ async function readModulesData(basePath: string): Promise<ModuleData[]> {
|
|||
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 typePath = path.join(modulePath, fileName);
|
||||
const fileContent = await fs.readFile(typePath, "utf8");
|
||||
return JSON.parse(fileContent);
|
||||
});
|
||||
|
||||
const [index, ...types] = await Promise.all([indexPromise(), ...typePromises]);
|
||||
const [index, ...types] = await Promise.all([
|
||||
indexPromise(),
|
||||
...typePromises,
|
||||
]);
|
||||
|
||||
return {
|
||||
name: index.name,
|
||||
description: index.description,
|
||||
details: index.details,
|
||||
types,
|
||||
}
|
||||
}));
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
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 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,
|
||||
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),
|
||||
})));
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
return {
|
||||
versions,
|
||||
default: data.default,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let globalVersionsData: Promise<VersionsData>;
|
||||
|
|
@ -71,5 +92,6 @@ export function getVersionsData(): Promise<VersionsData> {
|
|||
|
||||
export async function getModulesData(): Promise<ModuleData[]> {
|
||||
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";
|
||||
|
||||
// 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 guidePages = await getCollection("guide");
|
||||
|
||||
const pages: { [key: string]: CollectionEntry<'guide'> } = {};
|
||||
const pages: { [key: string]: CollectionEntry<"guide"> } = {};
|
||||
|
||||
for (const currentVersion of versions.toReversed()) {
|
||||
for (const page of guidePages) {
|
||||
let [guideVersion, id] = page.id.split('/');
|
||||
guideVersion = guideVersion.replaceAll('_', '.');
|
||||
let [guideVersion, id] = page.id.split("/");
|
||||
guideVersion = guideVersion.replaceAll("_", ".");
|
||||
id = id ?? "index";
|
||||
if (guideVersion !== currentVersion.name) continue;
|
||||
|
||||
|
|
@ -24,12 +29,18 @@ async function buildGuideCollection(version: string): Promise<CollectionEntry<'g
|
|||
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)) {
|
||||
guideCollections[version] = buildGuideCollection(version);
|
||||
}
|
||||
|
||||
return guideCollections[version];
|
||||
}
|
||||
|
||||
export { getGuideCollection };
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import type {
|
|||
ConfigHeading,
|
||||
ConfigTOC,
|
||||
} from "@components/navigation/sidebars/types";
|
||||
import type { QMLTypeLinkObject } from "./types";
|
||||
import type { QMLTypeLinkObject } from "@_types";
|
||||
|
||||
export function buildHierarchy(headings: ConfigHeading[]) {
|
||||
const toc: ConfigTOC[] = [];
|
||||
|
|
@ -30,7 +30,7 @@ export function buildHierarchy(headings: ConfigHeading[]) {
|
|||
let depth = heading.depth - 1;
|
||||
let parent = null;
|
||||
|
||||
while (!parent && depth != 0) {
|
||||
while (!parent && depth !== 0) {
|
||||
parent = parentHeadings.get(depth);
|
||||
depth -= 1;
|
||||
}
|
||||
|
|
@ -96,13 +96,10 @@ export function getQMLTypeLinkObject(unparsed: string) {
|
|||
return hashMap[index]();
|
||||
}
|
||||
|
||||
export function getQMLTypeLink(version: string, {
|
||||
type,
|
||||
module,
|
||||
name,
|
||||
mtype,
|
||||
mname,
|
||||
}: QMLTypeLinkObject) {
|
||||
export function getQMLTypeLink(
|
||||
version: string,
|
||||
{ type, module, name, mtype, mname }: QMLTypeLinkObject
|
||||
) {
|
||||
if (type === "unknown") {
|
||||
return "#unknown";
|
||||
}
|
||||
|
|
@ -116,7 +113,9 @@ export function getQMLTypeLink(version: string, {
|
|||
return localLink;
|
||||
},
|
||||
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}`;
|
||||
return qtLink;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -14,16 +14,20 @@ import { remarkAlert } from "remark-github-blockquote-alert";
|
|||
import rehypeShiki from "@shikijs/rehype";
|
||||
import sectionize from "@hbsnow/rehype-sectionize";
|
||||
import type { ShikiTransformer } from "shiki";
|
||||
import { h } from "hastscript";
|
||||
|
||||
import {
|
||||
getQMLTypeLinkObject,
|
||||
getQMLTypeLink,
|
||||
getIconForLink,
|
||||
} from "./helpers.ts";
|
||||
import type { CopyButtonOptions } from "@_types";
|
||||
|
||||
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) => {
|
||||
if (
|
||||
rawNode.type === "text" ||
|
||||
|
|
@ -31,7 +35,6 @@ const remarkParseAtTypes: RemarkPlugin<[]> = () => (root: Md.Root): Md.Root => {
|
|||
(rawNode as Md.Code).lang === "qml")
|
||||
) {
|
||||
const node = rawNode as Md.Literal;
|
||||
|
||||
node.value = node.value.replace(
|
||||
/@@(?<path>([A-Z]\w*\.)*([A-Z]\w*))?((?<member>[a-z]\w*)((?<function>\(\))|(?<signal>\(s\)))?)?(?=[$.,;:)\s]|$)/g,
|
||||
(_full, ...args) => {
|
||||
|
|
@ -43,9 +46,11 @@ const remarkParseAtTypes: RemarkPlugin<[]> = () => (root: Md.Root): Md.Root => {
|
|||
};
|
||||
|
||||
const groups = args.pop() as Capture;
|
||||
const pathp = (groups.path ?? "").split('.').filter(Boolean);
|
||||
let type = (pathp.length >= 1 ? pathp.pop() : "");
|
||||
let module = pathp.join('_');
|
||||
const pathp = (groups.path ?? "")
|
||||
.split(".")
|
||||
.filter(Boolean);
|
||||
let type = pathp.length >= 1 ? pathp.pop() : "";
|
||||
let module = pathp.join("_");
|
||||
|
||||
if (module) {
|
||||
const isQs = module.startsWith("Quickshell");
|
||||
|
|
@ -67,7 +72,9 @@ const remarkParseAtTypes: RemarkPlugin<[]> = () => (root: Md.Root): Md.Root => {
|
|||
return root;
|
||||
};
|
||||
|
||||
const rehypeRewriteTypelinks: RehypePlugin<[]> = () => (root: Html.Root): Html.Root => {
|
||||
const rehypeRewriteTypelinks: RehypePlugin<[]> =
|
||||
() =>
|
||||
(root: Html.Root): Html.Root => {
|
||||
visit(
|
||||
root as Unist.Parent,
|
||||
"text",
|
||||
|
|
@ -80,7 +87,10 @@ const rehypeRewriteTypelinks: RehypePlugin<[]> = () => (root: Html.Root): Html.R
|
|||
changed = true;
|
||||
|
||||
const linkObject = getQMLTypeLinkObject(match);
|
||||
const link = getQMLTypeLink(currentVersion, linkObject);
|
||||
const link = getQMLTypeLink(
|
||||
currentVersion,
|
||||
linkObject
|
||||
);
|
||||
const icon =
|
||||
linkObject.mtype && linkObject.mtype !== "func"
|
||||
? getIconForLink(linkObject.mtype, false)
|
||||
|
|
@ -101,21 +111,23 @@ const rehypeRewriteTypelinks: RehypePlugin<[]> = () => (root: Html.Root): Html.R
|
|||
parent.children.splice(index, 1, ...fragment.children);
|
||||
return SKIP;
|
||||
}
|
||||
|
||||
return CONTINUE;
|
||||
}
|
||||
);
|
||||
|
||||
return root;
|
||||
};
|
||||
|
||||
const rehypeRewriteVersionedDoclinks: RehypePlugin<[]> = () => (root: Html.Root): Html.Root => {
|
||||
const rehypeRewriteVersionedDoclinks: RehypePlugin<[]> =
|
||||
() =>
|
||||
(root: Html.Root): Html.Root => {
|
||||
visit(
|
||||
root as Unist.Parent,
|
||||
"element",
|
||||
({ tagName, properties }: Html.Element) => {
|
||||
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)}`;
|
||||
return CONTINUE;
|
||||
}
|
||||
|
|
@ -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,
|
||||
remarkPlugins: [
|
||||
remarkParseAtTypes,
|
||||
|
|
@ -168,7 +242,7 @@ export const markdownConfig: AstroMarkdownOptions = {
|
|||
},
|
||||
defaultColor: false,
|
||||
wrap: true,
|
||||
transformers: [shikiRewriteTypelinks],
|
||||
transformers: [shikiRewriteTypelinks, shikiCopyButton],
|
||||
},
|
||||
],
|
||||
// FIXME: incompatible types between unified/Plugin and Astro/RehypePlugin
|
||||
|
|
@ -185,18 +259,23 @@ let globalMarkdownProcessor: Promise<MarkdownProcessor>;
|
|||
|
||||
async function getMarkdownProcessor(): Promise<MarkdownProcessor> {
|
||||
if (!globalMarkdownProcessor) {
|
||||
globalMarkdownProcessor = createMarkdownProcessor(markdownConfig);
|
||||
globalMarkdownProcessor =
|
||||
createMarkdownProcessor(markdownConfig);
|
||||
}
|
||||
|
||||
return globalMarkdownProcessor;
|
||||
}
|
||||
|
||||
export async function processMarkdown(
|
||||
async function processMarkdown(
|
||||
version: string,
|
||||
markdown: string,
|
||||
markdown: string
|
||||
): Promise<string> {
|
||||
currentVersion = version;
|
||||
const r = (await (await getMarkdownProcessor()).render(markdown)).code;
|
||||
const r = (
|
||||
await (await getMarkdownProcessor()).render(markdown)
|
||||
).code;
|
||||
currentVersion = "NOVERSION";
|
||||
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";
|
||||
|
||||
const guide = defineCollection({
|
||||
loader: glob({ pattern: "**/*.md", base: "src/guide" }),
|
||||
loader: glob({ pattern: "**/*.{md,mdx}", base: "src/guide" }),
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
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 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]
|
||||
> 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.
|
||||
|
||||
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.
|
||||
|
||||
> [!note/Note]
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ Name {
|
|||
|
||||
Every object can contain [properties](#properties), [functions](#functions),
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
title: "QML Language"
|
||||
index: 10
|
||||
---
|
||||
import Collapsible from "@components/Collapsible.astro";
|
||||
|
||||
Quickshell is configured using the Qt Modeling Language, or QML.
|
||||
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),
|
||||
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
|
||||
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
---
|
||||
//import Header from "@components/Header.astro";
|
||||
import Head from "@config/Head.astro";
|
||||
import PreTheme from "@config/PreTheme.astro";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
|
|
@ -14,10 +13,20 @@ const { title, description } = Astro.props;
|
|||
<html lang="en" class="dark">
|
||||
<head>
|
||||
<Head description={description} title={title} />
|
||||
<PreTheme />
|
||||
</head>
|
||||
<body class="baselayout">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="theme-manual-toggle"
|
||||
class="theme-toggle-input"
|
||||
style="display: none;"
|
||||
aria-label="Toggle theme (light/dark)"
|
||||
>
|
||||
<!--<Header />-->
|
||||
<slot />
|
||||
<script>
|
||||
import "@config/styling/animations_helper.ts";
|
||||
import "@config/styling/theme_persistence.ts";
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -2,29 +2,29 @@
|
|||
import { Breadcrumbs } from "astro-breadcrumbs";
|
||||
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 Head from "@config/Head.astro";
|
||||
import Nav from "@components/navigation/sidebars/nav/index.astro";
|
||||
import type { ConfigHeading } from "@src/components/navigation/sidebars/types";
|
||||
import Footer from "@src/components/Footer.astro";
|
||||
import type { TypeData } from "@config/io/types";
|
||||
import type { TypeData } from "@config/_types";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
headings?: ConfigHeading[];
|
||||
type?: TypeData
|
||||
type?: TypeData;
|
||||
}
|
||||
|
||||
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",
|
||||
href: "/",
|
||||
}];
|
||||
},
|
||||
];
|
||||
|
||||
let linkPath = "";
|
||||
if (url[0] === "docs") {
|
||||
|
|
@ -49,16 +49,27 @@ for (const segment of url) {
|
|||
<html lang="en" class="dark">
|
||||
<head>
|
||||
<Head description={description} title={title} />
|
||||
<PreTheme />
|
||||
<CreateCopyButtons />
|
||||
</head>
|
||||
<body class="docslayout">
|
||||
<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">
|
||||
<Nav mobile={false} />
|
||||
<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
|
||||
<!-- @ts-expect-error -->
|
||||
slot="index"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em"
|
||||
|
|
@ -69,25 +80,61 @@ for (const segment of url) {
|
|||
<path
|
||||
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"
|
||||
></path></svg
|
||||
>
|
||||
></path>
|
||||
</svg>
|
||||
<svg
|
||||
<!-- @ts-expect-error -->
|
||||
slot="separator"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 256 256"
|
||||
><path
|
||||
>
|
||||
<path
|
||||
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"
|
||||
></path></svg
|
||||
>
|
||||
></path>
|
||||
</svg>
|
||||
</Breadcrumbs>
|
||||
<slot />
|
||||
</div>
|
||||
<slot name="alongside-content" />
|
||||
</div>
|
||||
<Footer />
|
||||
<script>
|
||||
import "@config/styling/animations_helper.ts";
|
||||
import "@config/styling/theme_persistence.ts";
|
||||
</script>
|
||||
</body>
|
||||
</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 TOC from "@components/navigation/sidebars/TOC.astro";
|
||||
import TOCIntersectionObserver from "@src/components/hooks/TOCIntersectionObserver.astro";
|
||||
import type { ConfigHeading } from "@src/components/navigation/sidebars/types";
|
||||
|
||||
export interface Props {
|
||||
|
|
@ -12,15 +11,20 @@ export interface Props {
|
|||
|
||||
const { title, description, headings } = Astro.props;
|
||||
---
|
||||
|
||||
<DocsLayout title={title} description={description} headings={headings}>
|
||||
<div class="docs">
|
||||
<div class="docs-content">
|
||||
<hr/>
|
||||
<hr>
|
||||
<h1>{title}</h1>
|
||||
<slot />
|
||||
</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>
|
||||
|
||||
<TOCIntersectionObserver/>
|
||||
|
|
|
|||
|
|
@ -7,11 +7,15 @@ export interface Props {
|
|||
frontmatter: {
|
||||
title: string;
|
||||
description?: string;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const { headings, frontmatter: { title, description } } = Astro.props;
|
||||
const {
|
||||
headings,
|
||||
frontmatter: { title, description },
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
<GuideLayout title={title} description={description ?? ""} headings={headings}>
|
||||
<slot />
|
||||
</GuideLayout>
|
||||
|
|
|
|||
|
|
@ -5,10 +5,14 @@ import { processMarkdown } from "@config/io/markdown";
|
|||
|
||||
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,
|
||||
changelog: await processMarkdown(version.name, version.changelog!)
|
||||
})));
|
||||
changelog: await processMarkdown(version.name, version.changelog ?? ""),
|
||||
}))
|
||||
);
|
||||
|
||||
const headings = versionsMd.map(({ version }) => ({
|
||||
text: version.name,
|
||||
|
|
@ -16,6 +20,7 @@ const headings = versionsMd.map(({ version }) => ({
|
|||
depth: 1,
|
||||
}));
|
||||
---
|
||||
|
||||
<GuideLayout title="Changelog" description="" headings={headings}>
|
||||
{versionsMd.map(({ version, changelog }) => (
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
|
|
|
|||
|
|
@ -2,31 +2,39 @@
|
|||
import GuideLayout from "@layouts/GuideLayout.astro";
|
||||
import { getVersionsData } from "@config/io/generateTypeData";
|
||||
import { getGuideCollection } from "@config/io/guides";
|
||||
import { processMarkdown } from "@config/io/markdown";
|
||||
|
||||
import { render } from "astro:content";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
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);
|
||||
|
||||
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 },
|
||||
}));
|
||||
}));
|
||||
})
|
||||
);
|
||||
|
||||
return pages.flat();
|
||||
}
|
||||
|
||||
const { version, page } = Astro.props;
|
||||
const { headings } = await render(page);
|
||||
const { page } = Astro.props;
|
||||
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
|
||||
const html = await processMarkdown(version.name, page.body!);
|
||||
|
||||
// const html = await processMarkdown(version.name, page.body!);
|
||||
---
|
||||
|
||||
<GuideLayout title={page.data.title} description="" headings={headings}>
|
||||
<Fragment set:html={html}/>
|
||||
<Content />
|
||||
</GuideLayout>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export async function getStaticPaths() {
|
|||
|
||||
const { version } = Astro.props;
|
||||
---
|
||||
|
||||
<DocsLayout title="Quickshell Docs" description="Quickshell Documentation">
|
||||
<h2>Docs</h2>
|
||||
<div class="root-nav">
|
||||
|
|
|
|||
|
|
@ -9,12 +9,25 @@ import Functions from "@components/type/Functions.astro";
|
|||
import Signals from "@components/type/Signals.astro";
|
||||
import Variants from "@components/type/Variants.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() {
|
||||
return (await getVersionsData()).versions.flatMap(version => {
|
||||
return version.modules.flatMap(module => {
|
||||
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 },
|
||||
}));
|
||||
});
|
||||
|
|
@ -29,10 +42,15 @@ const details = type.details
|
|||
? await processMarkdown(version.name, type.details)
|
||||
: 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-content typedocs-content">
|
||||
<hr />
|
||||
<hr>
|
||||
<section class="typedocs-title">
|
||||
<h2 class="typedocs-title-text" data-pagefind-weight="10">
|
||||
{type.name}:
|
||||
|
|
@ -45,11 +63,10 @@ const details = type.details
|
|||
</a>
|
||||
):(
|
||||
<span class="type-datatype" data-pagefind-ignore>{type.name}</span>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</h2>
|
||||
{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}/>
|
||||
))}</div>
|
||||
)}
|
||||
|
|
@ -64,13 +81,13 @@ const details = type.details
|
|||
<Properties props={type.properties!}/>
|
||||
)}
|
||||
{(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
|
||||
funcData={type.functions!}
|
||||
/>
|
||||
)}
|
||||
{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={type.signals!}
|
||||
/>
|
||||
|
|
@ -86,4 +103,3 @@ const details = type.details
|
|||
<TOC mobile={false} type={type} data-pagefind-ignore />
|
||||
</div>
|
||||
</DocsLayout>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import DocsLayout from "@layouts/DocsLayout.astro";
|
||||
import { getVersionsData } from "@config/io/generateTypeData";
|
||||
import { processMarkdown } from "@src/config/io/markdown";
|
||||
import type { TypeData } from "@_types";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
return (await getVersionsData()).versions.flatMap(version => {
|
||||
|
|
@ -23,12 +24,12 @@ const details = module.details
|
|||
description="Quickshell Type Documentation"
|
||||
>
|
||||
<div class="docs-content">
|
||||
<hr />
|
||||
<hr>
|
||||
<h2 class="typedocs-title">{module.name} Definitions</h2>
|
||||
<section>
|
||||
<span>{module.description}</span>
|
||||
<div class="root-nav" data-pagefind-ignore>
|
||||
{module.types.map(type =>
|
||||
{module.types.map((type: TypeData) =>
|
||||
(
|
||||
<div class="root-nav-entry">
|
||||
<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 { getVersionsData } from "@config/io/generateTypeData";
|
||||
import type { ModuleData } from "@_types";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
return (await getVersionsData()).versions.map(version => ({
|
||||
|
|
@ -11,14 +12,18 @@ export async function getStaticPaths() {
|
|||
|
||||
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">
|
||||
<hr/>
|
||||
<hr>
|
||||
<h2>Module Listing</h2>
|
||||
<section>
|
||||
<span>All modules included with Quickshell</span>
|
||||
<div class="root-nav" data-pagefind-ignore>
|
||||
{version.modules.map(module => (
|
||||
{version.modules.map((module: ModuleData) => (
|
||||
<div class="root-nav-entry">
|
||||
<a class="root-nav-link" href={`/docs/${version.name}/types/${module.name}`}>
|
||||
{module.name}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,18 @@ const defaultVersion = (await getVersionsData()).default;
|
|||
|
||||
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">
|
||||
Quickshell 0.2.1 has been released! | 2025-10-11
|
||||
</a>-->
|
||||
<div class="main-page_hero" data-pagefind-ignore>
|
||||
<div class="titlebox">
|
||||
<img src="/favicon.svg" alt="Quickshell"/>
|
||||
<img src="/favicon.svg" alt="Quickshell">
|
||||
<h1 class="gradient-text">Quickshell</h1>
|
||||
</div>
|
||||
<section class="main-page_hero-text">
|
||||
|
|
@ -24,26 +29,31 @@ const title = "Quickshell";
|
|||
<section class="about">
|
||||
<div class="about-txt">
|
||||
<p>
|
||||
Quickshell is a toolkit for building status bars, widgets, lockscreens,
|
||||
and other desktop components using QtQuick. It can be used alongside your
|
||||
wayland compositor or window manager to build a complete desktop environment.
|
||||
Quickshell is a toolkit for building status bars, widgets,
|
||||
lockscreens, and other desktop components using QtQuick. It can be
|
||||
used alongside your wayland compositor or window manager to build a
|
||||
complete desktop environment.
|
||||
<br class="about-break">
|
||||
<br class="about-break">
|
||||
<a href="/about">More information</a>
|
||||
</p>
|
||||
</div>
|
||||
<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>
|
||||
</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>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
<section class="featurelist-section">
|
||||
<FeatureList/>
|
||||
</section>
|
||||
<section class="featurelist-section"><FeatureList /></section>
|
||||
</div>
|
||||
<Footer class="frontpage-footer" />
|
||||
</BaseLayout>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
.accordion {
|
||||
& summary {
|
||||
list-style: none;
|
||||
transition: background-color 0.15s ease-out;
|
||||
transition: background-color var(--theme-transition);
|
||||
}
|
||||
|
||||
& .accordion-container {
|
||||
|
|
@ -12,7 +12,9 @@
|
|||
|
||||
& .accordion-container.animate {
|
||||
/* 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);
|
||||
max-height: var(--height);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,18 +12,22 @@
|
|||
.featurelist-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
gap: 0.618rem;
|
||||
gap: var(--xs);
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-block: 0.618rem;
|
||||
border-radius: 9px;
|
||||
margin-block: var(--xs);
|
||||
border-radius: var(--radius-md);
|
||||
background-color: hsl(var(--blue) 60% 98%);
|
||||
padding: 0.618rem;
|
||||
border: 1px solid hsl(var(--blue) 9% 75%);
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
border-color var(--theme-transition);
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0.618rem;
|
||||
inset: var(--xs);
|
||||
background-image: radial-gradient(
|
||||
hsl(var(--blue) 9% 75%) 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);
|
||||
border-color: hsl(0deg 0% 100% / 0.05);
|
||||
|
||||
|
|
@ -46,18 +51,22 @@ html.dark .featurelist-item {
|
|||
}
|
||||
|
||||
.feature-text {
|
||||
margin: 1rem 0;
|
||||
margin: var(--sm) 0;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
font-size: 1.2em;
|
||||
|
||||
& .feature-title {
|
||||
margin-bottom: 0.517rem;
|
||||
}
|
||||
|
||||
& .feature-subtitle {
|
||||
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 {
|
||||
color: #afafaf;
|
||||
}
|
||||
|
|
@ -72,7 +81,8 @@ html.dark .feature-text {
|
|||
& video {
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
border-radius: 0.681rem;
|
||||
border-radius: var(--radius-sm);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
& .shiki {
|
||||
|
|
@ -80,6 +90,7 @@ html.dark .feature-text {
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
/*font-size: 0.55rem;*/
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
& .showcase-desktop {
|
||||
|
|
@ -98,8 +109,13 @@ html.dark .feature-text {
|
|||
}
|
||||
}
|
||||
|
||||
html:not(.dark) .feature-showcase .shiki,
|
||||
html:not(.dark) .feature-showcase .shiki span {
|
||||
html:not(.dark):not(:has(input#theme-manual-toggle:checked))
|
||||
.feature-showcase
|
||||
.shiki,
|
||||
html:not(.dark):not(:has(input#theme-manual-toggle:checked))
|
||||
.feature-showcase
|
||||
.shiki
|
||||
span {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
|
|
@ -118,6 +134,7 @@ html:not(.dark) .feature-showcase .shiki span {
|
|||
position: absolute;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
& .cloud-center img {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
|
|
@ -140,6 +157,7 @@ html:not(.dark) .feature-showcase .shiki span {
|
|||
& > div {
|
||||
transform: rotate(0deg);
|
||||
animation: counter-spin 40s linear infinite;
|
||||
|
||||
& .feature-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
|
|
@ -149,26 +167,34 @@ html:not(.dark) .feature-showcase .shiki span {
|
|||
&.wayland {
|
||||
transform: translate(-50%, 0) rotate(0deg);
|
||||
}
|
||||
|
||||
&.hyprland {
|
||||
transform: translate(-50%, 0) rotate(72deg);
|
||||
|
||||
& .feature-icon {
|
||||
transform: rotate(-72deg);
|
||||
}
|
||||
}
|
||||
|
||||
&.pipewire {
|
||||
transform: translate(-50%, 0) rotate(144deg);
|
||||
|
||||
& .feature-icon {
|
||||
transform: rotate(-144deg);
|
||||
}
|
||||
}
|
||||
|
||||
&.x-org {
|
||||
transform: translate(-50%, 0) rotate(216deg);
|
||||
|
||||
& .feature-icon {
|
||||
transform: rotate(-216deg);
|
||||
}
|
||||
}
|
||||
|
||||
&.sway {
|
||||
transform: translate(-50%, 0) rotate(288deg);
|
||||
|
||||
& .feature-icon {
|
||||
transform: rotate(-288deg);
|
||||
}
|
||||
|
|
@ -180,6 +206,7 @@ html:not(.dark) .feature-showcase .shiki span {
|
|||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
|
|
@ -189,6 +216,7 @@ html:not(.dark) .feature-showcase .shiki span {
|
|||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
|
|
@ -213,33 +241,42 @@ html:not(.dark) .feature-showcase .shiki span {
|
|||
width: auto;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.feature-text {
|
||||
margin: 0 2.218rem;
|
||||
}
|
||||
|
||||
.featurelist-item {
|
||||
width: 100%;
|
||||
padding: 1.217rem;
|
||||
justify-content: space-between;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.featurelist-item.right {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.feature-showcase {
|
||||
height: 22rem;
|
||||
}
|
||||
|
||||
.feature-text {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.feature-showcase {
|
||||
width: auto;
|
||||
aspect-ratio: 16 / 9;
|
||||
|
||||
& video {
|
||||
scale: 1;
|
||||
}
|
||||
|
||||
& .shiki {
|
||||
font-size: 0.93rem;
|
||||
}
|
||||
|
||||
.feature-cloud {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 2.217rem;
|
||||
font-size: 1.874rem;
|
||||
gap: var(--xl);
|
||||
font-size: var(--lg);
|
||||
font-weight: 600;
|
||||
margin-inline: 0.618rem;
|
||||
margin-inline: var(--sm);
|
||||
}
|
||||
|
||||
.marquee-button {
|
||||
|
|
@ -20,36 +20,63 @@
|
|||
left: 2px;
|
||||
right: 2px;
|
||||
height: 3px;
|
||||
background-color: hsl(var(--accent-400) / 0.3);
|
||||
background-color: hsla(var(--accent-400) / 0.3);
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
.marquee {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin-block: 1.618rem;
|
||||
justify-content: center;
|
||||
margin-block: var(--xl);
|
||||
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 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
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 {
|
||||
flex: 1 0 100%;
|
||||
transition: transform 0.3s cubic-bezier(0.46, 0.03, 0.52, 0.96);
|
||||
transform: translateX(var(--scroll));
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: var(--md);
|
||||
padding-inline: 0.5rem;
|
||||
box-sizing: border-box;
|
||||
will-change: opacity;
|
||||
|
||||
& > div {
|
||||
& > * {
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
& video {
|
||||
position: relative;
|
||||
max-width: 75rem;
|
||||
width: 100%;
|
||||
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,34 +85,38 @@
|
|||
}
|
||||
|
||||
.marquee-item-content {
|
||||
border-radius: 6px;
|
||||
border-radius: var(--radius-sm);
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.marquee-scroll {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 100%;
|
||||
max-width: 85rem;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
transition:
|
||||
background-color 0.3s,
|
||||
opacity 0.3s;
|
||||
z-index: 10;
|
||||
user-select: none;
|
||||
align-items: stretch;
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
opacity var(--theme-transition);
|
||||
z-index: 20;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
|
||||
.marquee-scroll-arrow {
|
||||
max-width: 8rem;
|
||||
width: 8rem;
|
||||
font-size: 2rem;
|
||||
pointer-events: all;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
|
||||
& > div {
|
||||
width: 2.5rem;
|
||||
|
|
@ -95,10 +126,12 @@
|
|||
justify-content: center;
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.3s ease;
|
||||
backdrop-filter: blur(var(--2xs));
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
|
||||
& > div {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
|
@ -132,14 +165,10 @@
|
|||
@media not (min-width: 83rem) {
|
||||
.marquee-scroll-arrow {
|
||||
height: unset;
|
||||
|
||||
& > div {
|
||||
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%;
|
||||
}
|
||||
}
|
||||
|
||||
@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 {
|
||||
font-family: "Rubik Variable", Inter, system-ui, Avenir, Helvetica, Arial,
|
||||
sans-serif;
|
||||
font-family:
|
||||
"Rubik Variable", Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.272;
|
||||
font-weight: 400;
|
||||
|
||||
height: 100svh;
|
||||
/* width: 100svw; causes horizontal overflow due to the scrollbar*/
|
||||
width: 100%;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-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;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
/* transition: all 0.15s var(--ease-in-out); */
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
pre.shiki {
|
||||
margin-block: 1.618rem;
|
||||
margin-block: var(--lg);
|
||||
}
|
||||
|
||||
:where(p, li):has(> code) code {
|
||||
padding-inline: 0.272rem;
|
||||
border-radius: 0.272rem;
|
||||
color: hsl(var(--blue) 100% 69%);
|
||||
background-color: hsl(var(--blue) 85% 35% / 0.1);
|
||||
padding-inline: var(--sm);
|
||||
border-radius: var(--radius-xs);
|
||||
color: hsl(var(--blue) 100 69);
|
||||
background-color: hsla(var(--blue) 85 35 / 0.1);
|
||||
}
|
||||
|
||||
.shiki,
|
||||
|
|
@ -16,7 +16,9 @@ pre.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);
|
||||
background-color: var(--shiki-dark-bg);
|
||||
}
|
||||
|
|
@ -26,8 +28,11 @@ pre {
|
|||
border-radius: 0.618rem;
|
||||
overflow: hidden;
|
||||
text-wrap: wrap;
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
color var(--theme-transition);
|
||||
|
||||
& > button {
|
||||
& .copy-button {
|
||||
all: unset;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
|
|
@ -41,17 +46,51 @@ pre {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: hsl(var(--blue) 100% 69%);
|
||||
background-color: hsl(var(--blue) 85% 35% / 0.1);
|
||||
color: hsla(var(--blue) 100 69 / 0.33);
|
||||
background-color: hsla(var(--blue) 85 35 / 0.01);
|
||||
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 {
|
||||
color: hsl(var(--blue) 100% 75%);
|
||||
color: hsla(var(--blue) 100 75 / 0.75);
|
||||
background-color: hsla(var(--blue) 85 35 / 0.1);
|
||||
}
|
||||
|
||||
&.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 {
|
||||
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"] {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
transition: all 300ms;
|
||||
transition: all var(--theme-transition);
|
||||
}
|
||||
|
||||
[data-scope="collapsible"][data-part="content"][data-state="open"] {
|
||||
|
|
|
|||
|
|
@ -68,7 +68,9 @@
|
|||
margin-bottom: 0.618rem;
|
||||
border-radius: 12px;
|
||||
padding: 0.8rem;
|
||||
transition: border 0.3s;
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
border-color var(--theme-transition);
|
||||
}
|
||||
|
||||
& .typedata-details {
|
||||
|
|
@ -164,6 +166,9 @@
|
|||
.typeprops {
|
||||
& .typeprop-root {
|
||||
border: 1px solid hsl(var(--prop-color) / 0.6);
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
border-color var(--theme-transition);
|
||||
|
||||
&:hover {
|
||||
border: 1px solid hsl(var(--prop-color));
|
||||
|
|
@ -175,11 +180,13 @@
|
|||
|
||||
& .typeprop-name {
|
||||
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 {
|
||||
border: 1px solid hsl(var(--prop-color) / 0.3);
|
||||
|
||||
|
|
@ -193,6 +200,9 @@ html.dark .typeprops {
|
|||
.typefuncs {
|
||||
& .typefunc-root {
|
||||
border: 1px solid hsl(var(--func-color) / 0.6);
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
border-color var(--theme-transition);
|
||||
|
||||
&:hover {
|
||||
border: 1px solid hsl(var(--func-color));
|
||||
|
|
@ -204,6 +214,7 @@ html.dark .typeprops {
|
|||
|
||||
& .typefunc-name {
|
||||
color: hsl(var(--func-link-color));
|
||||
transition: color var(--theme-transition);
|
||||
}
|
||||
|
||||
& .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 {
|
||||
border: 1px solid hsl(var(--func-color) / 0.3);
|
||||
|
||||
|
|
@ -236,6 +248,9 @@ html.dark .typefuncs {
|
|||
.typesignals {
|
||||
& .typesignal-root {
|
||||
border: 1px solid hsl(var(--signal-color) / 0.6);
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
border-color var(--theme-transition);
|
||||
|
||||
&:hover {
|
||||
border: 1px solid hsl(var(--signal-color));
|
||||
|
|
@ -249,6 +264,7 @@ html.dark .typefuncs {
|
|||
position: relative;
|
||||
width: max-content;
|
||||
color: hsl(var(--signal-link-color));
|
||||
transition: color var(--theme-transition);
|
||||
|
||||
& .typesignal-doclink {
|
||||
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 {
|
||||
border: 1px solid hsl(var(--signal-color) / 0.3);
|
||||
|
||||
|
|
@ -288,6 +305,9 @@ html.dark .typesignals {
|
|||
.typevariants {
|
||||
& .typevariant-root {
|
||||
border: 1px solid hsl(var(--var-color) / 0.6);
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
border-color var(--theme-transition);
|
||||
|
||||
&:hover {
|
||||
border: 1px solid hsl(var(--var-color));
|
||||
|
|
@ -301,6 +321,7 @@ html.dark .typesignals {
|
|||
position: relative;
|
||||
width: max-content;
|
||||
color: hsl(var(--var-link-color));
|
||||
transition: color var(--theme-transition);
|
||||
|
||||
& .typevariant-doclink {
|
||||
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 {
|
||||
border: 1px solid hsl(var(--var-color) / 0.3);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
@import "./docs-types.css";
|
||||
|
||||
.docslayout {
|
||||
transition: background-color 0.3s;
|
||||
transition: background-color var(--theme-transition);
|
||||
}
|
||||
|
||||
.docslayout-root {
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
justify-content: safe center;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
transition: filter 0.3s;
|
||||
transition: filter var(--theme-transition);
|
||||
}
|
||||
|
||||
.docslayout-inner {
|
||||
|
|
@ -31,8 +31,9 @@
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
:not(html.dark) > .dim-content-toc,
|
||||
:not(html.dark) > .dim-content-nav {
|
||||
html:not(.dark):not(:has(input#theme-manual-toggle:checked)) > .dim-content-toc,
|
||||
html:not(.dark):not(:has(input#theme-manual-toggle:checked))
|
||||
> .dim-content-nav {
|
||||
background-color: #909090;
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +67,7 @@
|
|||
--color-link-breadcrumbs: hsl(var(--link));
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.318rem;
|
||||
max-width: 100svw;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.heading {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@
|
|||
.nav-item {
|
||||
display: block;
|
||||
border-radius: 6px;
|
||||
transition: background-color 0.2s ease;
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
color var(--theme-transition);
|
||||
padding: 0.4em;
|
||||
font-size: 1rem;
|
||||
|
||||
|
|
@ -39,11 +41,8 @@
|
|||
}
|
||||
|
||||
.fade {
|
||||
-webkit-mask-image: linear-gradient(
|
||||
to right,
|
||||
#000 80%,
|
||||
transparent
|
||||
);
|
||||
mask-image: linear-gradient(to right, #000 80%, transparent);
|
||||
-webkit-mask-image: linear-gradient(to right, #000 80%, transparent);
|
||||
}
|
||||
|
||||
.nav-collapsible {
|
||||
|
|
@ -55,7 +54,9 @@
|
|||
& > div {
|
||||
& > .nav-collapse-marker,
|
||||
a {
|
||||
transition: background-color 0.2s ease;
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
color var(--theme-transition);
|
||||
}
|
||||
|
||||
& > .nav-collapse-marker {
|
||||
|
|
|
|||
|
|
@ -7,12 +7,16 @@
|
|||
|
||||
.nav-icon {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
position: absolute;
|
||||
transition: opacity 0.6s;
|
||||
transition:
|
||||
opacity var(--theme-transition),
|
||||
transform var(--theme-transition);
|
||||
}
|
||||
|
||||
.nav-icon.active {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +54,9 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
transition: left 0.3s ease, padding 0.3s ease;
|
||||
transition:
|
||||
left 0.3s ease,
|
||||
padding 0.3s ease;
|
||||
|
||||
&.shown {
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@
|
|||
--search-corners: calc(0.3125rem * var(--pagefind-ui-scale));
|
||||
--search-page-icon-size: calc(1.875rem * var(--pagefind-ui-scale));
|
||||
--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-inline-start: calc(
|
||||
|
|
@ -57,9 +58,11 @@
|
|||
|
||||
#qs_search .pagefind-ui__search-clear::before {
|
||||
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;
|
||||
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;
|
||||
background-color: hsl(0deg 25% 45%);
|
||||
display: block;
|
||||
|
|
@ -166,9 +169,11 @@
|
|||
inset-inline-start: var(--search-tree-diagram-inline-start);
|
||||
width: var(--search-tree-diagram-size);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -204,9 +209,11 @@
|
|||
inset-inline-start: var(--search-tree-diagram-inline-start);
|
||||
width: var(--search-tree-diagram-size);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -219,7 +226,8 @@
|
|||
|
||||
/* default styles */
|
||||
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 4px 4px hsl(0deg, 0%, 0%, 0.75), 0px 4px 2px hsl(0deg, 0%, 0%, 0.25);
|
||||
display: contents;
|
||||
|
|
@ -275,7 +283,8 @@ button > kbd {
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
color: hsl(var(--blue) 40% 65%);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,28 @@
|
|||
font-size: 1.614rem;
|
||||
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 {
|
||||
height: 100%;
|
||||
width: 24px;
|
||||
|
|
@ -61,7 +83,9 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
transition: width 0.3s ease, padding 0.3s ease;
|
||||
transition:
|
||||
width 0.3s ease,
|
||||
padding 0.3s ease;
|
||||
|
||||
&.shown {
|
||||
& .toc-content {
|
||||
|
|
@ -115,7 +139,7 @@
|
|||
margin-right: 1.272rem;
|
||||
|
||||
& .toc_a {
|
||||
transition: color 0.33s;
|
||||
transition: color var(--theme-transition);
|
||||
color: hsl(var(--toc-link));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
@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 "./docs/nav/nav.css";
|
||||
|
|
@ -15,42 +12,69 @@
|
|||
@import "./components/featurelist.css";
|
||||
@import "./components/marquee.css";
|
||||
|
||||
.changing-theme * {
|
||||
transition: none !important;
|
||||
.theme-toggle {
|
||||
height: 24px;
|
||||
font-size: 1.614rem;
|
||||
color: hsla(var(--signal-color) / 0.7);
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
color: hsla(var(--signal-color) / 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* color styling */
|
||||
.header {
|
||||
background-color: hsl(var(--bg-400));
|
||||
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,
|
||||
.docslayout {
|
||||
background-color: hsl(var(--background));
|
||||
color: hsl(var(--secondary-900));
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
color var(--theme-transition);
|
||||
}
|
||||
|
||||
a {
|
||||
color: hsl(var(--link));
|
||||
text-decoration: none;
|
||||
transition: color var(--theme-transition);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
color: hsl(var(--secondary-400));
|
||||
}
|
||||
|
||||
html.dark {
|
||||
html.dark,
|
||||
html:has(input#theme-manual-toggle:checked) {
|
||||
& .header {
|
||||
background-color: hsl(var(--secondary-900));
|
||||
color: hsl(var(--secondary-500));
|
||||
}
|
||||
|
||||
& .theme-toggle {
|
||||
color: hsla(var(--func-color) / 0.7);
|
||||
|
||||
&:hover {
|
||||
color: hsla(var(--func-color) / 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* layout and positioning */
|
||||
|
|
@ -65,6 +89,7 @@ html.dark {
|
|||
transparent
|
||||
);
|
||||
}
|
||||
|
||||
.unset {
|
||||
all: unset;
|
||||
}
|
||||
|
|
@ -133,47 +158,63 @@ body.overflow-toc {
|
|||
display: block;
|
||||
}
|
||||
|
||||
.theme-toggle {
|
||||
height: 24px;
|
||||
font-size: 1.614rem;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
position: relative;
|
||||
margin-top: var(--2xl);
|
||||
width: 100%;
|
||||
font-size: 0.9rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 1rem 2rem;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
background: hsl(var(--footer-bkg));
|
||||
transition:
|
||||
background-color var(--theme-transition),
|
||||
color var(--theme-transition);
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -1rem;
|
||||
left: 0;
|
||||
right: calc(50% + 1.25rem);
|
||||
height: 1px;
|
||||
width: calc(100% + 1rem);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
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%
|
||||
);
|
||||
}
|
||||
|
||||
& .theme-toggle {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: max-content;
|
||||
height: max-content;
|
||||
}
|
||||
|
||||
& a {
|
||||
color: hsl(var(--text-dark));
|
||||
transition: color 0.3s ease;
|
||||
transition: color var(--theme-transition);
|
||||
|
||||
& .hint {
|
||||
transition: color 0.3s ease;
|
||||
transition: color var(--theme-transition);
|
||||
}
|
||||
|
||||
&:nth-child(2) .hint {
|
||||
|
|
@ -223,10 +264,11 @@ footer {
|
|||
gap: 0.373rem;
|
||||
align-items: flex-start;
|
||||
font-size: 2.5rem;
|
||||
|
||||
}
|
||||
|
||||
& .changelog {
|
||||
display: flex;
|
||||
|
||||
& a {
|
||||
text-decoration: none;
|
||||
margin-inline: auto;
|
||||
|
|
|
|||
|
|
@ -45,16 +45,15 @@ h1.gradient-text {
|
|||
hsl(var(--green) 80% 42%),
|
||||
hsl(var(--blue) 80% 49%)
|
||||
);
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
html.dark h1.gradient-text {
|
||||
background: linear-gradient(
|
||||
30deg,
|
||||
#42b96b,
|
||||
#4281b9
|
||||
);
|
||||
html.dark h1.gradient-text,
|
||||
html:has(input#theme-manual-toggle:checked) h1.gradient-text {
|
||||
background: linear-gradient(30deg, #42b96b, #4281b9);
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
-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 {
|
||||
color: hsl(var(--blue) 100% 83%);
|
||||
}
|
||||
|
|
@ -95,7 +95,9 @@ html.dark .main-page_hero-text {
|
|||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.about-break { display: none }
|
||||
.about-break {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.about-buttons {
|
||||
display: flex;
|
||||
|
|
@ -130,12 +132,13 @@ html.dark .main-page_hero-text {
|
|||
align-items: center;
|
||||
width: 100%;
|
||||
height: 3.67rem;
|
||||
border-radius: 9px;
|
||||
border-radius: var(--radius-sm);
|
||||
overflow: hidden;
|
||||
border: 1px solid hsl(var(--green) 10% 10%);
|
||||
box-shadow: var(--shadow-md);
|
||||
transition:
|
||||
background-color 0.3s,
|
||||
border-color 0.3s;
|
||||
background-color var(--theme-transition),
|
||||
box-shadow var(--theme-transition),
|
||||
border-color var(--theme-transition);
|
||||
|
||||
background-color: hsl(var(--green) 38% 30%);
|
||||
color: hsl(194deg 0% 100%);
|
||||
|
|
@ -143,17 +146,22 @@ html.dark .main-page_hero-text {
|
|||
&:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
border-color: hsl(var(--green) 20% 20%);
|
||||
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 {
|
||||
border-color: hsl(var(--blue) 10% 10%);
|
||||
background-color: hsl(var(--blue) 38% 30%);
|
||||
|
||||
&:hover {
|
||||
border-color: hsl(var(--blue) 20% 20%);
|
||||
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%);
|
||||
color: hsl(194deg 0% 100%);
|
||||
|
||||
|
|
@ -226,7 +235,15 @@ html.dark .main-page_link-card {
|
|||
flex-direction: row;
|
||||
}
|
||||
|
||||
.about-txt { max-width: 70% }
|
||||
.about-break { display: unset }
|
||||
.about-buttons { flex-direction: column }
|
||||
.about-txt {
|
||||
max-width: 70%;
|
||||
}
|
||||
|
||||
.about-break {
|
||||
display: unset;
|
||||
}
|
||||
|
||||
.about-buttons {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": ["src/**/*", "**/**.d.ts", "pagefind.ts"],
|
||||
"compilerOptions": {
|
||||
"lib": ["es2023"],
|
||||
"plugins": [
|
||||
{
|
||||
"name": "@astrojs/ts-plugin"
|
||||
|
|
@ -9,32 +11,25 @@
|
|||
"jsx": "preserve",
|
||||
"jsxImportSource": "solid-js",
|
||||
"verbatimModuleSyntax": true,
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@*": [
|
||||
"./*"
|
||||
],
|
||||
"@/*": [
|
||||
"./src/*"
|
||||
],
|
||||
"@config/*": [
|
||||
"./src/config/*"
|
||||
],
|
||||
"@icons": [
|
||||
"./src/components/icons.tsx"
|
||||
],
|
||||
"@icons/*": [
|
||||
"./src/icons/*"
|
||||
],
|
||||
"@components/*": [
|
||||
"./src/components/*"
|
||||
],
|
||||
"@layouts/*": [
|
||||
"./src/layouts/*"
|
||||
],
|
||||
"@styles/*": [
|
||||
"./src/styles/*"
|
||||
]
|
||||
}
|
||||
"@*": ["./*"],
|
||||
"@/*": ["./src/*"],
|
||||
"@config/*": ["./src/config/*"],
|
||||
"@icons": ["./src/components/icons.tsx"],
|
||||
"@icons/*": ["./src/icons/*"],
|
||||
"@components/*": ["./src/components/*"],
|
||||
"@layouts/*": ["./src/layouts/*"],
|
||||
"@styles/*": ["./src/styles/*"],
|
||||
"@_types": ["./src/config/_types/index.ts"],
|
||||
"@_types/*": ["./src/config/_types/*"]
|
||||
},
|
||||
"types": ["astro/client"]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue