@easybits.cloud/html-tailwind-generator 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/src/themes.ts ADDED
@@ -0,0 +1,204 @@
1
+ export interface LandingTheme {
2
+ id: string;
3
+ label: string;
4
+ colors: {
5
+ primary: string;
6
+ "primary-light": string;
7
+ "primary-dark": string;
8
+ secondary: string;
9
+ accent: string;
10
+ surface: string;
11
+ "surface-alt": string;
12
+ "on-surface": string;
13
+ "on-surface-muted": string;
14
+ "on-primary": string;
15
+ };
16
+ }
17
+
18
+ export const LANDING_THEMES: LandingTheme[] = [
19
+ {
20
+ id: "default",
21
+ label: "Neutral",
22
+ colors: {
23
+ primary: "#18181b",
24
+ "primary-light": "#3f3f46",
25
+ "primary-dark": "#09090b",
26
+ secondary: "#a1a1aa",
27
+ accent: "#18181b",
28
+ surface: "#ffffff",
29
+ "surface-alt": "#fafafa",
30
+ "on-surface": "#18181b",
31
+ "on-surface-muted": "#71717a",
32
+ "on-primary": "#ffffff",
33
+ },
34
+ },
35
+ {
36
+ id: "dark",
37
+ label: "Dark",
38
+ colors: {
39
+ primary: "#e4e4e7",
40
+ "primary-light": "#f4f4f5",
41
+ "primary-dark": "#a1a1aa",
42
+ secondary: "#71717a",
43
+ accent: "#e4e4e7",
44
+ surface: "#09090b",
45
+ "surface-alt": "#18181b",
46
+ "on-surface": "#fafafa",
47
+ "on-surface-muted": "#a1a1aa",
48
+ "on-primary": "#09090b",
49
+ },
50
+ },
51
+ {
52
+ id: "slate",
53
+ label: "Slate",
54
+ colors: {
55
+ primary: "#3b82f6",
56
+ "primary-light": "#60a5fa",
57
+ "primary-dark": "#2563eb",
58
+ secondary: "#64748b",
59
+ accent: "#3b82f6",
60
+ surface: "#ffffff",
61
+ "surface-alt": "#f8fafc",
62
+ "on-surface": "#0f172a",
63
+ "on-surface-muted": "#64748b",
64
+ "on-primary": "#ffffff",
65
+ },
66
+ },
67
+ {
68
+ id: "midnight",
69
+ label: "Midnight",
70
+ colors: {
71
+ primary: "#6366f1",
72
+ "primary-light": "#818cf8",
73
+ "primary-dark": "#4f46e5",
74
+ secondary: "#94a3b8",
75
+ accent: "#a78bfa",
76
+ surface: "#0f172a",
77
+ "surface-alt": "#1e293b",
78
+ "on-surface": "#e2e8f0",
79
+ "on-surface-muted": "#94a3b8",
80
+ "on-primary": "#ffffff",
81
+ },
82
+ },
83
+ {
84
+ id: "warm",
85
+ label: "Warm",
86
+ colors: {
87
+ primary: "#b45309",
88
+ "primary-light": "#d97706",
89
+ "primary-dark": "#92400e",
90
+ secondary: "#78716c",
91
+ accent: "#b45309",
92
+ surface: "#fafaf9",
93
+ "surface-alt": "#f5f5f4",
94
+ "on-surface": "#1c1917",
95
+ "on-surface-muted": "#78716c",
96
+ "on-primary": "#ffffff",
97
+ },
98
+ },
99
+ ];
100
+
101
+ export interface CustomColors {
102
+ primary: string;
103
+ secondary?: string;
104
+ accent?: string;
105
+ surface?: string;
106
+ }
107
+
108
+ function parseHex(hex: string) {
109
+ return {
110
+ r: parseInt(hex.slice(1, 3), 16),
111
+ g: parseInt(hex.slice(3, 5), 16),
112
+ b: parseInt(hex.slice(5, 7), 16),
113
+ };
114
+ }
115
+
116
+ function toHex(r: number, g: number, b: number) {
117
+ return `#${[r, g, b].map((c) => Math.max(0, Math.min(255, c)).toString(16).padStart(2, "0")).join("")}`;
118
+ }
119
+
120
+ function luminance(hex: string) {
121
+ const { r, g, b } = parseHex(hex);
122
+ return (0.299 * r + 0.587 * g + 0.114 * b) / 255;
123
+ }
124
+
125
+ function lighten(hex: string, amount = 40) {
126
+ const { r, g, b } = parseHex(hex);
127
+ return toHex(r + amount, g + amount, b + amount);
128
+ }
129
+
130
+ function darken(hex: string, amount = 40) {
131
+ const { r, g, b } = parseHex(hex);
132
+ return toHex(r - amount, g - amount, b - amount);
133
+ }
134
+
135
+ export function buildCustomTheme(colors: CustomColors): LandingTheme {
136
+ const { primary, secondary = "#f59e0b", accent = "#06b6d4", surface = "#ffffff" } = colors;
137
+
138
+ const onPrimary = luminance(primary) > 0.5 ? "#111827" : "#ffffff";
139
+ const surfaceLum = luminance(surface);
140
+ const isDarkSurface = surfaceLum < 0.5;
141
+
142
+ return {
143
+ id: "custom",
144
+ label: "Custom",
145
+ colors: {
146
+ primary,
147
+ "primary-light": lighten(primary),
148
+ "primary-dark": darken(primary),
149
+ secondary,
150
+ accent,
151
+ surface,
152
+ "surface-alt": isDarkSurface ? lighten(surface, 20) : darken(surface, 5),
153
+ "on-surface": isDarkSurface ? "#f1f5f9" : "#111827",
154
+ "on-surface-muted": isDarkSurface ? "#94a3b8" : "#6b7280",
155
+ "on-primary": onPrimary,
156
+ },
157
+ };
158
+ }
159
+
160
+ export function buildCustomThemeCss(colors: CustomColors): string {
161
+ const theme = buildCustomTheme(colors);
162
+ return `[data-theme="custom"] {\n${buildCssVars(theme.colors)}\n}`;
163
+ }
164
+
165
+ /** CSS custom properties for a theme */
166
+ function buildCssVars(colors: LandingTheme["colors"]): string {
167
+ return Object.entries(colors)
168
+ .map(([k, v]) => ` --color-${k}: ${v};`)
169
+ .join("\n");
170
+ }
171
+
172
+ /** Build the tailwind.config JS object string for TW v3 CDN */
173
+ function buildTailwindConfig(): string {
174
+ const colorEntries = Object.keys(LANDING_THEMES[0].colors)
175
+ .map((k) => ` '${k}': 'var(--color-${k})'`)
176
+ .join(",\n");
177
+
178
+ return `{
179
+ theme: {
180
+ extend: {
181
+ colors: {
182
+ ${colorEntries}
183
+ }
184
+ }
185
+ }
186
+ }`;
187
+ }
188
+
189
+ export function buildThemeCss(): { css: string; tailwindConfig: string } {
190
+ const defaultTheme = LANDING_THEMES[0];
191
+
192
+ const overrides = LANDING_THEMES.slice(1)
193
+ .map((t) => `[data-theme="${t.id}"] {\n${buildCssVars(t.colors)}\n}`)
194
+ .join("\n\n");
195
+
196
+ const css = `:root {\n${buildCssVars(defaultTheme.colors)}\n}\n\n${overrides}`;
197
+ return { css, tailwindConfig: buildTailwindConfig() };
198
+ }
199
+
200
+ export function buildSingleThemeCss(themeId: string): { css: string; tailwindConfig: string } {
201
+ const theme = LANDING_THEMES.find((t) => t.id === themeId) || LANDING_THEMES[0];
202
+ const css = `:root {\n${buildCssVars(theme.colors)}\n}`;
203
+ return { css, tailwindConfig: buildTailwindConfig() };
204
+ }
package/src/types.ts ADDED
@@ -0,0 +1,30 @@
1
+ export interface Section3 {
2
+ id: string;
3
+ order: number;
4
+ html: string;
5
+ label: string;
6
+ metadata?: {
7
+ type?: string;
8
+ dataBindings?: unknown[];
9
+ scripts?: string[];
10
+ };
11
+ }
12
+
13
+ export interface IframeMessage {
14
+ type:
15
+ | "element-selected"
16
+ | "text-edited"
17
+ | "element-deselected"
18
+ | "ready"
19
+ | "section-html-updated";
20
+ sectionId?: string;
21
+ tagName?: string;
22
+ rect?: { top: number; left: number; width: number; height: number };
23
+ text?: string;
24
+ elementPath?: string;
25
+ openTag?: string;
26
+ newText?: string;
27
+ isSectionRoot?: boolean;
28
+ attrs?: Record<string, string>;
29
+ sectionHtml?: string;
30
+ }