Skip to content

Commit

Permalink
Allow xml-node to be rendered as xml
Browse files Browse the repository at this point in the history
  • Loading branch information
istarkov committed May 7, 2024
1 parent 7616435 commit d2cf991
Showing 1 changed file with 34 additions and 9 deletions.
43 changes: 34 additions & 9 deletions packages/sdk-components-react/src/xml-node.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
import { Children, forwardRef, type ElementRef, type ReactNode } from "react";
import {
idAttribute,
componentAttribute,
ReactSdkContext,
} from "@webstudio-is/react-sdk";
import {
Children,
createElement,
forwardRef,
useContext,
type ElementRef,
type ReactNode,
} from "react";

export const defaultTag = "div";

Expand All @@ -7,10 +19,28 @@ type Props = {
tag: string;
xmlns?: string;
children: ReactNode;
// xxxAttribute is used for typings only
[idAttribute]: string;
[componentAttribute]: string;
};

export const XmlNode = forwardRef<ElementRef<"div">, Props>(
({ tag = "", children, ...props }, ref) => {
const { renderer } = useContext(ReactSdkContext);

const attributeEntries = Object.entries(props)
.filter(
([key]) =>
key.startsWith("data-") === false && key.startsWith("aria-") === false
)
.filter(([key]) => key !== "tabIndex")
.filter(([, value]) => typeof value !== "function");

if (renderer === undefined) {
const attrProps = Object.fromEntries(attributeEntries);
return createElement(tag, attrProps, children);
}

const isTextChild = Children.toArray(children).every(
(child) => typeof child === "string"
);
Expand All @@ -21,14 +51,9 @@ export const XmlNode = forwardRef<ElementRef<"div">, Props>(
// Clear all non letter, number, underscore, dot, and dash
.replaceAll(/[^\p{L}\p{N}\-._]+/gu, "");

const attributes = Object.entries(props)
.filter(
([key]) =>
key.startsWith("data-") === false && key.startsWith("aria-") === false
)
.filter(([key]) => key !== "tabIndex")
.filter(([, value]) => typeof value !== "function")
.map(([key, value]) => `${key}=${JSON.stringify(value)}`);
const attributes = attributeEntries.map(
([key, value]) => `${key}=${JSON.stringify(value)}`
);

return (
<div style={{ display: isTextChild ? "flex" : "contents" }} {...props}>
Expand Down

0 comments on commit d2cf991

Please sign in to comment.