react-tailwind-email-editor 0.0.13 → 0.0.15

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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React10 = require('react');
3
+ var React9 = require('react');
4
4
  var core = require('@craftjs/core');
5
5
  var AccordionPrimitive = require('@radix-ui/react-accordion');
6
6
  var lucideReact = require('lucide-react');
@@ -11,10 +11,7 @@ var reactSlot = require('@radix-ui/react-slot');
11
11
  var classVarianceAuthority = require('class-variance-authority');
12
12
  var ScrollAreaPrimitive = require('@radix-ui/react-scroll-area');
13
13
  var TabsPrimitive = require('@radix-ui/react-tabs');
14
- var DialogPrimitive = require('@radix-ui/react-dialog');
15
- var DropdownMenuPrimitive = require('@radix-ui/react-dropdown-menu');
16
- var PopoverPrimitive = require('@radix-ui/react-popover');
17
- var LabelPrimitive = require('@radix-ui/react-label');
14
+ var reactDom = require('react-dom');
18
15
 
19
16
  function _interopNamespace(e) {
20
17
  if (e && e.__esModule) return e;
@@ -34,21 +31,17 @@ function _interopNamespace(e) {
34
31
  return Object.freeze(n);
35
32
  }
36
33
 
37
- var React10__namespace = /*#__PURE__*/_interopNamespace(React10);
34
+ var React9__namespace = /*#__PURE__*/_interopNamespace(React9);
38
35
  var AccordionPrimitive__namespace = /*#__PURE__*/_interopNamespace(AccordionPrimitive);
39
36
  var ScrollAreaPrimitive__namespace = /*#__PURE__*/_interopNamespace(ScrollAreaPrimitive);
40
37
  var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
41
- var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
42
- var DropdownMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(DropdownMenuPrimitive);
43
- var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
44
- var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
45
38
 
46
39
  // src/components/editor/EmailEditor.tsx
47
40
  function cn(...inputs) {
48
41
  return tailwindMerge.twMerge(clsx.clsx(inputs));
49
42
  }
50
43
  var Accordion = AccordionPrimitive__namespace.Root;
51
- var AccordionItem = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
44
+ var AccordionItem = React9__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
52
45
  AccordionPrimitive__namespace.Item,
53
46
  {
54
47
  ref,
@@ -57,7 +50,7 @@ var AccordionItem = React10__namespace.forwardRef(({ className, ...props }, ref)
57
50
  }
58
51
  ));
59
52
  AccordionItem.displayName = "AccordionItem";
