Skip to content

Commit 3a9fe89

Browse files
add self closing jsx support
1 parent 47164bf commit 3a9fe89

5 files changed

Lines changed: 96 additions & 25 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./css-json";

packages/builder-web-core/builders/build-jsx-tree.ts

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ import {
1111
StyledComponentJSXElementConfig,
1212
} from "@web-builder/styled";
1313
import {
14+
JSXAttributes,
1415
JSXChildLike,
1516
JSXClosingElement,
1617
JSXElement,
1718
JSXIdentifier,
1819
JSXOpeningElement,
20+
JSXSelfClosingElement,
1921
} from "coli";
2022

2123
////
@@ -78,8 +80,12 @@ export function buildJsx(
7880
* required for id based styling strategy
7981
*/
8082
idTransformer?: (jsx, id: string) => void;
83+
},
84+
options: {
85+
self_closing_if_possible?: boolean;
8186
}
8287
): JSXChildLike {
88+
const force_dont_self_close = options.self_closing_if_possible === false;
8389
const mapper = (widget: JsxWidget) => {
8490
const _jsxcfg = widget.jsxConfig();
8591
if (_jsxcfg.type === "static-tree") {
@@ -90,31 +96,39 @@ export function buildJsx(
9096

9197
if (widget instanceof StylableJsxWidget) {
9298
const styledconfig = repository.styledConfig(widget.key.id);
99+
// region build jsx
100+
let jsx;
93101
if (widget instanceof TextChildWidget) {
94-
const jsx = buildTextChildJsx(widget, styledconfig);
95-
repository.idTransformer?.(jsx, styledconfig.id);
96-
return jsx;
97-
}
98-
const jsx = new JSXElement({
99-
openingElement: new JSXOpeningElement(styledconfig.tag, {
102+
jsx = buildTextChildJsx(widget, styledconfig);
103+
} else {
104+
jsx = _jsx_element_with_self_closing_if_possible({
105+
tag: styledconfig.tag,
100106
attributes: styledconfig.attributes,
101-
}),
102-
closingElement: new JSXClosingElement(styledconfig.tag),
103-
children: children,
104-
});
107+
children: children,
108+
options: {
109+
force_dont_self_close: force_dont_self_close,
110+
},
111+
});
112+
}
113+
// endregion build jsx
114+
115+
// apply injected transformer (if present)
105116
repository.idTransformer?.(jsx, styledconfig.id);
117+
106118
return jsx;
107119
} else {
108120
const config = widget.jsxConfig();
109121
if (config.type === "tag-and-attr") {
110122
const _tag = handle(config.tag);
111-
const jsx = new JSXElement({
112-
openingElement: new JSXOpeningElement(_tag, {
113-
attributes: config.attributes,
114-
}),
115-
closingElement: new JSXClosingElement(_tag),
123+
const jsx = _jsx_element_with_self_closing_if_possible({
124+
tag: _tag,
125+
attributes: config.attributes,
116126
children: children,
127+
options: {
128+
force_dont_self_close: force_dont_self_close,
129+
},
117130
});
131+
118132
return jsx;
119133
}
120134
return;
@@ -123,3 +137,33 @@ export function buildJsx(
123137

124138
return mapper(widget);
125139
}
140+
141+
function _jsx_element_with_self_closing_if_possible({
142+
children,
143+
tag,
144+
attributes,
145+
options = {
146+
force_dont_self_close: false,
147+
},
148+
}: {
149+
tag: JSXIdentifier;
150+
children?: any;
151+
attributes: JSXAttributes;
152+
options?: {
153+
force_dont_self_close?: boolean;
154+
};
155+
}) {
156+
if (!options?.force_dont_self_close && (!children || children.length == 0)) {
157+
return new JSXSelfClosingElement(tag, {
158+
attributes: attributes,
159+
});
160+
} else {
161+
return new JSXElement({
162+
openingElement: new JSXOpeningElement(tag, {
163+
attributes: attributes,
164+
}),
165+
closingElement: new JSXClosingElement(tag),
166+
children: children,
167+
});
168+
}
169+
}

packages/builder-web-react/react-inline-css-widget/react-inline-css-module-builder.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ import {
1111
import {
1212
BlockStatement,
1313
ImportDeclaration,
14+
JSXAttribute,
1415
Return,
1516
ScopedVariableNamer,
1617
} from "coli";
18+
import * as css from "@web-builder/styles";
1719
import { react_imports } from "../react-import-specifications";
1820
import { ReactWidgetModuleExportable } from "../react-module";
1921
import { makeReactModuleFile, ReactModuleFile } from "../react-module-file";
@@ -65,9 +67,21 @@ export class ReactCssInJSBuilder {
6567

6668
private jsxBuilder(widget: JsxWidget) {
6769
// TODO: add attributes transformer, inject style={{ ...}}
68-
return buildJsx(widget, {
69-
styledConfig: (id) => this.styledConfig(id),
70-
});
70+
71+
// const transformer = (style: string) => {
72+
// const styleobj = css.utils.cssToJson(style);
73+
// new JSXAttribute("style", styleobj);
74+
// };
75+
76+
return buildJsx(
77+
widget,
78+
{
79+
styledConfig: (id) => this.styledConfig(id),
80+
},
81+
{
82+
self_closing_if_possible: true,
83+
}
84+
);
7185
}
7286

7387
partImports() {

packages/builder-web-react/react-styled-component-widget/react-styled-components-module-builder.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,15 @@ export class ReactStyledComponentsBuilder {
5151
}
5252

5353
private jsxBuilder(widget: JsxWidget) {
54-
return buildJsx(widget, {
55-
styledConfig: (id) => this.styledConfig(id),
56-
});
54+
return buildJsx(
55+
widget,
56+
{
57+
styledConfig: (id) => this.styledConfig(id),
58+
},
59+
{
60+
self_closing_if_possible: true,
61+
}
62+
);
5763
}
5864

5965
partImports() {

packages/builder-web-vanilla/export-inline-css-html-file/index.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,16 @@ export function export_inlined_css_html_file(
7373
}
7474

7575
function buildBodyHtml(widget: JsxWidget) {
76-
return buildJsx(widget, {
77-
styledConfig: (id) => getStyleConfigById(id),
78-
idTransformer: (jsx, id) => injectIdToJsx(jsx, id),
79-
});
76+
return buildJsx(
77+
widget,
78+
{
79+
styledConfig: (id) => getStyleConfigById(id),
80+
idTransformer: (jsx, id) => injectIdToJsx(jsx, id),
81+
},
82+
{
83+
self_closing_if_possible: false,
84+
}
85+
);
8086
}
8187

8288
const css_declarations = Array.from(styles_map.keys())

0 commit comments

Comments
 (0)