scoobie 17.0.0 → 17.1.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 +18 -0
- package/package.json +4 -2
- package/remark/mermaid/utils.js +28 -7
- package/src/components/CodeBlock.tsx +18 -7
- package/src/private/MdxCodeBlock.tsx +18 -2
package/README.md
CHANGED
|
@@ -194,6 +194,24 @@ sequenceDiagram
|
|
|
194
194
|
```
|
|
195
195
|
````
|
|
196
196
|
|
|
197
|
+
Some Mermaid diagrams allow for YAML frontmatter. Scoobie has extended this by allowing a deep merge of the Mermaid configuration
|
|
198
|
+
with a special `overrides` key in the frontmatter. This could be useful for diagram-specific configuration that is not otherwise easy to set.
|
|
199
|
+
|
|
200
|
+
````markdown
|
|
201
|
+
```mermaid
|
|
202
|
+
---
|
|
203
|
+
overrides:
|
|
204
|
+
gantt:
|
|
205
|
+
useWidth: 500
|
|
206
|
+
---
|
|
207
|
+
gantt
|
|
208
|
+
title A Gantt Diagram
|
|
209
|
+
dateFormat YYYY-MM-DD
|
|
210
|
+
section Section
|
|
211
|
+
A task :a1, 2014-01-01, 30d
|
|
212
|
+
```
|
|
213
|
+
````
|
|
214
|
+
|
|
197
215
|
[mermaid live editor]: https://mermaidjs.github.io/mermaid-live-editor
|
|
198
216
|
|
|
199
217
|
### Headings
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"sideEffects": false,
|
|
7
|
-
"version": "17.
|
|
7
|
+
"version": "17.1.0",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@capsizecss/core": "^4.0.0",
|
|
10
10
|
"@mdx-js/react": "^1.6.22",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"@vanilla-extract/css-utils": "^0.1.1",
|
|
14
14
|
"babel-loader": "^9.0.0",
|
|
15
15
|
"clsx": "^2.0.0",
|
|
16
|
+
"deepmerge-ts": "^7.1.0",
|
|
16
17
|
"find-up": "^5.0.0",
|
|
17
18
|
"fs-extra": "^11.0.0",
|
|
18
19
|
"jsonc-parser": "^3.0.0",
|
|
@@ -26,7 +27,8 @@
|
|
|
26
27
|
"unist-util-visit": "^2.0.3",
|
|
27
28
|
"unist-util-visit-parents": "^3.1.1",
|
|
28
29
|
"webpack-merge": "^6.0.0",
|
|
29
|
-
"which": "^4.0.0"
|
|
30
|
+
"which": "^4.0.0",
|
|
31
|
+
"yaml": "^2.5.0"
|
|
30
32
|
},
|
|
31
33
|
"devDependencies": {
|
|
32
34
|
"@changesets/cli": "2.27.7",
|
package/remark/mermaid/utils.js
CHANGED
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
const crypto = require('crypto');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
|
|
7
|
+
const { deepmerge } = require('deepmerge-ts');
|
|
7
8
|
const fs = require('fs-extra');
|
|
8
9
|
const mermaidIsomorphic = require('mermaid-isomorphic');
|
|
9
10
|
const { optimize } = require('svgo');
|
|
11
|
+
const YAML = require('yaml');
|
|
10
12
|
|
|
11
13
|
const { MERMAID_DIR, PLUGIN_NAME } = require('./constants');
|
|
12
14
|
|
|
@@ -70,16 +72,28 @@ const generateFilePaths = (rootDir, data) => {
|
|
|
70
72
|
function createMermaidRenderer(options) {
|
|
71
73
|
const renderer = mermaidIsomorphic.createMermaidRenderer(options);
|
|
72
74
|
|
|
73
|
-
|
|
75
|
+
async function renderNodes(nodes) {
|
|
74
76
|
const mapped = nodes.map((node) => {
|
|
75
77
|
const paths = generateFilePaths(options.rootDir, node.value);
|
|
78
|
+
const frontmatter = node.value.startsWith('---')
|
|
79
|
+
? YAML.parse(node.value.match(/---([\s\S]*?)---/)[1]) ?? {}
|
|
80
|
+
: {};
|
|
81
|
+
|
|
76
82
|
return {
|
|
77
83
|
...paths,
|
|
78
84
|
value: node.value,
|
|
85
|
+
frontmatter,
|
|
79
86
|
exists: fs.existsSync(paths.svgPath),
|
|
80
87
|
};
|
|
81
88
|
});
|
|
82
89
|
|
|
90
|
+
if (mapped.length > 1 && mapped.some((n) => n.frontmatter.overrides)) {
|
|
91
|
+
// If any node has an override, render all nodes separately because we pass config globally
|
|
92
|
+
return await Promise.all(
|
|
93
|
+
nodes.map(async (node) => (await renderNodes([node]))[0]),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
83
97
|
if (mapped.every(({ exists }) => exists)) {
|
|
84
98
|
return mapped.map(({ svgNodeUrl }) => ({
|
|
85
99
|
status: 'fulfilled',
|
|
@@ -93,7 +107,13 @@ function createMermaidRenderer(options) {
|
|
|
93
107
|
|
|
94
108
|
const results = await renderer(
|
|
95
109
|
toRender.map(({ value }) => value),
|
|
96
|
-
{
|
|
110
|
+
{
|
|
111
|
+
...options,
|
|
112
|
+
mermaidConfig: deepmerge(
|
|
113
|
+
mermaidConfig,
|
|
114
|
+
...toRender.map(({ frontmatter }) => frontmatter.overrides),
|
|
115
|
+
),
|
|
116
|
+
},
|
|
97
117
|
);
|
|
98
118
|
|
|
99
119
|
const errorResults = new Map();
|
|
@@ -120,12 +140,13 @@ function createMermaidRenderer(options) {
|
|
|
120
140
|
}
|
|
121
141
|
});
|
|
122
142
|
|
|
123
|
-
return mapped.map(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
: { status: 'fulfilled', value: { svgNodeUrl } },
|
|
143
|
+
return mapped.map(
|
|
144
|
+
({ svgNodeUrl }, i) =>
|
|
145
|
+
errorResults.get(i) ?? { status: 'fulfilled', value: { svgNodeUrl } },
|
|
127
146
|
);
|
|
128
|
-
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return renderNodes;
|
|
129
150
|
}
|
|
130
151
|
|
|
131
152
|
module.exports = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Box, Stack, Text, TextLinkButton } from 'braid-design-system';
|
|
2
2
|
import { parse } from 'jsonc-parser';
|
|
3
3
|
import { Highlight } from 'prism-react-renderer';
|
|
4
|
-
import React, { useState } from 'react';
|
|
4
|
+
import React, { useEffect, useState } from 'react';
|
|
5
5
|
|
|
6
6
|
import { Prism, themes } from '../private/Prism';
|
|
7
7
|
import { ScrollableInline } from '../private/ScrollableInline';
|
|
@@ -23,6 +23,7 @@ import * as styles from './CodeBlock.css';
|
|
|
23
23
|
interface Props {
|
|
24
24
|
children: readonly CodeChildProps[] | string;
|
|
25
25
|
graphqlPlayground?: string;
|
|
26
|
+
initialIndex?: number;
|
|
26
27
|
label?: string;
|
|
27
28
|
language?: string;
|
|
28
29
|
size?: Size;
|
|
@@ -31,9 +32,10 @@ interface Props {
|
|
|
31
32
|
|
|
32
33
|
export const CodeBlock = ({
|
|
33
34
|
children: rawChildren,
|
|
35
|
+
graphqlPlayground,
|
|
36
|
+
initialIndex = 0,
|
|
34
37
|
label: rawLabel,
|
|
35
38
|
language: rawLanguage,
|
|
36
|
-
graphqlPlayground,
|
|
37
39
|
size = DEFAULT_SIZE,
|
|
38
40
|
trim = true,
|
|
39
41
|
}: Props) => {
|
|
@@ -53,9 +55,14 @@ export const CodeBlock = ({
|
|
|
53
55
|
const smallerSize = SIZE_TO_SMALLER[size];
|
|
54
56
|
const tablePadding = SIZE_TO_TABLE_PADDING[size];
|
|
55
57
|
|
|
56
|
-
const [index, setIndex] = useState(
|
|
58
|
+
const [index, setIndex] = useState({ dirty: false, value: initialIndex });
|
|
59
|
+
|
|
60
|
+
useEffect(
|
|
61
|
+
() => setIndex((i) => (i.dirty ? i : { ...i, value: initialIndex })),
|
|
62
|
+
[initialIndex],
|
|
63
|
+
);
|
|
57
64
|
|
|
58
|
-
const child = children[index];
|
|
65
|
+
const child = children[index.value] ?? children[0];
|
|
59
66
|
|
|
60
67
|
const jsoncVariables =
|
|
61
68
|
children[0].language === 'graphql' && children[1]?.label === 'Variables'
|
|
@@ -90,13 +97,17 @@ export const CodeBlock = ({
|
|
|
90
97
|
>
|
|
91
98
|
<Text
|
|
92
99
|
size={smallerSize}
|
|
93
|
-
tone={index === labelIndex ? 'secondary' : undefined}
|
|
100
|
+
tone={index.value === labelIndex ? 'secondary' : undefined}
|
|
94
101
|
weight="medium"
|
|
95
102
|
>
|
|
96
|
-
{children.length === 1 || index === labelIndex ? (
|
|
103
|
+
{children.length === 1 || index.value === labelIndex ? (
|
|
97
104
|
label
|
|
98
105
|
) : (
|
|
99
|
-
<TextLinkButton
|
|
106
|
+
<TextLinkButton
|
|
107
|
+
onClick={() =>
|
|
108
|
+
setIndex({ dirty: true, value: labelIndex })
|
|
109
|
+
}
|
|
110
|
+
>
|
|
100
111
|
{label}
|
|
101
112
|
</TextLinkButton>
|
|
102
113
|
)}
|
|
@@ -6,7 +6,13 @@ import type { CodeChildProps } from '../components/CodeBlock/CodeChild';
|
|
|
6
6
|
import { useGraphQLPlayground } from './hooks/graphqlPlayground';
|
|
7
7
|
import type { Size } from './size';
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
const LABEL_REGEX = /label="([^"]+)"/;
|
|
10
|
+
|
|
11
|
+
const toDefault = (meta?: string): boolean =>
|
|
12
|
+
Boolean(meta?.replace(LABEL_REGEX, '').match(/(^|\s)default(\s|$)/));
|
|
13
|
+
|
|
14
|
+
const toLabel = (meta?: string): string | undefined =>
|
|
15
|
+
meta?.match(LABEL_REGEX)?.[1];
|
|
10
16
|
|
|
11
17
|
/**
|
|
12
18
|
* MDAST node as passed through by the `mergeCodeBlocks` Remark plugin.
|
|
@@ -39,8 +45,18 @@ export const createMdxCodeBlock =
|
|
|
39
45
|
if (className === 'language-scoobie-merged-code' && metastring) {
|
|
40
46
|
const data = JSON.parse(metastring) as MdastCode[];
|
|
41
47
|
|
|
48
|
+
const firstDefaultIndex = data.findIndex((child) =>
|
|
49
|
+
toDefault(child.meta),
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const initialIndex = firstDefaultIndex === -1 ? 0 : firstDefaultIndex;
|
|
53
|
+
|
|
42
54
|
return (
|
|
43
|
-
<CodeBlock
|
|
55
|
+
<CodeBlock
|
|
56
|
+
graphqlPlayground={graphqlPlayground}
|
|
57
|
+
initialIndex={initialIndex}
|
|
58
|
+
size={size}
|
|
59
|
+
>
|
|
44
60
|
{data.map(toCodeChildProps)}
|
|
45
61
|
</CodeBlock>
|
|
46
62
|
);
|