60
- var AccordionTrigger = React10__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(AccordionPrimitive__namespace.Header, { className: "flex", children: /* @__PURE__ */ jsxRuntime.jsxs(
53
+ var AccordionTrigger = React9__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(AccordionPrimitive__namespace.Header, { className: "flex", children: /* @__PURE__ */ jsxRuntime.jsxs(
61
54
  AccordionPrimitive__namespace.Trigger,
62
55
  {
63
56
  ref,
@@ -73,7 +66,7 @@ var AccordionTrigger = React10__namespace.forwardRef(({ className, children, ...
73
66
  }
74
67
  ) }));
75
68
  AccordionTrigger.displayName = AccordionPrimitive__namespace.Trigger.displayName;
76
- var AccordionContent = React10__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
69
+ var AccordionContent = React9__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
77
70
  AccordionPrimitive__namespace.Content,
78
71
  {
79
72
  ref,
@@ -88,7 +81,7 @@ var defaultTheme = {
88
81
  paperMinHeight: 800,
89
82
  paperBackground: "#ffffff"
90
83
  };
91
- var EditorContext = React10.createContext({
84
+ var EditorContext = React9.createContext({
92
85
  components: {},
93
86
  theme: defaultTheme,
94
87
  slots: {},
@@ -100,16 +93,16 @@ var EditorContext = React10.createContext({
100
93
  showToolbox: true,
101
94
  showSettingsPanel: true
102
95
  });
103
- var useEditorConfig = () => React10.useContext(EditorContext);
96
+ var useEditorConfig = () => React9.useContext(EditorContext);
104
97
  var EditorProvider = ({
105
98
  children,
106
99
  value
107
100
  }) => {
108
- const mergedTheme = React10.useMemo(
101
+ const mergedTheme = React9.useMemo(
109
102
  () => ({ ...defaultTheme, ...value.theme }),
110
103
  [value.theme]
111
104
  );
112
- const ctx = React10.useMemo(
105
+ const ctx = React9.useMemo(
113
106
  () => ({ ...value, theme: mergedTheme }),
114
107
  [value, mergedTheme]
115
108
  );
@@ -138,7 +131,7 @@ var ToolboxItem = ({ name, config }) => {
138
131
  };
139
132
  var Toolbox = () => {
140
133
  const { components } = useEditorConfig();
141
- const grouped = React10__namespace.default.useMemo(() => {
134
+ const grouped = React9__namespace.default.useMemo(() => {
142
135
  const map = {};
143
136
  for (const [name, config] of Object.entries(components)) {
144
137
  const cat = config.category || "Other";
@@ -195,7 +188,7 @@ var buttonVariants = classVarianceAuthority.cva(
195
188
  }
196
189
  }
197
190
  );
198
- var Button = React10__namespace.forwardRef(
191
+ var Button = React9__namespace.forwardRef(
199
192
  ({ className, variant, size, asChild = false, ...props }, ref) => {
200
193
  const Comp = asChild ? reactSlot.Slot : "button";
201
194
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -209,7 +202,7 @@ var Button = React10__namespace.forwardRef(
209
202
  }
210
203
  );
211
204
  Button.displayName = "Button";
212
- var ScrollArea = React10__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
205
+ var ScrollArea = React9__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
213
206
  ScrollAreaPrimitive__namespace.Root,
214
207
  {
215
208
  ref,
@@ -223,7 +216,7 @@ var ScrollArea = React10__namespace.forwardRef(({ className, children, ...props
223
216
  }
224
217
  ));
225
218
  ScrollArea.displayName = ScrollAreaPrimitive__namespace.Root.displayName;
226
- var ScrollBar = React10__namespace.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
219
+ var ScrollBar = React9__namespace.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
227
220
  ScrollAreaPrimitive__namespace.ScrollAreaScrollbar,
228
221
  {
229
222
  ref,
@@ -301,7 +294,7 @@ var SettingsPanel = () => {
301
294
  }
302
295
  };
303
296
  if (slots.settingsPanel && selected) {
304
- return React10__namespace.default.createElement(slots.settingsPanel, {
297
+ return React9__namespace.default.createElement(slots.settingsPanel, {
305
298
  selectedId: selected.id,
306
299
  selectedName: selected.displayName || selected.name,
307
300
  //@ts-ignore
@@ -314,7 +307,7 @@ var SettingsPanel = () => {
314
307
  }
315
308
  if (!selected) {
316
309
  if (slots.settingsEmptyState) {
317
- return React10__namespace.default.createElement(slots.settingsEmptyState);
310
+ return React9__namespace.default.createElement(slots.settingsEmptyState);
318
311
  }
319
312
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 text-center", children: [
320
313
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 mx-auto mb-4 rounded-full bg-muted flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Layers, { className: "h-8 w-8 text-muted-foreground" }) }),
@@ -389,7 +382,7 @@ var SettingsPanel = () => {
389
382
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings2, { className: "h-4 w-4 text-muted-foreground" }),
390
383
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Properties" })
391
384
  ] }) }),
392
- /* @__PURE__ */ jsxRuntime.jsx(AccordionContent, { className: "pb-4", children: React10__namespace.default.createElement(selected.settings) })
385
+ /* @__PURE__ */ jsxRuntime.jsx(AccordionContent, { className: "pb-4", children: React9__namespace.default.createElement(selected.settings) })
393
386
  ] }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center text-muted-foreground text-sm py-8", children: [
394
387
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Paintbrush, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
395
388
  /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No editable properties" })
@@ -469,7 +462,7 @@ var RenderNode = ({ render }) => {
469
462
  deletable: query.node(node.id).isDeletable(),
470
463
  parent: node.data.parent
471
464
  }));
472
- React10.useEffect(() => {
465
+ React9.useEffect(() => {
473
466
  if (dom) {
474
467
  if (isActive || isHover) {
475
468
  dom.classList.add("component-selected");
@@ -478,19 +471,19 @@ var RenderNode = ({ render }) => {
478
471
  }
479
472
  }
480
473
  }, [dom, isActive, isHover]);
481
- const getPos = React10.useCallback((dom2) => {
474
+ const getPos = React9.useCallback((dom2) => {
482
475
  const { top, left, bottom } = dom2 ? dom2.getBoundingClientRect() : { top: 0, left: 0, bottom: 0 };
483
476
  return {
484
477
  top: `${top > 0 ? top : bottom}px`,
485
478
  left: `${left}px`
486
479
  };
487
480
  }, []);
488
- const scroll = React10.useCallback(() => {
481
+ const scroll = React9.useCallback(() => {
489
482
  const currentDOM = dom;
490
483
  if (!currentDOM) return;
491
484
  const { top, left } = getPos(currentDOM);
492
485
  }, [dom, getPos]);
493
- React10.useEffect(() => {
486
+ React9.useEffect(() => {
494
487
  var _a;
495
488
  (_a = document.querySelector(".craftjs-renderer")) == null ? void 0 : _a.addEventListener("scroll", scroll);
496
489
  return () => {
@@ -2021,126 +2014,6 @@ SocialLinks.craft = {
2021
2014
  settings: SocialLinksSettings
2022
2015
  }
2023
2016
  };
2024
- var TwoColumn = ({
2025
- leftWidth = 50,
2026
- gap = 20,
2027
- padding = 10,
2028
- backgroundColor = "#ffffff"
2029
- }) => {
2030
- const { connectors: { connect, drag } } = core.useNode();
2031
- return /* @__PURE__ */ jsxRuntime.jsxs(
2032
- "div",
2033
- {
2034
- ref: (ref) => connect(drag(ref)),
2035
- style: {
2036
- display: "flex",
2037
- gap: `${gap}px`,
2038
- padding: `${padding}px`,
2039
- backgroundColor,
2040
- width: "100%"
2041
- },
2042
- children: [
2043
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: `${leftWidth}%` }, children: /* @__PURE__ */ jsxRuntime.jsx(core.Element, { id: "left-column", is: Container, canvas: true, background: "#f9f9f9", padding: 10 }) }),
2044
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: `${100 - leftWidth}%` }, children: /* @__PURE__ */ jsxRuntime.jsx(core.Element, { id: "right-column", is: Container, canvas: true, background: "#f9f9f9", padding: 10 }) })
2045
- ]
2046
- }
2047
- );
2048
- };
2049
- var TwoColumnSettings = () => {
2050
- const { actions: { setProp }, leftWidth, gap, padding, backgroundColor } = core.useNode((node) => ({
2051
- leftWidth: node.data.props.leftWidth,
2052
- gap: node.data.props.gap,
2053
- padding: node.data.props.padding,
2054
- backgroundColor: node.data.props.backgroundColor
2055
- }));
2056
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
2057
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2058
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium mb-1", children: "Left Column Width" }),
2059
- /* @__PURE__ */ jsxRuntime.jsx(
2060
- "input",
2061
- {
2062
- type: "range",
2063
- min: 20,
2064
- max: 80,
2065
- value: leftWidth || 50,
2066
- onChange: (e) => setProp((props) => props.leftWidth = parseInt(e.target.value)),
2067
- className: "w-full"
2068
- }
2069
- ),
2070
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between text-sm text-muted-foreground", children: [
2071
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
2072
- "Left: ",
2073
- leftWidth,
2074
- "%"
2075
- ] }),
2076
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
2077
- "Right: ",
2078
- 100 - (leftWidth || 50),
2079
- "%"
2080
- ] })
2081
- ] })
2082
- ] }),
2083
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2084
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium mb-1", children: "Gap" }),
2085
- /* @__PURE__ */ jsxRuntime.jsx(
2086
- "input",
2087
- {
2088
- type: "range",
2089
- min: 0,
2090
- max: 40,
2091
- value: gap || 20,
2092
- onChange: (e) => setProp((props) => props.gap = parseInt(e.target.value)),
2093
- className: "w-full"
2094
- }
2095
- ),
2096
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground", children: [
2097
- gap,
2098
- "px"
2099
- ] })
2100
- ] }),
2101
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2102
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium mb-1", children: "Padding" }),
2103
- /* @__PURE__ */ jsxRuntime.jsx(
2104
- "input",
2105
- {
2106
- type: "range",
2107
- min: 0,
2108
- max: 40,
2109
- value: padding || 10,
2110
- onChange: (e) => setProp((props) => props.padding = parseInt(e.target.value)),
2111
- className: "w-full"
2112
- }
2113
- ),
2114
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground", children: [
2115
- padding,
2116
- "px"
2117
- ] })
2118
- ] }),
2119
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2120
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium mb-1", children: "Background Color" }),
2121
- /* @__PURE__ */ jsxRuntime.jsx(
2122
- "input",
2123
- {
2124
- type: "color",
2125
- value: backgroundColor || "#ffffff",
2126
- onChange: (e) => setProp((props) => props.backgroundColor = e.target.value),
2127
- className: "w-full h-10 rounded border cursor-pointer"
2128
- }
2129
- )
2130
- ] })
2131
- ] });
2132
- };
2133
- TwoColumn.craft = {
2134
- props: {
2135
- leftWidth: 50,
2136
- gap: 20,
2137
- padding: 10,
2138
- backgroundColor: "#ffffff"
2139
- },
2140
- related: {
2141
- settings: TwoColumnSettings
2142
- }
2143
- };
2144
2017
  var Countdown = ({
2145
2018
  title = "Sale Ends In",
2146
2019
  days = 3,
@@ -3671,13 +3544,6 @@ var DEFAULT_COMPONENTS = {
3671
3544
  category: "Layout",
3672
3545
  createElement: () => /* @__PURE__ */ jsxRuntime.jsx(core.Element, { is: Container, canvas: true })
3673
3546
  },
3674
- TwoColumn: {
3675
- component: TwoColumn,
3676
- label: "Two Columns",
3677
- description: "Side-by-side layout",
3678
- icon: lucideReact.Columns,
3679
- category: "Layout"
3680
- },
3681
3547
  Spacer: {
3682
3548
  component: Spacer,
3683
3549
  label: "Spacer",
@@ -4122,7 +3988,7 @@ ${childrenHtml}
4122
3988
  return renderNode("ROOT");
4123
3989
  };
4124
3990
  var Tabs = TabsPrimitive__namespace.Root;
4125
- var TabsList = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
3991
+ var TabsList = React9__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4126
3992
  TabsPrimitive__namespace.List,
4127
3993
  {
4128
3994
  ref,
@@ -4134,7 +4000,7 @@ var TabsList = React10__namespace.forwardRef(({ className, ...props }, ref) => /
4134
4000
  }
4135
4001
  ));
4136
4002
  TabsList.displayName = TabsPrimitive__namespace.List.displayName;
4137
- var TabsTrigger = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4003
+ var TabsTrigger = React9__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4138
4004
  TabsPrimitive__namespace.Trigger,
4139
4005
  {
4140
4006
  ref,
@@ -4146,7 +4012,7 @@ var TabsTrigger = React10__namespace.forwardRef(({ className, ...props }, ref) =
4146
4012
  }
4147
4013
  ));
