Skip to content

Commit c26b679

Browse files
add initial support for inline css object support for react
1 parent 3a9fe89 commit c26b679

6 files changed

Lines changed: 111 additions & 12 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
///
2+
/// css to js transformer
3+
/// reference:
4+
/// - https://github.com/postcss/postcss-js/blob/main/objectifier.js
5+
///
6+
import { CSSProperties } from "@coli.codes/css";
7+
import camel from "camelcase-css";
8+
9+
/**
10+
* convertes standard css object to react acceptable camel case object
11+
*
12+
*
13+
* ```js
14+
* // from
15+
* {
16+
* "background-color": "red",
17+
* }
18+
* // to
19+
* {
20+
* backgroundColor: "red",
21+
* }
22+
* ```
23+
* @param payload
24+
*/
25+
export function cssToJson(payload: CSSProperties) {
26+
const obj = Object.keys(payload).reduce(function (previous, key) {
27+
const camelkey = camel(key);
28+
return {
29+
...previous,
30+
[camelkey]: payload[key],
31+
};
32+
}, {});
33+
return JSON.parse(JSON.stringify(obj));
34+
}

packages/builder-css-styles/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,6 @@ export * from "./ellipse";
3434
// export * from "./polygon"; // WIP
3535
export * from "./path";
3636
// --------------------------------------------------------------------------------
37+
38+
// utils
39+
export * as utils from "./_utils";
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
{
22
"name": "@web-builder/styles",
3-
"version": "0.0.0"
3+
"version": "0.0.0",
4+
"dependencies": {
5+
"camelcase-css": "^2.0.1"
6+
},
7+
"devDependencies": {
8+
"@types/camelcase-css": "^2.0.0"
9+
}
410
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,22 @@ export function buildJsx(
8080
* required for id based styling strategy
8181
*/
8282
idTransformer?: (jsx, id: string) => void;
83+
preprocess?: (jsx: JSXElementConfig) => JSXElementConfig;
8384
},
8485
options: {
8586
self_closing_if_possible?: boolean;
8687
}
8788
): JSXChildLike {
8889
const force_dont_self_close = options.self_closing_if_possible === false;
8990
const mapper = (widget: JsxWidget) => {
90-
const _jsxcfg = widget.jsxConfig();
91+
let _jsxcfg = widget.jsxConfig();
9192
if (_jsxcfg.type === "static-tree") {
9293
return _jsxcfg.tree;
9394
}
9495

96+
// preprocess
97+
_jsxcfg = repository.preprocess?.(_jsxcfg) ?? _jsxcfg;
98+
9599
const children = widget.children?.map(mapper);
96100

97101
if (widget instanceof StylableJsxWidget) {

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

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ReservedKeywordPlatformPresets } from "@coli.codes/naming/reserved";
22
import { react as react_config } from "@designto/config";
3-
import type { JsxWidget } from "@web-builder/core";
3+
import type { JSXElementConfig, JsxWidget } from "@web-builder/core";
44
import {
55
buildJsx,
66
getWidgetStylesConfigMap,
@@ -10,15 +10,22 @@ import {
1010
} from "@web-builder/core/builders";
1111
import {
1212
BlockStatement,
13+
Identifier,
1314
ImportDeclaration,
1415
JSXAttribute,
16+
Literal,
17+
ObjectLiteralExpression,
18+
PropertyAssignment,
1519
Return,
1620
ScopedVariableNamer,
21+
StringLiteral,
1722
} from "coli";
1823
import * as css from "@web-builder/styles";
1924
import { react_imports } from "../react-import-specifications";
2025
import { ReactWidgetModuleExportable } from "../react-module";
2126
import { makeReactModuleFile, ReactModuleFile } from "../react-module-file";
27+
import { cssToJson } from "@web-builder/styles/_utils";
28+
import { CSSProperties } from "@coli.codes/css";
2229

2330
/**
2431
* CSS In JS Style builder for React Framework
@@ -66,17 +73,57 @@ export class ReactCssInJSBuilder {
6673
}
6774

6875
private jsxBuilder(widget: JsxWidget) {
69-
// TODO: add attributes transformer, inject style={{ ...}}
70-
71-
// const transformer = (style: string) => {
72-
// const styleobj = css.utils.cssToJson(style);
73-
// new JSXAttribute("style", styleobj);
74-
// };
75-
7676
return buildJsx(
7777
widget,
7878
{
79-
styledConfig: (id) => this.styledConfig(id),
79+
styledConfig: (id) => {
80+
const cfg = this.styledConfig(id);
81+
const _default_attr = cfg.attributes;
82+
83+
const existingstyleattr = _default_attr?.find(
84+
// where style refers to react's jsx style attribute
85+
(a) => a.name.name === "style"
86+
);
87+
88+
let style: JSXAttribute;
89+
if (existingstyleattr) {
90+
// ignore this case. (element already with style attriibute may be svg element)
91+
// this case is not supported. (should supported if the logic changes)
92+
} else {
93+
//
94+
const styledata: CSSProperties =
95+
(cfg as JSXWithStyleElementConfig).style ?? {};
96+
const reactStyleData = cssToJson(styledata);
97+
const properties: PropertyAssignment[] = Object.keys(
98+
reactStyleData
99+
).map(
100+
(key) =>
101+
new PropertyAssignment({
102+
name: key as unknown as Identifier,
103+
initializer: new StringLiteral(reactStyleData[key]),
104+
})
105+
);
106+
107+
style = new JSXAttribute(
108+
"style",
109+
new BlockStatement(
110+
new ObjectLiteralExpression({
111+
properties: properties,
112+
})
113+
)
114+
);
115+
}
116+
117+
const newattributes = [
118+
...(_default_attr ?? []),
119+
//
120+
style,
121+
];
122+
123+
cfg.attributes = newattributes;
124+
125+
return cfg;
126+
},
80127
},
81128
{
82129
self_closing_if_possible: true,

yarn.lock

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6104,6 +6104,11 @@
61046104
"@types/connect" "*"
61056105
"@types/node" "*"
61066106

6107+
"@types/camelcase-css@^2.0.0":
6108+
version "2.0.0"
6109+
resolved "https://registry.yarnpkg.com/@types/camelcase-css/-/camelcase-css-2.0.0.tgz#9604ffb754861b348e1f361c40fbf4d94d43b890"
6110+
integrity sha512-HSD3U+7+1BneOuIcvn3SUJHmEhPZGM6h5wUBQ3L7LL8VAIx2THIlN8HMH2ylxF4yuxu93UAFTcmeb+MT2Dozkg==
6111+
61076112
"@types/clone@2.1.1":
61086113
version "2.1.1"
61096114
resolved "https://registry.yarnpkg.com/@types/clone/-/clone-2.1.1.tgz#9b880d0ce9b1f209b5e0bd6d9caa38209db34024"
@@ -8174,7 +8179,7 @@ camel-case@^4.1.1:
81748179
pascal-case "^3.1.2"
81758180
tslib "^2.0.3"
81768181

8177-
camelcase-css@2.0.1:
8182+
camelcase-css@2.0.1, camelcase-css@^2.0.1:
81788183
version "2.0.1"
81798184
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
81808185
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==

0 commit comments

Comments
 (0)