@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.
Files changed (63) hide show
  1. package/README.md +98 -0
  2. package/index.ts +7 -0
  3. package/package.json +66 -0
  4. package/src/components/DocsSidebar.astro +89 -0
  5. package/src/components/NavDocsMenu.astro +26 -0
  6. package/src/components/NavLink.astro +24 -0
  7. package/src/components/ResponsiveImage.astro +31 -0
  8. package/src/components/TableOfContents.astro +31 -0
  9. package/src/components/ThemeToggler.astro +70 -0
  10. package/src/components/shortcodes/AddedIn.astro +13 -0
  11. package/src/components/shortcodes/Callout.astro +37 -0
  12. package/src/components/shortcodes/CxTable.astro +16 -0
  13. package/src/js/color-modes.js +82 -0
  14. package/src/js/icon-loader.js +220 -0
  15. package/src/js/search.js +58 -0
  16. package/src/js/sidebar.js +30 -0
  17. package/src/js/theme-color.js +126 -0
  18. package/src/layouts/BaseLayout.astro +94 -0
  19. package/src/layouts/DocsLayout.astro +147 -0
  20. package/src/layouts/IconsLayout.astro +19 -0
  21. package/src/layouts/RedirectLayout.astro +23 -0
  22. package/src/layouts/SingleLayout.astro +33 -0
  23. package/src/layouts/footer/Footer.astro +56 -0
  24. package/src/layouts/footer/Scripts.astro +22 -0
  25. package/src/layouts/head/Analytics.astro +22 -0
  26. package/src/layouts/head/Favicons.astro +11 -0
  27. package/src/layouts/head/Head.astro +54 -0
  28. package/src/layouts/head/Scss.astro +9 -0
  29. package/src/layouts/head/Social.astro +38 -0
  30. package/src/layouts/head/Stylesheet.astro +15 -0
  31. package/src/layouts/header/Header.astro +19 -0
  32. package/src/layouts/header/Navigation.astro +121 -0
  33. package/src/layouts/header/Skippy.astro +22 -0
  34. package/src/libs/image.ts +13 -0
  35. package/src/libs/layout.ts +7 -0
  36. package/src/libs/rehype.ts +38 -0
  37. package/src/libs/remark.ts +205 -0
  38. package/src/libs/toc.ts +44 -0
  39. package/src/libs/utils.ts +122 -0
  40. package/src/scss/_anchor.scss +21 -0
  41. package/src/scss/_brand.scss +59 -0
  42. package/src/scss/_buttons.scss +36 -0
  43. package/src/scss/_callouts.scss +40 -0
  44. package/src/scss/_clipboard-js.scss +63 -0
  45. package/src/scss/_code.scss +116 -0
  46. package/src/scss/_colors.scss +140 -0
  47. package/src/scss/_content.scss +141 -0
  48. package/src/scss/_docsearch.scss +174 -0
  49. package/src/scss/_footer.scss +29 -0
  50. package/src/scss/_layout.scss +72 -0
  51. package/src/scss/_masthead.scss +124 -0
  52. package/src/scss/_navbar.scss +138 -0
  53. package/src/scss/_placeholder-img.scss +15 -0
  54. package/src/scss/_scrolling.scss +16 -0
  55. package/src/scss/_settings.scss +37 -0
  56. package/src/scss/_sidebar.scss +161 -0
  57. package/src/scss/_skippy.scss +7 -0
  58. package/src/scss/_syntax.scss +158 -0
  59. package/src/scss/_toc.scss +117 -0
  60. package/src/scss/_variables.scss +78 -0
  61. package/src/scss/fonts.scss +1 -0
  62. package/src/scss/main.scss +90 -0
  63. 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
+ }
@@ -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
+ }