4148
4014
  TabsTrigger.displayName = TabsPrimitive__namespace.Trigger.displayName;
4149
- var TabsContent = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4015
+ var TabsContent = React9__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4150
4016
  TabsPrimitive__namespace.Content,
4151
4017
  {
4152
4018
  ref,
@@ -4158,308 +4024,303 @@ var TabsContent = React10__namespace.forwardRef(({ className, ...props }, ref) =
4158
4024
  }
4159
4025
  ));
4160
4026
  TabsContent.displayName = TabsPrimitive__namespace.Content.displayName;
4161
- var Dialog = DialogPrimitive__namespace.Root;
4162
- var DialogPortal = DialogPrimitive__namespace.Portal;
4163
- var DialogOverlay = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4164
- DialogPrimitive__namespace.Overlay,
4165
- {
4166
- ref,
4167
- className: cn(
4168
- "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",
4169
- className
4027
+ var Modal = ({
4028
+ open,
4029
+ onClose,
4030
+ title,
4031
+ description,
4032
+ children,
4033
+ maxWidth = 672,
4034
+ maxHeight = "85vh"
4035
+ }) => {
4036
+ const panelRef = React9__namespace.default.useRef(null);
4037
+ const [closeHovered, setCloseHovered] = React9__namespace.default.useState(false);
4038
+ React9.useEffect(() => {
4039
+ if (!open) return;
4040
+ const handler = (e) => {
4041
+ if (e.key === "Escape") onClose();
4042
+ };
4043
+ document.addEventListener("keydown", handler);
4044
+ return () => document.removeEventListener("keydown", handler);
4045
+ }, [open, onClose]);
4046
+ React9.useEffect(() => {
4047
+ if (open) {
4048
+ const prev = document.body.style.overflow;
4049
+ document.body.style.overflow = "hidden";
4050
+ return () => {
4051
+ document.body.style.overflow = prev;
4052
+ };
4053
+ }
4054
+ }, [open]);
4055
+ React9.useEffect(() => {
4056
+ if (open && panelRef.current) panelRef.current.focus();
4057
+ }, [open]);
4058
+ if (!open) return null;
4059
+ return reactDom.createPortal(
4060
+ /* @__PURE__ */ jsxRuntime.jsx(
4061
+ "div",
4062
+ {
4063
+ role: "dialog",
4064
+ "aria-modal": "true",
4065
+ "aria-labelledby": title ? "modal-title" : void 0,
4066
+ "aria-describedby": description ? "modal-desc" : void 0,
4067
+ onMouseDown: (e) => {
4068
+ if (e.target === e.currentTarget) onClose();
4069
+ },
4070
+ style: {
4071
+ position: "fixed",
4072
+ inset: 0,
4073
+ zIndex: 9999,
4074
+ display: "flex",
4075
+ alignItems: "center",
4076
+ justifyContent: "center",
4077
+ backgroundColor: "rgba(0,0,0,0.5)",
4078
+ padding: "16px"
4079
+ },
4080
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
4081
+ "div",
4082
+ {
4083
+ ref: panelRef,
4084
+ tabIndex: -1,
4085
+ style: {
4086
+ position: "relative",
4087
+ backgroundColor: "#ffffff",
4088
+ borderRadius: "12px",
4089
+ boxShadow: "0 20px 60px rgba(0,0,0,0.2), 0 4px 16px rgba(0,0,0,0.12)",
4090
+ display: "flex",
4091
+ flexDirection: "column",
4092
+ width: "100%",
4093
+ maxWidth: `${maxWidth}px`,
4094
+ maxHeight,
4095
+ overflowY: "auto",
4096
+ outline: "none"
4097
+ },
4098
+ children: [
4099
+ /* @__PURE__ */ jsxRuntime.jsx(
4100
+ "button",
4101
+ {
4102
+ onClick: onClose,
4103
+ "aria-label": "Close modal",
4104
+ onMouseEnter: () => setCloseHovered(true),
4105
+ onMouseLeave: () => setCloseHovered(false),
4106
+ style: {
4107
+ position: "absolute",
4108
+ top: "14px",
4109
+ right: "14px",
4110
+ width: "32px",
4111
+ height: "32px",
4112
+ borderRadius: "8px",
4113
+ border: "none",
4114
+ background: closeHovered ? "#f3f4f6" : "transparent",
4115
+ cursor: "pointer",
4116
+ display: "flex",
4117
+ alignItems: "center",
4118
+ justifyContent: "center",
4119
+ color: closeHovered ? "#111827" : "#6b7280",
4120
+ fontSize: "18px",
4121
+ lineHeight: 1,
4122
+ padding: 0,
4123
+ flexShrink: 0,
4124
+ transition: "background 0.15s, color 0.15s"
4125
+ },
4126
+ children: "\u2715"
4127
+ }
4128
+ ),
4129
+ (title || description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "20px 24px 0 24px", flexShrink: 0 }, children: [
4130
+ title && /* @__PURE__ */ jsxRuntime.jsx(
4131
+ "h2",
4132
+ {
4133
+ id: "modal-title",
4134
+ style: {
4135
+ margin: 0,
4136
+ fontSize: "18px",
4137
+ fontWeight: 600,
4138
+ lineHeight: "1.4",
4139
+ color: "#111827"
4140
+ },
4141
+ children: title
4142
+ }
4143
+ ),
4144
+ description && /* @__PURE__ */ jsxRuntime.jsx(
4145
+ "p",
4146
+ {
4147
+ id: "modal-desc",
4148
+ style: {
4149
+ margin: "6px 0 0 0",
4150
+ fontSize: "14px",
4151
+ lineHeight: "1.5",
4152
+ color: "#6b7280"
4153
+ },
4154
+ children: description
4155
+ }
4156
+ )
4157
+ ] }),
4158
+ /* @__PURE__ */ jsxRuntime.jsx(
4159
+ "div",
4160
+ {
4161
+ style: { padding: "16px 24px 24px 24px", overflowY: "auto", flex: 1 },
4162
+ children
4163
+ }
4164
+ )
4165
+ ]
4166
+ }
4167
+ )
4168
+ }
4170
4169
  ),
4171
- ...props
4172
- }
4173
- ));
4174
- DialogOverlay.displayName = DialogPrimitive__namespace.Overlay.displayName;
4175
- var DialogContent = React10__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [
4176
- /* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
4177
- /* @__PURE__ */ jsxRuntime.jsxs(
4178
- DialogPrimitive__namespace.Content,
4170
+ document.body
4171
+ );
4172
+ };
4173
+ var Dropdown = ({
4174
+ trigger,
4175
+ label,
4176
+ items,
4177
+ align = "start"
4178
+ }) => {
4179
+ const [open, setOpen] = React9.useState(false);
4180
+ const containerRef = React9__namespace.default.useRef(null);
4181
+ React9.useEffect(() => {
4182
+ if (!open) return;
4183
+ const handler = (e) => {
4184
+ var _a;
4185
+ if (!((_a = containerRef.current) == null ? void 0 : _a.contains(e.target))) setOpen(false);
4186
+ };
4187
+ document.addEventListener("mousedown", handler);
4188
+ return () => document.removeEventListener("mousedown", handler);
4189
+ }, [open]);
4190
+ React9.useEffect(() => {
4191
+ if (!open) return;
4192
+ const handler = (e) => {
4193
+ if (e.key === "Escape") setOpen(false);
4194
+ };
4195
+ document.addEventListener("keydown", handler);
4196
+ return () => document.removeEventListener("keydown", handler);
4197
+ }, [open]);
4198
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4199
+ "div",
4179
4200
  {
4180
- ref,
4181
- className: cn(
4182
- "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",
4183
- className
4184
- ),
4185
- ...props,
4201
+ ref: containerRef,
4202
+ style: { position: "relative", display: "inline-block" },
4186
4203
  children: [
4187
- children,
4188
- /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.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: [
4189
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }),
4190
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
4191
- ] })
4204
+ /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: () => setOpen((v) => !v), children: trigger }),
4205
+ open && /* @__PURE__ */ jsxRuntime.jsxs(
4206
+ "div",
4207
+ {
4208
+ style: {
4209
+ position: "absolute",
4210
+ top: "calc(100% + 6px)",
4211
+ ...align === "end" ? { right: 0 } : { left: 0 },
4212
+ zIndex: 9998,
4213
+ minWidth: "224px",
4214
+ backgroundColor: "#ffffff",
4215
+ border: "1px solid #e5e7eb",
4216
+ borderRadius: "8px",
4217
+ boxShadow: "0 8px 24px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.08)",
4218
+ padding: "4px",
4219
+ outline: "none"
4220
+ },
4221
+ children: [
4222
+ label && /* @__PURE__ */ jsxRuntime.jsx(
4223
+ "div",
4224
+ {
4225
+ style: {
4226
+ padding: "6px 8px 4px 8px",
4227
+ fontSize: "11px",
4228
+ fontWeight: 600,
4229
+ color: "#9ca3af",
4230
+ textTransform: "uppercase",
4231
+ letterSpacing: "0.06em"
4232
+ },
4233
+ children: label
4234
+ }
4235
+ ),
4236
+ items.map((entry) => {
4237
+ if ("separator" in entry && entry.separator) {
4238
+ return /* @__PURE__ */ jsxRuntime.jsx(
4239
+ "div",
4240
+ {
4241
+ style: {
4242
+ height: "1px",
4243
+ backgroundColor: "#f3f4f6",
4244
+ margin: "4px 0"
4245
+ }
4246
+ },
4247
+ entry.key
4248
+ );
4249
+ }
4250
+ const item = entry;
4251
+ return /* @__PURE__ */ jsxRuntime.jsx(
4252
+ DropdownItemRow,
4253
+ {
4254
+ item,
4255
+ onSelect: () => {
4256
+ item.onClick();
4257
+ setOpen(false);
4258
+ }
4259
+ },
4260
+ item.key
4261
+ );
4262
+ })
4263
+ ]
4264
+ }
4265
+ )
4192
4266
  ]
