mirror of
https://gitee.com/docsifyjs/docsify.git
synced 2024-11-29 18:48:14 +08:00
feat: v5 style overhaul (#2469)
Style updates: - New "core" theme serves as base for all other themes (official and third-party) - New CSS custom properties for simplified customization of "core" theme **Note:** List of available properties will be made available in documentation by embedding soruce CSS in docs after merge. Merge is required because embedded CSS needs to be in `main` branch. For now, see `_vars.css` and `_vars-advanced.css` for details. - New theme "add-ons" modify core theme properties and/or add custom declarations as needed. - New Prism.js theme support - New configurable sidebar toggle design - New typography defaults to system sans-serif and monospace fonts instead of relying on external web font. - New "Core Dark" theme addon provide dark theme styles. Can optionally be applied based on operating system's light/dark setting using `@media` attribute on `<link>` element. - New "Vue" theme addon. Closely replicated popular v4 theme while allowing for v5 enhancements. - New CSS class names available for adding loading indicators, adding sidebar expand/collapse icons, adding sidebar group styles, clamping sidebar links to a single line with ellipses, and changing the sidebar toggle icon. - New auto-generated gradient background for cover page (ensure gradient hue is > 50 degree apart, use OKLCH color if supported, randomize grandient angle, reduce brightness in dark mode) - New button styles (basic, primary, secondary) - New form element styles (text input, radio, checkbox, ) - New "callouts" (previously "important" and "tip" helpers) - New default syntax highlighting theme (from [docsify-themeable](https://jhildenbiddle.github.io/docsify-themeable/)) - New auto-generated theme color shade and tint colors - New auto-generated monochromatic color palette - New form element styles (fields, legend, text input, text area, checkbox, radio, toggles, and select) - New "headerless" tables - New `kbd` styles - New task list style - New merged navbar styles (consistent with sidebar nav styles) - New search plugin styles and keyboard shortcut indicators - Add ability restore previously focused content element after hiding sidebar - Add "focus trap" when sidebar is visible on mobile (accessibility) - Add ability for sidebar links to wrap by default (previous single-line w/ ellipsis display available as CSS class on `<body>` option) - Add sidebar `page-link`, `group`, and `group-title` CSS classes to sidebar markup. - Add reduced motion media query to set all animation/transition timings to zero - Update Google Font imports (use new variable vs older fixed width fonts) - Update primary/secondary button order on coverpage (primary should be first) - Fix missing merged navbar when loading at desktop resolution then resizing to mobile - Fix inverted open/close sidebar visibility state at desktop/mobile resolutions - Fix overflow setting to prevent clipping of element focus ring - Fix safe area inset margins on mobile in landscape orientation - Fix inverted "tip" and "warn" class names - Fix scroll padding to prevent headers from touching top edge of viewport when scrolled to - Remove Stylus dependency (now using only PostCSS) - Remove legacy themes "Buble", "Dark", "Dolphin", and "Pure". Documentation updates: - New "UI Kit" page showcasing all elements styled by Docsify - Update "Quick Start" page template - Update "Adding pages" page with information on how to properly create sidebar group titles and navbar drop-down menus - Update "Themes" page with theme and class toggles - Update "Configuration" page with deprecation warnings for `themeColor` and `topMargin` - Move "Edit Page" link to footer - Remove [docsify-themeable](https://jhildenbiddle.github.io/docsify-themeable/) endorsement (currently not compatible with v5 and future is unknown) Miscellaneous updates: - New search plugin options: `insertBefore` and `insertAfter` - Add PostCSS config file - Update BrowserSync config (disable "ghost" mode) - Update tests - Fix Jest + Prettier 3 conflict - Fix `getAndRemoveDocisfyIgnoreConfig` name type (now `Docisfy` => `Docsify`) - Fix execution of sidebar-generating code when `hiddenSidebar` is `true` - Remove `inBrowser` constant (SSR deprecated, so no longer needed)
This commit is contained in:
parent
90c0b02c63
commit
77d93fae78
@ -1,4 +1,3 @@
|
||||
.eslintignore
|
||||
.eslintrc.cjs
|
||||
.github
|
||||
.gitignore
|
||||
|
@ -4,6 +4,8 @@ dist
|
||||
lib
|
||||
|
||||
# Files
|
||||
_vars.css
|
||||
_vars-advanced.css
|
||||
CHANGELOG.md
|
||||
emoji-data.*
|
||||
HISTORY.md
|
@ -1,4 +1,4 @@
|
||||
## docsify
|
||||
# docsify
|
||||
|
||||
> A magical documentation site generator.
|
||||
|
||||
|
@ -1,12 +1,17 @@
|
||||
<!-- markdownlint-disable first-line-h1 -->
|
||||
|
||||
![logo](_media/icon.svg)
|
||||
|
||||
# docsify <small>4.13.0</small>
|
||||
|
||||
> A magical documentation site generator.
|
||||
> A magical documentation site generator
|
||||
|
||||
- Simple and lightweight
|
||||
- No statically built html files
|
||||
- No statically built HTML files
|
||||
- Multiple themes
|
||||
|
||||
[Get Started](#docsify)
|
||||
[GitHub](https://github.com/docsifyjs/docsify/)
|
||||
[Getting Started](#docsify)
|
||||
|
||||
<!-- ![color](#f0f0f0) -->
|
||||
<!-- ![](/_media/icon.svg) -->
|
||||
|
@ -1 +1,31 @@
|
||||
<h1>To infinity and Beyond!</h1>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #4158d0;
|
||||
background-image: linear-gradient(
|
||||
43deg,
|
||||
#4158d0 0%,
|
||||
#c850c0 46%,
|
||||
#ffcc70 100%
|
||||
);
|
||||
color: #fff;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
|
||||
<main>
|
||||
<p>Example HTML Page</p>
|
||||
</main>
|
||||
|
1
docs/_media/moon.svg
Normal file
1
docs/_media/moon.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg fill="none" height="800" viewBox="0 0 24 24" width="800" xmlns="http://www.w3.org/2000/svg"><path d="m13 6v-3m5.5 9v-5m-4-2.5h-3m9.5 5h-5m-.4452 7.3151c1.2281 0 2.3945-.2645 3.4452-.7397-1.3133 2.904-4.2358 4.9246-7.6302 4.9246-4.62249 0-8.3698-3.7473-8.3698-8.3698 0-3.39444 2.02061-6.31689 4.92462-7.6302-.47518 1.05072-.7397 2.21708-.7397 3.44523 0 4.62257 3.74728 8.36987 8.36988 8.36987z" stroke="#d6f5ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg>
|
After Width: | Height: | Size: 487 B |
1
docs/_media/sun.svg
Normal file
1
docs/_media/sun.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg fill="none" height="800" viewBox="0 0 24 24" width="800" xmlns="http://www.w3.org/2000/svg"><path d="m12 3v1m0 16v1m-8-9h-1m3.31412-5.68588-.81412-.81412m12.1859.81412.8141-.81412m-12.18588 12.19-.81412.8101m12.1859-.8101.8141.8101m2.5-6.5001h-1m-4 0c0 2.2091-1.7909 4-4 4-2.20914 0-4-1.7909-4-4 0-2.20914 1.79086-4 4-4 2.2091 0 4 1.79086 4 4z" stroke="#ffd333" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg>
|
After Width: | Height: | Size: 438 B |
@ -1,4 +1,7 @@
|
||||
<!-- markdownlint-disable first-line-h1 -->
|
||||
|
||||
- Translations
|
||||
|
||||
- [:uk: English](/)
|
||||
- [:cn: 简体中文](/zh-cn/)
|
||||
- [:de: Deutsch](/de-de/)
|
||||
|
@ -1,9 +1,11 @@
|
||||
<!-- markdownlint-disable first-line-h1 -->
|
||||
|
||||
- Getting started
|
||||
|
||||
- [Quick start](quickstart.md)
|
||||
- [Writing more pages](more-pages.md)
|
||||
- [Custom navbar](custom-navbar.md)
|
||||
- [Adding pages](adding-pages.md)
|
||||
- [Cover page](cover.md)
|
||||
- [Custom navbar](custom-navbar.md)
|
||||
|
||||
- Customization
|
||||
|
||||
@ -23,6 +25,7 @@
|
||||
- [CDN](cdn.md)
|
||||
- [Offline Mode (PWA)](pwa.md)
|
||||
- [Embed Files](embed-files.md)
|
||||
- [UI Kit](ui-kit.md)
|
||||
|
||||
- [Awesome docsify](awesome.md)
|
||||
- [Changelog](changelog.md)
|
||||
|
@ -1,4 +1,4 @@
|
||||
# More pages
|
||||
# Adding pages
|
||||
|
||||
If you need more pages, you can simply create more markdown files in your docsify directory. If you create a file named `guide.md`, then it is accessible via `/#/guide`.
|
||||
|
||||
@ -46,7 +46,23 @@ Create the `_sidebar.md`:
|
||||
<!-- docs/_sidebar.md -->
|
||||
|
||||
- [Home](/)
|
||||
- [Guide](guide.md)
|
||||
- [Page 1](page-1.md)
|
||||
```
|
||||
|
||||
To create section headers:
|
||||
|
||||
```markdown
|
||||
<!-- docs/_sidebar.md -->
|
||||
|
||||
- Section Header 1
|
||||
|
||||
- [Home](/)
|
||||
- [Page 1](page-1.md)
|
||||
|
||||
- Section Header 2
|
||||
|
||||
- [Page 2](page-2.md)
|
||||
- [Page 3](page-3.md)
|
||||
```
|
||||
|
||||
You need to create a `.nojekyll` in `./docs` to prevent GitHub Pages from ignoring files that begin with an underscore.
|
@ -376,7 +376,7 @@ window.$docsify = {
|
||||
|
||||
Website logo as it appears in the sidebar. You can resize it using CSS.
|
||||
|
||||
!> Logo will only bee visible if `name` prop is also set. See [name](#name) configuration.
|
||||
!> Logo will only be visible if `name` prop is also set. See [name](#name) configuration.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
@ -917,17 +917,9 @@ If you have a link to the homepage in the sidebar and want it to be shown as act
|
||||
|
||||
For more details, see [#1131](https://github.com/docsifyjs/docsify/issues/1131).
|
||||
|
||||
## themeColor (_deprecated_)
|
||||
## themeColor ⚠️
|
||||
|
||||
> **Warning** Deprecated. Use the CSS var `--theme-color` in your `<style>` sheet. Example:
|
||||
>
|
||||
> ```html
|
||||
> <style>
|
||||
> :root {
|
||||
> --theme-color: deeppink;
|
||||
> }
|
||||
> </style>
|
||||
> ```
|
||||
!> Deprecated as of v5. Use the `--theme-color` [theme property](themes#theme-properties) to [customize](themes#customization) your theme color.
|
||||
|
||||
- Type: `String`
|
||||
|
||||
@ -939,16 +931,18 @@ window.$docsify = {
|
||||
};
|
||||
```
|
||||
|
||||
## topMargin
|
||||
## topMargin ⚠️
|
||||
|
||||
- Type: `Number`
|
||||
!> Deprecated as of v5. Use the `--scroll-padding-top` [theme property](themes#theme-properties) to specify a scroll margin when using a sticky navbar.
|
||||
|
||||
- Type: `Number|String`
|
||||
- Default: `0`
|
||||
|
||||
Adds a space on top when scrolling the content page to reach the selected section. This is useful in case you have a _sticky-header_ layout and you want to align anchors to the end of your header.
|
||||
Adds scroll padding to the top of the viewport. This is useful when you have added a sticky or "fixed" element and would like auto scrolling to align with the bottom of your element.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
topMargin: 90, // default: 0
|
||||
topMargin: 90, // 90, '90px', '2rem', etc.
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -6,15 +6,10 @@ Activate the cover feature by setting `coverpage` to **true**. See [coverpage co
|
||||
|
||||
Set `coverpage` to **true**, and create a `_coverpage.md`:
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<script>
|
||||
window.$docsify = {
|
||||
coverpage: true,
|
||||
};
|
||||
</script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify@5/dist/docsify.min.js"></script>
|
||||
```js
|
||||
window.$docsify = {
|
||||
coverpage: true,
|
||||
};
|
||||
```
|
||||
|
||||
```markdown
|
||||
@ -22,42 +17,50 @@ Set `coverpage` to **true**, and create a `_coverpage.md`:
|
||||
|
||||
![logo](_media/icon.svg)
|
||||
|
||||
# docsify <small>3.5</small>
|
||||
# docsify
|
||||
|
||||
> A magical documentation site generator.
|
||||
> A magical documentation site generator
|
||||
|
||||
- Simple and lightweight
|
||||
- No statically built html files
|
||||
- No statically built HTML files
|
||||
- Multiple themes
|
||||
|
||||
[GitHub](https://github.com/docsifyjs/docsify/)
|
||||
[Get Started](#docsify)
|
||||
```
|
||||
|
||||
## Custom background
|
||||
## Customization
|
||||
|
||||
The background color is generated randomly by default. You can customize the background color or a background image:
|
||||
The cover page can be customized using [theme properties](themes#theme-properties):
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```css
|
||||
:root {
|
||||
--cover-bg : url('path/to/image.png');
|
||||
--cover-bg-overlay : rgba(0, 0, 0, 0.5);
|
||||
--cover-color : #fff;
|
||||
--cover-title-color: var(--theme-color);
|
||||
--cover-title-font : 600 var(--font-size-xxxl) var(--font-family);
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, a background color or image can be specified in the cover page markdown.
|
||||
|
||||
```markdown
|
||||
<!-- _coverpage.md -->
|
||||
|
||||
# docsify <small>3.5</small>
|
||||
|
||||
[GitHub](https://github.com/docsifyjs/docsify/)
|
||||
[Get Started](#quick-start)
|
||||
|
||||
<!-- background image -->
|
||||
|
||||
![](_media/bg.png)
|
||||
|
||||
<!-- background color -->
|
||||
|
||||
![color](#f0f0f0)
|
||||
```
|
||||
|
||||
```markdown
|
||||
<!-- background image -->
|
||||
|
||||
![](_media/bg.png)
|
||||
```
|
||||
|
||||
## Coverpage as homepage
|
||||
|
||||
Normally, the coverpage and the homepage appear at the same time. Of course, you can also separate the coverpage by [onlyCover option](configuration.md#onlycover).
|
||||
Normally, the coverpage and the homepage appear at the same time. Of course, you can also separate the coverpage by [`onlyCover`](configuration.md#onlycover) option.
|
||||
|
||||
## Multiple covers
|
||||
|
||||
|
@ -40,6 +40,17 @@ Alternatively, you can create a custom markdown-based navigation file by setting
|
||||
- [chinese](/zh-cn/)
|
||||
```
|
||||
|
||||
To create drop-down menus:
|
||||
|
||||
```markdown
|
||||
<!-- _navbar.md -->
|
||||
|
||||
- Translations
|
||||
|
||||
- [En](/)
|
||||
- [chinese](/zh-cn/)
|
||||
```
|
||||
|
||||
!> You need to create a `.nojekyll` in `./docs` to prevent GitHub Pages from ignoring files that begin with an underscore.
|
||||
|
||||
`_navbar.md` is loaded from each level directory. If the current directory doesn't have `_navbar.md`, it will fall back to the parent directory. If, for example, the current path is `/guide/quick-start`, the `_navbar.md` will be loaded from `/guide/_navbar.md`.
|
||||
@ -59,6 +70,7 @@ You can create sub-lists by indenting items that are under a certain parent.
|
||||
- [Cover page](cover.md)
|
||||
|
||||
- Configuration
|
||||
|
||||
- [Configuration](configuration.md)
|
||||
- [Themes](themes.md)
|
||||
- [Using plugins](plugins.md)
|
||||
|
@ -4,7 +4,9 @@ docsify extends Markdown syntax to make your documents more readable.
|
||||
|
||||
> Note: For the special code syntax cases, it's better to put them within code backticks to avoid any conflict from configurations or emojis.
|
||||
|
||||
## Important content
|
||||
## Callouts
|
||||
|
||||
### Important content
|
||||
|
||||
Important content like:
|
||||
|
||||
@ -16,7 +18,7 @@ is rendered as:
|
||||
|
||||
!> **Time** is money, my friend!
|
||||
|
||||
## General tips
|
||||
### Tips
|
||||
|
||||
General tips like:
|
||||
|
||||
@ -28,7 +30,15 @@ are rendered as:
|
||||
|
||||
?> _TODO_ unit test
|
||||
|
||||
## Ignore to compile link
|
||||
## Link attributes
|
||||
|
||||
### disabled
|
||||
|
||||
```md
|
||||
[link](/demo ':disabled')
|
||||
```
|
||||
|
||||
### href
|
||||
|
||||
Sometimes we will use some other relative path for the link, and we have to tell docsify that we don't need to compile this link. For example:
|
||||
|
||||
@ -52,20 +62,14 @@ You will get `<a href="/demo/">link</a>`html. Do not worry, you can still set th
|
||||
<a href="/demo/" title="title">link</a>
|
||||
```
|
||||
|
||||
## Set target attribute for link
|
||||
### target
|
||||
|
||||
```md
|
||||
[link](/demo ':target=_blank')
|
||||
[link](/demo2 ':target=_self')
|
||||
```
|
||||
|
||||
## Disable link
|
||||
|
||||
```md
|
||||
[link](/demo ':disabled')
|
||||
```
|
||||
|
||||
## GitHub Task Lists
|
||||
## Task lists
|
||||
|
||||
```md
|
||||
- [ ] foo
|
||||
@ -83,9 +87,21 @@ You will get `<a href="/demo/">link</a>`html. Do not worry, you can still set th
|
||||
- [ ] bim
|
||||
- [ ] lim
|
||||
|
||||
## Image
|
||||
## Images
|
||||
|
||||
### Resizing
|
||||
### Class names
|
||||
|
||||
```md
|
||||
![logo](https://docsify.js.org/_media/icon.svg ':class=someCssClass')
|
||||
```
|
||||
|
||||
### IDs
|
||||
|
||||
```md
|
||||
![logo](https://docsify.js.org/_media/icon.svg ':id=someCssId')
|
||||
```
|
||||
|
||||
### Sizes
|
||||
|
||||
```md
|
||||
![logo](https://docsify.js.org/_media/icon.svg ':size=WIDTHxHEIGHT')
|
||||
@ -101,25 +117,13 @@ You will get `<a href="/demo/">link</a>`html. Do not worry, you can still set th
|
||||
![logo](https://docsify.js.org/_media/icon.svg ':size=100')
|
||||
![logo](https://docsify.js.org/_media/icon.svg ':size=10%')
|
||||
|
||||
### Customise class
|
||||
|
||||
```md
|
||||
![logo](https://docsify.js.org/_media/icon.svg ':class=someCssClass')
|
||||
```
|
||||
|
||||
### Customise ID
|
||||
|
||||
```md
|
||||
![logo](https://docsify.js.org/_media/icon.svg ':id=someCssId')
|
||||
```
|
||||
|
||||
## Customise ID for headings
|
||||
## Heading IDs
|
||||
|
||||
```md
|
||||
### Hello, world! :id=hello-world
|
||||
```
|
||||
|
||||
## Markdown in html tag
|
||||
## Markdown + HTML
|
||||
|
||||
You need to insert a space between the html and markdown content.
|
||||
This is useful for rendering markdown content in the details element.
|
||||
@ -156,7 +160,8 @@ Markdown content can also be wrapped in html tags.
|
||||
|
||||
<div style='color: red'>
|
||||
|
||||
- Abc
|
||||
- Abc
|
||||
- listitem
|
||||
- listitem
|
||||
- listitem
|
||||
|
||||
</div>
|
||||
|
109
docs/index.html
109
docs/index.html
@ -1,7 +1,7 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta charset="utf-8" />
|
||||
<title>docsify</title>
|
||||
<link rel="icon" href="_media/favicon.ico" />
|
||||
<meta
|
||||
@ -15,52 +15,74 @@
|
||||
<meta name="description" content="A magical documentation generator." />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0"
|
||||
content="width=device-width, initial-scale=1.0, viewport-fit=cover"
|
||||
/>
|
||||
|
||||
<!-- Core Theme -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/core.min.css"
|
||||
/>
|
||||
|
||||
<!-- Theme Add-on(s) -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/addons/core-dark.min.css"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
data-group="addon"
|
||||
data-sheet="core-dark-auto"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/vue.min.css"
|
||||
title="vue"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/dark.min.css"
|
||||
title="dark"
|
||||
href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/addons/core-dark.min.css"
|
||||
data-group="addon"
|
||||
data-sheet="core-dark"
|
||||
disabled
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/buble.min.css"
|
||||
title="buble"
|
||||
disabled
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/pure.min.css"
|
||||
title="pure"
|
||||
disabled
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/dolphin.min.css"
|
||||
title="dolphin"
|
||||
href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/addons/vue.min.css"
|
||||
data-group="addon"
|
||||
data-sheet="vue"
|
||||
disabled
|
||||
/>
|
||||
|
||||
<!-- Site styles -->
|
||||
<style>
|
||||
nav.app-nav li ul {
|
||||
min-width: 100px;
|
||||
/* Plugin: Carbon Ads */
|
||||
#carbonads > :last-child {
|
||||
margin-block: calc((1em * var(--line-height)) / 2);
|
||||
}
|
||||
|
||||
#carbonads {
|
||||
box-shadow: none !important;
|
||||
width: auto !important;
|
||||
/* UI Kit */
|
||||
.ui-kit-color {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
font-size: var(--font-size-s);
|
||||
}
|
||||
|
||||
.ui-kit-color figure {
|
||||
flex-grow: 1;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ui-kit-color figure div {
|
||||
height: 4rem;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
.ui-kit-color figcaption {
|
||||
text-align: center;
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
// Set html "lang" attribute based on URL
|
||||
(function () {
|
||||
const lang = location.hash.match(/#\/(de-de|es|ru-ru|zh-cn)\//);
|
||||
|
||||
// Set html "lang" attribute based on URL
|
||||
if (lang) {
|
||||
document.documentElement.setAttribute('lang', lang[1]);
|
||||
}
|
||||
@ -68,8 +90,8 @@
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">Loading ...</div>
|
||||
<body class="loading sidebar-chevron-right sidebar-group-box">
|
||||
<div id="app"></div>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-plugin-carbon@1"></script>
|
||||
<script>
|
||||
// Docsify configuration
|
||||
@ -92,10 +114,13 @@
|
||||
auto2top: true,
|
||||
coverpage: true,
|
||||
executeScript: true,
|
||||
// hideSidebar: true,
|
||||
loadSidebar: true,
|
||||
loadNavbar: true,
|
||||
mergeNavbar: true,
|
||||
// mergeNavbar: true,
|
||||
maxLevel: 4,
|
||||
// repo: 'docsifyjs/docsify',
|
||||
// routerMode: 'history',
|
||||
subMaxLevel: 2,
|
||||
ga: 'UA-106147152-1',
|
||||
matomo: {
|
||||
@ -111,6 +136,8 @@
|
||||
'/': '#/',
|
||||
},
|
||||
search: {
|
||||
// insertAfter: '.app-name',
|
||||
// insertBefore: '.sidebar-nav',
|
||||
noData: {
|
||||
'/es/': '¡No hay resultados!',
|
||||
'/de-de/': 'Keine Ergebnisse!',
|
||||
@ -188,6 +215,7 @@
|
||||
},
|
||||
plugins: [
|
||||
DocsifyCarbon.create('CEBI6KQE', 'docsifyjsorg'),
|
||||
// Plugin: Footer
|
||||
function (hook, vm) {
|
||||
hook.beforeEach(html => {
|
||||
if (/githubusercontent\.com/.test(vm.route.file)) {
|
||||
@ -203,13 +231,16 @@
|
||||
'https://github.com/docsifyjs/docsify/blob/develop/docs/' +
|
||||
vm.route.file;
|
||||
}
|
||||
const editHtml = '[:memo: Edit Document](' + url + ')\n';
|
||||
return (
|
||||
editHtml +
|
||||
html +
|
||||
'\n\n----\n\n' +
|
||||
'<a href="https://docsify.js.org" target="_blank" style="color: inherit; font-weight: normal; text-decoration: none;">Powered by docsify</a>'
|
||||
);
|
||||
|
||||
const footerHTML = [
|
||||
'<hr>',
|
||||
'<div style="display: flex; align-items: center; justify-content: space-between;">',
|
||||
' <span>Powered by <a href="/">Docsify.js</a></span>',
|
||||
` <a href="${url}" style="display: inline-flex; align-items: center; gap: 0.25em;">:memo: Edit Page</a>`,
|
||||
'</div>',
|
||||
].join('\n');
|
||||
|
||||
return html + footerHTML;
|
||||
});
|
||||
},
|
||||
],
|
||||
|
@ -1,37 +1,35 @@
|
||||
# Language highlighting
|
||||
|
||||
Docsify uses [Prism](https://prismjs.com) to highlight code blocks in your pages. Prism supports the following languages by default:
|
||||
## Prism
|
||||
|
||||
- Markup - `markup`, `html`, `xml`, `svg`, `mathml`, `ssml`, `atom`, `rss`
|
||||
- CSS - `css`
|
||||
- C-like - `clike`
|
||||
- JavaScript - `javascript`, `js`
|
||||
Docsify uses [Prism](https://prismjs.com) for syntax highlighting within code blocks. Prism supports the following languages by default (additional [language support](#language-support) also available):
|
||||
|
||||
Support for [additional languages](https://prismjs.com/#supported-languages) is available by loading the language-specific [grammar files](https://cdn.jsdelivr.net/npm/prismjs@1/components/) via CDN:
|
||||
- Markup: HTML, XML, SVG, MathML, SSML, Atom, RSS
|
||||
- CSS
|
||||
- C-like
|
||||
- JavaScript
|
||||
|
||||
```html
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-php.min.js"></script>
|
||||
```
|
||||
To enable syntax highlighting, create a markdown codeblock using backticks (` ``` `) with a [language](https://prismjs.com/#supported-languages) specified on the first line (e.g., `html`, `css`, `js`):
|
||||
|
||||
!> This `<script>` tag must be placed after the docisfy `<script>` to work.
|
||||
|
||||
To enable syntax highlighting, wrap each code block in triple backticks with the [language](https://prismjs.com/#supported-languages) specified on the first line:
|
||||
|
||||
````
|
||||
````text
|
||||
```html
|
||||
<p>This is a paragraph</p>
|
||||
<a href="//docsify.js.org/">Docsify</a>
|
||||
```
|
||||
````
|
||||
|
||||
```bash
|
||||
echo "hello"
|
||||
````text
|
||||
```css
|
||||
p {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```php
|
||||
function getAdder(int $x): int
|
||||
{
|
||||
return 123;
|
||||
````text
|
||||
```js
|
||||
function add(a, b) {
|
||||
return a + b;
|
||||
}
|
||||
```
|
||||
````
|
||||
@ -43,24 +41,100 @@ The above markdown will be rendered as:
|
||||
<a href="//docsify.js.org/">Docsify</a>
|
||||
```
|
||||
|
||||
```bash
|
||||
echo "hello"
|
||||
```
|
||||
|
||||
```php
|
||||
function getAdder(int $x): int
|
||||
{
|
||||
return 123;
|
||||
```css
|
||||
p {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
## Highlighting Dynamic Content
|
||||
```js
|
||||
function add(a, b) {
|
||||
return a + b;
|
||||
}
|
||||
```
|
||||
|
||||
Code blocks [dynamically created from javascript](https://docsify.js.org/#/configuration?id=executescript) can be highlighted using the method `Prism.highlightElement` like so:
|
||||
## Language support
|
||||
|
||||
```javascript
|
||||
Support for additional [languages](https://prismjs.com/#supported-languages) is available by loading the Prism [grammar files](https://cdn.jsdelivr.net/npm/prismjs@1/components/):
|
||||
|
||||
!> Prism grammar files must be loaded after Docsify.
|
||||
|
||||
```html
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-docker.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-git.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-java.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-jsx.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-markdown.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-php.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-python.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-rust.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-sql.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-swift.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-typescript.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-yaml.min.js"></script>
|
||||
```
|
||||
|
||||
## Theme support
|
||||
|
||||
Docsify's official [themes](themes) are compatible with Prism syntax highlighting themes.
|
||||
|
||||
!> Prism themes must be loaded after Docsify themes.
|
||||
|
||||
```html
|
||||
<!-- Light and dark mode -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="//cdn.jsdelivr.net/npm/prism-themes@1/themes/prism-one-light.min.css"
|
||||
/>
|
||||
```
|
||||
|
||||
Themes can be applied in light and/or dark mode
|
||||
|
||||
```html
|
||||
<!-- Dark mode only -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
href="//cdn.jsdelivr.net/npm/prism-themes@1/themes/prism-one-dark.min.css"
|
||||
/>
|
||||
|
||||
<!-- Light mode only -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
media="(prefers-color-scheme: light)"
|
||||
href="//cdn.jsdelivr.net/npm/prism-themes@1/themes/prism-one-light.min.css"
|
||||
/>
|
||||
```
|
||||
|
||||
The following Docsify [theme properties](themes#theme-properties) will override Prism theme styles by default:
|
||||
|
||||
```text
|
||||
--border-radius
|
||||
--font-family-mono
|
||||
--font-size-mono
|
||||
```
|
||||
|
||||
To use the values specified in the Prism theme, set the desired theme property to `unset`:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<style>
|
||||
:root {
|
||||
--border-radius : unset;
|
||||
--font-family-mono: unset;
|
||||
--font-size-mono : unset;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## Dynamic content
|
||||
|
||||
Dynamically generated Code blocks can be highlighted using Prism's [`highlightElement()`](https://prismjs.com/docs/Prism.html#.highlightElement) method:
|
||||
|
||||
```js
|
||||
const code = document.createElement('code');
|
||||
code.innerHTML = "console.log('Hello World!')";
|
||||
code.setAttribute('class', 'lang-javascript');
|
||||
code.setAttribute('class', 'language-javascript');
|
||||
Prism.highlightElement(code);
|
||||
```
|
||||
|
@ -17,8 +17,13 @@ By default, the hyperlink on the current page is recognized and the content is s
|
||||
'/zh-cn/', // => /zh-cn/README.md
|
||||
],
|
||||
|
||||
// complete configuration parameters
|
||||
// Complete configuration parameters
|
||||
search: {
|
||||
// Location in sidebar (default: prepended as first child)
|
||||
// Optionally specify insertAfter or insertBefore (not both)
|
||||
insertAfter: '.app-name', // CSS selector in .sidebar scope
|
||||
insertBefore: '.sidebar-nav', // CSS selector in .sidebar scope
|
||||
|
||||
maxAge: 86400000, // Expiration time, the default one day
|
||||
paths: [], // or 'auto'
|
||||
placeholder: 'Type to search',
|
||||
@ -40,7 +45,7 @@ By default, the hyperlink on the current page is recognized and the content is s
|
||||
// Headline depth, 1 - 6
|
||||
depth: 2,
|
||||
|
||||
hideOtherSidebarContent: false, // whether or not to hide other sidebar content
|
||||
hideOtherSidebarContent: true, // Deprecated as of v5
|
||||
|
||||
// To avoid search index collision
|
||||
// between multiple websites under the same domain
|
||||
|
@ -36,31 +36,44 @@ docsify serve docs
|
||||
|
||||
## Manual initialization
|
||||
|
||||
If you don't like `npm` or have trouble installing the tool, you can manually create `index.html`:
|
||||
Download or create an `index.html` template using the following markup:
|
||||
|
||||
<div id="template">
|
||||
|
||||
<a href="#" class="button primary" download="index.html">Download Template</a>
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/themes/vue.min.css" />
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
|
||||
<!-- Core Theme -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/themes/core.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<body class="loading">
|
||||
<div id="app"></div>
|
||||
|
||||
<!-- Configuration -->
|
||||
<script>
|
||||
window.$docsify = {
|
||||
//...
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- Docsify.js -->
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify@5"></script>
|
||||
|
||||
<!-- Plugins (optional) -->
|
||||
<!-- <script src="//cdn.jsdelivr.net/npm/docsify@5/dist/plugins/search.min.js"></script> -->
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Specifying docsify versions
|
||||
|
||||
?> Note that in both of the examples below, docsify URLs will need to be manually updated when a new major version of docsify is released (e.g. `v5.x.x` => `v6.x.x`). Check the docsify website periodically to see if a new major version has been released.
|
||||
@ -69,8 +82,8 @@ Specifying a major version in the URL (`@5`) will allow your site to receive non
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<!-- Theme -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/themes/vue.min.css" />
|
||||
<!-- Core Theme -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/themes/core.min.css">
|
||||
|
||||
<!-- Docsify -->
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify@5"></script>
|
||||
@ -80,11 +93,11 @@ If you prefer to lock docsify to a specific version, specify the full version af
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<!-- Theme -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/themes/vue.min.css" />
|
||||
<!-- Core Theme -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5.0.0/themes/core.min.css">
|
||||
|
||||
<!-- Docsify -->
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify@5"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify@5.0.0"></script>
|
||||
```
|
||||
|
||||
### Manually preview your site
|
||||
@ -126,3 +139,13 @@ You should set the `data-app` attribute if you changed `el`:
|
||||
```
|
||||
|
||||
Compare [el configuration](configuration.md#el).
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const linkElm = document.querySelector('#template a[download="index.html"]');
|
||||
const codeElm = document.querySelector('#template code');
|
||||
const html = codeElm?.textContent;
|
||||
|
||||
linkElm?.setAttribute('href', `data:text/plain,${html}`);
|
||||
})();
|
||||
</script>
|
||||
|
445
docs/themes.md
445
docs/themes.md
@ -1,56 +1,425 @@
|
||||
# Themes
|
||||
|
||||
Docsify offers several official themes to choose from. Click a theme name below to preview each theme.
|
||||
## Core theme
|
||||
|
||||
- <a href="#" data-theme="vue">Vue</a>
|
||||
- <a href="#" data-theme="buble">Buble</a>
|
||||
- <a href="#" data-theme="dark">Dark</a>
|
||||
- <a href="#" data-theme="pure">Pure</a>
|
||||
- <a href="#" data-theme="dolphin">Dolphin</a>
|
||||
|
||||
Official themes are available on multiple [CDNs](cdn). Uncompressed themes are also available by omitting the `.min` from the filename.
|
||||
The Docsify "core" theme contains all of the styles and [theme properties](#theme-properties) needed to render a Docsify site. This theme is designed to serve as a minimalist theme on its own, in combination with [theme add-ons](#theme-add-ons), modified using core [classes](#classes), and as a starting point for [customization](#customization).
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<!-- Vue -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/themes/vue.min.css" />
|
||||
|
||||
<!-- Buble -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/themes/buble.min.css" />
|
||||
|
||||
<!-- Dark -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/themes/dark.min.css" />
|
||||
|
||||
<!-- Pure -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/themes/pure.min.css" />
|
||||
|
||||
<!-- Dolphin -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/themes/dolphin.min.css" />
|
||||
<!-- Core Theme -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/core.min.css" />
|
||||
```
|
||||
|
||||
## Endorsed
|
||||
## Theme add-ons
|
||||
|
||||
The Docsify team endorses the following third-party themes. Click a link below the learn more.
|
||||
Theme add-ons are used in combination with the [core theme](#core-theme). Add-ons contain CSS rules that modify [theme properties](#theme-properties) values and/or add custom style declarations. They can often (but not always) be used with other add-ons.
|
||||
|
||||
- [docsify-themeable](https://jhildenbiddle.github.io/docsify-themeable) - A delightfully simple theme system for docsify.
|
||||
!> Theme add-ons must be loaded after the [core theme](#core-theme).
|
||||
|
||||
## More Themes
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<!-- Core Theme -->
|
||||
<link rel="stylesheet" href="..." />
|
||||
|
||||
See [Awesome Docsify](awesome) for more themes.
|
||||
<!-- Theme (add-on) -->
|
||||
<link rel="stylesheet" href="..." />
|
||||
```
|
||||
|
||||
### Core Dark (Add-on)
|
||||
|
||||
Dark mode styles for the [core theme](#core-theme). Styles can applied only when an operating system's dark mode is active by specifying a `media` attribute.
|
||||
|
||||
<label>
|
||||
<input
|
||||
class="toggle"
|
||||
type="checkbox"
|
||||
value="core-dark"
|
||||
data-group="addon"
|
||||
data-sheet
|
||||
>
|
||||
Preview Core Dark
|
||||
</label>
|
||||
<br>
|
||||
<label>
|
||||
<input
|
||||
class="toggle"
|
||||
type="checkbox"
|
||||
value="core-dark-auto"
|
||||
data-group="addon"
|
||||
data-sheet
|
||||
>
|
||||
Preview Core Dark (Dark Mode Only)
|
||||
</label>
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<!-- Core Dark (add-on) -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/addons/core-dark.min.css" />
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<!-- Core Dark - Dark Mode Only (add-on) -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/addons/core-dark.min.css" media="(prefers-color-scheme: dark)" />
|
||||
```
|
||||
|
||||
### Vue theme (Add-on)
|
||||
|
||||
The popular Docsify v4 theme.
|
||||
|
||||
<label>
|
||||
<input
|
||||
class="toggle"
|
||||
type="checkbox"
|
||||
value="vue"
|
||||
data-group="addon"
|
||||
data-sheet
|
||||
>
|
||||
Preview Vue
|
||||
</label>
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<!-- Vue Theme (add-on) -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/addons/vue.min.css" />
|
||||
```
|
||||
|
||||
## Classes
|
||||
|
||||
The [core theme](#core-theme) provides several CSS classes for customizing your Docsify site. These classes should be applied to the `<body>` element within your `index.html` page.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<body class="...">
|
||||
```
|
||||
|
||||
### Loading
|
||||
|
||||
Display a loading animation while waiting for Docsify to initialize.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<body class="loading">
|
||||
```
|
||||
|
||||
<output data-lang="output">
|
||||
<div class="loading" style="margin: auto;"></div>
|
||||
</output>
|
||||
|
||||
### Sidebar chevrons
|
||||
|
||||
Display expand/collapse icons on page links in the sidebar.
|
||||
|
||||
<label>
|
||||
<input class="toggle" type="checkbox" value="sidebar-chevron-right" data-class data-group="sidebar-chevron"> Preview <code>sidebar-chevron-right</code>
|
||||
</label>
|
||||
<br>
|
||||
<label>
|
||||
<input class="toggle" type="checkbox" value="sidebar-chevron-left" data-class data-group="sidebar-chevron"> Preview <code>sidebar-chevron-left</code>
|
||||
</label>
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<body class="sidebar-chevron-right">
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<body class="sidebar-chevron-left">
|
||||
```
|
||||
|
||||
To prevent chevrons from displaying for specific page links, add a `no-chevron` class as follows:
|
||||
|
||||
```md
|
||||
[My Page](page.md ':class=no-chevron')
|
||||
```
|
||||
|
||||
**Theme properties**
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```css
|
||||
:root {
|
||||
--sidebar-chevron-collapsed-color: var(--color-mono-3);
|
||||
--sidebar-chevron-expanded-color : var(--theme-color);
|
||||
}
|
||||
```
|
||||
|
||||
### Sidebar groups
|
||||
|
||||
Add visual distinction between groups of links in the sidebar.
|
||||
|
||||
<label>
|
||||
<input class="toggle" type="checkbox" value="sidebar-group-box" data-class data-group="sidebar-group"> Preview <code>sidebar-group-box</code>
|
||||
</label>
|
||||
<br>
|
||||
<label>
|
||||
<input class="toggle" type="checkbox" value="sidebar-group-underline" data-class data-group="sidebar-group"> Preview <code>sidebar-group-underline</code>
|
||||
</label>
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<body class="sidebar-group-box">
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<body class="sidebar-group-underline">
|
||||
```
|
||||
|
||||
### Sidebar link clamp
|
||||
|
||||
Limit multi-line sidebar links to a single line followed by an ellipses.
|
||||
|
||||
<label>
|
||||
<input class="toggle" type="checkbox" value="sidebar-link-clamp" data-class>
|
||||
Preview <code>sidebar-link-clamp</code>
|
||||
</label>
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<body class="sidebar-link-clamp">
|
||||
```
|
||||
|
||||
### Sidebar toggle
|
||||
|
||||
Display a "hamburger" icon (three lines) in the sidebar toggle button instead of the default "kebab" icon.
|
||||
|
||||
<label>
|
||||
<input class="toggle" type="checkbox" value="sidebar-toggle-chevron" data-class data-group="sidebar-toggle">
|
||||
Preview <code>sidebar-toggle-chevron</code>
|
||||
</label>
|
||||
<br>
|
||||
<label>
|
||||
<input class="toggle" type="checkbox" value="sidebar-toggle-hamburger" data-class data-group="sidebar-toggle">
|
||||
Preview <code>sidebar-toggle-hamburger</code>
|
||||
</label>
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<body class="sidebar-toggle-chevron">
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<body class="sidebar-toggle-hamburger">
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
Docsify provides [theme properties](#theme-properties) for simplified customization of frequently modified styles.
|
||||
|
||||
1. Add a `<style>` tag after the theme stylesheet in your `index.html`.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<!-- Theme -->
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@5/dist/themes/core.min.css" />
|
||||
|
||||
<!-- Custom theme styles -->
|
||||
<style>
|
||||
:root {
|
||||
/* ... */
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
Theme properties can also be set on a per-page basis in markdown.
|
||||
|
||||
```markdown
|
||||
# My Heading
|
||||
|
||||
Hello, World!
|
||||
|
||||
<style>
|
||||
:root {
|
||||
/* ... */
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
2. Set custom [theme properties](#theme-properties) within a `:root` declaration.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```css
|
||||
:root {
|
||||
--theme-color: red;
|
||||
--font-size : 15px;
|
||||
--line-height: 1.5;
|
||||
}
|
||||
```
|
||||
|
||||
Custom [theme properties](#theme-properties) can be conditionally applied in light and/or dark mode.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```css
|
||||
/* Light and dark mode */
|
||||
:root {
|
||||
--theme-color: pink;
|
||||
}
|
||||
|
||||
/* Light mode only */
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--color-bg : #eee;
|
||||
--color-text: #444;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark mode only */
|
||||
@media screen and (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--color-bg : #222;
|
||||
--color-text: #ddd;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. Custom fonts can be used by adding web font resources and modifying `--font-family` properties as needed:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```css
|
||||
/* Fonts: Noto Sans, Noto Emoji, Noto Mono */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Noto+Color+Emoji&family=Noto+Sans+Mono:wght@100..900&family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
|
||||
:root {
|
||||
--font-family : 'Noto Sans', sans-serif;
|
||||
--font-family-emoji: 'Noto Color Emoji', sans-serif;
|
||||
--font-family-mono : 'Noto Sans Mono', monospace;
|
||||
}
|
||||
```
|
||||
|
||||
?> **Theme authors**: Consider providing instructions for loading your recommended web fonts manually instead of including them in your theme using `@import`. This allows users who prefer a different font to avoid loading your recommended web font(s) unnecessarily.
|
||||
|
||||
4. Advanced styling may require custom CSS declarations. This is expected, however custom CSS declarations may break when new versions of Docsify are released. When possible, leverage [theme properties](#theme-properties) instead of custom declarations or lock your [CDN](cdn) URLs to a [specific version](cdn#specific-version) to avoid potential issues when using custom CSS declarations.
|
||||
|
||||
```css
|
||||
.sidebar li.active > a {
|
||||
border-right: 3px solid var(--theme-color);
|
||||
}
|
||||
```
|
||||
|
||||
## Theme properties
|
||||
|
||||
The following properties are available in all official Docsify themes. Default values for the "Core" theme are shown.
|
||||
|
||||
?> **Theme and plugin authors**: We encourage you to leverage these custom theme properties and to offer similar customization options in your projects.
|
||||
|
||||
### Common
|
||||
|
||||
Below are the most commonly modified theme properties. [Advanced](#advanced) theme properties are also available for use but typically do not need to be modified.
|
||||
|
||||
<!-- TODO: Replace TBD with include CSS include below -->
|
||||
|
||||
**TBD**
|
||||
|
||||
<!-- [vars.css](https://raw.githubusercontent.com/docsifyjs/docsify/main/src/themes/shared/_vars.css ':include') -->
|
||||
|
||||
### Advanced
|
||||
|
||||
Advanced theme properties are also available for use but typically do not need to be modified. Values derived from [common](#common) theme properties but can be set explicitly if preferred.
|
||||
|
||||
<!-- TODO: Replace TBD with include CSS include below -->
|
||||
|
||||
**TBD**
|
||||
|
||||
<!-- [vars.css](https://raw.githubusercontent.com/docsifyjs/docsify/main/src/themes/shared/_vars.css ':include') -->
|
||||
|
||||
## Community
|
||||
|
||||
See [Awesome Docsify](awesome) for additional community themes.
|
||||
|
||||
<script>
|
||||
const previewElm = Docsify.dom.findAll('a[data-theme]');
|
||||
const stylesheetElms = Docsify.dom.findAll('link[rel="stylesheet"]');
|
||||
(function () {
|
||||
const toggleElms = Docsify.dom.findAll(
|
||||
'input:where([data-class], [data-sheet])',
|
||||
);
|
||||
const previewSheets = Docsify.dom.findAll(
|
||||
'link[rel="stylesheet"][data-sheet]',
|
||||
);
|
||||
|
||||
previewElm.forEach(elm => {
|
||||
elm.onclick = (e) => {
|
||||
e.preventDefault();
|
||||
const title = e.target.getAttribute('data-theme');
|
||||
function handleChange(e) {
|
||||
const elm = e.target.closest('[data-class], [data-sheet]');
|
||||
const value = elm.value;
|
||||
const groupVal = elm.getAttribute('data-group');
|
||||
const radioGroupName = elm.matches('[type="radio"]') ? elm.name : undefined;
|
||||
|
||||
stylesheetElms.forEach(theme => {
|
||||
theme.disabled = theme.title !== title;
|
||||
});
|
||||
};
|
||||
});
|
||||
// Toggle class
|
||||
if (elm.matches('[data-class]')) {
|
||||
document.body.classList.toggle(value, elm.checked);
|
||||
}
|
||||
// Toggle sheet
|
||||
else {
|
||||
const themeSheet = previewSheets.find(
|
||||
sheet => sheet.getAttribute('data-sheet') === value,
|
||||
);
|
||||
|
||||
themeSheet && (themeSheet.disabled = !elm.checked);
|
||||
}
|
||||
|
||||
if (!elm.checked || (!groupVal && !radioGroupName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Group elements & values
|
||||
const groupElms = toggleElms.filter(elm =>
|
||||
groupVal
|
||||
? groupVal === elm.getAttribute('data-group')
|
||||
: radioGroupName === elm.name,
|
||||
);
|
||||
const groupVals = groupElms.map(elm => elm.value);
|
||||
|
||||
if (groupElms.length <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (groupVal) {
|
||||
// Uncheck other group elements
|
||||
groupElms.forEach(groupElm => {
|
||||
if (groupElm !== elm) {
|
||||
groupElm.checked = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Remove group classes
|
||||
if (elm.matches('[data-class]')) {
|
||||
groupVals.forEach(className => {
|
||||
if (className !== value) {
|
||||
document.body.classList.remove(className);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Disable group sheets
|
||||
else {
|
||||
const otherSheets = groupVals
|
||||
.map(val =>
|
||||
previewSheets.find(sheet => sheet.getAttribute('data-sheet') === val),
|
||||
)
|
||||
.filter(sheet => sheet && sheet.getAttribute('data-sheet') !== value);
|
||||
const disableSheets = otherSheets.length ? otherSheets : previewSheets;
|
||||
|
||||
disableSheets.forEach(sheet => sheet.disabled = true);
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle active elms
|
||||
toggleElms.forEach(elm => {
|
||||
const value = elm.value;
|
||||
|
||||
// Class toggle
|
||||
if (elm.matches('[data-class]')) {
|
||||
elm.checked = document.body.classList.contains(value);
|
||||
}
|
||||
// Sheet toggle
|
||||
else {
|
||||
const previewSheet = previewSheets.find(
|
||||
sheet => sheet.getAttribute('data-sheet') === value,
|
||||
);
|
||||
|
||||
elm.checked = previewSheet && !previewSheet.disabled;
|
||||
}
|
||||
});
|
||||
|
||||
toggleElms.forEach(elm => elm.addEventListener('change', handleChange));
|
||||
})();
|
||||
</script>
|
||||
|
500
docs/ui-kit.md
Normal file
500
docs/ui-kit.md
Normal file
@ -0,0 +1,500 @@
|
||||
<!-- markdownlint-disable single-title no-duplicate-heading -->
|
||||
|
||||
# UI Kit
|
||||
|
||||
<details>
|
||||
<summary>View the markdown source for this page</summary>
|
||||
<div style="max-height: 50vh; overflow: auto;">
|
||||
|
||||
[ui-kit.md](ui-kit.md ':include :type=code')
|
||||
|
||||
</div>
|
||||
</details>
|
||||
|
||||
## Blockquotes
|
||||
|
||||
> Cras aliquet nulla quis metus tincidunt, sed placerat enim cursus. Etiam
|
||||
> turpis nisl, posuere eu condimentum ut, interdum a risus. Sed non luctus mi.
|
||||
> Quisque malesuada risus sit amet tortor aliquet, a posuere ex iaculis. Vivamus
|
||||
> ultrices enim dui, eleifend porttitor elit aliquet sed.
|
||||
>
|
||||
> _- Quote Source_
|
||||
|
||||
#### Nested
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
> Level 1
|
||||
> > Level 2
|
||||
> > > Level 3
|
||||
|
||||
## Buttons
|
||||
|
||||
#### Default
|
||||
|
||||
<button>Button</button>
|
||||
|
||||
#### Basic
|
||||
|
||||
<button type="button">Button</button>
|
||||
<a href="javascript:void(0);" class="button">Link Button</a>
|
||||
<input type="button" value="Input Button" class="button">
|
||||
|
||||
#### Primary
|
||||
|
||||
<button type="button" class="primary">Button</button>
|
||||
<a href="javascript:void(0);" class="button primary">Link Button</a>
|
||||
<input type="button" value="Input Button" class="primary">
|
||||
|
||||
#### Secondary
|
||||
|
||||
<button type="button" class="secondary">Button</button>
|
||||
<a href="javascript:void(0);" class="button secondary">Link Button</a>
|
||||
<input type="button" value="Input Button" class="secondary">
|
||||
|
||||
## Callouts
|
||||
|
||||
!> **Important** callout with `inline code` and additional placeholder text used
|
||||
to force the content to wrap and span multiple lines.
|
||||
|
||||
?> **Tip** callout with `inline code` and additional placeholder text used to
|
||||
force the content to wrap and span multiple lines.
|
||||
|
||||
## Code
|
||||
|
||||
This is `inline code`
|
||||
|
||||
```javascript
|
||||
const add = (num1, num2) => num1 + num2;
|
||||
const total = add(1, 2);
|
||||
|
||||
console.log(total); // 3
|
||||
```
|
||||
|
||||
```html
|
||||
<body>
|
||||
<p>Hello</p>
|
||||
</body>
|
||||
```
|
||||
|
||||
## Colors
|
||||
|
||||
#### Theme
|
||||
|
||||
<div class="ui-kit-color">
|
||||
<figure>
|
||||
<div style="background: var(--theme-color-1);"></div>
|
||||
<figcaption>1<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--theme-color-2);"></div>
|
||||
<figcaption>2<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--theme-color-3);"></div>
|
||||
<figcaption>3<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--theme-color-4);"></div>
|
||||
<figcaption>4<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--theme-color);"></div>
|
||||
<figcaption>Theme Color<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--theme-color-5);"></div>
|
||||
<figcaption>5<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--theme-color-6);"></div>
|
||||
<figcaption>6<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--theme-color-7);"></div>
|
||||
<figcaption>7<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--theme-color-8);"></div>
|
||||
<figcaption>8<figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
#### Monochromatic
|
||||
|
||||
<div class="ui-kit-color">
|
||||
<figure>
|
||||
<div style="background: var(--color-mono-min); border: 1px solid var(--color-mono-2);"></div>
|
||||
<figcaption>Min<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--color-mono-1);"></div>
|
||||
<figcaption>1<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--color-mono-2);"></div>
|
||||
<figcaption>2<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--color-mono-3);"></div>
|
||||
<figcaption>3<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--color-mono-4);"></div>
|
||||
<figcaption>4<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--color-mono-5);"></div>
|
||||
<figcaption>5<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--color-mono-6);"></div>
|
||||
<figcaption>6<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--color-mono-7);"></div>
|
||||
<figcaption>7<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--color-mono-8);"></div>
|
||||
<figcaption>8<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--color-mono-9);"></div>
|
||||
<figcaption>9<figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<div style="background: var(--color-mono-max);"></div>
|
||||
<figcaption>Max<figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
## Details
|
||||
|
||||
<details>
|
||||
<summary>Details (click to open)</summary>
|
||||
|
||||
Suscipit nemo aut ex suscipit voluptatem laboriosam odio velit. Ipsum eveniet labore sequi non optio vel. Ut culpa ad accusantium est aut harum ipsam voluptatum. Velit eum incidunt non sint. Et molestiae veniam natus autem vel assumenda ut numquam esse. Non nisi id qui vero corrupti quos et.
|
||||
|
||||
</details>
|
||||
|
||||
<details open>
|
||||
<summary>Details (open by default)</summary>
|
||||
|
||||
Suscipit nemo aut ex suscipit voluptatem laboriosam odio velit. Ipsum eveniet labore sequi non optio vel. Ut culpa ad accusantium est aut harum ipsam voluptatum. Velit eum incidunt non sint. Et molestiae veniam natus autem vel assumenda ut numquam esse. Non nisi id qui vero corrupti quos et.
|
||||
|
||||
</details>
|
||||
|
||||
## Form Elements
|
||||
|
||||
### Fieldset
|
||||
|
||||
<form>
|
||||
<fieldset>
|
||||
<legend>Legend</legend>
|
||||
<p>
|
||||
<label>
|
||||
Label<br>
|
||||
<input type="text" placeholder="Placeholder">
|
||||
</label>
|
||||
</p>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
### Input
|
||||
|
||||
#### Checkbox
|
||||
|
||||
<form>
|
||||
<label><input type="checkbox" value="HTML" checked> HTML</label><br>
|
||||
<label><input type="checkbox" value="CSS"> CSS</label><br>
|
||||
<label><input type="checkbox" value="JavaScript"> JavaScript</label>
|
||||
</form>
|
||||
|
||||
#### Datalist
|
||||
|
||||
<form>
|
||||
<label>
|
||||
Label<br>
|
||||
<input list="planets">
|
||||
<datalist id="planets">
|
||||
<option value="Earth">Earth</option>
|
||||
<option value="Jupiter">Jupiter</option>
|
||||
<option value="Mars">Mars</option>
|
||||
<option value="Mercury">Mercury</option>
|
||||
<option value="Neptune">Neptune</option>
|
||||
<option value="Saturn">Saturn</option>
|
||||
<option value="Uranus">Uranus</option>
|
||||
<option value="Venus">Venus</option>
|
||||
</datalist>
|
||||
</label>
|
||||
</form>
|
||||
|
||||
#### Radio
|
||||
|
||||
<form>
|
||||
<label><input type="radio" name="language" value="HTML" checked> HTML</label><br>
|
||||
<label><input type="radio" name="language" value="CSS"> CSS</label><br>
|
||||
<label><input type="radio" name="language" value="JavaScript"> JavaScript</label>
|
||||
</form>
|
||||
|
||||
#### Text
|
||||
|
||||
<form>
|
||||
<label>
|
||||
First name<br>
|
||||
<input type="text" placeholder="Placeholder">
|
||||
</label>
|
||||
</form>
|
||||
|
||||
#### Toggles
|
||||
|
||||
<form>
|
||||
Checkbox (multi-select)
|
||||
|
||||
<label><input class="toggle" type="checkbox" checked> HTML</label><br>
|
||||
<label><input class="toggle" type="checkbox"> CSS</label><br>
|
||||
<label><input class="toggle" type="checkbox"> JavaScript</label>
|
||||
|
||||
Radio (single-select)
|
||||
|
||||
<label><input class="toggle" type="radio" name="toggle" checked> HTML</label><br>
|
||||
<label><input class="toggle" type="radio" name="toggle"> CSS</label><br>
|
||||
<label><input class="toggle" type="radio" name="toggle"> JavaScript</label>
|
||||
|
||||
</form>
|
||||
|
||||
### Select
|
||||
|
||||
<form>
|
||||
<label>
|
||||
Label<br>
|
||||
<select>
|
||||
<option value="Earth">Select a planet...</option>
|
||||
<option value="Earth">Earth</option>
|
||||
<option value="Jupiter">Jupiter</option>
|
||||
<option value="Mars">Mars</option>
|
||||
<option value="Mercury">Mercury</option>
|
||||
<option value="Neptune">Neptune</option>
|
||||
<option value="Saturn">Saturn</option>
|
||||
<option value="Uranus">Uranus</option>
|
||||
<option value="Venus">Venus</option>
|
||||
</select>
|
||||
</label>
|
||||
</form>
|
||||
|
||||
### Textarea
|
||||
|
||||
<textarea rows="5" cols="40">
|
||||
Ipsam totam tempora. Dolorum voluptas error tempore asperiores vitae error laboriosam autem possimus.
|
||||
</textarea>
|
||||
|
||||
## Headings
|
||||
|
||||
# Heading 1 {docsify-ignore}
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse luctus nulla eu ex varius, a varius elit tincidunt. Aenean arcu magna, gravida id purus a, interdum convallis turpis. Aenean id ipsum eu tortor sollicitudin scelerisque in quis elit.
|
||||
|
||||
## Heading 2 {docsify-ignore}
|
||||
|
||||
Vestibulum lobortis laoreet nunc vel vulputate. In et augue non lectus pellentesque molestie et ac justo. Sed sed turpis ut diam gravida sagittis nec at neque. Vivamus id tellus est. Nam ac dignissim mi. Vestibulum nec sem convallis, condimentum augue at, commodo diam.
|
||||
|
||||
### Heading 3 {docsify-ignore}
|
||||
|
||||
Suspendisse sit amet tincidunt nibh, ac interdum velit. Ut orci diam, dignissim at enim sit amet, placerat rutrum magna. Mauris consectetur nibh eget sem feugiat, sit amet congue quam laoreet. Curabitur sed massa metus.
|
||||
|
||||
#### Heading 4 {docsify-ignore}
|
||||
|
||||
Donec odio orci, facilisis ac vehicula in, vestibulum ut urna. Ut bibendum ullamcorper risus, ac euismod leo maximus sed. In pulvinar sagittis rutrum. Morbi quis cursus diam. Cras ac laoreet nulla, rhoncus sodales dui.
|
||||
|
||||
##### Heading 5 {docsify-ignore}
|
||||
|
||||
Commodo sit veniam nulla cillum labore ullamco aliquip quis. Consequat nulla fugiat consequat ex duis proident. Adipisicing excepteur tempor exercitation ad. Consectetur voluptate Lorem sint elit exercitation ullamco dolor.
|
||||
|
||||
###### Heading 6 {docsify-ignore}
|
||||
|
||||
Ipsum ea amet dolore mollit incididunt fugiat nulla laboris est sint voluptate. Ex culpa id amet ipsum amet pariatur ipsum officia sit laborum irure ullamco deserunt. Consequat qui tempor occaecat nostrud proident.
|
||||
|
||||
## Horizontal Rule
|
||||
|
||||
Text before rule.
|
||||
|
||||
---
|
||||
|
||||
Text after rule.
|
||||
|
||||
## IFrame
|
||||
|
||||
[Example](_media/example.html ':include height=200px')
|
||||
|
||||
## Images
|
||||
|
||||
#### Inline-style
|
||||
|
||||
![Docsify Logo](/_media/icon.svg 'This is the Docsify logo!')
|
||||
|
||||
#### Reference-style
|
||||
|
||||
![Docsify Logo][logo]
|
||||
|
||||
[logo]: /_media/icon.svg 'This is the Docsify logo!'
|
||||
|
||||
#### Light / Dark Theme
|
||||
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="_media/moon.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="_media/sun.svg">
|
||||
<img alt="BinaryTree" src="_media/sun.svg" width="122">
|
||||
</picture>
|
||||
|
||||
## Keyboard
|
||||
|
||||
#### Default
|
||||
|
||||
<kbd>⌃</kbd><kbd>⌥</kbd><kbd>⌫</kbd>
|
||||
|
||||
<kbd>Ctrl</kbd><kbd>Alt</kbd><kbd>Del</kbd>
|
||||
|
||||
<kbd>⌃ Control</kbd><kbd>⌥ Alt</kbd><kbd>⌫ Delete</kbd>
|
||||
|
||||
#### Alternate
|
||||
|
||||
<kbd class="alt">⌃</kbd><kbd class="alt">⌥</kbd><kbd class="alt">⌫</kbd>
|
||||
|
||||
<kbd class="alt">Ctrl</kbd><kbd class="alt">Alt</kbd><kbd class="alt">Del</kbd>
|
||||
|
||||
<kbd class="alt">⌃ Control</kbd><kbd class="alt">⌥ Alt</kbd><kbd class="alt">⌫ Delete</kbd>
|
||||
|
||||
#### Entities
|
||||
|
||||
<div style="display: grid; grid-template-columns: auto auto 1fr; gap: 1em 0.2em; align-items: end;">
|
||||
<div><kbd class="alt">↑</kbd></div> <div><kbd>↑</kbd></div> <div>Arrow Up</div>
|
||||
<div><kbd class="alt">↓</kbd></div> <div><kbd>↓</kbd></div> <div>Arrow Down</div>
|
||||
<div><kbd class="alt">←</kbd></div> <div><kbd>←</kbd></div> <div>Arrow Left</div>
|
||||
<div><kbd class="alt">→</kbd></div> <div><kbd>→</kbd></div> <div>Arrow Right</div>
|
||||
<div><kbd class="alt">⇪</kbd></div> <div><kbd>⇪</kbd></div> <div>Caps Lock</div>
|
||||
<div><kbd class="alt">⌘</kbd></div> <div><kbd>⌘</kbd></div> <div>Command</div>
|
||||
<div><kbd class="alt">⌃</kbd></div> <div><kbd>⌃</kbd></div> <div>Control</div>
|
||||
<div><kbd class="alt">⌫</kbd></div> <div><kbd>⌫</kbd></div> <div>Delete</div>
|
||||
<div><kbd class="alt">⌦</kbd></div> <div><kbd>⌦</kbd></div> <div>Delete (Forward)</div>
|
||||
<div><kbd class="alt">↘</kbd></div> <div><kbd>↘</kbd></div> <div>End</div>
|
||||
<div><kbd class="alt">⌤</kbd></div> <div><kbd>⌤</kbd></div> <div>Enter</div>
|
||||
<div><kbd class="alt">⎋</kbd></div> <div><kbd>⎋</kbd></div> <div>Escape</div>
|
||||
<div><kbd class="alt">↖</kbd></div> <div><kbd>↖</kbd></div> <div>Home</div>
|
||||
<div><kbd class="alt">⇞</kbd></div> <div><kbd>⇞</kbd></div> <div>Page Up</div>
|
||||
<div><kbd class="alt">⇟</kbd></div> <div><kbd>⇟</kbd></div> <div>Page Down</div>
|
||||
<div><kbd class="alt">⌥</kbd></div> <div><kbd>⌥</kbd></div> <div>Option, Alt</div>
|
||||
<div><kbd class="alt">↵</kbd></div> <div><kbd>↵</kbd></div> <div>Return</div>
|
||||
<div><kbd class="alt">⇧</kbd></div> <div><kbd>⇧</kbd></div> <div>Shift</div>
|
||||
<div><kbd class="alt">␣</kbd></div> <div><kbd>␣</kbd></div> <div>Space</div>
|
||||
<div><kbd class="alt">⇥</kbd></div> <div><kbd>⇥</kbd></div> <div>Tab</div>
|
||||
<div><kbd class="alt">⇤</kbd></div> <div><kbd>⇤</kbd></div> <div>Tab + Shift</div>
|
||||
</div>
|
||||
|
||||
## Links
|
||||
|
||||
[Inline link](https://google.com)
|
||||
|
||||
[Inline link with title](https://google.com 'Google')
|
||||
|
||||
[Reference link by name][link1]
|
||||
|
||||
[Reference link by number][1]
|
||||
|
||||
[Reference link by self]
|
||||
|
||||
[link1]: https://google.com
|
||||
[1]: https://google.com
|
||||
[Reference link by self]: https://google.com
|
||||
|
||||
## Lists
|
||||
|
||||
### Ordered List
|
||||
|
||||
1. Ordered
|
||||
1. Ordered
|
||||
1. Nested
|
||||
1. Nested (Wrapping): Similique tempora et. Voluptatem consequuntur ut. Rerum minus et sed beatae. Consequatur ut nemo laboriosam quo architecto quia qui. Corrupti aut omnis velit.
|
||||
1. Ordered (Wrapping): Error minima modi rem sequi facere voluptatem. Est nihil veritatis doloribus et corporis ipsam. Pariatur eos ipsam qui odit labore est voluptatem enim. Veritatis est qui ut pariatur inventore.
|
||||
|
||||
### Unordered List
|
||||
|
||||
- Unordered
|
||||
- Unordered
|
||||
- Nested
|
||||
- Nested (Wrapping): Quia consectetur sint vel ut excepturi ipsa voluptatum suscipit hic. Ipsa error qui molestiae harum laboriosam. Rerum non amet illo voluptatem odio pariatur. Ut minus enim.
|
||||
- Unordered (Wrapping): Fugiat qui tempore ratione amet repellendus repudiandae non. Rerum nisi officia enim. Itaque est alias voluptatibus id molestiae accusantium. Cupiditate sequi qui omnis sed facere aliquid quia ut.
|
||||
|
||||
### Task List
|
||||
|
||||
- [x] Task
|
||||
- [ ] Task
|
||||
- [ ] Subtask
|
||||
- [ ] Subtask
|
||||
- [x] Subtask
|
||||
- [ ] Task (Wrapping): Earum consequuntur itaque numquam sunt error omnis ipsum repudiandae. Est assumenda neque eum quia quisquam laborum beatae autem ad. Fuga fugiat perspiciatis harum quia dignissimos molestiae. Officia quo eveniet tempore modi voluptates consequatur. Eum odio adipisci labore.
|
||||
- [x] Subtask (Wrapping): Vel possimus eaque laborum. Voluptates qui debitis quaerat atque molestiae quia explicabo doloremque. Reprehenderit perspiciatis a aut impedit temporibus aut quasi quia. Incidunt sed recusandae vitae asperiores sit in.
|
||||
|
||||
## Output
|
||||
|
||||
<output data-lang="output">
|
||||
<p>Et cum fugiat nesciunt voluptates. A atque quos doloribus dolorem quo. Et dignissimos omnis nam. Recusandae voluptatem nam. Tenetur veniam et qui consequatur. Aut sequi atque fuga itaque iusto eum nihil quod iure.</p>
|
||||
<ol>
|
||||
<li>Item</li>
|
||||
<li>Item</li>
|
||||
<li>Item</li>
|
||||
</ol>
|
||||
</output>
|
||||
|
||||
## Tables
|
||||
|
||||
### Alignment
|
||||
|
||||
| Left Align | Center Align | Right Align | Non‑Breaking Header |
|
||||
| ---------- | :----------: | ----------: | ------------------------------ |
|
||||
| A1 | A2 | A3 | A4 |
|
||||
| B1 | B2 | B3 | B4 |
|
||||
| C1 | C2 | C3 | C4 |
|
||||
|
||||
### Headerless
|
||||
|
||||
| | | | |
|
||||
| --- | --- | --- | --- |
|
||||
| A1 | A2 | A3 | A4 |
|
||||
| B1 | B2 | B3 | B4 |
|
||||
| C1 | C2 | C3 | C4 |
|
||||
|
||||
### Scrolling
|
||||
|
||||
| Header |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Dicta in nobis dolor adipisci qui. Accusantium voluptates est dolor laboriosam qui voluptatibus. Veritatis eos aspernatur iusto et dicta quas. Fugit voluptatem dolorum qui quisquam. nihil |
|
||||
| Aut praesentium officia aut delectus. Quas atque reprehenderit saepe. Et voluptatibus qui dolores rem facere in dignissimos id aut. Debitis excepturi delectus et quos numquam magnam. |
|
||||
| Sed eum atque at laborum aut et repellendus ullam dolor. Cupiditate saepe voluptatibus odit est pariatur qui. Hic sunt nihil optio enim eum laudantium. Repellendus voluptate. |
|
||||
|
||||
## Text Elements
|
||||
|
||||
<mark>Marked text</mark>
|
||||
|
||||
<pre>Preformatted text</pre>
|
||||
|
||||
<samp>Sample Output</samp>
|
||||
|
||||
<small>Small Text</small>
|
||||
|
||||
This is <sub>subscript</sub>
|
||||
|
||||
This is <sup>superscript</sup>
|
||||
|
||||
<ins>Underlined Text</ins>
|
||||
|
||||
## Text Styles
|
||||
|
||||
Body text
|
||||
|
||||
**Bold text**
|
||||
|
||||
_Italic text_
|
||||
|
||||
**_Bold and italic text_**
|
||||
|
||||
~~Strikethrough~~
|
@ -6,10 +6,11 @@ const sharedConfig = {
|
||||
errorOnDeprecated: true,
|
||||
globalSetup: './test/config/jest.setup.js',
|
||||
globalTeardown: './test/config/jest.teardown.js',
|
||||
prettierPath: null, // Fix for Jest v29 and Prettier v3 (https://github.com/jestjs/jest/issues/14305)
|
||||
resetModules: true,
|
||||
restoreMocks: true,
|
||||
setupFilesAfterEnv: ['<rootDir>/test/config/jest.setup-tests.js'],
|
||||
testEnvironment: 'jsdom',
|
||||
testEnvironment: 'jest-environment-jsdom',
|
||||
testEnvironmentOptions: {
|
||||
url: `${TEST_HOST}/_blank.html`,
|
||||
},
|
||||
|
1865
package-lock.json
generated
1865
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -72,17 +72,19 @@
|
||||
"marked": "^12.0.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss-cli": "^11.0.0",
|
||||
"postcss-import": "^16.1.0",
|
||||
"postcss-nesting": "^12.1.5",
|
||||
"prettier": "^3.2.5",
|
||||
"rimraf": "^5.0.7",
|
||||
"rollup": "^4.17.2",
|
||||
"stylus": "^0.63.0",
|
||||
"rollup-plugin-import-css": "^3.5.0",
|
||||
"vue": "^3.4.27",
|
||||
"xhr-mock": "^2.5.1"
|
||||
},
|
||||
"scripts": {
|
||||
"build:cover": "node build/cover.js",
|
||||
"build:css:min": "postcss \"dist/themes/**/!(*.min).css\" --dir dist/themes --ext .min.css --map --use cssnano",
|
||||
"build:css": "stylus src/themes --out dist/themes --sourcemap",
|
||||
"build:css": "postcss \"src/themes/*.css\" \"src/themes/**/[!_]*.css\" --base src/themes --dir dist/themes --map",
|
||||
"build:css:min": "cross-env NODE_ENV='production' npm run build:css -- --ext .min.css",
|
||||
"build:emoji": "node ./build/emoji.js",
|
||||
"build:js": "rollup -c",
|
||||
"build": "run-s clean build:js build:css build:css:min build:cover",
|
||||
|
10
postcss.config.cjs
Normal file
10
postcss.config.cjs
Normal file
@ -0,0 +1,10 @@
|
||||
module.exports = ctx => ({
|
||||
map: ctx.options.map,
|
||||
plugins: {
|
||||
'postcss-import': {},
|
||||
'postcss-nesting': {
|
||||
edition: '2024-02',
|
||||
},
|
||||
cssnano: ctx.env === 'production' ? { preset: 'default' } : false,
|
||||
},
|
||||
});
|
@ -2,6 +2,7 @@ import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { babel } from '@rollup/plugin-babel';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import css from 'rollup-plugin-import-css';
|
||||
import replace from '@rollup/plugin-replace';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import terser from '@rollup/plugin-terser';
|
||||
@ -46,6 +47,7 @@ const baseConfig = {
|
||||
plugins: [
|
||||
resolve(),
|
||||
commonjs(),
|
||||
css(),
|
||||
replace({
|
||||
preventAssignment: true,
|
||||
values: {
|
||||
|
@ -7,6 +7,7 @@ const __dirname = path.dirname(__filename);
|
||||
|
||||
// Production (CDN URLs, watch disabled)
|
||||
export const prodConfig = {
|
||||
ghostMode: false,
|
||||
hostname: '127.0.0.1',
|
||||
notify: false,
|
||||
open: false,
|
||||
|
@ -53,7 +53,7 @@ export default function (vm) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
stripIndent(`
|
||||
$docsify.themeColor is deprecated. Use a --theme-color property in your style sheet. Example:
|
||||
$docsify.themeColor is deprecated. Use the "--theme-color" theme property to set your theme color.
|
||||
<style>
|
||||
:root {
|
||||
--theme-color: deeppink;
|
||||
@ -78,11 +78,10 @@ export default function (vm) {
|
||||
toggleSidebar: {
|
||||
bindings: ['\\'],
|
||||
callback(e) {
|
||||
const toggleElm = document.querySelector('.sidebar-toggle');
|
||||
const toggleElm = document.querySelector('.sidebar-toggle-button');
|
||||
|
||||
if (toggleElm) {
|
||||
toggleElm.click();
|
||||
toggleElm.focus();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { isMobile } from '../util/env.js';
|
||||
import { isMobile, mobileBreakpoint } from '../util/env.js';
|
||||
import * as dom from '../util/dom.js';
|
||||
|
||||
/** @typedef {import('../Docsify.js').Constructor} Constructor */
|
||||
@ -25,16 +25,19 @@ export function Events(Base) {
|
||||
|
||||
// Apply topMargin to scrolled content
|
||||
if (topMargin) {
|
||||
const value =
|
||||
typeof topMargin === 'number' ? `${topMargin}px` : topMargin;
|
||||
|
||||
document.documentElement.style.setProperty(
|
||||
'scroll-padding-top',
|
||||
`${topMargin}px`,
|
||||
'--scroll-padding-top',
|
||||
value,
|
||||
);
|
||||
}
|
||||
|
||||
this.#initCover();
|
||||
this.#initSkipToContent('#skip-to-content');
|
||||
this.#initSidebarCollapse('.sidebar');
|
||||
this.#initSidebarToggle('button.sidebar-toggle');
|
||||
this.#initSkipToContent();
|
||||
this.#initSidebar();
|
||||
this.#initSidebarToggle();
|
||||
this.#initKeyBindings();
|
||||
}
|
||||
|
||||
@ -206,26 +209,32 @@ export function Events(Base) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize sidebar content expand/collapse toggle behavior
|
||||
* Initialize sidebar event listeners
|
||||
*
|
||||
* @param {Element|string} elm Sidebar Element or CSS selector
|
||||
* @void
|
||||
*/
|
||||
#initSidebarCollapse(elm) {
|
||||
elm = typeof elm === 'string' ? document.querySelector(elm) : elm;
|
||||
#initSidebar() {
|
||||
const sidebarElm = document.querySelector('.sidebar');
|
||||
|
||||
if (!elm) {
|
||||
if (!sidebarElm) {
|
||||
return;
|
||||
}
|
||||
|
||||
dom.on(elm, 'click', ({ target }) => {
|
||||
if (
|
||||
target.nodeName === 'A' &&
|
||||
target.nextSibling &&
|
||||
target.nextSibling.classList &&
|
||||
target.nextSibling.classList.contains('app-sub-sidebar')
|
||||
) {
|
||||
dom.toggleClass(target.parentNode, 'collapse');
|
||||
// Auto-toggle on resolution change
|
||||
window
|
||||
?.matchMedia?.(`(max-width: ${mobileBreakpoint})`)
|
||||
.addEventListener('change', evt => {
|
||||
this.#toggleSidebar(!evt.matches);
|
||||
});
|
||||
|
||||
// Collapse toggle
|
||||
dom.on(sidebarElm, 'click', ({ target }) => {
|
||||
const linkElm = target.closest('a');
|
||||
const linkParent = linkElm?.closest('li');
|
||||
const subSidebar = linkParent?.querySelector('.app-sub-sidebar');
|
||||
|
||||
if (subSidebar) {
|
||||
dom.toggleClass(linkParent, 'collapse');
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -233,58 +242,53 @@ export function Events(Base) {
|
||||
/**
|
||||
* Initialize sidebar show/hide toggle behavior
|
||||
*
|
||||
* @param {Element|string} elm Toggle Element or CSS selector
|
||||
* @void
|
||||
*/
|
||||
#initSidebarToggle(elm) {
|
||||
elm = typeof elm === 'string' ? document.querySelector(elm) : elm;
|
||||
#initSidebarToggle() {
|
||||
const contentElm = dom.find('main > .content');
|
||||
const toggleElm = dom.find('button.sidebar-toggle');
|
||||
|
||||
if (!elm) {
|
||||
if (!toggleElm) {
|
||||
return;
|
||||
}
|
||||
|
||||
const toggle = () => {
|
||||
dom.body.classList.toggle('close');
|
||||
let lastContentFocusElm;
|
||||
|
||||
const isClosed = isMobile
|
||||
? dom.body.classList.contains('close')
|
||||
: !dom.body.classList.contains('close');
|
||||
// Store last focused content element (restored via #toggleSidebar)
|
||||
dom.on(contentElm, 'focusin', e => {
|
||||
const focusAttr = 'data-restore-focus';
|
||||
|
||||
elm.setAttribute('aria-expanded', isClosed);
|
||||
};
|
||||
|
||||
dom.on(elm, 'click', e => {
|
||||
e.stopPropagation();
|
||||
toggle();
|
||||
lastContentFocusElm?.removeAttribute(focusAttr);
|
||||
lastContentFocusElm = e.target;
|
||||
lastContentFocusElm.setAttribute(focusAttr, '');
|
||||
});
|
||||
|
||||
isMobile &&
|
||||
dom.on(
|
||||
dom.body,
|
||||
'click',
|
||||
() => dom.body.classList.contains('close') && toggle(),
|
||||
);
|
||||
// Toggle sidebar
|
||||
dom.on(toggleElm, 'click', e => {
|
||||
e.stopPropagation();
|
||||
this.#toggleSidebar();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize skip to content behavior
|
||||
*
|
||||
* @param {Element|string} elm Skip link Element or CSS selector
|
||||
* @void
|
||||
*/
|
||||
#initSkipToContent(elm) {
|
||||
elm = typeof elm === 'string' ? document.querySelector(elm) : elm;
|
||||
#initSkipToContent() {
|
||||
const skipElm = document.querySelector('#skip-to-content');
|
||||
|
||||
if (!elm) {
|
||||
if (!skipElm) {
|
||||
return;
|
||||
}
|
||||
|
||||
elm.addEventListener('click', evt => {
|
||||
skipElm.addEventListener('click', evt => {
|
||||
const focusElm = this.#focusContent();
|
||||
|
||||
evt.preventDefault();
|
||||
dom.find('main')?.scrollIntoView({
|
||||
focusElm?.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
});
|
||||
this.#focusContent();
|
||||
});
|
||||
}
|
||||
|
||||
@ -318,7 +322,7 @@ export function Events(Base) {
|
||||
*/
|
||||
onNavigate(source) {
|
||||
const { auto2top, topMargin } = this.config;
|
||||
const { query } = this.route;
|
||||
const { path, query } = this.route;
|
||||
|
||||
this.#markSidebarActiveElm();
|
||||
|
||||
@ -347,7 +351,12 @@ export function Events(Base) {
|
||||
}
|
||||
}
|
||||
|
||||
// Move focus to content
|
||||
// Clicked anchor link
|
||||
if (path === '/' || (query.id && source === 'navigate')) {
|
||||
isMobile() && this.#toggleSidebar(false);
|
||||
}
|
||||
|
||||
// Clicked anchor link or page load with anchor ID
|
||||
if (query.id || source === 'navigate') {
|
||||
this.#focusContent();
|
||||
}
|
||||
@ -361,6 +370,7 @@ export function Events(Base) {
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
|
||||
* @param {Object} options HTMLElement focus() method options
|
||||
* @returns HTMLElement|undefined
|
||||
* @void
|
||||
*/
|
||||
#focusContent(options = {}) {
|
||||
@ -379,6 +389,8 @@ export function Events(Base) {
|
||||
|
||||
// Move focus to content area
|
||||
focusEl?.focus(settings);
|
||||
|
||||
return focusEl;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -386,32 +398,34 @@ export function Events(Base) {
|
||||
*
|
||||
* @param {string} [href] Matching element HREF value. If unspecified,
|
||||
* defaults to the current path (without query params)
|
||||
* @returns Element|undefined
|
||||
* @void
|
||||
*/
|
||||
#markAppNavActiveElm() {
|
||||
const href = decodeURIComponent(this.router.toURL(this.route.path));
|
||||
const navElm = dom.find('nav.app-nav');
|
||||
|
||||
if (!navElm) {
|
||||
return;
|
||||
}
|
||||
['.app-nav', '.app-nav-merged'].forEach(selector => {
|
||||
const navElm = dom.find(selector);
|
||||
|
||||
const newActive = dom
|
||||
.findAll(navElm, 'a')
|
||||
.sort((a, b) => b.href.length - a.href.length)
|
||||
.find(
|
||||
a =>
|
||||
href.includes(a.getAttribute('href')) ||
|
||||
href.includes(decodeURI(a.getAttribute('href'))),
|
||||
);
|
||||
const oldActive = dom.find(navElm, 'li.active');
|
||||
if (!navElm) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newActive && newActive !== oldActive) {
|
||||
oldActive?.classList.remove('active');
|
||||
newActive.classList.add('active');
|
||||
}
|
||||
const newActive = dom
|
||||
.findAll(navElm, 'a')
|
||||
.sort((a, b) => b.href.length - a.href.length)
|
||||
.find(
|
||||
a =>
|
||||
href.includes(a.getAttribute('href')) ||
|
||||
href.includes(decodeURI(a.getAttribute('href'))),
|
||||
)
|
||||
?.closest('li');
|
||||
const oldActive = dom.find(navElm, 'li.active');
|
||||
|
||||
return newActive;
|
||||
if (newActive && newActive !== oldActive) {
|
||||
oldActive?.classList.remove('active');
|
||||
newActive.classList.add('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -479,6 +493,53 @@ export function Events(Base) {
|
||||
return newPage;
|
||||
}
|
||||
|
||||
#toggleSidebar(force) {
|
||||
const sidebarElm = dom.find('.sidebar');
|
||||
|
||||
if (!sidebarElm) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ariaElms = dom.findAll('[aria-controls="__sidebar"]');
|
||||
const inertElms = dom.findAll(
|
||||
'body > *:not(main, script), main > .content',
|
||||
);
|
||||
const isShow = sidebarElm.classList.toggle('show', force);
|
||||
|
||||
// Set aria-expanded attribute
|
||||
ariaElms.forEach(toggleElm => {
|
||||
toggleElm.setAttribute(
|
||||
'aria-expanded',
|
||||
force ?? sidebarElm.classList.contains('show'),
|
||||
);
|
||||
});
|
||||
|
||||
// Add inert attributes (focus trap)
|
||||
if (isShow && isMobile()) {
|
||||
inertElms.forEach(elm => elm.setAttribute('inert', ''));
|
||||
}
|
||||
// Remove inert attributes
|
||||
else {
|
||||
inertElms.forEach(elm => elm.removeAttribute('inert'));
|
||||
}
|
||||
|
||||
if (isShow) {
|
||||
sidebarElm.focus();
|
||||
}
|
||||
// Restore focus
|
||||
else {
|
||||
const restoreElm = document.querySelector(
|
||||
'main > .content [data-restore-focus]',
|
||||
);
|
||||
|
||||
if (restoreElm) {
|
||||
restoreElm.focus({
|
||||
preventScroll: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitor next scroll start/end and set #isScrolling to true/false
|
||||
* accordingly. Listeners are removed after the start/end events are fired.
|
||||
|
@ -8,7 +8,7 @@ import { emojify } from './emojify.js';
|
||||
import {
|
||||
getAndRemoveConfig,
|
||||
removeAtag,
|
||||
getAndRemoveDocisfyIgnoreConfig,
|
||||
getAndRemoveDocsifyIgnoreConfig,
|
||||
} from './utils.js';
|
||||
import { imageCompiler } from './compiler/image.js';
|
||||
import { highlightCodeCompiler } from './compiler/code.js';
|
||||
@ -214,7 +214,7 @@ export class Compiler {
|
||||
const nextToc = { level, title: str };
|
||||
|
||||
const { content, ignoreAllSubs, ignoreSubHeading } =
|
||||
getAndRemoveDocisfyIgnoreConfig(str);
|
||||
getAndRemoveDocsifyIgnoreConfig(str);
|
||||
str = content.trim();
|
||||
|
||||
nextToc.title = removeAtag(str);
|
||||
|
@ -11,5 +11,5 @@ export const highlightCodeCompiler = ({ renderer }) =>
|
||||
lang,
|
||||
);
|
||||
|
||||
return /* html */ `<pre data-lang="${lang}"><code class="lang-${lang}" tabindex="0">${text}</code></pre>`;
|
||||
return /* html */ `<pre data-lang="${lang}" class="language-${lang}"><code class="lang-${lang} language-${lang}" tabindex="0">${text}</code></pre>`;
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {
|
||||
getAndRemoveConfig,
|
||||
removeAtag,
|
||||
getAndRemoveDocisfyIgnoreConfig,
|
||||
getAndRemoveDocsifyIgnoreConfig,
|
||||
} from '../utils.js';
|
||||
import { slugify } from './slugify.js';
|
||||
|
||||
@ -11,7 +11,7 @@ export const headingCompiler = ({ renderer, router, _self }) =>
|
||||
const nextToc = { level, title: str };
|
||||
|
||||
const { content, ignoreAllSubs, ignoreSubHeading } =
|
||||
getAndRemoveDocisfyIgnoreConfig(str);
|
||||
getAndRemoveDocsifyIgnoreConfig(str);
|
||||
str = content.trim();
|
||||
|
||||
nextToc.title = removeAtag(str);
|
||||
|
@ -3,10 +3,11 @@ import { helper as helperTpl } from '../tpl.js';
|
||||
export const paragraphCompiler = ({ renderer }) =>
|
||||
(renderer.paragraph = text => {
|
||||
let result;
|
||||
if (/^!>/.test(text)) {
|
||||
result = helperTpl('tip', text);
|
||||
} else if (/^\?>/.test(text)) {
|
||||
result = helperTpl('warn', text);
|
||||
|
||||
if (text.startsWith('!>')) {
|
||||
result = helperTpl('callout important', text);
|
||||
} else if (text.startsWith('?>')) {
|
||||
result = helperTpl('callout tip', text);
|
||||
} else {
|
||||
result = /* html */ `<p>${text}</p>`;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import tinydate from 'tinydate';
|
||||
import * as dom from '../util/dom.js';
|
||||
import { getPath, isAbsolutePath } from '../router/util.js';
|
||||
import { isMobile, inBrowser } from '../util/env.js';
|
||||
import { isMobile } from '../util/env.js';
|
||||
import { isPrimitive } from '../util/core.js';
|
||||
import { Compiler } from './compiler.js';
|
||||
import * as tpl from './tpl.js';
|
||||
@ -271,7 +271,7 @@ export function Render(Base) {
|
||||
if (el) {
|
||||
el.innerHTML = skipLinkText;
|
||||
} else {
|
||||
const html = `<button id="skip-to-content">${skipLinkText}</button>`;
|
||||
const html = `<button type="button" id="skip-to-content" class="primary">${skipLinkText}</button>`;
|
||||
dom.body.insertAdjacentHTML('afterbegin', html);
|
||||
}
|
||||
}
|
||||
@ -287,10 +287,10 @@ export function Render(Base) {
|
||||
_renderSidebar(text) {
|
||||
const { maxLevel, subMaxLevel, loadSidebar, hideSidebar } = this.config;
|
||||
const sidebarEl = dom.getNode('aside.sidebar');
|
||||
const sidebarNavEl = dom.getNode('.sidebar-nav');
|
||||
const sidebarToggleEl = dom.getNode('button.sidebar-toggle');
|
||||
|
||||
if (hideSidebar) {
|
||||
dom.body.classList.add('hidesidebar');
|
||||
sidebarEl?.remove(sidebarEl);
|
||||
sidebarToggleEl?.remove(sidebarToggleEl);
|
||||
|
||||
@ -298,7 +298,7 @@ export function Render(Base) {
|
||||
}
|
||||
|
||||
this._renderTo('.sidebar-nav', this.compiler.sidebar(text, maxLevel));
|
||||
sidebarToggleEl.setAttribute('aria-expanded', !isMobile);
|
||||
sidebarToggleEl.setAttribute('aria-expanded', !isMobile());
|
||||
|
||||
const activeElmHref = this.router.toURL(this.route.path);
|
||||
const activeEl = dom.find(`.sidebar-nav a[href="${activeElmHref}"]`);
|
||||
@ -315,6 +315,34 @@ export function Render(Base) {
|
||||
|
||||
// Bind event
|
||||
this._bindEventOnRendered(activeEl);
|
||||
|
||||
// Mark page links and groups
|
||||
const pageLinks = dom.findAll(
|
||||
sidebarNavEl,
|
||||
'a:is(li > a, li > p > a):not(.section-link, [target="_blank"])',
|
||||
);
|
||||
const pageLinkGroups = dom
|
||||
// NOTE: Using filter() method as a replacement for :has() selector. It
|
||||
// would be preferable to use only 'li:not(:has(> a, > p > a))' selector
|
||||
// but the :has() selector is not supported by our Jest test environment
|
||||
// See: https://github.com/jsdom/jsdom/issues/3506#issuecomment-1769782333
|
||||
.findAll(sidebarEl, 'li')
|
||||
.filter(
|
||||
elm =>
|
||||
elm.querySelector(':scope > ul') &&
|
||||
!elm.querySelectorAll(':scope > a, :scope > p > a').length,
|
||||
);
|
||||
|
||||
pageLinks.forEach(elm => {
|
||||
elm.classList.add('page-link');
|
||||
});
|
||||
|
||||
pageLinkGroups.forEach(elm => {
|
||||
elm.classList.add('group');
|
||||
elm
|
||||
.querySelector(':scope > p:not(:has(> *))')
|
||||
?.classList.add('group-title');
|
||||
});
|
||||
}
|
||||
|
||||
_bindEventOnRendered(activeEl) {
|
||||
@ -334,8 +362,16 @@ export function Render(Base) {
|
||||
}
|
||||
|
||||
_renderNav(text) {
|
||||
text && this._renderTo('nav', this.compiler.compile(text));
|
||||
this.#addTextAsTitleAttribute('nav a');
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
|
||||
const html = this.compiler.compile(text);
|
||||
|
||||
['.app-nav', '.app-nav-merged'].forEach(selector => {
|
||||
this._renderTo(selector, html);
|
||||
this.#addTextAsTitleAttribute(`${selector} a`);
|
||||
});
|
||||
}
|
||||
|
||||
_renderMain(text, opt = {}, next) {
|
||||
@ -384,12 +420,15 @@ export function Render(Base) {
|
||||
|
||||
_renderCover(text, coverOnly) {
|
||||
const el = dom.getNode('.cover');
|
||||
const rootElm = document.documentElement;
|
||||
const coverBg = getComputedStyle(rootElm).getPropertyValue('--cover-bg');
|
||||
|
||||
dom.toggleClass(
|
||||
dom.getNode('main'),
|
||||
coverOnly ? 'add' : 'remove',
|
||||
'hidden',
|
||||
);
|
||||
|
||||
if (!text) {
|
||||
dom.toggleClass(el, 'remove', 'show');
|
||||
return;
|
||||
@ -399,30 +438,90 @@ export function Render(Base) {
|
||||
|
||||
let html = this.coverIsHTML ? text : this.compiler.cover(text);
|
||||
|
||||
const m = html
|
||||
.trim()
|
||||
.match('<p><img.*?data-origin="(.*?)"[^a]+alt="(.*?)">([^<]*?)</p>$');
|
||||
if (!coverBg) {
|
||||
const mdBgMatch = html
|
||||
.trim()
|
||||
.match(
|
||||
'<p><img.*?data-origin="(.*?)".*?alt="(.*?)"[^>]*?>([^<]*?)</p>$',
|
||||
);
|
||||
|
||||
if (m) {
|
||||
if (m[2] === 'color') {
|
||||
el.style.background = m[1] + (m[3] || '');
|
||||
} else {
|
||||
let path = m[1];
|
||||
let mdCoverBg;
|
||||
|
||||
dom.toggleClass(el, 'add', 'has-mask');
|
||||
if (!isAbsolutePath(m[1])) {
|
||||
path = getPath(this.router.getBasePath(), m[1]);
|
||||
if (mdBgMatch) {
|
||||
const [bgMatch, bgValue, bgType] = mdBgMatch;
|
||||
|
||||
// Color
|
||||
if (bgType === 'color') {
|
||||
mdCoverBg = bgValue;
|
||||
}
|
||||
// Image
|
||||
else {
|
||||
const path = !isAbsolutePath(bgValue)
|
||||
? getPath(this.router.getBasePath(), bgValue)
|
||||
: bgValue;
|
||||
|
||||
mdCoverBg = `center center / cover url(${path})`;
|
||||
}
|
||||
|
||||
el.style.backgroundImage = `url(${path})`;
|
||||
el.style.backgroundSize = 'cover';
|
||||
el.style.backgroundPosition = 'center center';
|
||||
html = html.replace(bgMatch, '');
|
||||
}
|
||||
// Gradient background
|
||||
else {
|
||||
const degrees = Math.round((Math.random() * 120) / 2);
|
||||
|
||||
let hue1 = Math.round(Math.random() * 360);
|
||||
let hue2 = Math.round(Math.random() * 360);
|
||||
|
||||
// Ensure hue1 and hue2 are at least 50 degrees apart
|
||||
if (Math.abs(hue1 - hue2) < 50) {
|
||||
const hueShift = Math.round(Math.random() * 25) + 25;
|
||||
|
||||
hue1 = Math.max(hue1, hue2) + hueShift;
|
||||
hue2 = Math.min(hue1, hue2) - hueShift;
|
||||
}
|
||||
|
||||
// OKLCH color
|
||||
if (window?.CSS?.supports('color', 'oklch(0 0 0 / 1%)')) {
|
||||
const l = 90; // Lightness
|
||||
const c = 20; // Chroma
|
||||
|
||||
// prettier-ignore
|
||||
mdCoverBg = `linear-gradient(
|
||||
${degrees}deg,
|
||||
oklch(${l}% ${c}% ${hue1}) 0%,
|
||||
oklch(${l}% ${c}% ${hue2}) 100%
|
||||
)`.replace(/\s+/g, ' ');
|
||||
}
|
||||
// HSL color (Legacy)
|
||||
else {
|
||||
const s = 100; // Saturation
|
||||
const l = 85; // Lightness
|
||||
const o = 100; // Opacity
|
||||
|
||||
// prettier-ignore
|
||||
mdCoverBg = `linear-gradient(
|
||||
${degrees}deg,
|
||||
hsl(${hue1} ${s}% ${l}% / ${o}%) 0%,
|
||||
hsl(${hue2} ${s}% ${l}% / ${o}%) 100%
|
||||
)`.replace(/\s+/g, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
html = html.replace(m[0], '');
|
||||
rootElm.style.setProperty('--cover-bg', mdCoverBg);
|
||||
}
|
||||
|
||||
this._renderTo('.cover-main', html);
|
||||
|
||||
// Button styles
|
||||
dom
|
||||
.findAll('.cover-main > p:last-of-type > a:not([class])')
|
||||
.forEach(elm => {
|
||||
const buttonType = elm.matches(':first-child')
|
||||
? 'primary'
|
||||
: 'secondary';
|
||||
|
||||
elm.classList.add('button', buttonType);
|
||||
});
|
||||
}
|
||||
|
||||
_updateRender() {
|
||||
@ -438,9 +537,7 @@ export function Render(Base) {
|
||||
|
||||
// Init markdown compiler
|
||||
this.compiler = new Compiler(config, this.router);
|
||||
if (inBrowser) {
|
||||
window.__current_docsify_compiler__ = this.compiler;
|
||||
}
|
||||
window.__current_docsify_compiler__ = this.compiler;
|
||||
|
||||
const id = config.el || '#app';
|
||||
const el = dom.find(id);
|
||||
@ -477,16 +574,19 @@ export function Render(Base) {
|
||||
// Add nav
|
||||
if (config.loadNavbar) {
|
||||
const navEl = dom.find('nav') || dom.create('nav');
|
||||
const isMergedSidebar = config.mergeNavbar && isMobile;
|
||||
const isMergedSidebar = config.mergeNavbar;
|
||||
|
||||
navEl.classList.add('app-nav');
|
||||
navEl.setAttribute('aria-label', 'secondary');
|
||||
dom.body.prepend(navEl);
|
||||
|
||||
if (isMergedSidebar) {
|
||||
dom.find('.sidebar').prepend(navEl);
|
||||
} else {
|
||||
dom.body.prepend(navEl);
|
||||
navEl.classList.add('app-nav');
|
||||
navEl.classList.toggle('no-badge', !config.repo);
|
||||
const mergedNavEl = dom.create('div');
|
||||
const sidebarEl = dom.find('.sidebar');
|
||||
const sidebarNavEl = dom.find('.sidebar-nav');
|
||||
|
||||
mergedNavEl?.classList.add('app-nav-merged');
|
||||
sidebarEl?.insertBefore(mergedNavEl, sidebarNavEl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { isMobile } from '../util/env.js';
|
||||
|
||||
/**
|
||||
* Render github corner
|
||||
* @param {Object} data URL for the View Source on Github link
|
||||
@ -34,15 +36,18 @@ export function corner(data, cornerExternalLinkTarget) {
|
||||
* @returns {String} HTML of the main content
|
||||
*/
|
||||
export function main(config) {
|
||||
const name = config.name ? config.name : '';
|
||||
const { hideSidebar, name } = config;
|
||||
// const name = config.name ? config.name : '';
|
||||
|
||||
const aside = /* html */ `
|
||||
<button class="sidebar-toggle" title="Press \\ to toggle" aria-label="Toggle primary navigation" aria-keyshortcuts="\\" aria-controls="__sidebar">
|
||||
<div class="sidebar-toggle-button" aria-hidden="true">
|
||||
const aside = /* html */ hideSidebar
|
||||
? ''
|
||||
: `
|
||||
<button class="sidebar-toggle" tabindex="-1" title="Press \\ to toggle">
|
||||
<div class="sidebar-toggle-button" tabindex="0" aria-label="Toggle primary navigation" aria-keyshortcuts="\\" aria-controls="__sidebar">
|
||||
<span></span><span></span><span></span>
|
||||
</div>
|
||||
</button>
|
||||
<aside id="__sidebar" class="sidebar" role="none">
|
||||
<aside id="__sidebar" class="sidebar${!isMobile() ? ' show' : ''}" tabindex="-1" role="none">
|
||||
${
|
||||
config.name
|
||||
? /* html */ `
|
||||
@ -57,7 +62,8 @@ export function main(config) {
|
||||
`;
|
||||
|
||||
return /* html */ `
|
||||
<main role="presentation">${aside}
|
||||
<main role="presentation">
|
||||
${aside}
|
||||
<section class="content">
|
||||
<article id="main" class="markdown-section" role="main" tabindex="-1"><!--main--></article>
|
||||
</section>
|
||||
@ -70,17 +76,8 @@ export function main(config) {
|
||||
* @returns {String} Cover page
|
||||
*/
|
||||
export function cover() {
|
||||
const SL = ', 100%, 85%';
|
||||
const bgc = `
|
||||
linear-gradient(
|
||||
to left bottom,
|
||||
hsl(${Math.floor(Math.random() * 255) + SL}) 0%,
|
||||
hsl(${Math.floor(Math.random() * 255) + SL}) 100%
|
||||
)
|
||||
`;
|
||||
|
||||
return /* html */ `
|
||||
<section class="cover show" role="complementary" aria-label="cover" style="background: ${bgc}">
|
||||
<section class="cover show" role="complementary" aria-label="cover">
|
||||
<div class="mask"></div>
|
||||
<div class="cover-main"><!--cover--></div>
|
||||
</section>
|
||||
|
@ -55,7 +55,7 @@ export function removeAtag(str = '') {
|
||||
*
|
||||
* @return {{content: string, ignoreAllSubs: boolean, ignoreSubHeading: boolean}} The string after delete the docsifyIgnore configs, and whether to ignore some or all.
|
||||
*/
|
||||
export function getAndRemoveDocisfyIgnoreConfig(content = '') {
|
||||
export function getAndRemoveDocsifyIgnoreConfig(content = '') {
|
||||
let ignoreAllSubs, ignoreSubHeading;
|
||||
if (/<!-- {docsify-ignore} -->/g.test(content)) {
|
||||
content = content.replace('<!-- {docsify-ignore} -->', '');
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { isFn } from '../util/core.js';
|
||||
import { inBrowser } from './env.js';
|
||||
|
||||
const cacheNode = {};
|
||||
|
||||
@ -21,11 +20,11 @@ export function getNode(el, noCache = false) {
|
||||
return el;
|
||||
}
|
||||
|
||||
export const $ = inBrowser && document;
|
||||
export const $ = document;
|
||||
|
||||
export const body = inBrowser && $.body;
|
||||
export const body = $.body;
|
||||
|
||||
export const head = inBrowser && $.head;
|
||||
export const head = $.head;
|
||||
|
||||
/**
|
||||
* Find elements
|
||||
|
@ -1,3 +1,9 @@
|
||||
export const inBrowser = true; // True for now, may change when we add SSR.
|
||||
const computedStyle = getComputedStyle(document.documentElement, null);
|
||||
|
||||
export const isMobile = inBrowser && document.body.clientWidth <= 600;
|
||||
export const mobileBreakpoint = computedStyle.getPropertyValue(
|
||||
'--_mobile-breakpoint',
|
||||
);
|
||||
|
||||
export function isMobile() {
|
||||
return window?.matchMedia?.(`(max-width: ${mobileBreakpoint})`)?.matches;
|
||||
}
|
||||
|
@ -1,173 +1,47 @@
|
||||
import { search } from './search.js';
|
||||
import cssText from './style.css';
|
||||
|
||||
let NO_DATA_TEXT = '';
|
||||
let options;
|
||||
|
||||
function style() {
|
||||
const code = `
|
||||
.sidebar {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.search {
|
||||
margin-bottom: 20px;
|
||||
padding: 6px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.search .input-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search .results-status:not(:empty) {
|
||||
margin-top: 10px;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.search .results-panel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.search .results-panel.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.search input {
|
||||
outline: none;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 0.6em 7px;
|
||||
font-size: inherit;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.search input:focus {
|
||||
box-shadow: 0 0 5px var(--theme-color, #42b983);
|
||||
border: 1px solid var(--theme-color, #42b983);
|
||||
}
|
||||
|
||||
.search input::-webkit-search-decoration,
|
||||
.search input::-webkit-search-cancel-button,
|
||||
.search input {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.search input::-ms-clear {
|
||||
display: none;
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.search .clear-button {
|
||||
cursor: pointer;
|
||||
width: 36px;
|
||||
text-align: right;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.search .clear-button.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.search .clear-button svg {
|
||||
transform: scale(.5);
|
||||
}
|
||||
|
||||
.search kbd {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.search input:focus ~ kbd,
|
||||
.search input:not(:empty) ~ kbd {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.search h2 {
|
||||
font-size: 17px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.search a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.search .matching-post {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.search .matching-post:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.search p {
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.search p.empty {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.app-name.hide, .sidebar-nav.hide {
|
||||
display: none;
|
||||
}`;
|
||||
|
||||
Docsify.dom.style(code);
|
||||
}
|
||||
|
||||
function tpl(defaultValue = '') {
|
||||
function tpl(vm, defaultValue = '') {
|
||||
const { insertAfter, insertBefore } = vm.config?.search || {};
|
||||
const html = /* html */ `
|
||||
<div class="input-wrap">
|
||||
<input type="search" value="${defaultValue}" aria-keyshortcuts="/ control+k meta+k" />
|
||||
<div class="clear-button">
|
||||
<svg width="26" height="24">
|
||||
<circle cx="12" cy="12" r="11" fill="#ccc" />
|
||||
<path stroke="white" stroke-width="2" d="M8.25,8.25,15.75,15.75" />
|
||||
<path stroke="white" stroke-width="2"d="M8.25,15.75,15.75,8.25" />
|
||||
</svg>
|
||||
<input type="search" value="${defaultValue}" required aria-keyshortcuts="/ control+k meta+k" />
|
||||
<button class="clear-button" title="Clear search">
|
||||
<span class="visually-hidden">Clear search</span>
|
||||
</button>
|
||||
<div class="kbd-group">
|
||||
<kbd title="Press / to search">/</kbd>
|
||||
<kbd title="Press Control+K to search">⌃K</kbd>
|
||||
</div>
|
||||
<kbd title="Press / to search">/</kbd>
|
||||
</div>
|
||||
<div class="results-status" aria-live="polite"></div>
|
||||
<p class="results-status" aria-live="polite"></p>
|
||||
<div class="results-panel"></div>
|
||||
`;
|
||||
const el = Docsify.dom.create('div', html);
|
||||
const aside = Docsify.dom.find('aside');
|
||||
const sidebarElm = Docsify.dom.find('.sidebar');
|
||||
const searchElm = Docsify.dom.create('section', html);
|
||||
const insertElm = sidebarElm.querySelector(
|
||||
`:scope ${insertAfter || insertBefore || '> :first-child'}`,
|
||||
);
|
||||
|
||||
Docsify.dom.toggleClass(el, 'search');
|
||||
el.setAttribute('role', 'search');
|
||||
Docsify.dom.before(aside, el);
|
||||
searchElm.classList.add('search');
|
||||
searchElm.setAttribute('role', 'search');
|
||||
sidebarElm.insertBefore(
|
||||
searchElm,
|
||||
insertAfter ? insertElm.nextSibling : insertElm,
|
||||
);
|
||||
}
|
||||
|
||||
function doSearch(value) {
|
||||
const $search = Docsify.dom.find('div.search');
|
||||
const $search = Docsify.dom.find('.search');
|
||||
const $panel = Docsify.dom.find($search, '.results-panel');
|
||||
const $clearBtn = Docsify.dom.find($search, '.clear-button');
|
||||
const $sidebarNav = Docsify.dom.find('.sidebar-nav');
|
||||
const $status = Docsify.dom.find('div.search .results-status');
|
||||
const $appName = Docsify.dom.find('.app-name');
|
||||
const $status = Docsify.dom.find('.search .results-status');
|
||||
|
||||
if (!value) {
|
||||
$panel.classList.remove('show');
|
||||
$clearBtn.classList.remove('show');
|
||||
$panel.innerHTML = '';
|
||||
$status.textContent = '';
|
||||
|
||||
if (options.hideOtherSidebarContent) {
|
||||
$sidebarNav && $sidebarNav.classList.remove('hide');
|
||||
$appName && $appName.classList.remove('hide');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -178,28 +52,23 @@ function doSearch(value) {
|
||||
html += /* html */ `
|
||||
<div class="matching-post" aria-label="search result ${i + 1}">
|
||||
<a href="${post.url}">
|
||||
<h2>${post.title}</h2>
|
||||
<p>${post.content}</p>
|
||||
<p class="title clamp-1">${post.title}</p>
|
||||
<p class="content clamp-2">${post.content}</p>
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
$panel.classList.add('show');
|
||||
$clearBtn.classList.add('show');
|
||||
$panel.innerHTML = html || /* html */ `<p class="empty">${NO_DATA_TEXT}</p>`;
|
||||
$status.textContent = `Found ${matches.length} results`;
|
||||
|
||||
if (options.hideOtherSidebarContent) {
|
||||
$sidebarNav && $sidebarNav.classList.add('hide');
|
||||
$appName && $appName.classList.add('hide');
|
||||
}
|
||||
$panel.innerHTML = html || '';
|
||||
$status.textContent = matches.length
|
||||
? `Found ${matches.length} results`
|
||||
: NO_DATA_TEXT;
|
||||
}
|
||||
|
||||
function bindEvents() {
|
||||
const $search = Docsify.dom.find('div.search');
|
||||
const $search = Docsify.dom.find('.search');
|
||||
const $input = Docsify.dom.find($search, 'input');
|
||||
const $inputWrap = Docsify.dom.find($search, '.input-wrap');
|
||||
const $clear = Docsify.dom.find($search, '.clear-button');
|
||||
|
||||
let timeId;
|
||||
|
||||
@ -221,12 +90,9 @@ function bindEvents() {
|
||||
clearTimeout(timeId);
|
||||
timeId = setTimeout(_ => doSearch(e.target.value.trim()), 100);
|
||||
});
|
||||
Docsify.dom.on($inputWrap, 'click', e => {
|
||||
// Click input outside
|
||||
if (e.target.tagName !== 'INPUT') {
|
||||
$input.value = '';
|
||||
doSearch();
|
||||
}
|
||||
Docsify.dom.on($clear, 'click', e => {
|
||||
$input.value = '';
|
||||
doSearch();
|
||||
});
|
||||
}
|
||||
|
||||
@ -254,22 +120,22 @@ function updateNoData(text, path) {
|
||||
}
|
||||
}
|
||||
|
||||
function updateOptions(opts) {
|
||||
options = opts;
|
||||
}
|
||||
|
||||
export function init(opts, vm) {
|
||||
const sidebarElm = Docsify.dom.find('.sidebar');
|
||||
|
||||
if (!sidebarElm) {
|
||||
return;
|
||||
}
|
||||
|
||||
const keywords = vm.router.parse().query.s;
|
||||
|
||||
updateOptions(opts);
|
||||
style();
|
||||
tpl(keywords);
|
||||
Docsify.dom.style(cssText);
|
||||
tpl(vm, keywords);
|
||||
bindEvents();
|
||||
keywords && setTimeout(_ => doSearch(keywords), 500);
|
||||
}
|
||||
|
||||
export function update(opts, vm) {
|
||||
updateOptions(opts);
|
||||
updatePlaceholder(opts.placeholder, vm.route.path);
|
||||
updateNoData(opts.noData, vm.route.path);
|
||||
}
|
||||
|
@ -10,10 +10,11 @@ const CONFIG = {
|
||||
paths: 'auto',
|
||||
depth: 2,
|
||||
maxAge: 86400000, // 1 day
|
||||
hideOtherSidebarContent: false,
|
||||
namespace: undefined,
|
||||
pathNamespaces: undefined,
|
||||
keyBindings: ['/', 'meta+k', 'ctrl+k'],
|
||||
insertAfter: undefined, // CSS selector
|
||||
insertBefore: undefined, // CSS selector
|
||||
};
|
||||
|
||||
const install = function (hook, vm) {
|
||||
@ -28,8 +29,6 @@ const install = function (hook, vm) {
|
||||
CONFIG.placeholder = opts.placeholder || CONFIG.placeholder;
|
||||
CONFIG.noData = opts.noData || CONFIG.noData;
|
||||
CONFIG.depth = opts.depth || CONFIG.depth;
|
||||
CONFIG.hideOtherSidebarContent =
|
||||
opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent;
|
||||
CONFIG.namespace = opts.namespace || CONFIG.namespace;
|
||||
CONFIG.pathNamespaces = opts.pathNamespaces || CONFIG.pathNamespaces;
|
||||
CONFIG.keyBindings = opts.keyBindings || CONFIG.keyBindings;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {
|
||||
getAndRemoveConfig,
|
||||
getAndRemoveDocisfyIgnoreConfig,
|
||||
getAndRemoveDocsifyIgnoreConfig,
|
||||
} from '../../core/render/utils.js';
|
||||
|
||||
let INDEXS = {};
|
||||
@ -89,7 +89,7 @@ export function genIndex(path, content = '', router, depth) {
|
||||
if (token.type === 'heading' && token.depth <= depth) {
|
||||
const { str, config } = getAndRemoveConfig(token.text);
|
||||
|
||||
const text = getAndRemoveDocisfyIgnoreConfig(token.text).content;
|
||||
const text = getAndRemoveDocsifyIgnoreConfig(token.text).content;
|
||||
|
||||
if (config.id) {
|
||||
slug = router.toURL(path, { id: slugify(config.id) });
|
||||
@ -98,7 +98,7 @@ export function genIndex(path, content = '', router, depth) {
|
||||
}
|
||||
|
||||
if (str) {
|
||||
title = getAndRemoveDocisfyIgnoreConfig(str).content;
|
||||
title = getAndRemoveDocsifyIgnoreConfig(str).content;
|
||||
}
|
||||
|
||||
index[slug] = { slug, title: title, body: '' };
|
||||
@ -203,7 +203,7 @@ export function search(query) {
|
||||
let end = 0;
|
||||
|
||||
start = indexContent < 11 ? 0 : indexContent - 10;
|
||||
end = start === 0 ? 70 : indexContent + keyword.length + 60;
|
||||
end = start === 0 ? 100 : indexContent + keyword.length + 90;
|
||||
|
||||
if (postContent && end > postContent.length) {
|
||||
end = postContent.length;
|
||||
@ -211,14 +211,9 @@ export function search(query) {
|
||||
|
||||
const matchContent =
|
||||
handlePostContent &&
|
||||
'...' +
|
||||
handlePostContent
|
||||
.substring(start, end)
|
||||
.replace(
|
||||
regEx,
|
||||
word => /* html */ `<em class="search-keyword">${word}</em>`,
|
||||
) +
|
||||
'...';
|
||||
handlePostContent
|
||||
.substring(start, end)
|
||||
.replace(regEx, word => /* html */ `<mark>${word}</mark>`);
|
||||
|
||||
resultStr += matchContent;
|
||||
}
|
||||
|
159
src/plugins/search/style.css
Normal file
159
src/plugins/search/style.css
Normal file
@ -0,0 +1,159 @@
|
||||
/* prettier-ignore */
|
||||
:root {
|
||||
--plugin-search-input-bg : var(--form-element-bg);
|
||||
--plugin-search-input-border-color : var(--sidebar-border-color);
|
||||
--plugin-search-input-border-radius: var(--form-element-border-radius);
|
||||
--plugin-search-input-color : var(--form-element-color);
|
||||
--plugin-search-kbd-bg : var(--color-bg);
|
||||
--plugin-search-kbd-border : 1px solid var(--color-mono-3);
|
||||
--plugin-search-kbd-border-radius : 4px;
|
||||
--plugin-search-kbd-color : var(--color-mono-5);
|
||||
--plugin-search-margin : 10px;
|
||||
--plugin-search-reset-bg : var(--theme-color);
|
||||
--plugin-search-reset-border : transparent;
|
||||
--plugin-search-reset-border-radius: var(--border-radius);
|
||||
--plugin-search-reset-color : #fff;
|
||||
}
|
||||
|
||||
.search {
|
||||
margin: var(--plugin-search-margin);
|
||||
}
|
||||
|
||||
/* Input */
|
||||
/* ================================== */
|
||||
.search .input-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.search input {
|
||||
width: 100%;
|
||||
padding-inline-end: 36px;
|
||||
border: 1px solid var(--plugin-search-input-border-color);
|
||||
border-radius: var(--plugin-search-input-border-radius);
|
||||
background: var(--plugin-search-input-bg);
|
||||
color: var(--plugin-search-input-color);
|
||||
}
|
||||
|
||||
.search input::-webkit-search-decoration,
|
||||
.search input::-webkit-search-cancel-button {
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.search .clear-button,
|
||||
.search .kbd-group {
|
||||
visibility: hidden;
|
||||
display: flex;
|
||||
gap: 0.15em;
|
||||
position: absolute;
|
||||
right: 7px;
|
||||
top: 50%;
|
||||
opacity: 0;
|
||||
translate: 0 -50%;
|
||||
transition-property: opacity, visibility;
|
||||
transition-duration: var(--duration-medium);
|
||||
}
|
||||
|
||||
/* Note: invalid = empty, valid = not empty */
|
||||
.search input:valid ~ .clear-button,
|
||||
.search input:invalid:where(:focus, :hover) ~ .kbd-group,
|
||||
.search .kbd-group:hover {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.search .clear-button {
|
||||
--_button-size: 20px;
|
||||
--_content-size: 12px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: var(--_button-size);
|
||||
width: var(--_button-size);
|
||||
border: var(--plugin-search-reset-border);
|
||||
border-radius: var(--plugin-search-reset-border-radius);
|
||||
background: var(--plugin-search-reset-bg);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.search .clear-button::before,
|
||||
.search .clear-button::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
height: 2px;
|
||||
width: var(--_content-size);
|
||||
color: var(--plugin-search-reset-color);
|
||||
background: var(--plugin-search-reset-color);
|
||||
}
|
||||
|
||||
.search .clear-button::before {
|
||||
rotate: 45deg;
|
||||
}
|
||||
|
||||
.search .clear-button::after {
|
||||
rotate: -45deg;
|
||||
}
|
||||
|
||||
.search kbd {
|
||||
border: var(--plugin-search-kbd-border);
|
||||
border-radius: var(--plugin-search-kbd-border-radius);
|
||||
background: var(--plugin-search-kbd-bg);
|
||||
color: var(--plugin-search-kbd-color);
|
||||
font-size: var(--font-size-s);
|
||||
}
|
||||
|
||||
/* Results */
|
||||
/* ================================== */
|
||||
.search a:hover {
|
||||
color: var(--theme-color);
|
||||
}
|
||||
|
||||
.search .results-panel:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide other sidebar items when results are shown */
|
||||
.search:has(.results-panel:not(:empty)) ~ * {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Dim other sidebar items when no results are found */
|
||||
.search:where(:has(input:valid:focus), :has(.results-panel::empty)) ~ * {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.search .matching-post {
|
||||
overflow: hidden;
|
||||
padding: 1em 0 1.2em 0;
|
||||
border-bottom: 1px solid var(--color-mono-2);
|
||||
}
|
||||
|
||||
.search .matching-post:hover a {
|
||||
text-decoration-color: transparent;
|
||||
}
|
||||
|
||||
.search .matching-post:hover .title {
|
||||
text-decoration: inherit;
|
||||
text-decoration-color: var(--link-underline-color-hover);
|
||||
}
|
||||
|
||||
.search .matching-post .title {
|
||||
margin: 0 0 0.5em 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.search .matching-post .content {
|
||||
margin: 0;
|
||||
color: var(--color-mono-6);
|
||||
font-size: var(--font-size-s);
|
||||
}
|
||||
|
||||
.search .results-status {
|
||||
margin-bottom: 0;
|
||||
color: var(--color-mono-6);
|
||||
font-size: var(--font-size-s);
|
||||
}
|
||||
|
||||
.search .results-status:empty {
|
||||
display: none;
|
||||
}
|
36
src/themes/addons/core-dark.css
Normal file
36
src/themes/addons/core-dark.css
Normal file
@ -0,0 +1,36 @@
|
||||
/* prettier-ignore */
|
||||
:root {
|
||||
/* Color */
|
||||
--color-bg : #1f2428;
|
||||
--color-text: #ddd;
|
||||
|
||||
/* Cover */
|
||||
--cover-bg-brightness: 0.75;
|
||||
|
||||
/* Elements */
|
||||
--codeblock-comment : #516e7a;
|
||||
--codeblock-function : #f07178;
|
||||
--codeblock-keyword : #c2e78c;
|
||||
--codeblock-operator : #ffcb6b;
|
||||
--codeblock-punctuation: #89ddff;
|
||||
--codeblock-selector : #ffcb6b;
|
||||
--codeblock-tag : #f07178;
|
||||
--codeblock-variable : #ffcb6b;
|
||||
--heading-color : var(--strong-color);
|
||||
--mark-bg : #fde047;
|
||||
--mark-color : var(--color-bg);
|
||||
--strong-color : color-mix(in srgb, var(--color-text), white 35%);
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar-toggle-bg : var(--color-mono-3);
|
||||
--sidebar-toggle-color: var(--color-mono-5);
|
||||
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
.cover-main {
|
||||
a.button.secondary {
|
||||
color: var(--color-text);
|
||||
border-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
}
|
60
src/themes/addons/vue.css
Normal file
60
src/themes/addons/vue.css
Normal file
@ -0,0 +1,60 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap');
|
||||
|
||||
/* prettier-ignore */
|
||||
:root {
|
||||
/* Color */
|
||||
--color-text : #34495e;
|
||||
--theme-color: #42b983;
|
||||
|
||||
/* Typography */
|
||||
--font-family : 'Source Sans 3', sans-serif;
|
||||
--font-family-mono : 'Roboto Mono', monospace;
|
||||
--font-size : 15px;
|
||||
--font-size-xxxl : 2rem;
|
||||
--font-size-xxl : 1.75rem;
|
||||
--font-size-xl : 1.5rem;
|
||||
--font-size-l : 1.25rem;
|
||||
--content-max-width: 85ch;
|
||||
|
||||
/* Common */
|
||||
--margin-block: 1.2em;
|
||||
|
||||
/* Elements */
|
||||
--code-color : #e96900;
|
||||
--codeblock-comment : #8e908c;
|
||||
--codeblock-function : #c94922;
|
||||
--codeblock-important : #c94922;
|
||||
--codeblock-keyword : var(--theme-color);
|
||||
--codeblock-operator : #22a2c9;
|
||||
--codeblock-property : #c08b30;
|
||||
--codeblock-punctuation: #525252;
|
||||
--codeblock-selector : #6679cc;
|
||||
--codeblock-tag : #2973b7;
|
||||
--codeblock-variable : #3d8fd1;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
/* ========================================================================== */
|
||||
.sidebar-nav {
|
||||
li.active > a {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
width: 3px;
|
||||
background: var(--theme-color);
|
||||
}
|
||||
}
|
||||
|
||||
.app-sub-sidebar {
|
||||
li::before {
|
||||
content: '-';
|
||||
margin-right: 0.25em;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
section.cover
|
||||
position relative
|
||||
align-items center
|
||||
background-position center center
|
||||
background-repeat no-repeat
|
||||
background-size cover
|
||||
min-height 100vh
|
||||
width 100%
|
||||
display none
|
||||
|
||||
&.show
|
||||
display flex
|
||||
|
||||
&.has-mask .mask
|
||||
background-color $color-bg
|
||||
opacity 0.8
|
||||
position absolute
|
||||
top 0
|
||||
bottom 0
|
||||
width 100%
|
||||
|
||||
.cover-main
|
||||
flex 1
|
||||
margin 0 16px
|
||||
text-align center
|
||||
position: relative
|
||||
|
||||
a
|
||||
color inherit
|
||||
text-decoration none
|
||||
|
||||
&:hover
|
||||
text-decoration none
|
||||
|
||||
p
|
||||
line-height 1.5rem
|
||||
margin 1em 0
|
||||
|
||||
h1
|
||||
color inherit
|
||||
font-size 2.5rem
|
||||
font-weight 300
|
||||
margin 0.625rem 0 2.5rem
|
||||
position relative
|
||||
text-align center
|
||||
|
||||
a
|
||||
display block
|
||||
|
||||
small
|
||||
bottom -0.4375rem
|
||||
font-size 1rem
|
||||
position absolute
|
||||
|
||||
blockquote
|
||||
font-size 1.5rem
|
||||
text-align center
|
||||
|
||||
ul
|
||||
line-height 1.8
|
||||
list-style-type none
|
||||
margin 1em auto
|
||||
max-width 500px
|
||||
padding 0
|
||||
|
||||
.cover-main > p:last-child a
|
||||
border-color $color-primary
|
||||
border-color var(--theme-color, $color-primary)
|
||||
border-radius 2rem
|
||||
border-style solid
|
||||
border-width 1px
|
||||
box-sizing border-box
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
display inline-block
|
||||
font-size 1.05rem
|
||||
letter-spacing 0.1rem
|
||||
margin 0.5rem 1rem
|
||||
padding 0.75em 2rem
|
||||
text-decoration none
|
||||
transition all 0.15s ease
|
||||
|
||||
&:last-child
|
||||
background-color $color-primary
|
||||
background-color var(--theme-color, $color-primary)
|
||||
color #fff
|
||||
|
||||
&:hover
|
||||
color inherit
|
||||
opacity 0.8
|
||||
|
||||
&:hover
|
||||
color inherit
|
||||
|
||||
blockquote > p > a
|
||||
border-bottom 2px solid $color-primary
|
||||
border-bottom 2px solid var(--theme-color, $color-primary)
|
||||
transition color 0.3s
|
||||
|
||||
&:hover
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
@ -1,529 +0,0 @@
|
||||
*
|
||||
-webkit-font-smoothing antialiased
|
||||
-webkit-overflow-scrolling touch
|
||||
-webkit-tap-highlight-color rgba(0, 0, 0, 0)
|
||||
-webkit-text-size-adjust none
|
||||
-webkit-touch-callout none
|
||||
box-sizing border-box
|
||||
|
||||
body:not(.ready)
|
||||
overflow hidden
|
||||
|
||||
[data-cloak], .app-nav, > nav
|
||||
display none
|
||||
|
||||
div#app
|
||||
font-size 30px
|
||||
font-weight lighter
|
||||
margin 40vh auto
|
||||
text-align center
|
||||
|
||||
&:empty::before
|
||||
content 'Loading...'
|
||||
|
||||
img.emoji
|
||||
height 1.2em
|
||||
vertical-align middle
|
||||
|
||||
span.emoji
|
||||
font-family "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"
|
||||
font-size 1.2em
|
||||
vertical-align middle
|
||||
|
||||
.progress
|
||||
background-color $color-primary
|
||||
background-color var(--theme-color, $color-primary)
|
||||
height 2px
|
||||
left 0px
|
||||
position fixed
|
||||
right 0px
|
||||
top 0px
|
||||
transition width 0.2s, opacity 0.4s
|
||||
width 0%
|
||||
z-index 999999
|
||||
|
||||
.search a:hover
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
|
||||
.search .search-keyword
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
font-style normal
|
||||
font-weight bold
|
||||
|
||||
html, body
|
||||
height 100%
|
||||
|
||||
body
|
||||
-moz-osx-font-smoothing grayscale
|
||||
-webkit-font-smoothing antialiased
|
||||
color $color-text
|
||||
font-family 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif
|
||||
font-size 15px
|
||||
letter-spacing 0
|
||||
margin 0
|
||||
overflow-x hidden
|
||||
|
||||
img
|
||||
max-width 100%
|
||||
|
||||
a[disabled]
|
||||
cursor not-allowed
|
||||
opacity 0.6
|
||||
|
||||
kbd
|
||||
border solid 1px #ccc
|
||||
border-radius 3px
|
||||
display inline-block
|
||||
font-size 12px !important
|
||||
line-height 12px
|
||||
margin-bottom 3px
|
||||
padding 3px 5px
|
||||
vertical-align middle
|
||||
|
||||
li input[type='checkbox']
|
||||
margin 0 0.2em 0.25em 0
|
||||
vertical-align middle
|
||||
|
||||
[tabindex="-1"]:focus
|
||||
outline none !important
|
||||
|
||||
/* skip link */
|
||||
#skip-to-content
|
||||
appearance none
|
||||
display block
|
||||
position fixed
|
||||
z-index 2147483647
|
||||
top 0
|
||||
left 50%
|
||||
padding 0.5rem 1.5rem
|
||||
border 0
|
||||
border-radius: 100vw
|
||||
background-color $color-primary
|
||||
background-color var(--theme-color, $color-primary)
|
||||
color $color-bg
|
||||
color var(--theme-bg, $color-bg)
|
||||
opacity 0
|
||||
font-size inherit
|
||||
text-decoration none
|
||||
transform translate(-50%, -100%)
|
||||
transition-property opacity, transform
|
||||
transition-duration 0s, 0.2s
|
||||
transition-delay 0.2s, 0s
|
||||
|
||||
&:focus
|
||||
opacity 1
|
||||
transform translate(-50%, 0.75rem)
|
||||
transition-duration 0s, 0.2s
|
||||
transition-delay 0s, 0s
|
||||
|
||||
/* navbar */
|
||||
.app-nav
|
||||
margin 25px 60px 0 0
|
||||
position absolute
|
||||
right 0
|
||||
text-align right
|
||||
z-index 10
|
||||
|
||||
&.no-badge
|
||||
margin-right 25px
|
||||
|
||||
p
|
||||
margin 0
|
||||
|
||||
> a
|
||||
margin 0 1rem
|
||||
padding 5px 0
|
||||
|
||||
ul, li
|
||||
display inline-block
|
||||
list-style none
|
||||
margin 0
|
||||
|
||||
a
|
||||
color inherit
|
||||
font-size 16px
|
||||
text-decoration none
|
||||
transition color 0.3s
|
||||
|
||||
&:hover
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
|
||||
&.active
|
||||
border-bottom 2px solid $color-primary
|
||||
border-bottom 2px solid var(--theme-color, $color-primary)
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
|
||||
/* navbar dropdown */
|
||||
li
|
||||
display inline-block
|
||||
margin 0 1rem
|
||||
padding 5px 0
|
||||
position relative
|
||||
cursor pointer
|
||||
|
||||
ul
|
||||
background-color #fff
|
||||
border 1px solid #ddd
|
||||
border-bottom-color #ccc
|
||||
border-radius 4px
|
||||
box-sizing border-box
|
||||
max-height calc(100vh - 61px)
|
||||
overflow-y auto
|
||||
padding 10px 0
|
||||
position absolute
|
||||
right -15px
|
||||
text-align left
|
||||
top -100vh
|
||||
white-space nowrap
|
||||
|
||||
li
|
||||
display block
|
||||
font-size 14px
|
||||
line-height 1rem
|
||||
margin 0
|
||||
margin 8px 14px
|
||||
white-space nowrap
|
||||
|
||||
a
|
||||
display block
|
||||
font-size inherit
|
||||
margin 0
|
||||
padding 0
|
||||
|
||||
&.active
|
||||
border-bottom 0
|
||||
|
||||
&:focus-within ul,
|
||||
&:hover ul
|
||||
top: 100%;
|
||||
|
||||
/* github corner */
|
||||
.github-corner
|
||||
border-bottom 0
|
||||
position fixed
|
||||
right 0
|
||||
text-decoration none
|
||||
top 0
|
||||
z-index 1
|
||||
|
||||
&:hover .octo-arm
|
||||
animation octocat-wave 560ms ease-in-out
|
||||
|
||||
svg
|
||||
color $color-bg
|
||||
fill $color-primary
|
||||
fill var(--theme-color, $color-primary)
|
||||
height 80px
|
||||
width 80px
|
||||
|
||||
/* main */
|
||||
main
|
||||
display block
|
||||
position relative
|
||||
width 100vw
|
||||
height 100%
|
||||
z-index 0
|
||||
|
||||
main.hidden
|
||||
display none
|
||||
|
||||
.anchor
|
||||
display inline-block
|
||||
text-decoration none
|
||||
transition all 0.3s
|
||||
|
||||
span
|
||||
color $color-text
|
||||
|
||||
&:hover
|
||||
text-decoration underline
|
||||
|
||||
/* sidebar */
|
||||
.sidebar
|
||||
border-right 1px solid rgba(0, 0, 0, 0.07)
|
||||
overflow-y auto
|
||||
padding 40px 0 0
|
||||
position absolute
|
||||
top 0
|
||||
bottom 0
|
||||
left 0
|
||||
transition transform 250ms ease-out, visibility 250ms
|
||||
width $sidebar-width
|
||||
z-index 20
|
||||
|
||||
> h1
|
||||
margin 0 auto 1rem
|
||||
font-size 1.5rem
|
||||
font-weight 300
|
||||
text-align center
|
||||
|
||||
a
|
||||
color inherit
|
||||
text-decoration none
|
||||
|
||||
.app-nav
|
||||
display block
|
||||
position static
|
||||
|
||||
.sidebar-nav
|
||||
line-height 2em
|
||||
padding-bottom 40px
|
||||
|
||||
li
|
||||
scroll-margin-bottom 40px
|
||||
|
||||
li.collapse
|
||||
.app-sub-sidebar
|
||||
display none
|
||||
|
||||
ul
|
||||
margin 0 0 0 15px
|
||||
padding 0
|
||||
|
||||
li > p
|
||||
font-weight 700
|
||||
margin 0
|
||||
|
||||
ul, ul li
|
||||
list-style none
|
||||
|
||||
ul li a
|
||||
border-bottom none
|
||||
display block
|
||||
|
||||
ul li ul
|
||||
padding-left 20px
|
||||
|
||||
&::-webkit-scrollbar
|
||||
width 4px
|
||||
|
||||
&::-webkit-scrollbar-thumb
|
||||
background transparent
|
||||
border-radius 4px
|
||||
|
||||
&:hover::-webkit-scrollbar-thumb
|
||||
background rgba(136, 136, 136, 0.4)
|
||||
|
||||
&:hover::-webkit-scrollbar-track
|
||||
background rgba(136, 136, 136, 0.1)
|
||||
|
||||
/* sidebar toggle */
|
||||
.sidebar-toggle
|
||||
background-color transparent
|
||||
background-color rgba($color-bg, 0.8)
|
||||
border 0
|
||||
outline none
|
||||
padding 10px
|
||||
position absolute
|
||||
bottom 0
|
||||
left 0
|
||||
text-align center
|
||||
transition opacity 0.3s
|
||||
width $sidebar-width - 16px
|
||||
z-index 30
|
||||
cursor pointer
|
||||
|
||||
&:hover .sidebar-toggle-button
|
||||
opacity 0.4
|
||||
|
||||
span
|
||||
background-color $color-primary
|
||||
background-color var(--theme-color, $color-primary)
|
||||
display block
|
||||
margin-bottom 4px
|
||||
width 16px
|
||||
height 2px
|
||||
|
||||
body.sticky
|
||||
.sidebar, .sidebar-toggle
|
||||
position fixed
|
||||
|
||||
/* main content */
|
||||
.content
|
||||
padding-top 60px
|
||||
position absolute
|
||||
top 0
|
||||
right 0
|
||||
bottom 0
|
||||
left $sidebar-width
|
||||
transition left 250ms ease
|
||||
|
||||
body.hidesidebar &
|
||||
position relative
|
||||
left unset
|
||||
right unset
|
||||
|
||||
/* markdown content found on pages */
|
||||
.markdown-section
|
||||
margin 0 auto
|
||||
max-width 80%
|
||||
padding 30px 15px 40px 15px
|
||||
position relative
|
||||
|
||||
> *
|
||||
box-sizing border-box
|
||||
font-size inherit
|
||||
|
||||
> :first-child
|
||||
margin-top 0 !important
|
||||
|
||||
.markdown-section hr
|
||||
border none
|
||||
border-bottom 1px solid #eee
|
||||
margin 2em 0
|
||||
|
||||
.markdown-section iframe
|
||||
border 1px solid #eee
|
||||
/* fix horizontal overflow on iOS Safari */
|
||||
width 1px
|
||||
min-width 100%
|
||||
|
||||
.markdown-section table
|
||||
border-collapse collapse
|
||||
border-spacing 0
|
||||
display block
|
||||
margin-bottom 1rem
|
||||
overflow auto
|
||||
width 100%
|
||||
|
||||
.markdown-section th
|
||||
border 1px solid #ddd
|
||||
font-weight bold
|
||||
padding 6px 13px
|
||||
|
||||
.markdown-section td
|
||||
border 1px solid #ddd
|
||||
padding 6px 13px
|
||||
|
||||
.markdown-section tr
|
||||
border-top 1px solid #ccc
|
||||
|
||||
&:nth-child(2n)
|
||||
background-color #f8f8f8
|
||||
|
||||
.markdown-section p.tip
|
||||
background-color #f8f8f8
|
||||
border-bottom-right-radius 2px
|
||||
border-left 4px solid #f66
|
||||
border-top-right-radius 2px
|
||||
margin 2em 0
|
||||
padding 12px 24px 12px 30px
|
||||
position relative
|
||||
|
||||
&:before
|
||||
background-color #f66
|
||||
border-radius 100%
|
||||
color $color-bg
|
||||
content '!'
|
||||
font-family 'Dosis', 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif
|
||||
font-size 14px
|
||||
font-weight bold
|
||||
left -12px
|
||||
line-height 20px
|
||||
position absolute
|
||||
height 20px
|
||||
width 20px
|
||||
text-align center
|
||||
top 14px
|
||||
|
||||
code
|
||||
background-color #efefef
|
||||
|
||||
em
|
||||
color $color-text
|
||||
|
||||
.markdown-section p.warn
|
||||
background rgba($color-primary, 0.1)
|
||||
border-radius 2px
|
||||
padding 1rem
|
||||
|
||||
.markdown-section ul.task-list > li
|
||||
list-style-type none
|
||||
|
||||
body.close
|
||||
.sidebar
|
||||
visibility hidden
|
||||
transform translateX(- $sidebar-width)
|
||||
|
||||
.sidebar-toggle
|
||||
width auto
|
||||
|
||||
.content
|
||||
left 0
|
||||
|
||||
@media print
|
||||
.github-corner, .sidebar-toggle, .sidebar, .app-nav
|
||||
display none
|
||||
|
||||
@media screen and (max-width: 768px)
|
||||
.github-corner, .sidebar-toggle, .sidebar
|
||||
position fixed
|
||||
|
||||
.app-nav
|
||||
margin-top 16px
|
||||
|
||||
.app-nav li ul
|
||||
top 30px
|
||||
|
||||
main
|
||||
height auto
|
||||
min-height 100vh
|
||||
overflow-x hidden
|
||||
|
||||
.sidebar
|
||||
visibility hidden
|
||||
left - $sidebar-width
|
||||
transition transform 250ms ease-out, visibility 250ms
|
||||
|
||||
.content
|
||||
left 0
|
||||
max-width 100vw
|
||||
position static
|
||||
padding-top 20px
|
||||
transition transform 250ms ease
|
||||
|
||||
.app-nav, .github-corner
|
||||
transition transform 250ms ease-out
|
||||
|
||||
.sidebar-toggle
|
||||
background-color transparent
|
||||
width auto
|
||||
padding 30px 30px 10px 10px
|
||||
|
||||
body.close
|
||||
.sidebar
|
||||
visibility visible
|
||||
transform translateX($sidebar-width)
|
||||
|
||||
.sidebar-toggle
|
||||
background-color rgba($color-bg, 0.8)
|
||||
transition 1s background-color
|
||||
width $sidebar-width - 16px
|
||||
padding 10px
|
||||
|
||||
.content
|
||||
transform translateX($sidebar-width)
|
||||
|
||||
.app-nav, .github-corner
|
||||
display none
|
||||
|
||||
.github-corner
|
||||
&:hover .octo-arm
|
||||
animation none
|
||||
|
||||
.octo-arm
|
||||
animation octocat-wave 560ms ease-in-out
|
||||
|
||||
@keyframes octocat-wave
|
||||
0%, 100%
|
||||
transform rotate(0)
|
||||
|
||||
20%, 60%
|
||||
transform rotate(-25deg)
|
||||
|
||||
40%, 80%
|
||||
transform rotate(10deg)
|
@ -1,180 +0,0 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Inconsolata|Inconsolata-Bold')
|
||||
|
||||
$color-primary = #0074d9
|
||||
$color-bg = #fff
|
||||
$color-text = #34495e
|
||||
$sidebar-width = 16rem
|
||||
|
||||
@import 'basic/_layout'
|
||||
@import 'basic/_coverpage'
|
||||
|
||||
/* sidebar */
|
||||
.sidebar
|
||||
color #364149
|
||||
background-color $color-bg
|
||||
|
||||
a
|
||||
color #666
|
||||
text-decoration none
|
||||
|
||||
li
|
||||
list-style none
|
||||
margin 0
|
||||
padding 0.2em 0 0.2em 0
|
||||
|
||||
ul li ul
|
||||
padding 0
|
||||
|
||||
li.active
|
||||
a
|
||||
color #333
|
||||
|
||||
background-color #eee
|
||||
|
||||
.markdown-section h1, .markdown-section h2, .markdown-section h3, .markdown-section h4, .markdown-section strong
|
||||
color #333
|
||||
font-weight 400
|
||||
|
||||
.markdown-section strong
|
||||
color #333
|
||||
font-weight 600
|
||||
|
||||
.markdown-section a
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
|
||||
.markdown-section p, .markdown-section ul, .markdown-section ol
|
||||
line-height 1.6rem
|
||||
margin 0 0 1em 0
|
||||
word-spacing 0.05rem
|
||||
|
||||
.markdown-section h1
|
||||
font-size 2rem
|
||||
font-weight 500
|
||||
margin 0 0 1rem
|
||||
|
||||
.markdown-section h2
|
||||
font-size 1.8rem
|
||||
font-weight 400
|
||||
margin 0 0 1rem 0
|
||||
padding 1rem 0 0 0
|
||||
|
||||
.markdown-section h3
|
||||
font-size 1.5rem
|
||||
margin 52px 0 1.2rem
|
||||
|
||||
.markdown-section h4
|
||||
font-size 1.25rem
|
||||
|
||||
.markdown-section h5
|
||||
font-size 1rem
|
||||
|
||||
.markdown-section h6
|
||||
color #777
|
||||
font-size 1rem
|
||||
|
||||
.markdown-section figure, .markdown-section p, .markdown-section ul, .markdown-section ol
|
||||
margin 1.2em 0
|
||||
|
||||
.markdown-section ul, .markdown-section ol
|
||||
padding-left 1.5rem
|
||||
|
||||
.markdown-section li
|
||||
line-height 1.5
|
||||
margin 0
|
||||
|
||||
.markdown-section blockquote
|
||||
border-left 4px solid $color-primary
|
||||
border-left 4px solid var(--theme-color, $color-primary)
|
||||
color #858585
|
||||
margin 2em 0
|
||||
padding-left 20px
|
||||
|
||||
.markdown-section blockquote p
|
||||
font-weight 600
|
||||
margin-left 0
|
||||
|
||||
.markdown-section iframe
|
||||
margin 1em 0
|
||||
|
||||
.markdown-section em
|
||||
color #7f8c8d
|
||||
|
||||
.markdown-section code
|
||||
background-color #f9f9f9
|
||||
border-radius 3px
|
||||
font-family Inconsolata, monospace
|
||||
padding 0.2em 0.4rem
|
||||
white-space nowrap
|
||||
|
||||
.markdown-section pre
|
||||
background-color #f9f9f9
|
||||
border-left 2px solid #eee
|
||||
font-family Inconsolata, monospace
|
||||
font-size 16px
|
||||
margin 0 0 1em 0
|
||||
padding 8px
|
||||
padding 0 10px 12px 0
|
||||
overflow auto
|
||||
word-wrap normal
|
||||
position relative
|
||||
|
||||
/* code highlight */
|
||||
.token.cdata, .token.comment, .token.doctype, .token.prolog
|
||||
color #93a1a1 /* base1 */
|
||||
|
||||
.token.punctuation
|
||||
color #586e75 /* base01 */
|
||||
|
||||
.namespace
|
||||
opacity 0.7
|
||||
|
||||
.token.property, .token.tag, .token.boolean, .token.number, .token.constant, .token.symbol, .token.deleted
|
||||
color #268bd2 /* blue */
|
||||
|
||||
.token.selector, .token.attr-name, .token.string, .token.char, .token.builtin, .token.url, .token.inserted
|
||||
color #2aa198 /* cyan */
|
||||
|
||||
.token.entity
|
||||
color #657b83 /* base00 */
|
||||
background #eee8d5 /* base2 */
|
||||
|
||||
.token.atrule, .token.attr-value, .token.keyword
|
||||
color #a11 /* green */
|
||||
|
||||
.token.function
|
||||
color #b58900 /* yellow */
|
||||
|
||||
.token.regex, .token.important, .token.variable
|
||||
color #cb4b16 /* orange */
|
||||
|
||||
.token.important, .token.bold
|
||||
font-weight bold
|
||||
|
||||
.token.italic
|
||||
font-style italic
|
||||
|
||||
.token.entity
|
||||
cursor help
|
||||
|
||||
.markdown-section pre > code
|
||||
background-color #f8f8f8
|
||||
border-radius 2px
|
||||
display block
|
||||
font-family Inconsolata, monospace
|
||||
line-height 1.1rem
|
||||
max-width inherit
|
||||
overflow inherit
|
||||
padding 20px 0.8em 20px
|
||||
position relative
|
||||
white-space inherit
|
||||
|
||||
.markdown-section code::after, .markdown-section code::before
|
||||
letter-spacing 0.05rem
|
||||
|
||||
code .token
|
||||
-webkit-font-smoothing initial
|
||||
-moz-osx-font-smoothing initial
|
||||
min-height 1.5rem
|
||||
position: relative
|
||||
left: auto
|
1
src/themes/core.css
Normal file
1
src/themes/core.css
Normal file
@ -0,0 +1 @@
|
||||
@import 'shared/__index.css';
|
@ -1,237 +0,0 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Roboto+Mono|Source+Sans+Pro:300,400,600')
|
||||
|
||||
$color-primary = #ea6f5a
|
||||
$color-bg = #3f3f3f
|
||||
$color-text = #c8c8c8
|
||||
$sidebar-width = 300px
|
||||
|
||||
@import 'basic/_layout'
|
||||
@import 'basic/_coverpage'
|
||||
|
||||
body
|
||||
background-color $color-bg
|
||||
|
||||
/* sidebar */
|
||||
.sidebar
|
||||
background-color $color-bg
|
||||
color #c8c8c8
|
||||
|
||||
li
|
||||
margin 6px 15px 6px 0
|
||||
|
||||
ul li a
|
||||
color #c8c8c8
|
||||
font-size 14px
|
||||
overflow hidden
|
||||
text-decoration none
|
||||
text-overflow ellipsis
|
||||
white-space nowrap
|
||||
|
||||
&:hover
|
||||
text-decoration underline
|
||||
|
||||
ul li ul
|
||||
padding 0
|
||||
|
||||
ul li.active > a
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
font-weight 600
|
||||
|
||||
/* markdown content found on pages */
|
||||
.markdown-section h1, .markdown-section h2, .markdown-section h3, .markdown-section h4, .markdown-section strong
|
||||
color #657b83
|
||||
font-weight 600
|
||||
|
||||
.markdown-section a
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
font-weight 600
|
||||
|
||||
.markdown-section h1
|
||||
font-size 2rem
|
||||
margin 0 0 1rem
|
||||
|
||||
.markdown-section h2
|
||||
font-size 1.75rem
|
||||
margin 45px 0 0.8rem
|
||||
|
||||
.markdown-section h3
|
||||
font-size 1.5rem
|
||||
margin 40px 0 0.6rem
|
||||
|
||||
.markdown-section h4
|
||||
font-size 1.25rem
|
||||
|
||||
.markdown-section h5
|
||||
font-size 1rem
|
||||
|
||||
.markdown-section h6
|
||||
color #777
|
||||
font-size 1rem
|
||||
|
||||
.markdown-section figure, .markdown-section p, .markdown-section ul, .markdown-section ol
|
||||
margin 1.2em 0
|
||||
|
||||
.markdown-section p, .markdown-section ul, .markdown-section ol
|
||||
line-height 1.6rem
|
||||
word-spacing 0.05rem
|
||||
|
||||
.markdown-section ul, .markdown-section ol
|
||||
padding-left 1.5rem
|
||||
|
||||
.markdown-section blockquote
|
||||
border-left 4px solid $color-primary
|
||||
border-left 4px solid var(--theme-color, $color-primary)
|
||||
color #858585
|
||||
margin 2em 0
|
||||
padding-left 20px
|
||||
|
||||
.markdown-section blockquote p
|
||||
font-weight 600
|
||||
margin-left 0
|
||||
|
||||
.markdown-section iframe
|
||||
margin 1em 0
|
||||
|
||||
.markdown-section em
|
||||
color #7f8c8d
|
||||
|
||||
.markdown-section code
|
||||
background-color #282828
|
||||
border-radius 2px
|
||||
color #657b83
|
||||
font-family 'Roboto Mono', Monaco, courier, monospace
|
||||
margin 0 2px
|
||||
padding 3px 5px
|
||||
white-space pre-wrap
|
||||
|
||||
.markdown-section > :not(h1):not(h2):not(h3):not(h4):not(h5):not(h6) code
|
||||
font-size 0.8rem
|
||||
|
||||
.markdown-section pre
|
||||
-moz-osx-font-smoothing initial
|
||||
-webkit-font-smoothing initial
|
||||
background-color #282828
|
||||
font-family 'Roboto Mono', Monaco, courier, monospace
|
||||
line-height 1.5rem
|
||||
margin 1.2em 0
|
||||
overflow auto
|
||||
padding 0 1.4rem
|
||||
position relative
|
||||
word-wrap normal
|
||||
|
||||
.markdown-section tr:nth-child(2n)
|
||||
background-color #282828
|
||||
|
||||
/* code highlight */
|
||||
.token.comment, .token.prolog, .token.doctype, .token.cdata
|
||||
color #8e908c
|
||||
|
||||
.token.namespace
|
||||
opacity 0.7
|
||||
|
||||
.token.boolean, .token.number
|
||||
color #c76b29
|
||||
|
||||
.token.punctuation
|
||||
color #525252
|
||||
|
||||
.token.property
|
||||
color #c08b30
|
||||
|
||||
.token.tag
|
||||
color #2973b7
|
||||
|
||||
.token.string
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
|
||||
.token.selector
|
||||
color #6679cc
|
||||
|
||||
.token.attr-name
|
||||
color #2973b7
|
||||
|
||||
.token.entity, .token.url, .language-css .token.string, .style .token.string
|
||||
color #22a2c9
|
||||
|
||||
.token.attr-value, .token.control, .token.directive, .token.unit
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
|
||||
.token.keyword
|
||||
color #e96900
|
||||
|
||||
.token.statement, .token.regex, .token.atrule
|
||||
color #22a2c9
|
||||
|
||||
.token.placeholder, .token.variable
|
||||
color #3d8fd1
|
||||
|
||||
.token.deleted
|
||||
text-decoration line-through
|
||||
|
||||
.token.inserted
|
||||
border-bottom 1px dotted #202746
|
||||
text-decoration none
|
||||
|
||||
.token.italic
|
||||
font-style italic
|
||||
|
||||
.token.important, .token.bold
|
||||
font-weight bold
|
||||
|
||||
.token.important
|
||||
color #c94922
|
||||
|
||||
.token.entity
|
||||
cursor help
|
||||
|
||||
.markdown-section pre > code
|
||||
-moz-osx-font-smoothing initial
|
||||
-webkit-font-smoothing initial
|
||||
background-color #282828
|
||||
border-radius 2px
|
||||
color #657b83
|
||||
display block
|
||||
font-family 'Roboto Mono', Monaco, courier, monospace
|
||||
font-size 0.8rem
|
||||
line-height inherit
|
||||
margin 0 2px
|
||||
max-width inherit
|
||||
overflow inherit
|
||||
padding 2.2em 5px
|
||||
white-space inherit
|
||||
|
||||
.markdown-section code::after, .markdown-section code::before
|
||||
letter-spacing 0.05rem
|
||||
|
||||
code .token
|
||||
-moz-osx-font-smoothing initial
|
||||
-webkit-font-smoothing initial
|
||||
min-height 1.5rem
|
||||
position: relative
|
||||
left: auto
|
||||
|
||||
pre::after
|
||||
color #ccc
|
||||
content attr(data-lang)
|
||||
font-size 0.6rem
|
||||
font-weight 600
|
||||
height 15px
|
||||
line-height 15px
|
||||
padding 5px 10px 0
|
||||
position absolute
|
||||
right 0
|
||||
text-align right
|
||||
top 0
|
||||
|
||||
.markdown-section p.tip
|
||||
background-color #282828
|
||||
color #657b83
|
||||
|
||||
input[type='search']
|
||||
background #4f4f4f
|
||||
border-color #4f4f4f
|
||||
color #c8c8c8
|
@ -1,237 +0,0 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Thasadith:400,400i,700')
|
||||
|
||||
$color-primary = #00ffff
|
||||
$color-bg = #f0ffff
|
||||
$color-text = #34495e
|
||||
$sidebar-width = 300px
|
||||
|
||||
@import 'basic/_layout'
|
||||
@import 'basic/_coverpage'
|
||||
|
||||
body
|
||||
background-color $color-bg
|
||||
|
||||
/* sidebar */
|
||||
.sidebar
|
||||
background-color $color-bg
|
||||
color #364149
|
||||
|
||||
li
|
||||
margin 6px 0 6px 0
|
||||
|
||||
ul li a
|
||||
color #505d6b
|
||||
font-size 14px
|
||||
font-weight normal
|
||||
overflow hidden
|
||||
text-decoration none
|
||||
text-overflow ellipsis
|
||||
white-space nowrap
|
||||
|
||||
&:hover
|
||||
text-decoration underline
|
||||
|
||||
ul li ul
|
||||
padding 0
|
||||
|
||||
ul li.active > a
|
||||
border-right 2px solid
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
font-weight 600
|
||||
|
||||
.app-sub-sidebar
|
||||
li
|
||||
&::before
|
||||
content '-'
|
||||
padding-right 4px
|
||||
float left
|
||||
|
||||
/* markdown content found on pages */
|
||||
.markdown-section h1, .markdown-section h2, .markdown-section h3, .markdown-section h4, .markdown-section strong
|
||||
color #2c3e50
|
||||
font-weight 600
|
||||
|
||||
.markdown-section a
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
font-weight 600
|
||||
|
||||
&:hover
|
||||
text-decoration underline
|
||||
|
||||
.markdown-section h1
|
||||
font-size 2rem
|
||||
margin 0 0 1rem
|
||||
|
||||
.markdown-section h2
|
||||
font-size 1.75rem
|
||||
margin 45px 0 0.8rem
|
||||
|
||||
.markdown-section h3
|
||||
font-size 1.5rem
|
||||
margin 40px 0 0.6rem
|
||||
|
||||
.markdown-section h4
|
||||
font-size 1.25rem
|
||||
|
||||
.markdown-section h5
|
||||
font-size 1rem
|
||||
|
||||
.markdown-section h6
|
||||
color #777
|
||||
font-size 1rem
|
||||
|
||||
.markdown-section figure, .markdown-section p
|
||||
margin 1.2em 0
|
||||
|
||||
.markdown-section p, .markdown-section ul, .markdown-section ol
|
||||
line-height 1.6rem
|
||||
word-spacing 0.05rem
|
||||
|
||||
.markdown-section ul, .markdown-section ol
|
||||
padding-left 1.5rem
|
||||
|
||||
.markdown-section blockquote
|
||||
border-left 4px solid $color-primary
|
||||
border-left 4px solid var(--theme-color, $color-primary)
|
||||
color #858585
|
||||
margin 2em 0
|
||||
padding-left 20px
|
||||
|
||||
.markdown-section blockquote p
|
||||
font-weight 600
|
||||
margin-left 0
|
||||
|
||||
.markdown-section iframe
|
||||
margin 1em 0
|
||||
|
||||
.markdown-section em
|
||||
color #7f8c8d
|
||||
|
||||
.markdown-section code
|
||||
background-color #f8f8f8
|
||||
border-radius 2px
|
||||
color #e96900
|
||||
font-family 'Roboto Mono', Monaco, courier, monospace
|
||||
margin 0 2px
|
||||
padding 3px 5px
|
||||
white-space pre-wrap
|
||||
|
||||
.markdown-section > :not(h1):not(h2):not(h3):not(h4):not(h5):not(h6) code
|
||||
font-size 0.8rem
|
||||
|
||||
.markdown-section pre
|
||||
-moz-osx-font-smoothing initial
|
||||
-webkit-font-smoothing initial
|
||||
background-color #f8f8f8
|
||||
font-family 'Roboto Mono', Monaco, courier, monospace
|
||||
line-height 1.5rem
|
||||
margin 1.2em 0
|
||||
overflow auto
|
||||
padding 0 1.4rem
|
||||
position relative
|
||||
word-wrap normal
|
||||
|
||||
/* code highlight */
|
||||
.token.comment, .token.prolog, .token.doctype, .token.cdata
|
||||
color #8e908c
|
||||
|
||||
.token.namespace
|
||||
opacity 0.7
|
||||
|
||||
.token.boolean, .token.number
|
||||
color #c76b29
|
||||
|
||||
.token.punctuation
|
||||
color #525252
|
||||
|
||||
.token.property
|
||||
color #c08b30
|
||||
|
||||
.token.tag
|
||||
color #2973b7
|
||||
|
||||
.token.string
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
|
||||
.token.selector
|
||||
color #6679cc
|
||||
|
||||
.token.attr-name
|
||||
color #2973b7
|
||||
|
||||
.token.entity, .token.url, .language-css .token.string, .style .token.string
|
||||
color #22a2c9
|
||||
|
||||
.token.attr-value, .token.control, .token.directive, .token.unit
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
|
||||
.token.keyword, .token.function
|
||||
color #e96900
|
||||
|
||||
.token.statement, .token.regex, .token.atrule
|
||||
color #22a2c9
|
||||
|
||||
.token.placeholder, .token.variable
|
||||
color #3d8fd1
|
||||
|
||||
.token.deleted
|
||||
text-decoration line-through
|
||||
|
||||
.token.inserted
|
||||
border-bottom 1px dotted #202746
|
||||
text-decoration none
|
||||
|
||||
.token.italic
|
||||
font-style italic
|
||||
|
||||
.token.important, .token.bold
|
||||
font-weight bold
|
||||
|
||||
.token.important
|
||||
color #c94922
|
||||
|
||||
.token.entity
|
||||
cursor help
|
||||
|
||||
.markdown-section pre > code
|
||||
-moz-osx-font-smoothing initial
|
||||
-webkit-font-smoothing initial
|
||||
background-color #f8f8f8
|
||||
border-radius 2px
|
||||
color #525252
|
||||
display block
|
||||
font-family 'Roboto Mono', Monaco, courier, monospace
|
||||
font-size 0.8rem
|
||||
line-height inherit
|
||||
margin 0 2px
|
||||
max-width inherit
|
||||
overflow inherit
|
||||
padding 2.2em 5px
|
||||
white-space inherit
|
||||
|
||||
.markdown-section code::after, .markdown-section code::before
|
||||
letter-spacing 0.05rem
|
||||
|
||||
code .token
|
||||
-moz-osx-font-smoothing initial
|
||||
-webkit-font-smoothing initial
|
||||
min-height 1.5rem
|
||||
position: relative
|
||||
left: auto
|
||||
|
||||
pre::after
|
||||
color #ccc
|
||||
content attr(data-lang)
|
||||
font-size 0.6rem
|
||||
font-weight 600
|
||||
height 15px
|
||||
line-height 15px
|
||||
padding 5px 10px 0
|
||||
position absolute
|
||||
right 0
|
||||
text-align right
|
||||
top 0
|
@ -1,7 +0,0 @@
|
||||
$color-primary = #000
|
||||
$color-bg = #fff
|
||||
$color-text = #000
|
||||
$sidebar-width = 300px
|
||||
|
||||
@import 'basic/_layout'
|
||||
@import 'basic/_coverpage'
|
13
src/themes/shared/__index.css
Normal file
13
src/themes/shared/__index.css
Normal file
@ -0,0 +1,13 @@
|
||||
@import '_vars.css';
|
||||
@import '_vars-advanced.css';
|
||||
@import '_base.css';
|
||||
@import '_elements.css';
|
||||
@import '_app.css';
|
||||
@import '_coverpage.css';
|
||||
@import '_navbar.css';
|
||||
@import '_sidebar.css';
|
||||
@import '_markdown.css';
|
||||
@import '_syntax.css';
|
||||
@import '_util.css';
|
||||
@import '_mq.css';
|
||||
@import '_classes.css';
|
153
src/themes/shared/_app.css
Normal file
153
src/themes/shared/_app.css
Normal file
@ -0,0 +1,153 @@
|
||||
/* App */
|
||||
/* ========================================================================== */
|
||||
body {
|
||||
> .progress {
|
||||
position: fixed;
|
||||
z-index: var(--z-progress);
|
||||
inset: 0 0 auto 0;
|
||||
height: 2px;
|
||||
width: 0%;
|
||||
background: var(--theme-color);
|
||||
transition:
|
||||
width var(--duration-medium) ease,
|
||||
opacity calc(var(--duration-medium) * 2);
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
|
||||
/* Overlay */
|
||||
&::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
z-index: var(--z-main-overlay);
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 0;
|
||||
background: transparent;
|
||||
transition:
|
||||
width 0s var(--duration-medium),
|
||||
background var(--duration-medium);
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> .content {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
transition: left var(--duration-medium) ease;
|
||||
|
||||
body:has(.sidebar.show) & {
|
||||
left: var(--sidebar-width);
|
||||
}
|
||||
|
||||
/* hideSidebar: true */
|
||||
body:not:has(.sidebar) & {
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.github-corner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: var(--z-github-corner);
|
||||
border-bottom: 0;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
.octo-arm {
|
||||
animation: github-corner 560ms ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
height: var(--navbar-height);
|
||||
width: var(--navbar-height);
|
||||
color: var(--color-bg);
|
||||
fill: var(--theme-color);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes github-corner {
|
||||
0%,
|
||||
100% {
|
||||
rotate: 0;
|
||||
}
|
||||
20%,
|
||||
60% {
|
||||
rotate: -25deg;
|
||||
}
|
||||
40%,
|
||||
80% {
|
||||
rotate: 10deg;
|
||||
}
|
||||
}
|
||||
|
||||
.loading:empty /* Block: <div class="loading"></div> */,
|
||||
.loading:not(:empty)::before /* Pseudo: <div class="loading">Content</div> */ {
|
||||
--_gradient: no-repeat
|
||||
radial-gradient(farthest-side, var(--theme-color) 92%, #0000);
|
||||
|
||||
content: '';
|
||||
display: block;
|
||||
width: 36px;
|
||||
aspect-ratio: 1;
|
||||
background:
|
||||
var(--_gradient) top,
|
||||
var(--_gradient) left,
|
||||
var(--_gradient) right,
|
||||
var(--_gradient) bottom;
|
||||
background-size: 10px 10px;
|
||||
animation: loading 1s infinite;
|
||||
}
|
||||
|
||||
.loading:not(:empty)::before {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
translate: -50% -50%;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
to {
|
||||
rotate: 0.5turn;
|
||||
}
|
||||
}
|
||||
|
||||
#app {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.75em;
|
||||
height: 100vh;
|
||||
padding-inline: 50px;
|
||||
}
|
||||
|
||||
#skip-to-content {
|
||||
position: fixed;
|
||||
z-index: var(--z-skip-to-content);
|
||||
top: 0;
|
||||
left: 50%;
|
||||
opacity: 0;
|
||||
translate: -50% -100%;
|
||||
transition-property: opacity, translate;
|
||||
transition-duration: 0s, var(--duration-medium);
|
||||
transition-delay: var(--duration-medium), 0s;
|
||||
transition-timing-function: ease;
|
||||
|
||||
&:focus {
|
||||
opacity: 1;
|
||||
translate: -50% 0.75rem;
|
||||
transition-duration: 0s, var(--duration-medium);
|
||||
transition-delay: 0s, 0s;
|
||||
}
|
||||
}
|
63
src/themes/shared/_base.css
Normal file
63
src/themes/shared/_base.css
Normal file
@ -0,0 +1,63 @@
|
||||
/* Base */
|
||||
/* ========================================================================== */
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
border: 0;
|
||||
font: inherit;
|
||||
-webkit-text-size-adjust: none;
|
||||
text-size-adjust: none;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
html {
|
||||
background: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
font-family: var(--font-family);
|
||||
font-feature-settings:
|
||||
'liga' 1,
|
||||
'calt' 1; /* NOTE: Fix for Chrome */
|
||||
font-optical-sizing: auto;
|
||||
font-size: var(--font-size);
|
||||
font-weight: var(--font-weight);
|
||||
line-height: var(--line-height);
|
||||
scroll-padding-top: var(--scroll-padding-top);
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
margin: 0;
|
||||
|
||||
&:not(.ready) {
|
||||
overflow: hidden;
|
||||
|
||||
[data-cloak],
|
||||
.app-nav,
|
||||
> nav {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loading animation */
|
||||
&.loading {
|
||||
&::before {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
/* Content or cover loaded */
|
||||
&:has(:where(#main, .cover-main):not(:empty)) {
|
||||
&::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[tabindex='-1']:focus {
|
||||
outline: none !important;
|
||||
}
|
181
src/themes/shared/_classes.css
Normal file
181
src/themes/shared/_classes.css
Normal file
@ -0,0 +1,181 @@
|
||||
/* Sidebar chevrons */
|
||||
/* ========================================================================== */
|
||||
/* prettier-ignore */
|
||||
:root:has(body[class*='sidebar-chevron']) {
|
||||
--sidebar-chevron-collapsed-color: var(--color-mono-3);
|
||||
--sidebar-chevron-expanded-color : var(--theme-color);
|
||||
|
||||
/* Chevron right (Mono) */
|
||||
--sidebar-pagelink-bg: no-repeat var(--_sidebar_pagelink-bg-left)
|
||||
calc(50% - 2.5px) / 6px 5px
|
||||
linear-gradient(
|
||||
45deg,
|
||||
transparent 2.75px,
|
||||
var(--sidebar-chevron-collapsed-color) 2.75px 4.25px,
|
||||
transparent 4px
|
||||
),
|
||||
no-repeat var(--_sidebar_pagelink-bg-left) calc(50% + 2.5px) / 6px 5px
|
||||
linear-gradient(
|
||||
135deg,
|
||||
transparent 2.75px,
|
||||
var(--sidebar-chevron-collapsed-color) 2.75px 4.25px,
|
||||
transparent 4px
|
||||
);
|
||||
/* Chevron right (Theme color) */
|
||||
--sidebar-pagelink-bg-collapsed: no-repeat var(--_sidebar_pagelink-bg-left)
|
||||
calc(50% - 2.5px) / 6px 5px
|
||||
linear-gradient(
|
||||
45deg,
|
||||
transparent 2.75px,
|
||||
var(--sidebar-chevron-expanded-color) 2.75px 4.25px,
|
||||
transparent 4px
|
||||
),
|
||||
no-repeat var(--_sidebar_pagelink-bg-left) calc(50% + 2.5px) / 6px 5px
|
||||
linear-gradient(
|
||||
135deg,
|
||||
transparent 2.75px,
|
||||
var(--sidebar-chevron-expanded-color) 2.75px 4.25px,
|
||||
transparent 4px
|
||||
);
|
||||
/* Chevron down (Theme color) */
|
||||
--sidebar-pagelink-bg-expanded: no-repeat
|
||||
calc(var(--_sidebar_pagelink-bg-left) - 2px) center / 5px 6px
|
||||
linear-gradient(
|
||||
225deg,
|
||||
transparent 2.75px,
|
||||
var(--sidebar-chevron-expanded-color) 2.75px 4.25px,
|
||||
transparent 4.25px
|
||||
),
|
||||
no-repeat calc(var(--_sidebar_pagelink-bg-left) + 3px) center / 5px 6px
|
||||
linear-gradient(
|
||||
135deg,
|
||||
transparent 2.75px,
|
||||
var(--sidebar-chevron-expanded-color) 2.75px 4.25px,
|
||||
transparent 4.25px
|
||||
);
|
||||
/* Dot (active without children) */
|
||||
--sidebar-pagelink-bg-empty: no-repeat var(--_sidebar_pagelink-bg-left) center /
|
||||
7px 7px
|
||||
radial-gradient(
|
||||
circle,
|
||||
var(--sidebar-chevron-expanded-color) 0,
|
||||
var(--sidebar-chevron-expanded-color) 70%,
|
||||
transparent 71%
|
||||
);
|
||||
}
|
||||
|
||||
body[class*='sidebar-chevron'] {
|
||||
.sidebar-nav a.page-link.no-chevron {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Left */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
:root:has(body.sidebar-chevron-left) {
|
||||
--_sidebar_pagelink-bg-left: 2px;
|
||||
}
|
||||
|
||||
body.sidebar-chevron-left {
|
||||
.sidebar-nav {
|
||||
--_inset: 18px;
|
||||
|
||||
li {
|
||||
a.page-link {
|
||||
padding-left: var(--_inset);
|
||||
}
|
||||
|
||||
&:has(> .page-link, > p > .page-link) {
|
||||
> ul,
|
||||
> p > ul {
|
||||
margin-left: calc(var(--_sidebar-list-inset) + var(--_inset));
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Right */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
:root:has(body.sidebar-chevron-right) {
|
||||
--_sidebar_pagelink-bg-left: calc(100% - var(--_sidebar-inset));
|
||||
}
|
||||
|
||||
body.sidebar-chevron-right {
|
||||
.sidebar-nav {
|
||||
li {
|
||||
a {
|
||||
padding-right: calc(var(--_sidebar-inset) + 15px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sidebar groups */
|
||||
/* ========================================================================== */
|
||||
/* prettier-ignore */
|
||||
:root:has(body.sidebar-group-box) {
|
||||
--sidebar-group-border : 1px solid var(--sidebar-border-color);
|
||||
--sidebar-group-spacing: 1em;
|
||||
}
|
||||
|
||||
/* prettier-ignore */
|
||||
:root:has(body.sidebar-group-underline) {
|
||||
--sidebar-group-spacing : 0.5em;
|
||||
--sidebar-group-title-border : 1px solid var(--sidebar-border-color);
|
||||
--sidebar-group-title-spacing: 0.35em;
|
||||
}
|
||||
|
||||
/* Sidebar link clamp */
|
||||
/* ========================================================================== */
|
||||
body.sidebar-link-clamp {
|
||||
.sidebar {
|
||||
a {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sidebar toggle */
|
||||
/* ========================================================================== */
|
||||
body.sidebar-toggle-chevron {
|
||||
.sidebar-toggle-button {
|
||||
span {
|
||||
--_size: 10px;
|
||||
|
||||
border: solid currentColor;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
|
||||
&:where(:not(:first-child)) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
height: var(--_size);
|
||||
width: var(--_size);
|
||||
border-width: 2px 2px 0 0;
|
||||
rotate: 45deg;
|
||||
translate: -20%;
|
||||
|
||||
body:has(.sidebar.show) & {
|
||||
rotate: -135deg;
|
||||
translate: 20%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body.sidebar-toggle-hamburger {
|
||||
.sidebar-toggle-button {
|
||||
span {
|
||||
height: 2px;
|
||||
width: 65%;
|
||||
max-width: 16px;
|
||||
}
|
||||
}
|
||||
}
|
73
src/themes/shared/_coverpage.css
Normal file
73
src/themes/shared/_coverpage.css
Normal file
@ -0,0 +1,73 @@
|
||||
/* Cover */
|
||||
/* ========================================================================== */
|
||||
.cover {
|
||||
display: none;
|
||||
position: relative;
|
||||
z-index: var(--z-cover);
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
background: var(--cover-bg);
|
||||
color: var(--cover-color);
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0 0 0 0;
|
||||
background: var(--cover-bg-overlay);
|
||||
-webkit-backdrop-filter: brightness(var(--cover-bg-brightness));
|
||||
backdrop-filter: brightness(var(--cover-bg-brightness));
|
||||
}
|
||||
|
||||
&.show {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
a:not(.anchor) {
|
||||
text-decoration-color: var(--theme-color);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
font-size: var(--font-size-xl);
|
||||
line-height: var(--heading-line-height);
|
||||
text-align: center;
|
||||
|
||||
&,
|
||||
& > p {
|
||||
margin-block: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
position: relative;
|
||||
color: var(--cover-title-color);
|
||||
font: var(--cover-title-font);
|
||||
|
||||
a {
|
||||
&,
|
||||
&:hover {
|
||||
text-decoration-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
small {
|
||||
font-weight: var(--font-weight);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-bottom: 1.5rem;
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
}
|
||||
|
||||
.cover-main {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 1;
|
||||
margin: 5vh var(--content-margin-inline);
|
||||
text-align: center;
|
||||
}
|
332
src/themes/shared/_elements.css
Normal file
332
src/themes/shared/_elements.css
Normal file
@ -0,0 +1,332 @@
|
||||
/* Elements */
|
||||
/* ========================================================================== */
|
||||
small,
|
||||
sub,
|
||||
sup {
|
||||
display: inline-block;
|
||||
font-size: var(--font-size-s);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--link-color);
|
||||
|
||||
/* NOTE: Safari may require a forced redraw when changing text-decoration
|
||||
values (e.g., :hover). One way to do this is via translate: 0 0 0. */
|
||||
&:not(.button) {
|
||||
text-decoration-color: var(--link-underline-color);
|
||||
text-decoration-line: underline;
|
||||
text-decoration-style: solid;
|
||||
text-decoration-thickness: var(--link-underline-thickness);
|
||||
text-underline-offset: 2px;
|
||||
|
||||
&:hover {
|
||||
color: var(--link-color-hover);
|
||||
text-decoration-color: var(--link-underline-color-hover);
|
||||
text-decoration-thickness: var(--link-underline-thickness-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 0;
|
||||
line-height: var(--heading-line-height);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin-block: 1em;
|
||||
border: none;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
ins {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
kbd {
|
||||
display: inline-block;
|
||||
min-width: 2em;
|
||||
padding: 0.3em 0.5em;
|
||||
border: var(--kbd-border);
|
||||
border-radius: var(--kbd-border-radius);
|
||||
background: var(--kbd-bg);
|
||||
color: var(--kbd-color);
|
||||
font-size: var(--font-size-s);
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding-inline: 1px;
|
||||
border-radius: 1px;
|
||||
background: var(--mark-bg);
|
||||
color: var(--mark-color);
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--strong-color);
|
||||
font-weight: var(--strong-font-weight);
|
||||
}
|
||||
|
||||
summary {
|
||||
cursor: pointer;
|
||||
|
||||
> * {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
/* ---------------------------------- */
|
||||
a.button,
|
||||
button[type],
|
||||
input.button,
|
||||
input:is([type='button'], [type='reset'], [type='submit']) {
|
||||
display: inline-block;
|
||||
margin-block: 0.35em;
|
||||
border: 2px solid var(--color-mono-2);
|
||||
box-shadow: 0 0 0 3px transparent;
|
||||
background: var(--color-mono-2);
|
||||
color: var(--color-text);
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
transition: outline-color var(--duration-fast);
|
||||
|
||||
&:not(:focus-visible) {
|
||||
outline-color: transparent;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
outline: 3px solid var(--theme-color-3);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
+ & {
|
||||
margin-left: 0.25em;
|
||||
}
|
||||
|
||||
&.primary,
|
||||
&.secondary {
|
||||
border-color: var(--button-bg);
|
||||
}
|
||||
|
||||
/* Primary Button */
|
||||
&.primary {
|
||||
background: var(--button-bg);
|
||||
color: var(--button-color);
|
||||
}
|
||||
|
||||
/* Secondary Button */
|
||||
&.secondary {
|
||||
background: transparent;
|
||||
color: var(--button-bg);
|
||||
}
|
||||
}
|
||||
|
||||
a.button,
|
||||
button[type],
|
||||
input:where([type='button'], [type='reset'], [type='submit']) {
|
||||
padding: var(--button-padding);
|
||||
border-radius: var(--button-border-radius);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
button[type],
|
||||
input.button,
|
||||
input:where([type='button'], [type='reset'], [type='submit']) {
|
||||
&:disabled {
|
||||
opacity: 0.6;
|
||||
filter: grayscale(100%);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
button:not([type]) {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* Emoji */
|
||||
/* ---------------------------------- */
|
||||
.emoji {
|
||||
&:where(img) {
|
||||
height: 1.2em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&:where(span) {
|
||||
font-family: var(--font-family-emoji);
|
||||
font-size: var(--font-size-emoji);
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
/* Form Elements
|
||||
/* ---------------------------------- */
|
||||
fieldset,
|
||||
input:not([type='checkbox']),
|
||||
optgroup,
|
||||
option,
|
||||
select,
|
||||
textarea {
|
||||
&:disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
fieldset,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
max-width: 100%;
|
||||
border-radius: var(--form-element-border-radius);
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
padding: 0.25em 0.5em;
|
||||
border: 1px solid var(--form-element-border-color);
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
background: var(--form-element-bg);
|
||||
color: var(--form-element-color);
|
||||
}
|
||||
|
||||
input,
|
||||
label,
|
||||
select {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
padding: 1em;
|
||||
border: 1px solid var(--color-mono-2);
|
||||
|
||||
> :first-child,
|
||||
> legend + * {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
> :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
input:where([type='checkbox'], [type='radio']) {
|
||||
--_size: 1.1em;
|
||||
|
||||
appearance: none;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: -0.1em;
|
||||
height: var(--_size);
|
||||
width: var(--_size);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
&.toggle {
|
||||
--_inset: 2px;
|
||||
--_handle-size: calc(var(--_size) - (var(--_inset) * 2));
|
||||
|
||||
height: calc(var(--_size) + 2px);
|
||||
width: calc(var(--_size) * 1.9);
|
||||
border-radius: 100vh;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: var(--_inset);
|
||||
left: var(--_inset);
|
||||
height: var(--_handle-size);
|
||||
width: var(--_handle-size);
|
||||
border-radius: 100vh;
|
||||
background: var(--color-mono-3);
|
||||
transition: all var(--duration-fast);
|
||||
}
|
||||
|
||||
&:checked {
|
||||
background: var(--theme-color);
|
||||
border-color: var(--theme-color);
|
||||
|
||||
&::before {
|
||||
left: calc(100% - var(--_handle-size) - var(--_inset));
|
||||
background: var(--color-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
label & {
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
input:where([type='checkbox']):not(.toggle) {
|
||||
border-radius: min(var(--form-element-border-radius), 3px);
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 43%;
|
||||
left: 50%;
|
||||
rotate: 40deg;
|
||||
translate: -50% -50%;
|
||||
height: 0.7em;
|
||||
width: 0.4em;
|
||||
border-bottom: 2px solid transparent;
|
||||
border-right: 2px solid transparent;
|
||||
}
|
||||
|
||||
&:checked {
|
||||
border-color: var(--theme-color);
|
||||
background: var(--theme-color);
|
||||
|
||||
&::before {
|
||||
border-color: var(--color-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input:where([type='radio']):not(.toggle) {
|
||||
border-radius: 100vh;
|
||||
|
||||
&:checked {
|
||||
border-color: var(--theme-color);
|
||||
box-shadow: inset 0 0 0 0.25em var(--theme-color);
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
select {
|
||||
appearance: none;
|
||||
padding-right: 20px;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4.95 10'%3E%3Cpolygon fill='black' opacity='0.5' points='1.41 4.67 2.48 3.18 3.54 4.67 1.41 4.67'/%3E%3Cpolygon fill='black' opacity='0.5' points='3.54 5.33 2.48 6.82 1.41 5.33 3.54 5.33'/%3E%3C/svg%3E");
|
||||
background-position: right 2px center;
|
||||
background-repeat: no-repeat;
|
||||
font-weight: normal; /* Fix for Safari using serif font is weight is bold */
|
||||
|
||||
@media screen and (prefers-color-scheme: dark) {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4.95 10'%3E%3Cpolygon fill='white' opacity='0.4' points='1.41 4.67 2.48 3.18 3.54 4.67 1.41 4.67'/%3E%3Cpolygon fill='white' opacity='0.4' points='3.54 5.33 2.48 6.82 1.41 5.33 3.54 5.33'/%3E%3C/svg%3E");
|
||||
}
|
||||
}
|
430
src/themes/shared/_markdown.css
Normal file
430
src/themes/shared/_markdown.css
Normal file
@ -0,0 +1,430 @@
|
||||
/* Markdown */
|
||||
/* ========================================================================== */
|
||||
.markdown-section {
|
||||
position: relative;
|
||||
width: var(--content-max-width);
|
||||
max-width: calc(100% - (var(--content-margin-inline) * 2));
|
||||
margin: var(--content-margin-inline) auto 0 auto;
|
||||
padding-bottom: 2rem;
|
||||
|
||||
body:has(.app-nav) & {
|
||||
margin-top: calc(var(--navbar-height) + (var(--content-margin-inline) / 2));
|
||||
}
|
||||
|
||||
> :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
blockquote,
|
||||
details,
|
||||
figure,
|
||||
form,
|
||||
iframe,
|
||||
ol,
|
||||
output,
|
||||
p,
|
||||
pre,
|
||||
table,
|
||||
ul {
|
||||
margin-block: var(--margin-block);
|
||||
}
|
||||
|
||||
a {
|
||||
&.anchor {
|
||||
color: inherit;
|
||||
|
||||
&:not(:hover) {
|
||||
text-decoration-color: transparent;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
translate: 0 0 0; /* Safari Fix: Forced redraw */
|
||||
text-decoration-color: var(--link-underline-color-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
margin-inline: 0;
|
||||
padding: var(--blockquote-padding);
|
||||
border: solid var(--blockquote-border-color);
|
||||
border-width: var(--blockquote-border-width);
|
||||
border-radius: var(--blockquote-border-radius);
|
||||
background: var(--blockquote-bg);
|
||||
color: var(--blockquote-color);
|
||||
|
||||
> :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
> :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin-block: 2em;
|
||||
}
|
||||
|
||||
iframe {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
border: 1px solid var(--color-mono-2);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
kbd {
|
||||
margin-inline: 0.15em;
|
||||
|
||||
&.alt {
|
||||
padding: 0.5em;
|
||||
border: var(--kbd-alt-border);
|
||||
border-radius: var(--kbd-alt-border-radius);
|
||||
box-shadow: var(--kbd-alt-box-shadow);
|
||||
background: var(--kbd-alt-bg);
|
||||
color: var(--kbd-alt-color);
|
||||
font-size: var(--font-size-m);
|
||||
}
|
||||
}
|
||||
|
||||
/* Callouts */
|
||||
/* ---------------------------------- */
|
||||
.callout {
|
||||
position: relative;
|
||||
margin-block: calc(var(--margin-block) * 1.5);
|
||||
padding: var(--callout-padding);
|
||||
border: solid var(--callout-border-color);
|
||||
border-width: var(--callout-border-width);
|
||||
border-radius: var(--callout-border-radius);
|
||||
background: var(--callout-bg);
|
||||
color: var(--callout-color);
|
||||
|
||||
/* Charm */
|
||||
&::before {
|
||||
content: var(--callout-charm-content);
|
||||
position: absolute;
|
||||
inset: var(--callout-charm-inset);
|
||||
height: var(--callout-charm-size);
|
||||
width: var(--callout-charm-size);
|
||||
translate: var(--callout-charm-translate);
|
||||
border-radius: var(--callout-charm-border-radius);
|
||||
background: var(--callout-charm-bg);
|
||||
color: var(--callout-charm-color);
|
||||
font-size: var(--callout-charm-font-size);
|
||||
font-weight: var(--strong-font-weight);
|
||||
line-height: var(--callout-charm-size);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
code,
|
||||
strong {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
code {
|
||||
background: rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
}
|
||||
|
||||
/* Code, Output, Samp */
|
||||
/* ---------------------------------- */
|
||||
code,
|
||||
output,
|
||||
pre {
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
code,
|
||||
pre,
|
||||
samp {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: var(--font-size-mono);
|
||||
}
|
||||
|
||||
output,
|
||||
pre[data-lang] {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: attr(data-lang);
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 0.5rem;
|
||||
color: inherit;
|
||||
font-family: var(--font-family);
|
||||
font-size: var(--font-size-xs);
|
||||
letter-spacing: 0.02em;
|
||||
line-height: 1;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
code,
|
||||
samp {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
code {
|
||||
margin: 0 0.1em;
|
||||
padding: 0.2em 0.35em;
|
||||
background: var(--code-bg);
|
||||
color: var(--code-color);
|
||||
|
||||
.token {
|
||||
position: relative;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
output {
|
||||
display: block;
|
||||
padding: 1.7rem 1.4rem 1.4rem;
|
||||
border: 1px solid var(--color-mono-2);
|
||||
|
||||
> :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
> :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
pre[data-lang] {
|
||||
/* NOTE: !important declaration are intended to override third-party Prism theme values */
|
||||
padding: 0 !important;
|
||||
border-radius: var(--border-radius) !important;
|
||||
font-family: var(--font-family-mono) !important;
|
||||
font-size: var(--font-size-mono) !important;
|
||||
line-height: inherit !important;
|
||||
tab-size: 2 !important;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-wrap: normal;
|
||||
word-break: normal;
|
||||
hyphens: none;
|
||||
|
||||
&:only-child {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
> code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
padding-block: 1.5rem !important;
|
||||
padding-inline: 1.5rem !important;
|
||||
background: inherit;
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
white-space: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
samp {
|
||||
font-weight: var(--strong-font-weight);
|
||||
|
||||
.token {
|
||||
position: relative;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* Headings */
|
||||
/* --------------------------------- */
|
||||
:where(h1, h2, h3, h4, h5, h6) {
|
||||
margin: 2rem 0 0.5em;
|
||||
color: var(--heading-color);
|
||||
font-weight: var(--heading-font-weight);
|
||||
|
||||
/* Prevent long titles from causing horizontal scrolling */
|
||||
&[id] a {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
margin-top: 2.5rem;
|
||||
}
|
||||
|
||||
:is(h1, h2, h3, h4, h5, h6) + * {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: var(--font-size-xxxl);
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
--_spacing: 0.5em;
|
||||
|
||||
margin-bottom: calc(
|
||||
var(--_spacing) + (var(--heading-line-height) - var(--font-size-xxl))
|
||||
);
|
||||
padding-bottom: var(--_spacing);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
font-size: var(--font-size-xxl);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: var(--font-size-xl);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: var(--font-size-l);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: var(--font-size-m);
|
||||
}
|
||||
|
||||
h6 {
|
||||
&,
|
||||
& + :not(h1, h2, h3, h4, h5) {
|
||||
font-size: var(--font-size-s);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lists */
|
||||
/* ---------------------------------- */
|
||||
ol,
|
||||
ul {
|
||||
margin: 0;
|
||||
padding-inline-start: 1.5em;
|
||||
|
||||
& & {
|
||||
margin-top: 0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
ul.task-list {
|
||||
--_checkbox-margin: 0.2em;
|
||||
--_checkbox-offset: 1.6em;
|
||||
|
||||
padding-inline-start: 0.6em;
|
||||
|
||||
input[type='checkbox'] {
|
||||
margin-top: -0.15em;
|
||||
margin-right: var(--_checkbox-margin);
|
||||
margin-left: calc(0px - var(--_checkbox-offset));
|
||||
}
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
margin-top: var(--_checkbox-margin);
|
||||
margin-bottom: var(--_checkbox-margin);
|
||||
margin-left: var(--_checkbox-offset);
|
||||
list-style-type: none;
|
||||
|
||||
/* Vertical Connector */
|
||||
&:has(.task-list) {
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 1em;
|
||||
left: -1em;
|
||||
bottom: 0;
|
||||
border-left: 1px solid var(--color-mono-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul.task-list {
|
||||
padding-inline-start: 1.5em;
|
||||
|
||||
li {
|
||||
margin-left: var(--_checkbox-margin);
|
||||
}
|
||||
|
||||
> li {
|
||||
/* Horizontal Connector */
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 0.9em;
|
||||
left: -2.7em;
|
||||
width: 1.25em;
|
||||
border-top: 1px solid var(--color-mono-2);
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
/* Horizontal Connector + Mask */
|
||||
&:last-child {
|
||||
&::after {
|
||||
bottom: 0;
|
||||
background: var(--color-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
/* ---------------------------------- */
|
||||
th,
|
||||
td {
|
||||
padding: 0.25em 0.75em;
|
||||
border: 1px solid var(--color-mono-2);
|
||||
}
|
||||
|
||||
table {
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
thead {
|
||||
display: none;
|
||||
font-weight: var(--strong-font-weight);
|
||||
text-align: left;
|
||||
|
||||
&:has(th:not(:empty)) {
|
||||
display: table-header-group;
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
font-weight: var(--strong-font-weight);
|
||||
|
||||
&:not([align]) {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
tr {
|
||||
border-top: 1px solid var(--color-mono-2);
|
||||
|
||||
&:nth-child(2n) {
|
||||
background: var(--table-row-alt-bg);
|
||||
}
|
||||
}
|
||||
}
|
72
src/themes/shared/_mq.css
Normal file
72
src/themes/shared/_mq.css
Normal file
@ -0,0 +1,72 @@
|
||||
/* Media */
|
||||
/* ========================================================================== */
|
||||
:root {
|
||||
--_mobile-breakpoint: 640px; /* JS Accessible. Match with MQ below. */
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
:root {
|
||||
--duration-slow: 0s;
|
||||
--duration-medium: 0s;
|
||||
--duration-fast: 0s;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
.app-nav,
|
||||
.github-corner,
|
||||
.sidebar,
|
||||
.sidebar-toggle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
@media screen and (max-width: 640px) {
|
||||
.app-nav-merged {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body:has(.sidebar.show) {
|
||||
.app-nav,
|
||||
.github-corner {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.app-nav {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
main {
|
||||
&::before {
|
||||
width: 100%;
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
transition:
|
||||
width 0s,
|
||||
background var(--duration-medium);
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
width: calc(100% - var(--sidebar-width));
|
||||
|
||||
&:hover {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
main > .content {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
body:has(.app-nav-merged) {
|
||||
.app-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.markdown-section {
|
||||
margin-top: var(--content-margin-inline);
|
||||
}
|
||||
}
|
||||
}
|
122
src/themes/shared/_navbar.css
Normal file
122
src/themes/shared/_navbar.css
Normal file
@ -0,0 +1,122 @@
|
||||
/* Nav Bar */
|
||||
/* ========================================================================== */
|
||||
.app-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
gap: 1em;
|
||||
position: absolute;
|
||||
z-index: var(--z-app-nav);
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: var(--navbar-height);
|
||||
padding-inline: var(--content-margin-inline);
|
||||
transition: left var(--duration-medium) ease;
|
||||
|
||||
&:has(~ .github-corner) {
|
||||
padding-inline-end: calc(var(--navbar-height) + 1em);
|
||||
}
|
||||
|
||||
body:where(:has(.sidebar.show)) & {
|
||||
left: var(--sidebar-width);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--navbar-link-color);
|
||||
text-decoration-color: transparent;
|
||||
|
||||
&:hover {
|
||||
translate: 0; /* HACK: Force Safari to render text-decoration */
|
||||
text-decoration-color: var(--navbar-link-color-active);
|
||||
}
|
||||
|
||||
.active & {
|
||||
color: var(--navbar-link-color-active);
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
> ul {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
flex-wrap: wrap;
|
||||
gap: 0 1em;
|
||||
}
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
|
||||
/* Dropdown */
|
||||
ul {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: -9999vh;
|
||||
right: 50%;
|
||||
translate: 50% 0;
|
||||
overflow-y: auto;
|
||||
max-height: calc(100vh - 61px);
|
||||
padding: 1em;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
background: var(--color-bg);
|
||||
|
||||
li:last-child & {
|
||||
right: calc(0px - var(--content-margin-inline) / 2);
|
||||
translate: 0;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
display: block;
|
||||
margin-block: var(--navbar-drop-link-spacing);
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25em;
|
||||
margin: 0;
|
||||
|
||||
&:hover {
|
||||
color: var(--navbar-link-color-active);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:focus-within,
|
||||
&:hover {
|
||||
ul {
|
||||
top: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
> :where(a, p),
|
||||
> ul > li > :where(a, p) {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.app-nav-merged {
|
||||
display: none;
|
||||
}
|
285
src/themes/shared/_sidebar.css
Normal file
285
src/themes/shared/_sidebar.css
Normal file
@ -0,0 +1,285 @@
|
||||
/* Sidebar */
|
||||
/* ========================================================================== */
|
||||
:root {
|
||||
--_sidebar-inset: 20px;
|
||||
--_sidebar-list-inset: 0.85em;
|
||||
--_sidebar-scrollbar-width: 10px; /* macOS overlay scrollbar default */
|
||||
|
||||
@supports (scrollbar-width: auto) {
|
||||
--_sidebar-scrollbar-width: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.app-nav-merged,
|
||||
.sidebar-nav {
|
||||
> * {
|
||||
margin-inline: var(--_sidebar-inset);
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> hr {
|
||||
margin-inline: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
> ul {
|
||||
> * {
|
||||
margin-left: var(--_sidebar-inset);
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: var(--_sidebar-list-inset);
|
||||
}
|
||||
|
||||
> li {
|
||||
&.group {
|
||||
padding-top: var(--sidebar-group-spacing);
|
||||
border-top: var(--sidebar-group-border);
|
||||
|
||||
&:has(+ :not(.group)),
|
||||
&:last-child {
|
||||
border-bottom: var(--sidebar-group-border);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
margin-block: var(--sidebar-link-spacing);
|
||||
|
||||
> p {
|
||||
margin: 0;
|
||||
|
||||
/* Text-only <p> tags */
|
||||
&.group-title {
|
||||
margin-right: var(--_sidebar-inset);
|
||||
margin-bottom: var(--sidebar-group-title-spacing);
|
||||
padding-bottom: var(--sidebar-group-title-spacing);
|
||||
border-bottom: var(--sidebar-group-title-border);
|
||||
color: var(--sidebar-group-title-color);
|
||||
font-size: var(--sidebar-group-title-font-size);
|
||||
font-weight: var(--sidebar-group-title-font-weight);
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding-right: var(--_sidebar-inset);
|
||||
overflow: hidden;
|
||||
|
||||
&:has(img, svg) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
> a {
|
||||
color: var(--sidebar-link-color-active);
|
||||
}
|
||||
}
|
||||
|
||||
&.collapse {
|
||||
> :not(a) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
z-index: var(--z-sidebar);
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
translate: calc(0px - var(--sidebar-width));
|
||||
width: var(--sidebar-width);
|
||||
overscroll-behavior: contain;
|
||||
border-right: 1px solid var(--sidebar-border-color);
|
||||
background: var(--sidebar-bg);
|
||||
color: var(--sidebar-color);
|
||||
font-size: var(--sidebar-font-size);
|
||||
transition:
|
||||
translate var(--duration-medium) ease,
|
||||
visibility var(--duration-medium);
|
||||
|
||||
/* Non-webkit browsers: style scrollbar for consistency */
|
||||
@supports (scrollbar-width: auto) {
|
||||
&::-webkit-scrollbar {
|
||||
width: var(--_sidebar-scrollbar-width);
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: var(--_sidebar-scrollbar-width);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(136, 136, 136, 0.4);
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: rgba(136, 136, 136, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a[href] {
|
||||
text-decoration-color: transparent;
|
||||
color: var(--sidebar-link-color);
|
||||
|
||||
&:hover {
|
||||
translate: 0; /* HACK: Force Safari to render text-decoration */
|
||||
text-decoration-color: var(--sidebar-link-color-active);
|
||||
}
|
||||
}
|
||||
|
||||
.app-name {
|
||||
margin: var(--sidebar-name-margin);
|
||||
color: var(--sidebar-name-color);
|
||||
font-family: var(--sidebar-name-font-family);
|
||||
font-size: var(--sidebar-name-font-size);
|
||||
font-weight: var(--sidebar-name-font-weight);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a.app-name-link {
|
||||
img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--sidebar-link-color-active);
|
||||
text-decoration-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
body:has(.sidebar.show) & {
|
||||
visibility: visible;
|
||||
translate: 0;
|
||||
}
|
||||
|
||||
body.sticky & {
|
||||
position: fixed;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-nav {
|
||||
li {
|
||||
a.page-link {
|
||||
border-radius: var(--border-radius);
|
||||
background: var(--sidebar-pagelink-bg);
|
||||
|
||||
.active > &,
|
||||
:has(.active) > & {
|
||||
background: var(--sidebar-pagelink-bg-expanded);
|
||||
|
||||
&:only-child {
|
||||
background: var(--sidebar-pagelink-bg-empty);
|
||||
}
|
||||
}
|
||||
|
||||
.collapse > & {
|
||||
background: var(--sidebar-pagelink-bg-collapsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
display: flex;
|
||||
align-items: var(--sidebar-toggle-alignment);
|
||||
justify-content: start;
|
||||
position: absolute;
|
||||
z-index: var(--z-sidebar-toggle);
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: var(--sidebar-toggle-width);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
transition:
|
||||
background var(--duration-medium),
|
||||
translate var(--duration-medium) ease;
|
||||
|
||||
@media screen and (any-hover) {
|
||||
&:hover {
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--sidebar-toggle-bg-hover) 10%,
|
||||
transparent
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
body:where(:has(.sidebar.show)) & {
|
||||
translate: var(--sidebar-width);
|
||||
transition:
|
||||
background 0s,
|
||||
translate var(--duration-medium) ease;
|
||||
}
|
||||
|
||||
body.sticky & {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
/* Increase tap target size on touch-only devices */
|
||||
@media screen and not (any-hover) {
|
||||
width: calc(var(--content-margin-inline) - 10px);
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-toggle-button {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: var(--sidebar-toggle-height);
|
||||
width: var(--sidebar-toggle-width);
|
||||
margin-block: var(--sidebar-toggle-margin-block);
|
||||
border-radius: 0 var(--border-radius) var(--border-radius) 0;
|
||||
background: var(--sidebar-toggle-bg);
|
||||
color: var(--sidebar-toggle-color);
|
||||
transition-duration: var(--duration-medium);
|
||||
transition-property: background, translate;
|
||||
|
||||
span {
|
||||
--_size: 4px;
|
||||
|
||||
display: block;
|
||||
height: var(--_size);
|
||||
width: var(--_size);
|
||||
border-radius: 100vh;
|
||||
background: currentColor;
|
||||
transition: background var(--duration-medium);
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-block: calc(var(--_size) - 1px);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (any-hover) {
|
||||
&:hover,
|
||||
body:where(:has(.sidebar-toggle:hover)) & {
|
||||
background: var(--sidebar-toggle-bg-hover);
|
||||
color: var(--sidebar-toggle-color-hover);
|
||||
}
|
||||
}
|
||||
}
|
84
src/themes/shared/_syntax.css
Normal file
84
src/themes/shared/_syntax.css
Normal file
@ -0,0 +1,84 @@
|
||||
/* Syntax Highlighting */
|
||||
/* See: https://prismjs.com */
|
||||
/* ========================================================================== */
|
||||
pre[data-lang] {
|
||||
background: var(--codeblock-bg);
|
||||
color: var(--codeblock-color);
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.token {
|
||||
&.boolean,
|
||||
&.constant,
|
||||
&.deleted,
|
||||
&.number,
|
||||
&.property,
|
||||
&.symbol,
|
||||
&.tag {
|
||||
color: var(--codeblock-tag);
|
||||
}
|
||||
|
||||
&.attr-name,
|
||||
&.builtin,
|
||||
&.char,
|
||||
&.inserted,
|
||||
&.selector,
|
||||
&.string {
|
||||
color: var(--codeblock-selector);
|
||||
}
|
||||
|
||||
&.entity,
|
||||
&.operator,
|
||||
&.url,
|
||||
.language-css &.string,
|
||||
.style &.string {
|
||||
color: var(--codeblock-operator);
|
||||
}
|
||||
|
||||
&.cdata,
|
||||
&.comment,
|
||||
&.doctype,
|
||||
&.prolog {
|
||||
color: var(--codeblock-comment);
|
||||
}
|
||||
|
||||
&.atrule,
|
||||
&.attr-value,
|
||||
&.keyword {
|
||||
color: var(--codeblock-keyword);
|
||||
}
|
||||
|
||||
&.important,
|
||||
&.regex,
|
||||
&.variable {
|
||||
color: var(--codeblock-variable);
|
||||
}
|
||||
|
||||
&.bold,
|
||||
&.important {
|
||||
font-weight: var(--strong-font-weight);
|
||||
}
|
||||
|
||||
&.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
&.function {
|
||||
color: var(--codeblock-function);
|
||||
}
|
||||
|
||||
&.important {
|
||||
color: var(--codeblock-important);
|
||||
}
|
||||
|
||||
&.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
&.punctuation {
|
||||
color: var(--codeblock-punctuation);
|
||||
}
|
||||
}
|
32
src/themes/shared/_util.css
Normal file
32
src/themes/shared/_util.css
Normal file
@ -0,0 +1,32 @@
|
||||
/* Utility */
|
||||
/* ========================================================================== */
|
||||
[class*='clamp-'] {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:not(.clamp-1) {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
|
||||
.clamp-1 {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.clamp-2 {
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
.clamp-3 {
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
|
||||
.visually-hidden {
|
||||
clip-path: inset(50%);
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
width: 1px;
|
||||
}
|
14
src/themes/shared/_vars-advanced.css
Normal file
14
src/themes/shared/_vars-advanced.css
Normal file
@ -0,0 +1,14 @@
|
||||
/* Variables: Advanced */
|
||||
/* ========================================================================== */
|
||||
/* prettier-ignore */
|
||||
:root {
|
||||
/* z-index */
|
||||
--z-skip-to-content: 2147483647;
|
||||
--z-progress : 2147483637;
|
||||
--z-sidebar : 60;
|
||||
--z-sidebar-toggle : 50;
|
||||
--z-main-overlay : 40;
|
||||
--z-github-corner : 30;
|
||||
--z-app-nav : 20;
|
||||
--z-cover : 10;
|
||||
}
|
202
src/themes/shared/_vars.css
Normal file
202
src/themes/shared/_vars.css
Normal file
@ -0,0 +1,202 @@
|
||||
/* Variables: Basic */
|
||||
/* ========================================================================== */
|
||||
:root {
|
||||
/* Color */
|
||||
--color-bg : #fff;
|
||||
--color-text : #333;
|
||||
--theme-color: #0b85d7;
|
||||
|
||||
/* Color: Monochromatic */
|
||||
--color-mono-min: var(--color-bg);
|
||||
--color-mono-1 : color-mix(in srgb, var(--color-mono-min), var(--color-mono-max) 5%);
|
||||
--color-mono-2 : color-mix(in srgb, var(--color-mono-min), var(--color-mono-max) 10%);
|
||||
--color-mono-3 : color-mix(in srgb, var(--color-mono-min), var(--color-mono-max) 20%);
|
||||
--color-mono-4 : color-mix(in srgb, var(--color-mono-min), var(--color-mono-max) 32%);
|
||||
--color-mono-5 : color-mix(in srgb, var(--color-mono-max), var(--color-mono-min) 50%);
|
||||
--color-mono-6 : color-mix(in srgb, var(--color-mono-max), var(--color-mono-min) 32%);
|
||||
--color-mono-7 : color-mix(in srgb, var(--color-mono-max), var(--color-mono-min) 20%);
|
||||
--color-mono-8 : color-mix(in srgb, var(--color-mono-max), var(--color-mono-min) 10%);
|
||||
--color-mono-9 : color-mix(in srgb, var(--color-mono-max), var(--color-mono-min) 5%);
|
||||
--color-mono-max: var(--color-text);
|
||||
|
||||
/* Color: Theme Shades (darker) & Tints (lighter)*/
|
||||
/* NOTE: Values derived from --theme-color */
|
||||
--theme-color-1: color-mix(in srgb, var(--theme-color), var(--color-mono-min) 90%);
|
||||
--theme-color-2: color-mix(in srgb, var(--theme-color), var(--color-mono-min) 75%);
|
||||
--theme-color-3: color-mix(in srgb, var(--theme-color), var(--color-mono-min) 55%);
|
||||
--theme-color-4: color-mix(in srgb, var(--theme-color), var(--color-mono-min) 30%);
|
||||
--theme-color-5: color-mix(in srgb, var(--theme-color), var(--color-mono-max) 30%);
|
||||
--theme-color-6: color-mix(in srgb, var(--theme-color), var(--color-mono-max) 55%);
|
||||
--theme-color-7: color-mix(in srgb, var(--theme-color), var(--color-mono-max) 75%);
|
||||
--theme-color-8: color-mix(in srgb, var(--theme-color), var(--color-mono-max) 90%);
|
||||
|
||||
/* Typography */
|
||||
--font-family : system-ui, sans-serif;
|
||||
--font-family-emoji: 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
--font-family-mono : ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace;
|
||||
--font-size : 16px; /* px */
|
||||
--font-size-xxxl : calc(var(--font-size-xxl) * var(--modular-scale));
|
||||
--font-size-xxl : calc(var(--font-size-xl) * var(--modular-scale));
|
||||
--font-size-xl : calc(var(--font-size-l) * var(--modular-scale));
|
||||
--font-size-l : calc(1rem * var(--modular-scale));
|
||||
--font-size-m : var(--font-size);
|
||||
--font-size-s : max(13px, calc(var(--font-size-m) / var(--modular-scale)));
|
||||
--font-size-xs : max(11px, calc(var(--font-size-s) / var(--modular-scale)));
|
||||
--font-size-emoji : 1.2em;
|
||||
--font-size-mono : 0.875rem;
|
||||
--font-weight : 350;
|
||||
--font-weight-mono : var(--font-weight);
|
||||
--line-height : 1.6;
|
||||
--modular-scale : 1.250; /* 1.067, 1.125, 1.200, 1.250, 1.333, 1.414, 1.500, 1.618 */
|
||||
|
||||
/* Common */
|
||||
--border-color : var(--color-mono-2);
|
||||
--border-radius : 3px; /* Single value */
|
||||
--duration-slow : 500ms;
|
||||
--duration-medium : 250ms;
|
||||
--duration-fast : 150ms;
|
||||
--margin-block : 1rem; /* Single value */
|
||||
--scroll-padding-top: var(--margin-block);
|
||||
|
||||
/* Content */
|
||||
--content-margin-inline: 45px; /* Single value */
|
||||
--content-max-width : 72ch;
|
||||
|
||||
/* Cover */
|
||||
--cover-bg : unset;
|
||||
--cover-bg-brightness: 1;
|
||||
--cover-bg-overlay : radial-gradient(transparent 60%, rgba(0, 0, 0, 0.1));
|
||||
--cover-color : ;
|
||||
--cover-title-color : var(--strong-color);
|
||||
--cover-title-font : var(--font-size-xxxl) var(--font-family);
|
||||
|
||||
/* Elements */
|
||||
--blockquote-bg : ;
|
||||
--blockquote-border-color : var(--theme-color);
|
||||
--blockquote-border-radius : 0;
|
||||
--blockquote-border-width : 0 0 0 4px;
|
||||
--blockquote-color : var(--color-mono-6);
|
||||
--blockquote-padding : 0 0 0 1.5em;
|
||||
--button-bg : var(--theme-color);
|
||||
--button-border-radius : 100vh;
|
||||
--button-color : #fff;
|
||||
--button-padding : 0.3em 1.25em 0.315em 1.25em;
|
||||
--callout-bg : ;
|
||||
--callout-border-color : ;
|
||||
--callout-border-radius : 0 var(--border-radius) var(--border-radius) 0;
|
||||
--callout-border-width : 0 0 0 4px;
|
||||
--callout-charm-bg : ;
|
||||
--callout-charm-border-radius : 100vh;
|
||||
--callout-charm-color : ;
|
||||
--callout-charm-content : ;
|
||||
--callout-charm-font-size : 1.2em;
|
||||
--callout-charm-inset : 50% auto auto -2px;
|
||||
--callout-charm-size : 1.3em;
|
||||
--callout-charm-translate : -50% -50%;
|
||||
--callout-color : ;
|
||||
--callout-padding : 1em 1em 1em var(--callout-charm-size);
|
||||
--code-bg : var(--color-mono-1);
|
||||
--code-color : ;
|
||||
--codeblock-bg : var(--code-bg);
|
||||
--codeblock-color : var(--code-color);
|
||||
--codeblock-comment : #6e8090;
|
||||
--codeblock-function : #dd4a68;
|
||||
--codeblock-important : #c94922;
|
||||
--codeblock-keyword : #07a;
|
||||
--codeblock-operator : #a67f59;
|
||||
--codeblock-property : #c08b30;
|
||||
--codeblock-punctuation : #999;
|
||||
--codeblock-selector : #690;
|
||||
--codeblock-tag : #905;
|
||||
--codeblock-variable : #e90;
|
||||
--form-element-bg : var(--color-mono-1);
|
||||
--form-element-border-color : var(--color-mono-3);
|
||||
--form-element-border-radius : var(--border-radius);
|
||||
--form-element-color : ;
|
||||
--heading-color : var(--strong-color);
|
||||
--heading-font-weight : 600;
|
||||
--heading-line-height : calc(2ex + 5px); /* Unit required */
|
||||
--kbd-bg : var(--color-mono-1);
|
||||
--kbd-border : 1px solid var(--color-mono-3);
|
||||
--kbd-border-radius : 4px;
|
||||
--kbd-color : var(--color-mono-5);
|
||||
--kbd-alt-bg : var(--color-mono-1);
|
||||
--kbd-alt-border : none;
|
||||
--kbd-alt-border-radius : var(--kbd-border-radius);
|
||||
--kbd-alt-box-shadow : 0 2px 0 1px var(--color-mono-3);
|
||||
--kbd-alt-color : var(--kbd-color);
|
||||
--link-color : ;
|
||||
--link-color-hover : var(--theme-color);
|
||||
--link-underline-color : var(--theme-color);
|
||||
--link-underline-color-hover : var(--link-underline-color);
|
||||
--link-underline-thickness : 2px;
|
||||
--link-underline-thickness-hover: var(--link-underline-thickness);
|
||||
--mark-bg : #fef08a;
|
||||
--mark-color : ;
|
||||
--strong-color : color-mix(in srgb, var(--color-text), black 35%);
|
||||
--strong-font-weight : 600;
|
||||
--table-row-alt-bg : var(--color-mono-1);
|
||||
|
||||
/* Navbar */
|
||||
--navbar-font-size : var(--font-size);
|
||||
--navbar-height : 4em;
|
||||
--navbar-link-color : ;
|
||||
--navbar-link-color-active: var(--theme-color);
|
||||
--navbar-drop-link-spacing: 0.5em;
|
||||
|
||||
/* Sidebar */
|
||||
--sidebar-bg : var(--color-bg);
|
||||
--sidebar-border-color : var(--border-color);
|
||||
--sidebar-color : ;
|
||||
--sidebar-font-size : var(--font-size);
|
||||
--sidebar-group-border : ;
|
||||
--sidebar-group-spacing : ;
|
||||
--sidebar-group-title-border : ;
|
||||
--sidebar-group-title-color : var(--strong-color);
|
||||
--sidebar-group-title-font-size : ;
|
||||
--sidebar-group-title-font-weight : var(--strong-font-weight);
|
||||
--sidebar-group-title-spacing : ;
|
||||
--sidebar-link-color : var(--color-text);
|
||||
--sidebar-link-color-active : var(--theme-color);
|
||||
--sidebar-link-spacing : 0.75em;
|
||||
--sidebar-name-color : var(--strong-color);
|
||||
--sidebar-name-font-family : var(--font-family);
|
||||
--sidebar-name-font-size : var(--font-size-xl);
|
||||
--sidebar-name-font-weight : var(--strong-font-weight);
|
||||
--sidebar-name-margin : 1.5rem 20px;
|
||||
--sidebar-pagelink-bg : ;
|
||||
--sidebar-pagelink-bg-collapsed : ;
|
||||
--sidebar-pagelink-bg-empty : ;
|
||||
--sidebar-pagelink-bg-expanded : ;
|
||||
--sidebar-toggle-alignment : center; /* start center end */
|
||||
--sidebar-toggle-bg : var(--color-mono-2);
|
||||
--sidebar-toggle-bg-hover : var(--button-bg);
|
||||
--sidebar-toggle-color : var(--color-mono-4);
|
||||
--sidebar-toggle-color-hover : var(--button-color);
|
||||
--sidebar-toggle-height : 80px;
|
||||
--sidebar-toggle-margin-block : 20px;
|
||||
--sidebar-toggle-width : 22px;
|
||||
--sidebar-width : 280px;
|
||||
}
|
||||
|
||||
/* Scoped Variables */
|
||||
/* ========================================================================== */
|
||||
/* Callout: Important */
|
||||
.callout.important {
|
||||
--callout-bg : var(--color-mono-1);
|
||||
--callout-border-color : #f66;
|
||||
--callout-charm-bg : var(--callout-border-color);
|
||||
--callout-charm-color : #fff;
|
||||
--callout-charm-content: '!';
|
||||
--callout-color : ;
|
||||
}
|
||||
|
||||
/* Callout: Important */
|
||||
.callout.tip {
|
||||
--callout-bg : var(--theme-color-1);
|
||||
--callout-border-color : var(--theme-color);
|
||||
--callout-charm-bg : var(--callout-border-color);
|
||||
--callout-charm-color : #fff;
|
||||
--callout-charm-content: 'i';
|
||||
--callout-color : ;
|
||||
}
|
@ -1,260 +0,0 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Roboto+Mono|Source+Sans+Pro:300,400,600')
|
||||
|
||||
$color-primary = #42b983
|
||||
$color-bg = #fff
|
||||
$color-text = #34495e
|
||||
$sidebar-width = 300px
|
||||
|
||||
@import 'basic/_layout'
|
||||
@import 'basic/_coverpage'
|
||||
|
||||
body
|
||||
background-color $color-bg
|
||||
|
||||
/* sidebar */
|
||||
.sidebar
|
||||
background-color $color-bg
|
||||
color #364149
|
||||
|
||||
li
|
||||
margin 6px 0 6px 0
|
||||
|
||||
ul li a
|
||||
color #505d6b
|
||||
font-size 14px
|
||||
font-weight normal
|
||||
overflow hidden
|
||||
text-decoration none
|
||||
text-overflow ellipsis
|
||||
white-space nowrap
|
||||
|
||||
&:hover
|
||||
text-decoration underline
|
||||
|
||||
ul li ul
|
||||
padding 0
|
||||
|
||||
ul li.active > a
|
||||
border-right 2px solid
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
font-weight 600
|
||||
|
||||
.app-sub-sidebar
|
||||
li
|
||||
&::before
|
||||
content '-'
|
||||
padding-right 4px
|
||||
float left
|
||||
|
||||
/* markdown content found on pages */
|
||||
.markdown-section h1, .markdown-section h2, .markdown-section h3, .markdown-section h4, .markdown-section strong
|
||||
color #2c3e50
|
||||
font-weight 600
|
||||
|
||||
.markdown-section a
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
font-weight 600
|
||||
|
||||
.markdown-section h1
|
||||
font-size 2rem
|
||||
margin 0 0 1rem
|
||||
|
||||
.markdown-section h2
|
||||
font-size 1.75rem
|
||||
margin 45px 0 0.8rem
|
||||
|
||||
.markdown-section h3
|
||||
font-size 1.5rem
|
||||
margin 40px 0 0.6rem
|
||||
|
||||
.markdown-section h4
|
||||
font-size 1.25rem
|
||||
|
||||
.markdown-section h5
|
||||
font-size 1rem
|
||||
|
||||
.markdown-section h6
|
||||
color #777
|
||||
font-size 1rem
|
||||
|
||||
.markdown-section figure, .markdown-section p
|
||||
margin 1.2em 0
|
||||
|
||||
.markdown-section p, .markdown-section ul, .markdown-section ol
|
||||
line-height 1.6rem
|
||||
word-spacing 0.05rem
|
||||
|
||||
.markdown-section ul, .markdown-section ol
|
||||
padding-left 1.5rem
|
||||
|
||||
.markdown-section blockquote
|
||||
border-left 4px solid $color-primary
|
||||
border-left 4px solid var(--theme-color, $color-primary)
|
||||
color #858585
|
||||
margin 2em 0
|
||||
padding-left 20px
|
||||
|
||||
.markdown-section blockquote p
|
||||
font-weight 600
|
||||
margin-left 0
|
||||
|
||||
.markdown-section iframe
|
||||
margin 1em 0
|
||||
|
||||
.markdown-section em
|
||||
color #7f8c8d
|
||||
|
||||
.markdown-section code,
|
||||
.markdown-section pre,
|
||||
.markdown-section output::after
|
||||
font-family 'Roboto Mono', Monaco, courier, monospace
|
||||
|
||||
.markdown-section code,
|
||||
.markdown-section pre
|
||||
background-color #f8f8f8
|
||||
z-index 0
|
||||
|
||||
.markdown-section pre,
|
||||
.markdown-section output
|
||||
margin 1.2em 0
|
||||
position relative
|
||||
|
||||
.markdown-section pre > code,
|
||||
.markdown-section output
|
||||
border-radius 2px
|
||||
display block
|
||||
|
||||
.markdown-section pre > code,
|
||||
.markdown-section output::after
|
||||
-moz-osx-font-smoothing initial
|
||||
-webkit-font-smoothing initial
|
||||
|
||||
.markdown-section code
|
||||
border-radius 2px
|
||||
color #e96900
|
||||
margin 0 2px
|
||||
padding 3px 5px
|
||||
white-space pre-wrap
|
||||
|
||||
.markdown-section > :not(h1):not(h2):not(h3):not(h4):not(h5):not(h6) code
|
||||
font-size 0.8rem
|
||||
|
||||
.markdown-section pre
|
||||
line-height 1.5rem
|
||||
overflow auto
|
||||
word-wrap normal
|
||||
|
||||
.markdown-section pre > code
|
||||
color #525252
|
||||
font-size 0.8rem
|
||||
padding 2.2em 1.4rem
|
||||
line-height inherit
|
||||
margin 5px
|
||||
max-width inherit
|
||||
overflow inherit
|
||||
white-space inherit
|
||||
|
||||
.markdown-section pre > code:focus
|
||||
// outline 5px auto Highlight;
|
||||
outline 5px auto -webkit-focus-ring-color;
|
||||
|
||||
.markdown-section output
|
||||
padding: 1.7rem 1.4rem
|
||||
border 1px dotted #ccc
|
||||
|
||||
.markdown-section output > :first-child
|
||||
margin-top: 0;
|
||||
|
||||
.markdown-section output > :last-child
|
||||
margin-bottom: 0;
|
||||
|
||||
.markdown-section code::after, .markdown-section code::before,
|
||||
.markdown-section output::after, .markdown-section output::before
|
||||
letter-spacing 0.05rem
|
||||
|
||||
.markdown-section pre::after,
|
||||
.markdown-section output::after
|
||||
content attr(data-lang)
|
||||
color #ccc
|
||||
font-size 0.6rem
|
||||
font-weight 600
|
||||
height 15px
|
||||
line-height 15px
|
||||
padding 5px 10px 0
|
||||
position absolute
|
||||
right 0
|
||||
text-align right
|
||||
top 0
|
||||
|
||||
/* code highlight */
|
||||
.token.comment, .token.prolog, .token.doctype, .token.cdata
|
||||
color #8e908c
|
||||
|
||||
.token.namespace
|
||||
opacity 0.7
|
||||
|
||||
.token.boolean, .token.number
|
||||
color #c76b29
|
||||
|
||||
.token.punctuation
|
||||
color #525252
|
||||
|
||||
.token.property
|
||||
color #c08b30
|
||||
|
||||
.token.tag
|
||||
color #2973b7
|
||||
|
||||
.token.string
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
|
||||
.token.selector
|
||||
color #6679cc
|
||||
|
||||
.token.attr-name
|
||||
color #2973b7
|
||||
|
||||
.token.entity, .token.url, .language-css .token.string, .style .token.string
|
||||
color #22a2c9
|
||||
|
||||
.token.attr-value, .token.control, .token.directive, .token.unit
|
||||
color $color-primary
|
||||
color var(--theme-color, $color-primary)
|
||||
|
||||
.token.keyword, .token.function
|
||||
color #e96900
|
||||
|
||||
.token.statement, .token.regex, .token.atrule
|
||||
color #22a2c9
|
||||
|
||||
.token.placeholder, .token.variable
|
||||
color #3d8fd1
|
||||
|
||||
.token.deleted
|
||||
text-decoration line-through
|
||||
|
||||
.token.inserted
|
||||
border-bottom 1px dotted #202746
|
||||
text-decoration none
|
||||
|
||||
.token.italic
|
||||
font-style italic
|
||||
|
||||
.token.important, .token.bold
|
||||
font-weight bold
|
||||
|
||||
.token.important
|
||||
color #c94922
|
||||
|
||||
.token.entity
|
||||
cursor help
|
||||
|
||||
code .token
|
||||
-moz-osx-font-smoothing initial
|
||||
-webkit-font-smoothing initial
|
||||
min-height 1.5rem
|
||||
position: relative
|
||||
left: auto
|
@ -159,11 +159,11 @@ test.describe('keyBindings', () => {
|
||||
|
||||
await docsifyInit(docsifyInitConfig);
|
||||
|
||||
const bodyElm = page.locator('body');
|
||||
const sidebarElm = page.locator('.sidebar');
|
||||
|
||||
await expect(bodyElm).not.toHaveClass(/close/);
|
||||
await expect(sidebarElm).toHaveClass(/show/);
|
||||
await page.keyboard.press('\\');
|
||||
await expect(bodyElm).toHaveClass(/close/);
|
||||
await expect(sidebarElm).not.toHaveClass(/show/);
|
||||
});
|
||||
|
||||
test('handles custom binding', async ({ page }) => {
|
||||
|
@ -14,8 +14,8 @@ test.describe('Creating a Docsify site (e2e tests in Playwright)', () => {
|
||||
};
|
||||
});
|
||||
|
||||
// Inject docsify theme (vue.css)
|
||||
await page.addStyleTag({ url: '/dist/themes/vue.css' });
|
||||
// Inject docsify theme
|
||||
await page.addStyleTag({ url: '/dist/themes/core.css' });
|
||||
|
||||
// Inject docsify.js
|
||||
await page.addScriptTag({ url: '/dist/docsify.js' });
|
||||
@ -96,7 +96,7 @@ test.describe('Creating a Docsify site (e2e tests in Playwright)', () => {
|
||||
background: red !important;
|
||||
}
|
||||
`,
|
||||
styleURLs: ['/dist/themes/vue.css'],
|
||||
styleURLs: ['/dist/themes/core.css'],
|
||||
};
|
||||
|
||||
await docsifyInit({
|
||||
@ -214,7 +214,7 @@ test.describe('Creating a Docsify site (e2e tests in Playwright)', () => {
|
||||
// upon billions upon billions upon billions upon billions.
|
||||
// `,
|
||||
// },
|
||||
// styleURLs: [`/dist/themes/vue.css`],
|
||||
// styleURLs: [`/dist/themes/core.css`],
|
||||
// // _logHTML: true,
|
||||
// });
|
||||
|
||||
|
@ -38,7 +38,7 @@ test.describe('Gtag Plugin Tests', () => {
|
||||
gtag: gtagList[0],
|
||||
},
|
||||
scriptURLs: ['/dist/plugins/gtag.js'],
|
||||
styleURLs: ['/dist/themes/vue.css'],
|
||||
styleURLs: ['/dist/themes/core.css'],
|
||||
};
|
||||
|
||||
await docsifyInit({
|
||||
@ -64,7 +64,7 @@ test.describe('Gtag Plugin Tests', () => {
|
||||
gtag: gtagList,
|
||||
},
|
||||
scriptURLs: ['/dist/plugins/gtag.js'],
|
||||
styleURLs: ['/dist/themes/vue.css'],
|
||||
styleURLs: ['/dist/themes/core.css'],
|
||||
};
|
||||
|
||||
await docsifyInit({
|
||||
|
@ -25,7 +25,7 @@ test.describe('Search Plugin Tests', () => {
|
||||
};
|
||||
|
||||
const searchFieldElm = page.locator('input[type=search]');
|
||||
const resultsHeadingElm = page.locator('.results-panel h2');
|
||||
const resultsHeadingElm = page.locator('.results-panel .title');
|
||||
|
||||
await docsifyInit(docsifyInitConfig);
|
||||
|
||||
@ -68,7 +68,7 @@ test.describe('Search Plugin Tests', () => {
|
||||
};
|
||||
|
||||
const searchFieldElm = page.locator('input[type=search]');
|
||||
const resultsHeadingElm = page.locator('.results-panel h2');
|
||||
const resultsHeadingElm = page.locator('.results-panel .title');
|
||||
|
||||
await docsifyInit(docsifyInitConfig);
|
||||
|
||||
@ -103,7 +103,7 @@ test.describe('Search Plugin Tests', () => {
|
||||
};
|
||||
|
||||
const searchFieldElm = page.locator('input[type=search]');
|
||||
const resultsHeadingElm = page.locator('.results-panel h2');
|
||||
const resultsHeadingElm = page.locator('.results-panel .title');
|
||||
const resultElm = page.locator('.matching-post');
|
||||
|
||||
await docsifyInit(docsifyInitConfig);
|
||||
@ -129,7 +129,7 @@ test.describe('Search Plugin Tests', () => {
|
||||
};
|
||||
|
||||
const searchFieldElm = page.locator('input[type=search]');
|
||||
const resultsHeadingElm = page.locator('.results-panel h2');
|
||||
const resultsHeadingElm = page.locator('.results-panel .title');
|
||||
|
||||
await docsifyInit(docsifyInitConfig);
|
||||
|
||||
@ -163,7 +163,7 @@ test.describe('Search Plugin Tests', () => {
|
||||
};
|
||||
|
||||
const searchFieldElm = page.locator('input[type=search]');
|
||||
const resultsHeadingElm = page.locator('.results-panel h2');
|
||||
const resultsHeadingElm = page.locator('.results-panel .title');
|
||||
|
||||
await docsifyInit(docsifyInitConfig);
|
||||
|
||||
@ -190,7 +190,7 @@ test.describe('Search Plugin Tests', () => {
|
||||
};
|
||||
|
||||
const searchFieldElm = page.locator('input[type=search]');
|
||||
const resultsHeadingElm = page.locator('.results-panel h2');
|
||||
const resultsHeadingElm = page.locator('.results-panel .title');
|
||||
|
||||
await docsifyInit(docsifyInitConfig);
|
||||
|
||||
|
@ -25,7 +25,7 @@ const docsifyURL = '/dist/docsify.js'; // Playwright
|
||||
* @param {String} [options.script] JS to inject via <script> tag
|
||||
* @param {String|String[]} [options.scriptURLs] External JS to inject via <script src="..."> tag(s)
|
||||
* @param {String} [options.style] CSS to inject via <style> tag
|
||||
* @param {String|String[]} [options.styleURLs=['/dist/themes/vue.css']] External CSS to inject via <link rel="stylesheet"> tag(s)
|
||||
* @param {String|String[]} [options.styleURLs=['/dist/themes/core.css']] External CSS to inject via <link rel="stylesheet"> tag(s)
|
||||
* @param {String} [options.testURL] URL to set as window.location.href
|
||||
* @param {String} [options.waitForSelector='#main'] Element to wait for before returning promise
|
||||
* @param {Boolean|Object|String} [options._logHTML] Logs HTML to console after initialization. Accepts CSS selector.
|
||||
|
@ -1,26 +1,30 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Docs Site coverpage renders and is unchanged 1`] = `
|
||||
"<section class="cover show" role="complementary" aria-label="cover" style="background:
|
||||
linear-gradient(
|
||||
to left bottom,
|
||||
hsl(127, 100%, 85%) 0%,
|
||||
hsl(127, 100%, 85%) 100%
|
||||
)
|
||||
">
|
||||
"<section class="cover show" role="complementary" aria-label="cover">
|
||||
<div class="mask"></div>
|
||||
<div class="cover-main"><p><img src="http://127.0.0.1:4000/_media/icon.svg" data-origin="_media/icon.svg" alt="logo"></p><h1 id="docsify-4130" tabindex="-1"><a href="#/?id=docsify-4130" data-id="docsify-4130" class="anchor"><span>docsify <small>4.13.0</small></span></a></h1><blockquote>
|
||||
<p>A magical documentation site generator.</p></blockquote>
|
||||
<ul><li>Simple and lightweight</li><li>No statically built html files</li><li>Multiple themes</li></ul><p><a href="https://github.com/docsifyjs/docsify/" target="_blank" rel="noopener">GitHub</a>
|
||||
<a href="#/?id=docsify">Getting Started</a></p></div>
|
||||
<div class="cover-main"><!-- markdownlint-disable first-line-h1 -->
|
||||
|
||||
<p><img src="http://127.0.0.1:4000/_media/icon.svg" data-origin="_media/icon.svg" alt="logo"></p><h1 id="docsify-4130" tabindex="-1"><a href="#/?id=docsify-4130" data-id="docsify-4130" class="anchor"><span>docsify <small>4.13.0</small></span></a></h1><blockquote>
|
||||
<p>A magical documentation site generator</p></blockquote>
|
||||
<ul><li>Simple and lightweight</li><li>No statically built HTML files</li><li>Multiple themes</li></ul><p><a href="#/?id=docsify" class="button primary">Get Started</a>
|
||||
<a href="https://github.com/docsifyjs/docsify/" target="_blank" rel="noopener" class="button secondary">GitHub</a></p><!-- ![color](#f0f0f0) -->
|
||||
<!-- ![](/_media/icon.svg) -->
|
||||
</div>
|
||||
</section>"
|
||||
`;
|
||||
|
||||
exports[`Docs Site navbar renders and is unchanged 1`] = `"<nav aria-label="secondary" class="app-nav no-badge"><ul><li>Translations<ul><li><a href="#/"><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f1ec-1f1e7.png?v8.png" alt="uk" class="emoji" loading="lazy"> English</a></li><li><a href="#/zh-cn/"><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f1e8-1f1f3.png?v8.png" alt="cn" class="emoji" loading="lazy"> 简体中文</a></li><li><a href="#/de-de/"><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f1e9-1f1ea.png?v8.png" alt="de" class="emoji" loading="lazy"> Deutsch</a></li><li><a href="#/es/"><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f1ea-1f1f8.png?v8.png" alt="es" class="emoji" loading="lazy"> Español</a></li><li><a href="#/ru-ru/"><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f1f7-1f1fa.png?v8.png" alt="ru" class="emoji" loading="lazy"> Русский</a></li></ul></li></ul></nav>"`;
|
||||
exports[`Docs Site navbar renders and is unchanged 1`] = `
|
||||
"<nav class="app-nav" aria-label="secondary"><!-- markdownlint-disable first-line-h1 -->
|
||||
|
||||
<ul><li><p>Translations</p><ul><li><a href="#/"><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f1ec-1f1e7.png?v8.png" alt="uk" class="emoji" loading="lazy"> English</a></li><li><a href="#/zh-cn/"><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f1e8-1f1f3.png?v8.png" alt="cn" class="emoji" loading="lazy"> 简体中文</a></li><li><a href="#/de-de/"><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f1e9-1f1ea.png?v8.png" alt="de" class="emoji" loading="lazy"> Deutsch</a></li><li><a href="#/es/"><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f1ea-1f1f8.png?v8.png" alt="es" class="emoji" loading="lazy"> Español</a></li><li><a href="#/ru-ru/"><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f1f7-1f1fa.png?v8.png" alt="ru" class="emoji" loading="lazy"> Русский</a></li></ul></li></ul></nav>"
|
||||
`;
|
||||
|
||||
exports[`Docs Site sidebar renders and is unchanged 1`] = `
|
||||
"<aside id="__sidebar" class="sidebar" role="none">
|
||||
"<aside id="__sidebar" class="sidebar show" tabindex="-1" role="none">
|
||||
|
||||
<div class="sidebar-nav" role="navigation" aria-label="primary"><ul><li><p>Getting started</p><ul><li><a href="#/quickstart">Quick start</a></li><li><a href="#/more-pages">Writing more pages</a></li><li><a href="#/custom-navbar">Custom navbar</a></li><li><a href="#/cover">Cover page</a></li></ul></li><li><p>Customization</p><ul><li><a href="#/configuration">Configuration</a></li><li><a href="#/themes">Themes</a></li><li><a href="#/plugins">List of Plugins</a></li><li><a href="#/write-a-plugin">Write a Plugin</a></li><li><a href="#/markdown">Markdown configuration</a></li><li><a href="#/language-highlight">Language highlighting</a></li><li><a href="#/emoji">Emoji</a></li></ul></li><li><p>Guide</p><ul><li><a href="#/deploy">Deploy</a></li><li><a href="#/helpers">Helpers</a></li><li><a href="#/vue">Vue compatibility</a></li><li><a href="#/cdn">CDN</a></li><li><a href="#/pwa">Offline Mode (PWA)</a></li><li><a href="#/embed-files">Embed Files</a></li></ul></li><li><p><a href="#/awesome">Awesome docsify</a></p></li><li><p><a href="#/changelog">Changelog</a></p></li></ul></div>
|
||||
<div class="sidebar-nav" role="navigation" aria-label="primary"><!-- markdownlint-disable first-line-h1 -->
|
||||
|
||||
<ul><li><p>Getting started</p><ul><li><a href="#/quickstart" class="page-link">Quick start</a></li><li><a href="#/adding-pages" class="page-link">Adding pages</a></li><li><a href="#/cover" class="page-link">Cover page</a></li><li><a href="#/custom-navbar" class="page-link">Custom navbar</a></li></ul></li><li><p>Customization</p><ul><li><a href="#/configuration" class="page-link">Configuration</a></li><li><a href="#/themes" class="page-link">Themes</a></li><li><a href="#/plugins" class="page-link">List of Plugins</a></li><li><a href="#/write-a-plugin" class="page-link">Write a Plugin</a></li><li><a href="#/markdown" class="page-link">Markdown configuration</a></li><li><a href="#/language-highlight" class="page-link">Language highlighting</a></li><li><a href="#/emoji" class="page-link">Emoji</a></li></ul></li><li><p>Guide</p><ul><li><a href="#/deploy" class="page-link">Deploy</a></li><li><a href="#/helpers" class="page-link">Helpers</a></li><li><a href="#/vue" class="page-link">Vue compatibility</a></li><li><a href="#/cdn" class="page-link">CDN</a></li><li><a href="#/pwa" class="page-link">Offline Mode (PWA)</a></li><li><a href="#/embed-files" class="page-link">Embed Files</a></li><li><a href="#/ui-kit" class="page-link">UI Kit</a></li></ul></li><li><p><a href="#/awesome" class="page-link">Awesome docsify</a></p></li><li><p><a href="#/changelog" class="page-link">Changelog</a></p></li></ul></div>
|
||||
</aside>"
|
||||
`;
|
||||
|
@ -66,7 +66,7 @@ describe('Creating a Docsify site (integration tests in Jest)', function () {
|
||||
background: red !important;
|
||||
}
|
||||
`,
|
||||
styleURLs: ['/dist/themes/vue.css'],
|
||||
styleURLs: ['/dist/themes/core.css'],
|
||||
};
|
||||
|
||||
await docsifyInit({
|
||||
|
@ -16,14 +16,16 @@ describe('render', function () {
|
||||
const output = window.marked('!> Important content');
|
||||
|
||||
expect(output).toMatchInlineSnapshot(
|
||||
'"<p class="tip">Important content</p>"',
|
||||
`"<p class="callout important">Important content</p>"`,
|
||||
);
|
||||
});
|
||||
|
||||
test('general tip', () => {
|
||||
const output = window.marked('?> General tip');
|
||||
|
||||
expect(output).toMatchInlineSnapshot('"<p class="warn">General tip</p>"');
|
||||
expect(output).toMatchInlineSnapshot(
|
||||
`"<p class="callout tip">General tip</p>"`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -297,7 +299,7 @@ describe('render', function () {
|
||||
|
||||
expect(elm.textContent).toBe(expectText);
|
||||
expect(elm.outerHTML).toMatchInlineSnapshot(
|
||||
'"<button id="skip-to-content">Skip to main content</button>"',
|
||||
`"<button type="button" id="skip-to-content" class="primary">Skip to main content</button>"`,
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {
|
||||
removeAtag,
|
||||
getAndRemoveConfig,
|
||||
getAndRemoveDocisfyIgnoreConfig,
|
||||
getAndRemoveDocsifyIgnoreConfig,
|
||||
} from '../../src/core/render/utils.js';
|
||||
import { tree } from '../../src/core/render/tpl.js';
|
||||
import { slugify } from '../../src/core/render/slugify.js';
|
||||
@ -19,12 +19,12 @@ describe('core/render/utils', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// getAndRemoveDocisfyIgnorConfig()
|
||||
// getAndRemoveDocsifyIgnoreConfig()
|
||||
// ---------------------------------------------------------------------------
|
||||
describe('getAndRemoveDocisfyIgnorConfig()', () => {
|
||||
test('getAndRemoveDocisfyIgnorConfig from <!-- {docsify-ignore} -->', () => {
|
||||
describe('getAndRemoveDocsifyIgnoreConfig()', () => {
|
||||
test('getAndRemoveDocsifyIgnoreConfig from <!-- {docsify-ignore} -->', () => {
|
||||
const { content, ignoreAllSubs, ignoreSubHeading } =
|
||||
getAndRemoveDocisfyIgnoreConfig(
|
||||
getAndRemoveDocsifyIgnoreConfig(
|
||||
'My Ignore Title<!-- {docsify-ignore} -->',
|
||||
);
|
||||
expect(content).toBe('My Ignore Title');
|
||||
@ -32,9 +32,9 @@ describe('core/render/utils', () => {
|
||||
expect(ignoreAllSubs === undefined).toBeTruthy();
|
||||
});
|
||||
|
||||
test('getAndRemoveDocisfyIgnorConfig from <!-- {docsify-ignore-all} -->', () => {
|
||||
test('getAndRemoveDocsifyIgnoreConfig from <!-- {docsify-ignore-all} -->', () => {
|
||||
const { content, ignoreAllSubs, ignoreSubHeading } =
|
||||
getAndRemoveDocisfyIgnoreConfig(
|
||||
getAndRemoveDocsifyIgnoreConfig(
|
||||
'My Ignore Title<!-- {docsify-ignore-all} -->',
|
||||
);
|
||||
expect(content).toBe('My Ignore Title');
|
||||
@ -42,17 +42,17 @@ describe('core/render/utils', () => {
|
||||
expect(ignoreSubHeading === undefined).toBeTruthy();
|
||||
});
|
||||
|
||||
test('getAndRemoveDocisfyIgnorConfig from {docsify-ignore}', () => {
|
||||
test('getAndRemoveDocsifyIgnoreConfig from {docsify-ignore}', () => {
|
||||
const { content, ignoreAllSubs, ignoreSubHeading } =
|
||||
getAndRemoveDocisfyIgnoreConfig('My Ignore Title{docsify-ignore}');
|
||||
getAndRemoveDocsifyIgnoreConfig('My Ignore Title{docsify-ignore}');
|
||||
expect(content).toBe('My Ignore Title');
|
||||
expect(ignoreSubHeading).toBeTruthy();
|
||||
expect(ignoreAllSubs === undefined).toBeTruthy();
|
||||
});
|
||||
|
||||
test('getAndRemoveDocisfyIgnorConfig from {docsify-ignore-all}', () => {
|
||||
test('getAndRemoveDocsifyIgnoreConfig from {docsify-ignore-all}', () => {
|
||||
const { content, ignoreAllSubs, ignoreSubHeading } =
|
||||
getAndRemoveDocisfyIgnoreConfig('My Ignore Title{docsify-ignore-all}');
|
||||
getAndRemoveDocsifyIgnoreConfig('My Ignore Title{docsify-ignore-all}');
|
||||
expect(content).toBe('My Ignore Title');
|
||||
expect(ignoreAllSubs).toBeTruthy();
|
||||
expect(ignoreSubHeading === undefined).toBeTruthy();
|
||||
|
Loading…
Reference in New Issue
Block a user