diorama-js 0.1.1 → 0.2.1

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/dist/react.cjs CHANGED
@@ -626,6 +626,7 @@ function analyzeProject(project, overrideType, overrideEntry) {
626
626
  hasBareImports: hasBareImports(files),
627
627
  isVite
628
628
  });
629
+ const usesTailwind = usesTailwindCSS(files);
629
630
  return {
630
631
  type,
631
632
  entryPoint: htmlEntry,
@@ -634,7 +635,8 @@ function analyzeProject(project, overrideType, overrideEntry) {
634
635
  hasJSX,
635
636
  hasTypeScript,
636
637
  jsEntryPoint: jsEntry,
637
- isVite
638
+ isVite,
639
+ usesTailwind
638
640
  };
639
641
  }
640
642
  function detectProjectType(input) {
@@ -656,6 +658,17 @@ function hasBareImports(files) {
656
658
  }
657
659
  return false;
658
660
  }
661
+ function usesTailwindCSS(files) {
662
+ for (const [path, content] of files) {
663
+ if (/(?:^|\/)tailwind\.config\.(?:js|cjs|mjs|ts)$/.test(path)) {
664
+ return true;
665
+ }
666
+ if (path.endsWith(".css") && /@tailwind\b|@apply\b/.test(content)) {
667
+ return true;
668
+ }
669
+ }
670
+ return false;
671
+ }
659
672
 
660
673
  // src/core/sandbox.ts
661
674
  function buildErrorHTML(message) {
@@ -1740,20 +1753,25 @@ var ASSET_IMPORT_EXTENSIONS = {
1740
1753
  ".otf": "font/otf"
1741
1754
  };
1742
1755
  function assembleHTML(options) {
1743
- const { project, config, transformedFiles, cdnProvider } = options;
1756
+ const { project, config, transformedFiles, cdnProvider, tailwind = "auto" } = options;
1744
1757
  const files = transformedFiles ?? project.files;
1758
+ let result;
1745
1759
  switch (config.type) {
1746
1760
  case "static":
1747
- return assembleStatic(files, project, config);
1761
+ result = assembleStatic(files, project, config);
1762
+ break;
1748
1763
  case "static-esm":
1749
1764
  case "jsx":
1750
1765
  case "typescript":
1751
1766
  case "jsx-typescript":
1752
1767
  case "vite":
1753
- return assembleESM(files, project, config, cdnProvider);
1768
+ result = assembleESM(files, project, config, cdnProvider);
1769
+ break;
1754
1770
  default:
1755
1771
  throw new AssemblyError(`Unsupported project type: ${config.type}`);
1756
1772
  }
1773
+ result.html = applyTailwindRuntime(result.html, project, config, tailwind);
1774
+ return result;
1757
1775
  }
1758
1776
  function assembleStatic(files, project, config) {
1759
1777
  let html = files.get(config.entryPoint);
@@ -1823,6 +1841,7 @@ ${importMapJSON}
1823
1841
  );
1824
1842
  }
1825
1843
  }
1844
+ html = injectIntoHead(html, `<script>${HISTORY_GUARD_SCRIPT}</script>`);
1826
1845
  return { html, usesESM: true };
1827
1846
  }
