@webmate-studio/builder 0.2.77 → 0.2.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build-service.js CHANGED
@@ -172,9 +172,9 @@ async function buildComponent(payload) {
172
172
  // These become Custom Elements, others are just utilities/sub-components
173
173
  const usedIslands = new Set();
174
174
  if (html) {
175
- // Find all custom elements in HTML (e.g. <MenuMobile />, <SearchModal />)
176
- // Match: <ComponentName or <ComponentName> or <ComponentName/>
177
- const componentTagRegex = /<([A-Z][a-zA-Z0-9]*)\s*\/?>/g;
175
+ // Find all custom elements in HTML (e.g. <MenuMobile />, <SearchModal data={...} />)
176
+ // Match: <ComponentName ...> or <ComponentName .../> (with or without attributes)
177
+ const componentTagRegex = /<([A-Z][a-zA-Z0-9]*)[^>]*?\/?>/g;
178
178
  let match;
179
179
  while ((match = componentTagRegex.exec(html)) !== null) {
180
180
  const componentName = match[1]; // e.g. "MenuMobile"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webmate-studio/builder",
3
- "version": "0.2.77",
3
+ "version": "0.2.79",
4
4
  "type": "module",
5
5
  "description": "Webmate Studio Component Builder",
6
6
  "keywords": [
@@ -70,7 +70,7 @@ function stripNonUtilityLayers(css) {
70
70
 
71
71
  /**
72
72
  * Extract Tailwind classes from HTML content
73
- * Supports: class="...", class='...', and Svelte's class:xxx={...}
73
+ * Supports: class="...", class='...', class={...}, and Svelte's class:xxx={...}
74
74
  * @param {string} html - HTML content
75
75
  * @returns {Set<string>} Set of unique Tailwind classes
76
76
  */
@@ -91,6 +91,50 @@ export function extractTailwindClasses(html) {
91
91
  });
92
92
  }
93
93
 
94
+ // Match class={...} dynamic expressions (Svelte/React)
95
+ // Extracts ALL string literals within class={...}, including template strings
96
+ // Example: class={`bg-slate-500 ${open ? 'rotate-45' : 'rotate-0'}`}
97
+ // Finds: "bg-slate-500", "rotate-45", "rotate-0"
98
+ const dynamicClassBlockRegex = /class=\{([^}]+)\}/g;
99
+ while ((match = dynamicClassBlockRegex.exec(html)) !== null) {
100
+ const block = match[1];
101
+
102
+ // Extract all string literals:
103
+ // 1. Single quotes: 'text'
104
+ // 2. Double quotes: "text"
105
+ // 3. Template literal prefix (before ${): `text ${...`
106
+ // 4. String parts between template expressions: `...} text ${...`
107
+
108
+ // Match quoted strings (single and double quotes)
109
+ const quotedStringRegex = /['"]([^'"]+)['"]/g;
110
+ let stringMatch;
111
+ while ((stringMatch = quotedStringRegex.exec(block)) !== null) {
112
+ const classString = stringMatch[1];
113
+ classString.split(/\s+/).forEach(cls => {
114
+ if (cls.trim()) classes.add(cls.trim());
115
+ });
116
+ }
117
+
118
+ // Match template literal parts (text before/between ${...} expressions)
119
+ // Match backtick-quoted content, but stop at ${
120
+ const templateLiteralRegex = /`([^`]*?)\$\{/g;
121
+ while ((stringMatch = templateLiteralRegex.exec(block)) !== null) {
122
+ const classString = stringMatch[1];
123
+ classString.split(/\s+/).forEach(cls => {
124
+ if (cls.trim()) classes.add(cls.trim());
125
+ });
126
+ }
127
+
128
+ // Also match template literal at the end (after last } or if no ${)
129
+ const templateLiteralEndRegex = /\}([^`}]*?)`/g;
130
+ while ((stringMatch = templateLiteralEndRegex.exec(block)) !== null) {
131
+ const classString = stringMatch[1];
132
+ classString.split(/\s+/).forEach(cls => {
133
+ if (cls.trim()) classes.add(cls.trim());
134
+ });
135
+ }
136
+ }
137
+
94
138
  // Match Svelte conditional classes: class:xxx={...}
95
139
  // Supports arbitrary values with brackets: class:lg:pb-[calc(10px + 30px)]={...}
96
140
  // Same pattern as CLI preview-ui for consistency