@veluai/velu 0.2.35 → 0.2.36
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 +39 -0
- package/dist/cli.js +57 -49
- package/package.json +1 -1
- package/runtime/velu-ui/components/Accordion.jsx +3 -3
- package/runtime/velu-ui/components/ApiClient.jsx +4 -2
- package/runtime/velu-ui/components/ApiReferencePage.jsx +12 -12
- package/runtime/velu-ui/components/ApiSamples.jsx +2 -2
- package/runtime/velu-ui/components/AskBar.jsx +3 -2
- package/runtime/velu-ui/components/Callout.jsx +11 -26
- package/runtime/velu-ui/components/Card.jsx +9 -8
- package/runtime/velu-ui/components/ChangelogFilters.jsx +2 -1
- package/runtime/velu-ui/components/Chatbot.jsx +11 -5
- package/runtime/velu-ui/components/CodeBlock.jsx +7 -6
- package/runtime/velu-ui/components/Columns.jsx +1 -0
- package/runtime/velu-ui/components/ContextMenu.jsx +3 -2
- package/runtime/velu-ui/components/Field.jsx +2 -2
- package/runtime/velu-ui/components/Icon.jsx +1 -0
- package/runtime/velu-ui/components/Image.jsx +2 -2
- package/runtime/velu-ui/components/MethodBadge.jsx +2 -2
- package/runtime/velu-ui/components/NavSelect.jsx +22 -4
- package/runtime/velu-ui/components/NotFound.jsx +7 -7
- package/runtime/velu-ui/components/PageFeedback.jsx +13 -3
- package/runtime/velu-ui/components/PageHeader.jsx +24 -9
- package/runtime/velu-ui/components/PageNav.jsx +2 -1
- package/runtime/velu-ui/components/Prompt.jsx +2 -2
- package/runtime/velu-ui/components/Search.jsx +1 -0
- package/runtime/velu-ui/components/Sidebar.jsx +18 -6
- package/runtime/velu-ui/components/Steps.jsx +4 -4
- package/runtime/velu-ui/components/ThemeToggle.jsx +1 -0
- package/runtime/velu-ui/components/Toc.jsx +6 -4
- package/runtime/velu-ui/components/Tree.jsx +6 -5
- package/runtime/velu-ui/components/TryItBar.jsx +1 -0
- package/runtime/velu-ui/components/Update.jsx +2 -2
- package/runtime/velu-ui/components/callout.css +28 -0
- package/runtime/velu-ui/components/docs-layout.css +5 -0
- package/runtime/velu-ui/components/sidebar.css +5 -5
- package/runtime/velu-ui/element-selectors.css +66 -0
- package/runtime/velu-ui/primitives/Cluster.jsx +12 -0
- package/runtime/velu-ui/primitives/Stack.jsx +12 -0
- package/runtime/velu-ui/primitives/Switcher.jsx +11 -1
- package/runtime/velu-ui/styles.css +51 -35
- package/src/runtime/App.jsx +43 -11
- package/src/runtime/client-entry.jsx +23 -0
- package/src/runtime/dev-warnings.js +16 -0
- package/src/runtime/server-entry.jsx +1 -0
|
@@ -68,9 +68,13 @@ export function VeluMark() {
|
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
function ActionButton({ action, Link }) {
|
|
72
|
-
const { label, icon, kind = 'outlined', href, onClick, external } = action;
|
|
71
|
+
function ActionButton({ action, Link, id }) {
|
|
72
|
+
const { label, icon, kind = 'outlined', href, onClick, external, component } = action;
|
|
73
73
|
const cls = `velu-header__action velu-header__action--${kind}`;
|
|
74
|
+
// Mintlify-compatible hooks: `#topbar-cta-button` on the first primary
|
|
75
|
+
// action, `[data-component="navbar-link"]` on every action (overridable per
|
|
76
|
+
// action, e.g. component: 'logout-link').
|
|
77
|
+
const hooks = { id, 'data-component': component ?? 'navbar-link' };
|
|
74
78
|
const content = (
|
|
75
79
|
<>
|
|
76
80
|
{icon && (
|
|
@@ -87,13 +91,13 @@ function ActionButton({ action, Link }) {
|
|
|
87
91
|
? { target: '_blank', rel: 'noreferrer' }
|
|
88
92
|
: {};
|
|
89
93
|
return (
|
|
90
|
-
<Tag className={cls} href={href} {...extraProps}>
|
|
94
|
+
<Tag className={cls} href={href} {...hooks} {...extraProps}>
|
|
91
95
|
{content}
|
|
92
96
|
</Tag>
|
|
93
97
|
);
|
|
94
98
|
}
|
|
95
99
|
return (
|
|
96
|
-
<button type="button" className={cls} onClick={onClick}>
|
|
100
|
+
<button type="button" className={cls} onClick={onClick} {...hooks}>
|
|
97
101
|
{content}
|
|
98
102
|
</button>
|
|
99
103
|
);
|
|
@@ -111,6 +115,8 @@ function HeaderTab({ tab, isActive, Link }) {
|
|
|
111
115
|
className={cls}
|
|
112
116
|
href={href}
|
|
113
117
|
aria-current={isActive ? 'page' : undefined}
|
|
118
|
+
data-active={isActive ? 'true' : undefined}
|
|
119
|
+
data-component="nav-tabs-item"
|
|
114
120
|
{...extraProps}
|
|
115
121
|
>
|
|
116
122
|
{icon && (
|
|
@@ -243,6 +249,7 @@ export default function PageHeader({
|
|
|
243
249
|
const Link = linkComponent;
|
|
244
250
|
const brandLabel = brand?.label ?? 'Velu';
|
|
245
251
|
const brandHref = brand?.href;
|
|
252
|
+
const firstPrimary = actions.findIndex((a) => a.kind === 'primary');
|
|
246
253
|
|
|
247
254
|
// Track whether the page has been scrolled so the header can flip
|
|
248
255
|
// from solid to translucent / frosted. Edge-triggered (only updates
|
|
@@ -288,7 +295,7 @@ export default function PageHeader({
|
|
|
288
295
|
className="velu-header__col velu-header__col--brand"
|
|
289
296
|
>
|
|
290
297
|
{brandHref ? (
|
|
291
|
-
<Link href={brandHref} className="velu-header__brand-link">
|
|
298
|
+
<Link href={brandHref} className="velu-header__brand-link" data-component="nav-logo">
|
|
292
299
|
{brandBlock}
|
|
293
300
|
</Link>
|
|
294
301
|
) : (
|
|
@@ -306,6 +313,7 @@ export default function PageHeader({
|
|
|
306
313
|
|
|
307
314
|
{(actions.length > 0 || trailing) && (
|
|
308
315
|
<Cluster
|
|
316
|
+
as="topbar-right-container"
|
|
309
317
|
space="var(--s-2)"
|
|
310
318
|
align="center"
|
|
311
319
|
className="velu-header__col velu-header__col--actions"
|
|
@@ -316,7 +324,12 @@ export default function PageHeader({
|
|
|
316
324
|
{actions.length > 0 && (
|
|
317
325
|
<div className="velu-header__actions-list">
|
|
318
326
|
{actions.map((a, i) => (
|
|
319
|
-
<ActionButton
|
|
327
|
+
<ActionButton
|
|
328
|
+
key={i}
|
|
329
|
+
action={a}
|
|
330
|
+
Link={Link}
|
|
331
|
+
id={i === firstPrimary ? 'topbar-cta-button' : undefined}
|
|
332
|
+
/>
|
|
320
333
|
))}
|
|
321
334
|
</div>
|
|
322
335
|
)}
|
|
@@ -341,6 +354,7 @@ export default function PageHeader({
|
|
|
341
354
|
tabsTrailing ||
|
|
342
355
|
onMenuClick) && (
|
|
343
356
|
<Cluster
|
|
357
|
+
as="nav-tabs"
|
|
344
358
|
space="var(--s0)"
|
|
345
359
|
align="center"
|
|
346
360
|
className="velu-header__tabs"
|
|
@@ -367,6 +381,7 @@ export default function PageHeader({
|
|
|
367
381
|
<button
|
|
368
382
|
type="button"
|
|
369
383
|
className="velu-header__crumbs"
|
|
384
|
+
data-component="breadcrumb-list"
|
|
370
385
|
onClick={onMenuClick}
|
|
371
386
|
aria-label="Open navigation menu"
|
|
372
387
|
>
|
|
@@ -381,13 +396,13 @@ export default function PageHeader({
|
|
|
381
396
|
focusable="false"
|
|
382
397
|
/>
|
|
383
398
|
)}
|
|
384
|
-
<
|
|
385
|
-
|
|
399
|
+
<breadcrumb-item
|
|
400
|
+
class={`velu-header__crumb${
|
|
386
401
|
isLast ? ' velu-header__crumb--current' : ''
|
|
387
402
|
}`}
|
|
388
403
|
>
|
|
389
404
|
{c.label}
|
|
390
|
-
</
|
|
405
|
+
</breadcrumb-item>
|
|
391
406
|
</React.Fragment>
|
|
392
407
|
);
|
|
393
408
|
})}
|
|
@@ -32,9 +32,10 @@ function NavCard({ page, dir, Link }) {
|
|
|
32
32
|
return (
|
|
33
33
|
<Link
|
|
34
34
|
className={`velu-pagenav__card velu-pagenav__card--${dir}`}
|
|
35
|
+
data-component={`pagination-${dir}`}
|
|
35
36
|
href={page.href ?? '#'}
|
|
36
37
|
>
|
|
37
|
-
<
|
|
38
|
+
<pagination-title class="velu-pagenav__title">{page.label}</pagination-title>
|
|
38
39
|
<Cluster
|
|
39
40
|
space="var(--s-4)"
|
|
40
41
|
align="center"
|
|
@@ -69,7 +69,7 @@ export default function Prompt({
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
return (
|
|
72
|
-
<
|
|
72
|
+
<prompt className={`velu-prompt ${className}`.trim()} {...rest}>
|
|
73
73
|
{title != null && (
|
|
74
74
|
<div className="velu-prompt__title">{title}</div>
|
|
75
75
|
)}
|
|
@@ -110,6 +110,6 @@ export default function Prompt({
|
|
|
110
110
|
{copied ? 'Copied' : 'Copy Prompt'}
|
|
111
111
|
</button>
|
|
112
112
|
</Cluster>
|
|
113
|
-
</
|
|
113
|
+
</prompt>
|
|
114
114
|
);
|
|
115
115
|
}
|
|
@@ -63,9 +63,9 @@ function hasActiveDescendant(item, activeHref) {
|
|
|
63
63
|
function Icon({ icon }) {
|
|
64
64
|
const node = resolveIcon(icon);
|
|
65
65
|
return node ? (
|
|
66
|
-
<
|
|
66
|
+
<sidebar-group-icon class="velu-sidebar__icon" aria-hidden="true">
|
|
67
67
|
{node}
|
|
68
|
-
</
|
|
68
|
+
</sidebar-group-icon>
|
|
69
69
|
) : null;
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -99,7 +99,7 @@ function Node({ item, depth }) {
|
|
|
99
99
|
return (
|
|
100
100
|
<li>
|
|
101
101
|
<details open={hasActiveDescendant(item, activeHref) || undefined}>
|
|
102
|
-
<summary className={`${base} velu-sidebar__summary`}>
|
|
102
|
+
<summary className={`${base} velu-sidebar__summary`} data-component="sidebar-group-header">
|
|
103
103
|
<Icon icon={icon} />
|
|
104
104
|
<span className="velu-sidebar__label">{label}</span>
|
|
105
105
|
<Chevron />
|
|
@@ -124,10 +124,11 @@ function Node({ item, depth }) {
|
|
|
124
124
|
: { href };
|
|
125
125
|
|
|
126
126
|
return (
|
|
127
|
-
<li>
|
|
127
|
+
<li data-active={active ? 'true' : undefined}>
|
|
128
128
|
<LinkTag
|
|
129
129
|
className={cls}
|
|
130
130
|
aria-current={active ? 'page' : undefined}
|
|
131
|
+
data-active={active ? 'true' : undefined}
|
|
131
132
|
{...linkProps}
|
|
132
133
|
>
|
|
133
134
|
<Icon icon={icon} />
|
|
@@ -228,8 +229,19 @@ export default function Sidebar({
|
|
|
228
229
|
separates one section from the next — compact but still
|
|
229
230
|
visibly grouped. */}
|
|
230
231
|
{sections.map((section, i) => (
|
|
231
|
-
<Stack
|
|
232
|
-
|
|
232
|
+
<Stack
|
|
233
|
+
key={i}
|
|
234
|
+
as="sidebar-group"
|
|
235
|
+
space="var(--s-4)"
|
|
236
|
+
data-active={
|
|
237
|
+
section.items.some(
|
|
238
|
+
(it) => isActive(it, activeHref) || hasActiveDescendant(it, activeHref),
|
|
239
|
+
)
|
|
240
|
+
? 'true'
|
|
241
|
+
: undefined
|
|
242
|
+
}
|
|
243
|
+
>
|
|
244
|
+
<h5 className="velu-sidebar__section" data-component="sidebar-title">
|
|
233
245
|
<Icon icon={section.icon} />
|
|
234
246
|
{section.title}
|
|
235
247
|
</h5>
|
|
@@ -33,7 +33,7 @@ export function Step({
|
|
|
33
33
|
...rest
|
|
34
34
|
}) {
|
|
35
35
|
return (
|
|
36
|
-
<
|
|
36
|
+
<step className={`velu-step ${className}`.trim()} {...rest}>
|
|
37
37
|
<div className="velu-step__circle" aria-hidden="true">
|
|
38
38
|
{index}
|
|
39
39
|
</div>
|
|
@@ -44,7 +44,7 @@ export function Step({
|
|
|
44
44
|
{children != null && children !== false && (
|
|
45
45
|
<div className="velu-step__body">{children}</div>
|
|
46
46
|
)}
|
|
47
|
-
</
|
|
47
|
+
</step>
|
|
48
48
|
);
|
|
49
49
|
}
|
|
50
50
|
Step.displayName = 'Step';
|
|
@@ -58,8 +58,8 @@ export default function Steps({ children, className = '', ...rest }) {
|
|
|
58
58
|
return cloneElement(child, { index: child.props.index ?? i });
|
|
59
59
|
});
|
|
60
60
|
return (
|
|
61
|
-
<
|
|
61
|
+
<steps className={`velu-steps ${className}`.trim()} {...rest}>
|
|
62
62
|
{numbered}
|
|
63
|
-
</
|
|
63
|
+
</steps>
|
|
64
64
|
);
|
|
65
65
|
}
|
|
@@ -32,6 +32,7 @@ export default function ThemeToggle({ className = '', ...rest }) {
|
|
|
32
32
|
onClick={toggle}
|
|
33
33
|
aria-label="Toggle color theme"
|
|
34
34
|
title="Toggle color theme"
|
|
35
|
+
data-component-name="theme-toggle"
|
|
35
36
|
className={`velu-theme-toggle ${className}`.trim()}
|
|
36
37
|
{...rest}
|
|
37
38
|
>
|
|
@@ -127,9 +127,11 @@ const Row = React.forwardRef(function Row(
|
|
|
127
127
|
ref
|
|
128
128
|
) {
|
|
129
129
|
return (
|
|
130
|
-
<
|
|
130
|
+
<toc-item
|
|
131
131
|
ref={ref}
|
|
132
132
|
data-toc-active={active ? 'true' : undefined}
|
|
133
|
+
data-active={active ? 'true' : undefined}
|
|
134
|
+
data-active-deepest={active ? 'true' : undefined}
|
|
133
135
|
onMouseEnter={() => onEnter(idx)}
|
|
134
136
|
onClick={() => onClick(item.id)}
|
|
135
137
|
style={{
|
|
@@ -166,7 +168,7 @@ const Row = React.forwardRef(function Row(
|
|
|
166
168
|
>
|
|
167
169
|
{item.label}
|
|
168
170
|
</span>
|
|
169
|
-
</
|
|
171
|
+
</toc-item>
|
|
170
172
|
);
|
|
171
173
|
});
|
|
172
174
|
|
|
@@ -434,7 +436,7 @@ export default function Toc({
|
|
|
434
436
|
}, [activeIdx]);
|
|
435
437
|
|
|
436
438
|
return (
|
|
437
|
-
<
|
|
439
|
+
<toc
|
|
438
440
|
ref={rootRef}
|
|
439
441
|
onMouseLeave={() => setHoverIdx(null)}
|
|
440
442
|
style={{
|
|
@@ -532,6 +534,6 @@ export default function Toc({
|
|
|
532
534
|
fontSize={fontSize}
|
|
533
535
|
/>
|
|
534
536
|
))}
|
|
535
|
-
</
|
|
537
|
+
</toc>
|
|
536
538
|
);
|
|
537
539
|
}
|
|
@@ -25,9 +25,9 @@ import resolveIcon from '../lib/resolveIcon.jsx';
|
|
|
25
25
|
|
|
26
26
|
export default function Tree({ children, className = '', ...rest }) {
|
|
27
27
|
return (
|
|
28
|
-
<
|
|
28
|
+
<tree className={`velu-tree ${className}`.trim()} {...rest}>
|
|
29
29
|
{children}
|
|
30
|
-
</
|
|
30
|
+
</tree>
|
|
31
31
|
);
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -54,6 +54,7 @@ export function Folder({
|
|
|
54
54
|
// the <details> is not [open], so the rail collapses with them.
|
|
55
55
|
return (
|
|
56
56
|
<details
|
|
57
|
+
data-component="tree-folder"
|
|
57
58
|
className={`velu-tree__group ${className}`.trim()}
|
|
58
59
|
open={defaultOpen || undefined}
|
|
59
60
|
{...rest}
|
|
@@ -76,12 +77,12 @@ export function File({
|
|
|
76
77
|
...rest
|
|
77
78
|
}) {
|
|
78
79
|
return (
|
|
79
|
-
<
|
|
80
|
-
|
|
80
|
+
<tree-file
|
|
81
|
+
class={`velu-tree__item velu-tree__item--file ${className}`.trim()}
|
|
81
82
|
{...rest}
|
|
82
83
|
>
|
|
83
84
|
<ItemIcon icon={icon} />
|
|
84
85
|
<span className="velu-tree__label">{name}</span>
|
|
85
|
-
</
|
|
86
|
+
</tree-file>
|
|
86
87
|
);
|
|
87
88
|
}
|
|
@@ -55,7 +55,7 @@ export default function Update({
|
|
|
55
55
|
const tagList = toTagList(tags);
|
|
56
56
|
|
|
57
57
|
return (
|
|
58
|
-
<
|
|
58
|
+
<update
|
|
59
59
|
id={anchorId}
|
|
60
60
|
data-update-label={updateLabel}
|
|
61
61
|
data-update-tags={tagList.join('|')}
|
|
@@ -87,6 +87,6 @@ export default function Update({
|
|
|
87
87
|
) : null}
|
|
88
88
|
</div>
|
|
89
89
|
{children ? <div className="velu-update__content">{children}</div> : null}
|
|
90
|
-
</
|
|
90
|
+
</update>
|
|
91
91
|
);
|
|
92
92
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* Callout — admonition box. Static styles live here (not inline) so a
|
|
2
|
+
project's custom CSS can override them with a plain `callout { ... }`
|
|
3
|
+
element selector, as on Mintlify. The per-variant colours arrive as inline
|
|
4
|
+
custom properties (--velu-callout-bg / --velu-callout-stroke) set by
|
|
5
|
+
Callout.jsx from the type / stroke / bg props. */
|
|
6
|
+
.velu-callout {
|
|
7
|
+
display: flow-root; /* contains the floated icon, no clipping */
|
|
8
|
+
padding: var(--s0) var(--s3);
|
|
9
|
+
background: var(--velu-callout-bg);
|
|
10
|
+
border: var(--border-width) solid var(--velu-callout-stroke);
|
|
11
|
+
border-radius: var(--radius-sm);
|
|
12
|
+
color: var(--text-color);
|
|
13
|
+
font-size: var(--f-body);
|
|
14
|
+
line-height: var(--lh-body);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* The icon is FLOATED into the text flow (not a fixed column): it sits on the
|
|
18
|
+
first line and the text wraps beside it, then flows back under it. One
|
|
19
|
+
line-box tall so it's centred on the first line. */
|
|
20
|
+
.velu-callout__icon {
|
|
21
|
+
float: left;
|
|
22
|
+
display: inline-flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
block-size: calc(var(--f-body) * var(--lh-body));
|
|
25
|
+
margin-inline-end: var(--s-1);
|
|
26
|
+
color: var(--velu-callout-stroke);
|
|
27
|
+
font-size: var(--f-body);
|
|
28
|
+
}
|
|
@@ -71,8 +71,13 @@
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
.velu-docs-layout__aside--left {
|
|
74
|
+
/* Shared surface token for the rail and its sticky descendants. Project
|
|
75
|
+
CSS can override this once on #sidebar; section headers and their fade
|
|
76
|
+
then remain visually continuous with the customized rail. */
|
|
77
|
+
--velu-sidebar-bg: var(--page-bg);
|
|
74
78
|
inset-inline-start: 0;
|
|
75
79
|
inline-size: var(--velu-sidebar-width);
|
|
80
|
+
background: var(--velu-sidebar-bg);
|
|
76
81
|
/* Left gutter so the nav sits inset from the viewport edge rather
|
|
77
82
|
than hugging it. (At mobile the @container block resets this to 0
|
|
78
83
|
— the drawer manages its own padding.) */
|
|
@@ -58,15 +58,15 @@
|
|
|
58
58
|
takes over (iOS-list style). It sticks within its section wrapper
|
|
59
59
|
(Sidebar.jsx renders each section in its own Stack), which bounds
|
|
60
60
|
the push-out. Full-width opaque background so scrolling items
|
|
61
|
-
don't show behind it; --
|
|
62
|
-
|
|
61
|
+
don't show behind it; --velu-sidebar-bg is owned by the left rail and can
|
|
62
|
+
be customized there, so the bar remains continuous with its surroundings. */
|
|
63
63
|
position: sticky;
|
|
64
64
|
inset-block-start: 0;
|
|
65
65
|
/* Above the items (z-index 1) so scrolled rows tuck UNDER the heading (its
|
|
66
66
|
opaque bg + the ::after fade hide them), not over it; above the gliding
|
|
67
67
|
indicator (z-index 0) too. */
|
|
68
68
|
z-index: 2;
|
|
69
|
-
background: var(--page-bg);
|
|
69
|
+
background: var(--velu-sidebar-bg, var(--page-bg));
|
|
70
70
|
display: flex;
|
|
71
71
|
align-items: center;
|
|
72
72
|
gap: var(--s-2);
|
|
@@ -95,8 +95,8 @@
|
|
|
95
95
|
block-size: var(--s3);
|
|
96
96
|
background: linear-gradient(
|
|
97
97
|
to bottom,
|
|
98
|
-
var(--page-bg),
|
|
99
|
-
color-mix(in srgb, var(--page-bg) 55%, transparent),
|
|
98
|
+
var(--velu-sidebar-bg, var(--page-bg)),
|
|
99
|
+
color-mix(in srgb, var(--velu-sidebar-bg, var(--page-bg)) 55%, transparent),
|
|
100
100
|
transparent
|
|
101
101
|
);
|
|
102
102
|
pointer-events: none;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* Element selectors (Mintlify-compatible).
|
|
2
|
+
|
|
3
|
+
Component roots that have no semantic HTML meaning are rendered as the same
|
|
4
|
+
custom tag names Mintlify uses (`<card>`, `<callout>`, `<code-block>`, …) so
|
|
5
|
+
a project's custom CSS can target them as `card { … }`, exactly like on
|
|
6
|
+
Mintlify. Each element keeps its `velu-*` class, so the component CSS is
|
|
7
|
+
unchanged; this file only gives the unknown tags the display the `div` /
|
|
8
|
+
`span` they replaced had, and exempts them from the `* { max-width }`
|
|
9
|
+
measure reset in base.css (which lists `div` and `span` but obviously not
|
|
10
|
+
these). Class rules (specificity 0,1,0) still beat these tag rules (0,0,1).
|
|
11
|
+
|
|
12
|
+
Roots that must stay native for behaviour or accessibility (`<a>`,
|
|
13
|
+
`<button>`, `<details>`, `<summary>`, `<ul>`, `<textarea>`, headings…)
|
|
14
|
+
carry `data-component="<mintlify-name>"` instead. */
|
|
15
|
+
|
|
16
|
+
/* Block-level: replaced a <div> / <section>. */
|
|
17
|
+
accordion-group,
|
|
18
|
+
advanced-footer,
|
|
19
|
+
api-section,
|
|
20
|
+
callout,
|
|
21
|
+
card,
|
|
22
|
+
card-group,
|
|
23
|
+
chat-assistant-floating-input,
|
|
24
|
+
chat-assistant-sheet-content,
|
|
25
|
+
chat-assistant-sheet-header,
|
|
26
|
+
chat-assistant-disclaimer-text,
|
|
27
|
+
code-block,
|
|
28
|
+
code-group,
|
|
29
|
+
columns,
|
|
30
|
+
contextual-feedback-container,
|
|
31
|
+
contextual-feedback-form,
|
|
32
|
+
feedback-toolbar,
|
|
33
|
+
field,
|
|
34
|
+
mdx-content,
|
|
35
|
+
nav-tabs,
|
|
36
|
+
not-found-container,
|
|
37
|
+
not-found-status-code,
|
|
38
|
+
option-dropdown,
|
|
39
|
+
prompt,
|
|
40
|
+
sidebar-group,
|
|
41
|
+
sidebar-nav-group-divider,
|
|
42
|
+
step,
|
|
43
|
+
steps,
|
|
44
|
+
toc,
|
|
45
|
+
toc-item,
|
|
46
|
+
topbar-right-container,
|
|
47
|
+
tree,
|
|
48
|
+
tree-file,
|
|
49
|
+
update {
|
|
50
|
+
display: block;
|
|
51
|
+
max-width: none;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Inline: replaced a <span>. */
|
|
55
|
+
breadcrumb-item,
|
|
56
|
+
code-block-icon,
|
|
57
|
+
eyebrow,
|
|
58
|
+
method-pill,
|
|
59
|
+
nav-dropdown-item-icon,
|
|
60
|
+
nav-dropdown-item-title,
|
|
61
|
+
pagination-title,
|
|
62
|
+
sidebar-group-icon,
|
|
63
|
+
starter-question-text {
|
|
64
|
+
display: inline;
|
|
65
|
+
max-width: none;
|
|
66
|
+
}
|
|
@@ -22,11 +22,22 @@ import React from 'react';
|
|
|
22
22
|
* @param {string} [props.justify='flex-start']
|
|
23
23
|
* @param {string} [props.align='flex-start']
|
|
24
24
|
*/
|
|
25
|
+
|
|
26
|
+
// React 18 sets props on custom elements (tag names with a hyphen, e.g. the
|
|
27
|
+
// Mintlify-compatible `as="sidebar-group"`) as attributes verbatim, so
|
|
28
|
+
// `className` would come out as a literal className="" attribute. Hand those
|
|
29
|
+
// tags `class` instead. (React 19 maps className for custom elements itself,
|
|
30
|
+
// and accepts `class` too.)
|
|
31
|
+
const isCustomTag = (Tag) => typeof Tag === 'string' && Tag.includes('-');
|
|
32
|
+
const classProp = (Tag, className) =>
|
|
33
|
+
className == null ? {} : { [isCustomTag(Tag) ? 'class' : 'className']: className };
|
|
34
|
+
|
|
25
35
|
export default function Cluster({
|
|
26
36
|
as: Tag = 'div',
|
|
27
37
|
space = 'var(--s1)',
|
|
28
38
|
justify = 'flex-start',
|
|
29
39
|
align = 'flex-start',
|
|
40
|
+
className,
|
|
30
41
|
style,
|
|
31
42
|
children,
|
|
32
43
|
...rest
|
|
@@ -41,6 +52,7 @@ export default function Cluster({
|
|
|
41
52
|
gap: space,
|
|
42
53
|
...style,
|
|
43
54
|
}}
|
|
55
|
+
{...classProp(Tag, className)}
|
|
44
56
|
{...rest}
|
|
45
57
|
>
|
|
46
58
|
{children}
|
|
@@ -20,11 +20,22 @@ import React from 'react';
|
|
|
20
20
|
* @param {number|null} [props.splitAfter=null] 1-based child index; everything
|
|
21
21
|
* after it is pushed to the bottom (margin-block-end:auto on that child)
|
|
22
22
|
*/
|
|
23
|
+
|
|
24
|
+
// React 18 sets props on custom elements (tag names with a hyphen, e.g. the
|
|
25
|
+
// Mintlify-compatible `as="sidebar-group"`) as attributes verbatim, so
|
|
26
|
+
// `className` would come out as a literal className="" attribute. Hand those
|
|
27
|
+
// tags `class` instead. (React 19 maps className for custom elements itself,
|
|
28
|
+
// and accepts `class` too.)
|
|
29
|
+
const isCustomTag = (Tag) => typeof Tag === 'string' && Tag.includes('-');
|
|
30
|
+
const classProp = (Tag, className) =>
|
|
31
|
+
className == null ? {} : { [isCustomTag(Tag) ? 'class' : 'className']: className };
|
|
32
|
+
|
|
23
33
|
const Stack = React.forwardRef(function Stack(
|
|
24
34
|
{
|
|
25
35
|
as: Tag = 'div',
|
|
26
36
|
space = 'var(--s1)',
|
|
27
37
|
splitAfter = null,
|
|
38
|
+
className,
|
|
28
39
|
style,
|
|
29
40
|
children,
|
|
30
41
|
...rest
|
|
@@ -53,6 +64,7 @@ const Stack = React.forwardRef(function Stack(
|
|
|
53
64
|
...(splitAfter ? { blockSize: '100%' } : null),
|
|
54
65
|
...style,
|
|
55
66
|
}}
|
|
67
|
+
{...classProp(Tag, className)}
|
|
56
68
|
{...rest}
|
|
57
69
|
>
|
|
58
70
|
{kids}
|
|
@@ -22,6 +22,16 @@ import React from 'react';
|
|
|
22
22
|
* React-native + SSR-safe + tokenized (vs. the browser-only web component
|
|
23
23
|
* which injects a runtime <style>). Needs its own CSS (styles `> *`).
|
|
24
24
|
*/
|
|
25
|
+
|
|
26
|
+
// React 18 sets props on custom elements (tag names with a hyphen, e.g. the
|
|
27
|
+
// Mintlify-compatible `as="sidebar-group"`) as attributes verbatim, so
|
|
28
|
+
// `className` would come out as a literal className="" attribute. Hand those
|
|
29
|
+
// tags `class` instead. (React 19 maps className for custom elements itself,
|
|
30
|
+
// and accepts `class` too.)
|
|
31
|
+
const isCustomTag = (Tag) => typeof Tag === 'string' && Tag.includes('-');
|
|
32
|
+
const classProp = (Tag, className) =>
|
|
33
|
+
className == null ? {} : { [isCustomTag(Tag) ? 'class' : 'className']: className };
|
|
34
|
+
|
|
25
35
|
export default function Switcher({
|
|
26
36
|
as: Tag = 'div',
|
|
27
37
|
space = 'var(--s1)',
|
|
@@ -42,7 +52,7 @@ export default function Switcher({
|
|
|
42
52
|
|
|
43
53
|
return (
|
|
44
54
|
<Tag
|
|
45
|
-
|
|
55
|
+
{...classProp(Tag, `velu-switcher ${className}`.trim())}
|
|
46
56
|
data-limit-exceeded={exceeded ? '' : undefined}
|
|
47
57
|
style={{
|
|
48
58
|
'--switcher-space': space,
|