@writedocs/generator 0.4.8 → 0.4.10
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/astro.config.mjs +45 -2
- package/bin/writedocs.js +190 -139
- package/package.json +2 -1
- package/src/cli/convert.js +82 -0
- package/src/cli/generate-api-pages.js +56 -3
- package/src/components/Accordion.astro +2 -1
- package/src/components/AccordionGroup.astro +4 -1
- package/src/components/ApiPlayground.astro +6 -2
- package/src/components/ApiReferencePanel.astro +6 -2
- package/src/components/AppIcon.astro +14 -2
- package/src/components/Badge.astro +2 -0
- package/src/components/Callout.astro +2 -1
- package/src/components/Card.astro +2 -1
- package/src/components/CardGroup.astro +2 -1
- package/src/components/Check.astro +1 -1
- package/src/components/CodeBlock.astro +94 -0
- package/src/components/CodeGroup.astro +2 -1
- package/src/components/Color.astro +2 -1
- package/src/components/ColorItem.astro +2 -1
- package/src/components/ColorRow.astro +2 -1
- package/src/components/Column.astro +19 -0
- package/src/components/Columns.astro +1 -1
- package/src/components/Danger.astro +1 -1
- package/src/components/Expandable.astro +2 -1
- package/src/components/Frame.astro +2 -1
- package/src/components/GitHubRepo.astro +2 -1
- package/src/components/Hint.astro +2 -1
- package/src/components/Icon.astro +3 -2
- package/src/components/Image.astro +2 -1
- package/src/components/Info.astro +1 -1
- package/src/components/Note.astro +1 -1
- package/src/components/Panel.astro +2 -1
- package/src/components/Parameter.astro +2 -1
- package/src/components/Prompt.astro +2 -1
- package/src/components/RequestExample.astro +2 -1
- package/src/components/ResponseExample.astro +2 -1
- package/src/components/Searchbar.astro +2 -1
- package/src/components/Step.astro +2 -1
- package/src/components/Steps.astro +4 -1
- package/src/components/Tab.astro +2 -1
- package/src/components/Tabs.astro +2 -1
- package/src/components/Tile.astro +2 -1
- package/src/components/Tip.astro +1 -1
- package/src/components/TreeFile.astro +2 -1
- package/src/components/TreeFolder.astro +2 -1
- package/src/components/Update.astro +2 -1
- package/src/components/Video.astro +2 -1
- package/src/components/View.astro +2 -1
- package/src/components/Warning.astro +1 -1
- package/src/components/class-names.ts +8 -0
- package/src/components/index.ts +2 -0
- package/src/content.config.ts +29 -129
- package/src/lib/config-schema.js +124 -0
- package/src/lib/config-schema.ts +1574 -1437
- package/src/lib/config.ts +7 -140
- package/src/lib/content-check.js +262 -0
- package/src/lib/icons.js +109 -0
- package/src/lib/mdx-auto-hydrate.js +12 -0
- package/src/lib/mdx-inject-builtins.js +16 -1
- package/src/lib/mdx-inline-react.js +202 -0
- package/src/lib/mdx-mintlify.js +65 -0
- package/src/lib/mdx-substitute-variables.js +17 -0
- package/src/lib/mdx-unknown-components.js +149 -0
- package/src/lib/mintlify-convert.js +599 -0
- package/src/lib/openapi-ref.js +44 -0
- package/src/lib/openapi-render.ts +10 -1
- package/src/lib/pages.js +150 -0
- package/src/pages/[...slug].astro +8 -2
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
findOperationFile,
|
|
16
16
|
type OpenApiOperation,
|
|
17
17
|
} from '../lib/openapi-render';
|
|
18
|
+
import { parseOpenApiRef } from '../lib/openapi-ref.js';
|
|
18
19
|
import { loadDocsConfig, resolveCodeblockTheme } from '../lib/config';
|
|
19
20
|
import ApiLangSelect from './ApiLangSelect.astro';
|
|
20
21
|
|
|
@@ -64,8 +65,11 @@ const SNIPPET_THEMES = resolveCodeblockTheme(docsConfig);
|
|
|
64
65
|
// writedocs' CORS proxy - see PROXY_BASE_URL in the <script> below.
|
|
65
66
|
const proxyEnabled = docsConfig.api.proxy;
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
const
|
|
68
|
+
// "METHOD /path", or Mintlify's "spec.json METHOD /path" - see lib/openapi-ref.js.
|
|
69
|
+
const ref = parseOpenApiRef(operation);
|
|
70
|
+
const method = ref?.method ?? '';
|
|
71
|
+
const urlPath = ref?.path ?? '';
|
|
72
|
+
const opFile = ref ? findOperationFile(contentDir, method, urlPath, ref.spec) : null;
|
|
69
73
|
const op: OpenApiOperation | null = opFile ? JSON.parse(fs.readFileSync(opFile, 'utf-8')) : null;
|
|
70
74
|
|
|
71
75
|
// ApiPlayground.astro (rendered in the article column) already shows a
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// and Card.astro (the two places writedocs.json icon strings get rendered)
|
|
8
8
|
// don't each need their own copy of the resolveIcon() call + branch.
|
|
9
9
|
import { Icon } from 'astro-icon/components';
|
|
10
|
-
import { resolveIcon } from '../lib/config';
|
|
10
|
+
import { resolveIcon, iconExists } from '../lib/config';
|
|
11
11
|
|
|
12
12
|
interface Props {
|
|
13
13
|
icon?: string;
|
|
@@ -21,7 +21,19 @@ interface Props {
|
|
|
21
21
|
style?: string;
|
|
22
22
|
}
|
|
23
23
|
const { icon, class: className = 'wd-icon', style } = Astro.props as Props;
|
|
24
|
-
|
|
24
|
+
// An icon name no installed collection has renders nothing, with a warning
|
|
25
|
+
// (once per name - a sidebar icon renders on every page), instead of
|
|
26
|
+
// failing the whole build the way astro-icon does on a missing name.
|
|
27
|
+
// `writedocs validate` lists the same names ahead of time.
|
|
28
|
+
let resolved = icon ? resolveIcon(icon) : null;
|
|
29
|
+
if (icon && resolved?.kind === 'iconify' && !iconExists(icon)) {
|
|
30
|
+
const warned: Set<string> = ((globalThis as any).__wdWarnedIcons ??= new Set());
|
|
31
|
+
if (!warned.has(icon)) {
|
|
32
|
+
warned.add(icon);
|
|
33
|
+
console.warn(`[writedocs] unknown icon "${icon}" - no installed icon set has it, so it's left out.`);
|
|
34
|
+
}
|
|
35
|
+
resolved = null;
|
|
36
|
+
}
|
|
25
37
|
---
|
|
26
38
|
{resolved && (
|
|
27
39
|
resolved.kind === 'iconify' ? (
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// A small inline label - status indicators, version tags, "Beta"/"New"
|
|
3
4
|
// markers - modeled on Mintlify's own Badge
|
|
4
5
|
// (https://www.mintlify.com/docs/components/badge). Renders as an
|
|
@@ -42,6 +43,7 @@ const shapeClass = shape === 'pill' ? 'pill' : 'rounded';
|
|
|
42
43
|
`wd-badge-${shapeClass}`,
|
|
43
44
|
stroke && 'wd-badge-stroke',
|
|
44
45
|
disabled && 'wd-badge-disabled',
|
|
46
|
+
extraClasses(Astro.props),
|
|
45
47
|
]}
|
|
46
48
|
>
|
|
47
49
|
{icon && <AppIcon icon={icon} class="wd-badge-icon" />}<slot />
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// See src/components/{Note,Tip,Warning,Danger,Info,Check}.astro - one thin
|
|
3
4
|
// wrapper per `type` below, each just `<Callout type="x">` under the
|
|
4
5
|
// hood, so a page can write either `<Callout type="info">` or the
|
|
@@ -51,7 +52,7 @@ function slugify(value: string): string {
|
|
|
51
52
|
const titleId = title ? (_titleId ?? slugify(title)) : undefined;
|
|
52
53
|
---
|
|
53
54
|
|
|
54
|
-
<div class:list={["wd-callout", `wd-callout-${type}`, { "wd-callout-titled": Boolean(title) }]} style={accentStyle}>
|
|
55
|
+
<div class:list={["wd-callout", `wd-callout-${type}`, { "wd-callout-titled": Boolean(title) }, extraClasses(Astro.props)]} style={accentStyle}>
|
|
55
56
|
<AppIcon icon={icon ?? icons[type]} class="wd-callout-icon" />
|
|
56
57
|
<div class="wd-callout-content">
|
|
57
58
|
{
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
import AppIcon from './AppIcon.astro';
|
|
3
4
|
|
|
4
5
|
// Three visual variants, chosen by which optional prop is set - never more
|
|
@@ -42,7 +43,7 @@ const KNOWN_METHODS = ['get', 'post', 'put', 'patch', 'delete'];
|
|
|
42
43
|
const methodLower = method?.toLowerCase();
|
|
43
44
|
const methodClass = methodLower && KNOWN_METHODS.includes(methodLower) ? methodLower : 'other';
|
|
44
45
|
---
|
|
45
|
-
<Tag class:list={['wd-card', { 'wd-card-horizontal': horizontal, 'wd-card-has-arrow': arrow && href }]} href={href}>
|
|
46
|
+
<Tag class:list={['wd-card', { 'wd-card-horizontal': horizontal, 'wd-card-has-arrow': arrow && href }, extraClasses(Astro.props)]} href={href}>
|
|
46
47
|
{img && <img src={img} alt="" class="wd-card-image" />}
|
|
47
48
|
{!img && <AppIcon icon={icon} class="wd-card-icon" style={iconStyle} />}
|
|
48
49
|
<div class="wd-card-text">
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
interface Props {
|
|
3
4
|
cols?: number;
|
|
4
5
|
}
|
|
5
6
|
const { cols = 2 } = Astro.props as Props;
|
|
6
7
|
---
|
|
7
|
-
<div class="wd-card-group" style={`--wd-cols: ${cols}`}>
|
|
8
|
+
<div class:list={["wd-card-group", extraClasses(Astro.props)]} style={`--wd-cols: ${cols}`}>
|
|
8
9
|
<slot />
|
|
9
10
|
</div>
|
|
10
11
|
<style>
|
|
@@ -10,4 +10,4 @@ interface Props {
|
|
|
10
10
|
}
|
|
11
11
|
const { title, _titleId } = Astro.props as Props;
|
|
12
12
|
---
|
|
13
|
-
<Callout type="check" title={title} _titleId={_titleId}><slot /></Callout>
|
|
13
|
+
<Callout type="check" title={title} _titleId={_titleId} class={Astro.props.class} className={Astro.props.className}><slot /></Callout>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
// Mintlify's <CodeBlock> - a code block from props instead of a ``` fence,
|
|
3
|
+
// for code a page builds up in a component. Renders through the same Shiki
|
|
4
|
+
// setup and the same writedocs:code-block transformer as a fenced block
|
|
5
|
+
// (see astro.config.mjs's markdown.shikiConfig), so title, icon, line
|
|
6
|
+
// numbers, wrap, copy button, expandable, highlight and focus all look and
|
|
7
|
+
// behave the same.
|
|
8
|
+
//
|
|
9
|
+
// The code is the component's children (or a `code` prop). Mintlify's
|
|
10
|
+
// `highlight`/`focus` are stringified arrays ("[1,3,4]"); ranges like
|
|
11
|
+
// "1-3" work too.
|
|
12
|
+
import { Code } from 'astro:components';
|
|
13
|
+
import { extraClasses } from './class-names';
|
|
14
|
+
import {
|
|
15
|
+
transformerMetaHighlight,
|
|
16
|
+
transformerMetaWordHighlight,
|
|
17
|
+
transformerNotationHighlight,
|
|
18
|
+
transformerNotationWordHighlight,
|
|
19
|
+
transformerNotationFocus,
|
|
20
|
+
transformerNotationDiff,
|
|
21
|
+
transformerNotationErrorLevel,
|
|
22
|
+
} from '@shikijs/transformers';
|
|
23
|
+
import { codeBlockTransformer } from '../lib/shiki-code-block.js';
|
|
24
|
+
import { loadDocsConfig, resolveCodeblockTheme } from '../lib/config';
|
|
25
|
+
|
|
26
|
+
interface Props {
|
|
27
|
+
language?: string;
|
|
28
|
+
filename?: string;
|
|
29
|
+
icon?: string;
|
|
30
|
+
lines?: boolean;
|
|
31
|
+
wrap?: boolean;
|
|
32
|
+
nocopy?: boolean;
|
|
33
|
+
expandable?: boolean;
|
|
34
|
+
highlight?: string | number[];
|
|
35
|
+
focus?: string | number[];
|
|
36
|
+
code?: string;
|
|
37
|
+
}
|
|
38
|
+
const { language = 'text', filename, icon, lines, wrap, nocopy, expandable, highlight, focus, code: codeProp } = Astro.props as Props;
|
|
39
|
+
|
|
40
|
+
// Slot content arrives as rendered HTML text - undo its entity escaping.
|
|
41
|
+
function unescape(html: string): string {
|
|
42
|
+
return html
|
|
43
|
+
.replace(/<[^>]+>/g, '')
|
|
44
|
+
.replace(/</g, '<')
|
|
45
|
+
.replace(/>/g, '>')
|
|
46
|
+
.replace(/"/g, '"')
|
|
47
|
+
.replace(/'/g, "'")
|
|
48
|
+
.replace(/'/g, "'")
|
|
49
|
+
.replace(/&/g, '&');
|
|
50
|
+
}
|
|
51
|
+
const code = (codeProp ?? unescape(await Astro.slots.render('default'))).replace(/^\n+|\s+$/g, '');
|
|
52
|
+
|
|
53
|
+
const ranges = (value: string | number[] | undefined) =>
|
|
54
|
+
value === undefined ? '' : (Array.isArray(value) ? value.join(',') : String(value).replace(/[\[\]\s]/g, ''));
|
|
55
|
+
const quoted = (value: string) => `"${value.replace(/"/g, "'")}"`;
|
|
56
|
+
const meta = [
|
|
57
|
+
filename ? `title=${quoted(filename)}` : '',
|
|
58
|
+
icon ? `icon=${quoted(icon)}` : '',
|
|
59
|
+
lines ? 'lines' : '',
|
|
60
|
+
wrap ? 'wrap' : '',
|
|
61
|
+
nocopy ? 'nocopy' : '',
|
|
62
|
+
expandable ? 'expandable' : '',
|
|
63
|
+
ranges(highlight) ? `highlight={${ranges(highlight)}}` : '',
|
|
64
|
+
ranges(focus) ? `focus={${ranges(focus)}}` : '',
|
|
65
|
+
]
|
|
66
|
+
.filter(Boolean)
|
|
67
|
+
.join(' ');
|
|
68
|
+
|
|
69
|
+
const contentDir = process.env.WRITEDOCS_CONTENT_DIR || process.cwd();
|
|
70
|
+
const themes = resolveCodeblockTheme(loadDocsConfig(contentDir));
|
|
71
|
+
const transformers = [
|
|
72
|
+
transformerMetaHighlight(),
|
|
73
|
+
transformerMetaWordHighlight(),
|
|
74
|
+
transformerNotationHighlight(),
|
|
75
|
+
transformerNotationWordHighlight(),
|
|
76
|
+
transformerNotationFocus(),
|
|
77
|
+
transformerNotationDiff(),
|
|
78
|
+
transformerNotationErrorLevel(),
|
|
79
|
+
codeBlockTransformer(),
|
|
80
|
+
];
|
|
81
|
+
const extras = extraClasses(Astro.props);
|
|
82
|
+
---
|
|
83
|
+
{
|
|
84
|
+
// The block's own root (.wd-code-block) is built by the Shiki transformer,
|
|
85
|
+
// so `className`/`class` goes on a wrapper around it - only when given, so
|
|
86
|
+
// a plain CodeBlock renders exactly like a fenced block.
|
|
87
|
+
extras.length > 0 ? (
|
|
88
|
+
<div class:list={extras}>
|
|
89
|
+
<Code code={code} lang={language as any} meta={meta} themes={themes} transformers={transformers} />
|
|
90
|
+
</div>
|
|
91
|
+
) : (
|
|
92
|
+
<Code code={code} lang={language as any} meta={meta} themes={themes} transformers={transformers} />
|
|
93
|
+
)
|
|
94
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// `dropdown` is only ever passed down from RequestExample/
|
|
3
4
|
// ResponseExample.astro today (CodeGroup itself is never used with it
|
|
4
5
|
// directly in any fixture/doc) - kept as a real prop rather than a
|
|
@@ -9,7 +10,7 @@ interface Props {
|
|
|
9
10
|
}
|
|
10
11
|
const { dropdown = false } = Astro.props as Props;
|
|
11
12
|
---
|
|
12
|
-
<div class="wd-codegroup" data-dropdown={dropdown ? "true" : undefined}>
|
|
13
|
+
<div class:list={["wd-codegroup", extraClasses(Astro.props)]} data-dropdown={dropdown ? "true" : undefined}>
|
|
13
14
|
<slot />
|
|
14
15
|
</div>
|
|
15
16
|
<script>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Mintlify's <Color> - a palette of <Color.Item> swatches. `variant`:
|
|
3
4
|
// compact (default) - one grid of swatches.
|
|
4
5
|
// table - <Color.Row title="..."> rows, each a titled line of
|
|
@@ -10,7 +11,7 @@ interface Props {
|
|
|
10
11
|
}
|
|
11
12
|
const { variant = 'compact' } = Astro.props as Props;
|
|
12
13
|
---
|
|
13
|
-
<div class:list={['wd-color', `wd-color-${variant}
|
|
14
|
+
<div class:list={['wd-color', `wd-color-${variant}`, extraClasses(Astro.props)]}><slot /></div>
|
|
14
15
|
<script>
|
|
15
16
|
// Click (or Enter/Space) on a swatch copies the value currently shown -
|
|
16
17
|
// for a light/dark pair, the one matching the site's theme right now.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Mintlify's <Color.Item name="..." value="..."> - one swatch. `value` is
|
|
3
4
|
// any CSS color, or { light, dark } for a theme-aware pair: the swatch and
|
|
4
5
|
// the value text switch with the site's theme toggle ([data-theme] on
|
|
@@ -15,7 +16,7 @@ const themed = typeof value === 'object' && value !== null && light !== dark;
|
|
|
15
16
|
const style = light ? `--wd-swatch-light: ${light}; --wd-swatch-dark: ${dark ?? light}` : undefined;
|
|
16
17
|
---
|
|
17
18
|
<div
|
|
18
|
-
class=
|
|
19
|
+
class:list={['wd-color-item', extraClasses(Astro.props)]}
|
|
19
20
|
data-light={light}
|
|
20
21
|
data-dark={dark}
|
|
21
22
|
role={light ? 'button' : undefined}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Mintlify's <Color.Row title="..."> - one titled row inside
|
|
3
4
|
// <Color variant="table">. `title` takes inline Markdown.
|
|
4
5
|
import { inlineMarkdown } from '../lib/inline-markdown.js';
|
|
@@ -7,7 +8,7 @@ interface Props {
|
|
|
7
8
|
}
|
|
8
9
|
const { title } = Astro.props as Props;
|
|
9
10
|
---
|
|
10
|
-
<div class=
|
|
11
|
+
<div class:list={['wd-color-row', extraClasses(Astro.props)]}>
|
|
11
12
|
<div class="wd-color-row-title" set:html={inlineMarkdown(title ?? '')} />
|
|
12
13
|
<div class="wd-color-row-items"><slot /></div>
|
|
13
14
|
</div>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
3
|
+
// Mintlify's <Column> - one cell of a <Columns> grid, for arbitrary content
|
|
4
|
+
// (text, a code block) side by side rather than Cards. Just a grid item:
|
|
5
|
+
// <Columns>/CardGroup.astro lays its children out, this only keeps the
|
|
6
|
+
// cell's content together and trims the outer margins of what's inside.
|
|
7
|
+
---
|
|
8
|
+
<div class:list={['wd-column', extraClasses(Astro.props)]}><slot /></div>
|
|
9
|
+
<style>
|
|
10
|
+
.wd-column {
|
|
11
|
+
min-width: 0;
|
|
12
|
+
}
|
|
13
|
+
.wd-column > :global(:first-child) {
|
|
14
|
+
margin-top: 0;
|
|
15
|
+
}
|
|
16
|
+
.wd-column > :global(:last-child) {
|
|
17
|
+
margin-bottom: 0;
|
|
18
|
+
}
|
|
19
|
+
</style>
|
|
@@ -9,4 +9,4 @@ interface Props {
|
|
|
9
9
|
}
|
|
10
10
|
const { title, _titleId } = Astro.props as Props;
|
|
11
11
|
---
|
|
12
|
-
<Callout type="danger" title={title} _titleId={_titleId}><slot /></Callout>
|
|
12
|
+
<Callout type="danger" title={title} _titleId={_titleId} class={Astro.props.class} className={Astro.props.className}><slot /></Callout>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// The collapsible "Show/Hide properties" wrapper that pairs with
|
|
3
4
|
// Parameter for nested object properties - modeled directly on
|
|
4
5
|
// Mintlify's own Expandable (https://www.mintlify.com/docs/components/
|
|
@@ -25,7 +26,7 @@ interface Props {
|
|
|
25
26
|
const { title = "properties", defaultOpen = true } = Astro.props as Props;
|
|
26
27
|
---
|
|
27
28
|
|
|
28
|
-
<details class="wd-expandable" open={defaultOpen}>
|
|
29
|
+
<details class:list={["wd-expandable", extraClasses(Astro.props)]} open={defaultOpen}>
|
|
29
30
|
<summary>
|
|
30
31
|
<svg class="wd-expandable-chevron" width="11" height="11" viewBox="0 0 10 10" aria-hidden="true">
|
|
31
32
|
<path
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// A generic "put a rounded, bordered card around this" wrapper -
|
|
3
4
|
// deliberately different from Image (a specific <img> with its own
|
|
4
5
|
// src/srcDark/size handling): Frame wraps *arbitrary* slot content - a
|
|
@@ -21,7 +22,7 @@ interface Props {
|
|
|
21
22
|
const { caption, hint } = Astro.props as Props;
|
|
22
23
|
---
|
|
23
24
|
|
|
24
|
-
<figure class="wd-frame">
|
|
25
|
+
<figure class:list={["wd-frame", extraClasses(Astro.props)]}>
|
|
25
26
|
{hint && <p class="wd-frame-hint">{hint}</p>}
|
|
26
27
|
<div class="wd-frame-content">
|
|
27
28
|
<slot />
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Mintlify's <GitHub.Repo repo="owner/name" variant="inset|flat"> - a card
|
|
3
4
|
// linking to a public GitHub repository. Attached as GitHub.Repo in
|
|
4
5
|
// components/compound.ts. `repo` is an "owner/name" slug or a full
|
|
@@ -27,7 +28,7 @@ const valid = /^[\w.-]+\/[\w.-]+$/.test(slug);
|
|
|
27
28
|
---
|
|
28
29
|
{valid && (
|
|
29
30
|
<a
|
|
30
|
-
class:list={['wd-github-repo', `wd-github-repo-${variant}
|
|
31
|
+
class:list={['wd-github-repo', `wd-github-repo-${variant}`, extraClasses(Astro.props)]}
|
|
31
32
|
href={`https://github.com/${slug}`}
|
|
32
33
|
target="_blank"
|
|
33
34
|
rel="noopener noreferrer"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Inline, text-level component - unlike every other built-in here
|
|
3
4
|
// (Callout, Card, Accordion, ...), which are all block-level and get
|
|
4
5
|
// their own line, a Hint sits mid-sentence: `word <Hint tip="...">this
|
|
@@ -28,7 +29,7 @@ const { tip, headline, cta, href } = Astro.props as Props;
|
|
|
28
29
|
const hasLink = Boolean(cta && href);
|
|
29
30
|
---
|
|
30
31
|
|
|
31
|
-
<span class:list={["wd-hint", { "wd-hint-rich": Boolean(headline) || hasLink }]} tabindex="0">
|
|
32
|
+
<span class:list={["wd-hint", { "wd-hint-rich": Boolean(headline) || hasLink }, extraClasses(Astro.props)]} tabindex="0">
|
|
32
33
|
<span class="wd-hint-trigger"><slot /></span>
|
|
33
34
|
<span class="wd-hint-tooltip" role="tooltip">
|
|
34
35
|
{headline && <span class="wd-hint-headline">{headline}</span>}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Renders either a real icon (via `icon`) or a custom image (via
|
|
3
4
|
// `src`) inline with surrounding text - modeled on Mintlify's own Icon
|
|
4
5
|
// (https://www.mintlify.com/docs/components/icons), which documents
|
|
@@ -42,9 +43,9 @@ const iconStyle =
|
|
|
42
43
|
|
|
43
44
|
{
|
|
44
45
|
src ? (
|
|
45
|
-
<img src={src} alt={alt} class="wd-icon-image" style={`height:${height}`} />
|
|
46
|
+
<img src={src} alt={alt} class:list={["wd-icon-image", extraClasses(Astro.props)]} style={`height:${height}`} />
|
|
46
47
|
) : icon ? (
|
|
47
|
-
<AppIcon icon={icon} class="wd-icon-inline" style={iconStyle} />
|
|
48
|
+
<AppIcon icon={icon} class={["wd-icon-inline", ...extraClasses(Astro.props)].join(" ")} style={iconStyle} />
|
|
48
49
|
) : null
|
|
49
50
|
}
|
|
50
51
|
<style>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Block-level (own line, centered) - unlike Hint (inline/text-level),
|
|
3
4
|
// this is meant to be dropped in on its own the way Callout/Card are.
|
|
4
5
|
//
|
|
@@ -65,7 +66,7 @@ const sizeStyle = size ? `--wd-image-size:${size}` : undefined;
|
|
|
65
66
|
---
|
|
66
67
|
|
|
67
68
|
<figure
|
|
68
|
-
class:list={["wd-image-figure", caption && "wd-image-figure-framed", srcDark && "wd-image-has-dark"]}
|
|
69
|
+
class:list={["wd-image-figure", caption && "wd-image-figure-framed", srcDark && "wd-image-has-dark", extraClasses(Astro.props)]}
|
|
69
70
|
style={sizeStyle}
|
|
70
71
|
>
|
|
71
72
|
<img src={src} alt={alt} class="wd-image wd-image-light" nozoom={noZoom || undefined} />
|
|
@@ -9,4 +9,4 @@ interface Props {
|
|
|
9
9
|
}
|
|
10
10
|
const { title, _titleId } = Astro.props as Props;
|
|
11
11
|
---
|
|
12
|
-
<Callout type="info" title={title} _titleId={_titleId}><slot /></Callout>
|
|
12
|
+
<Callout type="info" title={title} _titleId={_titleId} class={Astro.props.class} className={Astro.props.className}><slot /></Callout>
|
|
@@ -9,4 +9,4 @@ interface Props {
|
|
|
9
9
|
}
|
|
10
10
|
const { title, _titleId } = Astro.props as Props;
|
|
11
11
|
---
|
|
12
|
-
<Callout type="note" title={title} _titleId={_titleId}><slot /></Callout>
|
|
12
|
+
<Callout type="note" title={title} _titleId={_titleId} class={Astro.props.class} className={Astro.props.className}><slot /></Callout>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Mintlify's <Panel> - content pinned to the right-hand column on desktop,
|
|
3
4
|
// in place of the table of contents. It's the same docking
|
|
4
5
|
// RequestExample/ResponseExample already use (initExamplePanels() in
|
|
@@ -8,4 +9,4 @@
|
|
|
8
9
|
// with no table-of-contents column (any mode but `default`), the Panel
|
|
9
10
|
// stays where it is in the page.
|
|
10
11
|
---
|
|
11
|
-
<div class="wd-example-panel wd-panel"><slot /></div>
|
|
12
|
+
<div class:list={["wd-example-panel wd-panel", extraClasses(Astro.props)]}><slot /></div>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// The name+type+description row used throughout API reference content -
|
|
3
4
|
// modeled directly on Mintlify's own ParamField/ResponseField
|
|
4
5
|
// (https://www.mintlify.com/docs/components/expandables), which this
|
|
@@ -38,7 +39,7 @@ const { name, type, required = false, default: defaultValue, deprecated = false,
|
|
|
38
39
|
const hasDefault = defaultValue !== undefined && defaultValue !== null && defaultValue !== "";
|
|
39
40
|
---
|
|
40
41
|
|
|
41
|
-
<div class:list={["wd-parameter", { "wd-parameter-deprecated": deprecated }]}>
|
|
42
|
+
<div class:list={["wd-parameter", { "wd-parameter-deprecated": deprecated }, extraClasses(Astro.props)]}>
|
|
42
43
|
<div class="wd-parameter-head">
|
|
43
44
|
{pre.map((label) => <span class="wd-parameter-label">{label}</span>)}
|
|
44
45
|
<span class="wd-parameter-name">{name}</span>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Mintlify's <Prompt> - a ready-made AI prompt: a card showing
|
|
3
4
|
// `description` (inline Markdown) and an optional icon, with actions to
|
|
4
5
|
// copy the prompt or open it in Cursor. The prompt itself is the slot; it's
|
|
@@ -27,7 +28,7 @@ const { description, icon, actions = ['copy'], _text } = Astro.props as Props;
|
|
|
27
28
|
const cursorHref = _text ? `https://cursor.com/link/prompt?text=${encodeURIComponent(_text)}` : null;
|
|
28
29
|
const showCursor = actions.includes('cursor') && cursorHref !== null && cursorHref.length <= 10000;
|
|
29
30
|
---
|
|
30
|
-
<div class="wd-prompt">
|
|
31
|
+
<div class:list={["wd-prompt", extraClasses(Astro.props)]}>
|
|
31
32
|
<div class="wd-prompt-head">
|
|
32
33
|
{icon && <AppIcon icon={icon} class="wd-prompt-icon" />}
|
|
33
34
|
{description && <div class="wd-prompt-description" set:html={inlineMarkdown(description)} />}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Pins its code example(s) in the right sidebar - in place of the page's
|
|
3
4
|
// normal table of contents - on desktop; falls back to a plain in-place
|
|
4
5
|
// CodeGroup on narrower viewports where that sidebar column doesn't
|
|
@@ -26,7 +27,7 @@ interface Props {
|
|
|
26
27
|
}
|
|
27
28
|
const { dropdown = false } = Astro.props as Props;
|
|
28
29
|
---
|
|
29
|
-
<div class="wd-example-panel wd-request-example">
|
|
30
|
+
<div class:list={["wd-example-panel wd-request-example", extraClasses(Astro.props)]}>
|
|
30
31
|
<CodeGroup dropdown={dropdown}>
|
|
31
32
|
<slot />
|
|
32
33
|
</CodeGroup>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// See RequestExample.astro's own comment - identical in every respect
|
|
3
4
|
// except the marker class (wd-response-example vs wd-request-example),
|
|
4
5
|
// which src/scripts/example-panels.ts uses to always dock Response
|
|
@@ -12,7 +13,7 @@ interface Props {
|
|
|
12
13
|
}
|
|
13
14
|
const { dropdown = false } = Astro.props as Props;
|
|
14
15
|
---
|
|
15
|
-
<div class="wd-example-panel wd-response-example">
|
|
16
|
+
<div class:list={["wd-example-panel wd-response-example", extraClasses(Astro.props)]}>
|
|
16
17
|
<CodeGroup dropdown={dropdown}>
|
|
17
18
|
<slot />
|
|
18
19
|
</CodeGroup>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Wraps a GFM table (or any other block-level slot content, though a
|
|
3
4
|
// table is the intended/primary use case) with a text input above it
|
|
4
5
|
// that live-filters rows by their own text content - "let users filter
|
|
@@ -21,7 +22,7 @@ interface Props {
|
|
|
21
22
|
const { placeholder = "Search..." } = Astro.props as Props;
|
|
22
23
|
---
|
|
23
24
|
|
|
24
|
-
<div class="wd-searchbar">
|
|
25
|
+
<div class:list={["wd-searchbar", extraClasses(Astro.props)]}>
|
|
25
26
|
<input type="text" class="wd-searchbar-input" placeholder={placeholder} aria-label={placeholder} />
|
|
26
27
|
<div class="wd-searchbar-content">
|
|
27
28
|
<slot />
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
import AppIcon from './AppIcon.astro';
|
|
3
4
|
// `icon`, `stepNumber` and `titleSize` are Mintlify's. `icon` replaces the
|
|
4
5
|
// number in the step's circle. `stepNumber` sets this step's number; the
|
|
@@ -15,7 +16,7 @@ const { title, icon, stepNumber, titleSize = 'p' } = Astro.props as Props;
|
|
|
15
16
|
const style = typeof stepNumber === 'number' ? `counter-set: wd-step ${stepNumber - 1}` : undefined;
|
|
16
17
|
const TitleTag = titleSize === 'h2' || titleSize === 'h3' ? titleSize : 'p';
|
|
17
18
|
---
|
|
18
|
-
<div class:list={['wd-step', { 'wd-step-has-icon': Boolean(icon) }]} style={style}>
|
|
19
|
+
<div class:list={['wd-step', { 'wd-step-has-icon': Boolean(icon) }, extraClasses(Astro.props)]} style={style}>
|
|
19
20
|
{icon && <AppIcon icon={icon} class="wd-step-icon" />}
|
|
20
21
|
{
|
|
21
22
|
title &&
|
package/src/components/Tab.astro
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
import AppIcon from './AppIcon.astro';
|
|
3
4
|
// `icon` is Mintlify's: shown before the title in the tab's button. The
|
|
4
5
|
// button is built client-side by Tabs.astro, which moves this hidden,
|
|
@@ -9,7 +10,7 @@ interface Props {
|
|
|
9
10
|
}
|
|
10
11
|
const { title, icon } = Astro.props as Props;
|
|
11
12
|
---
|
|
12
|
-
<div class="wd-tab" data-title={title}>
|
|
13
|
+
<div class:list={["wd-tab", extraClasses(Astro.props)]} data-title={title}>
|
|
13
14
|
{icon && <span class="wd-tab-icon-src" hidden><AppIcon icon={icon} class="wd-tabs-btn-icon" /></span>}
|
|
14
15
|
<slot />
|
|
15
16
|
</div>
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// `defaultTabIndex` is Mintlify's: which tab (0-based) starts selected.
|
|
3
4
|
interface Props {
|
|
4
5
|
defaultTabIndex?: number;
|
|
5
6
|
}
|
|
6
7
|
const { defaultTabIndex = 0 } = Astro.props as Props;
|
|
7
8
|
---
|
|
8
|
-
<div class="wd-tabs" data-default-index={defaultTabIndex}>
|
|
9
|
+
<div class:list={["wd-tabs", extraClasses(Astro.props)]} data-default-index={defaultTabIndex}>
|
|
9
10
|
<slot />
|
|
10
11
|
</div>
|
|
11
12
|
<script>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Mintlify's <Tile> - a visual preview (the slot, usually an image or a
|
|
3
4
|
// light/dark image pair) on a patterned background, with a title and
|
|
4
5
|
// description under it. Usually laid out in a <Columns> grid. `title`
|
|
@@ -13,7 +14,7 @@ interface Props {
|
|
|
13
14
|
const { href, title, description } = Astro.props as Props;
|
|
14
15
|
const Tag = href ? 'a' : 'div';
|
|
15
16
|
---
|
|
16
|
-
<Tag class="wd-tile" href={href}>
|
|
17
|
+
<Tag class:list={["wd-tile", extraClasses(Astro.props)]} href={href}>
|
|
17
18
|
<div class="wd-tile-preview"><slot /></div>
|
|
18
19
|
{title && <div class="wd-tile-title" set:html={inlineMarkdown(title)} />}
|
|
19
20
|
{description && <div class="wd-tile-description">{description}</div>}
|
package/src/components/Tip.astro
CHANGED
|
@@ -9,4 +9,4 @@ interface Props {
|
|
|
9
9
|
}
|
|
10
10
|
const { title, _titleId } = Astro.props as Props;
|
|
11
11
|
---
|
|
12
|
-
<Callout type="tip" title={title} _titleId={_titleId}><slot /></Callout>
|
|
12
|
+
<Callout type="tip" title={title} _titleId={_titleId} class={Astro.props.class} className={Astro.props.className}><slot /></Callout>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Mintlify's <Tree.File name="..."> - see Tree.astro. `highlight` marks it
|
|
3
4
|
// as the active item.
|
|
4
5
|
import AppIcon from './AppIcon.astro';
|
|
@@ -8,7 +9,7 @@ interface Props {
|
|
|
8
9
|
}
|
|
9
10
|
const { name, highlight = false } = Astro.props as Props;
|
|
10
11
|
---
|
|
11
|
-
<li class:list={['wd-tree-item', 'wd-tree-file', { 'wd-tree-highlight': highlight }]} role="treeitem" tabindex="-1">
|
|
12
|
+
<li class:list={['wd-tree-item', 'wd-tree-file', { 'wd-tree-highlight': highlight }, extraClasses(Astro.props)]} role="treeitem" tabindex="-1">
|
|
12
13
|
<span class="wd-tree-row">
|
|
13
14
|
<span class="wd-tree-chevron wd-tree-chevron-spacer" aria-hidden="true"></span>
|
|
14
15
|
<AppIcon icon="lucide:file" class="wd-tree-icon" />
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { extraClasses } from './class-names';
|
|
2
3
|
// Mintlify's <Tree.Folder name="..."> - see Tree.astro. `defaultOpen`
|
|
3
4
|
// starts it expanded; `openable={false}` makes it a fixed, non-toggling
|
|
4
5
|
// folder (shown open or closed per `defaultOpen`); `highlight` marks it as
|
|
@@ -13,7 +14,7 @@ interface Props {
|
|
|
13
14
|
const { name, defaultOpen = false, openable = true, highlight = false } = Astro.props as Props;
|
|
14
15
|
---
|
|
15
16
|
<li
|
|
16
|
-
class:list={['wd-tree-item', 'wd-tree-folder', { 'wd-tree-highlight': highlight, 'wd-tree-static': !openable }]}
|
|
17
|
+
class:list={['wd-tree-item', 'wd-tree-folder', { 'wd-tree-highlight': highlight, 'wd-tree-static': !openable }, extraClasses(Astro.props)]}
|
|
17
18
|
role="treeitem"
|
|
18
19
|
aria-expanded={defaultOpen ? 'true' : 'false'}
|
|
19
20
|
tabindex="-1"
|