Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add css parts for schema and automatically resize field type columns … #229

Merged
merged 1 commit into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/styling.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ CSS provides parts, these are special attributes, but that isn't really importan
</html>
```

There are many available `::part` selectors and many ways of styling based on parts. Here is a list of all the parts in the app, andy of them are styleable:
There are many available `::part` selectors and many ways of styling based on parts. Here is a list of all the parts in the app, all of them are styleable:

Explorer location | CSS ::part selector
--------------------|--------------------
Expand All @@ -69,3 +69,4 @@ Labels | `label-header-title` `label-overview-title` `label-selecte
Buttons | `btn` `btn-fill` `btn-outline` `btn-search`
Checkboxes/ Toggles | `checkbox` `checkbox-auth-scope`
Anchors | `anchor` `anchor-overview`
Schema Table/Tree | `schema-key` `schema-type` `schema-description` `schema-table-header`
2 changes: 2 additions & 0 deletions src/components/api-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ export default class ApiRequest extends LitElement {
schema-expand-level = "${this.schemaExpandLevel}"
schema-hide-read-only = "${this.schemaHideReadOnly.includes(this.method)}"
schema-hide-write-only = false
exportparts="schema-key, schema-type, schema-description, schema-table-header"
> </schema-table>
`;
} else {
Expand All @@ -513,6 +514,7 @@ export default class ApiRequest extends LitElement {
schema-expand-level = "${this.schemaExpandLevel}"
schema-hide-read-only = "${this.schemaHideReadOnly.includes(this.method)}"
schema-hide-write-only = false
exportparts="schema-key, schema-type, schema-description"
> </schema-tree>
`;
}
Expand Down
2 changes: 2 additions & 0 deletions src/components/api-response.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ export default class ApiResponse extends LitElement {
schema-expand-level = "${this.schemaExpandLevel}"
schema-hide-read-only = false
schema-hide-write-only = ${this.schemaHideWriteOnly}
exportparts="schema-key, schema-type, schema-description, schema-table-header"
> </schema-table> `
: html`
<schema-tree
Expand All @@ -319,6 +320,7 @@ export default class ApiResponse extends LitElement {
schema-expand-level = "${this.schemaExpandLevel}"
schema-hide-read-only = false
schema-hide-write-only = ${this.schemaHideWriteOnly}
exportparts="schema-key, schema-type, schema-description"
> </schema-tree>`
}`;
}
Expand Down
92 changes: 60 additions & 32 deletions src/components/schema-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ export default class SchemaTable extends LitElement {
.table .td {
padding: 4px 0;
}
.table .key {
width: 240px;
}

.requiredStar::after {
content: '*';
Expand All @@ -73,7 +70,6 @@ export default class SchemaTable extends LitElement {

.table .key-type {
white-space: normal;
width: 150px;
}

.key-type {
Expand Down Expand Up @@ -119,19 +115,31 @@ export default class SchemaTable extends LitElement {
/* eslint-disable indent */
render() {
const displayLine = [this.data?.['::title'], this.data?.['::description']].filter(d => d).join(' - ');

const { result, keyLabelMaxCharacterLength, typeMaxCharacterLength } = this.data ? this.generateTree(this.data['::type'] === 'array' ? this.data['::props'] : this.data, this.data['::type']) : {};
return html`
${displayLine
? html`<span class='m-markdown' style="padding-bottom: 8px;"> ${unsafeHTML(marked(displayLine))}</span>`
: ''
}
<style>
.table .key {
width: ${Math.max(240, (keyLabelMaxCharacterLength || 0) * 6) + 8}px;
max-width: Min(400px, 75%);
}
.table .key-type {
width: ${Math.max(150, (typeMaxCharacterLength || 0) * 6) + 8}px;
max-width: 25%;
}
</style>
<div class="table ${this.interactive ? 'interactive' : ''}">
<div style = 'border:1px solid var(--light-border-color)'>
<div style='display:flex; background-color: var(--bg2); padding:8px 4px; border-bottom:1px solid var(--light-border-color);'>
<div class='key' style='font-family:var(--font-regular); font-weight:bold; color:var(--fg); padding-left:${firstColumnInitialPadding}px'> Field </div>
<div class='key-type' style='font-family:var(--font-regular); font-weight:bold; color:var(--fg);'> Type </div>
<div class='key-descr' style='font-family:var(--font-regular); font-weight:bold; color:var(--fg);'> Description </div>
<div class='key' part="schema-key schema-table-header" style='font-family:var(--font-regular); font-weight:bold; color:var(--fg); padding-left:${firstColumnInitialPadding}px'> Field </div>
<div class='key-type' part="schema-type schema-table-header" style='font-family:var(--font-regular); font-weight:bold; color:var(--fg);'> Type </div>
<div class='key-descr' part="schema-description schema-table-header" style='font-family:var(--font-regular); font-weight:bold; color:var(--fg);'> Description </div>
</div>
${this.data ? html`${this.generateTree(this.data['::type'] === 'array' ? this.data['::props'] : this.data, this.data['::type'])}` : ''}
${result || ''}
</div>
</div>
`;
Expand All @@ -148,10 +156,10 @@ export default class SchemaTable extends LitElement {
const leftPadding = Math.max(firstColumnInitialPadding, tablePadding * newIndentLevel);

if (!data) {
return html`<div class="null" style="display:inline;">null</div>`;
return { result: html`<div class="null" style="display:inline;">null</div>`, keyLabelMaxCharacterLength: newIndentLevel };
}
if (Object.keys(data).length === 0) {
return html`<span class="td key object" style='padding-left:${leftPadding}px'>${key}</span>`;
return { result: html`<span class="td key object" style='padding-left:${leftPadding}px'>${key}</span>`, keyLabelMaxCharacterLength: newIndentLevel };
}
let keyLabel = '';
let keyDescr = '';
Expand Down Expand Up @@ -189,18 +197,40 @@ export default class SchemaTable extends LitElement {
if (typeof data === 'object') {
const flags = data['::flags'] || {};
if (flags['🆁'] && this.schemaHideReadOnly === 'true') {
return undefined;
return { result: undefined, keyLabelMaxCharacterLength: newIndentLevel };
}
if (flags['🆆'] && this.schemaHideWriteOnly === 'true') {
return undefined;
return { result: undefined, keyLabelMaxCharacterLength: newIndentLevel };
}

let recursiveResult;
let innerMaxIndentationLevel = newIndentLevel;
let innerTypeMaxCharacterLength = 0;
if (Array.isArray(data) && data[0]) {
({ result: recursiveResult, keyLabelMaxCharacterLength: innerMaxIndentationLevel, typeMaxCharacterLength: innerTypeMaxCharacterLength }
= this.generateTree(data[0], 'xxx-of-option', '::ARRAY~OF', data[0]['::title'], data[0]['::description'], newSchemaLevel, newIndentLevel));
} else {
recursiveResult = Object.keys(data).filter(dataKey =>
!['::metadata', '::title', '::description', '::type', '::link', '::props', '::deprecated', '::array-type', '::dataTypeLabel', '::flags'].includes(dataKey)
|| data[dataKey]?.['::type'] && !data[dataKey]['::type'].includes('xxx-of'))
.map((dataKey) => {
const { result: innerResult, keyLabelMaxCharacterLength: innerObjectLevelIndentTationLevel, typeMaxCharacterLength: innerObjectLevelTypeMaxCharacterLength }
= this.generateTree(data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey],
data[dataKey]['::type'], dataKey, data[dataKey]['::title'], data[dataKey]['::description'], newSchemaLevel, newIndentLevel) || {};

innerMaxIndentationLevel = Math.max(innerMaxIndentationLevel, innerObjectLevelIndentTationLevel);
innerTypeMaxCharacterLength = Math.max(innerTypeMaxCharacterLength, innerObjectLevelTypeMaxCharacterLength);
return innerResult;
});
}

const displayLine = [title && `**${title}${description ? ':' : ''}**`, description].filter(v => v).join(' ');
return html`
const outerResult = html`
${newSchemaLevel >= 0 && key
? html`
<div class='tr ${newSchemaLevel <= this.schemaExpandLevel ? '' : 'collapsed'} ${data['::type']}' data-obj='${keyLabel}'>
<div class="td no-select key ${data['::deprecated'] ? 'deprecated' : ''}" style='padding-left:${leftPadding}px; cursor: pointer' @click=${(e) => this.toggleObjectExpand(e, keyLabel)}>
<div class="td no-select key ${data['::deprecated'] ? 'deprecated' : ''}" part="schema-key"
style='padding-left:${leftPadding}px; cursor: pointer' @click=${(e) => this.toggleObjectExpand(e, keyLabel)}>
<div style="display: flex; align-items: center">
${(keyLabel || keyDescr) ? html`<div class='obj-toggle' data-obj='${keyLabel}'>▾</div>` : ''}
${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' || key.startsWith('::OPTION')
Expand All @@ -211,7 +241,7 @@ export default class SchemaTable extends LitElement {
}
</div>
</div>
<div class='td key-type'>
<div class='td key-type' part="schema-type">
${displaySchemaLink
? html`<div class="schema-link" style="overflow: hidden; text-overflow: ellipsis" @click='${() => this.scrollToSchemaComponentByName(displaySchemaLink)}'>
${dataType === 'array' ? '[' : ''}<span style="color: var(--primary)">${detailObjType}</span>${dataType === 'array' ? ']' : ''}
Expand All @@ -220,7 +250,7 @@ export default class SchemaTable extends LitElement {
}
<div class="attributes" title="${flags['🆁'] && 'Read only attribute' || flags['🆆'] && 'Write only attribute' || ''}">${flags['🆁'] || flags['🆆'] || ''}</div>
</div>
<div class='td key-descr'>
<div class='td key-descr' part="schema-description">
<span class=" m-markdown-small">${unsafeHTML(marked(displayLine))}</span>
${data['::metadata']?.constraints?.length
? html`<div style='display:inline-block; line-break:anywhere; margin-right:8px'><span class='bold-text'>Constraints: </span>${data['::metadata'].constraints.join(', ')}</div><br>` : ''}
Expand All @@ -234,43 +264,40 @@ export default class SchemaTable extends LitElement {
`
}
<div class='object-body'>
${Array.isArray(data) && data[0] ? html`${this.generateTree(data[0], 'xxx-of-option', '::ARRAY~OF', data[0]['::title'], data[0]['::description'], newSchemaLevel, newIndentLevel)}`
: html`
${Object.keys(data).map((dataKey) =>
!['::metadata', '::title', '::description', '::type', '::link', '::props', '::deprecated', '::array-type', '::dataTypeLabel', '::flags'].includes(dataKey)
|| data[dataKey]?.['::type'] && !data[dataKey]['::type'].includes('xxx-of')
? html`${this.generateTree(data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey],
data[dataKey]['::type'], dataKey, data[dataKey]['::title'], data[dataKey]['::description'], newSchemaLevel, newIndentLevel)}`
: ''
)}`
}
${recursiveResult}
<div>
`;

return {
result: outerResult,
keyLabelMaxCharacterLength: Math.max(innerMaxIndentationLevel, (keyLabel || keyDescr).length),
typeMaxCharacterLength: Math.max(innerTypeMaxCharacterLength, detailObjType.length) };
}

// For Primitive Data types
const { type, cssType, format, readOrWriteOnly, constraints, defaultValue, example, allowedValues, pattern, schemaDescription, schemaTitle, deprecated } = JSON.parse(data);
if (readOrWriteOnly === '🆁' && this.schemaHideReadOnly === 'true') {
return undefined;
return { result: undefined, keyLabelMaxCharacterLength: newIndentLevel };
}
if (readOrWriteOnly === '🆆' && this.schemaHideWriteOnly === 'true') {
return undefined;
return { result: undefined, keyLabelMaxCharacterLength: newIndentLevel };
}
return html`

const result = html`
<div class = "tr">
<div class="td key ${deprecated ? 'deprecated' : ''}" style='padding-left:${leftPadding}px'>
<div class="td key ${deprecated ? 'deprecated' : ''}" part="schema-key" style='padding-left:${leftPadding}px'>
${keyLabel?.endsWith('*')
? html`<span class="key-label requiredStar" title="Required">${keyLabel.substring(0, keyLabel.length - 1)}</span>`
: key.startsWith('::OPTION')
? html`<span class='xxx-of-key'>${keyLabel}</span><span class="xxx-of-descr">${keyDescr}</span>`
: html`${keyLabel ? html`<span class="key-label"> ${keyLabel}</span>` : html`<span class="xxx-of-descr">${schemaTitle}</span>`}`
}
</div>
<div class='td key-type'>
<div class='td key-type' part="schema-type">
<div>${dataType === 'array' ? '[' : ''}<span class="${cssType}">${format || type}</span>${dataType === 'array' ? ']' : ''}</div>
<div class="attributes ${cssType}" style="font-family: var(--font-mono);" title="${readOrWriteOnly === '🆁' && 'Read only attribute' || readOrWriteOnly === '🆆' && 'Write only attribute' || ''}">${readOrWriteOnly}</div>
</div>
<div class='td key-descr'>
<div class='td key-descr' part="schema-description">
<span class="m-markdown-small" style="vertical-align: middle;">
${unsafeHTML(marked(`${`${(schemaTitle || title) ? `**${schemaTitle || title}${schemaDescription || description ? ':' : ''}**` : ''} ${schemaDescription || description}` || ''}`))}
</span>
Expand All @@ -282,6 +309,7 @@ export default class SchemaTable extends LitElement {
</div>
</div>
`;
return { result, keyLabelMaxCharacterLength: keyLabel.length + newIndentLevel, typeMaxCharacterLength: (format || type).length };
}
/* eslint-enable indent */

Expand Down
4 changes: 2 additions & 2 deletions src/templates/callback-template.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function callbackTemplate(callbacks) {
schema-hide-read-only = "${this.schemaHideReadOnly}"
fetch-credentials = "${this.fetchCredentials}"
@scrollToSchemaComponentByName=${v => this.scrollToSchemaComponentByName(v)}
exportparts="btn, btn-fill, btn-outline, btn-try">
exportparts="btn, btn-fill, btn-outline, btn-try, schema-key, schema-type, schema-description, schema-table-header">
</api-request>

<api-response
Expand All @@ -49,7 +49,7 @@ export default function callbackTemplate(callbacks) {
active-schema-tab = "${this.defaultSchemaTab}"
schema-expand-level = "${this.schemaExpandLevel}"
@scrollToSchemaComponentByName=${v => this.scrollToSchemaComponentByName(v)}
exportparts = "btn--resp, btn-fill--resp, btn-outline--resp"
exportparts = "btn--resp, btn-fill--resp, btn-outline--resp, schema-key, schema-type, schema-description, schema-table-header"
> </api-response>
</div>
</div>
Expand Down
6 changes: 4 additions & 2 deletions src/templates/components-template.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ function componentBodyTemplate(sComponent) {
@scrollToSchemaComponentByName=${v => this.scrollToSchemaComponentByName(v)}
schema-expand-level = "${this.schemaExpandLevel}"
schema-hide-read-only=false
schema-hide-write-only=false> </schema-table>`
schema-hide-write-only=false
exportparts="schema-key, schema-type, schema-description, schema-table-header"> </schema-table>`

: html`<schema-tree
.data = '${formdataPartSchema}'
schema-expand-level = "${this.schemaExpandLevel}"
schema-hide-read-only=false
schema-hide-write-only=false> </schema-tree>`
schema-hide-write-only=false
exportparts="schema-key, schema-type, schema-description"> </schema-tree>`
}
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/templates/endpoint-template.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ function endpointBodyTemplate(path) {
schema-hide-read-only = "${this.schemaHideReadOnly}"
fetch-credentials = "${this.fetchCredentials}"
@scrollToSchemaComponentByName=${v => this.scrollToSchemaComponentByName(v)}
exportparts="btn, btn-fill, btn-outline, btn-try">
exportparts="btn, btn-fill, btn-outline, btn-try, schema-key, schema-type, schema-description, schema-table-header">
</api-request>
</div>
${path.callbacks ? callbackTemplate.call(this, path.callbacks) : ''}
Expand All @@ -124,7 +124,7 @@ function endpointBodyTemplate(path) {
schema-hide-write-only = "${this.schemaHideWriteOnly}"
selected-status = "${Object.keys(path.responses || {})[0] || ''}"
@scrollToSchemaComponentByName=${v => this.scrollToSchemaComponentByName(v)}
exportparts = "btn--resp, btn-fill--resp, btn-outline--resp"
exportparts = "btn--resp, btn-fill--resp, btn-outline--resp, schema-key, schema-type, schema-description, schema-table-header"
> </api-response>
</div>
</div>`;
Expand Down
4 changes: 2 additions & 2 deletions src/templates/expanded-endpoint-template.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export function expandedEndpointBodyTemplate(path, tagName = '') {
schema-hide-read-only = "${this.schemaHideReadOnly}"
fetch-credentials = "${this.fetchCredentials}"
@scrollToSchemaComponentByName=${v => this.scrollToSchemaComponentByName(v)}
exportparts = "btn, btn-fill, btn-outline, btn-try"
exportparts = "btn, btn-fill, btn-outline, btn-try, schema-key, schema-type, schema-description, schema-table-header"
> </api-request>

${path.callbacks ? callbackTemplate.call(this, path.callbacks) : ''}
Expand All @@ -84,7 +84,7 @@ export function expandedEndpointBodyTemplate(path, tagName = '') {
schema-hide-write-only = "${this.schemaHideWriteOnly}"
selected-status = "${Object.keys(path.responses || {})[0] || ''}"
@scrollToSchemaComponentByName=${v => this.scrollToSchemaComponentByName(v)}
exportparts = "btn--resp, btn-fill--resp, btn-outline--resp"
exportparts = "btn--resp, btn-fill--resp, btn-outline--resp, schema-key, schema-type, schema-description, schema-table-header"
> </api-response>
</div>
</div>`;
Expand Down
Loading