mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-29 20:13:43 +03:00
chore: refactor ObjectSchema and Field, less rerenders on expand
This commit is contained in:
parent
1f7fc44292
commit
71e189ffc5
|
@ -7,15 +7,17 @@ import {
|
||||||
PropertyBullet,
|
PropertyBullet,
|
||||||
PropertyDetailsCell,
|
PropertyDetailsCell,
|
||||||
PropertyNameCell,
|
PropertyNameCell,
|
||||||
|
InnerPropertiesWrap,
|
||||||
|
PropertyCellWithInner,
|
||||||
} from '../../common-elements/fields-layout';
|
} from '../../common-elements/fields-layout';
|
||||||
|
|
||||||
import { ShelfIcon } from '../../common-elements/';
|
import { ShelfIcon } from '../../common-elements/';
|
||||||
|
|
||||||
import { FieldModel } from '../../services/models';
|
import { FieldModel } from '../../services/models';
|
||||||
|
import { Schema, SchemaOptions } from '../Schema/Schema';
|
||||||
|
|
||||||
export interface FieldProps {
|
export interface FieldProps extends SchemaOptions {
|
||||||
className?: string;
|
className?: string;
|
||||||
onClick?: () => void;
|
|
||||||
isLast?: boolean;
|
isLast?: boolean;
|
||||||
showExamples?: boolean;
|
showExamples?: boolean;
|
||||||
|
|
||||||
|
@ -25,15 +27,16 @@ export interface FieldProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Field extends React.PureComponent<FieldProps> {
|
export class Field extends React.PureComponent<FieldProps> {
|
||||||
|
toggle = () => {
|
||||||
|
this.props.field.toggle();
|
||||||
|
};
|
||||||
render() {
|
render() {
|
||||||
const { className, field, isLast } = this.props;
|
const { className, field, isLast } = this.props;
|
||||||
const { name, expanded, deprecated, required } = field;
|
const { name, expanded, deprecated, required } = field;
|
||||||
|
const withSubSchema = !field.schema.isPrimitive && !field.schema.isCircular;
|
||||||
|
|
||||||
const paramName = this.props.onClick ? (
|
const paramName = withSubSchema ? (
|
||||||
<ClickablePropertyNameCell
|
<ClickablePropertyNameCell onClick={this.toggle} className={deprecated ? 'deprecated' : ''}>
|
||||||
onClick={this.props.onClick}
|
|
||||||
className={deprecated ? 'deprecated' : ''}
|
|
||||||
>
|
|
||||||
<PropertyBullet />
|
<PropertyBullet />
|
||||||
{name}
|
{name}
|
||||||
<ShelfIcon size={'1.2em'} direction={expanded ? 'down' : 'right'} />
|
<ShelfIcon size={'1.2em'} direction={expanded ? 'down' : 'right'} />
|
||||||
|
@ -47,12 +50,29 @@ export class Field extends React.PureComponent<FieldProps> {
|
||||||
</PropertyNameCell>
|
</PropertyNameCell>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<tr className={isLast ? 'last ' + className : className}>
|
<tr className={isLast ? 'last ' + className : className}>
|
||||||
{paramName}
|
{paramName}
|
||||||
<PropertyDetailsCell>
|
<PropertyDetailsCell>
|
||||||
<FieldDetails {...this.props} />
|
<FieldDetails {...this.props} />
|
||||||
</PropertyDetailsCell>
|
</PropertyDetailsCell>
|
||||||
</tr>
|
</tr>
|
||||||
|
{field.expanded &&
|
||||||
|
withSubSchema && (
|
||||||
|
<tr key={field.name + 'inner'}>
|
||||||
|
<PropertyCellWithInner colSpan={2}>
|
||||||
|
<InnerPropertiesWrap>
|
||||||
|
<Schema
|
||||||
|
schema={field.schema}
|
||||||
|
skipReadOnly={this.props.skipReadOnly}
|
||||||
|
skipWriteOnly={this.props.skipWriteOnly}
|
||||||
|
showTitle={this.props.showTitle}
|
||||||
|
/>
|
||||||
|
</InnerPropertiesWrap>
|
||||||
|
</PropertyCellWithInner>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import { FieldModel, SchemaModel } from '../../services/models';
|
import { SchemaModel } from '../../services/models';
|
||||||
|
|
||||||
import {
|
import { PropertiesTable, PropertiesTableCaption } from '../../common-elements/fields-layout';
|
||||||
InnerPropertiesWrap,
|
|
||||||
PropertiesTable,
|
|
||||||
PropertiesTableCaption,
|
|
||||||
PropertyCellWithInner,
|
|
||||||
} from '../../common-elements/fields-layout';
|
|
||||||
import { Field } from '../Fields/Field';
|
import { Field } from '../Fields/Field';
|
||||||
import { DiscriminatorDropdown } from './DiscriminatorDropdown';
|
import { DiscriminatorDropdown } from './DiscriminatorDropdown';
|
||||||
import { Schema, SchemaProps } from './Schema';
|
import { SchemaProps } from './Schema';
|
||||||
|
|
||||||
import { mapWithLast } from '../../utils';
|
import { mapWithLast } from '../../utils';
|
||||||
|
|
||||||
|
@ -28,42 +23,6 @@ export class ObjectSchema extends React.Component<ObjectSchemaProps> {
|
||||||
return this.props.discriminator!.parentSchema;
|
return this.props.discriminator!.parentSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderField(field: FieldModel, isLast: boolean, isDiscriminator: boolean = false) {
|
|
||||||
const withSubSchema = !field.schema.isPrimitive && !field.schema.isCircular;
|
|
||||||
return [
|
|
||||||
<Field
|
|
||||||
key={field.name}
|
|
||||||
isLast={isLast}
|
|
||||||
field={field}
|
|
||||||
onClick={(withSubSchema && (() => field.toggle())) || undefined}
|
|
||||||
renderDiscriminatorSwitch={
|
|
||||||
(isDiscriminator &&
|
|
||||||
(() => (
|
|
||||||
<DiscriminatorDropdown parent={this.parentSchema} enumValues={field.schema.enum} />
|
|
||||||
))) ||
|
|
||||||
undefined
|
|
||||||
}
|
|
||||||
className={field.expanded ? 'expanded' : undefined}
|
|
||||||
showExamples={false}
|
|
||||||
/>,
|
|
||||||
field.expanded &&
|
|
||||||
withSubSchema && (
|
|
||||||
<tr key={field.name + 'inner'}>
|
|
||||||
<PropertyCellWithInner colSpan={2}>
|
|
||||||
<InnerPropertiesWrap>
|
|
||||||
<Schema
|
|
||||||
schema={field.schema}
|
|
||||||
skipReadOnly={this.props.skipReadOnly}
|
|
||||||
skipWriteOnly={this.props.skipWriteOnly}
|
|
||||||
showTitle={this.props.showTitle}
|
|
||||||
/>
|
|
||||||
</InnerPropertiesWrap>
|
|
||||||
</PropertyCellWithInner>
|
|
||||||
</tr>
|
|
||||||
),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { schema: { fields = [] }, showTitle, discriminator } = this.props;
|
const { schema: { fields = [] }, showTitle, discriminator } = this.props;
|
||||||
|
|
||||||
|
@ -82,13 +41,31 @@ export class ObjectSchema extends React.Component<ObjectSchemaProps> {
|
||||||
<PropertiesTable>
|
<PropertiesTable>
|
||||||
{showTitle && <PropertiesTableCaption>{this.props.schema.title}</PropertiesTableCaption>}
|
{showTitle && <PropertiesTableCaption>{this.props.schema.title}</PropertiesTableCaption>}
|
||||||
<tbody>
|
<tbody>
|
||||||
{mapWithLast(filteredFields, (field, isLast) =>
|
{mapWithLast(filteredFields, (field, isLast) => {
|
||||||
this.renderField(
|
return (
|
||||||
field,
|
<Field
|
||||||
isLast,
|
key={field.name}
|
||||||
discriminator && discriminator.fieldName === field.name,
|
isLast={isLast}
|
||||||
),
|
field={field}
|
||||||
)}
|
renderDiscriminatorSwitch={
|
||||||
|
(discriminator &&
|
||||||
|
discriminator.fieldName === field.name &&
|
||||||
|
(() => (
|
||||||
|
<DiscriminatorDropdown
|
||||||
|
parent={this.parentSchema}
|
||||||
|
enumValues={field.schema.enum}
|
||||||
|
/>
|
||||||
|
))) ||
|
||||||
|
undefined
|
||||||
|
}
|
||||||
|
className={field.expanded ? 'expanded' : undefined}
|
||||||
|
showExamples={false}
|
||||||
|
skipReadOnly={this.props.skipReadOnly}
|
||||||
|
skipWriteOnly={this.props.skipWriteOnly}
|
||||||
|
showTitle={this.props.showTitle}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</PropertiesTable>
|
</PropertiesTable>
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,13 +10,16 @@ import { ArraySchema } from './ArraySchema';
|
||||||
import { ObjectSchema } from './ObjectSchema';
|
import { ObjectSchema } from './ObjectSchema';
|
||||||
import { OneOfSchema } from './OneOfSchema';
|
import { OneOfSchema } from './OneOfSchema';
|
||||||
|
|
||||||
export interface SchemaProps {
|
export interface SchemaOptions {
|
||||||
schema: SchemaModel;
|
|
||||||
showTitle?: boolean;
|
showTitle?: boolean;
|
||||||
skipReadOnly?: boolean;
|
skipReadOnly?: boolean;
|
||||||
skipWriteOnly?: boolean;
|
skipWriteOnly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SchemaProps extends SchemaOptions {
|
||||||
|
schema: SchemaModel;
|
||||||
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class Schema extends React.Component<Partial<SchemaProps>> {
|
export class Schema extends React.Component<Partial<SchemaProps>> {
|
||||||
render() {
|
render() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user