mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-29 03:53:43 +03:00
feat: add sampleCollapseLevel option (#937)
* feat: add sampleCollapseLevel option * fix: rename sampleCollapseLevel option to jsonSampleExpandLevel Change README.md description * fix: provide maxCollapseLevel option via argument * fix: rename normalizer function and some vars
This commit is contained in:
parent
7c06735c6d
commit
d3f1c1677c
|
@ -243,6 +243,7 @@ You can use all of the following options with standalone version on <redoc> tag
|
||||||
* `hideDownloadButton` - do not show "Download" spec button. **THIS DOESN'T MAKE YOUR SPEC PRIVATE**, it just hides the button.
|
* `hideDownloadButton` - do not show "Download" spec button. **THIS DOESN'T MAKE YOUR SPEC PRIVATE**, it just hides the button.
|
||||||
* `disableSearch` - disable search indexing and search box
|
* `disableSearch` - disable search indexing and search box
|
||||||
* `onlyRequiredInSamples` - shows only required fields in request samples.
|
* `onlyRequiredInSamples` - shows only required fields in request samples.
|
||||||
|
* `jsonSampleExpandLevel` - set the default expand level for JSON payload samples (responses and request body). Special value 'all' expands all levels. The default value is `2`.
|
||||||
* `theme` - ReDoc theme. Not documented yet. For details check source code: [theme.ts](https://github.com/Redocly/redoc/blob/master/src/theme.ts)
|
* `theme` - ReDoc theme. Not documented yet. For details check source code: [theme.ts](https://github.com/Redocly/redoc/blob/master/src/theme.ts)
|
||||||
|
|
||||||
## Advanced usage of standalone version
|
## Advanced usage of standalone version
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { SampleControls } from '../../common-elements';
|
||||||
import { CopyButtonWrapper } from '../../common-elements/CopyButtonWrapper';
|
import { CopyButtonWrapper } from '../../common-elements/CopyButtonWrapper';
|
||||||
import { PrismDiv } from '../../common-elements/PrismDiv';
|
import { PrismDiv } from '../../common-elements/PrismDiv';
|
||||||
import { jsonToHTML } from '../../utils/jsonToHtml';
|
import { jsonToHTML } from '../../utils/jsonToHtml';
|
||||||
|
import { OptionsContext } from '../OptionsProvider';
|
||||||
import { jsonStyles } from './style';
|
import { jsonStyles } from './style';
|
||||||
|
|
||||||
export interface JsonProps {
|
export interface JsonProps {
|
||||||
|
@ -32,12 +33,18 @@ class Json extends React.PureComponent<JsonProps> {
|
||||||
<span onClick={this.expandAll}> Expand all </span>
|
<span onClick={this.expandAll}> Expand all </span>
|
||||||
<span onClick={this.collapseAll}> Collapse all </span>
|
<span onClick={this.collapseAll}> Collapse all </span>
|
||||||
</SampleControls>
|
</SampleControls>
|
||||||
<PrismDiv
|
<OptionsContext.Consumer>
|
||||||
className={this.props.className}
|
{options => (
|
||||||
// tslint:disable-next-line
|
<PrismDiv
|
||||||
ref={node => (this.node = node!)}
|
className={this.props.className}
|
||||||
dangerouslySetInnerHTML={{ __html: jsonToHTML(this.props.data) }}
|
// tslint:disable-next-line
|
||||||
/>
|
ref={node => (this.node = node!)}
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: jsonToHTML(this.props.data, options.jsonSampleExpandLevel),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</OptionsContext.Consumer>
|
||||||
</JsonViewerWrap>
|
</JsonViewerWrap>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ export interface RedocRawOptions {
|
||||||
onlyRequiredInSamples?: boolean | string;
|
onlyRequiredInSamples?: boolean | string;
|
||||||
showExtensions?: boolean | string | string[];
|
showExtensions?: boolean | string | string[];
|
||||||
hideSingleRequestSampleTab?: boolean | string;
|
hideSingleRequestSampleTab?: boolean | string;
|
||||||
|
jsonSampleExpandLevel?: number | string | 'all';
|
||||||
|
|
||||||
unstable_ignoreMimeParameters?: boolean;
|
unstable_ignoreMimeParameters?: boolean;
|
||||||
|
|
||||||
|
@ -111,6 +112,16 @@ export class RedocNormalizedOptions {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static normalizeJsonSampleExpandLevel(level?: number | string | 'all'): number {
|
||||||
|
if (level === 'all') {
|
||||||
|
return +Infinity;
|
||||||
|
}
|
||||||
|
if (!isNaN(Number(level))) {
|
||||||
|
return Math.ceil(Number(level));
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
theme: ResolvedThemeInterface;
|
theme: ResolvedThemeInterface;
|
||||||
scrollYOffset: () => number;
|
scrollYOffset: () => number;
|
||||||
hideHostname: boolean;
|
hideHostname: boolean;
|
||||||
|
@ -126,6 +137,7 @@ export class RedocNormalizedOptions {
|
||||||
onlyRequiredInSamples: boolean;
|
onlyRequiredInSamples: boolean;
|
||||||
showExtensions: boolean | string[];
|
showExtensions: boolean | string[];
|
||||||
hideSingleRequestSampleTab: boolean;
|
hideSingleRequestSampleTab: boolean;
|
||||||
|
jsonSampleExpandLevel: number;
|
||||||
enumSkipQuotes: boolean;
|
enumSkipQuotes: boolean;
|
||||||
|
|
||||||
/* tslint:disable-next-line */
|
/* tslint:disable-next-line */
|
||||||
|
@ -158,6 +170,9 @@ export class RedocNormalizedOptions {
|
||||||
this.onlyRequiredInSamples = argValueToBoolean(raw.onlyRequiredInSamples);
|
this.onlyRequiredInSamples = argValueToBoolean(raw.onlyRequiredInSamples);
|
||||||
this.showExtensions = RedocNormalizedOptions.normalizeShowExtensions(raw.showExtensions);
|
this.showExtensions = RedocNormalizedOptions.normalizeShowExtensions(raw.showExtensions);
|
||||||
this.hideSingleRequestSampleTab = argValueToBoolean(raw.hideSingleRequestSampleTab);
|
this.hideSingleRequestSampleTab = argValueToBoolean(raw.hideSingleRequestSampleTab);
|
||||||
|
this.jsonSampleExpandLevel = RedocNormalizedOptions.normalizeJsonSampleExpandLevel(
|
||||||
|
raw.jsonSampleExpandLevel,
|
||||||
|
);
|
||||||
this.enumSkipQuotes = argValueToBoolean(raw.enumSkipQuotes);
|
this.enumSkipQuotes = argValueToBoolean(raw.enumSkipQuotes);
|
||||||
|
|
||||||
this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters);
|
this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters);
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
let level = 1;
|
let level = 1;
|
||||||
const COLLAPSE_LEVEL = 2;
|
|
||||||
|
|
||||||
export function jsonToHTML(json) {
|
export function jsonToHTML(json, maxExpandLevel) {
|
||||||
level = 1;
|
level = 1;
|
||||||
let output = '';
|
let output = '';
|
||||||
output += '<div class="redoc-json">';
|
output += '<div class="redoc-json">';
|
||||||
output += valueToHTML(json);
|
output += valueToHTML(json, maxExpandLevel);
|
||||||
output += '</div>';
|
output += '</div>';
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -33,20 +32,20 @@ function punctuation(val) {
|
||||||
return '<span class="token punctuation">' + val + '</span>';
|
return '<span class="token punctuation">' + val + '</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
function valueToHTML(value) {
|
function valueToHTML(value, maxExpandLevel: number) {
|
||||||
const valueType = typeof value;
|
const valueType = typeof value;
|
||||||
let output = '';
|
let output = '';
|
||||||
if (value === undefined || value === null) {
|
if (value === undefined || value === null) {
|
||||||
output += decorateWithSpan('null', 'token keyword');
|
output += decorateWithSpan('null', 'token keyword');
|
||||||
} else if (value && value.constructor === Array) {
|
} else if (value && value.constructor === Array) {
|
||||||
level++;
|
level++;
|
||||||
output += arrayToHTML(value);
|
output += arrayToHTML(value, maxExpandLevel);
|
||||||
level--;
|
level--;
|
||||||
} else if (value && value.constructor === Date) {
|
} else if (value && value.constructor === Date) {
|
||||||
output += decorateWithSpan('"' + value.toISOString() + '"', 'token string');
|
output += decorateWithSpan('"' + value.toISOString() + '"', 'token string');
|
||||||
} else if (valueType === 'object') {
|
} else if (valueType === 'object') {
|
||||||
level++;
|
level++;
|
||||||
output += objectToHTML(value);
|
output += objectToHTML(value, maxExpandLevel);
|
||||||
level--;
|
level--;
|
||||||
} else if (valueType === 'number') {
|
} else if (valueType === 'number') {
|
||||||
output += decorateWithSpan(value, 'token number');
|
output += decorateWithSpan(value, 'token number');
|
||||||
|
@ -70,8 +69,8 @@ function valueToHTML(value) {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
function arrayToHTML(json) {
|
function arrayToHTML(json, maxExpandLevel: number) {
|
||||||
const collapsed = level > COLLAPSE_LEVEL ? 'collapsed' : '';
|
const collapsed = level > maxExpandLevel ? 'collapsed' : '';
|
||||||
let output = `<div class="collapser"></div>${punctuation(
|
let output = `<div class="collapser"></div>${punctuation(
|
||||||
'[',
|
'[',
|
||||||
)}<span class="ellipsis"></span><ul class="array collapsible">`;
|
)}<span class="ellipsis"></span><ul class="array collapsible">`;
|
||||||
|
@ -80,7 +79,7 @@ function arrayToHTML(json) {
|
||||||
for (let i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
hasContents = true;
|
hasContents = true;
|
||||||
output += '<li><div class="hoverable ' + collapsed + '">';
|
output += '<li><div class="hoverable ' + collapsed + '">';
|
||||||
output += valueToHTML(json[i]);
|
output += valueToHTML(json[i], maxExpandLevel);
|
||||||
if (i < length - 1) {
|
if (i < length - 1) {
|
||||||
output += ',';
|
output += ',';
|
||||||
}
|
}
|
||||||
|
@ -93,8 +92,8 @@ function arrayToHTML(json) {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
function objectToHTML(json) {
|
function objectToHTML(json, maxExpandLevel: number) {
|
||||||
const collapsed = level > COLLAPSE_LEVEL ? 'collapsed' : '';
|
const collapsed = level > maxExpandLevel ? 'collapsed' : '';
|
||||||
const keys = Object.keys(json);
|
const keys = Object.keys(json);
|
||||||
const length = keys.length;
|
const length = keys.length;
|
||||||
let output = `<div class="collapser"></div>${punctuation(
|
let output = `<div class="collapser"></div>${punctuation(
|
||||||
|
@ -106,7 +105,7 @@ function objectToHTML(json) {
|
||||||
hasContents = true;
|
hasContents = true;
|
||||||
output += '<li><div class="hoverable ' + collapsed + '">';
|
output += '<li><div class="hoverable ' + collapsed + '">';
|
||||||
output += '<span class="property token string">"' + htmlEncode(key) + '"</span>: ';
|
output += '<span class="property token string">"' + htmlEncode(key) + '"</span>: ';
|
||||||
output += valueToHTML(json[key]);
|
output += valueToHTML(json[key], maxExpandLevel);
|
||||||
if (i < length - 1) {
|
if (i < length - 1) {
|
||||||
output += punctuation(',');
|
output += punctuation(',');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user