4193
4267
  }
4194
- )
4195
- ] }));
4196
- DialogContent.displayName = DialogPrimitive__namespace.Content.displayName;
4197
- var DialogHeader = ({
4198
- className,
4199
- ...props
4200
- }) => /* @__PURE__ */ jsxRuntime.jsx(
4201
- "div",
4202
- {
4203
- className: cn(
4204
- "flex flex-col space-y-1.5 text-center sm:text-left",
4205
- className
4206
- ),
4207
- ...props
4208
- }
4209
- );
4210
- DialogHeader.displayName = "DialogHeader";
4211
- var DialogTitle = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4212
- DialogPrimitive__namespace.Title,
4213
- {
4214
- ref,
4215
- className: cn(
4216
- "text-lg font-semibold leading-none tracking-tight",
4217
- className
4218
- ),
4219
- ...props
4220
- }
4221
- ));
4222
- DialogTitle.displayName = DialogPrimitive__namespace.Title.displayName;
4223
- var DialogDescription = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4224
- DialogPrimitive__namespace.Description,
4225
- {
4226
- ref,
4227
- className: cn("text-sm text-muted-foreground", className),
4228
- ...props
4229
- }
4230
- ));
4231
- DialogDescription.displayName = DialogPrimitive__namespace.Description.displayName;
4232
- var DropdownMenu = DropdownMenuPrimitive__namespace.Root;
4233
- var DropdownMenuTrigger = DropdownMenuPrimitive__namespace.Trigger;
4234
- var DropdownMenuSubTrigger = React10__namespace.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
4235
- DropdownMenuPrimitive__namespace.SubTrigger,
4236
- {
4237
- ref,
4238
- className: cn(
4239
- "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",
4240
- inset && "pl-8",
4241
- className
4242
- ),
4243
- ...props,
4244
- children: [
4245
- children,
4246
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "ml-auto h-4 w-4" })
4247
- ]
4248
- }
4249
- ));
4250
- DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive__namespace.SubTrigger.displayName;
4251
- var DropdownMenuSubContent = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4252
- DropdownMenuPrimitive__namespace.SubContent,
4253
- {
4254
- ref,
4255
- className: cn(
4256
- "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",
4257
- className
4258
- ),
4259
- ...props
4260
- }
4261
- ));
4262
- DropdownMenuSubContent.displayName = DropdownMenuPrimitive__namespace.SubContent.displayName;
4263
- var DropdownMenuContent = React10__namespace.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
4264
- DropdownMenuPrimitive__namespace.Content,
4265
- {
4266
- ref,
4267
- sideOffset,
4268
- className: cn(
4269
- "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",
4270
- className
4271
- ),
4272
- ...props
4273
- }
4274
- ) }));
4275
- DropdownMenuContent.displayName = DropdownMenuPrimitive__namespace.Content.displayName;
4276
- var DropdownMenuItem = React10__namespace.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4277
- DropdownMenuPrimitive__namespace.Item,
4278
- {
4279
- ref,
4280
- className: cn(
4281
- "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",
4282
- inset && "pl-8",
4283
- className
4284
- ),
4285
- ...props
4286
- }
4287
- ));
4288
- DropdownMenuItem.displayName = DropdownMenuPrimitive__namespace.Item.displayName;
4289
- var DropdownMenuCheckboxItem = React10__namespace.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
4290
- DropdownMenuPrimitive__namespace.CheckboxItem,
4291
- {
4292
- ref,
4293
- className: cn(
4294
- "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",
4295
- className
4296
- ),
4297
- checked,
4298
- ...props,
4299
- children: [
4300
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4" }) }) }),
4301
- children
4302
- ]
4303
- }
4304
- ));
4305
- DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive__namespace.CheckboxItem.displayName;
4306
- var DropdownMenuRadioItem = React10__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
4307
- DropdownMenuPrimitive__namespace.RadioItem,
4308
- {
4309
- ref,
4310
- className: cn(
4311
- "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",
4312
- className
4313
- ),
4314
- ...props,
4315
- children: [
4316
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Circle, { className: "h-2 w-2 fill-current" }) }) }),
4317
- children
4318
- ]
4319
- }
4320
- ));
4321
- DropdownMenuRadioItem.displayName = DropdownMenuPrimitive__namespace.RadioItem.displayName;
4322
- var DropdownMenuLabel = React10__namespace.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4323
- DropdownMenuPrimitive__namespace.Label,
4324
- {
4325
- ref,
4326
- className: cn(
4327
- "px-2 py-1.5 text-sm font-semibold",
4328
- inset && "pl-8",
4329
- className
4330
- ),
4331
- ...props
4332
- }
4333
- ));
4334
- DropdownMenuLabel.displayName = DropdownMenuPrimitive__namespace.Label.displayName;
4335
- var DropdownMenuSeparator = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4336
- DropdownMenuPrimitive__namespace.Separator,
4337
- {
4338
- ref,
4339
- className: cn("-mx-1 my-1 h-px bg-muted", className),
4340
- ...props
4341
- }
4342
- ));
4343
- DropdownMenuSeparator.displayName = DropdownMenuPrimitive__namespace.Separator.displayName;
4344
- var Popover = PopoverPrimitive__namespace.Root;
4345
- var PopoverTrigger = PopoverPrimitive__namespace.Trigger;
4346
- var PopoverContent = React10__namespace.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
4347
- PopoverPrimitive__namespace.Content,
4348
- {
4349
- ref,
4350
- align,
4351
- sideOffset,
4352
- className: cn(
4353
- "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",
4354
- className
4355
- ),
4356
- ...props
4357
- }
4358
- ) }));
4359
- PopoverContent.displayName = PopoverPrimitive__namespace.Content.displayName;
4360
- var labelVariants = classVarianceAuthority.cva(
4361
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
4362
- );
4363
- var Label2 = React10__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
4364
- LabelPrimitive__namespace.Root,
4365
- {
4366
- ref,
4367
- className: cn(labelVariants(), className),
4368
- ...props
4369
- }
4370
- ));
4371
- Label2.displayName = LabelPrimitive__namespace.Root.displayName;
4372
- var COLOR_PRESETS = [
4373
- { name: "Blue", hsl: "222.2 47.4% 11.2%" },
4374
- { name: "Indigo", hsl: "243 75% 59%" },
4375
- { name: "Emerald", hsl: "160 84% 39%" },
4376
- { name: "Rose", hsl: "346 77% 50%" },
4377
- { name: "Amber", hsl: "32 95% 44%" },
4378
- { name: "Violet", hsl: "263 70% 50%" },
4379
- { name: "Cyan", hsl: "192 91% 36%" },
4380
- { name: "Slate", hsl: "215 20% 35%" }
4381
- ];
4382
- var ColorCustomizer = ({ value, onColorChange }) => {
4383
- const [customColor, setCustomColor] = React10.useState("#1e293b");
4384
- const applyColor = (hsl) => {
4385
- onColorChange(hsl);
4386
- };
4387
- const hexToHsl = (hex) => {
4388
- const r = parseInt(hex.slice(1, 3), 16) / 255;
4389
- const g = parseInt(hex.slice(3, 5), 16) / 255;
4390
- const b = parseInt(hex.slice(5, 7), 16) / 255;
4391
- const max = Math.max(r, g, b);
4392
- const min = Math.min(r, g, b);
4393
- let h = 0;
4394
- let s = 0;
4395
- const l = (max + min) / 2;
4396
- if (max !== min) {
4397
- const d = max - min;
4398
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
4399
- switch (max) {
4400
- case r:
4401
- h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
4402
- break;
4403
- case g:
4404
- h = ((b - r) / d + 2) / 6;
4405
- break;
4406
- case b:
4407
- h = ((r - g) / d + 4) / 6;
4408
- break;
4409
- }
4268
+ );
4269
+ };
4270
+ var DropdownItemRow = ({ item, onSelect }) => {
4271
+ const [hovered, setHovered] = React9.useState(false);
4272
+ return /* @__PURE__ */ jsxRuntime.jsx(
4273
+ "button",
4274
+ {
4275
+ onClick: onSelect,
4276
+ onMouseEnter: () => setHovered(true),
4277
+ onMouseLeave: () => setHovered(false),
4278
+ style: {
4279
+ display: "flex",
4280
+ alignItems: "center",
4281
+ gap: "8px",
4282
+ width: "100%",
4283
+ padding: "7px 8px",
4284
+ fontSize: "13px",
4285
+ fontWeight: 400,
4286
+ borderRadius: "6px",
4287
+ border: "none",
4288
+ background: hovered ? "#f9fafb" : "transparent",
4289
+ cursor: "pointer",
4290
+ color: item.danger ? "#ef4444" : "#111827",
4291
+ textAlign: "left",
4292
+ transition: "background 0.1s"
4293
+ },
4294
+ children: item.label
4410
4295
  }
4411
- return `${Math.round(h * 360)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
4412
- };
4413
- return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { children: [
4414
- /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", className: "gap-2 h-8 text-xs", children: [
4415
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Paintbrush, { className: "h-3.5 w-3.5" }),
4416
- "Primary"
4417
- ] }) }),
4418
- /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-64", align: "end", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
4419
- /* @__PURE__ */ jsxRuntime.jsx(Label2, { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: "Primary Color" }),
4420
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-4 gap-2", children: COLOR_PRESETS.map((preset) => /* @__PURE__ */ jsxRuntime.jsxs(
4421
- "button",
4422
- {
4423
- type: "button",
4424
- onClick: () => applyColor(preset.hsl),
4425
- className: "group flex flex-col items-center gap-1",
4426
- title: preset.name,
4427
- children: [
4428
- /* @__PURE__ */ jsxRuntime.jsx(
4429
- "div",
4430
- {
4431
- className: "w-8 h-8 rounded-full border-2 transition-all shadow-sm",
4432
- style: {
4433
- backgroundColor: `hsl(${preset.hsl})`,
4434
- borderColor: value === preset.hsl ? "hsl(var(--foreground))" : "transparent"
4435
- }
4436
- }
4437
- ),
4438
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: preset.name })
4439
- ]
4440
- },
4441
- preset.name
4442
- )) }),
4443
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-2 border-t border-border", children: [
4444
- /* @__PURE__ */ jsxRuntime.jsx(Label2, { className: "text-xs text-muted-foreground mb-1.5 block", children: "Custom Color" }),
4445
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 items-center", children: [
4446
- /* @__PURE__ */ jsxRuntime.jsx(
4447
- "input",
4448
- {
4449
- type: "color",
4450
- value: customColor,
4451
- onChange: (e) => {
4452
- setCustomColor(e.target.value);
4453
- applyColor(hexToHsl(e.target.value));
4454
- },
4455
- className: "w-10 h-8 rounded border border-border cursor-pointer bg-background"
4456
- }
4457
- ),
4458
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground font-mono", children: customColor })
4459
- ] })
4460
- ] })
4461
- ] }) })
4462
- ] });
4296
+ );
4297
+ };
4298
+ var modalActionButtonStyle = {
4299
+ display: "inline-flex",
4300
+ alignItems: "center",
4301
+ padding: "6px 12px",
4302
+ fontSize: "13px",
4303
+ fontWeight: 500,
4304
+ borderRadius: "6px",
4305
+ border: "1px solid #d1d5db",
4306
+ background: "#ffffff",
4307
+ cursor: "pointer",
4308
+ color: "#374151",
4309
+ transition: "background 0.15s"
4310
+ };
4311
+ var codeScrollStyle = {
4312
+ height: "400px",
4313
+ overflowY: "auto",
4314
+ border: "1px solid #e5e7eb",
4315
+ borderRadius: "6px"
4316
+ };
4317
+ var preStyle = {
4318
+ padding: "16px",
4319
+ fontSize: "12px",
4320
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
4321
+ whiteSpace: "pre-wrap",
4322
+ margin: 0,
4323
+ color: "#111827"
4463
4324
  };
4464
4325
  var TopBar = ({
4465
4326
  isDarkMode,
@@ -4472,14 +4333,14 @@ var TopBar = ({
4472
4333
  canRedo: state.options.enabled && queryCtx.history.canRedo()
4473
4334
  }));
4474
4335
  const { title, logo, templates, callbacks, slots, htmlRenderers } = useEditorConfig();
4475
- const [showCode, setShowCode] = React10.useState(false);
4476
- const [showPreview, setShowPreview] = React10.useState(false);
4477
- const [copied, setCopied] = React10.useState(false);
4478
- const [htmlCode, setHtmlCode] = React10.useState("");
4479
- const [previewDevice, setPreviewDevice] = React10.useState(
4336
+ const [showCode, setShowCode] = React9.useState(false);
4337
+ const [showPreview, setShowPreview] = React9.useState(false);
4338
+ const [copied, setCopied] = React9.useState(false);
4339
+ const [htmlCode, setHtmlCode] = React9.useState("");
4340
+ const [previewDevice, setPreviewDevice] = React9.useState(
4480
4341
  "desktop"
4481
4342
  );
4482
- const getHtml = React10.useCallback(() => {
4343
+ const getHtml = React9.useCallback(() => {
4483
4344
  const json = query.serialize();
4484
4345
  const nodes = JSON.parse(json);
4485
4346
  return generateEmailHtml(nodes, htmlRenderers);
@@ -4539,7 +4400,7 @@ var TopBar = ({
4539
4400
  }
4540
4401
  };
4541
4402
  if (slots.toolbar) {
4542
- return React10__namespace.default.createElement(slots.toolbar, {
4403
+ return React9__namespace.default.createElement(slots.toolbar, {
4543
4404
  onExport: getHtml,
4544
4405
  onPreview: getHtml,
4545
4406
  onClear: handleClearCanvas,
@@ -4552,72 +4413,64 @@ var TopBar = ({
4552
4413
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
4553
4414
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-sm font-semibold text-foreground", children: title }) }),
4554
4415
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-5 w-px bg-border" }),
4555
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
4556
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
4557
- Button,
4558
- {
4559
- variant: "outline",
4560
- size: "sm",
4561
- className: "gap-1.5 h-8 text-xs",
4562
- children: [
4563
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LayoutTemplate, { className: "h-3.5 w-3.5" }),
4564
- "Templates"
4565
- ]
4566
- }
4567
- ) }),
4568
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { align: "start", className: "w-56", children: [
4569
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuLabel, { children: "Quick Start Templates" }),
4570
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
4571
- templates.map((template) => /* @__PURE__ */ jsxRuntime.jsxs(
4572
- DropdownMenuItem,
4416
+ /* @__PURE__ */ jsxRuntime.jsx(
4417
+ Dropdown,
4418
+ {
4419
+ align: "start",
4420
+ label: "Quick Start Templates",
4421
+ trigger: /* @__PURE__ */ jsxRuntime.jsxs(
4422
+ Button,
4573
4423
  {
4574
- className: "gap-2",
4575
- onClick: () => handleLoadTemplate(template),
4424
+ variant: "outline",
4425
+ size: "sm",
4426
+ className: "gap-1.5 h-8 text-xs",
4576
4427
  children: [
4577
- template.icon && React10__namespace.default.createElement(template.icon, {
4578
- className: "h-4 w-4 text-muted-foreground"
4428
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LayoutTemplate, { className: "h-3.5 w-3.5" }),
4429
+ "Templates"
4430
+ ]
4431
+ }
4432
+ ),
4433
+ items: [
4434
+ ...templates.map((template) => ({
4435
+ key: template.id,
4436
+ label: /* @__PURE__ */ jsxRuntime.jsxs(React9__namespace.default.Fragment, { children: [
4437
+ template.icon && React9__namespace.default.createElement(template.icon, {
4438
+ style: {
4439
+ width: 14,
4440
+ height: 14,
4441
+ color: "#9ca3af",
4442
+ flexShrink: 0
4443
+ }
4579
4444
  }),
4580
4445
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4581
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: template.name }),
4582
- template.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: template.description })
4446
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 500, fontSize: "13px" }, children: template.name }),
4447
+ template.description && /* @__PURE__ */ jsxRuntime.jsx(
4448
+ "div",
4449
+ {
4450
+ style: {
4451
+ fontSize: "11px",
4452
+ color: "#9ca3af",
4453
+ marginTop: 1
4454
+ },
4455
+ children: template.description
4456
+ }
4457
+ )
4583
4458
  ] })
4584
- ]
4585
- },
4586
- template.id
4587
- )),
4588
- templates.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
4589
- /* @__PURE__ */ jsxRuntime.jsx(
4590
- DropdownMenuItem,
4459
+ ] }),
4460
+ onClick: () => handleLoadTemplate(template)
4461
+ })),
4462
+ ...templates.length > 0 ? [{ key: "sep-clear", separator: true }] : [],
4591
4463
  {
4464
+ key: "clear",
4465
+ label: "Clear Canvas",
4592
4466
  onClick: handleClearCanvas,
4593
- className: "text-destructive",
4594
- children: "Clear Canvas"
4467
+ danger: true
4595
4468
  }
4596
- )
4597
- ] })
4598
- ] })
4599
- ] }),
4600
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
4601
- /* @__PURE__ */ jsxRuntime.jsxs(
4602
- Button,
4603
- {
4604
- variant: "outline",
4605
- size: "sm",
4606
- onClick: onToggleDarkMode,
4607
- className: "gap-1.5 h-8 text-xs",
4608
- children: [
4609
- isDarkMode ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sun, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Moon, { className: "h-3.5 w-3.5" }),
4610
- isDarkMode ? "Light" : "Dark"
4611
4469
  ]
4612
4470
  }
4613
- ),
4614
- /* @__PURE__ */ jsxRuntime.jsx(
4615
- ColorCustomizer,
4616
- {
4617
- value: primaryColor,
4618
- onColorChange: onPrimaryColorChange
4619
- }
4620
- ),
4471
+ )
4472
+ ] }),
4473
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
4621
4474
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5 bg-muted rounded-md p-0.5", children: [
4622
4475
  /* @__PURE__ */ jsxRuntime.jsx(
4623
4476
  Button,
@@ -4671,57 +4524,126 @@ var TopBar = ({
4671
4524
  )
4672
4525
  ] })
4673
4526
  ] }),
4674
- /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: showCode, onOpenChange: setShowCode, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "max-w-4xl max-h-[80vh]", children: [
4675
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
4676
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Export HTML" }),
4677
- /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Copy this HTML code to use in your email client or system." })
4678
- ] }),
4679
- slots.exportDialog ? React10__namespace.default.createElement(slots.exportDialog, {
4680
- html: htmlCode,
4681
- onClose: () => setShowCode(false)
4682
- }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4683
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 mb-2", children: [
4684
- /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", onClick: handleCopy, children: [
4685
- copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 mr-2" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "h-4 w-4 mr-2" }),
4686
- copied ? "Copied!" : "Copy"
4527
+ /* @__PURE__ */ jsxRuntime.jsx(
4528
+ Modal,
4529
+ {
4530
+ open: showCode,
4531
+ onClose: () => setShowCode(false),
4532
+ title: "Export HTML",
4533
+ description: "Copy this HTML code to use in your email client or system.",
4534
+ maxWidth: 896,
4535
+ maxHeight: "80vh",
4536
+ children: slots.exportDialog ? React9__namespace.default.createElement(slots.exportDialog, {
4537
+ html: htmlCode,
4538
+ onClose: () => setShowCode(false)
4539
+ }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4540
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "8px", marginBottom: "12px" }, children: [
4541
+ /* @__PURE__ */ jsxRuntime.jsxs(
4542
+ "button",
4543
+ {
4544
+ onClick: handleCopy,
4545
+ style: modalActionButtonStyle,
4546
+ onMouseEnter: (e) => e.currentTarget.style.background = "#f3f4f6",
4547
+ onMouseLeave: (e) => e.currentTarget.style.background = "#ffffff",
4548
+ children: [
4549
+ copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { size: 14, style: { marginRight: 6 } }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { size: 14, style: { marginRight: 6 } }),
4550
+ copied ? "Copied!" : "Copy"
4551
+ ]
4552
+ }
4553
+ ),
4554
+ /* @__PURE__ */ jsxRuntime.jsxs(
4555
+ "button",
4556
+ {
4557
+ onClick: handleDownload,
4558
+ style: modalActionButtonStyle,
4559
+ onMouseEnter: (e) => e.currentTarget.style.background = "#f3f4f6",
4560
+ onMouseLeave: (e) => e.currentTarget.style.background = "#ffffff",
4561
+ children: [
4562
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { size: 14, style: { marginRight: 6 } }),
4563
+ "Download"
4564
+ ]
4565
+ }
4566
+ )
4687
4567
  ] }),
4688
- /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", onClick: handleDownload, children: [
4689
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "h-4 w-4 mr-2" }),
4690
- " Download"
4691
- ] })
4692
- ] }),
4693
- /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-[400px] border rounded-md", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "p-4 text-xs font-mono whitespace-pre-wrap", children: htmlCode }) })
4694
- ] })
4695
- ] }) }),
4696
- /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: showPreview, onOpenChange: setShowPreview, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "max-w-5xl max-h-[90vh]", children: [
4697
- /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
4698
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Email Preview" }) }),
4699
- /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Preview how your email will look in email clients." })
4700
- ] }),
4701
- slots.previewDialog ? React10__namespace.default.createElement(slots.previewDialog, {
4702
- html: htmlCode,
4703
- onClose: () => setShowPreview(false)
4704
- }) : /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-[600px]", children: /* @__PURE__ */ jsxRuntime.jsx(
4705
- "div",
4706
- {
4707
- className: `mx-auto transition-all duration-300 ${previewDevice === "mobile" ? "max-w-[375px]" : "max-w-full"}`,
4708
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border rounded-lg bg-muted/30 overflow-hidden", children: [
4709
- previewDevice === "mobile" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 bg-muted flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-1 bg-muted-foreground/30 rounded-full" }) }),
4710
- /* @__PURE__ */ jsxRuntime.jsx(
4711
- "iframe",
4568
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: codeScrollStyle, children: /* @__PURE__ */ jsxRuntime.jsx("pre", { style: preStyle, children: htmlCode }) })
4569
+ ] })
4570
+ }
4571
+ ),
4572
+ /* @__PURE__ */ jsxRuntime.jsx(
4573
+ Modal,
4574
+ {
4575
+ open: showPreview,
4576
+ onClose: () => setShowPreview(false),
4577
+ title: "Email Preview",
4578
+ description: "Preview how your email will look in email clients.",
4579
+ maxWidth: 1024,
4580
+ maxHeight: "90vh",
4581
+ children: slots.previewDialog ? React9__namespace.default.createElement(slots.previewDialog, {
4582
+ html: htmlCode,
4583
+ onClose: () => setShowPreview(false)
4584
+ }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { overflowY: "auto", maxHeight: "600px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
4585
+ "div",
4586
+ {
4587
+ style: {
4588
+ margin: "0 auto",
4589
+ transition: "max-width 0.3s",
4590
+ maxWidth: previewDevice === "mobile" ? "375px" : "100%"
4591
+ },
4592
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
4593
+ "div",
4712
4594
  {
4713
- srcDoc: htmlCode,
4714
- className: "w-full min-h-[500px] bg-white",
4715
- title: "Email Preview",
4716
4595
  style: {
4717
- height: previewDevice === "mobile" ? "667px" : "600px"
4718
- }
4596
+ border: "1px solid #e5e7eb",
4597
+ borderRadius: "8px",
4598
+ background: "rgba(243,244,246,0.3)",
4599
+ overflow: "hidden"
4600
+ },
4601
+ children: [
4602
+ previewDevice === "mobile" && /* @__PURE__ */ jsxRuntime.jsx(
4603
+ "div",
4604
+ {
4605
+ style: {
4606
+ height: "24px",
4607
+ background: "#f3f4f6",
4608
+ display: "flex",
4609
+ alignItems: "center",
4610
+ justifyContent: "center"
4611
+ },
4612
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4613
+ "div",
4614
+ {
4615
+ style: {
4616
+ width: "64px",
4617
+ height: "4px",
4618
+ background: "rgba(107,114,128,0.3)",
4619
+ borderRadius: "9999px"
4620
+ }
4621
+ }
4622
+ )
4623
+ }
4624
+ ),
4625
+ /* @__PURE__ */ jsxRuntime.jsx(
4626
+ "iframe",
4627
+ {
4628
+ srcDoc: htmlCode,
4629
+ title: "Email Preview",
4630
+ style: {
4631
+ width: "100%",
4632
+ minHeight: "500px",
4633
+ background: "#ffffff",
4634
+ border: "none",
4635
+ display: "block",
4636
+ height: previewDevice === "mobile" ? "667px" : "600px"
4637
+ }
4638
+ }
4639
+ )
4640
+ ]
4719
4641
  }
4720
4642
  )
4721
- ] })
4722
- }
4723
- ) })
4724
- ] }) })
4643
+ }
4644
+ ) })
4645
+ }
4646
+ )
4725
4647
  ] });
4726
4648
  };
4727
4649
  var LeftSidebar = ({ setActiveTab, activeTab }) => {
@@ -4730,12 +4652,12 @@ var LeftSidebar = ({ setActiveTab, activeTab }) => {
4730
4652
  //@ts-ignore
4731
4653
  selectedNodeId: state.events.selected[0]
4732
4654
  }));
4733
- React10.useEffect(() => {
4655
+ React9.useEffect(() => {
4734
4656
  if (selectedNodeId) {
4735
4657
  setActiveTab("properties");
4736
4658
  }
4737
4659
  }, [selectedNodeId]);
4738
- const categories = React10.useMemo(() => {
4660
+ const categories = React9.useMemo(() => {
4739
4661
  return Object.keys(components).reduce((acc, k) => {
4740
4662
  const cat = components[k].category || "Other";
4741
4663
  if (!acc.includes(cat)) acc.push(cat);
@@ -4773,7 +4695,7 @@ var LeftSidebar = ({ setActiveTab, activeTab }) => {
4773
4695
  }
4774
4696
  )
4775
4697
  ] }) }),
4776
- /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: "components", className: "flex-1 mt-0 ", children: /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-full max-h-[180vh] ", children: slots.toolbox ? React10__namespace.default.createElement(slots.toolbox, { components, categories }) : /* @__PURE__ */ jsxRuntime.jsx(Toolbox, {}) }) }),
4698
+ /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: "components", className: "flex-1 mt-0 ", children: /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-full max-h-[180vh] ", children: slots.toolbox ? React9__namespace.default.createElement(slots.toolbox, { components, categories }) : /* @__PURE__ */ jsxRuntime.jsx(Toolbox, {}) }) }),
4777
4699
  /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: "properties", className: "flex-1 mt-0 ", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full", children: /* @__PURE__ */ jsxRuntime.jsx(SettingsPanel, {}) }) })
4778
4700
  ]
4779
4701
  }
@@ -4806,34 +4728,34 @@ var EmailEditor = ({
4806
4728
  style
4807
4729
  }) => {
4808
4730
  var _a, _b, _c, _d;
4809
- const mergedComponents = React10.useMemo(() => {
4731
+ const mergedComponents = React9.useMemo(() => {
4810
4732
  if (replaceBuiltins) return userComponents || {};
4811
4733
  return { ...DEFAULT_COMPONENTS, ...userComponents || {} };
4812
4734
  }, [userComponents, replaceBuiltins]);
4813
- const [activeTab, setActiveTab] = React10.useState(
4735
+ const [activeTab, setActiveTab] = React9.useState(
4814
4736
  "components"
4815
4737
  );
4816
- const resolver = React10.useMemo(() => {
4738
+ const resolver = React9.useMemo(() => {
4817
4739
  const res = buildResolver(mergedComponents);
4818
4740
  res.Paper = Paper;
4819
4741
  return res;
4820
4742
  }, [mergedComponents]);
4821
4743
  const renderNodeFn = slots.renderNode || RenderNode;
4822
- const [isDarkMode, setIsDarkMode] = React10.useState(!darkMode);
4823
- const [primaryColor, setPrimaryColor] = React10.useState(
4744
+ const [isDarkMode, setIsDarkMode] = React9.useState(!darkMode);
4745
+ const [primaryColor, setPrimaryColor] = React9.useState(
4824
4746
  (_a = theme.colors) == null ? void 0 : _a.primary
4825
4747
  );
4826
- React10.useEffect(() => {
4748
+ React9.useEffect(() => {
4827
4749
  var _a2;
4828
4750
  setPrimaryColor((_a2 = theme.colors) == null ? void 0 : _a2.primary);
4829
4751
  }, [(_b = theme.colors) == null ? void 0 : _b.primary]);
4830
- const primaryForeground = React10.useMemo(() => {
4752
+ const primaryForeground = React9.useMemo(() => {
4831
4753
  var _a2;
4832
4754
  if ((_a2 = theme.colors) == null ? void 0 : _a2.primaryForeground) return theme.colors.primaryForeground;
4833
4755
  if (!primaryColor) return void 0;
4834
4756
  return getReadablePrimaryForeground(primaryColor);
4835
4757
  }, [primaryColor, (_c = theme.colors) == null ? void 0 : _c.primaryForeground]);
4836
- const themeColorVars = React10.useMemo(() => {
4758
+ const themeColorVars = React9.useMemo(() => {
4837
4759
  const colors = theme.colors || {};
4838
4760
  return {
4839
4761
  background: colors.background,
@@ -4846,7 +4768,7 @@ var EmailEditor = ({
4846
4768
  "canvas-background": colors.canvasBackground
4847
4769
  };
4848
4770
  }, [theme.colors]);
4849
- const editorStyle = React10.useMemo(() => {
4771
+ const editorStyle = React9.useMemo(() => {
4850
4772
  const cssVars = { ...style || {} };
4851
4773
  Object.entries(themeColorVars).forEach(([token, value]) => {
4852
4774
  if (value) cssVars[`--${token}`] = value;
@@ -4956,7 +4878,6 @@ exports.Spacer = Spacer;
4956
4878
  exports.Testimonial = Testimonial;
4957
4879
  exports.TextBlock = TextBlock;
4958
4880
  exports.Toolbox = Toolbox;
4959
- exports.TwoColumn = TwoColumn;
4960
4881
  exports.VariableText = VariableText;
4961
4882
  exports.VideoPlaceholder = VideoPlaceholder;
4962
4883
  exports.buildResolver = buildResolver;