import * as React from 'react'; import Attributes from './Attributes'; import Collapsoid from './Collapsoid'; import TextNode from './TextNode'; import { Actions, BubbleOptions, Element as ElementConfig, Xml } from './types'; import { push, updateNode } from './Util'; interface Props { actions: Actions; attributes?: { [key: string]: string }; childElements?: ElementConfig[]; collapsed?: boolean; id: string[]; name: string; xml: Xml; } export default class Element extends React.Component { private ref: React.RefObject; public constructor(props: Props) { super(props); this.onCollapse = this.onCollapse.bind(this); this.onClick = this.onClick.bind(this); this.ref = React.createRef(); } public render(): React.ReactNode { const { actions, childElements, collapsed, id, name, xml, } = this.props; const elements: React.ReactNode[] = []; if (childElements) { childElements.forEach((childElement: ElementConfig, index: number) => { if (childElement['#name'] !== '__text__') { elements.push( , ); } else if (childElement._) { elements.push( , ); } }); } const childrenContainer = ( {childElements && }
{ elements }
); let elementClass = ''; if (elements.length === 0) { elementClass = ' noChildren'; } let expandCollapseLabel = 'Collapse'; if (collapsed) { elementClass += ' collapsed'; expandCollapseLabel = 'Expand'; } const openingTag = ( < { name } { this.getAttributes() } / > ); let closingTag; if (elements.length > 0) { closingTag = ( < / { name } > ); } return (
{ openingTag } { childrenContainer } { closingTag }
); } private onClick(event: React.MouseEvent) { const { actions, id, name } = this.props; const bubbleOptions: Partial = { id, element: name, show: true, value: name, }; if (this.ref.current) { const rect = this.ref.current.getBoundingClientRect(); bubbleOptions.left = rect.left; bubbleOptions.top = rect.top; } actions.showBubble(bubbleOptions); event.stopPropagation(); } private onCollapse() { const { actions, collapsed, id, xml } = this.props; const collapseId = push(id, '#collapsed'); actions.showBubble({ show: false, }); actions.setXml(updateNode(xml, collapseId, !collapsed)); } private getAttributes() { const { actions, attributes, id, name } = this.props; if (attributes) { return ( ); } return null; } }