docusaurus-plugin-generate-schema-docs 1.8.1 → 1.8.3
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 +17 -7
- package/__tests__/__fixtures__/validateSchemas/main-schema-with-constraints-ref.json +20 -0
- package/__tests__/__snapshots__/generateEventDocs.anchor.test.js.snap +15 -3
- package/__tests__/__snapshots__/generateEventDocs.nested.test.js.snap +20 -4
- package/__tests__/__snapshots__/generateEventDocs.test.js.snap +30 -6
- package/__tests__/__snapshots__/generateEventDocs.versioned.test.js.snap +10 -2
- package/__tests__/components/ConditionalRows.test.js +28 -0
- package/__tests__/components/FoldableRows.test.js +31 -290
- package/__tests__/components/PropertyRow.test.js +216 -0
- package/__tests__/components/SchemaJsonViewer.test.js +76 -10
- package/__tests__/components/SchemaRows.test.js +62 -12
- package/__tests__/components/__snapshots__/ConnectorLines.visualRegression.test.js.snap +3 -3
- package/__tests__/generateEventDocs.partials.test.js +95 -0
- package/__tests__/generateEventDocs.test.js +3 -0
- package/__tests__/helpers/processSchema.test.js +29 -0
- package/__tests__/helpers/schemaToTableData.test.js +112 -0
- package/__tests__/helpers/validator.test.js +32 -0
- package/components/ConditionalRows.js +6 -3
- package/components/FoldableRows.js +9 -3
- package/components/PropertiesTable.js +2 -1
- package/components/PropertyRow.js +90 -5
- package/components/SchemaJsonViewer.js +221 -4
- package/components/SchemaRows.css +98 -7
- package/components/SchemaRows.js +11 -1
- package/generateEventDocs.js +184 -18
- package/helpers/buildExampleFromSchema.js +3 -3
- package/helpers/choice-index-template.js +6 -2
- package/helpers/constraintSchemaPaths.js +46 -0
- package/helpers/file-system.js +28 -0
- package/helpers/mergeSchema.js +16 -0
- package/helpers/processSchema.js +19 -6
- package/helpers/schema-doc-template.js +7 -1
- package/helpers/schema-processing.js +4 -11
- package/helpers/schemaToExamples.js +4 -4
- package/helpers/schemaToTableData.js +68 -7
- package/helpers/validator.js +7 -0
- package/package.json +1 -1
|
@@ -26,12 +26,36 @@ const getContainerSymbol = (containerType) => {
|
|
|
26
26
|
return '';
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
const KEYWORD_HELP_TEXT = {
|
|
30
|
+
additionalProperties:
|
|
31
|
+
'Controls properties not listed in properties and not matched by patternProperties.',
|
|
32
|
+
patternProperties:
|
|
33
|
+
'Applies the subschema to property names that match the given regular expression.',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function splitKeywordLabel(name) {
|
|
37
|
+
const match = /^patternProperties (\/.+\/)$/.exec(name);
|
|
38
|
+
if (!match) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
keyword: 'patternProperties',
|
|
44
|
+
pattern: match[1],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
29
48
|
/**
|
|
30
49
|
* Renders a single property row in the schema table.
|
|
31
50
|
* All data is passed in via the `row` prop, which comes from `tableData`.
|
|
32
51
|
* This component handles multi-row constraints using `rowSpan`.
|
|
33
52
|
*/
|
|
34
|
-
export default function PropertyRow({
|
|
53
|
+
export default function PropertyRow({
|
|
54
|
+
row,
|
|
55
|
+
stripeIndex,
|
|
56
|
+
isLastInGroup,
|
|
57
|
+
bracketEnds,
|
|
58
|
+
}) {
|
|
35
59
|
const {
|
|
36
60
|
name,
|
|
37
61
|
level,
|
|
@@ -44,6 +68,8 @@ export default function PropertyRow({ row, isLastInGroup, bracketEnds }) {
|
|
|
44
68
|
containerType,
|
|
45
69
|
continuingLevels = [],
|
|
46
70
|
groupBrackets = [],
|
|
71
|
+
isSchemaKeywordRow = false,
|
|
72
|
+
keepConnectorOpen = false,
|
|
47
73
|
} = row;
|
|
48
74
|
|
|
49
75
|
const indentStyle = {
|
|
@@ -112,11 +138,27 @@ export default function PropertyRow({ row, isLastInGroup, bracketEnds }) {
|
|
|
112
138
|
const bracketStyle = getBracketLinesStyle(groupBrackets, bracketCaps);
|
|
113
139
|
|
|
114
140
|
const containerSymbol = getContainerSymbol(containerType);
|
|
141
|
+
const shouldCloseConnector = isLastInGroup && !keepConnectorOpen;
|
|
142
|
+
const splitKeyword = splitKeywordLabel(name);
|
|
143
|
+
const keywordHelpKey = name.startsWith('patternProperties ')
|
|
144
|
+
? 'patternProperties'
|
|
145
|
+
: name;
|
|
146
|
+
const keywordHelpText = KEYWORD_HELP_TEXT[keywordHelpKey];
|
|
147
|
+
const keywordHelpId = keywordHelpText
|
|
148
|
+
? `schema-keyword-help-${name}`
|
|
149
|
+
: undefined;
|
|
150
|
+
const zebraClassName =
|
|
151
|
+
stripeIndex === undefined
|
|
152
|
+
? undefined
|
|
153
|
+
: stripeIndex % 2 === 0
|
|
154
|
+
? 'schema-row--zebra-even'
|
|
155
|
+
: 'schema-row--zebra-odd';
|
|
115
156
|
|
|
116
157
|
return (
|
|
117
158
|
<>
|
|
118
159
|
<tr
|
|
119
160
|
className={clsx(
|
|
161
|
+
zebraClassName,
|
|
120
162
|
required && 'required-row',
|
|
121
163
|
row.isCondition && 'conditional-condition-row',
|
|
122
164
|
)}
|
|
@@ -126,17 +168,57 @@ export default function PropertyRow({ row, isLastInGroup, bracketEnds }) {
|
|
|
126
168
|
style={{ ...indentStyle, ...continuingLinesStyle }}
|
|
127
169
|
className={clsx(
|
|
128
170
|
'property-cell',
|
|
171
|
+
isSchemaKeywordRow && 'property-cell--keyword',
|
|
172
|
+
required && 'property-cell--required',
|
|
173
|
+
level > 0 && 'property-cell--tree',
|
|
129
174
|
level > 0 && `level-${level}`,
|
|
130
|
-
|
|
175
|
+
shouldCloseConnector && 'is-last',
|
|
131
176
|
hasChildren && 'has-children',
|
|
132
177
|
containerType && `container-${containerType}`,
|
|
133
178
|
)}
|
|
134
179
|
>
|
|
135
|
-
<span
|
|
180
|
+
<span
|
|
181
|
+
className={clsx(
|
|
182
|
+
'property-name',
|
|
183
|
+
isSchemaKeywordRow && 'property-name--keyword',
|
|
184
|
+
)}
|
|
185
|
+
>
|
|
136
186
|
{containerSymbol && (
|
|
137
187
|
<span className="container-symbol">{containerSymbol}</span>
|
|
138
188
|
)}
|
|
139
|
-
|
|
189
|
+
{isSchemaKeywordRow ? (
|
|
190
|
+
<span className="property-keyword-wrapper">
|
|
191
|
+
{splitKeyword ? (
|
|
192
|
+
<span className="property-keyword-stack">
|
|
193
|
+
<code
|
|
194
|
+
className="property-keyword"
|
|
195
|
+
aria-describedby={keywordHelpId}
|
|
196
|
+
>
|
|
197
|
+
{splitKeyword.keyword}
|
|
198
|
+
</code>
|
|
199
|
+
<code className="property-keyword-pattern">
|
|
200
|
+
{splitKeyword.pattern}
|
|
201
|
+
</code>
|
|
202
|
+
</span>
|
|
203
|
+
) : (
|
|
204
|
+
<code
|
|
205
|
+
className="property-keyword"
|
|
206
|
+
aria-describedby={keywordHelpId}
|
|
207
|
+
>
|
|
208
|
+
{name}
|
|
209
|
+
</code>
|
|
210
|
+
)}
|
|
211
|
+
<span
|
|
212
|
+
id={keywordHelpId}
|
|
213
|
+
className="property-keyword-tooltip"
|
|
214
|
+
role="tooltip"
|
|
215
|
+
>
|
|
216
|
+
{keywordHelpText}
|
|
217
|
+
</span>
|
|
218
|
+
</span>
|
|
219
|
+
) : (
|
|
220
|
+
<strong>{name}</strong>
|
|
221
|
+
)}
|
|
140
222
|
</span>
|
|
141
223
|
</td>
|
|
142
224
|
<td rowSpan={rowSpan}>
|
|
@@ -181,7 +263,10 @@ export default function PropertyRow({ row, isLastInGroup, bracketEnds }) {
|
|
|
181
263
|
|
|
182
264
|
{/* Render subsequent constraints in their own rows */}
|
|
183
265
|
{remainingConstraints.map((constraint) => (
|
|
184
|
-
<tr
|
|
266
|
+
<tr
|
|
267
|
+
className={clsx(zebraClassName, required && 'required-row')}
|
|
268
|
+
key={constraint}
|
|
269
|
+
>
|
|
185
270
|
<td className="constraint-cell">
|
|
186
271
|
<code
|
|
187
272
|
className={clsx(
|
|
@@ -1,11 +1,228 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import
|
|
1
|
+
import React, { Fragment, useState } from 'react';
|
|
2
|
+
import Link from '@docusaurus/Link';
|
|
3
|
+
|
|
4
|
+
function isPlainObject(value) {
|
|
5
|
+
return (
|
|
6
|
+
value !== null &&
|
|
7
|
+
typeof value === 'object' &&
|
|
8
|
+
!Array.isArray(value) &&
|
|
9
|
+
Object.getPrototypeOf(value) === Object.prototype
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function isExternalRef(value) {
|
|
14
|
+
return typeof value === 'string' && /^https?:\/\//.test(value);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function normalizePathSegments(pathValue) {
|
|
18
|
+
const normalized = pathValue.replace(/\\/g, '/');
|
|
19
|
+
const isAbsolute = normalized.startsWith('/');
|
|
20
|
+
const segments = normalized.split('/');
|
|
21
|
+
const resolvedSegments = [];
|
|
22
|
+
|
|
23
|
+
segments.forEach((segment) => {
|
|
24
|
+
if (!segment || segment === '.') return;
|
|
25
|
+
if (segment === '..') {
|
|
26
|
+
resolvedSegments.pop();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
resolvedSegments.push(segment);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return `${isAbsolute ? '/' : ''}${resolvedSegments.join('/')}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function dirname(pathValue) {
|
|
36
|
+
const normalized = normalizePathSegments(pathValue);
|
|
37
|
+
const segments = normalized.split('/');
|
|
38
|
+
|
|
39
|
+
if (segments.length <= 1) {
|
|
40
|
+
return normalized.startsWith('/') ? '/' : '.';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
segments.pop();
|
|
44
|
+
const joined = segments.join('/');
|
|
45
|
+
return joined || '/';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function resolveLocalRef(currentPath, refValue) {
|
|
49
|
+
if (!currentPath || typeof refValue !== 'string') return null;
|
|
50
|
+
if (refValue.startsWith('#')) return null;
|
|
51
|
+
return normalizePathSegments(`${dirname(currentPath)}/${refValue}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function JsonIndent({ depth }) {
|
|
55
|
+
return <span>{' '.repeat(depth)}</span>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function JsonPrimitive({
|
|
59
|
+
value,
|
|
60
|
+
propertyKey,
|
|
61
|
+
currentPath,
|
|
62
|
+
schemaSources,
|
|
63
|
+
onNavigate,
|
|
64
|
+
}) {
|
|
65
|
+
const interactiveRefClassName = 'schema-json-viewer__link';
|
|
66
|
+
const quotedValue = `${JSON.stringify(value)}`;
|
|
67
|
+
|
|
68
|
+
if (typeof value === 'string') {
|
|
69
|
+
if (propertyKey === '$ref') {
|
|
70
|
+
if (isExternalRef(value)) {
|
|
71
|
+
return (
|
|
72
|
+
<Link
|
|
73
|
+
className={interactiveRefClassName}
|
|
74
|
+
href={value}
|
|
75
|
+
target="_blank"
|
|
76
|
+
rel="noreferrer"
|
|
77
|
+
>
|
|
78
|
+
{quotedValue}
|
|
79
|
+
</Link>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const resolvedRef = resolveLocalRef(currentPath, value);
|
|
84
|
+
if (resolvedRef && schemaSources?.[resolvedRef]) {
|
|
85
|
+
return (
|
|
86
|
+
<button
|
|
87
|
+
type="button"
|
|
88
|
+
className={interactiveRefClassName}
|
|
89
|
+
onClick={() => onNavigate(resolvedRef)}
|
|
90
|
+
>
|
|
91
|
+
{quotedValue}
|
|
92
|
+
</button>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return <span className="token string">{quotedValue}</span>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (typeof value === 'number') {
|
|
101
|
+
return <span className="token number">{value}</span>;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (typeof value === 'boolean') {
|
|
105
|
+
return <span className="token boolean">{String(value)}</span>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return <span className="token null keyword">null</span>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function JsonNode({
|
|
112
|
+
value,
|
|
113
|
+
depth,
|
|
114
|
+
currentPath,
|
|
115
|
+
schemaSources,
|
|
116
|
+
onNavigate,
|
|
117
|
+
propertyKey = null,
|
|
118
|
+
}) {
|
|
119
|
+
if (Array.isArray(value)) {
|
|
120
|
+
return (
|
|
121
|
+
<>
|
|
122
|
+
<span className="token punctuation">[</span>
|
|
123
|
+
{value.length > 0 && <br />}
|
|
124
|
+
{value.map((item, index) => (
|
|
125
|
+
<Fragment key={`${depth}-${index}`}>
|
|
126
|
+
<JsonIndent depth={depth + 1} />
|
|
127
|
+
<JsonNode
|
|
128
|
+
value={item}
|
|
129
|
+
depth={depth + 1}
|
|
130
|
+
currentPath={currentPath}
|
|
131
|
+
schemaSources={schemaSources}
|
|
132
|
+
onNavigate={onNavigate}
|
|
133
|
+
/>
|
|
134
|
+
{index < value.length - 1 && (
|
|
135
|
+
<span className="token punctuation">,</span>
|
|
136
|
+
)}
|
|
137
|
+
<br />
|
|
138
|
+
</Fragment>
|
|
139
|
+
))}
|
|
140
|
+
{value.length > 0 && <JsonIndent depth={depth} />}
|
|
141
|
+
<span className="token punctuation">]</span>
|
|
142
|
+
</>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (isPlainObject(value)) {
|
|
147
|
+
const entries = Object.entries(value);
|
|
148
|
+
return (
|
|
149
|
+
<>
|
|
150
|
+
<span className="token punctuation">{'{'}</span>
|
|
151
|
+
{entries.length > 0 && <br />}
|
|
152
|
+
{entries.map(([key, child], index) => (
|
|
153
|
+
<Fragment key={`${depth}-${key}`}>
|
|
154
|
+
<JsonIndent depth={depth + 1} />
|
|
155
|
+
<span className="token property">{JSON.stringify(key)}</span>
|
|
156
|
+
<span className="token punctuation">: </span>
|
|
157
|
+
<JsonNode
|
|
158
|
+
value={child}
|
|
159
|
+
depth={depth + 1}
|
|
160
|
+
currentPath={currentPath}
|
|
161
|
+
schemaSources={schemaSources}
|
|
162
|
+
onNavigate={onNavigate}
|
|
163
|
+
propertyKey={key}
|
|
164
|
+
/>
|
|
165
|
+
{index < entries.length - 1 && (
|
|
166
|
+
<span className="token punctuation">,</span>
|
|
167
|
+
)}
|
|
168
|
+
<br />
|
|
169
|
+
</Fragment>
|
|
170
|
+
))}
|
|
171
|
+
{entries.length > 0 && <JsonIndent depth={depth} />}
|
|
172
|
+
<span className="token punctuation">{'}'}</span>
|
|
173
|
+
</>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<JsonPrimitive
|
|
179
|
+
value={value}
|
|
180
|
+
propertyKey={propertyKey}
|
|
181
|
+
currentPath={currentPath}
|
|
182
|
+
schemaSources={schemaSources}
|
|
183
|
+
onNavigate={onNavigate}
|
|
184
|
+
/>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export default function SchemaJsonViewer({
|
|
189
|
+
schema,
|
|
190
|
+
sourcePath = null,
|
|
191
|
+
schemaSources = null,
|
|
192
|
+
}) {
|
|
193
|
+
const resolvedSchemaSources =
|
|
194
|
+
schemaSources || (sourcePath ? { [sourcePath]: schema } : {});
|
|
195
|
+
const rootPath = sourcePath;
|
|
196
|
+
const [currentPath, setCurrentPath] = useState(rootPath);
|
|
197
|
+
|
|
198
|
+
const currentSchema =
|
|
199
|
+
(currentPath && resolvedSchemaSources?.[currentPath]) || schema;
|
|
3
200
|
|
|
4
|
-
export default function SchemaJsonViewer({ schema }) {
|
|
5
201
|
return (
|
|
6
202
|
<details className="schema-json-viewer">
|
|
7
203
|
<summary>View Raw JSON Schema</summary>
|
|
8
|
-
|
|
204
|
+
{rootPath && currentPath !== rootPath ? (
|
|
205
|
+
<div className="schema-json-viewer__controls">
|
|
206
|
+
<button
|
|
207
|
+
type="button"
|
|
208
|
+
className="schema-json-viewer__link"
|
|
209
|
+
onClick={() => setCurrentPath(rootPath)}
|
|
210
|
+
>
|
|
211
|
+
Back to root
|
|
212
|
+
</button>
|
|
213
|
+
</div>
|
|
214
|
+
) : null}
|
|
215
|
+
<pre data-language="json">
|
|
216
|
+
<code className="language-json">
|
|
217
|
+
<JsonNode
|
|
218
|
+
value={currentSchema}
|
|
219
|
+
depth={0}
|
|
220
|
+
currentPath={currentPath}
|
|
221
|
+
schemaSources={resolvedSchemaSources}
|
|
222
|
+
onNavigate={setCurrentPath}
|
|
223
|
+
/>
|
|
224
|
+
</code>
|
|
225
|
+
</pre>
|
|
9
226
|
</details>
|
|
10
227
|
);
|
|
11
228
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.required
|
|
1
|
+
.property-cell--required {
|
|
2
2
|
background-color: rgba(var(--ifm-color-danger-rgb), 0.05);
|
|
3
3
|
}
|
|
4
4
|
|
|
@@ -26,6 +26,26 @@
|
|
|
26
26
|
margin-bottom: 1em;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
.schema-json-viewer__controls {
|
|
30
|
+
margin: 0.5rem 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.schema-json-viewer__link {
|
|
34
|
+
appearance: none;
|
|
35
|
+
background: none;
|
|
36
|
+
border: none;
|
|
37
|
+
color: var(--ifm-link-color);
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
font: inherit;
|
|
40
|
+
padding: 0;
|
|
41
|
+
text-decoration: none;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.schema-json-viewer__link:hover {
|
|
45
|
+
color: var(--ifm-link-hover-color);
|
|
46
|
+
text-decoration: underline;
|
|
47
|
+
}
|
|
48
|
+
|
|
29
49
|
/* --- Property Name and Container Symbol Styles --- */
|
|
30
50
|
|
|
31
51
|
.property-name {
|
|
@@ -34,6 +54,61 @@
|
|
|
34
54
|
gap: 4px;
|
|
35
55
|
}
|
|
36
56
|
|
|
57
|
+
.property-name--keyword {
|
|
58
|
+
align-items: center;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.property-keyword-wrapper {
|
|
62
|
+
position: relative;
|
|
63
|
+
display: inline-flex;
|
|
64
|
+
align-items: center;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.property-keyword-stack {
|
|
68
|
+
display: inline-flex;
|
|
69
|
+
flex-direction: column;
|
|
70
|
+
align-items: flex-start;
|
|
71
|
+
gap: 0.2rem;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.property-keyword {
|
|
75
|
+
font-size: 0.95em;
|
|
76
|
+
font-weight: 600;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.property-keyword-pattern {
|
|
80
|
+
font-size: 0.85em;
|
|
81
|
+
color: var(--ifm-color-emphasis-700);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.property-keyword-tooltip {
|
|
85
|
+
position: absolute;
|
|
86
|
+
left: 0;
|
|
87
|
+
bottom: calc(100% + 0.4rem);
|
|
88
|
+
z-index: 3;
|
|
89
|
+
min-width: 14rem;
|
|
90
|
+
max-width: 18rem;
|
|
91
|
+
padding: 0.5rem 0.625rem;
|
|
92
|
+
border-radius: 0.375rem;
|
|
93
|
+
background: var(--ifm-background-surface-color);
|
|
94
|
+
border: 1px solid var(--ifm-table-border-color);
|
|
95
|
+
box-shadow: var(--ifm-global-shadow-lw);
|
|
96
|
+
color: var(--ifm-font-color-base);
|
|
97
|
+
font-size: 0.8rem;
|
|
98
|
+
line-height: 1.35;
|
|
99
|
+
opacity: 0;
|
|
100
|
+
pointer-events: none;
|
|
101
|
+
transform: translateY(0.125rem);
|
|
102
|
+
transition:
|
|
103
|
+
opacity 120ms ease,
|
|
104
|
+
transform 120ms ease;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.property-keyword-wrapper:hover .property-keyword-tooltip {
|
|
108
|
+
opacity: 1;
|
|
109
|
+
transform: translateY(0);
|
|
110
|
+
}
|
|
111
|
+
|
|
37
112
|
.container-symbol {
|
|
38
113
|
font-family: var(--ifm-font-family-monospace);
|
|
39
114
|
font-size: 0.9em;
|
|
@@ -67,6 +142,10 @@
|
|
|
67
142
|
border-left: none;
|
|
68
143
|
}
|
|
69
144
|
|
|
145
|
+
.schema-table td[colspan='5'] {
|
|
146
|
+
border-left: none;
|
|
147
|
+
}
|
|
148
|
+
|
|
70
149
|
/*
|
|
71
150
|
* Constraint-only continuation rows render a single cell; in those rows that
|
|
72
151
|
* cell is also :first-child, but it still needs the separator before the
|
|
@@ -85,6 +164,18 @@
|
|
|
85
164
|
box-shadow: inset 0 1px 0 var(--ifm-table-border-color);
|
|
86
165
|
}
|
|
87
166
|
|
|
167
|
+
.schema-table tbody tr.schema-row--zebra-even {
|
|
168
|
+
background-color: var(--ifm-table-stripe-background);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.schema-table tbody tr.schema-row--zebra-odd {
|
|
172
|
+
background-color: transparent;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.schema-table tbody tr.schema-row--control {
|
|
176
|
+
background-color: transparent;
|
|
177
|
+
}
|
|
178
|
+
|
|
88
179
|
/* --- Organigram Connector Line Styles --- */
|
|
89
180
|
|
|
90
181
|
/*
|
|
@@ -108,10 +199,12 @@ td.has-children {
|
|
|
108
199
|
td[class*='level-']::before {
|
|
109
200
|
content: '';
|
|
110
201
|
position: absolute;
|
|
111
|
-
top:
|
|
112
|
-
bottom:
|
|
202
|
+
top: -1px;
|
|
203
|
+
bottom: -1px;
|
|
113
204
|
width: 0;
|
|
114
205
|
border-left: 1px solid var(--ifm-table-border-color);
|
|
206
|
+
z-index: 1;
|
|
207
|
+
pointer-events: none;
|
|
115
208
|
}
|
|
116
209
|
|
|
117
210
|
/* Last items: stop vertical line at middle */
|
|
@@ -130,6 +223,8 @@ td[class*='level-']::after {
|
|
|
130
223
|
height: 0;
|
|
131
224
|
width: 0.75rem;
|
|
132
225
|
border-bottom: 1px solid var(--ifm-table-border-color);
|
|
226
|
+
z-index: 1;
|
|
227
|
+
pointer-events: none;
|
|
133
228
|
}
|
|
134
229
|
|
|
135
230
|
/* --- Level-based positioning --- */
|
|
@@ -172,10 +267,6 @@ td.level-6::after {
|
|
|
172
267
|
|
|
173
268
|
/* --- Choice Row Styles --- */
|
|
174
269
|
|
|
175
|
-
.choice-row {
|
|
176
|
-
background-color: var(--ifm-table-stripe-background);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
270
|
.choice-row:hover {
|
|
180
271
|
background-color: var(--ifm-hover-overlay);
|
|
181
272
|
}
|
package/components/SchemaRows.js
CHANGED
|
@@ -12,7 +12,11 @@ import ConditionalRows from './ConditionalRows';
|
|
|
12
12
|
* @param {Array} props.tableData - Flat array of row objects
|
|
13
13
|
* @param {Array} [props.bracketEnds] - Bracket descriptors that end on the last row
|
|
14
14
|
*/
|
|
15
|
-
export default function SchemaRows({
|
|
15
|
+
export default function SchemaRows({
|
|
16
|
+
tableData,
|
|
17
|
+
bracketEnds,
|
|
18
|
+
stripeState = { current: 0 },
|
|
19
|
+
}) {
|
|
16
20
|
if (!tableData) {
|
|
17
21
|
return null;
|
|
18
22
|
}
|
|
@@ -20,12 +24,15 @@ export default function SchemaRows({ tableData, bracketEnds }) {
|
|
|
20
24
|
return tableData.map((row, index) => {
|
|
21
25
|
const key = row.path.join('.');
|
|
22
26
|
const isLast = index === tableData.length - 1;
|
|
27
|
+
const stripeIndex = stripeState.current++;
|
|
23
28
|
|
|
24
29
|
if (row.type === 'choice') {
|
|
25
30
|
return (
|
|
26
31
|
<FoldableRows
|
|
27
32
|
key={key}
|
|
28
33
|
row={row}
|
|
34
|
+
stripeIndex={stripeIndex}
|
|
35
|
+
stripeState={stripeState}
|
|
29
36
|
bracketEnds={isLast ? bracketEnds : undefined}
|
|
30
37
|
/>
|
|
31
38
|
);
|
|
@@ -36,6 +43,8 @@ export default function SchemaRows({ tableData, bracketEnds }) {
|
|
|
36
43
|
<ConditionalRows
|
|
37
44
|
key={key}
|
|
38
45
|
row={row}
|
|
46
|
+
stripeIndex={stripeIndex}
|
|
47
|
+
stripeState={stripeState}
|
|
39
48
|
bracketEnds={isLast ? bracketEnds : undefined}
|
|
40
49
|
/>
|
|
41
50
|
);
|
|
@@ -46,6 +55,7 @@ export default function SchemaRows({ tableData, bracketEnds }) {
|
|
|
46
55
|
<PropertyRow
|
|
47
56
|
key={key}
|
|
48
57
|
row={row}
|
|
58
|
+
stripeIndex={stripeIndex}
|
|
49
59
|
isLastInGroup={row.isLastInGroup}
|
|
50
60
|
bracketEnds={isLast ? bracketEnds : undefined}
|
|
51
61
|
/>
|