@talend/react-components
Version:
Set of react components.
277 lines (267 loc) • 6.81 kB
JavaScript
import PropTypes from 'prop-types';
import classNames from 'classnames';
import css from './JSONSchemaRenderer.module.scss';
import { entries, get } from "lodash";
import { jsx as _jsx } from "react/jsx-runtime";
const CLASS_NAME = 'json-schema-renderer';
const RendererProptypes = {
propertyKey: PropTypes.string.isRequired,
title: PropTypes.string
};
const SchemaProptypes = {
jsonSchema: PropTypes.object.isRequired,
uiSchema: PropTypes.shape({
'ui:order': PropTypes.array
}),
properties: PropTypes.object.isRequired
};
/**
* UnknownTypeException
*
* @param {string} type - The Unknown type
* @returns {Object} An UnknownTypeException
*/
function UnknownTypeException(type) {
this.name = 'UnknownTypeException';
this.message = `Unknown type: ${type}`;
}
/**
* InvalidSchemaException
*
* @returns {Object} An InvalidSchemaException
*/
function InvalidSchemaException() {
this.name = 'InvalidSchemaException';
this.message = 'Invalid Schema';
}
/**
* NullRenderer renders nothing to hide specified properties
* or properties that don't have a corresponding schema definition
*
* @returns null
*/
function NullRenderer() {
return null;
}
/**
* TextRenderer renders text based properties (string and numbers)
*/
function TextRenderer({
propertyKey,
title,
properties
}) {
return [/*#__PURE__*/_jsx("dt", {
children: title || propertyKey
}, `${propertyKey}_key`), /*#__PURE__*/_jsx("dd", {
children: properties
}, `${propertyKey}_value`)];
}
TextRenderer.propTypes = {
...RendererProptypes,
properties: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
};
function PasswordRenderer({
propertyKey,
title
}) {
return [/*#__PURE__*/_jsx("dt", {
children: title || propertyKey
}, `${propertyKey}_key`), /*#__PURE__*/_jsx("dd", {
children: '\u2022'.repeat(5)
}, `${propertyKey}_value`)];
}
PasswordRenderer.propTypes = {
...RendererProptypes,
properties: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
};
/**
* booleanRenderer renders boolean properties
*/
function BooleanRenderer({
propertyKey,
title,
properties
}) {
return [/*#__PURE__*/_jsx("dt", {
children: title || propertyKey
}, `${propertyKey}_key`), /*#__PURE__*/_jsx("dd", {
children: properties
}, `${propertyKey}_value`)];
}
BooleanRenderer.propTypes = {
...RendererProptypes,
properties: PropTypes.bool.isRequired
};
/**
* arrayRenderer renders an array of properties
*/
function ArrayRenderer({
propertyKey,
title,
properties
}) {
return [/*#__PURE__*/_jsx("dt", {
children: title || propertyKey
}, `${propertyKey}_key`)].concat(properties.map((val, i) => /*#__PURE__*/_jsx("dd", {
className: css['array-value'],
children: val
}, `${propertyKey}-value-${i}`)));
}
ArrayRenderer.propTypes = {
...RendererProptypes,
properties: PropTypes.arrayOf(PropTypes.shape({
...RendererProptypes
})).isRequired
};
const registry = {
string: TextRenderer,
integer: TextRenderer,
boolean: BooleanRenderer,
array: ArrayRenderer,
object: ObjectRenderer // eslint-disable-line @typescript-eslint/no-use-before-define
};
function isHidden(uiSchema, element) {
return uiSchema && uiSchema[element] && uiSchema[element]['ui:widget'] === 'hidden';
}
function isPassword(uiSchema, element) {
return get(uiSchema, [element, 'ui:widget'], '') === 'password';
}
/**
* typeResolver
*
* @param schema - The JSONSchema of the data being rendered
* @param uiSchema
* @throws {UnknownTypeException} Type must be part of the registry
* @returns {Object} Resolved Renderer and props
*/
function typeResolver(schema, uiSchema) {
return function resolver(e) {
if (!schema[e[0]]) {
return {
render: NullRenderer
};
}
if (isHidden(uiSchema, e[0])) {
return {
render: NullRenderer
};
}
const type = schema[e[0]].type;
const title = schema[e[0]].title;
if (isPassword(uiSchema, e[0])) {
return {
render: PasswordRenderer,
propertyKey: e[0],
title,
properties: e[1],
schema,
uiSchema
};
}
const renderer = registry[type];
if (!renderer) {
throw new UnknownTypeException(type);
}
return {
render: renderer,
propertyKey: e[0],
title,
properties: e[1],
schema,
uiSchema
};
};
}
/**
* orderProperties sorts properties based on uiSchema ui:order array
*
* @param order
* @param properties
* @returns {Array}
*/
function orderProperties(order, properties) {
if (!order) {
return properties;
}
return properties.sort((a, b) => {
const aIndex = order.indexOf(a[0]);
const bIndex = order.indexOf(b[0]);
if (aIndex < 0) {
return 1;
}
if (bIndex < 0) {
return -1;
}
return aIndex - bIndex;
});
}
/**
* objectRenderer renders nested properties
*/
function ObjectRenderer({
propertyKey,
title,
uiSchema,
schema,
properties,
...props
}) {
return [/*#__PURE__*/_jsx("dt", {
children: /*#__PURE__*/_jsx("h2", {
children: title || propertyKey
})
}, `${propertyKey}_key`), /*#__PURE__*/_jsx("dd", {
children: /*#__PURE__*/_jsx(JSONSchemaRenderer, {
schema: {
jsonSchema: schema[propertyKey],
uiSchema: uiSchema[propertyKey],
properties
},
className: css.nested,
...props
})
}, `${propertyKey}_value`)];
}
ObjectRenderer.propTypes = {
...RendererProptypes,
schema: PropTypes.shape(SchemaProptypes)
};
/**
* JSONSchemaRenderer renders elements based on a JSONSchema and data
*
* @throws {InvalidSchemaException} schema must contain a jsonSchema and
* properties
* @returns {string} - HTML markup for the component
*/
function JSONSchemaRenderer({
schema,
className,
...props
}) {
if (!schema.jsonSchema || !schema.properties) {
throw new InvalidSchemaException();
}
let properties = entries(schema.properties);
if (schema.uiSchema) {
properties = orderProperties(schema.uiSchema['ui:order'], properties);
}
const elements = properties.map(typeResolver(schema.jsonSchema.properties, schema.uiSchema));
return /*#__PURE__*/_jsx("dl", {
className: classNames(css[CLASS_NAME], 'json-schema-renderer', className),
...props,
children: elements.map(({
render,
...rest
}) => render(rest))
});
}
JSONSchemaRenderer.displayName = 'JSONSchemaRenderer';
JSONSchemaRenderer.propTypes = {
schema: PropTypes.shape(SchemaProptypes),
className: PropTypes.string
};
JSONSchemaRenderer.InvalidSchemaException = InvalidSchemaException;
JSONSchemaRenderer.UnknownTypeException = UnknownTypeException;
export default JSONSchemaRenderer;
//# sourceMappingURL=JSONSchemaRenderer.component.js.map