1import { css } from '@emotion/react'; 2import { theme } from '@expo/styleguide'; 3import MDX from '@mdx-js/runtime'; 4import * as React from 'react'; 5 6import * as components from '~/common/translate-markdown'; 7 8const STYLES_TABLE = css` 9 font-size: 1rem; 10 margin-top: 24px; 11`; 12 13const STYLES_HEAD = css` 14 background-color: ${theme.background.tertiary}; 15`; 16 17const STYLES_DESCRIPTION_CELL = css` 18 word-break: break-word; 19 white-space: break-spaces; 20 padding-bottom: 0.2rem; 21`; 22 23export type Property = { 24 description?: string[]; 25 name: string; 26 type?: string | string[]; 27 enum?: string[]; 28 properties?: Property[]; 29}; 30 31type FormattedProperty = { 32 name: string; 33 description: string; 34 nestingLevel: number; 35}; 36 37export function formatSchema(rawSchema: Property[]) { 38 const formattedSchema: FormattedProperty[] = []; 39 40 rawSchema.map(property => { 41 appendProperty(formattedSchema, property, 0); 42 }); 43 44 return formattedSchema; 45} 46 47//appends a property and recursively appends sub-properties 48function appendProperty( 49 formattedSchema: FormattedProperty[], 50 property: Property, 51 _nestingLevel: number 52) { 53 let nestingLevel = _nestingLevel; 54 55 formattedSchema.push({ 56 name: nestingLevel 57 ? `<subpropertyAnchor level={${nestingLevel}}><inlineCode>${property.name}</inlineCode></subpropertyAnchor>` 58 : `<propertyAnchor level={0}><inlineCode>${property.name}</inlineCode></propertyAnchor>`, 59 description: createDescription(property), 60 nestingLevel, 61 }); 62 63 nestingLevel++; 64 65 if (property.properties) { 66 (property.properties ?? []).forEach(subproperty => { 67 appendProperty(formattedSchema, subproperty, nestingLevel); 68 }); 69 } 70} 71 72export function _getType(property: Property) { 73 if (property.enum) { 74 return 'enum'; 75 } else { 76 return property.type?.toString().replace(/,/g, ' || '); 77 } 78} 79 80export function createDescription(property: Property) { 81 let propertyDescription = `**(${_getType(property)})**`; 82 if (property.description) { 83 propertyDescription += ` - ` + property.description.join('\n'); 84 } 85 86 return propertyDescription; 87} 88 89export default class EasJsonPropertiesTable extends React.Component<{ 90 schema: Property[]; 91}> { 92 render() { 93 const formattedSchema = formatSchema(this.props.schema); 94 95 return ( 96 <table css={STYLES_TABLE}> 97 <thead css={STYLES_HEAD}> 98 <tr> 99 <td>Property</td> 100 <td>Description</td> 101 </tr> 102 </thead> 103 <tbody> 104 {formattedSchema.map((property, index) => { 105 return ( 106 <tr key={index}> 107 <td> 108 <div 109 data-testid={property.name} 110 style={{ 111 marginLeft: `${property.nestingLevel * 32}px`, 112 display: property.nestingLevel ? 'list-item' : 'block', 113 listStyleType: property.nestingLevel % 2 ? 'default' : 'circle', 114 width: 'fit-content', 115 overflowX: 'visible', 116 }}> 117 <MDX components={components}>{property.name}</MDX> 118 </div> 119 </td> 120 <td css={STYLES_DESCRIPTION_CELL}> 121 <MDX components={components}>{property.description}</MDX> 122 </td> 123 </tr> 124 ); 125 })} 126 </tbody> 127 </table> 128 ); 129 } 130} 131