@clikvn/showroom-visualizer 0.2.2-dev-09 β†’ 0.2.2-dev-10

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.
Files changed (46) hide show
  1. package/DEVELOPMENT.md +120 -0
  2. package/EXAMPLES.md +967 -0
  3. package/README.md +133 -26
  4. package/SETUP_COMPLETE.md +149 -0
  5. package/dist/components/SkinLayer/DefaultLayout/index.d.ts.map +1 -1
  6. package/dist/components/SkinLayer/Floorplan/Map.d.ts.map +1 -1
  7. package/dist/components/SkinLayer/Floorplan/Minimap/MiniMapMarker.d.ts.map +1 -1
  8. package/dist/components/SkinLayer/Floorplan/Minimap/index.d.ts.map +1 -1
  9. package/dist/components/SkinLayer/Layout/index.d.ts.map +1 -1
  10. package/dist/components/SkinLayer/index.d.ts +32 -0
  11. package/dist/components/SkinLayer/index.d.ts.map +1 -1
  12. package/dist/context/CustomLayoutContext.d.ts +20 -0
  13. package/dist/context/CustomLayoutContext.d.ts.map +1 -0
  14. package/dist/features/ShowroomVisualizer/VirtualTour.d.ts +5 -0
  15. package/dist/features/ShowroomVisualizer/VirtualTour.d.ts.map +1 -1
  16. package/dist/features/ShowroomVisualizer/VirtualTourContainer.d.ts +4 -3
  17. package/dist/features/ShowroomVisualizer/VirtualTourContainer.d.ts.map +1 -1
  18. package/dist/features/ShowroomVisualizer/index.d.ts +24 -3
  19. package/dist/features/ShowroomVisualizer/index.d.ts.map +1 -1
  20. package/dist/hooks/headless/index.d.ts +0 -31
  21. package/dist/hooks/headless/index.d.ts.map +1 -1
  22. package/dist/hooks/useToolConfig.d.ts.map +1 -1
  23. package/dist/index.d.ts +11 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/register.d.ts +3 -0
  27. package/dist/register.d.ts.map +1 -1
  28. package/dist/types/SkinLayer/tool.type.d.ts +6 -0
  29. package/dist/types/SkinLayer/tool.type.d.ts.map +1 -1
  30. package/dist/types/SkinLayer/visualizer.type.d.ts +3 -0
  31. package/dist/types/SkinLayer/visualizer.type.d.ts.map +1 -1
  32. package/dist/types/custom-layout.d.ts +63 -0
  33. package/dist/types/custom-layout.d.ts.map +1 -0
  34. package/dist/web.js +1 -1
  35. package/example/CSS_HANDLING.md +141 -0
  36. package/example/FIXES_SUMMARY.md +121 -0
  37. package/example/PATH_ALIASES.md +103 -0
  38. package/example/README.md +64 -0
  39. package/example/index.html +13 -0
  40. package/example/package.json +25 -0
  41. package/example/postcss.config.cjs +6 -0
  42. package/example/tailwind.config.cjs +12 -0
  43. package/example/tsconfig.node.json +12 -0
  44. package/example/vite.config.ts +126 -0
  45. package/package.json +9 -1
  46. package/rollup.config.js +270 -3
package/rollup.config.js CHANGED
@@ -1,3 +1,38 @@
1
+ /**
2
+ * ============================================================================
3
+ * SHOWROOM VISUALIZER - ROLLUP BUILD CONFIGURATION
4
+ * ============================================================================
5
+ *
6
+ * 🎯 MỀC TIÊU:
7
+ * TαΊ‘o ra 2 build outputs phα»₯c vα»₯ 2 use cases khΓ‘c nhau:
8
+ *
9
+ * 1️⃣ NPM Package (dist/index.js) - EXTERNAL REACT
10
+ * - DΓΉng React tα»« host app (Next.js, React apps)
11
+ * - βœ… Hα»— trợ Custom Layout overrides
12
+ * - File nhỏ hƑn (~1.8MB)
13
+ * - Use: import { ShowroomVisualizer } from '@clikvn/showroom-visualizer'
14
+ *
15
+ * 2️⃣ Web Component (dist/web.js) - BUNDLED REACT
16
+ * - Bundle React 19 vΓ o file
17
+ * - ❌ KHΓ”NG hα»— trợ custom layout overrides
18
+ * - File lα»›n hΖ‘n (~2.0MB)
19
+ * - Use: <script type="module" src="web.js"></script>
20
+ *
21
+ * ────────────────────────────────────────────────────────────────────────────
22
+ *
23
+ * πŸ“Š SO SÁNH:
24
+ *
25
+ * | Feature | NPM Package | Web Component |
26
+ * |----------------------|-------------|---------------|
27
+ * | React Source | Host app | Bundled |
28
+ * | Custom Layout | βœ… Yes | ❌ No |
29
+ * | File Size | ~1.8MB | ~2.0MB |
30
+ * | Dependencies | Need React | Standalone |
31
+ * | Use Case | React apps | Vanilla JS |
32
+ *
33
+ * ────────────────────────────────────────────────────────────────────────────
34
+ */
35
+
1
36
  import resolve from '@rollup/plugin-node-resolve';
