Merged PR 18: Add support for custom SVG
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Add support for custom SVG Add userData back into IProperties Added library interweave Update example
This commit is contained in:
parent
82eae4971e
commit
e96e4f123b
8 changed files with 109 additions and 9 deletions
|
@ -218,7 +218,9 @@ export function AddContainer(
|
|||
isRigidBody: false,
|
||||
isAnchor: false,
|
||||
XPositionReference: containerConfig.XPositionReference ?? XPositionReference.Left,
|
||||
style: containerConfig.Style
|
||||
customSVG: containerConfig.CustomSVG,
|
||||
style: containerConfig.Style,
|
||||
userData: containerConfig.UserData
|
||||
};
|
||||
|
||||
// Create the container
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import * as React from 'react';
|
||||
import { Interweave, Node } from 'interweave';
|
||||
import { XPositionReference } from '../../../Enums/XPositionReference';
|
||||
import { IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||
import { DIMENSION_MARGIN } from '../../../utils/default';
|
||||
import { getDepth } from '../../../utils/itertools';
|
||||
import { Dimension } from './Dimension';
|
||||
import IProperties from '../../../Interfaces/IProperties';
|
||||
|
||||
interface IContainerProps {
|
||||
model: IContainerModel
|
||||
|
@ -33,6 +35,14 @@ export const Container: React.FC<IContainerProps> = (props: IContainerProps) =>
|
|||
props.model.properties.style
|
||||
);
|
||||
|
||||
const svg = (props.model.properties.customSVG != null)
|
||||
? CreateReactCustomSVG(props.model.properties.customSVG, props.model.properties)
|
||||
: (<rect
|
||||
width={props.model.properties.width}
|
||||
height={props.model.properties.height}
|
||||
style={style}
|
||||
>
|
||||
</rect>);
|
||||
// Dimension props
|
||||
const depth = getDepth(props.model);
|
||||
const dimensionMargin = DIMENSION_MARGIN * (depth + 1);
|
||||
|
@ -79,12 +89,7 @@ export const Container: React.FC<IContainerProps> = (props: IContainerProps) =>
|
|||
text={text}
|
||||
/>
|
||||
{ dimensionChildren }
|
||||
<rect
|
||||
width={props.model.properties.width}
|
||||
height={props.model.properties.height}
|
||||
style={style}
|
||||
>
|
||||
</rect>
|
||||
{ svg }
|
||||
<text
|
||||
x={xText}
|
||||
y={yText}
|
||||
|
@ -141,3 +146,63 @@ export function restoreX(x: number, width: number, xPositionReference = XPositio
|
|||
}
|
||||
return transformedX;
|
||||
}
|
||||
|
||||
function CreateReactCustomSVG(customSVG: string, props: IProperties): React.ReactNode {
|
||||
return <Interweave
|
||||
tagName='g'
|
||||
disableLineBreaks={true}
|
||||
content={customSVG}
|
||||
allowElements={true}
|
||||
transform={(node, children) => transform(node, children, props)}
|
||||
/>;
|
||||
}
|
||||
|
||||
function transform(node: HTMLElement, children: Node[], props: IProperties): React.ReactNode {
|
||||
const supportedTags = ['line', 'path', 'rect'];
|
||||
if (supportedTags.includes(node.tagName.toLowerCase())) {
|
||||
const attributes: {[att: string]: string | object | null} = {};
|
||||
node.getAttributeNames().forEach(attName => {
|
||||
const attributeValue = node.getAttribute(attName);
|
||||
if (attributeValue === null) {
|
||||
attributes[attName] = attributeValue;
|
||||
return;
|
||||
}
|
||||
|
||||
if (attributeValue.startsWith('{userData.') && attributeValue.endsWith('}')) {
|
||||
// support for userData
|
||||
if (props.userData === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const userDataKey = attributeValue.replace(/userData\./, '');
|
||||
|
||||
const prop = Object.entries(props.userData).find(([key]) => `{${key}}` === userDataKey);
|
||||
if (prop !== undefined) {
|
||||
attributes[camelize(attName)] = prop[1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (attributeValue.startsWith('{{') && attributeValue.endsWith('}}')) {
|
||||
// support for object
|
||||
const stringObject = attributeValue.slice(1, -1);
|
||||
const object: JSON = JSON.parse(stringObject);
|
||||
attributes[camelize(attName)] = object;
|
||||
return;
|
||||
}
|
||||
|
||||
const prop = Object.entries(props).find(([key]) => `{${key}}` === attributeValue);
|
||||
if (prop !== undefined) {
|
||||
attributes[camelize(attName)] = prop[1];
|
||||
return;
|
||||
}
|
||||
attributes[camelize(attName)] = attributeValue;
|
||||
});
|
||||
return React.createElement(node.tagName.toLowerCase(), attributes, children);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function camelize(str: string): any {
|
||||
return str.split('-').map((word, index) => index > 0 ? word.charAt(0).toUpperCase() + word.slice(1) : word).join('');
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue