react-tailwind-email-editor 0.0.14 → 0.0.16

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/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import * as React10 from 'react';
2
- import React10__default, { createContext, useContext, useMemo, useEffect, useCallback, useState } from 'react';
1
+ import * as React9 from 'react';
2
+ import React9__default, { createContext, useContext, useMemo, useEffect, useCallback, useState } from 'react';
3
3
  import { useEditor, useNode, Element, Editor, Frame } from '@craftjs/core';
4
4
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
5
- import { ChevronDown, X, ChevronRight, Check, Circle, Table, Variable, Quote, Tag, Timer, Share2, List, PlayCircle, MousePointer2, Image, Type, Minus, ArrowUpDown, Columns, LayoutTemplate, PanelBottom, PanelTop, Layers, ChevronUp, Copy, Trash2, Settings2, Paintbrush, Move, ArrowUp, Sun, Moon, Undo2, Redo2, Eye, Code, Download, Settings } from 'lucide-react';
5
+ import { ChevronDown, Table, Variable, Quote, Tag, Timer, Share2, List, PlayCircle, MousePointer2, Image, Type, Minus, ArrowUpDown, LayoutTemplate, PanelBottom, PanelTop, Layers, ChevronUp, Copy, Trash2, Settings2, Paintbrush, Move, ArrowUp, Undo2, Redo2, Eye, Code, Check, Download, Settings } from 'lucide-react';
6
6
  import { clsx } from 'clsx';
7
7
  import { twMerge } from 'tailwind-merge';
8
8
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -10,17 +10,14 @@ import { Slot } from '@radix-ui/react-slot';
10
10
  import { cva } from 'class-variance-authority';
11
11
  import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
12
12
  import * as TabsPrimitive from '@radix-ui/react-tabs';
13
- import * as DialogPrimitive from '@radix-ui/react-dialog';
14
- import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
15
- import * as PopoverPrimitive from '@radix-ui/react-popover';
16
- import * as LabelPrimitive from '@radix-ui/react-label';
13
+ import { createPortal } from 'react-dom';
17
14
 
18
15
  // src/components/editor/EmailEditor.tsx
19
16
  function cn(...inputs) {
20
17
  return twMerge(clsx(inputs));
21
18
  }
22
19
  var Accordion = AccordionPrimitive.Root;
23
- var AccordionItem = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
20
+ var AccordionItem = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
24
21
  AccordionPrimitive.Item,
