function createElementFor()

in packages/renderer-react-svg/src/Renderer.tsx [15:80]


function createElementFor(
	vdom: VSvgNode,
	key: string,
	handlers: Channels,
): ReactElement<any> {
	const {
		type,
		children,
		attrs = {},
		style,
		transforms: vdomTransforms = [],
		channels = {},
		metadata = { index: -1, id: 'unknown' },
		ariaDescription,
		ariaTitle,
	} = vdom
	const reactAttrs: { [key: string]: any } = {
		key,
		style,
		transform: getTransformAttribute(vdomTransforms),
		...attrs,
	}

	// Map the handlers into the vdom
	Object.keys(channels).forEach(eventName => {
		const eventId = channels[eventName]
		const reactEventName = eventName
		const handler = handlers[eventId]
		reactAttrs[reactEventName] = (event: any) =>
			handler({ ...(metadata as Metadata), event })
	})

	const childrenElements = (children || [])
		.filter(c => !!c)
		.map((c, index) =>
			typeof c !== 'object'
				? c
				: createElementFor(c, `${key}::${index}`, handlers),
		)

	const labelledBy: string[] = []
	if (ariaTitle) {
		const titleId = `${metadata.id}__title`
		childrenElements.push(
			<title key="t" id={titleId}>
				{ariaTitle}
			</title>,
		)
		labelledBy.push(titleId)
	}
	if (ariaDescription) {
		const descId = `${metadata.id}__desc`
		childrenElements.push(
			<desc key="d" id={descId}>
				{ariaDescription}
			</desc>,
		)
		labelledBy.push(descId)
	}
	if (labelledBy.length > 0) {
		reactAttrs['aria-labelledby'] = labelledBy.join(' ')
	}

	const visualElement = createElement(type, reactAttrs, childrenElements)
	return visualElement
}