Skip to content

Commit 6fcdcc3

Browse files
authored
Fix styled component inconsistent naming and missing component definition (#246)
* fix: inconsistent styled component variable name * fix: Add text wrapper definition by calling build * refactor: declare componentName in CSSCollection * refactor: remove unreachable conditionals * refactor: change first parameter of getComponentName to string * fix: change to assertion(!) * rollback: Rollback getComponentName * rollback: Rollback getComponentName to original * fix: add better fallback * fix: add fallback condition
1 parent 88913c2 commit 6fcdcc3

3 files changed

Lines changed: 45 additions & 52 deletions

File tree

packages/backend/src/html/htmlDefaultBuilder.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
cssCollection,
3333
generateUniqueClassName,
3434
stylesToCSS,
35+
getComponentName,
3536
} from "./htmlMain";
3637

3738
export class HtmlDefaultBuilder {
@@ -523,14 +524,15 @@ export class HtmlDefaultBuilder {
523524
element = "img";
524525
}
525526

527+
const nodeName = (this.node as any).uniqueName || this.node.name;
528+
529+
const componentName = getComponentName(nodeName, this.cssClassName, element);
530+
526531
cssCollection[this.cssClassName] = {
527532
styles: cssStyles,
528-
nodeName:
529-
(this.node as any).uniqueName ||
530-
this.node.name?.replace(/[^a-zA-Z0-9]/g, "") ||
531-
undefined,
532533
nodeType: this.node.type,
533534
element: element,
535+
componentName: componentName,
534536
};
535537
}
536538
}

packages/backend/src/html/htmlMain.ts

Lines changed: 35 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ export type HtmlGenerationMode =
4242
interface CSSCollection {
4343
[className: string]: {
4444
styles: string[];
45-
nodeName?: string;
4645
nodeType?: string;
4746
element?: string; // Base HTML element to use
47+
componentName: string; // Required for type safety, only used in styled-components mode
4848
};
4949
}
5050

@@ -101,16 +101,13 @@ export function stylesToCSS(styles: string[], isJSX: boolean): string[] {
101101

102102
// Get proper component name from node info
103103
export function getComponentName(
104-
node: any,
105-
className?: string,
106-
nodeType = "div",
104+
nodeName: string | undefined,
105+
className: string,
106+
nodeType: string,
107107
): string {
108108
// Start with Styled prefix
109109
let name = "Styled";
110110

111-
// Use uniqueName if available, otherwise use name
112-
const nodeName: string = node.uniqueName || node.name;
113-
114111
// Try to use node name first
115112
if (nodeName && nodeName.length > 0) {
116113
// Clean up the node name and capitalize first letter
@@ -157,17 +154,12 @@ export function generateStyledComponents(): string {
157154
const components: string[] = [];
158155

159156
Object.entries(cssCollection).forEach(
160-
([className, { styles, nodeName, nodeType, element }]) => {
157+
([className, { styles, componentName, element, nodeType }]) => {
161158
// Skip if no styles
162159
if (!styles.length) return;
163160

164161
// Determine base HTML element - defaults to div
165162
const baseElement = element || (nodeType === "TEXT" ? "p" : "div");
166-
const componentName = getComponentName(
167-
{ name: nodeName },
168-
className,
169-
baseElement,
170-
);
171163

172164
const styledComponent = `const ${componentName} = styled.${baseElement}\`
173165
${styles.join(";\n ")}${styles.length ? ";" : ""}
@@ -489,31 +481,29 @@ const htmlText = (node: TextNode, settings: HTMLSettings): string => {
489481

490482
// For styled-components mode
491483
if (mode === "styled-components") {
492-
const componentName = layoutBuilder.cssClassName
493-
? getComponentName(node, layoutBuilder.cssClassName, "p")
494-
: getComponentName(node, undefined, "p");
484+
// Build wrapper to store in cssCollection
485+
layoutBuilder.build();
495486

496-
if (styledHtml.length === 1) {
497-
return `\n<${componentName}>${styledHtml[0].text}</${componentName}>`;
498-
} else {
499-
const content = styledHtml
500-
.map((style) => {
501-
const tag =
502-
style.openTypeFeatures.SUBS === true
503-
? "sub"
504-
: style.openTypeFeatures.SUPS === true
505-
? "sup"
506-
: "span";
507-
508-
if (style.componentName) {
509-
return `<${style.componentName}>${style.text}</${style.componentName}>`;
510-
}
511-
return `<${tag}>${style.text}</${tag}>`;
512-
})
513-
.join("");
514-
515-
return `\n<${componentName}>${content}</${componentName}>`;
516-
}
487+
const wrapperComponentName =
488+
cssCollection[layoutBuilder.cssClassName!]?.componentName || "div";
489+
490+
const content = styledHtml
491+
.map((style) => {
492+
const tag =
493+
style.openTypeFeatures.SUBS === true
494+
? "sub"
495+
: style.openTypeFeatures.SUPS === true
496+
? "sup"
497+
: "span";
498+
499+
if (style.componentName) {
500+
return `<${style.componentName}>${style.text}</${style.componentName}>`;
501+
}
502+
return `<${tag}>${style.text}</${tag}>`;
503+
})
504+
.join("");
505+
506+
return `\n<${wrapperComponentName}>${content}</${wrapperComponentName}>`;
517507
}
518508

519509
// Standard HTML/CSS approach for HTML, React or Svelte
@@ -640,13 +630,16 @@ const htmlContainer = async (
640630

641631
// For styled-components mode
642632
if (mode === "styled-components" && builder.cssClassName) {
643-
const componentName = getComponentName(node, builder.cssClassName);
633+
const componentName = cssCollection[builder.cssClassName].componentName;
644634

645-
if (children) {
646-
return `\n<${componentName}>${indentString(children)}\n</${componentName}>`;
647-
} else {
648-
return `\n<${componentName} ${src}/>`;
635+
if (componentName) {
636+
if (children) {
637+
return `\n<${componentName}>${indentString(children)}\n</${componentName}>`;
638+
} else {
639+
return `\n<${componentName} ${src}/>`;
640+
}
649641
}
642+
// fallback to standard HTML if no component was created
650643
}
651644

652645
// Standard HTML approach for HTML, React, or Svelte

packages/backend/src/html/htmlTextBuilder.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,18 @@ export class HtmlTextBuilder extends HtmlDefaultBuilder {
108108
// In both modes, use span for text segments to avoid selector conflicts
109109
const elementTag = "span";
110110

111+
const componentName = getComponentName(segmentName, className, elementTag);
112+
111113
// Store in cssCollection with consistent metadata
112114
cssCollection[className] = {
113115
styles: cssStyles,
114-
nodeName: segmentName,
115116
nodeType: "TEXT",
116117
element: elementTag,
118+
componentName: componentName,
117119
};
118120

119121
if (mode === "styled-components") {
120-
result.componentName = getComponentName(
121-
{ name: segmentName },
122-
className,
123-
elementTag,
124-
);
122+
result.componentName = componentName;
125123
}
126124
}
127125

0 commit comments

Comments
 (0)