@chassis-ui/docs 0.1.0
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/README.md +98 -0
- package/index.ts +7 -0
- package/package.json +66 -0
- package/src/components/DocsSidebar.astro +89 -0
- package/src/components/NavDocsMenu.astro +26 -0
- package/src/components/NavLink.astro +24 -0
- package/src/components/ResponsiveImage.astro +31 -0
- package/src/components/TableOfContents.astro +31 -0
- package/src/components/ThemeToggler.astro +70 -0
- package/src/components/shortcodes/AddedIn.astro +13 -0
- package/src/components/shortcodes/Callout.astro +37 -0
- package/src/components/shortcodes/CxTable.astro +16 -0
- package/src/js/color-modes.js +82 -0
- package/src/js/icon-loader.js +220 -0
- package/src/js/search.js +58 -0
- package/src/js/sidebar.js +30 -0
- package/src/js/theme-color.js +126 -0
- package/src/layouts/BaseLayout.astro +94 -0
- package/src/layouts/DocsLayout.astro +147 -0
- package/src/layouts/IconsLayout.astro +19 -0
- package/src/layouts/RedirectLayout.astro +23 -0
- package/src/layouts/SingleLayout.astro +33 -0
- package/src/layouts/footer/Footer.astro +56 -0
- package/src/layouts/footer/Scripts.astro +22 -0
- package/src/layouts/head/Analytics.astro +22 -0
- package/src/layouts/head/Favicons.astro +11 -0
- package/src/layouts/head/Head.astro +54 -0
- package/src/layouts/head/Scss.astro +9 -0
- package/src/layouts/head/Social.astro +38 -0
- package/src/layouts/head/Stylesheet.astro +15 -0
- package/src/layouts/header/Header.astro +19 -0
- package/src/layouts/header/Navigation.astro +121 -0
- package/src/layouts/header/Skippy.astro +22 -0
- package/src/libs/image.ts +13 -0
- package/src/libs/layout.ts +7 -0
- package/src/libs/rehype.ts +38 -0
- package/src/libs/remark.ts +205 -0
- package/src/libs/toc.ts +44 -0
- package/src/libs/utils.ts +122 -0
- package/src/scss/_anchor.scss +21 -0
- package/src/scss/_brand.scss +59 -0
- package/src/scss/_buttons.scss +36 -0
- package/src/scss/_callouts.scss +40 -0
- package/src/scss/_clipboard-js.scss +63 -0
- package/src/scss/_code.scss +116 -0
- package/src/scss/_colors.scss +140 -0
- package/src/scss/_content.scss +141 -0
- package/src/scss/_docsearch.scss +174 -0
- package/src/scss/_footer.scss +29 -0
- package/src/scss/_layout.scss +72 -0
- package/src/scss/_masthead.scss +124 -0
- package/src/scss/_navbar.scss +138 -0
- package/src/scss/_placeholder-img.scss +15 -0
- package/src/scss/_scrolling.scss +16 -0
- package/src/scss/_settings.scss +37 -0
- package/src/scss/_sidebar.scss +161 -0
- package/src/scss/_skippy.scss +7 -0
- package/src/scss/_syntax.scss +158 -0
- package/src/scss/_toc.scss +117 -0
- package/src/scss/_variables.scss +78 -0
- package/src/scss/fonts.scss +1 -0
- package/src/scss/main.scss +90 -0
- package/src/scss/search.scss +26 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type { Root } from 'mdast'
|
|
2
|
+
import type { MdxJsxAttribute, MdxJsxExpressionAttribute } from 'mdast-util-mdx-jsx'
|
|
3
|
+
import type { Plugin } from 'unified'
|
|
4
|
+
import { visit } from 'unist-util-visit'
|
|
5
|
+
|
|
6
|
+
// Global registry for config and path functions
|
|
7
|
+
let globalConfigGetter: (() => any) | null = null
|
|
8
|
+
let globalPathGetter: ((path: string) => string) | null = null
|
|
9
|
+
|
|
10
|
+
// Registration function for consuming sites to provide their config and path functions
|
|
11
|
+
export function registerRemarkFunctions(
|
|
12
|
+
getConfig: () => any,
|
|
13
|
+
getChassisDocsPath: (path: string) => string
|
|
14
|
+
) {
|
|
15
|
+
globalConfigGetter = getConfig
|
|
16
|
+
globalPathGetter = getChassisDocsPath
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// [[config:foo]]
|
|
20
|
+
// [[config:foo.bar]]
|
|
21
|
+
const configRegExp = /\[\[config:(?<name>[\w.]+)]]/g
|
|
22
|
+
// [[docsref:/foo]]
|
|
23
|
+
// [[docsref:/foo/bar#baz]]
|
|
24
|
+
const docsrefRegExp = /\[\[docsref:(?<path>[\w./#-]+)]]/g
|
|
25
|
+
|
|
26
|
+
// A remark plugin to replace config values embedded in markdown (or MDX) files.
|
|
27
|
+
// For example, [[config:foo]] will be replaced with the value of the `foo` key in the `config.yml` file.
|
|
28
|
+
// Nested values are also supported, e.g. [[config:foo.bar]].
|
|
29
|
+
// Note: this also works in frontmatter.
|
|
30
|
+
// Note: this plugin is meant to facilitate the migration from Hugo to Astro while keeping the differences to a minimum.
|
|
31
|
+
// At some point, this plugin should maybe be removed and embrace a more MDX-friendly syntax.
|
|
32
|
+
export const remarkCxConfig: Plugin<[], Root> = function () {
|
|
33
|
+
return function remarkCxConfigPlugin(ast, file) {
|
|
34
|
+
if (containsFrontmatter(file.data.astro)) {
|
|
35
|
+
replaceInFrontmatter(file.data.astro.frontmatter, replaceConfigInText)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// https://github.com/syntax-tree/mdast#nodes
|
|
39
|
+
// https://github.com/syntax-tree/mdast-util-mdx-jsx#nodes
|
|
40
|
+
visit(
|
|
41
|
+
ast,
|
|
42
|
+
['code', 'definition', 'image', 'inlineCode', 'link', 'mdxJsxFlowElement', 'text'],
|
|
43
|
+
(node) => {
|
|
44
|
+
switch (node.type) {
|
|
45
|
+
case 'code':
|
|
46
|
+
case 'inlineCode':
|
|
47
|
+
case 'text': {
|
|
48
|
+
node.value = replaceConfigInText(node.value)
|
|
49
|
+
break
|
|
50
|
+
}
|
|
51
|
+
case 'image': {
|
|
52
|
+
if (node.alt) {
|
|
53
|
+
node.alt = replaceConfigInText(node.alt)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
node.url = replaceConfigInText(node.url)
|
|
57
|
+
break
|
|
58
|
+
}
|
|
59
|
+
case 'definition':
|
|
60
|
+
case 'link': {
|
|
61
|
+
node.url = replaceConfigInText(node.url)
|
|
62
|
+
break
|
|
63
|
+
}
|
|
64
|
+
case 'mdxJsxFlowElement': {
|
|
65
|
+
node.attributes = replaceConfigInAttributes(node.attributes)
|
|
66
|
+
break
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// A remark plugin to add versionned docs links in markdown (or MDX) files.
|
|
75
|
+
// For example, [[docsref:/foo]] will be replaced with the `/docs/${docs_version}/foo` value with the `docs_version`
|
|
76
|
+
// value being read from the `config.yml` file.
|
|
77
|
+
// Note: this also works in frontmatter.
|
|
78
|
+
// Note: this plugin is meant to facilitate the migration from Hugo to Astro while keeping the differences to a minimum.
|
|
79
|
+
// At some point, this plugin should maybe be removed and embrace a more MDX-friendly syntax.
|
|
80
|
+
export const remarkCxDocsref: Plugin<[], Root> = function () {
|
|
81
|
+
return function remarkCxDocsrefPlugin(ast, file) {
|
|
82
|
+
if (containsFrontmatter(file.data.astro)) {
|
|
83
|
+
replaceInFrontmatter(file.data.astro.frontmatter, replaceDocsrefInText)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// https://github.com/syntax-tree/mdast#nodes
|
|
87
|
+
// https://github.com/syntax-tree/mdast-util-mdx-jsx#nodes
|
|
88
|
+
visit(
|
|
89
|
+
ast,
|
|
90
|
+
[
|
|
91
|
+
'code',
|
|
92
|
+
'definition',
|
|
93
|
+
'image',
|
|
94
|
+
'inlineCode',
|
|
95
|
+
'link',
|
|
96
|
+
'mdxJsxFlowElement',
|
|
97
|
+
'mdxJsxTextElement',
|
|
98
|
+
'text'
|
|
99
|
+
],
|
|
100
|
+
(node) => {
|
|
101
|
+
switch (node.type) {
|
|
102
|
+
case 'code':
|
|
103
|
+
case 'inlineCode':
|
|
104
|
+
case 'text': {
|
|
105
|
+
node.value = replaceDocsrefInText(node.value)
|
|
106
|
+
break
|
|
107
|
+
}
|
|
108
|
+
case 'definition':
|
|
109
|
+
case 'link': {
|
|
110
|
+
node.url = replaceDocsrefInText(node.url)
|
|
111
|
+
break
|
|
112
|
+
}
|
|
113
|
+
case 'mdxJsxFlowElement':
|
|
114
|
+
case 'mdxJsxTextElement': {
|
|
115
|
+
node.attributes = replaceDocsrefInAttributes(node.attributes)
|
|
116
|
+
break
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function replaceConfigInText(text: string) {
|
|
125
|
+
return text.replace(configRegExp, (_match, path) => {
|
|
126
|
+
const value = getConfigValueAtPath(path)
|
|
127
|
+
|
|
128
|
+
if (!value) {
|
|
129
|
+
throw new Error(`Failed to find a valid configuration value for '${path}'.`)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return value
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function replaceConfigInAttributes(attributes: (MdxJsxAttribute | MdxJsxExpressionAttribute)[]) {
|
|
137
|
+
return attributes.map((attribute) => {
|
|
138
|
+
if (attribute.type === 'mdxJsxAttribute' && typeof attribute.value === 'string') {
|
|
139
|
+
attribute.value = replaceConfigInText(attribute.value)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return attribute
|
|
143
|
+
})
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function replaceDocsrefInText(text: string) {
|
|
147
|
+
if (!globalPathGetter) {
|
|
148
|
+
throw new Error('remark functions not registered. Call registerRemarkFunctions() first.')
|
|
149
|
+
}
|
|
150
|
+
return text.replace(docsrefRegExp, (_match, path) => {
|
|
151
|
+
return globalPathGetter!(path)
|
|
152
|
+
})
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function replaceDocsrefInAttributes(attributes: (MdxJsxAttribute | MdxJsxExpressionAttribute)[]) {
|
|
156
|
+
return attributes.map((attribute) => {
|
|
157
|
+
if (attribute.type === 'mdxJsxAttribute' && typeof attribute.value === 'string') {
|
|
158
|
+
attribute.value = replaceDocsrefInText(attribute.value)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return attribute
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function getConfigValueAtPath(path: string) {
|
|
166
|
+
if (!globalConfigGetter) {
|
|
167
|
+
throw new Error('remark functions not registered. Call registerRemarkFunctions() first.')
|
|
168
|
+
}
|
|
169
|
+
const config = globalConfigGetter()
|
|
170
|
+
|
|
171
|
+
const value = path.split('.').reduce((values, part) => {
|
|
172
|
+
if (!values || typeof values !== 'object') {
|
|
173
|
+
return undefined
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return (values as any)?.[part]
|
|
177
|
+
}, config as unknown)
|
|
178
|
+
|
|
179
|
+
return typeof value === 'string' ? value : undefined
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function replaceInFrontmatter(
|
|
183
|
+
record: Record<string, unknown>,
|
|
184
|
+
replacer: (value: string) => string
|
|
185
|
+
) {
|
|
186
|
+
for (const [key, value] of Object.entries(record)) {
|
|
187
|
+
if (typeof value === 'string') {
|
|
188
|
+
record[key] = replacer(value)
|
|
189
|
+
} else if (Array.isArray(value)) {
|
|
190
|
+
record[key] = value.map((arrayValue) => {
|
|
191
|
+
return typeof arrayValue === 'string'
|
|
192
|
+
? replacer(arrayValue)
|
|
193
|
+
: typeof arrayValue === 'object'
|
|
194
|
+
? replaceInFrontmatter(arrayValue, replacer)
|
|
195
|
+
: arrayValue
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return record
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function containsFrontmatter(data: unknown): data is { frontmatter: Record<string, unknown> } {
|
|
204
|
+
return data != undefined && typeof data === 'object' && 'frontmatter' in data
|
|
205
|
+
}
|
package/src/libs/toc.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { MarkdownHeading } from 'astro'
|
|
2
|
+
// import { getConfig } from './config'
|
|
3
|
+
|
|
4
|
+
// Generate a tree like structure from a list of headings.
|
|
5
|
+
export function generateToc(allHeadings: MarkdownHeading[], config: any) {
|
|
6
|
+
const headings = allHeadings.filter(
|
|
7
|
+
(heading) => heading.depth >= config.toc.min && heading.depth <= config.toc.max
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
const toc: TocEntry[] = []
|
|
11
|
+
|
|
12
|
+
for (const heading of headings) {
|
|
13
|
+
if (toc.length === 0) {
|
|
14
|
+
toc.push({ ...heading, children: [] })
|
|
15
|
+
continue
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const previousEntry = toc[toc.length - 1]
|
|
19
|
+
|
|
20
|
+
if (heading.depth === previousEntry.depth) {
|
|
21
|
+
toc.push({ ...heading, children: [] })
|
|
22
|
+
continue
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const children = getEntryChildrenAtDepth(previousEntry, heading.depth - previousEntry.depth)
|
|
26
|
+
children.push({ ...heading, children: [] })
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return toc
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getEntryChildrenAtDepth(entry: TocEntry, depth: number): TocEntry['children'] {
|
|
33
|
+
if (!entry) {
|
|
34
|
+
return []
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return depth === 1
|
|
38
|
+
? entry.children
|
|
39
|
+
: getEntryChildrenAtDepth(entry.children[entry.children.length - 1], depth - 1)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface TocEntry extends MarkdownHeading {
|
|
43
|
+
children: TocEntry[]
|
|
44
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import os from 'os'
|
|
2
|
+
import { slug } from 'github-slugger'
|
|
3
|
+
import { fromMarkdown } from 'mdast-util-from-markdown'
|
|
4
|
+
import { toString } from 'mdast-util-to-string'
|
|
5
|
+
import { remark } from 'remark'
|
|
6
|
+
import remarkHtml from 'remark-html'
|
|
7
|
+
|
|
8
|
+
export function capitalizeFirstLetter(str: string) {
|
|
9
|
+
return str.charAt(0).toUpperCase() + str.slice(1)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function getSequence(start: number, end: number, step = 1) {
|
|
13
|
+
const sequence = []
|
|
14
|
+
|
|
15
|
+
for (let i = start; i <= end; i += step) {
|
|
16
|
+
sequence.push(i)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return sequence
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// This function is used in the docs sidebar to generate partial slugs and properly order the sidebar entries and also
|
|
23
|
+
// to generate docs frontmatter sections slugs.
|
|
24
|
+
// Note: this should be refactored and removed, the sidebar ordering defined in `site/data/sidebar.yml` should not rely
|
|
25
|
+
// on slugified custom titles that are expected to generate a string matching the actual file names on disk, this is
|
|
26
|
+
// error prone. Instead, custom sidebar titles should be defined in the frontmatter of the MDX files when needed and
|
|
27
|
+
// `site/data/sidebar.yml` should only reference the actual file names and slug extracted from the docs content
|
|
28
|
+
// collection. Same goes for the docs frontmatter sections.
|
|
29
|
+
export function getSlug(str: string) {
|
|
30
|
+
return slug(str).replace(/--+/g, '-')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function trimLeadingAndTrailingSlashes(str: string) {
|
|
34
|
+
return str.replace(/^\/+|\/+$/g, '')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function stripMarkdown(str: string) {
|
|
38
|
+
return toString(fromMarkdown(str))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function processMarkdownToHtml(markdown: string): string {
|
|
42
|
+
// Use remark to process markdown to HTML
|
|
43
|
+
const result = remark().use(remarkHtml).processSync(markdown)
|
|
44
|
+
return result.toString()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function titleCase(str: string) {
|
|
48
|
+
return str.replace(
|
|
49
|
+
/\w\S*/g,
|
|
50
|
+
(text) => text.charAt(0).toUpperCase() + text.substring(1).toLowerCase()
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Gets the appropriate host and port for development server
|
|
56
|
+
* @returns {object} Object with host and port properties
|
|
57
|
+
*/
|
|
58
|
+
function getDevHost() {
|
|
59
|
+
const hasHostFlag = process.argv.includes('--host')
|
|
60
|
+
let host = 'localhost'
|
|
61
|
+
let port = 4321
|
|
62
|
+
|
|
63
|
+
// Check for --port command line argument (e.g., astro dev --port 4322)
|
|
64
|
+
const portFlagIndex = process.argv.findIndex((arg) => arg === '--port')
|
|
65
|
+
if (portFlagIndex !== -1 && process.argv[portFlagIndex + 1]) {
|
|
66
|
+
const cliPort = parseInt(process.argv[portFlagIndex + 1], 10)
|
|
67
|
+
if (!isNaN(cliPort) && cliPort > 0 && cliPort < 65536) {
|
|
68
|
+
port = cliPort
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Check for PORT environment variable (most common way to override port)
|
|
73
|
+
if (process.env.PORT) {
|
|
74
|
+
const envPort = parseInt(process.env.PORT, 10)
|
|
75
|
+
if (!isNaN(envPort) && envPort > 0 && envPort < 65536) {
|
|
76
|
+
port = envPort
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Determine host based on --host flag
|
|
81
|
+
if (hasHostFlag) {
|
|
82
|
+
const interfaces = os.networkInterfaces()
|
|
83
|
+
for (const iface of Object.values(interfaces).flat()) {
|
|
84
|
+
if (iface?.family === 'IPv4' && !iface.internal) {
|
|
85
|
+
host = iface.address
|
|
86
|
+
break
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { host, port }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Determines the site URL based on environment and deployment context
|
|
96
|
+
* @returns {string} The appropriate site URL for the current environment
|
|
97
|
+
*/
|
|
98
|
+
export function getSiteUrl(config: any) {
|
|
99
|
+
// Check for explicit SITE_URL override first
|
|
100
|
+
if (process.env.SITE_URL) {
|
|
101
|
+
return process.env.SITE_URL
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Development: Local server with optional network access
|
|
105
|
+
if (process.env.NODE_ENV === 'development') {
|
|
106
|
+
const { host, port } = getDevHost()
|
|
107
|
+
return `http://${host}:${port}`
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Vercel Production: Live production deployment
|
|
111
|
+
if (process.env.VERCEL_ENV === 'production') {
|
|
112
|
+
return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Vercel Preview: Branch deployments and previews
|
|
116
|
+
if (process.env.VERCEL_URL) {
|
|
117
|
+
return `https://${process.env.VERCEL_URL}`
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Fallback: Use baseURL from config.yml
|
|
121
|
+
return config.baseURL
|
|
122
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
.anchor-link {
|
|
2
|
+
padding: 0 .175rem;
|
|
3
|
+
font-weight: 400;
|
|
4
|
+
color: rgba($link-main, .5);
|
|
5
|
+
text-decoration: none;
|
|
6
|
+
opacity: 0;
|
|
7
|
+
@include transition(color .15s ease-in-out, opacity .15s ease-in-out);
|
|
8
|
+
|
|
9
|
+
&::after {
|
|
10
|
+
content: "#";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
&:focus,
|
|
14
|
+
&:hover,
|
|
15
|
+
:hover > &,
|
|
16
|
+
:target > & {
|
|
17
|
+
color: $link-main;
|
|
18
|
+
text-decoration: none;
|
|
19
|
+
opacity: 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Brand guidelines
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
// Logo series wrapper
|
|
6
|
+
.cxd-brand-logos {
|
|
7
|
+
color: $cxd-subtle;
|
|
8
|
+
|
|
9
|
+
.inverse {
|
|
10
|
+
color: $white;
|
|
11
|
+
background-color: $cxd-subtle;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Individual items
|
|
16
|
+
.cxd-brand-item {
|
|
17
|
+
+ .cxd-brand-item {
|
|
18
|
+
border-top: 1px solid var(--cx-border-color);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@include media-breakpoint-up(medium) {
|
|
22
|
+
+ .cxd-brand-item {
|
|
23
|
+
border-top: 0;
|
|
24
|
+
border-left: 1px solid var(--cx-border-color);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//
|
|
30
|
+
// Color swatches
|
|
31
|
+
//
|
|
32
|
+
|
|
33
|
+
.color-swatches {
|
|
34
|
+
margin: 0 -5px;
|
|
35
|
+
|
|
36
|
+
// Docs colors
|
|
37
|
+
.cxd-main {
|
|
38
|
+
background-color: $cxd-main;
|
|
39
|
+
}
|
|
40
|
+
.cxd-main-light {
|
|
41
|
+
background-color: $cxd-main-light;
|
|
42
|
+
}
|
|
43
|
+
.cxd-main-lighter {
|
|
44
|
+
background-color: #e5e1ea;
|
|
45
|
+
}
|
|
46
|
+
.cxd-gray {
|
|
47
|
+
background-color: #f9f9f9;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.color-swatch {
|
|
52
|
+
width: 4rem;
|
|
53
|
+
height: 4rem;
|
|
54
|
+
|
|
55
|
+
@include media-breakpoint-up(medium) {
|
|
56
|
+
width: 6rem;
|
|
57
|
+
height: 6rem;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
@import "@chassis-ui/css/scss/mixins/context";
|
|
2
|
+
@import "@chassis-ui/css/scss/placeholders/context";
|
|
3
|
+
@import "@chassis-ui/css/scss/placeholders/component";
|
|
4
|
+
@import "@chassis-ui/css/scss/placeholders/button";
|
|
5
|
+
// Buttons
|
|
6
|
+
//
|
|
7
|
+
// Custom buttons for the docs.
|
|
8
|
+
|
|
9
|
+
// scss-docs-start cxd-button
|
|
10
|
+
.cxd-button {
|
|
11
|
+
|
|
12
|
+
--#{$prefix}padding-y: var(--#{$prefix}space-3xsmall);
|
|
13
|
+
--#{$prefix}padding-x: var(--#{$prefix}space-large);
|
|
14
|
+
--#{$prefix}gap: var(--#{$prefix}space-small);
|
|
15
|
+
--#{$prefix}font-family: var(--#{$prefix}font-family-text);
|
|
16
|
+
--#{$prefix}font-size: var(--#{$prefix}font-size-large);
|
|
17
|
+
--#{$prefix}font-weight: var(--#{$prefix}font-weight-mass);
|
|
18
|
+
// --#{$prefix}line-height: var(--#{$prefix}line-height-large);
|
|
19
|
+
--#{$prefix}icon-size: var(--#{$prefix}icon-large);
|
|
20
|
+
|
|
21
|
+
display: inline-flex;
|
|
22
|
+
gap: var(--#{$prefix}gap);
|
|
23
|
+
align-items: center;
|
|
24
|
+
text-decoration: if($link-decoration == none, null, none);
|
|
25
|
+
|
|
26
|
+
@extend %button, %solid-button, %component, %box-padding;
|
|
27
|
+
|
|
28
|
+
&.large {
|
|
29
|
+
--#{$prefix}font-size: var(--#{$prefix}font-size-xlarge);
|
|
30
|
+
--#{$prefix}line-height: var(--#{$prefix}line-height-xlarge);
|
|
31
|
+
--#{$prefix}font-weight: var(--#{$prefix}font-weight-strong);
|
|
32
|
+
--#{$prefix}icon-size: var(--#{$prefix}icon-xlarge);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
// scss-docs-end cxd-button
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Callouts
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
.cxd-callout {
|
|
6
|
+
--#{$prefix}link-main-color-rgb: var(--cxd-callout-link);
|
|
7
|
+
--#{$prefix}code-color: var(--cxd-callout-code-color);
|
|
8
|
+
|
|
9
|
+
padding: 1.25rem;
|
|
10
|
+
margin-top: 1.25rem;
|
|
11
|
+
margin-bottom: 1.25rem;
|
|
12
|
+
color: var(--cxd-callout-color, inherit);
|
|
13
|
+
background-color: var(--cxd-callout-bg, var(--cx-gray-100));
|
|
14
|
+
border-left: .25rem solid var(--cxd-callout-border, var(--cx-gray-300));
|
|
15
|
+
|
|
16
|
+
h4 {
|
|
17
|
+
margin-bottom: .25rem;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
> :last-child {
|
|
21
|
+
margin-bottom: 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
+ .cxd-callout {
|
|
25
|
+
margin-top: -.25rem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.highlight {
|
|
29
|
+
background-color: rgba($black, .05);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Variations
|
|
34
|
+
@each $variant in $cxd-callout-variants {
|
|
35
|
+
.cxd-callout-#{$variant} {
|
|
36
|
+
--cxd-callout-color: var(--cx-#{$variant}-fg-main);
|
|
37
|
+
--cxd-callout-bg: var(--cx-#{$variant}-bg-even);
|
|
38
|
+
--cxd-callout-border: var(--cx-#{$variant}-border-subtle);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// clipboard.js
|
|
2
|
+
//
|
|
3
|
+
// JS-based `Copy` buttons for code snippets.
|
|
4
|
+
|
|
5
|
+
.cxd-mode {
|
|
6
|
+
position: absolute;
|
|
7
|
+
top: 0;
|
|
8
|
+
right: 0;
|
|
9
|
+
z-index: 3;
|
|
10
|
+
margin-top: .75rem;
|
|
11
|
+
margin-right: .75rem;
|
|
12
|
+
.button-mode {
|
|
13
|
+
background-color: var(--cx-bg-idle);
|
|
14
|
+
border: var(--cx-border-width) solid var(--cx-border-subtle);
|
|
15
|
+
}
|
|
16
|
+
&:not(.cxd-example:hover &) {
|
|
17
|
+
display: none;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
.cxd-clipboard,
|
|
21
|
+
.cxd-edit {
|
|
22
|
+
position: relative;
|
|
23
|
+
display: none;
|
|
24
|
+
float: right;
|
|
25
|
+
|
|
26
|
+
+ .highlight {
|
|
27
|
+
margin-top: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@include media-breakpoint-up(medium) {
|
|
31
|
+
display: block;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.button-mode,
|
|
36
|
+
.button-clipboard,
|
|
37
|
+
.button-edit {
|
|
38
|
+
--cx-icon-color: var(--cx-fg-subtle);
|
|
39
|
+
--cx-icon-size: var(--cx-icon-small);
|
|
40
|
+
display: block;
|
|
41
|
+
padding: .5em .25em;
|
|
42
|
+
line-height: 1;
|
|
43
|
+
background-color: var(--cxd-pre-bg);
|
|
44
|
+
border: 0;
|
|
45
|
+
@include border-radius(.25rem);
|
|
46
|
+
|
|
47
|
+
&:hover {
|
|
48
|
+
color: var(--cx-hover-color);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&:focus {
|
|
52
|
+
z-index: 3;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.button-mode,
|
|
57
|
+
.button-clipboard {
|
|
58
|
+
position: relative;
|
|
59
|
+
z-index: 2;
|
|
60
|
+
margin-top: .75rem;
|
|
61
|
+
margin-right: .75rem;
|
|
62
|
+
}
|
|
63
|
+
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Docs examples
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
.cxd-code-snippet {
|
|
6
|
+
//background-color: var(--cx-bg-evident);
|
|
7
|
+
margin: 0 ($cxd-gutter-x * -.5) 1rem;
|
|
8
|
+
border: solid var(--cx-border-subtle);
|
|
9
|
+
border-width: 1px 0;
|
|
10
|
+
|
|
11
|
+
@include media-breakpoint-up(medium) {
|
|
12
|
+
margin-right: 0;
|
|
13
|
+
margin-left: 0;
|
|
14
|
+
border-width: 1px;
|
|
15
|
+
@include border-radius(var(--cx-border-radius));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.cxd-example {
|
|
20
|
+
|
|
21
|
+
// background-color: var(--cx-bg-main);
|
|
22
|
+
--cxd-example-padding: 1rem;
|
|
23
|
+
|
|
24
|
+
position: relative;
|
|
25
|
+
padding: var(--cxd-example-padding);
|
|
26
|
+
margin: 0 ($cxd-gutter-x * -.5) 1rem;
|
|
27
|
+
border: solid var(--cx-border-subtle);
|
|
28
|
+
border-width: 1px 0;
|
|
29
|
+
@include clearfix();
|
|
30
|
+
|
|
31
|
+
@include media-breakpoint-up(medium) {
|
|
32
|
+
--cxd-example-padding: 1.5rem;
|
|
33
|
+
|
|
34
|
+
margin-right: 0;
|
|
35
|
+
margin-left: 0;
|
|
36
|
+
border-width: 1px;
|
|
37
|
+
@include border-radius(var(--cx-border-radius));
|
|
38
|
+
&:has(~ .highlight-toolbar) {
|
|
39
|
+
@include border-bottom-radius(0);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
+ p {
|
|
44
|
+
margin-top: 2rem;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
//
|
|
49
|
+
// Code snippets
|
|
50
|
+
//
|
|
51
|
+
|
|
52
|
+
.highlight {
|
|
53
|
+
position: relative;
|
|
54
|
+
padding: 1.25rem ($cxd-gutter-x * .5);
|
|
55
|
+
background-color: var(--cxd-pre-bg, var(--cx-bg-even));
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@include media-breakpoint-up(medium) {
|
|
59
|
+
padding: 1.25rem;
|
|
60
|
+
@include border-radius(calc(var(--cx-border-radius) - 1px));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@include media-breakpoint-up(large) {
|
|
64
|
+
pre {
|
|
65
|
+
margin-right: 1.875rem;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
pre {
|
|
70
|
+
// padding: .25rem 0 .875rem;
|
|
71
|
+
// margin-top: .8125rem;
|
|
72
|
+
margin-bottom: 0;
|
|
73
|
+
overflow: overlay;
|
|
74
|
+
@include font-size(var(--cx-font-size-code-small));
|
|
75
|
+
line-height: var(--cx-line-height-code-small);
|
|
76
|
+
white-space: pre;
|
|
77
|
+
background-color: transparent;
|
|
78
|
+
border: 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
pre code {
|
|
82
|
+
color: var(--cx-fg-color); // Effectively the base text color
|
|
83
|
+
word-wrap: normal;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.cxd-example-snippet .highlight pre {
|
|
88
|
+
margin-right: 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.highlight-toolbar {
|
|
92
|
+
background-color: var(--cxd-pre-bg, var(--cx-bg-even));
|
|
93
|
+
border-top: var(--cx-border-width) var(--cx-border-style) var(--cx-border-subtle);
|
|
94
|
+
border-bottom: var(--cx-border-width) var(--cx-border-style) var(--cx-border-subtle);
|
|
95
|
+
|
|
96
|
+
+ .highlight {
|
|
97
|
+
@include border-top-radius(0);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
> a {
|
|
101
|
+
@include font-size(var(--cx-font-size-small));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.cxd-file-ref {
|
|
106
|
+
.highlight-toolbar {
|
|
107
|
+
border-top: 0;
|
|
108
|
+
@include media-breakpoint-up(medium) {
|
|
109
|
+
@include border-top-radius(calc(var(--cx-border-radius) - 1px));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.cxd-content .cxd-code-snippet {
|
|
115
|
+
margin-bottom: 1rem;
|
|
116
|
+
}
|