2
37
  import commonjs from '@rollup/plugin-commonjs';
3
38
  import typescript from '@rollup/plugin-typescript';
@@ -16,8 +51,163 @@ const extensions = ['.ts', '.tsx', '.js'];
16
51
  const isDev =
17
52
  process.env.NODE_ENV === 'development' || process.env.ROLLUP_WATCH === 'true';
18
53
 
54
+ // ============================================================================
55
+ // CUSTOM PLUGIN: Fix React-DOM Imports
56
+ // ============================================================================
57
+ // React 18's ESM build khΓ΄ng export findDOMNode, nhΖ°ng CommonJS build cΓ³.
58
+ // Plugin nΓ y rewrite code để chỉ dΓΉng default import vΓ  access properties,
59
+ // trΓ‘nh Rollup extract named imports.
60
+ const fixReactDomImports = () => ({
61
+ name: 'fix-react-dom-imports',
62
+ renderChunk(code) {
63
+ let fixed = code;
64
+
65
+ // Fix invalid variable declarations with dots in the name
66
+ // This pattern appears in minified code from third-party libraries
67
+ fixed = fixed.replace(
68
+ /var\s+_ReactDOM\$ReactDOM__default\.findDOMNode;/g,
69
+ 'var _ReactDOM$findDOMNode;'
70
+ );
71
+
72
+ // Fix all occurrences of the invalid variable name
73
+ fixed = fixed.replace(
74
+ /_ReactDOM\$ReactDOM__default\.findDOMNode/g,
75
+ '_ReactDOM$findDOMNode'
76
+ );
77
+
78
+ // Fix double ReactDOM__default references
79
+ fixed = fixed.replace(
80
+ /ReactDOM__default\.ReactDOM__default\./g,
81
+ 'ReactDOM__default.'
82
+ );
83
+
84
+ // Additional fix for similar patterns with other methods
85
+ fixed = fixed.replace(
86
+ /var\s+_ReactDOM\$ReactDOM__default\.(\w+);/g,
87
+ 'var _ReactDOM$$1;'
88
+ );
89
+
90
+ // Fix minified code that creates invalid variable names
91
+ fixed = fixed.replace(
92
+ /var\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\$([a-zA-Z_$][a-zA-Z0-9_$]*)\.[a-zA-Z_$][a-zA-Z0-9_$]*;/g,
93
+ function (match, prefix, suffix) {
94
+ return `var ${prefix}$${suffix}_temp;`;
95
+ }
96
+ );
97
+
98
+ // First, remove any findDOMNode from named imports
99
+ fixed = fixed.replace(
100
+ /import\s*\{([^}]*)\}\s*from\s*['"]react-dom['"]/g,
101
+ (match, imports) => {
102
+ if (imports.includes('findDOMNode')) {
103
+ const cleanedImports = imports
104
+ .split(',')
105
+ .map((imp) => imp.trim())
106
+ .filter((imp) => !imp.includes('findDOMNode'))
107
+ .join(', ');
108
+
109
+ if (cleanedImports.trim()) {
110
+ return `import { ${cleanedImports} } from 'react-dom'`;
111
+ }
112
+ return '';
113
+ }
114
+ return match;
115
+ }
116
+ );
117
+
118
+ // Handle combined default and named imports
119
+ fixed = fixed.replace(
120
+ /import\s+(\w+),\s*\{\s*([^}]+)\s*\}\s*from\s*['"]react-dom['"]/g,
121
+ (match, defaultImport, namedImports) => {
122
+ // Check if named imports contains invalid syntax like "ReactDOM__default.createPortal"
123
+ if (
124
+ namedImports.includes('ReactDOM__default.') ||
125
+ namedImports.includes('findDOMNode')
126
+ ) {
127
+ // Extract valid imports only
128
+ const validImports = namedImports
129
+ .split(',')
130
+ .map((imp) => imp.trim())
131
+ .filter((imp) => {
132
+ // Remove any import that has dots or includes findDOMNode
133
+ return !imp.includes('.') && !imp.includes('findDOMNode');
134
+ })
135
+ .map((imp) => {
136
+ // Clean up "as" aliases
137
+ const parts = imp.split(/\s+as\s+/);
138
+ if (parts.length === 2 && !parts[0].includes('.')) {
139
+ return imp;
140
+ }
141
+ return '';
142
+ })
143
+ .filter(Boolean)
144
+ .join(', ');
145
+
146
+ if (validImports) {
147
+ return `import ${defaultImport}, { ${validImports} } from 'react-dom'`;
148
+ }
149
+ return `import ${defaultImport} from 'react-dom'`;
150
+ }
151
+ return match;
152
+ }
153
+ );
154
+
155
+ // Replace all variations of findDOMNode (but not in function declarations)
156
+ fixed = fixed.replace(/\bfindDOMNode\$?\d*\b/g, (match, offset) => {
157
+ // Check if this is a function declaration
158
+ const beforeMatch = fixed.substring(Math.max(0, offset - 20), offset);
159
+ if (beforeMatch.trim().endsWith('function')) {
160
+ return match; // Don't replace in function declarations
161
+ }
162
+ return 'ReactDOM__default.findDOMNode';
163
+ });
164
+
165
+ // Fix property access patterns
166
+ fixed = fixed.replace(/(\w+)\.findDOMNode\b/g, (match, obj) => {
167
+ if (obj === 'ReactDOM__default') return match;
168
+ return 'ReactDOM__default.findDOMNode';
169
+ });
170
+
171
+ // Replace other methods - but NOT when they're being used in import statements
172
+ const methodsToReplace = [
173
+ 'createPortal',
174
+ 'unstable_batchedUpdates',
175
+ 'flushSync',
176
+ ];
177
+
178
+ methodsToReplace.forEach((method) => {
179
+ // Only replace when not in import context
180
+ const regex = new RegExp(
181
+ `\\b${method}\\$?\\d*\\b(?![:\\.]|\\s*as\\s*\\w+)`,
182
+ 'g'
183
+ );
184
+ fixed = fixed.replace(regex, (match, offset) => {
185
+ // Check if this is within an import statement
186
+ const beforeMatch = fixed.substring(Math.max(0, offset - 100), offset);
187
+ if (beforeMatch.includes('import') && beforeMatch.includes('{')) {
188
+ return match;
189
+ }
190
+ return `ReactDOM__default.${method}`;
191
+ });
192
+ });
193
+
194
+ return { code: fixed, map: null };
195
+ },
196
+ });
197
+
198
+ // ============================================================================
199
+ // CONFIG CHO NPM PACKAGE - External React
200
+ // ============================================================================
201
+ // DΓΉng khi: import { ShowroomVisualizer } from '@clikvn/showroom-visualizer'
202
+ // - React được external β†’ DΓΉng React version cα»§a host app (Next.js, React app)
203
+ // - Cho phép custom layout overrides vì share cùng React instance
204
+ // - File nhỏ hƑn vì không bundle React
19
205
  const indexConfig = {
20
206
  context: 'this',
207
+
208
+ // βœ… External React - Library sαΊ½ dΓΉng React tα»« host app
209
+ external: ['react', 'react-dom', 'react/jsx-runtime', 'react-dom/client'],
210
+
21
211
  onwarn(warning, warn) {
22
212
  // Bỏ qua warning về "use client" directive
23
213
  if (
@@ -33,9 +223,21 @@ const indexConfig = {
33
223
  resolve({
34
224
  extensions,
35
225
  browser: true,
36
- dedupe: ['useTranslation', 'i18n', 'I18nextProvider'],
226
+ preferBuiltins: false,
227
+ dedupe: [
228
+ 'react',
229
+ 'react-dom',
230
+ 'useTranslation',
231
+ 'i18n',
232
+ 'I18nextProvider',
233
+ ],
234
+ }),
235
+ commonjs({
236
+ esmExternals: true,
237
+ requireReturnsDefault: 'auto',
238
+ // KhΓ΄ng extract named imports tα»« external modules
239
+ ignoreDynamicRequires: false,
37
240
  }),
38
- commonjs(),
39
241
  // Skip uglify in dev mode - tα»‘n thời gian
40
242
  !isDev && uglify(),
41
243
  json(),
@@ -79,10 +281,75 @@ const indexConfig = {
79
281
  typescriptPaths({ preserveExtensions: true }),
80
282
  // Skip terser trong dev - tα»‘n rαΊ₯t nhiều thời gian
81
283
  !isDev && terser({ output: { comments: false } }),
284
+ // ⚠️ QUAN TRỌNG: Fix react-dom imports sau khi bundle
285
+ // PhαΊ£i Δ‘αΊ·t ở cuα»‘i để chαΊ‘y sau tαΊ₯t cαΊ£ transformations
286
+ fixReactDomImports(),
82
287
  ].filter(Boolean), // Remove false values
83
288
  };
84
289
 
290
+ // ============================================================================
291
+ // CONFIG CHO WEB COMPONENT - Bundled React
292
+ // ============================================================================
293
+ // DΓΉng khi: <script src="web.js"> hoαΊ·c dynamic import('web.js')
294
+ // - React được BUNDLE vΓ o β†’ Standalone, khΓ΄ng cαΊ§n dependencies
295
+ // - KHΓ”NG hα»— trợ custom layout overrides (vΓ¬ khΓ‘c React instance vα»›i host app)
296
+ // - File lớn hƑn vì bundle React (~200KB extra)
297
+ // - Phù hợp cho vanilla JS/HTML projects
298
+ const browserConfig = {
299
+ context: 'this',
300
+ // ❌ KHΓ”NG external React - Bundle React version 19 vΓ o file
301
+ // external: [], // KhΓ΄ng khai bΓ‘o external = bundle tαΊ₯t cαΊ£
302
+ onwarn: indexConfig.onwarn,
303
+ plugins: indexConfig.plugins,
304
+ };
305
+
306
+ // ============================================================================
307
+ // DUAL BUILD STRATEGY
308
+ // ============================================================================
85
309
  const configs = [
310
+ // ────────────────────────────────────────────────────────────────────────
311
+ // BUILD 1: NPM Package (dist/index.js)
312
+ // ────────────────────────────────────────────────────────────────────────
313
+ // πŸ“¦ Sα»­ dα»₯ng: import { ShowroomVisualizer } from '@clikvn/showroom-visualizer'
314
+ //
315
+ // βœ… Ζ―u Δ‘iểm:
316
+ // - DΓΉng React version cα»§a host app (Next.js, React app)
317
+ // - Cho phΓ©p SWIZZLE components (share React instance)
318
+ // - File nhỏ (~1.8MB) vì không bundle React
319
+ //
320
+ // πŸ“ Use cases:
321
+ // - React/Next.js applications
322
+ // - CαΊ§n customize components qua custom layout overrides
323
+ // - Muα»‘n kiểm soΓ‘t React version
324
+ {
325
+ input: './src/index.ts',
326
+ output: {
327
+ file: 'dist/index.js',
328
+ format: 'esm',
329
+ inlineDynamicImports: true,
330
+ },
331
+ ...indexConfig, // βœ… External React dependencies
332
+ },
333
+
334
+ // ────────────────────────────────────────────────────────────────────────
335
+ // BUILD 2: Web Component (dist/web.js)
336
+ // ────────────────────────────────────────────────────────────────────────
337
+ // 🌐 Sα»­ dα»₯ng: <script type="module" src="web.js"></script>
338
+ // hoαΊ·c: await import('web.js')
339
+ //
340
+ // βœ… Ζ―u Δ‘iểm:
341
+ // - Standalone, khΓ΄ng cαΊ§n install dependencies
342
+ // - HoαΊ‘t Δ‘α»™ng trong vanilla JS/HTML
343
+ // - KhΓ΄ng cαΊ§n build tools
344
+ //
345
+ // ❌ Hẑn chế:
346
+ // - KHΓ”NG hα»— trợ custom layout overrides (khΓ‘c React instance)
347
+ // - File lớn hƑn (~2.0MB) vì bundle React
348
+ //
349
+ // πŸ“ Use cases:
350
+ // - Vanilla JS/HTML projects
351
+ // - KhΓ΄ng cαΊ§n customize UI
352
+ // - Quick integration
86
353
  {
87
354
  input: './src/web.ts',
88
355
  output: {
@@ -90,7 +357,7 @@ const configs = [
90
357
  format: 'esm',
91
358
  inlineDynamicImports: true,
92
359
  },
93
- ...indexConfig,
360
+ ...browserConfig, // βœ… Bundle React version 19
94
361
  },
95
362
  ];
96
363