Skip to content

Commit 47164bf

Browse files
add inline css builder (attributes modification not ready)
1 parent f28e055 commit 47164bf

12 files changed

Lines changed: 319 additions & 115 deletions

File tree

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ export function buildContainingJsx(
6060
}
6161
}
6262

63+
/**
64+
*
65+
* A Utility-like general jsx builder globally used while building html tree.
66+
*
67+
* @param widget
68+
* @param repository
69+
* @returns
70+
*/
6371
export function buildJsx(
6472
widget: JsxWidget,
6573
repository: {

packages/builder-web-react/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from "./react-styled-component-widget";
2+
export * from "./react-inline-css-widget";
23
export * from "./react-import-specifications";
34
export * from "./react-project";
45
export * from "./widgets-native";
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { JsxWidget } from "@web-builder/core";
2+
import { react as react_config } from "@designto/config";
3+
import { ReactCssInJSBuilder } from "./react-inline-css-module-builder";
4+
5+
export function finalizeReactWidget_InlineCss(
6+
entry: JsxWidget,
7+
{
8+
styling,
9+
exporting,
10+
}: {
11+
styling: react_config.ReactInlineCssConfig;
12+
exporting: react_config.ReactComponentExportingCofnig;
13+
}
14+
) {
15+
const builder = new ReactCssInJSBuilder({
16+
entry,
17+
config: styling,
18+
});
19+
return builder.asExportableModule().finalize(exporting);
20+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from "./react-inline-css-module-builder";
2+
export * from "./from-static-widget-tree";

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

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
1+
import { ReservedKeywordPlatformPresets } from "@coli.codes/naming/reserved";
12
import { react as react_config } from "@designto/config";
23
import type { JsxWidget } from "@web-builder/core";
4+
import {
5+
buildJsx,
6+
getWidgetStylesConfigMap,
7+
JSXWithoutStyleElementConfig,
8+
JSXWithStyleElementConfig,
9+
WidgetStyleConfigMap,
10+
} from "@web-builder/core/builders";
11+
import {
12+
BlockStatement,
13+
ImportDeclaration,
14+
Return,
15+
ScopedVariableNamer,
16+
} from "coli";
17+
import { react_imports } from "../react-import-specifications";
18+
import { ReactWidgetModuleExportable } from "../react-module";
19+
import { makeReactModuleFile, ReactModuleFile } from "../react-module-file";
320

421
/**
522
* CSS In JS Style builder for React Framework
@@ -15,7 +32,10 @@ import type { JsxWidget } from "@web-builder/core";
1532
*/
1633
export class ReactCssInJSBuilder {
1734
private readonly entry: JsxWidget;
35+
private readonly widgetName: string;
1836
readonly config: react_config.ReactInlineCssConfig;
37+
private readonly namer: ScopedVariableNamer;
38+
private readonly styledConfigWidgetMap: WidgetStyleConfigMap;
1939

2040
constructor({
2141
entry,
@@ -25,6 +45,82 @@ export class ReactCssInJSBuilder {
2545
config: react_config.ReactInlineCssConfig;
2646
}) {
2747
this.entry = entry;
48+
this.widgetName = entry.key.name;
2849
this.config = config;
50+
this.namer = new ScopedVariableNamer(
51+
entry.key.id,
52+
ReservedKeywordPlatformPresets.react
53+
);
54+
this.styledConfigWidgetMap = getWidgetStylesConfigMap(entry, {
55+
namer: this.namer,
56+
rename_tag: false,
57+
});
58+
}
59+
60+
private styledConfig(
61+
id: string
62+
): JSXWithStyleElementConfig | JSXWithoutStyleElementConfig {
63+
return this.styledConfigWidgetMap.get(id);
64+
}
65+
66+
private jsxBuilder(widget: JsxWidget) {
67+
// TODO: add attributes transformer, inject style={{ ...}}
68+
return buildJsx(widget, {
69+
styledConfig: (id) => this.styledConfig(id),
70+
});
71+
}
72+
73+
partImports() {
74+
return [react_imports.import_react_from_react];
75+
}
76+
77+
partBody(): BlockStatement {
78+
let jsxTree = this.jsxBuilder(this.entry);
79+
return new BlockStatement(new Return(jsxTree));
80+
}
81+
82+
asExportableModule() {
83+
const body = this.partBody();
84+
const imports = this.partImports();
85+
return new ReactInlineCssWidgetModuleExportable(this.widgetName, {
86+
body,
87+
imports,
88+
});
89+
}
90+
}
91+
92+
export class ReactInlineCssWidgetModuleExportable extends ReactWidgetModuleExportable {
93+
constructor(
94+
name,
95+
{
96+
body,
97+
imports,
98+
}: {
99+
body: BlockStatement;
100+
imports: ImportDeclaration[];
101+
}
102+
) {
103+
super({
104+
name,
105+
body,
106+
imports,
107+
});
108+
}
109+
110+
asFile({
111+
exporting,
112+
}: {
113+
exporting: react_config.ReactComponentExportingCofnig;
114+
}) {
115+
return makeReactModuleFile({
116+
name: this.name,
117+
path: "src/components",
118+
imports: this.imports,
119+
declarations: [],
120+
body: this.body,
121+
config: {
122+
exporting: exporting,
123+
},
124+
});
29125
}
30126
}
Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,111 @@
1-
import { SourceFile } from "coli";
1+
import {
2+
SourceFile,
3+
BlockStatement,
4+
FunctionDeclaration,
5+
Import,
6+
ImportDeclaration,
7+
Return,
8+
Declaration,
9+
} from "coli";
10+
import { SyntaxKind } from "@coli.codes/core-syntax-kind";
11+
import { react as react_config } from "@designto/config";
12+
import {
13+
add_export_keyword_modifier_to_declaration,
14+
wrap_with_export_assignment_react_component_identifier,
15+
} from "../react-component-exporting";
216

317
export class ReactModuleFile extends SourceFile {
418
constructor({ name, path }: { name: string; path: string }) {
519
super({ name, path });
620
}
721
}
22+
23+
export function makeReactModuleFile({
24+
name,
25+
path,
26+
imports,
27+
body,
28+
declarations,
29+
config,
30+
}: {
31+
name: string;
32+
path: string;
33+
imports: ImportDeclaration[];
34+
body: BlockStatement;
35+
declarations: Declaration[];
36+
config: {
37+
exporting: react_config.ReactComponentExportingCofnig;
38+
};
39+
}) {
40+
const { exporting } = config;
41+
const file = new ReactModuleFile({
42+
name: `${name}.tsx`,
43+
path: path,
44+
});
45+
file.imports(...imports);
46+
47+
// console.log("exporting", exporting);
48+
switch (exporting.type) {
49+
case "export-default-anonymous-functional-component": {
50+
// exporting.declaration_syntax_choice;
51+
// exporting.export_declaration_syntax_choice;
52+
// exporting.exporting_position;
53+
54+
const export_default_anaonymous_functional_component =
55+
new FunctionDeclaration(undefined, {
56+
body: body,
57+
modifiers: {
58+
default: SyntaxKind.DefaultKeyword,
59+
export: SyntaxKind.ExportKeyword,
60+
},
61+
});
62+
file.declare(export_default_anaonymous_functional_component);
63+
file.declare(...declarations);
64+
break;
65+
}
66+
case "export-named-functional-component": {
67+
// exporting.declaration_syntax_choice;
68+
// exporting.export_declaration_syntax_choice;
69+
70+
const named_function_declaration = new FunctionDeclaration(name, {
71+
body: body,
72+
});
73+
74+
switch (exporting.exporting_position) {
75+
case "after-declaration":
76+
file.declare(named_function_declaration);
77+
file.export(
78+
wrap_with_export_assignment_react_component_identifier(
79+
named_function_declaration.id
80+
)
81+
);
82+
file.declare(...declarations);
83+
break;
84+
case "end-of-file":
85+
file.declare(named_function_declaration);
86+
file.declare(...declarations);
87+
file.export(
88+
wrap_with_export_assignment_react_component_identifier(
89+
named_function_declaration.id
90+
)
91+
);
92+
break;
93+
case "with-declaration":
94+
const _exported_named_function_declaration =
95+
add_export_keyword_modifier_to_declaration<FunctionDeclaration>(
96+
named_function_declaration
97+
);
98+
file.declare(_exported_named_function_declaration);
99+
file.declare(...declarations);
100+
break;
101+
}
102+
break;
103+
}
104+
case "export-named-class-component":
105+
break;
106+
case "export-anonymous-class-component":
107+
throw new Error("Class component not supported");
108+
}
109+
110+
return file;
111+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./react-exportable-module-declaration";
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { BlockStatement, ImportDeclaration } from "coli";
2+
import { stringfy } from "@coli.codes/export-string";
3+
import { ReactModuleFile } from "../react-module-file";
4+
import { react as react_config } from "@designto/config";
5+
6+
export abstract class ReactWidgetModuleExportable {
7+
readonly name: string;
8+
readonly dependencies: string[];
9+
readonly body: BlockStatement;
10+
readonly imports: ImportDeclaration[];
11+
12+
constructor({
13+
name,
14+
body,
15+
imports,
16+
dependencies,
17+
}: {
18+
name;
19+
body;
20+
imports;
21+
dependencies?: string[];
22+
}) {
23+
this.name = name;
24+
this.body = body;
25+
this.imports = imports;
26+
this.dependencies = dependencies;
27+
}
28+
29+
abstract asFile({
30+
exporting,
31+
}: {
32+
exporting: react_config.ReactComponentExportingCofnig;
33+
}): ReactModuleFile;
34+
35+
finalize(config: react_config.ReactComponentExportingCofnig) {
36+
const file = this.asFile({ exporting: config });
37+
const final = stringfy(file.blocks, {
38+
language: "tsx",
39+
});
40+
return {
41+
code: final,
42+
name: this.name,
43+
dependencies: this.dependencies,
44+
};
45+
}
46+
}

packages/builder-web-react/react-styled-component-widget/from-vanilla-widget-tree.ts renamed to packages/builder-web-react/react-styled-component-widget/from-static-widget-tree.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { JsxWidget, StylableJsxWidget } from "@web-builder/core";
22
import { ReactComponentExportResult } from "../export-result";
3-
import { react } from "@designto/config";
3+
import { react as react_config } from "@designto/config";
44
import { ReactStyledComponentsBuilder } from "./react-styled-components-module-builder";
55

66
/**
@@ -15,8 +15,8 @@ export function finalizeReactWidget_StyledComponents(
1515
styling,
1616
exporting,
1717
}: {
18-
styling: react.ReactStyledComponentsConfig;
19-
exporting: react.ReactComponentExportingCofnig;
18+
styling: react_config.ReactStyledComponentsConfig;
19+
exporting: react_config.ReactComponentExportingCofnig;
2020
}
2121
): ReactComponentExportResult {
2222
const builder = new ReactStyledComponentsBuilder({ entry, config: styling });
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
export * from "./from-vanilla-widget-tree";
1+
export * from "./from-static-widget-tree";
22
export * from "./from-reusable-widget-tree";

0 commit comments

Comments
 (0)