@chassis-ui/docs 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +149 -20
- package/bin/chassis-docs.js +6 -0
- package/package.json +16 -2
- package/src/cli/assets.js +111 -0
- package/src/cli/files.js +97 -0
- package/src/cli/html-validate.js +111 -0
- package/src/cli/main.js +131 -0
- package/src/cli/shared.js +69 -0
- package/src/cli/vnu.js +94 -0
- package/src/components/shortcodes/Code.astro +2 -2
- package/src/components/shortcodes/Example.astro +2 -1
- package/src/components/shortcodes/Icon.astro +3 -1
- package/src/components/shortcodes/ResizableExample.astro +2 -1
- package/src/integration.ts +6 -0
- package/src/js/example-mode.js +3 -2
- package/src/js/search.js +2 -1
- package/src/layouts/BaseLayout.astro +5 -2
- package/src/layouts/footer/Consent.astro +135 -0
- package/src/layouts/footer/Footer.astro +14 -4
- package/src/layouts/head/Favicons.astro +7 -6
- package/src/layouts/head/Head.astro +8 -2
- package/src/layouts/head/Social.astro +5 -2
- package/src/layouts/head/Stylesheet.astro +3 -2
- package/src/layouts/header/Navigation.astro +3 -2
- package/src/libs/docs-path.ts +7 -0
- package/src/libs/highlight.ts +2 -2
- package/src/libs/icon.ts +4 -4
- package/src/libs/markdown.ts +13 -1
- package/src/libs/schema.ts +11 -1
- package/src/scss/_consent.scss +14 -0
- package/src/scss/_footer.scss +11 -1
- package/src/scss/main.scss +1 -1
- package/src/site.ts +9 -1
- package/virtual.d.ts +5 -0
- package/src/layouts/head/Analytics.astro +0 -31
- package/src/scss/fonts.scss +0 -1
|
@@ -10,7 +10,6 @@ import type { Layout } from '../../libs/layout'
|
|
|
10
10
|
import Stylesheet from './Stylesheet.astro'
|
|
11
11
|
import Favicons from './Favicons.astro'
|
|
12
12
|
import Social from './Social.astro'
|
|
13
|
-
import Analytics from './Analytics.astro'
|
|
14
13
|
import 'virtual:chassis-docs/styles'
|
|
15
14
|
|
|
16
15
|
interface Props {
|
|
@@ -41,6 +40,14 @@ const pageTitle = isHome
|
|
|
41
40
|
|
|
42
41
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
43
42
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
43
|
+
<!--
|
|
44
|
+
A link, not an `@import` in the styles, so that the browser finds it with the page and
|
|
45
|
+
not after the stylesheet that imports it
|
|
46
|
+
-->
|
|
47
|
+
<link
|
|
48
|
+
rel="stylesheet"
|
|
49
|
+
href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&family=Inter:wght@100..900&family=Archivo+Narrow:ital,wght@0,400..700;1,400..700&display=swap"
|
|
50
|
+
/>
|
|
44
51
|
|
|
45
52
|
<meta name="description" content={description} />
|
|
46
53
|
|
|
@@ -59,4 +66,3 @@ const pageTitle = isHome
|
|
|
59
66
|
<slot name="styles" />
|
|
60
67
|
<Favicons />
|
|
61
68
|
<Social description={description} layout={layout} thumbnail={thumbnail} title={title} />
|
|
62
|
-
<Analytics />
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { getRemoteImageSize, getStaticImageSize } from '../../libs/image'
|
|
9
9
|
import type { Layout } from '../../libs/layout'
|
|
10
|
-
import { getConfig, getPublicFsPath } from '../../site'
|
|
10
|
+
import { getConfig, getPublicFsPath, getStaticPath } from '../../site'
|
|
11
11
|
|
|
12
12
|
interface Props {
|
|
13
13
|
/** Page description */
|
|
@@ -22,7 +22,10 @@ interface Props {
|
|
|
22
22
|
|
|
23
23
|
const { description, layout, thumbnail, title } = Astro.props
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
// A file in `static/` of the `public` directory is read from there, and linked under
|
|
26
|
+
// `staticPath` of the config.
|
|
27
|
+
const staticFile = thumbnail.match(/^\/?static\/(.+)$/)?.[1]
|
|
28
|
+
const socialImageUrl = new URL(staticFile ? getStaticPath(staticFile) : thumbnail, Astro.site)
|
|
26
29
|
const isRemoteThumbnail = /^https?:\/\//i.test(thumbnail)
|
|
27
30
|
const socialImageSize = isRemoteThumbnail
|
|
28
31
|
? await getRemoteImageSize(thumbnail)
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { HTMLAttributes } from 'astro/types'
|
|
9
|
+
import { getStaticPath } from '../../site'
|
|
9
10
|
|
|
10
11
|
function getChassisCssProps() {
|
|
11
|
-
let cxCssLinkHref = '
|
|
12
|
+
let cxCssLinkHref = getStaticPath('css/chassis')
|
|
12
13
|
|
|
13
14
|
if (import.meta.env.PROD) {
|
|
14
15
|
cxCssLinkHref = `${cxCssLinkHref}.min`
|
|
@@ -26,4 +27,4 @@ function getChassisCssProps() {
|
|
|
26
27
|
---
|
|
27
28
|
|
|
28
29
|
<link {...getChassisCssProps()} />
|
|
29
|
-
<link rel="stylesheet" href={
|
|
30
|
+
<link rel="stylesheet" href={getStaticPath('icons/chassis-icons.css')} />
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { Layout } from '../../libs/layout'
|
|
9
|
-
import { getConfig } from '../../site'
|
|
9
|
+
import { getConfig, getStaticPath } from '../../site'
|
|
10
10
|
import NavLink from '../../components/NavLink.astro'
|
|
11
11
|
import ThemeToggler from '../../components/ThemeToggler.astro'
|
|
12
12
|
import SearchTrigger from './SearchTrigger.astro'
|
|
@@ -55,7 +55,7 @@ const isActive = (path: string) => {
|
|
|
55
55
|
{layout !== 'docs' && <div class="lg:d-none" style="width: 4.25rem;" />}
|
|
56
56
|
|
|
57
57
|
<a class="navbar-brand m-0 py-sm lg:me-md" href="/" aria-label="Chassis">
|
|
58
|
-
<img src=
|
|
58
|
+
<img src={getStaticPath('images/site-logo.svg')} alt="Chassis UI" width="123" height="32" />
|
|
59
59
|
</a>
|
|
60
60
|
|
|
61
61
|
<div class="d-flex">
|
|
@@ -94,6 +94,7 @@ const isActive = (path: string) => {
|
|
|
94
94
|
<NavLink active={isActive('/tokens')} href="/tokens">Tokens</NavLink>
|
|
95
95
|
<NavLink active={isActive('/figma')} href="/figma">Figma</NavLink>
|
|
96
96
|
<NavLink active={isActive('/css')} href="/css">CSS</NavLink>
|
|
97
|
+
<NavLink active={isActive('/react')} href="/react">React</NavLink>
|
|
97
98
|
<NavLink active={isActive('/assets')} href="/assets">Assets</NavLink>
|
|
98
99
|
<NavLink active={isActive('/icons')} href="/icons">Icons</NavLink>
|
|
99
100
|
<li class="nav-item col-12 lg:col-auto lg:d-flex">
|
package/src/libs/docs-path.ts
CHANGED
|
@@ -10,3 +10,10 @@ export function joinDocsPath(docsPath: string, inputPath: string): string {
|
|
|
10
10
|
|
|
11
11
|
return page ? `${base}/${page}` : base
|
|
12
12
|
}
|
|
13
|
+
|
|
14
|
+
/** Joins the static path of the config and a file: `('/css/static', 'css/chassis.css')`. */
|
|
15
|
+
export function joinStaticPath(staticPath: string, file = ''): string {
|
|
16
|
+
const name = file.replace(/^\/+/, '')
|
|
17
|
+
|
|
18
|
+
return name ? `${staticPath}/${name}` : staticPath
|
|
19
|
+
}
|
package/src/libs/highlight.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { codeToHtml, type ShikiTransformer } from 'shiki'
|
|
2
|
-
import { DOCS_SHIKI_THEMES } from './markdown'
|
|
2
|
+
import { DOCS_SHIKI_THEMES, focusableTransformer } from './markdown'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Shiki transformer that renames the `shiki` CSS class on `<pre>` elements to
|
|
@@ -44,7 +44,7 @@ export async function highlightCode(
|
|
|
44
44
|
lang,
|
|
45
45
|
themes: DOCS_SHIKI_THEMES,
|
|
46
46
|
defaultColor: false,
|
|
47
|
-
transformers: [...extraTransformers, classTransformer]
|
|
47
|
+
transformers: [...extraTransformers, classTransformer, focusableTransformer]
|
|
48
48
|
})
|
|
49
49
|
|
|
50
50
|
return { html: replaceShikiClasses(highlighted) }
|
package/src/libs/icon.ts
CHANGED
|
@@ -20,7 +20,7 @@ interface IconOptions {
|
|
|
20
20
|
* actually invoked — they need to be expanded to their rendered markup ahead of time.
|
|
21
21
|
* @see src/components/shortcodes/Icon.astro
|
|
22
22
|
*/
|
|
23
|
-
export function replaceIconsInHtml(html: string) {
|
|
23
|
+
export function replaceIconsInHtml(html: string, staticPath = '/static') {
|
|
24
24
|
return html.replace(iconRegex, (match) => {
|
|
25
25
|
const document = htmlparser2.parseDocument(match, { xmlMode: true })
|
|
26
26
|
const iconElement = document.firstChild
|
|
@@ -34,11 +34,11 @@ export function replaceIconsInHtml(html: string) {
|
|
|
34
34
|
throw new Error('Invalid icon element.')
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
return renderIconToString(getOptionsWithDefaults(iconElement.attribs))
|
|
37
|
+
return renderIconToString(getOptionsWithDefaults(iconElement.attribs, staticPath))
|
|
38
38
|
})
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function getOptionsWithDefaults(attribs: Record<string, string
|
|
41
|
+
function getOptionsWithDefaults(attribs: Record<string, string>, staticPath: string): IconOptions {
|
|
42
42
|
if (!attribs.name) {
|
|
43
43
|
throw new Error('Icon element is missing the required "name" attribute.')
|
|
44
44
|
}
|
|
@@ -48,7 +48,7 @@ function getOptionsWithDefaults(attribs: Record<string, string>): IconOptions {
|
|
|
48
48
|
class: attribs.class,
|
|
49
49
|
size: attribs.size ? Number(attribs.size.replace(/[{}]/g, '')) : 24,
|
|
50
50
|
font: attribs.font !== undefined && attribs.font !== '{false}',
|
|
51
|
-
sprite: attribs.sprite ||
|
|
51
|
+
sprite: attribs.sprite || `${staticPath}/icons/chassis-icons.svg`,
|
|
52
52
|
title: attribs.title
|
|
53
53
|
}
|
|
54
54
|
}
|
package/src/libs/markdown.ts
CHANGED
|
@@ -35,6 +35,17 @@ const addLanguageAttributeTransformer: ShikiTransformer = {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Shiki transformer that puts `<pre>` in the tab order. A code block that is wider than the
|
|
40
|
+
* page scrolls sideways, and a keyboard can scroll it only when it can take focus.
|
|
41
|
+
*/
|
|
42
|
+
export const focusableTransformer: ShikiTransformer = {
|
|
43
|
+
name: 'focusable-pre',
|
|
44
|
+
pre(node) {
|
|
45
|
+
node.properties['tabindex'] = '0'
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
38
49
|
/**
|
|
39
50
|
* Options accepted by `getDocsMarkdownConfig`.
|
|
40
51
|
*/
|
|
@@ -121,7 +132,8 @@ export function getDocsMarkdownConfig(options: DocsMarkdownConfigOptions): Markd
|
|
|
121
132
|
transformers: [
|
|
122
133
|
transformerNotationDiff(),
|
|
123
134
|
transformerNotationHighlight(),
|
|
124
|
-
addLanguageAttributeTransformer
|
|
135
|
+
addLanguageAttributeTransformer,
|
|
136
|
+
focusableTransformer
|
|
125
137
|
]
|
|
126
138
|
}
|
|
127
139
|
}
|
package/src/libs/schema.ts
CHANGED
|
@@ -38,7 +38,7 @@ const zHeadingRange = z.object({
|
|
|
38
38
|
* ```
|
|
39
39
|
*/
|
|
40
40
|
export const configSchema = z.strictObject({
|
|
41
|
-
/** Google Analytics is
|
|
41
|
+
/** Google Analytics is offered in production builds when `googleId` is set, and loads after the visitor accepts. */
|
|
42
42
|
analytics: z.strictObject({ googleId: z.string().optional() }).default({}),
|
|
43
43
|
/** Heading levels that get an anchor link. */
|
|
44
44
|
anchors: zHeadingRange.default({ min: 2, max: 5 }),
|
|
@@ -70,6 +70,16 @@ export const configSchema = z.strictObject({
|
|
|
70
70
|
sourceDir: z.string().default('.'),
|
|
71
71
|
/** The same directory from the root of the repository, e.g. `"packages/css"`. */
|
|
72
72
|
sourcePath: z.string().optional(),
|
|
73
|
+
/**
|
|
74
|
+
* URL path that the pages load the static files from, e.g. `"/css/static"`. The files stay
|
|
75
|
+
* in `static/` of the `public` directory: a site under a prefix of another host sets this
|
|
76
|
+
* and rewrites the path to `/static`.
|
|
77
|
+
*/
|
|
78
|
+
staticPath: z
|
|
79
|
+
.string()
|
|
80
|
+
.regex(/^\/(.*[^/])?$/, 'Expected a URL path that starts with "/" and has no trailing slash')
|
|
81
|
+
.refine((value) => value !== '/', 'Expected a path below the root, such as "/static"')
|
|
82
|
+
.default('/static'),
|
|
73
83
|
subtitle: z.string(),
|
|
74
84
|
title: z.string(),
|
|
75
85
|
/** Heading levels that the table of contents lists. */
|
package/src/scss/_footer.scss
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
a
|
|
17
|
+
a,
|
|
18
|
+
.cxd-footer-link {
|
|
18
19
|
color: var(--cx-fg-color);
|
|
19
20
|
text-decoration: none;
|
|
20
21
|
|
|
@@ -24,5 +25,14 @@
|
|
|
24
25
|
text-decoration: underline;
|
|
25
26
|
}
|
|
26
27
|
}
|
|
28
|
+
|
|
29
|
+
// A button that looks like the links next to it
|
|
30
|
+
.cxd-footer-link {
|
|
31
|
+
padding: 0;
|
|
32
|
+
font: inherit;
|
|
33
|
+
cursor: pointer;
|
|
34
|
+
background: none;
|
|
35
|
+
border: 0;
|
|
36
|
+
}
|
|
27
37
|
}
|
|
28
38
|
}
|
package/src/scss/main.scss
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
@use "@chassis-ui/css/scss/mixins" as *;
|
|
2
2
|
|
|
3
|
-
@forward "./fonts";
|
|
4
3
|
@forward "./navbar";
|
|
5
4
|
@forward "./content";
|
|
6
5
|
@forward "./skippy";
|
|
@@ -8,6 +7,7 @@
|
|
|
8
7
|
@forward "./layout";
|
|
9
8
|
@forward "./toc";
|
|
10
9
|
@forward "./footer";
|
|
10
|
+
@forward "./consent";
|
|
11
11
|
@forward "./snippets";
|
|
12
12
|
@forward "./callouts";
|
|
13
13
|
@forward "./placeholder-img";
|
package/src/site.ts
CHANGED
|
@@ -9,7 +9,7 @@ import sidebar from 'virtual:chassis-docs/sidebar'
|
|
|
9
9
|
import * as paths from 'virtual:chassis-docs/paths'
|
|
10
10
|
import { getCollection, getEntry, type render } from 'astro:content'
|
|
11
11
|
import { loadData } from './libs/config'
|
|
12
|
-
import { joinDocsPath } from './libs/docs-path'
|
|
12
|
+
import { joinDocsPath, joinStaticPath } from './libs/docs-path'
|
|
13
13
|
import { getNodeModulesFsPaths, resolvePackageFilePath } from './libs/paths'
|
|
14
14
|
import { replaceConfigInText, replaceDocsrefInText } from './libs/remark'
|
|
15
15
|
import type { ChassisConfig, DocsPage, Sidebar } from './libs/schema'
|
|
@@ -35,6 +35,14 @@ export function getDocsPath(inputPath: string): string {
|
|
|
35
35
|
return joinDocsPath(config.docsPath, inputPath)
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* URL path of a static file, under `staticPath` of the config:
|
|
40
|
+
* `getStaticPath('images/site-logo.svg')` is `/static/images/site-logo.svg` by default.
|
|
41
|
+
*/
|
|
42
|
+
export function getStaticPath(file = ''): string {
|
|
43
|
+
return joinStaticPath(config.staticPath ?? '/static', file)
|
|
44
|
+
}
|
|
45
|
+
|
|
38
46
|
/** Absolute path of the site's root: the directory that holds `astro.config.ts`. */
|
|
39
47
|
export function getSiteRoot(): string {
|
|
40
48
|
return paths.root
|
package/virtual.d.ts
CHANGED
|
@@ -22,4 +22,9 @@ declare module 'virtual:chassis-docs/paths' {
|
|
|
22
22
|
export const packageRoot: string
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
declare module 'virtual:chassis-docs/static' {
|
|
26
|
+
/** `staticPath` of the config, for scripts that run in the browser. */
|
|
27
|
+
export const staticPath: string
|
|
28
|
+
}
|
|
29
|
+
|
|
25
30
|
declare module 'virtual:chassis-docs/styles' {}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
/**
|
|
3
|
-
* Analytics
|
|
4
|
-
*
|
|
5
|
-
* Google Analytics script tags. Rendered in production builds, when `analytics.googleId` is
|
|
6
|
-
* set in `config.yml`.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { getConfig } from '../../site'
|
|
10
|
-
|
|
11
|
-
const isProd = import.meta.env.PROD
|
|
12
|
-
const { googleId } = getConfig().analytics
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
{
|
|
16
|
-
isProd && googleId && (
|
|
17
|
-
<>
|
|
18
|
-
<script is:inline async src={`https://www.googletagmanager.com/gtag/js?id=${googleId}`} />
|
|
19
|
-
<script
|
|
20
|
-
is:inline
|
|
21
|
-
set:html={`
|
|
22
|
-
window.dataLayer = window.dataLayer || [];
|
|
23
|
-
function gtag(){dataLayer.push(arguments);}
|
|
24
|
-
gtag('js', new Date());
|
|
25
|
-
|
|
26
|
-
gtag('config', '${googleId}');
|
|
27
|
-
`}
|
|
28
|
-
/>
|
|
29
|
-
</>
|
|
30
|
-
)
|
|
31
|
-
}
|
package/src/scss/fonts.scss
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@import "https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&family=Inter:wght@100..900&family=Archivo+Narrow:ital,wght@0,400..700;1,400..700&display=swap";
|