25
22
  {
26
23
  ref,
@@ -29,7 +26,7 @@ var AccordionItem = React10.forwardRef(({ className, ...props }, ref) => /* @__P
29
26
  }
30
27
  ));
31
28
  AccordionItem.displayName = "AccordionItem";
32
- var AccordionTrigger = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
29
+ var AccordionTrigger = React9.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
33
30
  AccordionPrimitive.Trigger,
34
31
  {
35
32
  ref,
@@ -45,7 +42,7 @@ var AccordionTrigger = React10.forwardRef(({ className, children, ...props }, re
45
42
  }
46
43
  ) }));
47
44
  AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
48
- var AccordionContent = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
45
+ var AccordionContent = React9.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
49
46
  AccordionPrimitive.Content,
50
47
  {
51
48
  ref,
@@ -110,7 +107,7 @@ var ToolboxItem = ({ name, config }) => {
110
107
  };
111
108
  var Toolbox = () => {
112
109
  const { components } = useEditorConfig();
113
- const grouped = React10__default.useMemo(() => {
110
+ const grouped = React9__default.useMemo(() => {
114
111
  const map = {};
115
112
  for (const [name, config] of Object.entries(components)) {
116
113
  const cat = config.category || "Other";
@@ -167,7 +164,7 @@ var buttonVariants = cva(
167
164
  }
168
165
  }
169
166
  );
170
- var Button = React10.forwardRef(
167
+ var Button = React9.forwardRef(
171
168
  ({ className, variant, size, asChild = false, ...props }, ref) => {
172
169
  const Comp = asChild ? Slot : "button";
173
170
  return /* @__PURE__ */ jsx(
@@ -181,7 +178,7 @@ var Button = React10.forwardRef(
181
178
  }
182
179
  );
183
180
  Button.displayName = "Button";
184
- var ScrollArea = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
181
+ var ScrollArea = React9.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
185
182
  ScrollAreaPrimitive.Root,
186
183
  {
187
184
  ref,
@@ -195,7 +192,7 @@ var ScrollArea = React10.forwardRef(({ className, children, ...props }, ref) =>
195
192
  }
196
193
  ));
197
194
  ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
198
- var ScrollBar = React10.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
195
+ var ScrollBar = React9.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
199
196
  ScrollAreaPrimitive.ScrollAreaScrollbar,
200
197
  {
201
198
  ref,
@@ -273,7 +270,7 @@ var SettingsPanel = () => {
273
270
  }
274
271
  };
275
272
  if (slots.settingsPanel && selected) {
276
- return React10__default.createElement(slots.settingsPanel, {
273
+ return React9__default.createElement(slots.settingsPanel, {
277
274
  selectedId: selected.id,
278
275
  selectedName: selected.displayName || selected.name,
279
276
  //@ts-ignore
@@ -286,7 +283,7 @@ var SettingsPanel = () => {
286
283
  }
287
284
  if (!selected) {
288
285
  if (slots.settingsEmptyState) {
289
- return React10__default.createElement(slots.settingsEmptyState);
286
+ return React9__default.createElement(slots.settingsEmptyState);
290
287
  }
291
288
  return /* @__PURE__ */ jsxs("div", { className: "p-6 text-center", children: [
292
289
  /* @__PURE__ */ jsx("div", { className: "w-16 h-16 mx-auto mb-4 rounded-full bg-muted flex items-center justify-center", children: /* @__PURE__ */ jsx(Layers, { className: "h-8 w-8 text-muted-foreground" }) }),
@@ -361,7 +358,7 @@ var SettingsPanel = () => {
361
358
  /* @__PURE__ */ jsx(Settings2, { className: "h-4 w-4 text-muted-foreground" }),
362
359
  /* @__PURE__ */ jsx("span", { children: "Properties" })
363
360
  ] }) }),
364
- /* @__PURE__ */ jsx(AccordionContent, { className: "pb-4", children: React10__default.createElement(selected.settings) })
361
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-4", children: React9__default.createElement(selected.settings) })
365
362
  ] }) }) : /* @__PURE__ */ jsxs("div", { className: "text-center text-muted-foreground text-sm py-8", children: [
366
363
  /* @__PURE__ */ jsx(Paintbrush, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
367
364
  /* @__PURE__ */ jsx("p", { children: "No editable properties" })
@@ -1993,126 +1990,6 @@ SocialLinks.craft = {
1993
1990
  settings: SocialLinksSettings
1994
1991
  }
1995
1992
  };
1996
- var TwoColumn = ({
1997
- leftWidth = 50,
1998
- gap = 20,
1999
- padding = 10,
2000
- backgroundColor = "#ffffff"
2001
- }) => {
2002
- const { connectors: { connect, drag } } = useNode();
2003
- return /* @__PURE__ */ jsxs(
2004
- "div",
2005
- {
2006
- ref: (ref) => connect(drag(ref)),
2007
- style: {
2008
- display: "flex",
2009
- gap: `${gap}px`,
2010
- padding: `${padding}px`,
2011
- backgroundColor,
2012
- width: "100%"
2013
- },
2014
- children: [
2015
- /* @__PURE__ */ jsx("div", { style: { width: `${leftWidth}%` }, children: /* @__PURE__ */ jsx(Element, { id: "left-column", is: Container, canvas: true, background: "#f9f9f9", padding: 10 }) }),
2016
- /* @__PURE__ */ jsx("div", { style: { width: `${100 - leftWidth}%` }, children: /* @__PURE__ */ jsx(Element, { id: "right-column", is: Container, canvas: true, background: "#f9f9f9", padding: 10 }) })
2017
- ]
2018
- }
2019
- );
2020
- };
2021
- var TwoColumnSettings = () => {
2022
- const { actions: { setProp }, leftWidth, gap, padding, backgroundColor } = useNode((node) => ({
2023
- leftWidth: node.data.props.leftWidth,
2024
- gap: node.data.props.gap,
2025
- padding: node.data.props.padding,
2026
- backgroundColor: node.data.props.backgroundColor
2027
- }));
2028
- return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
2029
- /* @__PURE__ */ jsxs("div", { children: [
2030
- /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-1", children: "Left Column Width" }),
2031
- /* @__PURE__ */ jsx(
2032
- "input",
2033
- {
2034
- type: "range",
2035
- min: 20,
2036
- max: 80,
2037
- value: leftWidth || 50,
2038
- onChange: (e) => setProp((props) => props.leftWidth = parseInt(e.target.value)),
2039
- className: "w-full"
2040
- }
2041
- ),
2042
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm text-muted-foreground", children: [
2043
- /* @__PURE__ */ jsxs("span", { children: [
2044
- "Left: ",
2045
- leftWidth,
2046
- "%"
2047
- ] }),
2048
- /* @__PURE__ */ jsxs("span", { children: [
2049
- "Right: ",
2050
- 100 - (leftWidth || 50),
2051
- "%"
2052
- ] })
2053
- ] })
2054
- ] }),
2055
- /* @__PURE__ */ jsxs("div", { children: [
2056
- /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-1", children: "Gap" }),
2057
- /* @__PURE__ */ jsx(
2058
- "input",
2059
- {
2060
- type: "range",
2061
- min: 0,
2062
- max: 40,
2063
- value: gap || 20,
2064
- onChange: (e) => setProp((props) => props.gap = parseInt(e.target.value)),
2065
- className: "w-full"
2066
- }
2067
- ),
2068
- /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground", children: [
2069
- gap,
2070
- "px"
2071
- ] })
2072
- ] }),
2073
- /* @__PURE__ */ jsxs("div", { children: [
2074
- /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-1", children: "Padding" }),
2075
- /* @__PURE__ */ jsx(
2076
- "input",
2077
- {
2078
- type: "range",
2079
- min: 0,
2080
- max: 40,
2081
- value: padding || 10,
2082
- onChange: (e) => setProp((props) => props.padding = parseInt(e.target.value)),
2083
- className: "w-full"
2084
- }
2085
- ),
2086
- /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground", children: [
2087
- padding,
2088
- "px"
2089
- ] })
2090
- ] }),
2091
- /* @__PURE__ */ jsxs("div", { children: [
2092
- /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-1", children: "Background Color" }),
2093
- /* @__PURE__ */ jsx(
2094
- "input",
2095
- {
2096
- type: "color",
2097
- value: backgroundColor || "#ffffff",
2098
- onChange: (e) => setProp((props) => props.backgroundColor = e.target.value),
2099
- className: "w-full h-10 rounded border cursor-pointer"
2100
- }
2101
- )
2102
- ] })
2103
- ] });
2104
- };
2105
- TwoColumn.craft = {
2106
- props: {
2107
- leftWidth: 50,
2108
- gap: 20,
2109
- padding: 10,
2110
- backgroundColor: "#ffffff"
2111
- },
2112
- related: {
2113
- settings: TwoColumnSettings
2114
- }
2115
- };
2116
1993
  var Countdown = ({
2117
1994
  title = "Sale Ends In",
2118
1995
  days = 3,
@@ -3643,13 +3520,6 @@ var DEFAULT_COMPONENTS = {
3643
3520
  category: "Layout",
3644
3521
  createElement: () => /* @__PURE__ */ jsx(Element, { is: Container, canvas: true })
3645
3522
  },
3646
- TwoColumn: {
3647
- component: TwoColumn,
3648
- label: "Two Columns",
3649
- description: "Side-by-side layout",
3650
- icon: Columns,
3651
- category: "Layout"
3652
- },
3653
3523
  Spacer: {
3654
3524
  component: Spacer,
3655
3525
  label: "Spacer",
@@ -4094,7 +3964,7 @@ ${childrenHtml}
4094
3964
  return renderNode("ROOT");
4095
3965
  };
4096
3966
  var Tabs = TabsPrimitive.Root;
4097
- var TabsList = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3967
+ var TabsList = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4098
3968
  TabsPrimitive.List,
4099
3969
  {
4100
3970
  ref,
@@ -4106,7 +3976,7 @@ var TabsList = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__
4106
3976
  }
4107
3977
  ));
