@writedocs/generator 0.4.6 → 0.4.7

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 CHANGED
@@ -131,7 +131,12 @@ function collectNoindexIds(rootContentDir) {
131
131
  for (const relativeId of findAllPages(rootContentDir)) {
132
132
  const file = path.join(rootContentDir, relativeId);
133
133
  const { data } = matter(fs.readFileSync(file, 'utf-8'));
134
- if (!data?.seo?.noindex) continue;
134
+ // Top-level `noindex` is Mintlify's spelling, and a Mintlify `hidden`
135
+ // page is noindexed too - content.config.ts folds both into
136
+ // `seo.noindex` the same way (an explicit value wins).
137
+ // A frontmatter `url` page's route only redirects to that link, so it
138
+ // doesn't belong in the sitemap either.
139
+ if (!(data?.seo?.noindex ?? data?.noindex ?? data?.hidden === true) && !data?.url) continue;
135
140
  const fallbackId = relativeId.replace(/\.mdx?$/i, '').replace(/\/index$/, '');
136
141
  ids.add(normalizeEntryId(data.slug ?? fallbackId));
137
142
  }
@@ -140,7 +145,7 @@ function collectNoindexIds(rootContentDir) {
140
145
  // to the way there is for a hand-written page.
141
146
  for (const file of walkMdFiles(generatedDocsDir)) {
142
147
  const { data } = matter(fs.readFileSync(file, 'utf-8'));
143
- if (data?.seo?.noindex && data.slug) ids.add(normalizeEntryId(data.slug));
148
+ if ((data?.seo?.noindex ?? data?.noindex ?? data?.hidden === true) && data.slug) ids.add(normalizeEntryId(data.slug));
144
149
  }
145
150
  return ids;
146
151
  }
@@ -192,6 +197,25 @@ function singleSitemapFile() {
192
197
  // of only opting into a feature's config surface when it's actually used.
193
198
  const redirectsConfig = Object.fromEntries(docsConfig.redirects.map((r) => [r.source, r.destination]));
194
199
 
200
+ /** Tailwind only scans the Vite root for class names - this package, not
201
+ * the site being built, which is usually somewhere else entirely - so a
202
+ * utility class written in a site's own MDX or snippet (Mintlify content
203
+ * uses them freely, e.g. className="block dark:hidden") never got
204
+ * generated. Appends an @source for the site's content files to
205
+ * global.css before Tailwind compiles it. Forward slashes, since
206
+ * Tailwind reads the path as a glob. */
207
+ function contentTailwindSource() {
208
+ const sourceGlob = `${contentDir.split(path.sep).join('/')}/**/*.{md,mdx,jsx,tsx}`;
209
+ return {
210
+ name: 'writedocs:content-tailwind-source',
211
+ enforce: 'pre',
212
+ transform(code, id) {
213
+ if (!id.split('?')[0].replace(/\\/g, '/').endsWith('/src/styles/global.css')) return null;
214
+ return { code: `${code}\n@source ${JSON.stringify(sourceGlob)};\n`, map: null };
215
+ },
216
+ };
217
+ }
218
+
195
219
  export default defineConfig({
196
220
  ...(siteUrl ? { site: siteUrl } : {}),
197
221
  ...(docsConfig.redirects.length ? { redirects: redirectsConfig } : {}),
@@ -404,7 +428,10 @@ export default defineConfig({
404
428
  // working. See src/styles/global.css for the one @import that wires
405
429
  // Tailwind's utilities in.
406
430
  vite: {
407
- plugins: [tailwindcss()],
431
+ // contentTailwindSource() must come before tailwindcss(): both are
432
+ // enforce: 'pre' transforms, which Vite runs in array order, and
433
+ // Tailwind has to see the added @source when it compiles global.css.
434
+ plugins: [contentTailwindSource(), tailwindcss()],
408
435
  resolve: {
409
436
  alias: [
410
437
  // Lets a page's MDX write `import Foo from '/snippets/foo.mdx'`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@writedocs/generator",
3
- "version": "0.4.6",
3
+ "version": "0.4.7",
4
4
  "description": "Static site generator for docs — a writedocs.json + MDX folder in, a static site out.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -4,6 +4,10 @@ import AppIcon from "./AppIcon.astro";
4
4
  interface Props {
5
5
  title: string;
6
6
  icon?: string;
7
+ // Mintlify parity: `description` is a muted second line under the title,
8
+ // `defaultOpen` renders the accordion already expanded.
9
+ description?: string;
10
+ defaultOpen?: boolean;
7
11
  // Set automatically by remarkTitleAnchorIds (src/lib/mdx-title-anchor-ids.js)
8
12
  // for every <Accordion title="..."> it finds in an .mdx file's own JSX,
9
13
  // already deduped (-2, -3, ...) against every other Accordion/Callout
@@ -14,7 +18,7 @@ interface Props {
14
18
  // title={expr}, or this component used directly from a .astro file).
15
19
  _titleId?: string;
16
20
  }
17
- const { title, icon, _titleId } = Astro.props as Props;
21
+ const { title, icon, description, defaultOpen = false, _titleId } = Astro.props as Props;
18
22
  // Astro's own heading-id slugging (github-slugger, via the markdown
19
23
  // pipeline) never sees this - `title` is a component prop, not a markdown
20
24
  // heading, so it gets no id unless we make one ourselves. Same slugify
@@ -28,13 +32,16 @@ function slugify(value: string): string {
28
32
  const titleId = _titleId ?? slugify(title);
29
33
  ---
30
34
 
31
- <details class="wd-accordion">
35
+ <details class="wd-accordion" open={defaultOpen}>
32
36
  <summary>
33
37
  <span class="wd-accordion-heading">
34
38
  {icon && <AppIcon icon={icon} class="wd-accordion-icon" />}
35
- <span class="wd-accordion-title" id={titleId}>
36
- {title}
37
- <a class="wd-heading-anchor" href={`#${titleId}`} aria-label="Link to this section"> # </a>
39
+ <span class="wd-accordion-text">
40
+ <span class="wd-accordion-title" id={titleId}>
41
+ {title}
42
+ <a class="wd-heading-anchor" href={`#${titleId}`} aria-label="Link to this section"> # </a>
43
+ </span>
44
+ {description && <span class="wd-accordion-description">{description}</span>}
38
45
  </span>
39
46
  </span>
40
47
  {
@@ -128,6 +135,16 @@ const titleId = _titleId ?? slugify(title);
128
135
  flex-shrink: 0;
129
136
  color: var(--wd-text-muted);
130
137
  }
138
+ .wd-accordion-text {
139
+ display: flex;
140
+ flex-direction: column;
141
+ gap: 0.15rem;
142
+ min-width: 0;
143
+ }
144
+ .wd-accordion-description {
145
+ font-size: 0.85rem;
146
+ color: var(--wd-text-muted);
147
+ }
131
148
  .wd-accordion-title {
132
149
  font-weight: 700;
133
150
  color: var(--wd-text);
@@ -26,6 +26,11 @@ const resolved = icon ? resolveIcon(icon) : null;
26
26
  {resolved && (
27
27
  resolved.kind === 'iconify' ? (
28
28
  <Icon name={resolved.name} class={className} style={style} />
29
+ ) : resolved.kind === 'image' ? (
30
+ // Wrapped in the same <span> text icons use, so each caller's own
31
+ // span.<class> rule (font-size, spacing) sizes it; the image fills
32
+ // 1em of that (img.wd-icon-img in layout/styles/base.css).
33
+ <span class={className} style={style}><img src={resolved.src} alt="" class="wd-icon-img" /></span>
29
34
  ) : (
30
35
  <span class={className} style={style}>{resolved.value}</span>
31
36
  )
@@ -1,5 +1,5 @@
1
1
  ---
2
- // See src/components/{Note,Tip,Warning,Danger,Info}.astro - one thin
2
+ // See src/components/{Note,Tip,Warning,Danger,Info,Check}.astro - one thin
3
3
  // wrapper per `type` below, each just `<Callout type="x">` under the
4
4
  // hood, so a page can write either `<Callout type="info">` or the
5
5
  // shorthand `<Info>` and get an identical result. Both forms take the
@@ -7,7 +7,7 @@
7
7
  import AppIcon from "./AppIcon.astro";
8
8
 
9
9
  interface Props {
10
- type?: "note" | "tip" | "warning" | "danger" | "info";
10
+ type?: "note" | "tip" | "warning" | "danger" | "info" | "check";
11
11
  title?: string;
12
12
  // Set automatically by remarkCalloutAnchorIds (src/lib/mdx-callout-anchor-ids.js)
13
13
  // for every <Callout title="...">/<Note title="...">/etc. it finds in an
@@ -19,8 +19,14 @@ interface Props {
19
19
  // dynamic `title={expr}`, or this component used directly from a .astro
20
20
  // file rather than through MDX).
21
21
  _titleId?: string;
22
+ // Mintlify's custom callout: `icon` replaces the type's own icon (any
23
+ // icon string AppIcon accepts), `color` replaces its accent color - the
24
+ // border, tint, icon and title all derive from that one value.
25
+ icon?: string;
26
+ color?: string;
22
27
  }
23
- const { type = "note", title, _titleId } = Astro.props as Props;
28
+ const { type = "note", title, _titleId, icon, color } = Astro.props as Props;
29
+ const accentStyle = color ? `--wd-callout-accent: ${color}` : undefined;
24
30
  // FontAwesome Solid (fa6-solid, already an installed @iconify-json/*
25
31
  // collection - see astro.config.mjs's own comment on icon() needing no
26
32
  // allowlist) rather than a literal emoji, so every callout gets a real,
@@ -31,6 +37,7 @@ const icons: Record<string, string> = {
31
37
  tip: "fa6-solid:lightbulb",
32
38
  warning: "fa6-solid:triangle-exclamation",
33
39
  danger: "fa6-solid:circle-xmark",
40
+ check: "fa6-solid:circle-check",
34
41
  };
35
42
  // Astro's own heading-id slugging (github-slugger, via the markdown
36
43
  // pipeline) never sees this - `title` is a component prop, not a
@@ -44,8 +51,8 @@ function slugify(value: string): string {
44
51
  const titleId = title ? (_titleId ?? slugify(title)) : undefined;
45
52
  ---
46
53
 
47
- <div class:list={["wd-callout", `wd-callout-${type}`, { "wd-callout-titled": Boolean(title) }]}>
48
- <AppIcon icon={icons[type]} class="wd-callout-icon" />
54
+ <div class:list={["wd-callout", `wd-callout-${type}`, { "wd-callout-titled": Boolean(title) }]} style={accentStyle}>
55
+ <AppIcon icon={icon ?? icons[type]} class="wd-callout-icon" />
49
56
  <div class="wd-callout-content">
50
57
  {
51
58
  title && (
@@ -165,4 +172,7 @@ const titleId = title ? (_titleId ?? slugify(title)) : undefined;
165
172
  .wd-callout-danger {
166
173
  --wd-callout-accent: #dc2626;
167
174
  }
175
+ .wd-callout-check {
176
+ --wd-callout-accent: #059669;
177
+ }
168
178
  </style>
@@ -26,27 +26,40 @@ interface Props {
26
26
  // generic component over a handful of literal hex values).
27
27
  method?: string;
28
28
  href?: string;
29
+ // Mintlify's Card props: `color` tints the icon, `horizontal` puts the
30
+ // icon beside the text instead of above it, `cta` adds a call-to-action
31
+ // line at the bottom, and `arrow` marks a linked card with an arrow in
32
+ // its corner.
33
+ color?: string;
34
+ horizontal?: boolean;
35
+ cta?: string;
36
+ arrow?: boolean;
29
37
  }
30
- const { title, icon, img, method, href } = Astro.props as Props;
38
+ const { title, icon, img, method, href, color, horizontal = false, cta, arrow = false } = Astro.props as Props;
39
+ const iconStyle = color ? `color: ${color}` : undefined;
31
40
  const Tag = href ? 'a' : 'div';
32
41
  const KNOWN_METHODS = ['get', 'post', 'put', 'patch', 'delete'];
33
42
  const methodLower = method?.toLowerCase();
34
43
  const methodClass = methodLower && KNOWN_METHODS.includes(methodLower) ? methodLower : 'other';
35
44
  ---
36
- <Tag class="wd-card" href={href}>
45
+ <Tag class:list={['wd-card', { 'wd-card-horizontal': horizontal, 'wd-card-has-arrow': arrow && href }]} href={href}>
37
46
  {img && <img src={img} alt="" class="wd-card-image" />}
38
- {!img && <AppIcon icon={icon} class="wd-card-icon" />}
39
- <div class="wd-card-title-row">
40
- <h3 class="wd-card-title">{title}</h3>
41
- {
42
- method && (
43
- <span class:list={['wd-card-method', `wd-card-method-${methodClass}`]}>
44
- {method.toUpperCase()}
45
- </span>
46
- )
47
- }
47
+ {!img && <AppIcon icon={icon} class="wd-card-icon" style={iconStyle} />}
48
+ <div class="wd-card-text">
49
+ <div class="wd-card-title-row">
50
+ <h3 class="wd-card-title">{title}</h3>
51
+ {
52
+ method && (
53
+ <span class:list={['wd-card-method', `wd-card-method-${methodClass}`]}>
54
+ {method.toUpperCase()}
55
+ </span>
56
+ )
57
+ }
58
+ </div>
59
+ <div class="wd-card-body"><slot /></div>
60
+ {cta && <span class="wd-card-cta">{cta} <span aria-hidden="true">&rarr;</span></span>}
48
61
  </div>
49
- <div class="wd-card-body"><slot /></div>
62
+ {arrow && href && <span class="wd-card-arrow" aria-hidden="true">&#8599;</span>}
50
63
  </Tag>
51
64
  <style>
52
65
  .wd-card {
@@ -133,4 +146,42 @@ const methodClass = methodLower && KNOWN_METHODS.includes(methodLower) ? methodL
133
146
  .wd-card-body :global(p) {
134
147
  margin: 0;
135
148
  }
149
+ /* Icon in its own column beside the title/body, both vertically
150
+ centered - Mintlify's compact horizontal card. */
151
+ .wd-card-horizontal {
152
+ display: flex;
153
+ align-items: center;
154
+ gap: 0.9rem;
155
+ }
156
+ .wd-card-horizontal .wd-card-title-row {
157
+ margin-top: 0;
158
+ }
159
+ .wd-card-text {
160
+ min-width: 0;
161
+ flex: 1;
162
+ }
163
+ .wd-card-cta {
164
+ display: inline-block;
165
+ margin-top: 0.7rem;
166
+ font-size: 0.85rem;
167
+ font-weight: 600;
168
+ color: var(--wd-primary);
169
+ }
170
+ /* Only a card that shows the arrow becomes a positioning context -
171
+ setting it on every card changed how existing cards' text was
172
+ antialiased, for no layout reason. */
173
+ .wd-card-has-arrow {
174
+ position: relative;
175
+ }
176
+ .wd-card-arrow {
177
+ position: absolute;
178
+ top: 0.8rem;
179
+ right: 0.9rem;
180
+ color: var(--wd-text-muted);
181
+ font-size: 0.95rem;
182
+ line-height: 1;
183
+ }
184
+ a.wd-card:hover .wd-card-arrow {
185
+ color: var(--wd-primary);
186
+ }
136
187
  </style>
@@ -0,0 +1,13 @@
1
+ ---
2
+ // Shorthand for <Callout type="check"> - Mintlify's <Check> ("this worked",
3
+ // "you're done"). See Callout.astro's own comment.
4
+ import Callout from './Callout.astro';
5
+ interface Props {
6
+ title?: string;
7
+ // See Callout.astro's own comment - set automatically by
8
+ // remarkCalloutAnchorIds, not meant to be passed by hand.
9
+ _titleId?: string;
10
+ }
11
+ const { title, _titleId } = Astro.props as Props;
12
+ ---
13
+ <Callout type="check" title={title} _titleId={_titleId}><slot /></Callout>
@@ -0,0 +1,11 @@
1
+ ---
2
+ // Mintlify's <Columns cols={n}> - the grid Mintlify now uses around Cards
3
+ // (its docs moved from <CardGroup> to this). Same grid as CardGroup.astro,
4
+ // which already lays out any children, not only Cards.
5
+ import CardGroup from './CardGroup.astro';
6
+ interface Props {
7
+ cols?: number;
8
+ }
9
+ const { cols } = Astro.props as Props;
10
+ ---
11
+ <CardGroup cols={cols}><slot /></CardGroup>
@@ -12,13 +12,17 @@
12
12
  // component's name collides with frontmatter's own `mode: "frame"`
13
13
  // page-rendering option (BaseLayout.astro) - that's an unrelated,
14
14
  // page-level concept keyed off a plain string, not a JSX component.
15
+ // `hint` is Mintlify's: a short line shown above the framed content, as
16
+ // opposed to `caption` below it.
15
17
  interface Props {
16
18
  caption?: string;
19
+ hint?: string;
17
20
  }
18
- const { caption } = Astro.props as Props;
21
+ const { caption, hint } = Astro.props as Props;
19
22
  ---
20
23
 
21
24
  <figure class="wd-frame">
25
+ {hint && <p class="wd-frame-hint">{hint}</p>}
22
26
  <div class="wd-frame-content">
23
27
  <slot />
24
28
  </div>
@@ -93,6 +97,11 @@ const { caption } = Astro.props as Props;
93
97
  .wd-frame-content :global(p) {
94
98
  display: contents;
95
99
  }
100
+ .wd-frame-hint {
101
+ margin: 0.1rem 0.25rem 0.5rem;
102
+ color: var(--wd-text-muted);
103
+ font-size: 0.8rem;
104
+ }
96
105
  .wd-frame-caption {
97
106
  margin: 0.6rem 0 0;
98
107
  text-align: center;
@@ -11,15 +11,30 @@
11
11
  // position predictably; a second <slot> would let an author put
12
12
  // arbitrary markup (another Hint, a link, a whole paragraph) in there,
13
13
  // which the hover-bubble layout below was never built to hold.
14
+ //
15
+ // `headline`, `cta` and `href` exist for Mintlify's <Tooltip> (see
16
+ // Tooltip.astro): an optional bold line above the tip, and an optional
17
+ // link below it. They're still plain strings, not slots - same reasoning
18
+ // as above. A tooltip with a link has to stay open while the pointer moves
19
+ // from the trigger onto the bubble, so the bubble takes pointer events
20
+ // once shown, and a transparent ::before bridges the gap between them.
14
21
  interface Props {
15
22
  tip: string;
23
+ headline?: string;
24
+ cta?: string;
25
+ href?: string;
16
26
  }
17
- const { tip } = Astro.props as Props;
27
+ const { tip, headline, cta, href } = Astro.props as Props;
28
+ const hasLink = Boolean(cta && href);
18
29
  ---
19
30
 
20
- <span class="wd-hint" tabindex="0">
31
+ <span class:list={["wd-hint", { "wd-hint-rich": Boolean(headline) || hasLink }]} tabindex="0">
21
32
  <span class="wd-hint-trigger"><slot /></span>
22
- <span class="wd-hint-tooltip" role="tooltip">{tip}</span>
33
+ <span class="wd-hint-tooltip" role="tooltip">
34
+ {headline && <span class="wd-hint-headline">{headline}</span>}
35
+ <span class="wd-hint-tip">{tip}</span>
36
+ {hasLink && <a class="wd-hint-cta" href={href}>{cta}</a>}
37
+ </span>
23
38
  </span>
24
39
  <style>
25
40
  .wd-hint {
@@ -91,9 +106,40 @@ const { tip } = Astro.props as Props;
91
106
  border-top-color: #18181b;
92
107
  }
93
108
  .wd-hint:hover .wd-hint-tooltip,
94
- .wd-hint:focus-visible .wd-hint-tooltip {
109
+ .wd-hint:focus-visible .wd-hint-tooltip,
110
+ .wd-hint:focus-within .wd-hint-tooltip {
95
111
  opacity: 1;
96
112
  visibility: visible;
97
113
  transform: translateX(-50%) translateY(0);
98
114
  }
115
+ /* Only a tooltip with a headline or link is interactive - a plain one
116
+ keeps pointer-events: none so it never blocks the text under it. */
117
+ .wd-hint-rich:hover .wd-hint-tooltip,
118
+ .wd-hint-rich:focus-within .wd-hint-tooltip {
119
+ pointer-events: auto;
120
+ }
121
+ .wd-hint-rich .wd-hint-tooltip::before {
122
+ content: "";
123
+ position: absolute;
124
+ top: 100%;
125
+ left: 0;
126
+ right: 0;
127
+ height: 0.6rem;
128
+ }
129
+ .wd-hint-tip,
130
+ .wd-hint-headline,
131
+ .wd-hint-cta {
132
+ display: block;
133
+ }
134
+ .wd-hint-rich .wd-hint-tip {
135
+ font-weight: 400;
136
+ }
137
+ .wd-hint-headline {
138
+ margin-bottom: 0.2rem;
139
+ }
140
+ .wd-hint-cta {
141
+ margin-top: 0.35rem;
142
+ color: #93c5fd;
143
+ text-decoration: underline;
144
+ }
99
145
  </style>
@@ -0,0 +1,25 @@
1
+ ---
2
+ // Mintlify's <ParamField> - a request parameter row, rendered by
3
+ // Parameter.astro. Mintlify names the parameter through whichever
4
+ // location prop it's in (`path="id"`, `query="limit"`, `body="email"`,
5
+ // `header="Authorization"`) rather than `name`; the first one present
6
+ // becomes the name. The location itself isn't shown - on a Mintlify page
7
+ // it's already implied by the section the field sits in.
8
+ import Parameter from './Parameter.astro';
9
+ interface Props {
10
+ name?: string;
11
+ path?: string;
12
+ query?: string;
13
+ body?: string;
14
+ header?: string;
15
+ type?: string;
16
+ required?: boolean;
17
+ default?: unknown;
18
+ deprecated?: boolean;
19
+ pre?: string[];
20
+ post?: string[];
21
+ }
22
+ const { name, path, query, body, header, ...rest } = Astro.props as Props;
23
+ const fieldName = name ?? path ?? query ?? body ?? header ?? '';
24
+ ---
25
+ <Parameter name={fieldName} {...rest}><slot /></Parameter>
@@ -16,21 +16,37 @@
16
16
  // text, an <Expandable> wrapping more Parameters for a nested object's
17
17
  // own properties, or both - see Expandable.astro's own comment for that
18
18
  // half of the pattern.
19
+ //
20
+ // `deprecated`, `pre` and `post` exist for Mintlify parity (see
21
+ // ParamField.astro/ResponseField.astro, the Mintlify-named wrappers around
22
+ // this): `pre`/`post` are extra labels Mintlify renders before/after the
23
+ // name. `default` accepts any value, not just a string - Mintlify content
24
+ // routinely writes `default={10}` or `default={false}`, and a falsy one
25
+ // (0, false) is still a real default worth showing, so only
26
+ // undefined/null/"" hide the chip.
19
27
  interface Props {
20
28
  name: string;
21
29
  type?: string;
22
30
  required?: boolean;
23
- default?: string;
31
+ default?: unknown;
32
+ deprecated?: boolean;
33
+ pre?: string[];
34
+ post?: string[];
24
35
  }
25
- const { name, type, required = false, default: defaultValue } = Astro.props as Props;
36
+ const { name, type, required = false, default: defaultValue, deprecated = false, pre = [], post = [] } =
37
+ Astro.props as Props;
38
+ const hasDefault = defaultValue !== undefined && defaultValue !== null && defaultValue !== "";
26
39
  ---
27
40
 
28
- <div class="wd-parameter">
41
+ <div class:list={["wd-parameter", { "wd-parameter-deprecated": deprecated }]}>
29
42
  <div class="wd-parameter-head">
43
+ {pre.map((label) => <span class="wd-parameter-label">{label}</span>)}
30
44
  <span class="wd-parameter-name">{name}</span>
31
45
  {type && <span class="wd-parameter-type">{type}</span>}
32
46
  {required && <span class="wd-parameter-required">required</span>}
33
- {defaultValue && <span class="wd-parameter-default">default: {defaultValue}</span>}
47
+ {deprecated && <span class="wd-parameter-deprecated-badge">deprecated</span>}
48
+ {post.map((label) => <span class="wd-parameter-label">{label}</span>)}
49
+ {hasDefault && <span class="wd-parameter-default">default: {String(defaultValue)}</span>}
34
50
  </div>
35
51
  <div class="wd-parameter-body">
36
52
  <slot />
@@ -96,6 +112,27 @@ const { name, type, required = false, default: defaultValue } = Astro.props as P
96
112
  padding: 0.1em 0.5em;
97
113
  color: #dc2626;
98
114
  }
115
+ /* Same chip as .wd-parameter-type, in amber - a warning, not an error
116
+ like .wd-parameter-required. The name itself is struck through below
117
+ so the field reads as "don't use this" even before the badge. */
118
+ .wd-parameter-deprecated-badge {
119
+ font-family: monospace;
120
+ font-size: 0.8rem;
121
+ font-weight: 600;
122
+ background: color-mix(in srgb, #d97706 8%, var(--wd-surface));
123
+ border: 1px solid color-mix(in srgb, #d97706 35%, var(--wd-border));
124
+ border-radius: 0.35em;
125
+ padding: 0.1em 0.5em;
126
+ color: #d97706;
127
+ }
128
+ .wd-parameter-deprecated .wd-parameter-name {
129
+ text-decoration: line-through;
130
+ opacity: 0.7;
131
+ }
132
+ .wd-parameter-label {
133
+ font-size: 0.78rem;
134
+ color: var(--wd-text-muted);
135
+ }
99
136
  .wd-parameter-default {
100
137
  font-size: 0.78rem;
101
138
  color: var(--wd-text-muted);
@@ -0,0 +1,18 @@
1
+ ---
2
+ // Mintlify's <ResponseField> - a response field row. Same props as
3
+ // Parameter.astro (`name`, `type`, `required`, `default`, `deprecated`,
4
+ // `pre`, `post`), so this is a straight pass-through; see Parameter.astro
5
+ // for why one component covers both directions.
6
+ import Parameter from './Parameter.astro';
7
+ interface Props {
8
+ name: string;
9
+ type?: string;
10
+ required?: boolean;
11
+ default?: unknown;
12
+ deprecated?: boolean;
13
+ pre?: string[];
14
+ post?: string[];
15
+ }
16
+ const props = Astro.props as Props;
17
+ ---
18
+ <Parameter {...props}><slot /></Parameter>
@@ -1,10 +1,29 @@
1
1
  ---
2
+ import AppIcon from './AppIcon.astro';
3
+ // `icon`, `stepNumber` and `titleSize` are Mintlify's. `icon` replaces the
4
+ // number in the step's circle. `stepNumber` sets this step's number; the
5
+ // steps after it keep counting from there (counter-set on the step itself
6
+ // runs before its own ::before increments the counter - see Steps.astro).
7
+ // `titleSize` renders the title as an h2/h3 instead of bold text.
2
8
  interface Props {
3
9
  title?: string;
10
+ icon?: string;
11
+ stepNumber?: number;
12
+ titleSize?: 'p' | 'h2' | 'h3';
4
13
  }
5
- const { title } = Astro.props as Props;
14
+ const { title, icon, stepNumber, titleSize = 'p' } = Astro.props as Props;
15
+ const style = typeof stepNumber === 'number' ? `counter-set: wd-step ${stepNumber - 1}` : undefined;
16
+ const TitleTag = titleSize === 'h2' || titleSize === 'h3' ? titleSize : 'p';
6
17
  ---
7
- <div class="wd-step">
8
- {title && <p class="wd-step-title"><strong>{title}</strong></p>}
18
+ <div class:list={['wd-step', { 'wd-step-has-icon': Boolean(icon) }]} style={style}>
19
+ {icon && <AppIcon icon={icon} class="wd-step-icon" />}
20
+ {
21
+ title &&
22
+ (TitleTag === 'p' ? (
23
+ <p class="wd-step-title"><strong>{title}</strong></p>
24
+ ) : (
25
+ <TitleTag class="wd-step-title">{title}</TitleTag>
26
+ ))
27
+ }
9
28
  <slot />
10
29
  </div>
@@ -12,6 +12,28 @@
12
12
  margin-left: 0.9rem;
13
13
  }
14
14
  .wd-step:last-child { border-color: transparent; padding-bottom: 0; }
15
+ /* A Step with an `icon` (see Step.astro) keeps the same circle - the
16
+ ::before below still increments the counter so later steps number
17
+ correctly - and draws the icon on top of it instead of the digit. */
18
+ .wd-step.wd-step-has-icon::before { color: transparent; }
19
+ .wd-step-icon {
20
+ position: absolute;
21
+ left: -0.95rem;
22
+ top: 0;
23
+ width: 1.8rem;
24
+ height: 1.8rem;
25
+ padding: 0.45rem;
26
+ box-sizing: border-box;
27
+ color: white;
28
+ z-index: 1;
29
+ }
30
+ span.wd-step-icon {
31
+ display: flex;
32
+ align-items: center;
33
+ justify-content: center;
34
+ padding: 0;
35
+ font-size: 0.85rem;
36
+ }
15
37
  .wd-step::before {
16
38
  counter-increment: wd-step;
17
39
  content: counter(wd-step);
@@ -1,9 +1,15 @@
1
1
  ---
2
+ import AppIcon from './AppIcon.astro';
3
+ // `icon` is Mintlify's: shown before the title in the tab's button. The
4
+ // button is built client-side by Tabs.astro, which moves this hidden,
5
+ // server-rendered icon into it.
2
6
  interface Props {
3
7
  title: string;
8
+ icon?: string;
4
9
  }
5
- const { title } = Astro.props as Props;
10
+ const { title, icon } = Astro.props as Props;
6
11
  ---
7
12
  <div class="wd-tab" data-title={title}>
13
+ {icon && <span class="wd-tab-icon-src" hidden><AppIcon icon={icon} class="wd-tabs-btn-icon" /></span>}
8
14
  <slot />
9
15
  </div>