@veluai/velu 0.1.11 → 0.1.12
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 +80 -80
- package/dist/cli.js +0 -0
- package/package.json +55 -52
- package/runtime/velu-ui/components/ErrorCard.jsx +138 -138
- package/runtime/velu-ui/components/theme-toggle.css +101 -70
- package/runtime/velu-ui/index.js +46 -46
- package/runtime/velu-ui/lib/component-schemas.js +100 -100
- package/runtime/velu-ui/lib/copyText.js +64 -64
- package/runtime/velu-ui/mdx-components.jsx +105 -105
- package/src/lib/extract-mdx-error.js +170 -0
- package/src/lib/issues.js +159 -0
- package/src/lib/known-components.js +34 -0
- package/src/runtime/App.jsx +1476 -1476
- package/src/runtime/ErrorBoundary.jsx +54 -54
package/README.md
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
# Velu
|
|
2
|
-
|
|
3
|
-
A documentation-site generator with live preview. Scaffold a docs project
|
|
4
|
-
and run it locally with two commands — author your pages in Markdown +
|
|
5
|
-
components, configure the site with a single `velu.json`.
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install -g @veluai/velu
|
|
9
|
-
velu init my-docs
|
|
10
|
-
velu dev my-docs
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
Then open <http://localhost:8358>. Editing any `.mdx` page or `velu.json`
|
|
14
|
-
reloads the browser automatically.
|
|
15
|
-
|
|
16
|
-
> Requires **Node.js 18+**. Prefer not to install globally? Use
|
|
17
|
-
> `npx @veluai/velu init my-docs` and `npx @veluai/velu dev my-docs`.
|
|
18
|
-
|
|
19
|
-
## Commands
|
|
20
|
-
|
|
21
|
-
| Command | What it does |
|
|
22
|
-
| --- | --- |
|
|
23
|
-
| `velu init <dir>` | Scaffold a new docs project into `<dir>` (creates `velu.json`, a favicon, and a set of starter `.mdx` pages). |
|
|
24
|
-
| `velu dev [dir]` | Start the live-preview dev server for the project in `<dir>` (defaults to the current directory). |
|
|
25
|
-
|
|
26
|
-
Set a custom port with the `PORT` env var:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
PORT=5180 velu dev my-docs
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Project layout
|
|
33
|
-
|
|
34
|
-
`velu init` produces a project shaped like this:
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
my-docs/
|
|
38
|
-
├─ velu.json # site config: name, colors, font, favicon, navigation
|
|
39
|
-
├─ favicon.svg
|
|
40
|
-
├─ index.mdx # pages, organized however your navigation references them
|
|
41
|
-
├─ quickstart.mdx
|
|
42
|
-
└─ …
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## `velu.json`
|
|
46
|
-
|
|
47
|
-
`velu.json` drives the whole site — branding and navigation:
|
|
48
|
-
|
|
49
|
-
```json
|
|
50
|
-
{
|
|
51
|
-
"$schema": "https://veluai.com/velu.schema.json",
|
|
52
|
-
"name": "My Docs",
|
|
53
|
-
"colors": { "primary": "#dc143c" },
|
|
54
|
-
"favicon": "/favicon.svg",
|
|
55
|
-
"font": { "family": "Inter" },
|
|
56
|
-
"navigation": {
|
|
57
|
-
"tabs": [
|
|
58
|
-
{
|
|
59
|
-
"tab": "Guides",
|
|
60
|
-
"groups": [
|
|
61
|
-
{ "group": "Getting started", "pages": ["index", "quickstart"] }
|
|
62
|
-
]
|
|
63
|
-
}
|
|
64
|
-
]
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
- **`colors`** — `primary` is required; `light` and `dark` default to `primary`.
|
|
70
|
-
- **`navigation`** — Mintlify-compatible: `products → versions → languages →
|
|
71
|
-
tabs → anchors → groups → pages`. Switchable axes (products, versions,
|
|
72
|
-
languages) become URL path prefixes; the default value of each axis is
|
|
73
|
-
unprefixed. Languages are stored as ISO 639-1 codes and shown with their
|
|
74
|
-
native name.
|
|
75
|
-
|
|
76
|
-
Page labels come from each page's frontmatter `title`.
|
|
77
|
-
|
|
78
|
-
## License
|
|
79
|
-
|
|
80
|
-
Proprietary. © Velu.
|
|
1
|
+
# Velu
|
|
2
|
+
|
|
3
|
+
A documentation-site generator with live preview. Scaffold a docs project
|
|
4
|
+
and run it locally with two commands — author your pages in Markdown +
|
|
5
|
+
components, configure the site with a single `velu.json`.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @veluai/velu
|
|
9
|
+
velu init my-docs
|
|
10
|
+
velu dev my-docs
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then open <http://localhost:8358>. Editing any `.mdx` page or `velu.json`
|
|
14
|
+
reloads the browser automatically.
|
|
15
|
+
|
|
16
|
+
> Requires **Node.js 18+**. Prefer not to install globally? Use
|
|
17
|
+
> `npx @veluai/velu init my-docs` and `npx @veluai/velu dev my-docs`.
|
|
18
|
+
|
|
19
|
+
## Commands
|
|
20
|
+
|
|
21
|
+
| Command | What it does |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| `velu init <dir>` | Scaffold a new docs project into `<dir>` (creates `velu.json`, a favicon, and a set of starter `.mdx` pages). |
|
|
24
|
+
| `velu dev [dir]` | Start the live-preview dev server for the project in `<dir>` (defaults to the current directory). |
|
|
25
|
+
|
|
26
|
+
Set a custom port with the `PORT` env var:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
PORT=5180 velu dev my-docs
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Project layout
|
|
33
|
+
|
|
34
|
+
`velu init` produces a project shaped like this:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
my-docs/
|
|
38
|
+
├─ velu.json # site config: name, colors, font, favicon, navigation
|
|
39
|
+
├─ favicon.svg
|
|
40
|
+
├─ index.mdx # pages, organized however your navigation references them
|
|
41
|
+
├─ quickstart.mdx
|
|
42
|
+
└─ …
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## `velu.json`
|
|
46
|
+
|
|
47
|
+
`velu.json` drives the whole site — branding and navigation:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"$schema": "https://veluai.com/velu.schema.json",
|
|
52
|
+
"name": "My Docs",
|
|
53
|
+
"colors": { "primary": "#dc143c" },
|
|
54
|
+
"favicon": "/favicon.svg",
|
|
55
|
+
"font": { "family": "Inter" },
|
|
56
|
+
"navigation": {
|
|
57
|
+
"tabs": [
|
|
58
|
+
{
|
|
59
|
+
"tab": "Guides",
|
|
60
|
+
"groups": [
|
|
61
|
+
{ "group": "Getting started", "pages": ["index", "quickstart"] }
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- **`colors`** — `primary` is required; `light` and `dark` default to `primary`.
|
|
70
|
+
- **`navigation`** — Mintlify-compatible: `products → versions → languages →
|
|
71
|
+
tabs → anchors → groups → pages`. Switchable axes (products, versions,
|
|
72
|
+
languages) become URL path prefixes; the default value of each axis is
|
|
73
|
+
unprefixed. Languages are stored as ISO 639-1 codes and shown with their
|
|
74
|
+
native name.
|
|
75
|
+
|
|
76
|
+
Page labels come from each page's frontmatter `title`.
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
Proprietary. © Velu.
|
package/dist/cli.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,52 +1,55 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@veluai/velu",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"bin": "./dist/cli.js",
|
|
6
|
-
"publishConfig": {
|
|
7
|
-
"access": "public"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"dist/**",
|
|
11
|
-
"src/runtime/**",
|
|
12
|
-
"src/navigation.js",
|
|
13
|
-
"src/template.html",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"@
|
|
27
|
-
"@
|
|
28
|
-
"@
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"react-
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
}
|
|
52
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@veluai/velu",
|
|
3
|
+
"version": "0.1.12",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": "./dist/cli.js",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist/**",
|
|
11
|
+
"src/runtime/**",
|
|
12
|
+
"src/navigation.js",
|
|
13
|
+
"src/template.html",
|
|
14
|
+
"src/lib/issues.js",
|
|
15
|
+
"src/lib/extract-mdx-error.js",
|
|
16
|
+
"src/lib/known-components.js",
|
|
17
|
+
"runtime/velu-ui/**",
|
|
18
|
+
"schema/**",
|
|
19
|
+
"templates/**"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "node scripts/build.mjs",
|
|
23
|
+
"prepack": "node scripts/build.mjs"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@icons-pack/react-simple-icons": ">=13.0.0 <13.13.0",
|
|
27
|
+
"@mdx-js/mdx": "^3.1.1",
|
|
28
|
+
"@mdx-js/react": "^3.1.1",
|
|
29
|
+
"@mdx-js/rollup": "^3.1.1",
|
|
30
|
+
"@tailwindcss/vite": "^4.1.0",
|
|
31
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
32
|
+
"chokidar": "^3.6.0",
|
|
33
|
+
"estree-util-value-to-estree": "^3.5.0",
|
|
34
|
+
"express": "^4.21.1",
|
|
35
|
+
"github-slugger": "^2.0.0",
|
|
36
|
+
"iso-639-1": "^3.1.5",
|
|
37
|
+
"lucide-react": "^0.460.0",
|
|
38
|
+
"mdast-util-to-string": "^4.0.0",
|
|
39
|
+
"prism-react-renderer": "^2.4.0",
|
|
40
|
+
"prismjs": "^1.29.0",
|
|
41
|
+
"react": "^18.3.1",
|
|
42
|
+
"react-dom": "^18.3.1",
|
|
43
|
+
"react-router-dom": "^6.28.0",
|
|
44
|
+
"rehype-slug": "^6.0.0",
|
|
45
|
+
"remark-frontmatter": "^5.0.0",
|
|
46
|
+
"remark-gfm": "^4.0.1",
|
|
47
|
+
"remark-mdx-frontmatter": "^5.2.0",
|
|
48
|
+
"tailwindcss": "^4.1.0",
|
|
49
|
+
"unist-util-visit": "^5.1.0",
|
|
50
|
+
"vite": "^5.4.11"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"esbuild": "^0.28.0"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,138 +1,138 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* ErrorCard — a branded, self-contained card that renders ONE Velu "issue"
|
|
5
|
-
* (an MDX or velu.json problem). Used by the dev server's per-page error
|
|
6
|
-
* boundary. Deliberately presentational and dependency-free (no other Velu
|
|
7
|
-
* components, no effects) so it can never fail while reporting a failure.
|
|
8
|
-
*
|
|
9
|
-
* Styled with inline styles + design tokens (with hard fallbacks), so it looks
|
|
10
|
-
* right even when the page's own CSS hasn't loaded.
|
|
11
|
-
*/
|
|
12
|
-
const DANGER = 'var(--danger-stroke-color, #ef4444)';
|
|
13
|
-
const DANGER_BG =
|
|
14
|
-
'var(--danger-bg-color, color-mix(in srgb, #ef4444 7%, transparent))';
|
|
15
|
-
const MUTED = 'var(--muted-color, #6b7280)';
|
|
16
|
-
const TEXT = 'var(--text-color, #111827)';
|
|
17
|
-
|
|
18
|
-
export default function ErrorCard({
|
|
19
|
-
label,
|
|
20
|
-
title,
|
|
21
|
-
file,
|
|
22
|
-
line,
|
|
23
|
-
column,
|
|
24
|
-
frame,
|
|
25
|
-
detail,
|
|
26
|
-
hint,
|
|
27
|
-
suggestion,
|
|
28
|
-
}) {
|
|
29
|
-
const loc = file
|
|
30
|
-
? `${file}${line ? `:${line}${column ? `:${column}` : ''}` : ''}`
|
|
31
|
-
: null;
|
|
32
|
-
|
|
33
|
-
return (
|
|
34
|
-
<div
|
|
35
|
-
role="alert"
|
|
36
|
-
style={{
|
|
37
|
-
border: `1px solid ${DANGER}`,
|
|
38
|
-
borderRadius: 'var(--radius-md, 10px)',
|
|
39
|
-
background: DANGER_BG,
|
|
40
|
-
padding: 'var(--s2, 1rem)',
|
|
41
|
-
margin: 'var(--s2, 1rem) 0',
|
|
42
|
-
fontFamily: 'var(--font-sans, system-ui, sans-serif)',
|
|
43
|
-
color: TEXT,
|
|
44
|
-
lineHeight: 1.5,
|
|
45
|
-
}}
|
|
46
|
-
>
|
|
47
|
-
<div
|
|
48
|
-
style={{
|
|
49
|
-
display: 'flex',
|
|
50
|
-
gap: '0.6rem',
|
|
51
|
-
alignItems: 'center',
|
|
52
|
-
flexWrap: 'wrap',
|
|
53
|
-
}}
|
|
54
|
-
>
|
|
55
|
-
<span
|
|
56
|
-
style={{
|
|
57
|
-
fontFamily: 'var(--font-mono, ui-monospace, monospace)',
|
|
58
|
-
fontSize: 11,
|
|
59
|
-
textTransform: 'uppercase',
|
|
60
|
-
letterSpacing: '0.06em',
|
|
61
|
-
fontWeight: 600,
|
|
62
|
-
color: DANGER,
|
|
63
|
-
border: `1px solid ${DANGER}`,
|
|
64
|
-
borderRadius: 999,
|
|
65
|
-
padding: '2px 9px',
|
|
66
|
-
whiteSpace: 'nowrap',
|
|
67
|
-
}}
|
|
68
|
-
>
|
|
69
|
-
{label}
|
|
70
|
-
</span>
|
|
71
|
-
</div>
|
|
72
|
-
|
|
73
|
-
{title && (
|
|
74
|
-
<div style={{ marginTop: '0.6rem', fontWeight: 600, fontSize: '1.05rem' }}>
|
|
75
|
-
{title}
|
|
76
|
-
</div>
|
|
77
|
-
)}
|
|
78
|
-
|
|
79
|
-
{loc && (
|
|
80
|
-
<div
|
|
81
|
-
style={{
|
|
82
|
-
display: 'inline-block',
|
|
83
|
-
marginTop: '0.7rem',
|
|
84
|
-
fontFamily: 'var(--font-mono, ui-monospace, monospace)',
|
|
85
|
-
fontSize: 15,
|
|
86
|
-
fontWeight: 600,
|
|
87
|
-
letterSpacing: '0.01em',
|
|
88
|
-
color: DANGER,
|
|
89
|
-
background: 'var(--danger-bg-color, rgba(239,68,68,0.12))',
|
|
90
|
-
border: `1px solid ${DANGER}`,
|
|
91
|
-
borderRadius: 7,
|
|
92
|
-
padding: '7px 11px',
|
|
93
|
-
}}
|
|
94
|
-
>
|
|
95
|
-
{loc}
|
|
96
|
-
</div>
|
|
97
|
-
)}
|
|
98
|
-
{detail && (
|
|
99
|
-
<div style={{ marginTop: '0.25rem', color: MUTED }}>{detail}</div>
|
|
100
|
-
)}
|
|
101
|
-
|
|
102
|
-
{frame && (
|
|
103
|
-
<pre
|
|
104
|
-
style={{
|
|
105
|
-
marginTop: '0.75rem',
|
|
106
|
-
marginBottom: 0,
|
|
107
|
-
padding: '0.75rem 0.9rem',
|
|
108
|
-
overflow: 'auto',
|
|
109
|
-
background: 'var(--code-bg-color, rgba(0,0,0,0.05))',
|
|
110
|
-
borderRadius: 'var(--radius-sm, 6px)',
|
|
111
|
-
fontFamily: 'var(--font-mono, ui-monospace, monospace)',
|
|
112
|
-
fontSize: 12.5,
|
|
113
|
-
lineHeight: 1.5,
|
|
114
|
-
color: TEXT,
|
|
115
|
-
}}
|
|
116
|
-
>
|
|
117
|
-
{frame}
|
|
118
|
-
</pre>
|
|
119
|
-
)}
|
|
120
|
-
|
|
121
|
-
{suggestion && (
|
|
122
|
-
<div style={{ marginTop: '0.75rem' }}>
|
|
123
|
-
Did you mean{' '}
|
|
124
|
-
<code style={{ fontWeight: 600, color: DANGER }}>
|
|
125
|
-
{`<${suggestion}>`}
|
|
126
|
-
</code>
|
|
127
|
-
?
|
|
128
|
-
</div>
|
|
129
|
-
)}
|
|
130
|
-
|
|
131
|
-
{hint && (
|
|
132
|
-
<div style={{ marginTop: '0.6rem', color: MUTED, fontSize: '0.92rem' }}>
|
|
133
|
-
{hint}
|
|
134
|
-
</div>
|
|
135
|
-
)}
|
|
136
|
-
</div>
|
|
137
|
-
);
|
|
138
|
-
}
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ErrorCard — a branded, self-contained card that renders ONE Velu "issue"
|
|
5
|
+
* (an MDX or velu.json problem). Used by the dev server's per-page error
|
|
6
|
+
* boundary. Deliberately presentational and dependency-free (no other Velu
|
|
7
|
+
* components, no effects) so it can never fail while reporting a failure.
|
|
8
|
+
*
|
|
9
|
+
* Styled with inline styles + design tokens (with hard fallbacks), so it looks
|
|
10
|
+
* right even when the page's own CSS hasn't loaded.
|
|
11
|
+
*/
|
|
12
|
+
const DANGER = 'var(--danger-stroke-color, #ef4444)';
|
|
13
|
+
const DANGER_BG =
|
|
14
|
+
'var(--danger-bg-color, color-mix(in srgb, #ef4444 7%, transparent))';
|
|
15
|
+
const MUTED = 'var(--muted-color, #6b7280)';
|
|
16
|
+
const TEXT = 'var(--text-color, #111827)';
|
|
17
|
+
|
|
18
|
+
export default function ErrorCard({
|
|
19
|
+
label,
|
|
20
|
+
title,
|
|
21
|
+
file,
|
|
22
|
+
line,
|
|
23
|
+
column,
|
|
24
|
+
frame,
|
|
25
|
+
detail,
|
|
26
|
+
hint,
|
|
27
|
+
suggestion,
|
|
28
|
+
}) {
|
|
29
|
+
const loc = file
|
|
30
|
+
? `${file}${line ? `:${line}${column ? `:${column}` : ''}` : ''}`
|
|
31
|
+
: null;
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<div
|
|
35
|
+
role="alert"
|
|
36
|
+
style={{
|
|
37
|
+
border: `1px solid ${DANGER}`,
|
|
38
|
+
borderRadius: 'var(--radius-md, 10px)',
|
|
39
|
+
background: DANGER_BG,
|
|
40
|
+
padding: 'var(--s2, 1rem)',
|
|
41
|
+
margin: 'var(--s2, 1rem) 0',
|
|
42
|
+
fontFamily: 'var(--font-sans, system-ui, sans-serif)',
|
|
43
|
+
color: TEXT,
|
|
44
|
+
lineHeight: 1.5,
|
|
45
|
+
}}
|
|
46
|
+
>
|
|
47
|
+
<div
|
|
48
|
+
style={{
|
|
49
|
+
display: 'flex',
|
|
50
|
+
gap: '0.6rem',
|
|
51
|
+
alignItems: 'center',
|
|
52
|
+
flexWrap: 'wrap',
|
|
53
|
+
}}
|
|
54
|
+
>
|
|
55
|
+
<span
|
|
56
|
+
style={{
|
|
57
|
+
fontFamily: 'var(--font-mono, ui-monospace, monospace)',
|
|
58
|
+
fontSize: 11,
|
|
59
|
+
textTransform: 'uppercase',
|
|
60
|
+
letterSpacing: '0.06em',
|
|
61
|
+
fontWeight: 600,
|
|
62
|
+
color: DANGER,
|
|
63
|
+
border: `1px solid ${DANGER}`,
|
|
64
|
+
borderRadius: 999,
|
|
65
|
+
padding: '2px 9px',
|
|
66
|
+
whiteSpace: 'nowrap',
|
|
67
|
+
}}
|
|
68
|
+
>
|
|
69
|
+
{label}
|
|
70
|
+
</span>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
{title && (
|
|
74
|
+
<div style={{ marginTop: '0.6rem', fontWeight: 600, fontSize: '1.05rem' }}>
|
|
75
|
+
{title}
|
|
76
|
+
</div>
|
|
77
|
+
)}
|
|
78
|
+
|
|
79
|
+
{loc && (
|
|
80
|
+
<div
|
|
81
|
+
style={{
|
|
82
|
+
display: 'inline-block',
|
|
83
|
+
marginTop: '0.7rem',
|
|
84
|
+
fontFamily: 'var(--font-mono, ui-monospace, monospace)',
|
|
85
|
+
fontSize: 15,
|
|
86
|
+
fontWeight: 600,
|
|
87
|
+
letterSpacing: '0.01em',
|
|
88
|
+
color: DANGER,
|
|
89
|
+
background: 'var(--danger-bg-color, rgba(239,68,68,0.12))',
|
|
90
|
+
border: `1px solid ${DANGER}`,
|
|
91
|
+
borderRadius: 7,
|
|
92
|
+
padding: '7px 11px',
|
|
93
|
+
}}
|
|
94
|
+
>
|
|
95
|
+
{loc}
|
|
96
|
+
</div>
|
|
97
|
+
)}
|
|
98
|
+
{detail && (
|
|
99
|
+
<div style={{ marginTop: '0.25rem', color: MUTED }}>{detail}</div>
|
|
100
|
+
)}
|
|
101
|
+
|
|
102
|
+
{frame && (
|
|
103
|
+
<pre
|
|
104
|
+
style={{
|
|
105
|
+
marginTop: '0.75rem',
|
|
106
|
+
marginBottom: 0,
|
|
107
|
+
padding: '0.75rem 0.9rem',
|
|
108
|
+
overflow: 'auto',
|
|
109
|
+
background: 'var(--code-bg-color, rgba(0,0,0,0.05))',
|
|
110
|
+
borderRadius: 'var(--radius-sm, 6px)',
|
|
111
|
+
fontFamily: 'var(--font-mono, ui-monospace, monospace)',
|
|
112
|
+
fontSize: 12.5,
|
|
113
|
+
lineHeight: 1.5,
|
|
114
|
+
color: TEXT,
|
|
115
|
+
}}
|
|
116
|
+
>
|
|
117
|
+
{frame}
|
|
118
|
+
</pre>
|
|
119
|
+
)}
|
|
120
|
+
|
|
121
|
+
{suggestion && (
|
|
122
|
+
<div style={{ marginTop: '0.75rem' }}>
|
|
123
|
+
Did you mean{' '}
|
|
124
|
+
<code style={{ fontWeight: 600, color: DANGER }}>
|
|
125
|
+
{`<${suggestion}>`}
|
|
126
|
+
</code>
|
|
127
|
+
?
|
|
128
|
+
</div>
|
|
129
|
+
)}
|
|
130
|
+
|
|
131
|
+
{hint && (
|
|
132
|
+
<div style={{ marginTop: '0.6rem', color: MUTED, fontSize: '0.92rem' }}>
|
|
133
|
+
{hint}
|
|
134
|
+
</div>
|
|
135
|
+
)}
|
|
136
|
+
</div>
|
|
137
|
+
);
|
|
138
|
+
}
|