Skip to content

Commit f4aab72

Browse files
committed
Improve tree display and sanitize type names in css. #279
1 parent ed75d5e commit f4aab72

3 files changed

Lines changed: 63 additions & 49 deletions

File tree

src/components/schema-table.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,11 @@ export default class SchemaTable extends LitElement {
110110
transform: rotate(-90deg);
111111
}
112112
113-
.tr.circular-object .obj-toggle {
113+
.tr.object.circular-object .obj-toggle {
114114
display: none;
115115
}
116116
117-
.tr.object .key-label {
117+
.tr.object:not(.circular-object) .key-label {
118118
margin-left: -6px
119119
}
120120
`,
@@ -135,11 +135,11 @@ export default class SchemaTable extends LitElement {
135135
}
136136
<style>
137137
.table .key {
138-
width: ${Math.max(240, (keyLabelMaxCharacterLength || 0) * 8) + 16}px;
138+
width: calc(var(--font-size-small) * ${Math.max(16, keyLabelMaxCharacterLength || 0)});
139139
max-width: Min(400px, 75%);
140140
}
141141
.table .key-type {
142-
width: ${Math.max(150, (typeMaxCharacterLength || 0) * 8) + 16}px;
142+
width: calc(var(--font-size-small) * ${Math.max(16, typeMaxCharacterLength || 0)});
143143
max-width: 25%;
144144
}
145145
</style>
@@ -235,7 +235,7 @@ export default class SchemaTable extends LitElement {
235235
});
236236
}
237237

238-
const displayLine = [title && `**${title}${description ? ':' : ''}**`, description].filter(v => v).join(' ');
238+
const displayLine = [title && !data['::link'] && `**${title}${description ? ':' : ''}**`, description].filter(v => v).join(' ');
239239
const detailObjTypeDisplay = data['::circular'] ? `{ Recursive: ${detailObjType} }` : detailObjType;
240240
const outerResult = html`
241241
${newSchemaLevel >= 0 && key

src/components/schema-tree.js

Lines changed: 55 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ export default class SchemaTree extends LitElement {
142142
this.requestUpdate();
143143
}
144144

145+
scrollToSchemaComponentByName(componentName) {
146+
this.dispatchEvent(new CustomEvent('scrollToSchemaComponentByName', { bubbles: true, composed: true, detail: componentName }));
147+
}
148+
145149
generateTree(data, dataType = 'object', arrayType = '', flags = {}, key = '', title = '', description = '', schemaLevel = 0, indentLevel = 0) {
146150
if (!data) {
147151
return html`<div class="null" style="display:inline;">
@@ -170,53 +174,62 @@ export default class SchemaTree extends LitElement {
170174
const leftPadding = 16;
171175
// Min-width used for model keys: `td key `
172176
const minFieldColWidth = 300 - (indentLevel * leftPadding);
173-
let openBracket = '';
174-
let closeBracket = '';
175177
const newSchemaLevel = data['::type'] === 'xxx-of-option' ? schemaLevel : (schemaLevel + 1);
176178
const newIndentLevel = indentLevel + 1;
177-
if (data['::type'] === 'array') {
178-
if (dataType === 'array') {
179-
const arrType = arrayType !== 'object' ? arrayType : '';
180-
if (schemaLevel < this.schemaExpandLevel) {
181-
openBracket = html`<span class="open-bracket array-of-array" data-array-type="${arrType}" @click="${this.toggleObjectExpand}">[[ ${arrType} </span>`;
182-
} else {
183-
openBracket = html`<span class="open-bracket array-of-array" data-array-type="${arrType}" @click="${this.toggleObjectExpand}">[[...]]</span>`;
179+
180+
const [openBracket, closeBracket] = (() => {
181+
if (data['::circular']) {
182+
const displaySchemaLink = data['::link'];
183+
return [html`<span class="open-bracket object" @click='${() => this.scrollToSchemaComponentByName(displaySchemaLink)}'>
184+
<span>${dataType === 'array' ? '[' : ''}<span style="color: var(--secondary-color)">{${displaySchemaLink}}</span>${dataType === 'array' ? ']' : ''}</span>
185+
</span>`];
186+
}
187+
188+
if (data['::type'] === 'array') {
189+
if (dataType === 'array') {
190+
const arrType = arrayType !== 'object' ? arrayType : '';
191+
if (schemaLevel < this.schemaExpandLevel && !data['::circular']) {
192+
return [html`<span class="open-bracket array-of-array" data-array-type="${arrType}" @click="${this.toggleObjectExpand}">[[ ${arrType} </span>`, ']]'];
193+
}
194+
195+
return [html`<span class="open-bracket array-of-array" data-array-type="${arrType}" @click="${this.toggleObjectExpand}">[[...]]</span>`];
184196
}
185-
closeBracket = ']]';
186-
} else {
187-
if (schemaLevel < this.schemaExpandLevel) {
188-
openBracket = html`<span class="open-bracket array" @click="${this.toggleObjectExpand}">[</span>`;
189-
} else {
190-
openBracket = html`<span class="open-bracket array" @click="${this.toggleObjectExpand}">[...]</span>`;
197+
198+
if (schemaLevel < this.schemaExpandLevel && !data['::circular']) {
199+
return [html`<span class="open-bracket array" @click="${this.toggleObjectExpand}">[</span>`, ']'];
191200
}
192-
closeBracket = ']';
201+
202+
return [html`<span class="open-bracket array" @click="${this.toggleObjectExpand}">[...]</span>`];
193203
}
194-
} else if (data['::type'] === 'xxx-of-option') {
195-
if (dataType === 'array') {
196-
if (schemaLevel < this.schemaExpandLevel) {
197-
openBracket = html`<span class="open-bracket array" @click="${this.toggleObjectExpand}">[</span>`;
198-
} else {
199-
openBracket = html`<span class="open-bracket array" @click="${this.toggleObjectExpand}">[...]</span>`;
204+
205+
if (data['::type'] === 'xxx-of-option') {
206+
if (dataType === 'array') {
207+
if (schemaLevel < this.schemaExpandLevel && !data['::circular']) {
208+
return [html`<span class="open-bracket array" @click="${this.toggleObjectExpand}">[</span>`, ']'];
209+
}
210+
211+
return [html`<span class="open-bracket array" @click="${this.toggleObjectExpand}">[...]</span>`];
200212
}
201-
closeBracket = ']';
202213
}
203-
} else if (data['::type']) {
204-
if (dataType === 'array') {
205-
if (schemaLevel < this.schemaExpandLevel) {
206-
openBracket = html`<span class="open-bracket array-of-object" @click="${this.toggleObjectExpand}">[{</span>`;
207-
} else {
208-
openBracket = html`<span class="open-bracket array-of-object" @click="${this.toggleObjectExpand}">[{...}]</span>`;
214+
215+
if (data['::type']) {
216+
if (dataType === 'array') {
217+
if (schemaLevel < this.schemaExpandLevel && !data['::circular']) {
218+
return [html`<span class="open-bracket array-of-object" @click="${this.toggleObjectExpand}">[{</span>`, '}]'];
219+
}
220+
221+
return [html`<span class="open-bracket array-of-object" @click="${this.toggleObjectExpand}">[{...}]</span>`];
209222
}
210-
closeBracket = '}]';
211-
} else {
212-
if (schemaLevel < this.schemaExpandLevel) {
213-
openBracket = html`<span class="open-bracket object" @click="${this.toggleObjectExpand}">{</span>`;
214-
} else {
215-
openBracket = html`<span class="open-bracket object" @click="${this.toggleObjectExpand}">{...}</span>`;
223+
224+
if (schemaLevel < this.schemaExpandLevel && !data['::circular']) {
225+
return [html`<span class="open-bracket object" @click="${this.toggleObjectExpand}">{</span>`, '}'];
216226
}
217-
closeBracket = '}';
227+
228+
return [html`<span class="open-bracket object" @click="${this.toggleObjectExpand}">{...}</span>`];
218229
}
219-
}
230+
231+
return [''];
232+
})();
220233

221234
if (typeof data === 'object') {
222235
if (flags['🆁'] && this.schemaHideReadOnly === 'true') {
@@ -226,9 +239,9 @@ export default class SchemaTree extends LitElement {
226239
return undefined;
227240
}
228241

229-
const displayLine = [flags['🆁'] || flags['🆆'], title && `**${title}${description ? ':' : ''}**`, description].filter(v => v).join(' ');
242+
const displayLine = [flags['🆁'] || flags['🆆'], title && !data['::link'] && `**${title}${description ? ':' : ''}**`, description].filter(v => v).join(' ');
230243
return html`
231-
<div class="tr ${schemaLevel < this.schemaExpandLevel || data['::type'] && data['::type'].startsWith('xxx-of') ? '' : 'collapsed'} ${data['::type'] || 'no-type-info'}">
244+
<div class="tr ${schemaLevel < this.schemaExpandLevel || data['::type'] && data['::type'].startsWith('xxx-of') ? '' : 'collapsed'} ${data['::circular'] ? 'circular-object' : 'object'} ${data['::type'] || 'no-type-info'}">
232245
<div class="td key ${data['::deprecated'] ? 'deprecated' : ''}" style='min-width:${minFieldColWidth}px'>
233246
${data['::type'] === 'xxx-of-option' || key.startsWith('::OPTION')
234247
? html`<span class='key-label xxx-of-key'>${keyLabel}</span><span class="xxx-of-descr">${keyDescr}</span>`
@@ -255,15 +268,15 @@ export default class SchemaTree extends LitElement {
255268
${Array.isArray(data) && data[0] ? html`${this.generateTree(data[0], 'xxx-of-option', '', data[0]['::flags'] || {}, '::ARRAY~OF', data[0]['::title'], data[0]['::description'], newSchemaLevel, newIndentLevel)}`
256269
: html`
257270
${Object.keys(data).map((dataKey) =>
258-
!['::metadata', '::title', '::description', '::type', '::link', '::props', '::deprecated', '::array-type', '::dataTypeLabel', '::flags'].includes(dataKey)
271+
!['::metadata', '::title', '::description', '::type', '::link', '::circular', '::props', '::deprecated', '::array-type', '::dataTypeLabel', '::flags'].includes(dataKey)
259272
|| data[dataKey]?.['::type'] && !data[dataKey]['::type'].includes('xxx-of')
260273
? html`${this.generateTree(data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey],
261274
data[dataKey]['::type'], data[dataKey]['::array-type'] || '', data[dataKey]['::flags'], dataKey, data[dataKey]['::title'], data[dataKey]['::description'], newSchemaLevel, newIndentLevel)}`
262275
: ''
263276
)}`
264277
}
265278
</div>
266-
${data['::type'] && data['::type'].includes('xxx-of') ? '' : html`<div class='close-bracket'> ${closeBracket} </div>`}
279+
${!closeBracket || data['::type'] && data['::type'].includes('xxx-of') ? '' : html`<div class='close-bracket'> ${closeBracket} </div>`}
267280
</div>
268281
`;
269282
}
@@ -311,6 +324,7 @@ export default class SchemaTree extends LitElement {
311324

312325
toggleObjectExpand(e) {
313326
const rowEl = e.target.closest('.tr');
327+
314328
rowEl.classList.toggle('collapsed');
315329
if (rowEl.classList.contains('collapsed')) {
316330
e.target.innerHTML = e.target.classList.contains('array-of-object')

src/utils/schema-utils.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '
383383

384384
resultObj['::link'] = schema.title || '';
385385
resultObj['::circular'] = !!schema.circularReference;
386-
resultObj['::type'] = schema.title || 'object';
386+
resultObj['::type'] = 'object';
387387
resultObj['::flags'] = { '🆁': readOnly && '🆁', '🆆': writeOnly && '🆆' };
388388
resultObj['::title'] = schema.title || '';
389389
resultObj['::description'] = schema.description || '';
@@ -444,7 +444,7 @@ export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '
444444
'::flags': { '🆁': schema.readOnly && '🆁', '🆆': schema.writeOnly && '🆆' },
445445
'::link': schema.title || '',
446446
'::circular': !!schema.circularReference,
447-
'::type': schema.title || 'object',
447+
'::type': 'object',
448448
'::deprecated': schema.deprecated || false,
449449
'::metadata': metadata
450450
};
@@ -484,7 +484,7 @@ export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '
484484
obj['::flags'] = { '🆁': schema.readOnly && '🆁', '🆆': schema.writeOnly && '🆆' };
485485
obj['::link'] = schema.title || '';
486486
obj['::circular'] = !!schema.circularReference;
487-
obj['::type'] = schema.title || 'object';
487+
obj['::type'] = 'object';
488488
obj['::deprecated'] = schema.deprecated || false;
489489
obj['::metadata'] = metadata;
490490
for (const key in schemaProperties) {

0 commit comments

Comments
 (0)