@webmate-studio/builder 0.2.78 → 0.2.80

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webmate-studio/builder",
3
- "version": "0.2.78",
3
+ "version": "0.2.80",
4
4
  "type": "module",
5
5
  "description": "Webmate Studio Component Builder",
6
6
  "keywords": [
@@ -58,11 +58,18 @@ function transformIslandsToDataAttributes(html, availableIslands = []) {
58
58
  // Convert island name to kebab-case for Custom Element tag
59
59
  // SwiperTest → swiper-test
60
60
  // MyAwesomeComponent → my-awesome-component
61
- const kebabTag = tagName
61
+ let kebabTag = tagName
62
62
  .replace(/([A-Z])/g, '-$1')
63
63
  .toLowerCase()
64
64
  .replace(/^-/, '');
65
65
 
66
+ // Svelte requires custom element names to be hyphenated
67
+ // If there's no hyphen, add a prefix to make it valid
68
+ // IMPORTANT: Must match the prefix logic in injectSvelteOptions()
69
+ if (!kebabTag.includes('-')) {
70
+ kebabTag = 'wm-' + kebabTag; // e.g., "sidebar" → "wm-sidebar"
71
+ }
72
+
66
73
  // Parse attributes and convert to HTML attributes
67
74
  const attrs = [];
68
75
 
@@ -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