1828
1847
  function generateHTMLShell(files, config) {
@@ -2079,6 +2098,96 @@ ${css}`);
2079
2098
  }
2080
2099
  return { css: cssChunks.join("\n\n"), links };
2081
2100
  }
2101
+ var TAILWIND_DIRECTIVE_RE = /@tailwind\b|@apply\b/;
2102
+ var TAILWIND_CDN_URL = "https://cdn.tailwindcss.com";
2103
+ function hasTailwindDirectives(css) {
2104
+ return TAILWIND_DIRECTIVE_RE.test(css);
2105
+ }
2106
+ function applyTailwindRuntime(html, project, config, tailwind) {
2107
+ const enabled = tailwind === true || tailwind === "auto" && (config.usesTailwind ?? usesTailwindCSS(project.files));
2108
+ if (!enabled) return html;
2109
+ html = html.replace(
2110
+ /<style>([\s\S]*?)<\/style>/g,
2111
+ (match, css) => hasTailwindDirectives(css) ? `<style type="text/tailwindcss">${css}</style>` : match
2112
+ );
2113
+ let injection = "";
2114
+ const configObject = extractTailwindConfig(project.files);
2115
+ if (configObject) {
2116
+ injection += `<script>window.tailwind = { config: ${configObject} };</script>
2117
+ `;
2118
+ }
2119
+ injection += `<script src="${TAILWIND_CDN_URL}" defer></script>`;
2120
+ return injectIntoHead(html, injection);
2121
+ }
2122
+ function extractTailwindConfig(files) {
2123
+ let source;
2124
+ for (const [path, content] of files) {
2125
+ if (/(?:^|\/)tailwind\.config\.(?:js|cjs|mjs|ts)$/.test(path)) {
2126
+ source = content;
2127
+ break;
2128
+ }
2129
+ }
2130
+ if (!source) return null;
2131
+ const object = extractBalancedObject(source);
2132
+ if (!object || !isSafeConfigObject(object)) return null;
2133
+ return object;
2134
+ }
2135
+ function extractBalancedObject(source) {
2136
+ const opener = source.match(/(?:export\s+default|module\.exports\s*=)\s*\{/);
2137
+ if (!opener || opener.index === void 0) return null;
2138
+ const start = opener.index + opener[0].length - 1;
2139
+ let depth = 0;
2140
+ let str = null;
2141
+ let lineComment = false;
2142
+ let blockComment = false;
2143
+ for (let i = start; i < source.length; i++) {
2144
+ const c = source[i];
2145
+ const n = source[i + 1];
2146
+ if (lineComment) {
2147
+ if (c === "\n") lineComment = false;
2148
+ continue;
2149
+ }
2150
+ if (blockComment) {
2151
+ if (c === "*" && n === "/") {
2152
+ blockComment = false;
2153
+ i++;
2154
+ }
2155
+ continue;
2156
+ }
2157
+ if (str) {
2158
+ if (c === "\\") {
2159
+ i++;
2160
+ continue;
2161
+ }
2162
+ if (c === str) str = null;
2163
+ continue;
2164
+ }
2165
+ if (c === "/" && n === "/") {
2166
+ lineComment = true;
2167
+ i++;
2168
+ continue;
2169
+ }
2170
+ if (c === "/" && n === "*") {
2171
+ blockComment = true;
2172
+ i++;
2173
+ continue;
2174
+ }
2175
+ if (c === '"' || c === "'" || c === "`") {
2176
+ str = c;
2177
+ continue;
2178
+ }
2179
+ if (c === "{") depth++;
2180
+ else if (c === "}") {
2181
+ depth--;
2182
+ if (depth === 0) return source.slice(start, i + 1);
2183
+ }
2184
+ }
2185
+ return null;
2186
+ }
2187
+ function isSafeConfigObject(object) {
2188
+ return !(/\brequire\s*\(/.test(object) || /\bimport\b/.test(object) || /=>/.test(object) || /\bfunction\b/.test(object) || /`/.test(object) || /\bprocess\b/.test(object) || /\b__dirname\b|\b__filename\b/.test(object));
2189
+ }
2190
+ var HISTORY_GUARD_SCRIPT = "try{for(const m of ['pushState','replaceState']){const orig=history[m].bind(history);history[m]=function(state,title,url){try{return orig(state,title,url);}catch(e){try{return orig(state,title);}catch(e2){}}};}}catch(e){}";
2082
2191
  function injectImportMetaEnv(files) {
2083
2192
  const shim = `if(!import.meta.env){Object.defineProperty(import.meta,'env',{value:{MODE:'production',BASE_URL:'/',PROD:true,DEV:false,SSR:false}});}`;
2084
2193
  for (const [path, content] of files) {
@@ -2189,7 +2298,8 @@ var Diorama = class {
2189
2298
  project,
2190
2299
  config,
2191
2300
  transformedFiles: files,
2192
- cdnProvider: this.options.cdnProvider
2301
+ cdnProvider: this.options.cdnProvider,
2302
+ tailwind: options.tailwind ?? "auto"
2193
2303
  });
2194
2304
  return { html: html2, usesESM: usesESM2, repoName: repoName2 };
2195
2305
  };
@@ -2302,6 +2412,7 @@ var DioramaPreview = react.forwardRef(
2302
2412
  height = "500px",
2303
2413
  frame,
2304
2414
  expand,
2415
+ tailwind,
2305
2416
  onLoad,
2306
2417
  onError,
2307
2418
  options,
@@ -2328,6 +2439,7 @@ var DioramaPreview = react.forwardRef(
2328
2439
  height,
2329
2440
  frame,
2330
2441
  expand,
2442
+ tailwind,
2331
2443
  onLoad,
2332
2444
  onError: (err) => {
2333
2445
  onError?.(err);
@@ -2348,7 +2460,7 @@ var DioramaPreview = react.forwardRef(
2348
2460
  instanceRef.current?.destroy();
2349
2461
  instanceRef.current = null;
2350
2462
  };
2351
- }, [repo, branch, subdirectory, loading, placeholder, height, frame, expand]);
2463
+ }, [repo, branch, subdirectory, loading, placeholder, height, frame, expand, tailwind]);
2352
2464
  const containerStyle = {
2353
2465
  width: "100%",
2354
2466
  minHeight: height,