@firebuzz/design-mode 0.1.0
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/README.md +111 -0
- package/dist/index.d.mts +87 -0
- package/dist/index.d.ts +87 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +11 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# @firebuzz/design-mode
|
|
2
|
+
|
|
3
|
+
Design mode overlay and utilities for Firebuzz landing page templates. Enables visual editing of React components in development mode using React Fiber's `_debugSource`.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Visual Element Selection**: Click to select any element in your template
|
|
8
|
+
- **Runtime Element Tracking**: Uses React Fiber internals (no build-time modifications needed)
|
|
9
|
+
- **Client-side Tailwind Generation**: Generates CSS for Tailwind classes at runtime
|
|
10
|
+
- **Theme Customization**: Live preview of theme changes (colors, fonts, etc.)
|
|
11
|
+
- **Element Editing**: Edit className, text content, images, and links
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add @firebuzz/design-mode
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### 1. Add the Vite Plugin
|
|
22
|
+
|
|
23
|
+
In your `vite.config.ts`:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { defineConfig } from "vite";
|
|
27
|
+
import react from "@vitejs/plugin-react-swc";
|
|
28
|
+
import { firebuzzDesignMode } from "@firebuzz/design-mode";
|
|
29
|
+
|
|
30
|
+
export default defineConfig({
|
|
31
|
+
plugins: [
|
|
32
|
+
react(),
|
|
33
|
+
firebuzzDesignMode(),
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. Create Design Mode Directory
|
|
39
|
+
|
|
40
|
+
The plugin expects a Tailwind config JSON to be generated at `./src/design-mode/tailwind.config.json`. The directory will be created automatically.
|
|
41
|
+
|
|
42
|
+
### 3. Enable Design Mode
|
|
43
|
+
|
|
44
|
+
Design mode is automatically enabled in development (`NODE_ENV=development`). To disable it, set:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
VITE_DESIGN_MODE=false
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Configuration
|
|
51
|
+
|
|
52
|
+
The plugin accepts optional configuration:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
firebuzzDesignMode({
|
|
56
|
+
// Path to your tailwind.config.js (default: "./tailwind.config.js")
|
|
57
|
+
tailwindConfigPath: "./tailwind.config.js",
|
|
58
|
+
|
|
59
|
+
// Output path for generated JSON (default: "./src/design-mode/tailwind.config.json")
|
|
60
|
+
outputPath: "./src/design-mode/tailwind.config.json",
|
|
61
|
+
|
|
62
|
+
// Custom overlay script path (default: uses package's overlay)
|
|
63
|
+
overlayPath: "@firebuzz/design-mode/overlay",
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## How It Works
|
|
68
|
+
|
|
69
|
+
1. **Vite Plugin**: Generates Tailwind config JSON at build time and injects the overlay script
|
|
70
|
+
2. **Overlay Script**: Listens for postMessage events from parent window and enables element selection
|
|
71
|
+
3. **Tailwind Generator**: Generates CSS for Tailwind classes at runtime as they're applied
|
|
72
|
+
4. **React Fiber Integration**: Tracks element source locations using React's internal `_debugSource` property
|
|
73
|
+
|
|
74
|
+
## Message Protocol
|
|
75
|
+
|
|
76
|
+
The overlay communicates with the parent window using postMessage:
|
|
77
|
+
|
|
78
|
+
### Messages to Overlay (from parent)
|
|
79
|
+
|
|
80
|
+
- `ENABLE_DESIGN_MODE`: Enable design mode overlay
|
|
81
|
+
- `DISABLE_DESIGN_MODE`: Disable design mode overlay
|
|
82
|
+
- `FB_SELECT_ELEMENT`: Programmatically select an element
|
|
83
|
+
- `FB_DESELECT_ELEMENT`: Deselect the current element
|
|
84
|
+
- `FB_UPDATE_ELEMENT`: Update element properties (className, textContent, etc.)
|
|
85
|
+
- `FB_UPDATE_THEME`: Update theme CSS variables
|
|
86
|
+
- `FB_GET_ALL_ELEMENTS_STATE`: Request current state of all elements
|
|
87
|
+
|
|
88
|
+
### Messages from Overlay (to parent)
|
|
89
|
+
|
|
90
|
+
- `FB_ELEMENT_SELECTED`: User selected an element (includes source location and properties)
|
|
91
|
+
- `FB_ALL_ELEMENTS_STATE`: Response with all elements' current state
|
|
92
|
+
|
|
93
|
+
## TypeScript
|
|
94
|
+
|
|
95
|
+
The package includes full TypeScript definitions:
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import type {
|
|
99
|
+
DesignModeMessage,
|
|
100
|
+
ElementSelectedMessage,
|
|
101
|
+
ElementData,
|
|
102
|
+
} from "@firebuzz/design-mode";
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Development
|
|
106
|
+
|
|
107
|
+
This package is part of the Firebuzz monorepo and is designed to work with Vite-based React templates.
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Vite plugin that enables design mode features for Firebuzz templates
|
|
5
|
+
* - Generates Tailwind config JSON for client-side use
|
|
6
|
+
* - Injects overlay script for element selection
|
|
7
|
+
*
|
|
8
|
+
* NOTE: This plugin does NOT modify JSX/TSX files.
|
|
9
|
+
* Element tracking is done at runtime using React Fiber's _debugSource.
|
|
10
|
+
*
|
|
11
|
+
* @param options - Plugin configuration options
|
|
12
|
+
* @param options.tailwindConfigPath - Path to tailwind.config.js (default: "./tailwind.config.js")
|
|
13
|
+
* @param options.outputPath - Path to output tailwind.config.json (default: "./src/design-mode/tailwind.config.json")
|
|
14
|
+
* @param options.overlayPath - Path to overlay script (default: uses package's overlay.ts)
|
|
15
|
+
*/
|
|
16
|
+
declare function firebuzzDesignMode(options?: {
|
|
17
|
+
tailwindConfigPath?: string;
|
|
18
|
+
outputPath?: string;
|
|
19
|
+
overlayPath?: string;
|
|
20
|
+
}): Plugin;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* TypeScript type definitions for Firebuzz Design Mode
|
|
24
|
+
*/
|
|
25
|
+
interface SourceLocation {
|
|
26
|
+
fileName: string;
|
|
27
|
+
lineNumber: number;
|
|
28
|
+
columnNumber: number;
|
|
29
|
+
}
|
|
30
|
+
interface ElementUpdates {
|
|
31
|
+
className?: string;
|
|
32
|
+
textContent?: string;
|
|
33
|
+
src?: string;
|
|
34
|
+
alt?: string;
|
|
35
|
+
href?: string;
|
|
36
|
+
target?: string;
|
|
37
|
+
rel?: string;
|
|
38
|
+
}
|
|
39
|
+
interface ThemeVariables {
|
|
40
|
+
lightVariables?: Record<string, string>;
|
|
41
|
+
darkVariables?: Record<string, string>;
|
|
42
|
+
}
|
|
43
|
+
interface DesignModeMessage {
|
|
44
|
+
type: "ENABLE_DESIGN_MODE" | "DISABLE_DESIGN_MODE" | "FB_UPDATE_ELEMENT" | "FB_GET_ALL_ELEMENTS_STATE" | "FB_UPDATE_THEME" | "FB_DESELECT_ELEMENT" | "FB_SELECT_ELEMENT";
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
sourceFile?: string;
|
|
47
|
+
sourceLine?: number;
|
|
48
|
+
sourceColumn?: number;
|
|
49
|
+
updates?: ElementUpdates;
|
|
50
|
+
theme?: ThemeVariables;
|
|
51
|
+
}
|
|
52
|
+
interface ElementData {
|
|
53
|
+
sourceFile: string;
|
|
54
|
+
sourceLine: number;
|
|
55
|
+
sourceColumn: number;
|
|
56
|
+
tagName: string;
|
|
57
|
+
className: string;
|
|
58
|
+
textContent: string | null;
|
|
59
|
+
src?: string;
|
|
60
|
+
alt?: string;
|
|
61
|
+
href?: string;
|
|
62
|
+
target?: string;
|
|
63
|
+
rel?: string;
|
|
64
|
+
computedStyles: Record<string, string>;
|
|
65
|
+
}
|
|
66
|
+
interface ElementSelectedMessage {
|
|
67
|
+
type: "FB_ELEMENT_SELECTED";
|
|
68
|
+
data: ElementData;
|
|
69
|
+
}
|
|
70
|
+
interface AllElementsStateMessage {
|
|
71
|
+
type: "FB_ALL_ELEMENTS_STATE";
|
|
72
|
+
data: Array<{
|
|
73
|
+
sourceFile: string;
|
|
74
|
+
sourceLine: number;
|
|
75
|
+
sourceColumn: number;
|
|
76
|
+
className: string;
|
|
77
|
+
textContent: string | null;
|
|
78
|
+
src?: string;
|
|
79
|
+
alt?: string;
|
|
80
|
+
href?: string;
|
|
81
|
+
target?: string;
|
|
82
|
+
rel?: string;
|
|
83
|
+
}>;
|
|
84
|
+
}
|
|
85
|
+
type DesignModeMessageType = DesignModeMessage | ElementSelectedMessage | AllElementsStateMessage;
|
|
86
|
+
|
|
87
|
+
export { type AllElementsStateMessage, type DesignModeMessage, type DesignModeMessageType, type ElementData, type ElementSelectedMessage, type ElementUpdates, type SourceLocation, type ThemeVariables, firebuzzDesignMode };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Vite plugin that enables design mode features for Firebuzz templates
|
|
5
|
+
* - Generates Tailwind config JSON for client-side use
|
|
6
|
+
* - Injects overlay script for element selection
|
|
7
|
+
*
|
|
8
|
+
* NOTE: This plugin does NOT modify JSX/TSX files.
|
|
9
|
+
* Element tracking is done at runtime using React Fiber's _debugSource.
|
|
10
|
+
*
|
|
11
|
+
* @param options - Plugin configuration options
|
|
12
|
+
* @param options.tailwindConfigPath - Path to tailwind.config.js (default: "./tailwind.config.js")
|
|
13
|
+
* @param options.outputPath - Path to output tailwind.config.json (default: "./src/design-mode/tailwind.config.json")
|
|
14
|
+
* @param options.overlayPath - Path to overlay script (default: uses package's overlay.ts)
|
|
15
|
+
*/
|
|
16
|
+
declare function firebuzzDesignMode(options?: {
|
|
17
|
+
tailwindConfigPath?: string;
|
|
18
|
+
outputPath?: string;
|
|
19
|
+
overlayPath?: string;
|
|
20
|
+
}): Plugin;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* TypeScript type definitions for Firebuzz Design Mode
|
|
24
|
+
*/
|
|
25
|
+
interface SourceLocation {
|
|
26
|
+
fileName: string;
|
|
27
|
+
lineNumber: number;
|
|
28
|
+
columnNumber: number;
|
|
29
|
+
}
|
|
30
|
+
interface ElementUpdates {
|
|
31
|
+
className?: string;
|
|
32
|
+
textContent?: string;
|
|
33
|
+
src?: string;
|
|
34
|
+
alt?: string;
|
|
35
|
+
href?: string;
|
|
36
|
+
target?: string;
|
|
37
|
+
rel?: string;
|
|
38
|
+
}
|
|
39
|
+
interface ThemeVariables {
|
|
40
|
+
lightVariables?: Record<string, string>;
|
|
41
|
+
darkVariables?: Record<string, string>;
|
|
42
|
+
}
|
|
43
|
+
interface DesignModeMessage {
|
|
44
|
+
type: "ENABLE_DESIGN_MODE" | "DISABLE_DESIGN_MODE" | "FB_UPDATE_ELEMENT" | "FB_GET_ALL_ELEMENTS_STATE" | "FB_UPDATE_THEME" | "FB_DESELECT_ELEMENT" | "FB_SELECT_ELEMENT";
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
sourceFile?: string;
|
|
47
|
+
sourceLine?: number;
|
|
48
|
+
sourceColumn?: number;
|
|
49
|
+
updates?: ElementUpdates;
|
|
50
|
+
theme?: ThemeVariables;
|
|
51
|
+
}
|
|
52
|
+
interface ElementData {
|
|
53
|
+
sourceFile: string;
|
|
54
|
+
sourceLine: number;
|
|
55
|
+
sourceColumn: number;
|
|
56
|
+
tagName: string;
|
|
57
|
+
className: string;
|
|
58
|
+
textContent: string | null;
|
|
59
|
+
src?: string;
|
|
60
|
+
alt?: string;
|
|
61
|
+
href?: string;
|
|
62
|
+
target?: string;
|
|
63
|
+
rel?: string;
|
|
64
|
+
computedStyles: Record<string, string>;
|
|
65
|
+
}
|
|
66
|
+
interface ElementSelectedMessage {
|
|
67
|
+
type: "FB_ELEMENT_SELECTED";
|
|
68
|
+
data: ElementData;
|
|
69
|
+
}
|
|
70
|
+
interface AllElementsStateMessage {
|
|
71
|
+
type: "FB_ALL_ELEMENTS_STATE";
|
|
72
|
+
data: Array<{
|
|
73
|
+
sourceFile: string;
|
|
74
|
+
sourceLine: number;
|
|
75
|
+
sourceColumn: number;
|
|
76
|
+
className: string;
|
|
77
|
+
textContent: string | null;
|
|
78
|
+
src?: string;
|
|
79
|
+
alt?: string;
|
|
80
|
+
href?: string;
|
|
81
|
+
target?: string;
|
|
82
|
+
rel?: string;
|
|
83
|
+
}>;
|
|
84
|
+
}
|
|
85
|
+
type DesignModeMessageType = DesignModeMessage | ElementSelectedMessage | AllElementsStateMessage;
|
|
86
|
+
|
|
87
|
+
export { type AllElementsStateMessage, type DesignModeMessage, type DesignModeMessageType, type ElementData, type ElementSelectedMessage, type ElementUpdates, type SourceLocation, type ThemeVariables, firebuzzDesignMode };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';var d=require('fs/promises'),i=require('path'),f=require('esbuild');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var d__default=/*#__PURE__*/_interopDefault(d);var i__default=/*#__PURE__*/_interopDefault(i);var f__namespace=/*#__PURE__*/_interopNamespace(f);function m(n){let r=process.env.NODE_ENV==="development"&&process.env.VITE_DESIGN_MODE!=="false",o=process.cwd(),a=i__default.default.resolve(o,n?.tailwindConfigPath||"./tailwind.config.js"),s=i__default.default.resolve(o,n?.outputPath||"./src/design-mode/tailwind.config.json"),l=i__default.default.resolve(o,"./.fb-tailwind.config.js");n?.overlayPath||"@firebuzz/design-mode/overlay";return {name:"vite-plugin-firebuzz-design-mode",enforce:"pre",async buildStart(){if(r)try{await u();}catch(e){console.warn("[Firebuzz Design Mode] Could not generate Tailwind config:",e);}},configureServer(e){if(r)try{e.watcher.add(a),e.watcher.on("change",async t=>{i__default.default.normalize(t)===i__default.default.normalize(a)&&await u();});}catch(t){console.warn("[Firebuzz Design Mode] Could not watch Tailwind config:",t);}},transformIndexHtml(e){if(!r)return e;let c=`
|
|
2
|
+
<script type="module">
|
|
3
|
+
// Load Tailwind config and make it available globally
|
|
4
|
+
const response = await fetch('${s.replace(o,"")}');
|
|
5
|
+
const config = await response.json();
|
|
6
|
+
window.__FIREBUZZ_TAILWIND_CONFIG__ = config;
|
|
7
|
+
|
|
8
|
+
// Then load the overlay
|
|
9
|
+
await import('/@fs${i__default.default.resolve(__dirname,"overlay.js").replace(/\\/g,"/")}');
|
|
10
|
+
</script>`;return e.replace("</body>",`${c}</body>`)}};async function u(){try{await f__namespace.build({entryPoints:[a],outfile:l,bundle:!0,format:"esm",banner:{js:'import { createRequire } from "module"; const require = createRequire(import.meta.url);'}});let e=await import(`${l}?update=${Date.now()}`);if(!e?.default)throw new Error("Invalid Tailwind config structure");let{default:t}=await import('tailwindcss/resolveConfig.js'),c=t(e.default),g=i__default.default.dirname(s);await d__default.default.mkdir(g,{recursive:!0}),await d__default.default.writeFile(s,JSON.stringify(c,null,2)),await d__default.default.unlink(l).catch(()=>{}),console.log("[Firebuzz Design Mode] Generated Tailwind config JSON successfully");}catch(e){throw console.error("[Firebuzz Design Mode] Error generating config:",e),e}}}exports.firebuzzDesignMode=m;//# sourceMappingURL=index.js.map
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/vite-plugin.ts"],"names":["firebuzzDesignMode","options","isDesignModeEnabled","projectRoot","tailwindConfigFile","path","tailwindJsonOutfile","tailwindIntermediateFile","generateTailwindConfig","error","server","changedPath","html","scripts","f","userConfig","resolveConfig","resolvedConfig","outputDir","fs"],"mappings":"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","file":"index.js","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport * as esbuild from \"esbuild\";\nimport type { Plugin } from \"vite\";\n\n/**\n * Vite plugin that enables design mode features for Firebuzz templates\n * - Generates Tailwind config JSON for client-side use\n * - Injects overlay script for element selection\n *\n * NOTE: This plugin does NOT modify JSX/TSX files.\n * Element tracking is done at runtime using React Fiber's _debugSource.\n *\n * @param options - Plugin configuration options\n * @param options.tailwindConfigPath - Path to tailwind.config.js (default: \"./tailwind.config.js\")\n * @param options.outputPath - Path to output tailwind.config.json (default: \"./src/design-mode/tailwind.config.json\")\n * @param options.overlayPath - Path to overlay script (default: uses package's overlay.ts)\n */\nexport function firebuzzDesignMode(options?: {\n\ttailwindConfigPath?: string;\n\toutputPath?: string;\n\toverlayPath?: string;\n}): Plugin {\n\t// Only enable in development, never in production builds\n\tconst isDesignModeEnabled =\n\t\tprocess.env.NODE_ENV === \"development\" &&\n\t\tprocess.env.VITE_DESIGN_MODE !== \"false\";\n\n\tconst projectRoot = process.cwd();\n\tconst tailwindConfigFile = path.resolve(\n\t\tprojectRoot,\n\t\toptions?.tailwindConfigPath || \"./tailwind.config.js\",\n\t);\n\tconst tailwindJsonOutfile = path.resolve(\n\t\tprojectRoot,\n\t\toptions?.outputPath || \"./src/design-mode/tailwind.config.json\",\n\t);\n\tconst tailwindIntermediateFile = path.resolve(\n\t\tprojectRoot,\n\t\t\"./.fb-tailwind.config.js\",\n\t);\n\n\t// Use package's overlay script if not specified\n\tconst overlayScriptPath = options?.overlayPath || \"@firebuzz/design-mode/overlay\";\n\n\treturn {\n\t\tname: \"vite-plugin-firebuzz-design-mode\",\n\t\tenforce: \"pre\",\n\n\t\tasync buildStart() {\n\t\t\tif (!isDesignModeEnabled) return;\n\n\t\t\t// Generate Tailwind config JSON for client-side use\n\t\t\ttry {\n\t\t\t\tawait generateTailwindConfig();\n\t\t\t} catch (error) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t\"[Firebuzz Design Mode] Could not generate Tailwind config:\",\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\n\t\tconfigureServer(server) {\n\t\t\tif (!isDesignModeEnabled) return;\n\n\t\t\t// Watch Tailwind config for changes\n\t\t\ttry {\n\t\t\t\tserver.watcher.add(tailwindConfigFile);\n\t\t\t\tserver.watcher.on(\"change\", async (changedPath) => {\n\t\t\t\t\tif (\n\t\t\t\t\t\tpath.normalize(changedPath) === path.normalize(tailwindConfigFile)\n\t\t\t\t\t) {\n\t\t\t\t\t\tawait generateTailwindConfig();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t\"[Firebuzz Design Mode] Could not watch Tailwind config:\",\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\n\t\ttransformIndexHtml(html) {\n\t\t\tif (!isDesignModeEnabled) return html;\n\n\t\t\t// Inject Tailwind config as a global variable first\n\t\t\tconst configJsonPath = tailwindJsonOutfile.replace(projectRoot, \"\");\n\n\t\t\t// Inject the overlay script before </body>\n\t\t\tconst scripts = `\n<script type=\"module\">\n\t// Load Tailwind config and make it available globally\n\tconst response = await fetch('${configJsonPath}');\n\tconst config = await response.json();\n\twindow.__FIREBUZZ_TAILWIND_CONFIG__ = config;\n\n\t// Then load the overlay\n\tawait import('/@fs${path.resolve(__dirname, 'overlay.js').replace(/\\\\/g, '/')}');\n</script>`;\n\n\t\t\treturn html.replace(\"</body>\", `${scripts}</body>`);\n\t\t},\n\t};\n\n\tasync function generateTailwindConfig() {\n\t\ttry {\n\t\t\t// Bundle Tailwind config using esbuild\n\t\t\tawait esbuild.build({\n\t\t\t\tentryPoints: [tailwindConfigFile],\n\t\t\t\toutfile: tailwindIntermediateFile,\n\t\t\t\tbundle: true,\n\t\t\t\tformat: \"esm\",\n\t\t\t\tbanner: {\n\t\t\t\t\tjs: 'import { createRequire } from \"module\"; const require = createRequire(import.meta.url);',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Import and resolve the config\n\t\t\tconst userConfig = await import(\n\t\t\t\t`${tailwindIntermediateFile}?update=${Date.now()}`\n\t\t\t);\n\n\t\t\tif (!userConfig?.default) {\n\t\t\t\tthrow new Error(\"Invalid Tailwind config structure\");\n\t\t\t}\n\n\t\t\t// Dynamically import tailwindcss/resolveConfig\n\t\t\tconst { default: resolveConfig } = await import(\n\t\t\t\t\"tailwindcss/resolveConfig.js\"\n\t\t\t);\n\t\t\tconst resolvedConfig = resolveConfig(userConfig.default);\n\n\t\t\t// Ensure output directory exists\n\t\t\tconst outputDir = path.dirname(tailwindJsonOutfile);\n\t\t\tawait fs.mkdir(outputDir, { recursive: true });\n\n\t\t\t// Write resolved config to JSON\n\t\t\tawait fs.writeFile(\n\t\t\t\ttailwindJsonOutfile,\n\t\t\t\tJSON.stringify(resolvedConfig, null, 2),\n\t\t\t);\n\n\t\t\t// Clean up intermediate file\n\t\t\tawait fs.unlink(tailwindIntermediateFile).catch(() => {});\n\n\t\t\tconsole.log(\n\t\t\t\t\"[Firebuzz Design Mode] Generated Tailwind config JSON successfully\",\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[Firebuzz Design Mode] Error generating config:\", error);\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import d from'fs/promises';import i from'path';import*as f from'esbuild';function m(n){let r=process.env.NODE_ENV==="development"&&process.env.VITE_DESIGN_MODE!=="false",o=process.cwd(),a=i.resolve(o,n?.tailwindConfigPath||"./tailwind.config.js"),s=i.resolve(o,n?.outputPath||"./src/design-mode/tailwind.config.json"),l=i.resolve(o,"./.fb-tailwind.config.js");n?.overlayPath||"@firebuzz/design-mode/overlay";return {name:"vite-plugin-firebuzz-design-mode",enforce:"pre",async buildStart(){if(r)try{await u();}catch(e){console.warn("[Firebuzz Design Mode] Could not generate Tailwind config:",e);}},configureServer(e){if(r)try{e.watcher.add(a),e.watcher.on("change",async t=>{i.normalize(t)===i.normalize(a)&&await u();});}catch(t){console.warn("[Firebuzz Design Mode] Could not watch Tailwind config:",t);}},transformIndexHtml(e){if(!r)return e;let c=`
|
|
2
|
+
<script type="module">
|
|
3
|
+
// Load Tailwind config and make it available globally
|
|
4
|
+
const response = await fetch('${s.replace(o,"")}');
|
|
5
|
+
const config = await response.json();
|
|
6
|
+
window.__FIREBUZZ_TAILWIND_CONFIG__ = config;
|
|
7
|
+
|
|
8
|
+
// Then load the overlay
|
|
9
|
+
await import('/@fs${i.resolve(__dirname,"overlay.js").replace(/\\/g,"/")}');
|
|
10
|
+
</script>`;return e.replace("</body>",`${c}</body>`)}};async function u(){try{await f.build({entryPoints:[a],outfile:l,bundle:!0,format:"esm",banner:{js:'import { createRequire } from "module"; const require = createRequire(import.meta.url);'}});let e=await import(`${l}?update=${Date.now()}`);if(!e?.default)throw new Error("Invalid Tailwind config structure");let{default:t}=await import('tailwindcss/resolveConfig.js'),c=t(e.default),g=i.dirname(s);await d.mkdir(g,{recursive:!0}),await d.writeFile(s,JSON.stringify(c,null,2)),await d.unlink(l).catch(()=>{}),console.log("[Firebuzz Design Mode] Generated Tailwind config JSON successfully");}catch(e){throw console.error("[Firebuzz Design Mode] Error generating config:",e),e}}}export{m as firebuzzDesignMode};//# sourceMappingURL=index.mjs.map
|
|
11
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/vite-plugin.ts"],"names":["firebuzzDesignMode","options","isDesignModeEnabled","projectRoot","tailwindConfigFile","path","tailwindJsonOutfile","tailwindIntermediateFile","generateTailwindConfig","error","server","changedPath","html","scripts","userConfig","resolveConfig","resolvedConfig","outputDir","fs"],"mappings":"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","file":"index.mjs","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport * as esbuild from \"esbuild\";\nimport type { Plugin } from \"vite\";\n\n/**\n * Vite plugin that enables design mode features for Firebuzz templates\n * - Generates Tailwind config JSON for client-side use\n * - Injects overlay script for element selection\n *\n * NOTE: This plugin does NOT modify JSX/TSX files.\n * Element tracking is done at runtime using React Fiber's _debugSource.\n *\n * @param options - Plugin configuration options\n * @param options.tailwindConfigPath - Path to tailwind.config.js (default: \"./tailwind.config.js\")\n * @param options.outputPath - Path to output tailwind.config.json (default: \"./src/design-mode/tailwind.config.json\")\n * @param options.overlayPath - Path to overlay script (default: uses package's overlay.ts)\n */\nexport function firebuzzDesignMode(options?: {\n\ttailwindConfigPath?: string;\n\toutputPath?: string;\n\toverlayPath?: string;\n}): Plugin {\n\t// Only enable in development, never in production builds\n\tconst isDesignModeEnabled =\n\t\tprocess.env.NODE_ENV === \"development\" &&\n\t\tprocess.env.VITE_DESIGN_MODE !== \"false\";\n\n\tconst projectRoot = process.cwd();\n\tconst tailwindConfigFile = path.resolve(\n\t\tprojectRoot,\n\t\toptions?.tailwindConfigPath || \"./tailwind.config.js\",\n\t);\n\tconst tailwindJsonOutfile = path.resolve(\n\t\tprojectRoot,\n\t\toptions?.outputPath || \"./src/design-mode/tailwind.config.json\",\n\t);\n\tconst tailwindIntermediateFile = path.resolve(\n\t\tprojectRoot,\n\t\t\"./.fb-tailwind.config.js\",\n\t);\n\n\t// Use package's overlay script if not specified\n\tconst overlayScriptPath = options?.overlayPath || \"@firebuzz/design-mode/overlay\";\n\n\treturn {\n\t\tname: \"vite-plugin-firebuzz-design-mode\",\n\t\tenforce: \"pre\",\n\n\t\tasync buildStart() {\n\t\t\tif (!isDesignModeEnabled) return;\n\n\t\t\t// Generate Tailwind config JSON for client-side use\n\t\t\ttry {\n\t\t\t\tawait generateTailwindConfig();\n\t\t\t} catch (error) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t\"[Firebuzz Design Mode] Could not generate Tailwind config:\",\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\n\t\tconfigureServer(server) {\n\t\t\tif (!isDesignModeEnabled) return;\n\n\t\t\t// Watch Tailwind config for changes\n\t\t\ttry {\n\t\t\t\tserver.watcher.add(tailwindConfigFile);\n\t\t\t\tserver.watcher.on(\"change\", async (changedPath) => {\n\t\t\t\t\tif (\n\t\t\t\t\t\tpath.normalize(changedPath) === path.normalize(tailwindConfigFile)\n\t\t\t\t\t) {\n\t\t\t\t\t\tawait generateTailwindConfig();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t\"[Firebuzz Design Mode] Could not watch Tailwind config:\",\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\n\t\ttransformIndexHtml(html) {\n\t\t\tif (!isDesignModeEnabled) return html;\n\n\t\t\t// Inject Tailwind config as a global variable first\n\t\t\tconst configJsonPath = tailwindJsonOutfile.replace(projectRoot, \"\");\n\n\t\t\t// Inject the overlay script before </body>\n\t\t\tconst scripts = `\n<script type=\"module\">\n\t// Load Tailwind config and make it available globally\n\tconst response = await fetch('${configJsonPath}');\n\tconst config = await response.json();\n\twindow.__FIREBUZZ_TAILWIND_CONFIG__ = config;\n\n\t// Then load the overlay\n\tawait import('/@fs${path.resolve(__dirname, 'overlay.js').replace(/\\\\/g, '/')}');\n</script>`;\n\n\t\t\treturn html.replace(\"</body>\", `${scripts}</body>`);\n\t\t},\n\t};\n\n\tasync function generateTailwindConfig() {\n\t\ttry {\n\t\t\t// Bundle Tailwind config using esbuild\n\t\t\tawait esbuild.build({\n\t\t\t\tentryPoints: [tailwindConfigFile],\n\t\t\t\toutfile: tailwindIntermediateFile,\n\t\t\t\tbundle: true,\n\t\t\t\tformat: \"esm\",\n\t\t\t\tbanner: {\n\t\t\t\t\tjs: 'import { createRequire } from \"module\"; const require = createRequire(import.meta.url);',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Import and resolve the config\n\t\t\tconst userConfig = await import(\n\t\t\t\t`${tailwindIntermediateFile}?update=${Date.now()}`\n\t\t\t);\n\n\t\t\tif (!userConfig?.default) {\n\t\t\t\tthrow new Error(\"Invalid Tailwind config structure\");\n\t\t\t}\n\n\t\t\t// Dynamically import tailwindcss/resolveConfig\n\t\t\tconst { default: resolveConfig } = await import(\n\t\t\t\t\"tailwindcss/resolveConfig.js\"\n\t\t\t);\n\t\t\tconst resolvedConfig = resolveConfig(userConfig.default);\n\n\t\t\t// Ensure output directory exists\n\t\t\tconst outputDir = path.dirname(tailwindJsonOutfile);\n\t\t\tawait fs.mkdir(outputDir, { recursive: true });\n\n\t\t\t// Write resolved config to JSON\n\t\t\tawait fs.writeFile(\n\t\t\t\ttailwindJsonOutfile,\n\t\t\t\tJSON.stringify(resolvedConfig, null, 2),\n\t\t\t);\n\n\t\t\t// Clean up intermediate file\n\t\t\tawait fs.unlink(tailwindIntermediateFile).catch(() => {});\n\n\t\t\tconsole.log(\n\t\t\t\t\"[Firebuzz Design Mode] Generated Tailwind config JSON successfully\",\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[Firebuzz Design Mode] Error generating config:\", error);\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@firebuzz/design-mode",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Design mode overlay and utilities for Firebuzz landing page templates",
|
|
5
|
+
"author": "Firebuzz Team",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.mjs",
|
|
14
|
+
"require": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"dev": "tsup --watch",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"clean": "rm -rf dist",
|
|
26
|
+
"prepublishOnly": "pnpm build"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"react": ">=18.0.0",
|
|
30
|
+
"tailwindcss": "^3.0.0",
|
|
31
|
+
"vite": "^6.0.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/babel__generator": "^7.27.0",
|
|
35
|
+
"@types/node": "^22.0.0",
|
|
36
|
+
"tsup": "^8.0.0",
|
|
37
|
+
"typescript": "^5.7.2"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"esbuild": "^0.25.11"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"design-mode",
|
|
44
|
+
"visual-editor",
|
|
45
|
+
"firebuzz",
|
|
46
|
+
"landing-pages",
|
|
47
|
+
"vite",
|
|
48
|
+
"tailwind"
|
|
49
|
+
],
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "https://github.com/firebuzz/firebuzz.git",
|
|
53
|
+
"directory": "packages/design-mode"
|
|
54
|
+
},
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"access": "public"
|
|
57
|
+
}
|
|
58
|
+
}
|