4108
3978
  TabsList.displayName = TabsPrimitive.List.displayName;
4109
- var TabsTrigger = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3979
+ var TabsTrigger = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4110
3980
  TabsPrimitive.Trigger,
4111
3981
  {
4112
3982
  ref,
@@ -4118,7 +3988,7 @@ var TabsTrigger = React10.forwardRef(({ className, ...props }, ref) => /* @__PUR
4118
3988
  }
4119
3989
  ));
4120
3990
  TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
4121
- var TabsContent = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3991
+ var TabsContent = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4122
3992
  TabsPrimitive.Content,
4123
3993
  {
4124
3994
  ref,
@@ -4130,308 +4000,303 @@ var TabsContent = React10.forwardRef(({ className, ...props }, ref) => /* @__PUR
4130
4000
  }
4131
4001
  ));
4132
4002
  TabsContent.displayName = TabsPrimitive.Content.displayName;
4133
- var Dialog = DialogPrimitive.Root;
4134
- var DialogPortal = DialogPrimitive.Portal;
4135
- var DialogOverlay = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4136
- DialogPrimitive.Overlay,
4137
- {
4138
- ref,
4139
- className: cn(
4140
- "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
4141
- className
4003
+ var Modal = ({
4004
+ open,
4005
+ onClose,
4006
+ title,
4007
+ description,
4008
+ children,
4009
+ maxWidth = 672,
4010
+ maxHeight = "85vh"
4011
+ }) => {
4012
+ const panelRef = React9__default.useRef(null);
4013
+ const [closeHovered, setCloseHovered] = React9__default.useState(false);
4014
+ useEffect(() => {
4015
+ if (!open) return;
4016
+ const handler = (e) => {
4017
+ if (e.key === "Escape") onClose();
4018
+ };
4019
+ document.addEventListener("keydown", handler);
4020
+ return () => document.removeEventListener("keydown", handler);
4021
+ }, [open, onClose]);
4022
+ useEffect(() => {
4023
+ if (open) {
4024
+ const prev = document.body.style.overflow;
4025
+ document.body.style.overflow = "hidden";
4026
+ return () => {
4027
+ document.body.style.overflow = prev;
4028
+ };
4029
+ }
4030
+ }, [open]);
4031
+ useEffect(() => {
4032
+ if (open && panelRef.current) panelRef.current.focus();
4033
+ }, [open]);
4034
+ if (!open) return null;
4035
+ return createPortal(
4036
+ /* @__PURE__ */ jsx(
4037
+ "div",
4038
+ {
4039
+ role: "dialog",
4040
+ "aria-modal": "true",
4041
+ "aria-labelledby": title ? "modal-title" : void 0,
4042
+ "aria-describedby": description ? "modal-desc" : void 0,
4043
+ onMouseDown: (e) => {
4044
+ if (e.target === e.currentTarget) onClose();
4045
+ },
4046
+ style: {
4047
+ position: "fixed",
4048
+ inset: 0,
4049
+ zIndex: 9999,
4050
+ display: "flex",
4051
+ alignItems: "center",
4052
+ justifyContent: "center",
4053
+ backgroundColor: "rgba(0,0,0,0.5)",
4054
+ padding: "16px"
4055
+ },
4056
+ children: /* @__PURE__ */ jsxs(
4057
+ "div",
4058
+ {
4059
+ ref: panelRef,
4060
+ tabIndex: -1,
4061
+ style: {
4062
+ position: "relative",
4063
+ backgroundColor: "#ffffff",
4064
+ borderRadius: "12px",
4065
+ boxShadow: "0 20px 60px rgba(0,0,0,0.2), 0 4px 16px rgba(0,0,0,0.12)",
4066
+ display: "flex",
4067
+ flexDirection: "column",
4068
+ width: "100%",
4069
+ maxWidth: `${maxWidth}px`,
4070
+ maxHeight,
4071
+ overflowY: "auto",
4072
+ outline: "none"
4073
+ },
4074
+ children: [
4075
+ /* @__PURE__ */ jsx(
4076
+ "button",
4077
+ {
4078
+ onClick: onClose,
4079
+ "aria-label": "Close modal",
4080
+ onMouseEnter: () => setCloseHovered(true),
4081
+ onMouseLeave: () => setCloseHovered(false),
4082
+ style: {
4083
+ position: "absolute",
4084
+ top: "14px",
4085
+ right: "14px",
4086
+ width: "32px",
4087
+ height: "32px",
4088
+ borderRadius: "8px",
4089
+ border: "none",
4090
+ background: closeHovered ? "#f3f4f6" : "transparent",
4091
+ cursor: "pointer",
4092
+ display: "flex",
4093
+ alignItems: "center",
4094
+ justifyContent: "center",
4095
+ color: closeHovered ? "#111827" : "#6b7280",
4096
+ fontSize: "18px",
4097
+ lineHeight: 1,
4098
+ padding: 0,
4099
+ flexShrink: 0,
4100
+ transition: "background 0.15s, color 0.15s"
4101
+ },
4102
+ children: "\u2715"
4103
+ }
4104
+ ),
4105
+ (title || description) && /* @__PURE__ */ jsxs("div", { style: { padding: "20px 24px 0 24px", flexShrink: 0 }, children: [
4106
+ title && /* @__PURE__ */ jsx(
4107
+ "h2",
4108
+ {
4109
+ id: "modal-title",
4110
+ style: {
4111
+ margin: 0,
4112
+ fontSize: "18px",
4113
+ fontWeight: 600,
4114
+ lineHeight: "1.4",
4115
+ color: "#111827"
4116
+ },
4117
+ children: title
4118
+ }
4119
+ ),
4120
+ description && /* @__PURE__ */ jsx(
4121
+ "p",
4122
+ {
4123
+ id: "modal-desc",
4124
+ style: {
4125
+ margin: "6px 0 0 0",
4126
+ fontSize: "14px",
4127
+ lineHeight: "1.5",
4128
+ color: "#6b7280"
4129
+ },
4130
+ children: description
4131
+ }
4132
+ )
4133
+ ] }),
4134
+ /* @__PURE__ */ jsx(
4135
+ "div",
4136
+ {
4137
+ style: { padding: "16px 24px 24px 24px", overflowY: "auto", flex: 1 },
4138
+ children
4139
+ }
4140
+ )
4141
+ ]
4142
+ }
4143
+ )
4144
+ }
4142
4145
  ),
4143
- ...props
4144
- }
4145
- ));
4146
- DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
4147
- var DialogContent = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
4148
- /* @__PURE__ */ jsx(DialogOverlay, {}),
4149
- /* @__PURE__ */ jsxs(
4150
- DialogPrimitive.Content,
4146
+ document.body
4147
+ );
4148
+ };
4149
+ var Dropdown = ({
4150
+ trigger,
4151
+ label,
4152
+ items,
4153
+ align = "start"
4154
+ }) => {
4155
+ const [open, setOpen] = useState(false);
4156
+ const containerRef = React9__default.useRef(null);
4157
+ useEffect(() => {
4158
+ if (!open) return;
4159
+ const handler = (e) => {
4160
+ var _a;
4161
+ if (!((_a = containerRef.current) == null ? void 0 : _a.contains(e.target))) setOpen(false);
4162
+ };
4163
+ document.addEventListener("mousedown", handler);
4164
+ return () => document.removeEventListener("mousedown", handler);
4165
+ }, [open]);
4166
+ useEffect(() => {
4167
+ if (!open) return;
4168
+ const handler = (e) => {
4169
+ if (e.key === "Escape") setOpen(false);
4170
+ };
4171
+ document.addEventListener("keydown", handler);
4172
+ return () => document.removeEventListener("keydown", handler);
4173
+ }, [open]);
4174
+ return /* @__PURE__ */ jsxs(
4175
+ "div",
4151
4176
  {
4152
- ref,
4153
- className: cn(
4154
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
4155
- className
4156
- ),
4157
- ...props,
4177
+ ref: containerRef,
4178
+ style: { position: "relative", display: "inline-block" },
4158
4179
  children: [
4159
- children,
4160
- /* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none", children: [
4161
- /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
4162
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
4163
- ] })
4180
+ /* @__PURE__ */ jsx("div", { onClick: () => setOpen((v) => !v), children: trigger }),
4181
+ open && /* @__PURE__ */ jsxs(
4182
+ "div",
4183
+ {
4184
+ style: {
4185
+ position: "absolute",
4186
+ top: "calc(100% + 6px)",
4187
+ ...align === "end" ? { right: 0 } : { left: 0 },
4188
+ zIndex: 9998,
4189
+ minWidth: "224px",
4190
+ backgroundColor: "#ffffff",
4191
+ border: "1px solid #e5e7eb",
4192
+ borderRadius: "8px",
4193
+ boxShadow: "0 8px 24px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.08)",
4194
+ padding: "4px",
4195
+ outline: "none"
4196
+ },
4197
+ children: [
4198
+ label && /* @__PURE__ */ jsx(
4199
+ "div",
4200
+ {
4201
+ style: {
4202
+ padding: "6px 8px 4px 8px",
4203
+ fontSize: "11px",
4204
+ fontWeight: 600,
4205
+ color: "#9ca3af",
4206
+ textTransform: "uppercase",
4207
+ letterSpacing: "0.06em"
4208
+ },
4209
+ children: label
4210
+ }
4211
+ ),
4212
+ items.map((entry) => {
4213
+ if ("separator" in entry && entry.separator) {
4214
+ return /* @__PURE__ */ jsx(
4215
+ "div",
4216
+ {
4217
+ style: {
4218
+ height: "1px",
4219
+ backgroundColor: "#f3f4f6",
4220
+ margin: "4px 0"
4221
+ }
4222
+ },
4223
+ entry.key
4224
+ );
4225
+ }
4226
+ const item = entry;
4227
+ return /* @__PURE__ */ jsx(
4228
+ DropdownItemRow,
4229
+ {
4230
+ item,
4231
+ onSelect: () => {
4232
+ item.onClick();
4233
+ setOpen(false);
4234
+ }
4235
+ },
4236
+ item.key
4237
+ );
4238
+ })
4239
+ ]
4240
+ }
4241
+ )
4164
4242
  ]
4165
4243
  }
4166
- )
4167
- ] }));
4168
- DialogContent.displayName = DialogPrimitive.Content.displayName;
4169
- var DialogHeader = ({
4170
- className,
4171
- ...props
4172
- }) => /* @__PURE__ */ jsx(
4173
- "div",
4174
- {
4175
- className: cn(
4176
- "flex flex-col space-y-1.5 text-center sm:text-left",
4177
- className
4178
- ),
4179
- ...props
4180
- }
4181
- );
4182
- DialogHeader.displayName = "DialogHeader";
4183
- var DialogTitle = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4184
- DialogPrimitive.Title,
4185
- {
4186
- ref,
4187
- className: cn(
4188
- "text-lg font-semibold leading-none tracking-tight",
4189
- className
4190
- ),
4191
- ...props
4192
- }
4193
- ));
4194
- DialogTitle.displayName = DialogPrimitive.Title.displayName;
4195
- var DialogDescription = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4196
- DialogPrimitive.Description,
4197
- {
4198
- ref,
4199
- className: cn("text-sm text-muted-foreground", className),
4200
- ...props
4201
- }
4202
- ));
4203
- DialogDescription.displayName = DialogPrimitive.Description.displayName;
4204
- var DropdownMenu = DropdownMenuPrimitive.Root;
4205
- var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
4206
- var DropdownMenuSubTrigger = React10.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
4207
- DropdownMenuPrimitive.SubTrigger,
4208
- {
4209
- ref,
4210
- className: cn(
4211
- "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[state=open]:bg-accent focus:bg-accent",
4212
- inset && "pl-8",
4213
- className
4214
- ),
4215
- ...props,
4216
- children: [
4217
- children,
4218
- /* @__PURE__ */ jsx(ChevronRight, { className: "ml-auto h-4 w-4" })
4219
- ]
4220
- }
4221
- ));
4222
- DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
4223
- var DropdownMenuSubContent = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4224
- DropdownMenuPrimitive.SubContent,
4225
- {
4226
- ref,
4227
- className: cn(
4228
- "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4229
- className
4230
- ),
4231
- ...props
4232
- }
4233
- ));
4234
- DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
4235
- var DropdownMenuContent = React10.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
4236
- DropdownMenuPrimitive.Content,
4237
- {
4238
- ref,
4239
- sideOffset,
4240
- className: cn(
4241
- "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4242
- className
4243
- ),
4244
- ...props
4245
- }
4246
- ) }));
4247
- DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
4248
- var DropdownMenuItem = React10.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
4249
- DropdownMenuPrimitive.Item,
4250
- {
4251
- ref,
4252
- className: cn(
4253
- "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
4254
- inset && "pl-8",
4255
- className
4256
- ),
4257
- ...props
4258
- }
4259
- ));
4260
- DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
4261
- var DropdownMenuCheckboxItem = React10.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
4262
- DropdownMenuPrimitive.CheckboxItem,
4263
- {
4264
- ref,
4265
- className: cn(
4266
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
4267
- className
4268
- ),
4269
- checked,
4270
- ...props,
4271
- children: [
4272
- /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
4273
- children
4274
- ]
4275
- }
4276
- ));
4277
- DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
4278
- var DropdownMenuRadioItem = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
4279
- DropdownMenuPrimitive.RadioItem,
4280
- {
4281
- ref,
4282
- className: cn(
4283
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
4284
- className
4285
- ),
4286
- ...props,
4287
- children: [
4288
- /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Circle, { className: "h-2 w-2 fill-current" }) }) }),
4289
- children
4290
- ]
4291
- }
4292
- ));
4293
- DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
4294
- var DropdownMenuLabel = React10.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
4295
- DropdownMenuPrimitive.Label,
4296
- {
4297
- ref,
4298
- className: cn(
4299
- "px-2 py-1.5 text-sm font-semibold",
4300
- inset && "pl-8",
4301
- className
4302
- ),
4303
- ...props
4304
- }
4305
- ));
4306
- DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
4307
- var DropdownMenuSeparator = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4308
- DropdownMenuPrimitive.Separator,
4309
- {
4310
- ref,
4311
- className: cn("-mx-1 my-1 h-px bg-muted", className),
4312
- ...props
4313
- }
4314
- ));
4315
- DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
4316
- var Popover = PopoverPrimitive.Root;
4317
- var PopoverTrigger = PopoverPrimitive.Trigger;
4318
- var PopoverContent = React10.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
4319
- PopoverPrimitive.Content,
4320
- {
4321
- ref,
4322
- align,
4323
- sideOffset,
4324
- className: cn(
4325
- "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4326
- className
4327
- ),
4328
- ...props
4329
- }
4330
- ) }));
4331
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
4332
- var labelVariants = cva(
4333
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
4334
- );
4335
- var Label2 = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4336
- LabelPrimitive.Root,
4337
- {
4338
- ref,
4339
- className: cn(labelVariants(), className),
4340
- ...props
4341
- }
4342
- ));
4343
- Label2.displayName = LabelPrimitive.Root.displayName;
4344
- var COLOR_PRESETS = [
4345
- { name: "Blue", hsl: "222.2 47.4% 11.2%" },
4346
- { name: "Indigo", hsl: "243 75% 59%" },
4347
- { name: "Emerald", hsl: "160 84% 39%" },
4348
- { name: "Rose", hsl: "346 77% 50%" },
4349
- { name: "Amber", hsl: "32 95% 44%" },
4350
- { name: "Violet", hsl: "263 70% 50%" },
4351
- { name: "Cyan", hsl: "192 91% 36%" },
4352
- { name: "Slate", hsl: "215 20% 35%" }
4353
- ];
4354
- var ColorCustomizer = ({ value, onColorChange }) => {
4355
- const [customColor, setCustomColor] = useState("#1e293b");
4356
- const applyColor = (hsl) => {
4357
- onColorChange(hsl);
4358
- };
4359
- const hexToHsl = (hex) => {
4360
- const r = parseInt(hex.slice(1, 3), 16) / 255;
4361
- const g = parseInt(hex.slice(3, 5), 16) / 255;
4362
- const b = parseInt(hex.slice(5, 7), 16) / 255;
4363
- const max = Math.max(r, g, b);
4364
- const min = Math.min(r, g, b);
4365
- let h = 0;
4366
- let s = 0;
4367
- const l = (max + min) / 2;
4368
- if (max !== min) {
4369
- const d = max - min;
4370
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
4371
- switch (max) {
4372
- case r:
4373
- h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
4374
- break;
4375
- case g:
4376
- h = ((b - r) / d + 2) / 6;
4377
- break;
4378
- case b:
4379
- h = ((r - g) / d + 4) / 6;
4380
- break;
4381
- }
4244
+ );
4245
+ };
4246
+ var DropdownItemRow = ({ item, onSelect }) => {
4247
+ const [hovered, setHovered] = useState(false);
4248
+ return /* @__PURE__ */ jsx(
4249
+ "button",
4250
+ {
4251
+ onClick: onSelect,
4252
+ onMouseEnter: () => setHovered(true),
4253
+ onMouseLeave: () => setHovered(false),
4254
+ style: {
4255
+ display: "flex",
4256
+ alignItems: "center",
4257
+ gap: "8px",
4258
+ width: "100%",
4259
+ padding: "7px 8px",
4260
+ fontSize: "13px",
4261
+ fontWeight: 400,
4262
+ borderRadius: "6px",
4263
+ border: "none",
4264
+ background: hovered ? "#f9fafb" : "transparent",
4265
+ cursor: "pointer",
4266
+ color: item.danger ? "#ef4444" : "#111827",
4267
+ textAlign: "left",
4268
+ transition: "background 0.1s"
4269
+ },
4270
+ children: item.label
4382
4271
  }
4383
- return `${Math.round(h * 360)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
4384
- };
4385
- return /* @__PURE__ */ jsxs(Popover, { children: [
4386
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", className: "gap-2 h-8 text-xs", children: [
4387
- /* @__PURE__ */ jsx(Paintbrush, { className: "h-3.5 w-3.5" }),
4388
- "Primary"
4389
- ] }) }),
4390
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-64", align: "end", children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
4391
- /* @__PURE__ */ jsx(Label2, { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: "Primary Color" }),
4392
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-4 gap-2", children: COLOR_PRESETS.map((preset) => /* @__PURE__ */ jsxs(
4393
- "button",
4394
- {
4395
- type: "button",
4396
- onClick: () => applyColor(preset.hsl),
4397
- className: "group flex flex-col items-center gap-1",
4398
- title: preset.name,
4399
- children: [
4400
- /* @__PURE__ */ jsx(
4401
- "div",
4402
- {
4403
- className: "w-8 h-8 rounded-full border-2 transition-all shadow-sm",
4404
- style: {
4405
- backgroundColor: `hsl(${preset.hsl})`,
4406
- borderColor: value === preset.hsl ? "hsl(var(--foreground))" : "transparent"
4407
- }
4408
- }
4409
- ),
4410
- /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: preset.name })
4411
- ]
4412
- },
4413
- preset.name
4414
- )) }),
4415
- /* @__PURE__ */ jsxs("div", { className: "pt-2 border-t border-border", children: [
4416
- /* @__PURE__ */ jsx(Label2, { className: "text-xs text-muted-foreground mb-1.5 block", children: "Custom Color" }),
4417
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-center", children: [
4418
- /* @__PURE__ */ jsx(
4419
- "input",
4420
- {
4421
- type: "color",
4422
- value: customColor,
4423
- onChange: (e) => {
4424
- setCustomColor(e.target.value);
4425
- applyColor(hexToHsl(e.target.value));
4426
- },
4427
- className: "w-10 h-8 rounded border border-border cursor-pointer bg-background"
4428
- }
4429
- ),
4430
- /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground font-mono", children: customColor })
4431
- ] })
4432
- ] })
4433
- ] }) })
4434
- ] });
4272
+ );
4273
+ };
4274
+ var modalActionButtonStyle = {
4275
+ display: "inline-flex",
4276
+ alignItems: "center",
4277
+ padding: "6px 12px",
4278
+ fontSize: "13px",
4279
+ fontWeight: 500,
4280
+ borderRadius: "6px",
4281
+ border: "1px solid #d1d5db",
4282
+ background: "#ffffff",
4283
+ cursor: "pointer",
4284
+ color: "#374151",
4285
+ transition: "background 0.15s"
4286
+ };
4287
+ var codeScrollStyle = {
4288
+ height: "400px",
4289
+ overflowY: "auto",
4290
+ border: "1px solid #e5e7eb",
4291
+ borderRadius: "6px"
4292
+ };
4293
+ var preStyle = {
4294
+ padding: "16px",
4295
+ fontSize: "12px",
4296
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
4297
+ whiteSpace: "pre-wrap",
4298
+ margin: 0,
4299
+ color: "#111827"
4435
4300
  };
4436
4301
  var TopBar = ({
4437
4302
  isDarkMode,
@@ -4511,7 +4376,7 @@ var TopBar = ({
4511
4376
  }
4512
4377
  };
4513
4378
  if (slots.toolbar) {
4514
- return React10__default.createElement(slots.toolbar, {
4379
+ return React9__default.createElement(slots.toolbar, {
4515
4380
  onExport: getHtml,
4516
4381
  onPreview: getHtml,
4517
4382
  onClear: handleClearCanvas,
@@ -4524,72 +4389,64 @@ var TopBar = ({
4524
4389
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
4525
4390
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx("h1", { className: "text-sm font-semibold text-foreground", children: title }) }),
4526
4391
  /* @__PURE__ */ jsx("div", { className: "h-5 w-px bg-border" }),
4527
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
4528
- /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
4529
- Button,
4530
- {
4531
- variant: "outline",
4532
- size: "sm",
4533
- className: "gap-1.5 h-8 text-xs",
4534
- children: [
4535
- /* @__PURE__ */ jsx(LayoutTemplate, { className: "h-3.5 w-3.5" }),
4536
- "Templates"
4537
- ]
4538
- }
4539
- ) }),
4540
- /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "start", className: "w-56", children: [
4541
- /* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Quick Start Templates" }),
4542
- /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
4543
- templates.map((template) => /* @__PURE__ */ jsxs(
4544
- DropdownMenuItem,
4392
+ /* @__PURE__ */ jsx(
4393
+ Dropdown,
4394
+ {
4395
+ align: "start",
4396
+ label: "Quick Start Templates",
4397
+ trigger: /* @__PURE__ */ jsxs(
4398
+ Button,
4545
4399
  {
4546
- className: "gap-2",
4547
- onClick: () => handleLoadTemplate(template),
4400
+ variant: "outline",
4401
+ size: "sm",
4402
+ className: "gap-1.5 h-8 text-xs",
4548
4403
  children: [
4549
- template.icon && React10__default.createElement(template.icon, {
4550
- className: "h-4 w-4 text-muted-foreground"
4404
+ /* @__PURE__ */ jsx(LayoutTemplate, { className: "h-3.5 w-3.5" }),
4405
+ "Templates"
4406
+ ]
4407
+ }
4408
+ ),
4409
+ items: [
4410
+ ...templates.map((template) => ({
4411
+ key: template.id,
4412
+ label: /* @__PURE__ */ jsxs(React9__default.Fragment, { children: [
4413
+ template.icon && React9__default.createElement(template.icon, {
4414
+ style: {
4415
+ width: 14,
4416
+ height: 14,
4417
+ color: "#9ca3af",
4418
+ flexShrink: 0
4419
+ }
4551
4420
  }),
4552
4421
  /* @__PURE__ */ jsxs("div", { children: [
4553
- /* @__PURE__ */ jsx("div", { className: "font-medium", children: template.name }),
4554
- template.description && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: template.description })
4422
+ /* @__PURE__ */ jsx("div", { style: { fontWeight: 500, fontSize: "13px" }, children: template.name }),
4423
+ template.description && /* @__PURE__ */ jsx(
4424
+ "div",
4425
+ {
4426
+ style: {
4427
+ fontSize: "11px",
4428
+ color: "#9ca3af",
4429
+ marginTop: 1
4430
+ },
4431
+ children: template.description
4432
+ }
4433
+ )
4555
4434
  ] })
4556
- ]
4557
- },
4558
- template.id
4559
- )),
4560
- templates.length > 0 && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
4561
- /* @__PURE__ */ jsx(
4562
- DropdownMenuItem,
4435
+ ] }),
4436
+ onClick: () => handleLoadTemplate(template)
4437
+ })),
4438
+ ...templates.length > 0 ? [{ key: "sep-clear", separator: true }] : [],
4563
4439
  {
4440
+ key: "clear",
4441
+ label: "Clear Canvas",
4564
4442
  onClick: handleClearCanvas,
4565
- className: "text-destructive",
4566
- children: "Clear Canvas"
4443
+ danger: true
4567
4444
  }
4568
- )
4569
- ] })
4570
- ] })
4571
- ] }),
4572
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
4573
- /* @__PURE__ */ jsxs(
4574
- Button,
4575
- {
4576
- variant: "outline",
4577
- size: "sm",
4578
- onClick: onToggleDarkMode,
4579
- className: "gap-1.5 h-8 text-xs",
4580
- children: [
4581
- isDarkMode ? /* @__PURE__ */ jsx(Sun, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(Moon, { className: "h-3.5 w-3.5" }),
4582
- isDarkMode ? "Light" : "Dark"
4583
4445
  ]
4584
4446
  }
4585
- ),
4586
- /* @__PURE__ */ jsx(
4587
- ColorCustomizer,
4588
- {
4589
- value: primaryColor,
4590
- onColorChange: onPrimaryColorChange
4591
- }
4592
- ),
4447
+ )
4448
+ ] }),
4449
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
4593
4450
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 bg-muted rounded-md p-0.5", children: [
4594
4451
  /* @__PURE__ */ jsx(
4595
4452
  Button,
@@ -4643,57 +4500,126 @@ var TopBar = ({
4643
4500
  )
4644
4501
  ] })
4645
4502
  ] }),
4646
- /* @__PURE__ */ jsx(Dialog, { open: showCode, onOpenChange: setShowCode, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-4xl max-h-[80vh]", children: [
4647
- /* @__PURE__ */ jsxs(DialogHeader, { children: [
4648
- /* @__PURE__ */ jsx(DialogTitle, { children: "Export HTML" }),
4649
- /* @__PURE__ */ jsx(DialogDescription, { children: "Copy this HTML code to use in your email client or system." })
4650
- ] }),
4651
- slots.exportDialog ? React10__default.createElement(slots.exportDialog, {
4652
- html: htmlCode,
4653
- onClose: () => setShowCode(false)
4654
- }) : /* @__PURE__ */ jsxs(Fragment, { children: [
4655
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2 mb-2", children: [
4656
- /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: handleCopy, children: [
4657
- copied ? /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 mr-2" }) : /* @__PURE__ */ jsx(Copy, { className: "h-4 w-4 mr-2" }),
4658
- copied ? "Copied!" : "Copy"
4503
+ /* @__PURE__ */ jsx(
4504
+ Modal,
4505
+ {
4506
+ open: showCode,
4507
+ onClose: () => setShowCode(false),
4508
+ title: "Export HTML",
4509
+ description: "Copy this HTML code to use in your email client or system.",
4510
+ maxWidth: 896,
4511
+ maxHeight: "80vh",
4512
+ children: slots.exportDialog ? React9__default.createElement(slots.exportDialog, {
4513
+ html: htmlCode,
4514
+ onClose: () => setShowCode(false)
4515
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [
4516
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", marginBottom: "12px" }, children: [
4517
+ /* @__PURE__ */ jsxs(
4518
+ "button",
4519
+ {
4520
+ onClick: handleCopy,
4521
+ style: modalActionButtonStyle,
4522
+ onMouseEnter: (e) => e.currentTarget.style.background = "#f3f4f6",
4523
+ onMouseLeave: (e) => e.currentTarget.style.background = "#ffffff",
4524
+ children: [
4525
+ copied ? /* @__PURE__ */ jsx(Check, { size: 14, style: { marginRight: 6 } }) : /* @__PURE__ */ jsx(Copy, { size: 14, style: { marginRight: 6 } }),
4526
+ copied ? "Copied!" : "Copy"
4527
+ ]
4528
+ }
4529
+ ),
4530
+ /* @__PURE__ */ jsxs(
4531
+ "button",
4532
+ {
4533
+ onClick: handleDownload,
4534
+ style: modalActionButtonStyle,
4535
+ onMouseEnter: (e) => e.currentTarget.style.background = "#f3f4f6",
4536
+ onMouseLeave: (e) => e.currentTarget.style.background = "#ffffff",
4537
+ children: [
4538
+ /* @__PURE__ */ jsx(Download, { size: 14, style: { marginRight: 6 } }),
4539
+ "Download"
4540
+ ]
4541
+ }
4542
+ )
4659
4543
  ] }),
4660
- /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: handleDownload, children: [
4661
- /* @__PURE__ */ jsx(Download, { className: "h-4 w-4 mr-2" }),
4662
- " Download"
4663
- ] })
4664
- ] }),
4665
- /* @__PURE__ */ jsx(ScrollArea, { className: "h-[400px] border rounded-md", children: /* @__PURE__ */ jsx("pre", { className: "p-4 text-xs font-mono whitespace-pre-wrap", children: htmlCode }) })
4666
- ] })
4667
- ] }) }),
4668
- /* @__PURE__ */ jsx(Dialog, { open: showPreview, onOpenChange: setShowPreview, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-5xl max-h-[90vh]", children: [
4669
- /* @__PURE__ */ jsxs(DialogHeader, { children: [
4670
- /* @__PURE__ */ jsx(DialogTitle, { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx("span", { children: "Email Preview" }) }),
4671
- /* @__PURE__ */ jsx(DialogDescription, { children: "Preview how your email will look in email clients." })
4672
- ] }),
4673
- slots.previewDialog ? React10__default.createElement(slots.previewDialog, {
4674
- html: htmlCode,
4675
- onClose: () => setShowPreview(false)
4676
- }) : /* @__PURE__ */ jsx(ScrollArea, { className: "h-[600px]", children: /* @__PURE__ */ jsx(
4677
- "div",
4678
- {
4679
- className: `mx-auto transition-all duration-300 ${previewDevice === "mobile" ? "max-w-[375px]" : "max-w-full"}`,
4680
- children: /* @__PURE__ */ jsxs("div", { className: "border rounded-lg bg-muted/30 overflow-hidden", children: [
4681
- previewDevice === "mobile" && /* @__PURE__ */ jsx("div", { className: "h-6 bg-muted flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "w-16 h-1 bg-muted-foreground/30 rounded-full" }) }),
4682
- /* @__PURE__ */ jsx(
4683
- "iframe",
4544
+ /* @__PURE__ */ jsx("div", { style: codeScrollStyle, children: /* @__PURE__ */ jsx("pre", { style: preStyle, children: htmlCode }) })
4545
+ ] })
4546
+ }
4547
+ ),
4548
+ /* @__PURE__ */ jsx(
4549
+ Modal,
4550
+ {
4551
+ open: showPreview,
4552
+ onClose: () => setShowPreview(false),
4553
+ title: "Email Preview",
4554
+ description: "Preview how your email will look in email clients.",
4555
+ maxWidth: 1024,
4556
+ maxHeight: "90vh",
4557
+ children: slots.previewDialog ? React9__default.createElement(slots.previewDialog, {
4558
+ html: htmlCode,
4559
+ onClose: () => setShowPreview(false)
4560
+ }) : /* @__PURE__ */ jsx("div", { style: { overflowY: "auto", maxHeight: "600px" }, children: /* @__PURE__ */ jsx(
4561
+ "div",
4562
+ {
4563
+ style: {
4564
+ margin: "0 auto",
4565
+ transition: "max-width 0.3s",
4566
+ maxWidth: previewDevice === "mobile" ? "375px" : "100%"
4567
+ },
4568
+ children: /* @__PURE__ */ jsxs(
4569
+ "div",
4684
4570
  {
4685
- srcDoc: htmlCode,
4686
- className: "w-full min-h-[500px] bg-white",
4687
- title: "Email Preview",
4688
4571
  style: {
4689
- height: previewDevice === "mobile" ? "667px" : "600px"
4690
- }
4572
+ border: "1px solid #e5e7eb",
4573
+ borderRadius: "8px",
4574
+ background: "rgba(243,244,246,0.3)",
4575
+ overflow: "hidden"
4576
+ },
4577
+ children: [
4578
+ previewDevice === "mobile" && /* @__PURE__ */ jsx(
4579
+ "div",
4580
+ {
4581
+ style: {
4582
+ height: "24px",
4583
+ background: "#f3f4f6",
4584
+ display: "flex",
4585
+ alignItems: "center",
4586
+ justifyContent: "center"
4587
+ },
4588
+ children: /* @__PURE__ */ jsx(
4589
+ "div",
4590
+ {
4591
+ style: {
4592
+ width: "64px",
4593
+ height: "4px",
4594
+ background: "rgba(107,114,128,0.3)",
4595
+ borderRadius: "9999px"
4596
+ }
4597
+ }
4598
+ )
4599
+ }
4600
+ ),
4601
+ /* @__PURE__ */ jsx(
4602
+ "iframe",
4603
+ {
4604
+ srcDoc: htmlCode,
4605
+ title: "Email Preview",
4606
+ style: {
4607
+ width: "100%",
4608
+ minHeight: "500px",
4609
+ background: "#ffffff",
4610
+ border: "none",
4611
+ display: "block",
4612
+ height: previewDevice === "mobile" ? "667px" : "600px"
4613
+ }
4614
+ }
4615
+ )
4616
+ ]
4691
4617
  }
4692
4618
  )
4693
- ] })
4694
- }
4695
- ) })
4696
- ] }) })
4619
+ }
4620
+ ) })
4621
+ }
4622
+ )
4697
4623
  ] });
4698
4624
  };
4699
4625
  var LeftSidebar = ({ setActiveTab, activeTab }) => {
@@ -4745,7 +4671,7 @@ var LeftSidebar = ({ setActiveTab, activeTab }) => {
4745
4671
  }
4746
4672
  )
4747
4673
  ] }) }),
4748
- /* @__PURE__ */ jsx(TabsContent, { value: "components", className: "flex-1 mt-0 ", children: /* @__PURE__ */ jsx(ScrollArea, { className: "h-full max-h-[180vh] ", children: slots.toolbox ? React10__default.createElement(slots.toolbox, { components, categories }) : /* @__PURE__ */ jsx(Toolbox, {}) }) }),
4674
+ /* @__PURE__ */ jsx(TabsContent, { value: "components", className: "flex-1 mt-0 ", children: /* @__PURE__ */ jsx(ScrollArea, { className: "h-full max-h-[180vh] ", children: slots.toolbox ? React9__default.createElement(slots.toolbox, { components, categories }) : /* @__PURE__ */ jsx(Toolbox, {}) }) }),
4749
4675
  /* @__PURE__ */ jsx(TabsContent, { value: "properties", className: "flex-1 mt-0 ", children: /* @__PURE__ */ jsx("div", { className: "h-full", children: /* @__PURE__ */ jsx(SettingsPanel, {}) }) })
4750
4676
  ]
4751
4677
  }
@@ -4906,6 +4832,6 @@ var EmailEditor = ({
4906
4832
  );
4907
4833
  };
4908
4834
 
4909
- export { AVAILABLE_VARIABLES, Container, Countdown, DEFAULT_COMPONENTS, Divider, EditorProvider, EmailButton, EmailEditor, EmailFooter, EmailHeader, IconList, ImageBlock, InvoiceTable, Paper, PromoCode, RenderNode, SettingsPanel, SocialLinks, Spacer, Testimonial, TextBlock, Toolbox, TwoColumn, VariableText, VideoPlaceholder, buildResolver, generateEmailHtml, getCategories, useEditorConfig };
4835
+ export { AVAILABLE_VARIABLES, Container, Countdown, DEFAULT_COMPONENTS, Divider, EditorProvider, EmailButton, EmailEditor, EmailFooter, EmailHeader, IconList, ImageBlock, InvoiceTable, Paper, PromoCode, RenderNode, SettingsPanel, SocialLinks, Spacer, Testimonial, TextBlock, Toolbox, VariableText, VideoPlaceholder, buildResolver, generateEmailHtml, getCategories, useEditorConfig };
4910
4836
  //# sourceMappingURL=index.mjs.map
4911
4837
  //# sourceMappingURL=index.mjs.map