@airalogy/aimd-renderer 2.5.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/README.zh-CN.md +6 -5
- package/dist/aimd-renderer.css +1 -1
- package/dist/common/processor.d.ts.map +1 -1
- package/dist/common/unified-token-renderer.d.ts.map +1 -1
- package/dist/html.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +262 -217
- package/dist/{processor-B2mByErv.js → processor-CHbNEcN8.js} +2687 -2094
- package/dist/vue/index.d.ts +1 -1
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/vue-renderer.d.ts +22 -1
- package/dist/vue/vue-renderer.d.ts.map +1 -1
- package/dist/vue.js +10 -9
- package/package.json +6 -6
- package/src/__tests__/renderer.test.ts +191 -1
- package/src/common/processor.ts +173 -41
- package/src/common/unified-token-renderer.ts +104 -24
- package/src/index.ts +3 -0
- package/src/styles/katex.css +109 -0
- package/src/vue/index.ts +3 -0
- package/src/vue/vue-renderer.ts +318 -48
|
@@ -13,6 +13,13 @@ import type {
|
|
|
13
13
|
} from "@airalogy/aimd-core/types"
|
|
14
14
|
import type { AimdNode, QuizPreviewOptions, RenderContext } from "@airalogy/aimd-core/types"
|
|
15
15
|
import type { ExtractedAimdFields } from "@airalogy/aimd-core/types"
|
|
16
|
+
import {
|
|
17
|
+
formatAimdExampleValue,
|
|
18
|
+
getAimdFieldDescription,
|
|
19
|
+
getAimdFieldDisplayLabel,
|
|
20
|
+
getAimdFieldExamples,
|
|
21
|
+
getAimdFieldTitle,
|
|
22
|
+
} from "@airalogy/aimd-core/utils"
|
|
16
23
|
import type { AimdRendererI18nOptions, AimdRendererMessages } from "../locales"
|
|
17
24
|
import type { AimdComponentRenderer, ElementRenderer, ShikiHighlighter, VueRendererOptions } from "../vue/vue-renderer"
|
|
18
25
|
import type { AimdRendererOptions, RenderResult } from "./processor"
|
|
@@ -226,6 +233,74 @@ function buildScaleBandChildren(quizNode: AimdQuizNode): VNode[] {
|
|
|
226
233
|
]
|
|
227
234
|
}
|
|
228
235
|
|
|
236
|
+
interface FieldMetadataHelp {
|
|
237
|
+
tooltip: string
|
|
238
|
+
description?: string
|
|
239
|
+
examples: string[]
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function getFieldHelpText(definition: { kwargs?: Record<string, unknown> } | undefined): FieldMetadataHelp {
|
|
243
|
+
const description = getAimdFieldDescription(definition)
|
|
244
|
+
const examples = getAimdFieldExamples(definition)
|
|
245
|
+
.map(formatAimdExampleValue)
|
|
246
|
+
.map(example => example.trim())
|
|
247
|
+
.filter(Boolean)
|
|
248
|
+
const exampleText = examples.length > 0 ? `e.g. ${examples.join(", ")}` : undefined
|
|
249
|
+
const tooltipLines = [description, exampleText].filter((value): value is string => Boolean(value))
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
tooltip: tooltipLines.join("\n"),
|
|
253
|
+
description,
|
|
254
|
+
examples,
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function renderFieldMetadataPopover(help: FieldMetadataHelp): VNode | null {
|
|
259
|
+
if (!help.description && help.examples.length === 0) {
|
|
260
|
+
return null
|
|
261
|
+
}
|
|
262
|
+
const children: VNode[] = []
|
|
263
|
+
if (help.description) {
|
|
264
|
+
children.push(h("span", {
|
|
265
|
+
class: "aimd-field__metadata-popover-line",
|
|
266
|
+
}, help.description))
|
|
267
|
+
}
|
|
268
|
+
if (help.examples.length > 0) {
|
|
269
|
+
children.push(h("span", { class: "aimd-field__metadata-examples" }, [
|
|
270
|
+
h("span", { class: "aimd-field__metadata-examples-label" }, "e.g."),
|
|
271
|
+
...help.examples.map((example, index) => h("span", {
|
|
272
|
+
key: `${index}-${example}`,
|
|
273
|
+
class: "aimd-field__metadata-example",
|
|
274
|
+
}, example)),
|
|
275
|
+
]))
|
|
276
|
+
}
|
|
277
|
+
return h("span", {
|
|
278
|
+
class: "aimd-field__metadata-popover",
|
|
279
|
+
role: "tooltip",
|
|
280
|
+
}, children)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function renderFieldName(id: string, definition: { kwargs?: Record<string, unknown> } | undefined): VNode {
|
|
284
|
+
const displayTitle = getAimdFieldDisplayLabel(id, definition)
|
|
285
|
+
const hasCustomTitle = getAimdFieldTitle(definition) !== undefined && displayTitle !== id
|
|
286
|
+
const help = getFieldHelpText(definition)
|
|
287
|
+
const hasHelp = Boolean(help.description) || help.examples.length > 0
|
|
288
|
+
|
|
289
|
+
return h("span", {
|
|
290
|
+
class: [
|
|
291
|
+
"aimd-field__name",
|
|
292
|
+
(hasCustomTitle || hasHelp) ? "aimd-field__name--with-metadata" : undefined,
|
|
293
|
+
hasHelp ? "aimd-field__metadata-host" : undefined,
|
|
294
|
+
],
|
|
295
|
+
tabindex: hasHelp ? 0 : undefined,
|
|
296
|
+
"aria-label": help.tooltip || undefined,
|
|
297
|
+
}, [
|
|
298
|
+
h("span", { class: "aimd-field__title" }, displayTitle),
|
|
299
|
+
hasCustomTitle ? h("span", { class: "aimd-field__key" }, id) : null,
|
|
300
|
+
renderFieldMetadataPopover(help),
|
|
301
|
+
])
|
|
302
|
+
}
|
|
303
|
+
|
|
229
304
|
/**
|
|
230
305
|
* Render preview tag for AIMD field
|
|
231
306
|
*/
|
|
@@ -234,6 +309,7 @@ function renderPreviewTag(
|
|
|
234
309
|
id: string,
|
|
235
310
|
messages: AimdRendererMessages,
|
|
236
311
|
columns?: string[],
|
|
312
|
+
definition?: { kwargs?: Record<string, unknown>, subvars?: Record<string, { kwargs?: Record<string, unknown> }> },
|
|
237
313
|
): VNode {
|
|
238
314
|
const scopeKey = getScopeKey(scope)
|
|
239
315
|
const scopeLabel = getAimdRendererScopeLabel(scope, messages)
|
|
@@ -241,17 +317,19 @@ function renderPreviewTag(
|
|
|
241
317
|
// var_table: render tag with table preview inside
|
|
242
318
|
if (scope === "var_table") {
|
|
243
319
|
const children: VNode[] = [
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
320
|
+
h("div", { class: "aimd-field__header" }, [
|
|
321
|
+
h("span", { class: "aimd-field__scope" }, messages.scope.table),
|
|
322
|
+
renderFieldName(id, definition),
|
|
323
|
+
]),
|
|
248
324
|
]
|
|
249
325
|
// Add table preview inside the container
|
|
250
326
|
if (columns && columns.length > 0) {
|
|
251
327
|
children.push(
|
|
252
328
|
h("table", { class: "aimd-field__table-preview" }, [
|
|
253
329
|
h("thead", [
|
|
254
|
-
|
|
330
|
+
h("tr", columns.map(col => h("th", {
|
|
331
|
+
"data-column-id": col,
|
|
332
|
+
}, [renderFieldName(col, definition?.subvars?.[col])]))),
|
|
255
333
|
]),
|
|
256
334
|
h("tbody", [
|
|
257
335
|
h("tr", columns.map(() => h("td", "..."))),
|
|
@@ -272,10 +350,10 @@ function renderPreviewTag(
|
|
|
272
350
|
"class": `aimd-field aimd-field--${classSuffix}`,
|
|
273
351
|
"data-aimd-type": scopeKey,
|
|
274
352
|
"data-aimd-id": id,
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
353
|
+
}, [
|
|
354
|
+
h("span", { class: "aimd-field__scope" }, scopeLabel),
|
|
355
|
+
renderFieldName(id, definition),
|
|
356
|
+
])
|
|
279
357
|
}
|
|
280
358
|
|
|
281
359
|
/**
|
|
@@ -299,19 +377,20 @@ function createAimdRenderers(options: UnifiedTokenRendererOptions): Record<strin
|
|
|
299
377
|
resolveQuizPreviewOptions(getMode(), options.quizPreview)
|
|
300
378
|
|
|
301
379
|
return {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
380
|
+
var: async (node, ctx, children) => {
|
|
381
|
+
const varNode = node as AimdVarNode
|
|
382
|
+
const { id, scope } = varNode
|
|
383
|
+
const definition = varNode.definition
|
|
305
384
|
|
|
306
|
-
|
|
385
|
+
if (isPreview()) {
|
|
307
386
|
if (PreviewRenderer) {
|
|
308
387
|
return h(PreviewRenderer, { type: "var" }, {
|
|
309
388
|
default: () => children,
|
|
310
389
|
name: () => id,
|
|
311
390
|
})
|
|
312
391
|
}
|
|
313
|
-
|
|
314
|
-
|
|
392
|
+
return renderPreviewTag(scope, id, messages, undefined, definition)
|
|
393
|
+
}
|
|
315
394
|
|
|
316
395
|
// Edit mode
|
|
317
396
|
if (getTokenProps && AIMDItem) {
|
|
@@ -325,12 +404,13 @@ function createAimdRenderers(options: UnifiedTokenRendererOptions): Record<strin
|
|
|
325
404
|
}
|
|
326
405
|
}
|
|
327
406
|
|
|
328
|
-
|
|
329
|
-
|
|
407
|
+
return renderPreviewTag(scope, id, messages, undefined, definition)
|
|
408
|
+
},
|
|
330
409
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
410
|
+
var_table: async (node, ctx, children) => {
|
|
411
|
+
const tableNode = node as AimdVarTableNode
|
|
412
|
+
const { id, scope, columns } = tableNode
|
|
413
|
+
const definition = tableNode.definition
|
|
334
414
|
|
|
335
415
|
if (isPreview()) {
|
|
336
416
|
if (PreviewRenderer) {
|
|
@@ -340,8 +420,8 @@ function createAimdRenderers(options: UnifiedTokenRendererOptions): Record<strin
|
|
|
340
420
|
})
|
|
341
421
|
}
|
|
342
422
|
// Preview mode: render inline tag with columns info
|
|
343
|
-
|
|
344
|
-
|
|
423
|
+
return renderPreviewTag(scope, id, messages, columns, definition)
|
|
424
|
+
}
|
|
345
425
|
|
|
346
426
|
// Edit mode
|
|
347
427
|
if (getTokenProps && AIMDTag) {
|
|
@@ -349,8 +429,8 @@ function createAimdRenderers(options: UnifiedTokenRendererOptions): Record<strin
|
|
|
349
429
|
return h(AIMDTag, { ...item, props: columns })
|
|
350
430
|
}
|
|
351
431
|
|
|
352
|
-
|
|
353
|
-
|
|
432
|
+
return renderPreviewTag(scope, id, messages, columns, definition)
|
|
433
|
+
},
|
|
354
434
|
|
|
355
435
|
quiz: async (node, ctx, children) => {
|
|
356
436
|
const quizNode = node as AimdQuizNode
|
package/src/index.ts
CHANGED
|
@@ -51,9 +51,12 @@ export {
|
|
|
51
51
|
createEmbeddedRenderer,
|
|
52
52
|
createMermaidRenderer,
|
|
53
53
|
createStepCardRenderer,
|
|
54
|
+
loadShikiHighlighter,
|
|
55
|
+
type CodeBlockRendererOptions,
|
|
54
56
|
type ElementRenderer,
|
|
55
57
|
hastToVue,
|
|
56
58
|
renderToVNodes,
|
|
59
|
+
type LoadShikiHighlighterOptions,
|
|
57
60
|
type AimdStepCardRendererOptions,
|
|
58
61
|
type ShikiHighlighter,
|
|
59
62
|
type VueRendererOptions,
|
package/src/styles/katex.css
CHANGED
|
@@ -1,2 +1,111 @@
|
|
|
1
1
|
/* Re-export KaTeX base styles for AIMD renderer consumers. */
|
|
2
2
|
@import "katex/dist/katex.min.css";
|
|
3
|
+
|
|
4
|
+
.aimd-field__metadata-host {
|
|
5
|
+
position: relative;
|
|
6
|
+
cursor: help;
|
|
7
|
+
outline: none;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.aimd-field__metadata-host:hover,
|
|
11
|
+
.aimd-field__metadata-host:focus,
|
|
12
|
+
.aimd-field__metadata-host:focus-within {
|
|
13
|
+
z-index: 90;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.aimd-field__metadata-host:focus-visible {
|
|
17
|
+
border-radius: 4px;
|
|
18
|
+
box-shadow: 0 0 0 2px rgba(65, 129, 253, 0.24);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.aimd-field__metadata-host .aimd-field__title {
|
|
22
|
+
text-decoration-line: underline;
|
|
23
|
+
text-decoration-style: dotted;
|
|
24
|
+
text-decoration-color: rgba(15, 23, 42, 0.36);
|
|
25
|
+
text-underline-offset: 3px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.aimd-field__metadata-popover {
|
|
29
|
+
position: absolute;
|
|
30
|
+
z-index: 80;
|
|
31
|
+
inset-inline-start: 0;
|
|
32
|
+
top: calc(100% + 7px);
|
|
33
|
+
display: inline-flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
gap: 4px;
|
|
36
|
+
width: max-content;
|
|
37
|
+
min-width: 220px;
|
|
38
|
+
max-width: min(360px, 82vw);
|
|
39
|
+
padding: 8px 10px;
|
|
40
|
+
border-radius: 8px;
|
|
41
|
+
background: rgba(15, 23, 42, 0.96);
|
|
42
|
+
color: #f8fafc;
|
|
43
|
+
box-shadow: 0 12px 30px rgba(15, 23, 42, 0.28);
|
|
44
|
+
font-size: 12px;
|
|
45
|
+
font-weight: 500;
|
|
46
|
+
line-height: 1.45;
|
|
47
|
+
letter-spacing: 0;
|
|
48
|
+
text-align: left;
|
|
49
|
+
text-transform: none;
|
|
50
|
+
white-space: normal;
|
|
51
|
+
pointer-events: none;
|
|
52
|
+
opacity: 0;
|
|
53
|
+
visibility: hidden;
|
|
54
|
+
transform: translateY(-2px);
|
|
55
|
+
transition:
|
|
56
|
+
opacity 120ms ease,
|
|
57
|
+
transform 120ms ease,
|
|
58
|
+
visibility 120ms ease;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.aimd-field__metadata-popover::before {
|
|
62
|
+
content: "";
|
|
63
|
+
position: absolute;
|
|
64
|
+
inset-inline-start: 14px;
|
|
65
|
+
top: -5px;
|
|
66
|
+
width: 10px;
|
|
67
|
+
height: 10px;
|
|
68
|
+
background: rgba(15, 23, 42, 0.96);
|
|
69
|
+
transform: rotate(45deg);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.aimd-field__metadata-popover-line {
|
|
73
|
+
display: block;
|
|
74
|
+
color: inherit;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.aimd-field__metadata-examples {
|
|
78
|
+
display: flex;
|
|
79
|
+
flex-wrap: wrap;
|
|
80
|
+
align-items: center;
|
|
81
|
+
gap: 4px;
|
|
82
|
+
padding-top: 1px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.aimd-field__metadata-examples-label {
|
|
86
|
+
color: rgba(226, 232, 240, 0.78);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.aimd-field__metadata-example {
|
|
90
|
+
display: inline-flex;
|
|
91
|
+
align-items: center;
|
|
92
|
+
max-width: 100%;
|
|
93
|
+
padding: 1px 6px;
|
|
94
|
+
border: 1px solid rgba(248, 250, 252, 0.18);
|
|
95
|
+
border-radius: 5px;
|
|
96
|
+
background: rgba(248, 250, 252, 0.1);
|
|
97
|
+
color: #f8fafc;
|
|
98
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
|
|
99
|
+
font-size: 11px;
|
|
100
|
+
font-weight: 600;
|
|
101
|
+
line-height: 1.45;
|
|
102
|
+
overflow-wrap: anywhere;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.aimd-field__metadata-host:hover > .aimd-field__metadata-popover,
|
|
106
|
+
.aimd-field__metadata-host:focus > .aimd-field__metadata-popover,
|
|
107
|
+
.aimd-field__metadata-host:focus-within > .aimd-field__metadata-popover {
|
|
108
|
+
opacity: 1;
|
|
109
|
+
visibility: visible;
|
|
110
|
+
transform: translateY(0);
|
|
111
|
+
}
|
package/src/vue/index.ts
CHANGED
|
@@ -12,9 +12,12 @@ export {
|
|
|
12
12
|
createEmbeddedRenderer,
|
|
13
13
|
createMermaidRenderer,
|
|
14
14
|
createStepCardRenderer,
|
|
15
|
+
loadShikiHighlighter,
|
|
16
|
+
type CodeBlockRendererOptions,
|
|
15
17
|
type ElementRenderer,
|
|
16
18
|
hastToVue,
|
|
17
19
|
renderToVNodes,
|
|
20
|
+
type LoadShikiHighlighterOptions,
|
|
18
21
|
type AimdStepCardRendererOptions,
|
|
19
22
|
type ShikiHighlighter,
|
|
20
23
|
type VueRendererOptions,
|