@anvilkit/puck-studio 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +195 -176
- package/dist/index.cjs +945 -803
- package/dist/index.d.cts +110 -46
- package/dist/index.d.ts +110 -46
- package/dist/index.js +928 -789
- package/dist/legacy.cjs +54 -0
- package/dist/legacy.js +52 -0
- package/dist/overrides.cjs +2090 -0
- package/dist/overrides.d.cts +212 -0
- package/dist/overrides.d.ts +212 -0
- package/dist/overrides.js +2057 -0
- package/dist/styles.css +88 -0
- package/package.json +109 -65
package/dist/index.cjs
CHANGED
|
@@ -1,38 +1,35 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var core = require('@puckeditor/core');
|
|
4
3
|
var lucideReact = require('lucide-react');
|
|
5
|
-
var button = require('@base-ui/react/button');
|
|
6
|
-
var classVarianceAuthority = require('class-variance-authority');
|
|
7
|
-
var clsx = require('clsx');
|
|
8
|
-
var tailwindMerge = require('tailwind-merge');
|
|
9
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
10
|
-
var separator = require('@base-ui/react/separator');
|
|
11
4
|
var zustand = require('zustand');
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
var menu = require('@base-ui/react/menu');
|
|
5
|
+
var React17 = require('react');
|
|
6
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
15
7
|
var scrollArea = require('@base-ui/react/scroll-area');
|
|
8
|
+
var clsx = require('clsx');
|
|
9
|
+
var tailwindMerge = require('tailwind-merge');
|
|
16
10
|
var input = require('@base-ui/react/input');
|
|
11
|
+
var core = require('@puckeditor/core');
|
|
12
|
+
var separator = require('@base-ui/react/separator');
|
|
13
|
+
var tooltip = require('@base-ui/react/tooltip');
|
|
17
14
|
var mergeProps = require('@base-ui/react/merge-props');
|
|
18
15
|
var useRender = require('@base-ui/react/use-render');
|
|
16
|
+
var button = require('@base-ui/react/button');
|
|
17
|
+
var classVarianceAuthority = require('class-variance-authority');
|
|
19
18
|
var select = require('@base-ui/react/select');
|
|
20
19
|
var core$1 = require('@dnd-kit/core');
|
|
21
20
|
var sortable = require('@dnd-kit/sortable');
|
|
22
21
|
var utilities = require('@dnd-kit/utilities');
|
|
23
|
-
var popover = require('@base-ui
|
|
22
|
+
var popover = require('@base-ui/react/popover');
|
|
24
23
|
var react = require('motion/react');
|
|
25
24
|
var toggle = require('@base-ui/react/toggle');
|
|
26
25
|
var cmdk = require('cmdk');
|
|
27
|
-
require('@base-ui/react/dialog');
|
|
28
|
-
var pluginAi = require('@puckeditor/plugin-ai');
|
|
29
|
-
require('@puckeditor/plugin-ai/styles.css');
|
|
30
26
|
require('@puckeditor/core/puck.css');
|
|
31
|
-
var tabs = require('@base-ui
|
|
32
|
-
var
|
|
27
|
+
var tabs = require('@base-ui/react/tabs');
|
|
28
|
+
var middleware = require('zustand/middleware');
|
|
29
|
+
var motion8 = require('motion/react-client');
|
|
33
30
|
var react$1 = require('@floating-ui/react');
|
|
34
31
|
var avatar = require('@base-ui/react/avatar');
|
|
35
|
-
var
|
|
32
|
+
var menu = require('@base-ui/react/menu');
|
|
36
33
|
|
|
37
34
|
function _interopNamespace(e) {
|
|
38
35
|
if (e && e.__esModule) return e;
|
|
@@ -52,90 +49,24 @@ function _interopNamespace(e) {
|
|
|
52
49
|
return Object.freeze(n);
|
|
53
50
|
}
|
|
54
51
|
|
|
55
|
-
var
|
|
56
|
-
var
|
|
57
|
-
var motion9__namespace = /*#__PURE__*/_interopNamespace(motion9);
|
|
52
|
+
var React17__namespace = /*#__PURE__*/_interopNamespace(React17);
|
|
53
|
+
var motion8__namespace = /*#__PURE__*/_interopNamespace(motion8);
|
|
58
54
|
|
|
59
|
-
// src/
|
|
60
|
-
function cn(...inputs) {
|
|
61
|
-
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
62
|
-
}
|
|
63
|
-
var buttonVariants = classVarianceAuthority.cva(
|
|
64
|
-
"group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
65
|
-
{
|
|
66
|
-
variants: {
|
|
67
|
-
variant: {
|
|
68
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
69
|
-
outline: "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
|
|
70
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
71
|
-
ghost: "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
|
|
72
|
-
destructive: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
|
|
73
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
74
|
-
},
|
|
75
|
-
size: {
|
|
76
|
-
default: "h-8 gap-1.5 px-2.5",
|
|
77
|
-
xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs [&_svg:not([class*='size-'])]:size-3",
|
|
78
|
-
sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] [&_svg:not([class*='size-'])]:size-3.5",
|
|
79
|
-
lg: "h-9 gap-1.5 px-2.5",
|
|
80
|
-
icon: "size-8",
|
|
81
|
-
"icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] [&_svg:not([class*='size-'])]:size-3",
|
|
82
|
-
"icon-sm": "size-7 rounded-[min(var(--radius-md),12px)]",
|
|
83
|
-
"icon-lg": "size-9"
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
defaultVariants: {
|
|
87
|
-
variant: "default",
|
|
88
|
-
size: "default"
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
);
|
|
92
|
-
function Button({
|
|
93
|
-
className,
|
|
94
|
-
variant = "default",
|
|
95
|
-
size = "default",
|
|
96
|
-
...props
|
|
97
|
-
}) {
|
|
98
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
99
|
-
button.Button,
|
|
100
|
-
{
|
|
101
|
-
"data-slot": "button",
|
|
102
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
103
|
-
...props
|
|
104
|
-
}
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
function Separator({
|
|
108
|
-
className,
|
|
109
|
-
orientation = "horizontal",
|
|
110
|
-
...props
|
|
111
|
-
}) {
|
|
112
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
113
|
-
separator.Separator,
|
|
114
|
-
{
|
|
115
|
-
"data-slot": "separator",
|
|
116
|
-
orientation,
|
|
117
|
-
className: cn(
|
|
118
|
-
"shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
|
|
119
|
-
className
|
|
120
|
-
),
|
|
121
|
-
...props
|
|
122
|
-
}
|
|
123
|
-
);
|
|
124
|
-
}
|
|
55
|
+
// src/core/overrides/layout/EditorDrawer.tsx
|
|
125
56
|
function getStrictContext(name) {
|
|
126
|
-
const Context =
|
|
127
|
-
const
|
|
57
|
+
const Context = React17__namespace.createContext(void 0);
|
|
58
|
+
const Provider = ({
|
|
128
59
|
value,
|
|
129
60
|
children
|
|
130
61
|
}) => /* @__PURE__ */ jsxRuntime.jsx(Context.Provider, { value, children });
|
|
131
62
|
const useSafeContext = () => {
|
|
132
|
-
const ctx =
|
|
63
|
+
const ctx = React17__namespace.useContext(Context);
|
|
133
64
|
if (ctx === void 0) {
|
|
134
65
|
throw new Error(`useContext must be used within ${name ?? "a Provider"}`);
|
|
135
66
|
}
|
|
136
67
|
return ctx;
|
|
137
68
|
};
|
|
138
|
-
return [
|
|
69
|
+
return [Provider, useSafeContext];
|
|
139
70
|
}
|
|
140
71
|
|
|
141
72
|
// src/store/ui-context.ts
|
|
@@ -166,137 +97,8 @@ function useToggleTheme() {
|
|
|
166
97
|
function useMsg(key) {
|
|
167
98
|
return zustand.useStore(useEditorI18nStoreApi(), (s) => s.messages[key] ?? key);
|
|
168
99
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
var TooltipTrigger = TooltipPrimitive__namespace.Trigger;
|
|
172
|
-
var TooltipContent = React18__namespace.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
173
|
-
TooltipPrimitive__namespace.Content,
|
|
174
|
-
{
|
|
175
|
-
ref,
|
|
176
|
-
sideOffset,
|
|
177
|
-
className: cn(
|
|
178
|
-
"z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-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 origin-[--radix-tooltip-content-transform-origin]",
|
|
179
|
-
className
|
|
180
|
-
),
|
|
181
|
-
...props
|
|
182
|
-
}
|
|
183
|
-
) }));
|
|
184
|
-
TooltipContent.displayName = TooltipPrimitive__namespace.Content.displayName;
|
|
185
|
-
function DropdownMenu({ ...props }) {
|
|
186
|
-
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
187
|
-
}
|
|
188
|
-
function DropdownMenuTrigger({ ...props }) {
|
|
189
|
-
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
190
|
-
}
|
|
191
|
-
function DropdownMenuContent({
|
|
192
|
-
align = "start",
|
|
193
|
-
alignOffset = 0,
|
|
194
|
-
side = "bottom",
|
|
195
|
-
sideOffset = 4,
|
|
196
|
-
className,
|
|
197
|
-
...props
|
|
198
|
-
}) {
|
|
199
|
-
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
200
|
-
menu.Menu.Positioner,
|
|
201
|
-
{
|
|
202
|
-
className: "isolate z-50 outline-none",
|
|
203
|
-
align,
|
|
204
|
-
alignOffset,
|
|
205
|
-
side,
|
|
206
|
-
sideOffset,
|
|
207
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
208
|
-
menu.Menu.Popup,
|
|
209
|
-
{
|
|
210
|
-
"data-slot": "dropdown-menu-content",
|
|
211
|
-
className: cn(
|
|
212
|
-
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-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 ring-foreground/10 bg-popover text-popover-foreground min-w-32 rounded-lg p-1 shadow-md ring-1 duration-100 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto outline-none data-closed:overflow-hidden",
|
|
213
|
-
className
|
|
214
|
-
),
|
|
215
|
-
...props
|
|
216
|
-
}
|
|
217
|
-
)
|
|
218
|
-
}
|
|
219
|
-
) });
|
|
220
|
-
}
|
|
221
|
-
function DropdownMenuItem({
|
|
222
|
-
className,
|
|
223
|
-
inset,
|
|
224
|
-
variant = "default",
|
|
225
|
-
...props
|
|
226
|
-
}) {
|
|
227
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
228
|
-
menu.Menu.Item,
|
|
229
|
-
{
|
|
230
|
-
"data-slot": "dropdown-menu-item",
|
|
231
|
-
"data-inset": inset,
|
|
232
|
-
"data-variant": variant,
|
|
233
|
-
className: cn(
|
|
234
|
-
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md px-1.5 py-1 text-sm data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
235
|
-
className
|
|
236
|
-
),
|
|
237
|
-
...props
|
|
238
|
-
}
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
|
-
function EditorHeader({
|
|
242
|
-
actions,
|
|
243
|
-
children
|
|
244
|
-
}) {
|
|
245
|
-
const { history, appState } = core.usePuck();
|
|
246
|
-
const undo = useMsg("header.undo");
|
|
247
|
-
const undoTooltip = useMsg("header.undo.tooltip");
|
|
248
|
-
const redo = useMsg("header.redo");
|
|
249
|
-
const redoTooltip = useMsg("header.redo.tooltip");
|
|
250
|
-
const exportLabel = useMsg("header.export");
|
|
251
|
-
const exportJson = useMsg("header.export.json");
|
|
252
|
-
return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex h-12 items-center justify-between border-b bg-background px-4 gap-2", children: [
|
|
253
|
-
/* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "h-4 w-4" }) }),
|
|
254
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: appState?.data?.root?.props?.title || "" }),
|
|
255
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
256
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
257
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
258
|
-
Button,
|
|
259
|
-
{
|
|
260
|
-
variant: "ghost",
|
|
261
|
-
size: "icon",
|
|
262
|
-
disabled: !history.hasPast,
|
|
263
|
-
onClick: () => history.back(),
|
|
264
|
-
"aria-label": undo,
|
|
265
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Undo2, { className: "h-4 w-4" })
|
|
266
|
-
}
|
|
267
|
-
) }),
|
|
268
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: undoTooltip })
|
|
269
|
-
] }),
|
|
270
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
271
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
272
|
-
Button,
|
|
273
|
-
{
|
|
274
|
-
variant: "ghost",
|
|
275
|
-
size: "icon",
|
|
276
|
-
disabled: !history.hasFuture,
|
|
277
|
-
onClick: () => history.forward(),
|
|
278
|
-
"aria-label": redo,
|
|
279
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Redo2, { className: "h-4 w-4" })
|
|
280
|
-
}
|
|
281
|
-
) }),
|
|
282
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: redoTooltip })
|
|
283
|
-
] }),
|
|
284
|
-
/* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "h-5 mx-1" }),
|
|
285
|
-
/* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
|
|
286
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
287
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { "aria-label": exportLabel, className: "inline-flex items-center justify-center rounded-md h-9 w-9 hover:bg-accent hover:text-accent-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "h-4 w-4" }) }) }),
|
|
288
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: exportLabel })
|
|
289
|
-
] }),
|
|
290
|
-
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "end", children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuItem, { children: exportJson }) })
|
|
291
|
-
] }),
|
|
292
|
-
actions
|
|
293
|
-
] })
|
|
294
|
-
] }) });
|
|
295
|
-
}
|
|
296
|
-
function EditorHeaderActions({
|
|
297
|
-
children
|
|
298
|
-
}) {
|
|
299
|
-
return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children }) });
|
|
100
|
+
function cn(...inputs) {
|
|
101
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
300
102
|
}
|
|
301
103
|
function ScrollArea({
|
|
302
104
|
className,
|
|
@@ -357,7 +159,7 @@ function Input({ className, type, ...props }) {
|
|
|
357
159
|
type,
|
|
358
160
|
"data-slot": "input",
|
|
359
161
|
className: cn(
|
|
360
|
-
"h-
|
|
162
|
+
"h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-2.5 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
|
361
163
|
className
|
|
362
164
|
),
|
|
363
165
|
...props
|
|
@@ -422,9 +224,9 @@ function DrawerItem({
|
|
|
422
224
|
children,
|
|
423
225
|
name
|
|
424
226
|
}) {
|
|
425
|
-
const {
|
|
426
|
-
const componentConfig =
|
|
427
|
-
const thumbnail = componentConfig?.metadata?.thumbnail;
|
|
227
|
+
const { config } = core.usePuck();
|
|
228
|
+
const componentConfig = config.components?.[name];
|
|
229
|
+
const thumbnail = typeof componentConfig?.metadata?.thumbnail === "string" ? componentConfig.metadata.thumbnail : void 0;
|
|
428
230
|
const src = thumbnail ?? getPlaceholderUrl(name);
|
|
429
231
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col rounded-md border border-border bg-muted/40 cursor-grab select-none transition-colors hover:bg-muted active:cursor-grabbing overflow-hidden", children: [
|
|
430
232
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-16 bg-muted overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -441,6 +243,24 @@ function DrawerItem({
|
|
|
441
243
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5 text-xs font-medium truncate", children: name ?? children })
|
|
442
244
|
] });
|
|
443
245
|
}
|
|
246
|
+
function Separator({
|
|
247
|
+
className,
|
|
248
|
+
orientation = "horizontal",
|
|
249
|
+
...props
|
|
250
|
+
}) {
|
|
251
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
252
|
+
separator.Separator,
|
|
253
|
+
{
|
|
254
|
+
"data-slot": "separator",
|
|
255
|
+
orientation,
|
|
256
|
+
className: cn(
|
|
257
|
+
"shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
|
|
258
|
+
className
|
|
259
|
+
),
|
|
260
|
+
...props
|
|
261
|
+
}
|
|
262
|
+
);
|
|
263
|
+
}
|
|
444
264
|
function EditorOutline({
|
|
445
265
|
children
|
|
446
266
|
}) {
|
|
@@ -451,7 +271,7 @@ function EditorOutline({
|
|
|
451
271
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-1.5 text-xs text-muted-foreground truncate", children: [
|
|
452
272
|
"Selected:",
|
|
453
273
|
" ",
|
|
454
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: selectedItem.type
|
|
274
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: typeof selectedItem.type === "string" ? selectedItem.type : String(selectedItem.type) })
|
|
455
275
|
] }),
|
|
456
276
|
/* @__PURE__ */ jsxRuntime.jsx(Separator, {})
|
|
457
277
|
] }),
|
|
@@ -483,6 +303,61 @@ var CANVAS_CSS = `
|
|
|
483
303
|
}
|
|
484
304
|
body { margin: 0; font-family: system-ui, sans-serif; }
|
|
485
305
|
`;
|
|
306
|
+
var CANVAS_STYLE_ID = "__anvilkit_styles__";
|
|
307
|
+
function resolveDocument(target) {
|
|
308
|
+
if (target) return target;
|
|
309
|
+
if (typeof document === "undefined") return void 0;
|
|
310
|
+
return document;
|
|
311
|
+
}
|
|
312
|
+
function useThemeSync({
|
|
313
|
+
document: targetDocument,
|
|
314
|
+
injectCanvasCss = false
|
|
315
|
+
} = {}) {
|
|
316
|
+
const theme = useTheme();
|
|
317
|
+
React17__namespace.useEffect(() => {
|
|
318
|
+
const resolvedDocument = resolveDocument(targetDocument);
|
|
319
|
+
if (!resolvedDocument || !injectCanvasCss) return;
|
|
320
|
+
const existing = resolvedDocument.getElementById(CANVAS_STYLE_ID);
|
|
321
|
+
if (existing) existing.remove();
|
|
322
|
+
const style = resolvedDocument.createElement("style");
|
|
323
|
+
style.id = CANVAS_STYLE_ID;
|
|
324
|
+
style.textContent = CANVAS_CSS;
|
|
325
|
+
resolvedDocument.head.appendChild(style);
|
|
326
|
+
}, [targetDocument, injectCanvasCss]);
|
|
327
|
+
React17__namespace.useEffect(() => {
|
|
328
|
+
const resolvedDocument = resolveDocument(targetDocument);
|
|
329
|
+
if (!resolvedDocument) return;
|
|
330
|
+
resolvedDocument.documentElement.classList.toggle("dark", theme === "dark");
|
|
331
|
+
}, [targetDocument, theme]);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// src/features/library-dnd/drop-contract.ts
|
|
335
|
+
var LIBRARY_DRAG_START = "anvilkit:librarydragstart";
|
|
336
|
+
var IMAGE_DROP = "anvilkit:imagedrop";
|
|
337
|
+
var TEXT_DROP = "anvilkit:textdrop";
|
|
338
|
+
function createLibraryDragEvent(type, detail) {
|
|
339
|
+
return new CustomEvent(type, { detail });
|
|
340
|
+
}
|
|
341
|
+
function addLibraryDragEventListener(type, listener, target = window) {
|
|
342
|
+
const wrapped = (event) => {
|
|
343
|
+
listener(event);
|
|
344
|
+
};
|
|
345
|
+
target.addEventListener(type, wrapped);
|
|
346
|
+
return () => {
|
|
347
|
+
target.removeEventListener(type, wrapped);
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
function dispatchLibraryDragStart(type) {
|
|
351
|
+
window.dispatchEvent(createLibraryDragEvent(LIBRARY_DRAG_START, { type }));
|
|
352
|
+
}
|
|
353
|
+
function dispatchImageDrop(detail) {
|
|
354
|
+
window.dispatchEvent(createLibraryDragEvent(IMAGE_DROP, detail));
|
|
355
|
+
}
|
|
356
|
+
function dispatchTextDrop(detail) {
|
|
357
|
+
window.dispatchEvent(createLibraryDragEvent(TEXT_DROP, detail));
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// src/features/library-dnd/replace-props.ts
|
|
486
361
|
function isImageUrl(val) {
|
|
487
362
|
return /\.(jpg|jpeg|png|gif|webp|svg|avif)(\?.*)?$/i.test(val) || val.includes("picsum.photos") || val.includes("unsplash.com") || val.includes("images.") || val.startsWith("data:image/");
|
|
488
363
|
}
|
|
@@ -521,160 +396,187 @@ function replaceTextInProps(props, newText, targetText) {
|
|
|
521
396
|
}
|
|
522
397
|
return { result: props, replaced: false };
|
|
523
398
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
399
|
+
|
|
400
|
+
// src/core/overrides/canvas/drop-targets.ts
|
|
401
|
+
var TEXT_TAGS = /* @__PURE__ */ new Set([
|
|
402
|
+
"P",
|
|
403
|
+
"H1",
|
|
404
|
+
"H2",
|
|
405
|
+
"H3",
|
|
406
|
+
"H4",
|
|
407
|
+
"H5",
|
|
408
|
+
"H6",
|
|
409
|
+
"SPAN",
|
|
410
|
+
"A",
|
|
411
|
+
"LI",
|
|
412
|
+
"BUTTON",
|
|
413
|
+
"LABEL"
|
|
414
|
+
]);
|
|
415
|
+
function getIframeCoords(iframeEl, clientX, clientY) {
|
|
416
|
+
const rect = iframeEl.getBoundingClientRect();
|
|
417
|
+
const x = clientX - rect.left;
|
|
418
|
+
const y = clientY - rect.top;
|
|
419
|
+
if (x < 0 || y < 0 || x > rect.width || y > rect.height) {
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
return { x, y };
|
|
423
|
+
}
|
|
424
|
+
function getComponentElAt(iframeDoc, iframeEl, clientX, clientY) {
|
|
425
|
+
const coords = getIframeCoords(iframeEl, clientX, clientY);
|
|
426
|
+
if (!coords) return null;
|
|
427
|
+
const element = iframeDoc.elementFromPoint(coords.x, coords.y);
|
|
428
|
+
if (!element) return null;
|
|
429
|
+
return element.closest("[data-puck-component]");
|
|
430
|
+
}
|
|
431
|
+
function getImageElInComponent(compEl, iframeEl, clientX, clientY) {
|
|
432
|
+
const images = Array.from(compEl.querySelectorAll("img"));
|
|
433
|
+
if (!images.length) return null;
|
|
434
|
+
if (images.length === 1) return images[0];
|
|
435
|
+
const rect = iframeEl.getBoundingClientRect();
|
|
436
|
+
const x = clientX - rect.left;
|
|
437
|
+
const y = clientY - rect.top;
|
|
438
|
+
let closest = null;
|
|
439
|
+
let minDistance = Infinity;
|
|
440
|
+
for (const image of images) {
|
|
441
|
+
const imageRect = image.getBoundingClientRect();
|
|
442
|
+
const centerX = imageRect.left + imageRect.width / 2;
|
|
443
|
+
const centerY = imageRect.top + imageRect.height / 2;
|
|
444
|
+
const distance = Math.hypot(centerX - x, centerY - y);
|
|
445
|
+
if (distance < minDistance) {
|
|
446
|
+
minDistance = distance;
|
|
447
|
+
closest = image;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
return closest;
|
|
451
|
+
}
|
|
452
|
+
function getTextElInComponent(iframeDoc, iframeEl, compEl, clientX, clientY) {
|
|
453
|
+
const coords = getIframeCoords(iframeEl, clientX, clientY);
|
|
454
|
+
if (!coords) return null;
|
|
455
|
+
const element = iframeDoc.elementFromPoint(coords.x, coords.y);
|
|
456
|
+
if (element && compEl.contains(element)) {
|
|
457
|
+
let current = element;
|
|
458
|
+
while (current && current !== iframeDoc.body) {
|
|
459
|
+
if (TEXT_TAGS.has(current.tagName) && current.textContent?.trim()) {
|
|
460
|
+
return current;
|
|
461
|
+
}
|
|
462
|
+
current = current.parentElement;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
for (const tag of TEXT_TAGS) {
|
|
466
|
+
const candidate = compEl.querySelector(tag.toLowerCase());
|
|
467
|
+
if (candidate?.textContent?.trim()) {
|
|
468
|
+
return candidate;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return null;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// src/core/overrides/canvas/highlight.ts
|
|
475
|
+
function createElementHighlighter() {
|
|
476
|
+
let highlightedEl = null;
|
|
477
|
+
function set(el, color) {
|
|
478
|
+
if (highlightedEl && highlightedEl !== el) {
|
|
479
|
+
highlightedEl.style.outline = "";
|
|
480
|
+
highlightedEl.style.outlineOffset = "";
|
|
481
|
+
}
|
|
482
|
+
if (el) {
|
|
483
|
+
el.style.outline = `2px solid ${color}`;
|
|
484
|
+
el.style.outlineOffset = "2px";
|
|
485
|
+
}
|
|
486
|
+
highlightedEl = el;
|
|
487
|
+
}
|
|
488
|
+
function clear() {
|
|
489
|
+
set(null, "");
|
|
490
|
+
}
|
|
491
|
+
return { set, clear };
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// src/core/overrides/canvas/useLibraryDropBridge.ts
|
|
495
|
+
function useLibraryDropBridge(iframeDoc) {
|
|
528
496
|
const getPuck = core.useGetPuck();
|
|
529
|
-
|
|
530
|
-
React18__namespace.useEffect(() => {
|
|
531
|
-
if (!iframeDoc) return;
|
|
532
|
-
const existing = iframeDoc.getElementById("__anvilkit_styles__");
|
|
533
|
-
if (existing) existing.remove();
|
|
534
|
-
const style = iframeDoc.createElement("style");
|
|
535
|
-
style.id = "__anvilkit_styles__";
|
|
536
|
-
style.textContent = CANVAS_CSS;
|
|
537
|
-
iframeDoc.head.appendChild(style);
|
|
538
|
-
}, [iframeDoc]);
|
|
539
|
-
React18__namespace.useEffect(() => {
|
|
540
|
-
if (!iframeDoc) return;
|
|
541
|
-
iframeDoc.documentElement.classList.toggle("dark", theme === "dark");
|
|
542
|
-
}, [iframeDoc, theme]);
|
|
543
|
-
React18__namespace.useEffect(() => {
|
|
497
|
+
React17__namespace.useEffect(() => {
|
|
544
498
|
if (!iframeDoc) return;
|
|
545
499
|
const iframeEl = iframeDoc.defaultView?.frameElement;
|
|
546
500
|
if (!iframeEl) return;
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
function getImgInComponent(compEl, clientX, clientY) {
|
|
564
|
-
const imgs = Array.from(compEl.querySelectorAll("img"));
|
|
565
|
-
if (!imgs.length) return null;
|
|
566
|
-
if (imgs.length === 1) return imgs[0];
|
|
567
|
-
const rect = iframeEl.getBoundingClientRect();
|
|
568
|
-
const x = clientX - rect.left;
|
|
569
|
-
const y = clientY - rect.top;
|
|
570
|
-
let closest = null;
|
|
571
|
-
let minDist = Infinity;
|
|
572
|
-
for (const img of imgs) {
|
|
573
|
-
const r = img.getBoundingClientRect();
|
|
574
|
-
const cx = r.left + r.width / 2;
|
|
575
|
-
const cy = r.top + r.height / 2;
|
|
576
|
-
const dist = Math.hypot(cx - x, cy - y);
|
|
577
|
-
if (dist < minDist) {
|
|
578
|
-
minDist = dist;
|
|
579
|
-
closest = img;
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
return closest;
|
|
583
|
-
}
|
|
584
|
-
const TEXT_TAGS = /* @__PURE__ */ new Set(["P", "H1", "H2", "H3", "H4", "H5", "H6", "SPAN", "A", "LI", "BUTTON", "LABEL"]);
|
|
585
|
-
function getTextElInComponent(compEl, clientX, clientY) {
|
|
586
|
-
const coords = iframeCoords(clientX, clientY);
|
|
587
|
-
if (!coords) return null;
|
|
588
|
-
const el = iframeDoc.elementFromPoint(coords.x, coords.y);
|
|
589
|
-
if (el && compEl.contains(el)) {
|
|
590
|
-
let cur = el;
|
|
591
|
-
while (cur && cur !== iframeDoc.body) {
|
|
592
|
-
if (TEXT_TAGS.has(cur.tagName) && cur.textContent?.trim()) return cur;
|
|
593
|
-
cur = cur.parentElement;
|
|
501
|
+
const iframeDocument = iframeDoc;
|
|
502
|
+
const frameElement = iframeEl;
|
|
503
|
+
let activeLibrary = null;
|
|
504
|
+
const highlighter = createElementHighlighter();
|
|
505
|
+
function dispatchReplace(componentId, updatedProps) {
|
|
506
|
+
const { dispatch, getItemById, getSelectorForId } = getPuck();
|
|
507
|
+
const item = getItemById(componentId);
|
|
508
|
+
const selector = getSelectorForId(componentId);
|
|
509
|
+
if (!item || !selector) return false;
|
|
510
|
+
dispatch({
|
|
511
|
+
type: "replace",
|
|
512
|
+
destinationIndex: selector.index,
|
|
513
|
+
destinationZone: selector.zone,
|
|
514
|
+
data: {
|
|
515
|
+
...item,
|
|
516
|
+
props: { ...item.props, ...updatedProps }
|
|
594
517
|
}
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
const found = compEl.querySelector(tag.toLowerCase());
|
|
598
|
-
if (found?.textContent?.trim()) return found;
|
|
599
|
-
}
|
|
600
|
-
return null;
|
|
601
|
-
}
|
|
602
|
-
function setHighlight(el, color) {
|
|
603
|
-
if (highlightedEl && highlightedEl !== el) {
|
|
604
|
-
highlightedEl.style.outline = "";
|
|
605
|
-
highlightedEl.style.outlineOffset = "";
|
|
606
|
-
}
|
|
607
|
-
if (el) {
|
|
608
|
-
el.style.outline = `2px solid ${color}`;
|
|
609
|
-
el.style.outlineOffset = "2px";
|
|
610
|
-
}
|
|
611
|
-
highlightedEl = el;
|
|
518
|
+
});
|
|
519
|
+
return true;
|
|
612
520
|
}
|
|
613
|
-
function
|
|
614
|
-
|
|
615
|
-
}
|
|
616
|
-
let activeLibrary = null;
|
|
617
|
-
function onLibraryDragStart(e) {
|
|
618
|
-
activeLibrary = e.detail.type;
|
|
521
|
+
function onLibraryDragStart(type) {
|
|
522
|
+
activeLibrary = type;
|
|
619
523
|
}
|
|
620
524
|
function onPointerMove(e) {
|
|
621
525
|
if (!activeLibrary) return;
|
|
622
|
-
const compEl = getComponentElAt(e.clientX, e.clientY);
|
|
526
|
+
const compEl = getComponentElAt(iframeDocument, frameElement, e.clientX, e.clientY);
|
|
623
527
|
if (!compEl) {
|
|
624
|
-
|
|
528
|
+
highlighter.clear();
|
|
625
529
|
return;
|
|
626
530
|
}
|
|
627
531
|
if (activeLibrary === "image") {
|
|
628
|
-
|
|
629
|
-
|
|
532
|
+
highlighter.set(
|
|
533
|
+
getImageElInComponent(compEl, frameElement, e.clientX, e.clientY),
|
|
534
|
+
"#6366f1"
|
|
535
|
+
);
|
|
630
536
|
} else {
|
|
631
|
-
|
|
632
|
-
|
|
537
|
+
highlighter.set(
|
|
538
|
+
getTextElInComponent(iframeDocument, frameElement, compEl, e.clientX, e.clientY),
|
|
539
|
+
"#f59e0b"
|
|
540
|
+
);
|
|
633
541
|
}
|
|
634
542
|
}
|
|
635
543
|
function onPointerUp() {
|
|
636
544
|
activeLibrary = null;
|
|
637
|
-
|
|
638
|
-
}
|
|
639
|
-
function dispatchReplace(componentId, updatedProps) {
|
|
640
|
-
const { dispatch, getItemById, getSelectorForId } = getPuck();
|
|
641
|
-
const item = getItemById(componentId);
|
|
642
|
-
const selector = getSelectorForId(componentId);
|
|
643
|
-
if (!item || !selector) return false;
|
|
644
|
-
dispatch({
|
|
645
|
-
type: "replace",
|
|
646
|
-
destinationIndex: selector.index,
|
|
647
|
-
destinationZone: selector.zone,
|
|
648
|
-
data: { ...item, props: { ...item.props, ...updatedProps } }
|
|
649
|
-
});
|
|
650
|
-
return true;
|
|
545
|
+
highlighter.clear();
|
|
651
546
|
}
|
|
652
|
-
function onImageDrop(
|
|
653
|
-
|
|
654
|
-
clearHighlight();
|
|
547
|
+
function onImageDrop(src, clientX, clientY) {
|
|
548
|
+
highlighter.clear();
|
|
655
549
|
activeLibrary = null;
|
|
656
550
|
if (!src) return;
|
|
657
|
-
const compEl = getComponentElAt(clientX, clientY);
|
|
551
|
+
const compEl = getComponentElAt(iframeDocument, frameElement, clientX, clientY);
|
|
658
552
|
if (!compEl) return;
|
|
659
|
-
const componentId = compEl.
|
|
660
|
-
|
|
661
|
-
const item = getItemById(componentId);
|
|
553
|
+
const componentId = compEl.dataset.puckComponent;
|
|
554
|
+
if (!componentId) return;
|
|
555
|
+
const item = getPuck().getItemById(componentId);
|
|
662
556
|
if (!item) return;
|
|
663
|
-
const updatedProps = replaceImageInProps(
|
|
557
|
+
const updatedProps = replaceImageInProps(
|
|
558
|
+
item.props,
|
|
559
|
+
src
|
|
560
|
+
);
|
|
664
561
|
dispatchReplace(componentId, updatedProps);
|
|
665
562
|
}
|
|
666
|
-
function onTextDrop(
|
|
667
|
-
|
|
668
|
-
clearHighlight();
|
|
563
|
+
function onTextDrop(text, clientX, clientY) {
|
|
564
|
+
highlighter.clear();
|
|
669
565
|
activeLibrary = null;
|
|
670
566
|
if (!text) return;
|
|
671
|
-
const compEl = getComponentElAt(clientX, clientY);
|
|
567
|
+
const compEl = getComponentElAt(iframeDocument, frameElement, clientX, clientY);
|
|
672
568
|
if (!compEl) return;
|
|
673
|
-
const componentId = compEl.
|
|
674
|
-
|
|
569
|
+
const componentId = compEl.dataset.puckComponent;
|
|
570
|
+
if (!componentId) return;
|
|
571
|
+
const textEl = getTextElInComponent(
|
|
572
|
+
iframeDocument,
|
|
573
|
+
frameElement,
|
|
574
|
+
compEl,
|
|
575
|
+
clientX,
|
|
576
|
+
clientY
|
|
577
|
+
);
|
|
675
578
|
const targetText = textEl?.textContent?.trim() ?? "";
|
|
676
|
-
const
|
|
677
|
-
const item = getItemById(componentId);
|
|
579
|
+
const item = getPuck().getItemById(componentId);
|
|
678
580
|
if (!item) return;
|
|
679
581
|
const { result: updatedProps, replaced } = replaceTextInProps(
|
|
680
582
|
item.props,
|
|
@@ -683,19 +585,38 @@ function CanvasIframe({
|
|
|
683
585
|
);
|
|
684
586
|
if (replaced) dispatchReplace(componentId, updatedProps);
|
|
685
587
|
}
|
|
686
|
-
|
|
588
|
+
const removeLibraryDragStart = addLibraryDragEventListener(
|
|
589
|
+
LIBRARY_DRAG_START,
|
|
590
|
+
(event) => {
|
|
591
|
+
onLibraryDragStart(event.detail.type);
|
|
592
|
+
}
|
|
593
|
+
);
|
|
687
594
|
window.addEventListener("pointermove", onPointerMove);
|
|
688
595
|
window.addEventListener("pointerup", onPointerUp);
|
|
689
|
-
|
|
690
|
-
|
|
596
|
+
const removeImageDrop = addLibraryDragEventListener(IMAGE_DROP, (event) => {
|
|
597
|
+
const { src, clientX, clientY } = event.detail;
|
|
598
|
+
onImageDrop(src, clientX, clientY);
|
|
599
|
+
});
|
|
600
|
+
const removeTextDrop = addLibraryDragEventListener(TEXT_DROP, (event) => {
|
|
601
|
+
const { text, clientX, clientY } = event.detail;
|
|
602
|
+
onTextDrop(text, clientX, clientY);
|
|
603
|
+
});
|
|
691
604
|
return () => {
|
|
692
|
-
|
|
605
|
+
removeLibraryDragStart();
|
|
693
606
|
window.removeEventListener("pointermove", onPointerMove);
|
|
694
607
|
window.removeEventListener("pointerup", onPointerUp);
|
|
695
|
-
|
|
696
|
-
|
|
608
|
+
removeImageDrop();
|
|
609
|
+
removeTextDrop();
|
|
610
|
+
highlighter.clear();
|
|
697
611
|
};
|
|
698
612
|
}, [iframeDoc, getPuck]);
|
|
613
|
+
}
|
|
614
|
+
function CanvasIframe({
|
|
615
|
+
children,
|
|
616
|
+
document: iframeDoc
|
|
617
|
+
}) {
|
|
618
|
+
useThemeSync({ document: iframeDoc, injectCanvasCss: true });
|
|
619
|
+
useLibraryDropBridge(iframeDoc);
|
|
699
620
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
700
621
|
}
|
|
701
622
|
function CanvasPreview({
|
|
@@ -719,6 +640,60 @@ function ComponentOverlay({
|
|
|
719
640
|
}
|
|
720
641
|
);
|
|
721
642
|
}
|
|
643
|
+
function TooltipProvider({
|
|
644
|
+
delay = 0,
|
|
645
|
+
...props
|
|
646
|
+
}) {
|
|
647
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
648
|
+
tooltip.Tooltip.Provider,
|
|
649
|
+
{
|
|
650
|
+
"data-slot": "tooltip-provider",
|
|
651
|
+
delay,
|
|
652
|
+
...props
|
|
653
|
+
}
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
function Tooltip({ ...props }) {
|
|
657
|
+
return /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Root, { "data-slot": "tooltip", ...props });
|
|
658
|
+
}
|
|
659
|
+
function TooltipTrigger({ ...props }) {
|
|
660
|
+
return /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
661
|
+
}
|
|
662
|
+
function TooltipContent({
|
|
663
|
+
className,
|
|
664
|
+
side = "top",
|
|
665
|
+
sideOffset = 4,
|
|
666
|
+
align = "center",
|
|
667
|
+
alignOffset = 0,
|
|
668
|
+
children,
|
|
669
|
+
...props
|
|
670
|
+
}) {
|
|
671
|
+
return /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
672
|
+
tooltip.Tooltip.Positioner,
|
|
673
|
+
{
|
|
674
|
+
align,
|
|
675
|
+
alignOffset,
|
|
676
|
+
side,
|
|
677
|
+
sideOffset,
|
|
678
|
+
className: "isolate z-50",
|
|
679
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
680
|
+
tooltip.Tooltip.Popup,
|
|
681
|
+
{
|
|
682
|
+
"data-slot": "tooltip-content",
|
|
683
|
+
className: cn(
|
|
684
|
+
"z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
685
|
+
className
|
|
686
|
+
),
|
|
687
|
+
...props,
|
|
688
|
+
children: [
|
|
689
|
+
children,
|
|
690
|
+
/* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Arrow, { className: "z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5" })
|
|
691
|
+
]
|
|
692
|
+
}
|
|
693
|
+
)
|
|
694
|
+
}
|
|
695
|
+
) });
|
|
696
|
+
}
|
|
722
697
|
function ActionBar({
|
|
723
698
|
children,
|
|
724
699
|
label,
|
|
@@ -736,16 +711,13 @@ function ActionBar({
|
|
|
736
711
|
children
|
|
737
712
|
] }) });
|
|
738
713
|
}
|
|
739
|
-
function cn2(...inputs) {
|
|
740
|
-
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
741
|
-
}
|
|
742
714
|
function Label({ className, ...props }) {
|
|
743
715
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
744
716
|
"label",
|
|
745
717
|
{
|
|
746
718
|
"data-slot": "label",
|
|
747
|
-
className:
|
|
748
|
-
"gap-2 text-sm leading-none font-medium group-data-[disabled=true]:
|
|
719
|
+
className: cn(
|
|
720
|
+
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
749
721
|
className
|
|
750
722
|
),
|
|
751
723
|
...props
|
|
@@ -758,7 +730,7 @@ function Breadcrumb({ className, ...props }) {
|
|
|
758
730
|
{
|
|
759
731
|
"aria-label": "breadcrumb",
|
|
760
732
|
"data-slot": "breadcrumb",
|
|
761
|
-
className:
|
|
733
|
+
className: cn(className),
|
|
762
734
|
...props
|
|
763
735
|
}
|
|
764
736
|
);
|
|
@@ -768,8 +740,8 @@ function BreadcrumbList({ className, ...props }) {
|
|
|
768
740
|
"ol",
|
|
769
741
|
{
|
|
770
742
|
"data-slot": "breadcrumb-list",
|
|
771
|
-
className:
|
|
772
|
-
"
|
|
743
|
+
className: cn(
|
|
744
|
+
"flex flex-wrap items-center gap-1.5 text-sm wrap-break-word text-muted-foreground sm:gap-2.5",
|
|
773
745
|
className
|
|
774
746
|
),
|
|
775
747
|
...props
|
|
@@ -781,7 +753,7 @@ function BreadcrumbItem({ className, ...props }) {
|
|
|
781
753
|
"li",
|
|
782
754
|
{
|
|
783
755
|
"data-slot": "breadcrumb-item",
|
|
784
|
-
className:
|
|
756
|
+
className: cn("inline-flex items-center gap-1.5", className),
|
|
785
757
|
...props
|
|
786
758
|
}
|
|
787
759
|
);
|
|
@@ -795,7 +767,7 @@ function BreadcrumbLink({
|
|
|
795
767
|
defaultTagName: "a",
|
|
796
768
|
props: mergeProps.mergeProps(
|
|
797
769
|
{
|
|
798
|
-
className:
|
|
770
|
+
className: cn("transition-colors hover:text-foreground", className)
|
|
799
771
|
},
|
|
800
772
|
props
|
|
801
773
|
),
|
|
@@ -813,7 +785,7 @@ function BreadcrumbPage({ className, ...props }) {
|
|
|
813
785
|
role: "link",
|
|
814
786
|
"aria-disabled": "true",
|
|
815
787
|
"aria-current": "page",
|
|
816
|
-
className:
|
|
788
|
+
className: cn("font-normal text-foreground", className),
|
|
817
789
|
...props
|
|
818
790
|
}
|
|
819
791
|
);
|
|
@@ -829,32 +801,39 @@ function BreadcrumbSeparator({
|
|
|
829
801
|
"data-slot": "breadcrumb-separator",
|
|
830
802
|
role: "presentation",
|
|
831
803
|
"aria-hidden": "true",
|
|
832
|
-
className:
|
|
804
|
+
className: cn("[&>svg]:size-3.5", className),
|
|
833
805
|
...props,
|
|
834
|
-
children: children ?? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, {
|
|
806
|
+
children: children ?? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, {})
|
|
835
807
|
}
|
|
836
808
|
);
|
|
837
809
|
}
|
|
810
|
+
function getComponentTypeLabel(item) {
|
|
811
|
+
if (!item) return "Component";
|
|
812
|
+
return typeof item.type === "string" ? item.type : String(item.type);
|
|
813
|
+
}
|
|
814
|
+
function getComponentId(item) {
|
|
815
|
+
const id = item?.props?.id;
|
|
816
|
+
return typeof id === "string" ? id : null;
|
|
817
|
+
}
|
|
838
818
|
function useBreadcrumbs() {
|
|
839
|
-
const { appState, dispatch, selectedItem, getParentById
|
|
819
|
+
const { appState, dispatch, selectedItem, getParentById } = core.usePuck();
|
|
840
820
|
const { itemSelector } = appState.ui;
|
|
841
821
|
const selectRoot = () => dispatch({ type: "setUi", ui: { itemSelector: null } });
|
|
842
822
|
if (!itemSelector || !selectedItem) {
|
|
843
823
|
return [{ label: "Page" }];
|
|
844
824
|
}
|
|
845
|
-
const selectedType = selectedItem
|
|
846
|
-
const
|
|
825
|
+
const selectedType = getComponentTypeLabel(selectedItem);
|
|
826
|
+
const parentId = getComponentId(selectedItem);
|
|
827
|
+
const parent = parentId ? getParentById(parentId) : void 0;
|
|
847
828
|
if (!parent) {
|
|
848
829
|
return [{ label: "Page", onSelect: selectRoot }, { label: selectedType }];
|
|
849
830
|
}
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
}
|
|
857
|
-
return [{ label: "Page", onSelect: selectRoot }, { label: selectedType }];
|
|
831
|
+
const parentType = getComponentTypeLabel(parent);
|
|
832
|
+
return [
|
|
833
|
+
{ label: "Page", onSelect: selectRoot },
|
|
834
|
+
{ label: parentType },
|
|
835
|
+
{ label: selectedType }
|
|
836
|
+
];
|
|
858
837
|
}
|
|
859
838
|
function FieldWrapper({
|
|
860
839
|
children
|
|
@@ -863,7 +842,7 @@ function FieldWrapper({
|
|
|
863
842
|
return /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0", children: [
|
|
864
843
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-2 border-b", children: /* @__PURE__ */ jsxRuntime.jsx(Breadcrumb, { children: /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbList, { children: crumbs.map((crumb, i) => {
|
|
865
844
|
const isLast = i === crumbs.length - 1;
|
|
866
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
845
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React17__namespace.Fragment, { children: [
|
|
867
846
|
i > 0 && /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbSeparator, {}),
|
|
868
847
|
/* @__PURE__ */ jsxRuntime.jsx(BreadcrumbItem, { children: isLast ? /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbPage, { children: crumb.label }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
869
848
|
BreadcrumbLink,
|
|
@@ -881,20 +860,33 @@ function FieldWrapper({
|
|
|
881
860
|
function FieldLabel({
|
|
882
861
|
children,
|
|
883
862
|
label,
|
|
863
|
+
icon,
|
|
884
864
|
labelIcon,
|
|
885
865
|
el,
|
|
886
|
-
type: _type,
|
|
887
866
|
readOnly,
|
|
888
867
|
className
|
|
889
868
|
}) {
|
|
890
|
-
console.log("Lable type", labelIcon);
|
|
891
869
|
const El = el ?? "div";
|
|
870
|
+
const labelAdornment = icon ?? labelIcon;
|
|
892
871
|
return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(El, { className: `flex flex-col gap-1.5 ${className ?? ""}`, children: [
|
|
893
872
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
894
|
-
|
|
873
|
+
labelAdornment && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: labelAdornment }),
|
|
895
874
|
/* @__PURE__ */ jsxRuntime.jsx(Label, { className: "text-xs font-medium text-muted-foreground", children: label }),
|
|
896
875
|
label && /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
897
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
876
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
877
|
+
TooltipTrigger,
|
|
878
|
+
{
|
|
879
|
+
"aria-label": label,
|
|
880
|
+
render: /* @__PURE__ */ jsxRuntime.jsx(
|
|
881
|
+
"button",
|
|
882
|
+
{
|
|
883
|
+
type: "button",
|
|
884
|
+
className: "inline-flex cursor-help items-center justify-center text-muted-foreground/60 transition-colors hover:text-muted-foreground"
|
|
885
|
+
}
|
|
886
|
+
),
|
|
887
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Info, { className: "h-3 w-3 text-muted-foreground/60 cursor-help" })
|
|
888
|
+
}
|
|
889
|
+
),
|
|
898
890
|
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "right", children: label })
|
|
899
891
|
] }),
|
|
900
892
|
readOnly && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto text-xs text-muted-foreground/50", children: "Read only" })
|
|
@@ -902,6 +894,50 @@ function FieldLabel({
|
|
|
902
894
|
children
|
|
903
895
|
] }) });
|
|
904
896
|
}
|
|
897
|
+
var buttonVariants = classVarianceAuthority.cva(
|
|
898
|
+
"group/button inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
899
|
+
{
|
|
900
|
+
variants: {
|
|
901
|
+
variant: {
|
|
902
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
903
|
+
outline: "border-border bg-background shadow-xs hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
|
|
904
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
905
|
+
ghost: "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
|
|
906
|
+
destructive: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
|
|
907
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
908
|
+
},
|
|
909
|
+
size: {
|
|
910
|
+
default: "h-9 gap-1.5 px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
911
|
+
xs: "h-6 gap-1 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
912
|
+
sm: "h-8 gap-1 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5",
|
|
913
|
+
lg: "h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
|
|
914
|
+
icon: "size-9",
|
|
915
|
+
"icon-xs": "size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3",
|
|
916
|
+
"icon-sm": "size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md",
|
|
917
|
+
"icon-lg": "size-10"
|
|
918
|
+
}
|
|
919
|
+
},
|
|
920
|
+
defaultVariants: {
|
|
921
|
+
variant: "default",
|
|
922
|
+
size: "default"
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
);
|
|
926
|
+
function Button({
|
|
927
|
+
className,
|
|
928
|
+
variant = "default",
|
|
929
|
+
size = "default",
|
|
930
|
+
...props
|
|
931
|
+
}) {
|
|
932
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
933
|
+
button.Button,
|
|
934
|
+
{
|
|
935
|
+
"data-slot": "button",
|
|
936
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
937
|
+
...props
|
|
938
|
+
}
|
|
939
|
+
);
|
|
940
|
+
}
|
|
905
941
|
var MOCK_VALUES = {
|
|
906
942
|
default: ["AI-generated content", "Smart suggestion", "Generated text"]
|
|
907
943
|
};
|
|
@@ -913,7 +949,7 @@ function getMock(instructions) {
|
|
|
913
949
|
return pool[Math.floor(Math.random() * pool.length)];
|
|
914
950
|
}
|
|
915
951
|
function AiButton({ ai, onGenerate }) {
|
|
916
|
-
const [loading, setLoading] =
|
|
952
|
+
const [loading, setLoading] = React17__namespace.useState(false);
|
|
917
953
|
const handleClick = () => {
|
|
918
954
|
setLoading(true);
|
|
919
955
|
setTimeout(() => {
|
|
@@ -944,13 +980,22 @@ function TextField({
|
|
|
944
980
|
label,
|
|
945
981
|
labelIcon
|
|
946
982
|
}) {
|
|
947
|
-
const [local, setLocal] =
|
|
948
|
-
|
|
983
|
+
const [local, setLocal] = React17__namespace.useState(value ?? "");
|
|
984
|
+
const onChangeRef = React17__namespace.useRef(onChange);
|
|
985
|
+
const lastCommittedValueRef = React17__namespace.useRef(value ?? "");
|
|
986
|
+
React17__namespace.useEffect(() => {
|
|
987
|
+
onChangeRef.current = onChange;
|
|
988
|
+
}, [onChange]);
|
|
989
|
+
React17__namespace.useEffect(() => {
|
|
990
|
+
lastCommittedValueRef.current = value ?? "";
|
|
949
991
|
setLocal(value ?? "");
|
|
950
992
|
}, [value]);
|
|
951
|
-
|
|
993
|
+
React17__namespace.useEffect(() => {
|
|
952
994
|
const timer = setTimeout(() => {
|
|
953
|
-
if (local !==
|
|
995
|
+
if (local !== lastCommittedValueRef.current) {
|
|
996
|
+
onChangeRef.current(local);
|
|
997
|
+
lastCommittedValueRef.current = local;
|
|
998
|
+
}
|
|
954
999
|
}, 200);
|
|
955
1000
|
return () => clearTimeout(timer);
|
|
956
1001
|
}, [local]);
|
|
@@ -965,10 +1010,17 @@ function TextField({
|
|
|
965
1010
|
className: "h-8 text-sm flex-1"
|
|
966
1011
|
}
|
|
967
1012
|
),
|
|
968
|
-
field?.ai && /* @__PURE__ */ jsxRuntime.jsx(
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
1013
|
+
field?.ai && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1014
|
+
AiButton,
|
|
1015
|
+
{
|
|
1016
|
+
ai: field.ai,
|
|
1017
|
+
onGenerate: (nextValue) => {
|
|
1018
|
+
lastCommittedValueRef.current = nextValue;
|
|
1019
|
+
setLocal(nextValue);
|
|
1020
|
+
onChangeRef.current(nextValue);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
)
|
|
972
1024
|
] }) });
|
|
973
1025
|
}
|
|
974
1026
|
function Textarea({ className, ...props }) {
|
|
@@ -977,7 +1029,7 @@ function Textarea({ className, ...props }) {
|
|
|
977
1029
|
{
|
|
978
1030
|
"data-slot": "textarea",
|
|
979
1031
|
className: cn(
|
|
980
|
-
"flex field-sizing-content min-h-16 w-full rounded-
|
|
1032
|
+
"flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-2.5 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
|
981
1033
|
className
|
|
982
1034
|
),
|
|
983
1035
|
...props
|
|
@@ -985,11 +1037,11 @@ function Textarea({ className, ...props }) {
|
|
|
985
1037
|
);
|
|
986
1038
|
}
|
|
987
1039
|
function TextareaField({ value, onChange, readOnly, placeholder, label }) {
|
|
988
|
-
const [local, setLocal] =
|
|
989
|
-
|
|
1040
|
+
const [local, setLocal] = React17__namespace.useState(value ?? "");
|
|
1041
|
+
React17__namespace.useEffect(() => {
|
|
990
1042
|
setLocal(value ?? "");
|
|
991
1043
|
}, [value]);
|
|
992
|
-
|
|
1044
|
+
React17__namespace.useEffect(() => {
|
|
993
1045
|
const timer = setTimeout(() => {
|
|
994
1046
|
if (local !== value) onChange(local);
|
|
995
1047
|
}, 200);
|
|
@@ -1007,11 +1059,11 @@ function TextareaField({ value, onChange, readOnly, placeholder, label }) {
|
|
|
1007
1059
|
) });
|
|
1008
1060
|
}
|
|
1009
1061
|
function NumberField({ value, onChange, readOnly, min, max, step, label }) {
|
|
1010
|
-
const [local, setLocal] =
|
|
1011
|
-
|
|
1062
|
+
const [local, setLocal] = React17__namespace.useState(String(value ?? ""));
|
|
1063
|
+
React17__namespace.useEffect(() => {
|
|
1012
1064
|
setLocal(String(value ?? ""));
|
|
1013
1065
|
}, [value]);
|
|
1014
|
-
|
|
1066
|
+
React17__namespace.useEffect(() => {
|
|
1015
1067
|
const parsed = parseFloat(local);
|
|
1016
1068
|
if (!isNaN(parsed) && parsed !== value) {
|
|
1017
1069
|
const timer = setTimeout(() => onChange(parsed), 200);
|
|
@@ -1065,7 +1117,7 @@ function SelectTrigger({
|
|
|
1065
1117
|
"data-slot": "select-trigger",
|
|
1066
1118
|
"data-size": size,
|
|
1067
1119
|
className: cn(
|
|
1068
|
-
"
|
|
1120
|
+
"flex w-fit items-center justify-between gap-1.5 rounded-md border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
1069
1121
|
className
|
|
1070
1122
|
),
|
|
1071
1123
|
...props,
|
|
@@ -1074,7 +1126,7 @@ function SelectTrigger({
|
|
|
1074
1126
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1075
1127
|
select.Select.Icon,
|
|
1076
1128
|
{
|
|
1077
|
-
render: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "
|
|
1129
|
+
render: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "pointer-events-none size-4 text-muted-foreground" })
|
|
1078
1130
|
}
|
|
1079
1131
|
)
|
|
1080
1132
|
]
|
|
@@ -1105,10 +1157,7 @@ function SelectContent({
|
|
|
1105
1157
|
{
|
|
1106
1158
|
"data-slot": "select-content",
|
|
1107
1159
|
"data-align-trigger": alignItemWithTrigger,
|
|
1108
|
-
className: cn(
|
|
1109
|
-
"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-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 ring-foreground/10 min-w-36 rounded-lg shadow-md ring-1 duration-100 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 relative isolate z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto data-[align-trigger=true]:animate-none",
|
|
1110
|
-
className
|
|
1111
|
-
),
|
|
1160
|
+
className: cn("relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
|
|
1112
1161
|
...props,
|
|
1113
1162
|
children: [
|
|
1114
1163
|
/* @__PURE__ */ jsxRuntime.jsx(SelectScrollUpButton, {}),
|
|
@@ -1130,16 +1179,17 @@ function SelectItem({
|
|
|
1130
1179
|
{
|
|
1131
1180
|
"data-slot": "select-item",
|
|
1132
1181
|
className: cn(
|
|
1133
|
-
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground
|
|
1182
|
+
"relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
1134
1183
|
className
|
|
1135
1184
|
),
|
|
1136
1185
|
...props,
|
|
1137
1186
|
children: [
|
|
1138
|
-
/* @__PURE__ */ jsxRuntime.jsx(select.Select.ItemText, { className: "flex flex-1 gap-2
|
|
1187
|
+
/* @__PURE__ */ jsxRuntime.jsx(select.Select.ItemText, { className: "flex flex-1 shrink-0 gap-2 whitespace-nowrap", children }),
|
|
1139
1188
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1140
1189
|
select.Select.ItemIndicator,
|
|
1141
1190
|
{
|
|
1142
|
-
render: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center"
|
|
1191
|
+
render: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center" }),
|
|
1192
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "pointer-events-none" })
|
|
1143
1193
|
}
|
|
1144
1194
|
)
|
|
1145
1195
|
]
|
|
@@ -1155,11 +1205,14 @@ function SelectScrollUpButton({
|
|
|
1155
1205
|
{
|
|
1156
1206
|
"data-slot": "select-scroll-up-button",
|
|
1157
1207
|
className: cn(
|
|
1158
|
-
"
|
|
1208
|
+
"top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
1159
1209
|
className
|
|
1160
1210
|
),
|
|
1161
1211
|
...props,
|
|
1162
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1212
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1213
|
+
lucideReact.ChevronUpIcon,
|
|
1214
|
+
{}
|
|
1215
|
+
)
|
|
1163
1216
|
}
|
|
1164
1217
|
);
|
|
1165
1218
|
}
|
|
@@ -1172,11 +1225,14 @@ function SelectScrollDownButton({
|
|
|
1172
1225
|
{
|
|
1173
1226
|
"data-slot": "select-scroll-down-button",
|
|
1174
1227
|
className: cn(
|
|
1175
|
-
"
|
|
1228
|
+
"bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
1176
1229
|
className
|
|
1177
1230
|
),
|
|
1178
1231
|
...props,
|
|
1179
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1232
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1233
|
+
lucideReact.ChevronDownIcon,
|
|
1234
|
+
{}
|
|
1235
|
+
)
|
|
1180
1236
|
}
|
|
1181
1237
|
);
|
|
1182
1238
|
}
|
|
@@ -1198,12 +1254,12 @@ function SelectField({ field, value, onChange, id, readOnly, label }) {
|
|
|
1198
1254
|
) });
|
|
1199
1255
|
}
|
|
1200
1256
|
var buttonGroupVariants = classVarianceAuthority.cva(
|
|
1201
|
-
"has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-
|
|
1257
|
+
"flex w-fit items-stretch *:focus-visible:relative *:focus-visible:z-10 has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
|
|
1202
1258
|
{
|
|
1203
1259
|
variants: {
|
|
1204
1260
|
orientation: {
|
|
1205
|
-
horizontal: "[&>[data-slot]:not(:has(~[data-slot]))]:rounded-r-
|
|
1206
|
-
vertical: "[&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-
|
|
1261
|
+
horizontal: "*:data-slot:rounded-r-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-r-md! [&>[data-slot]~[data-slot]]:rounded-l-none [&>[data-slot]~[data-slot]]:border-l-0",
|
|
1262
|
+
vertical: "flex-col *:data-slot:rounded-b-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-md! [&>[data-slot]~[data-slot]]:rounded-t-none [&>[data-slot]~[data-slot]]:border-t-0"
|
|
1207
1263
|
}
|
|
1208
1264
|
},
|
|
1209
1265
|
defaultVariants: {
|
|
@@ -1222,7 +1278,7 @@ function ButtonGroup({
|
|
|
1222
1278
|
role: "group",
|
|
1223
1279
|
"data-slot": "button-group",
|
|
1224
1280
|
"data-orientation": orientation,
|
|
1225
|
-
className:
|
|
1281
|
+
className: cn(buttonGroupVariants({ orientation }), className),
|
|
1226
1282
|
...props
|
|
1227
1283
|
}
|
|
1228
1284
|
);
|
|
@@ -1252,8 +1308,8 @@ function ItemGroup({ className, ...props }) {
|
|
|
1252
1308
|
{
|
|
1253
1309
|
role: "list",
|
|
1254
1310
|
"data-slot": "item-group",
|
|
1255
|
-
className:
|
|
1256
|
-
"gap-4 has-data-[size=sm]:gap-2.5 has-data-[size=xs]:gap-2
|
|
1311
|
+
className: cn(
|
|
1312
|
+
"group/item-group flex w-full flex-col gap-4 has-data-[size=sm]:gap-2.5 has-data-[size=xs]:gap-2",
|
|
1257
1313
|
className
|
|
1258
1314
|
),
|
|
1259
1315
|
...props
|
|
@@ -1261,16 +1317,16 @@ function ItemGroup({ className, ...props }) {
|
|
|
1261
1317
|
);
|
|
1262
1318
|
}
|
|
1263
1319
|
var itemVariants = classVarianceAuthority.cva(
|
|
1264
|
-
"
|
|
1320
|
+
"group/item flex w-full flex-wrap items-center rounded-md border text-sm transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a]:transition-colors [a]:hover:bg-muted",
|
|
1265
1321
|
{
|
|
1266
1322
|
variants: {
|
|
1267
1323
|
variant: {
|
|
1268
1324
|
default: "border-transparent",
|
|
1269
1325
|
outline: "border-border",
|
|
1270
|
-
muted: "bg-muted/50
|
|
1326
|
+
muted: "border-transparent bg-muted/50"
|
|
1271
1327
|
},
|
|
1272
1328
|
size: {
|
|
1273
|
-
default: "gap-
|
|
1329
|
+
default: "gap-3.5 px-4 py-3.5",
|
|
1274
1330
|
sm: "gap-2.5 px-3 py-2.5",
|
|
1275
1331
|
xs: "gap-2 px-2.5 py-2 in-data-[slot=dropdown-menu-content]:p-0"
|
|
1276
1332
|
}
|
|
@@ -1292,7 +1348,7 @@ function Item({
|
|
|
1292
1348
|
defaultTagName: "div",
|
|
1293
1349
|
props: mergeProps.mergeProps(
|
|
1294
1350
|
{
|
|
1295
|
-
className:
|
|
1351
|
+
className: cn(itemVariants({ variant, size, className }))
|
|
1296
1352
|
},
|
|
1297
1353
|
props
|
|
1298
1354
|
),
|
|
@@ -1305,7 +1361,7 @@ function Item({
|
|
|
1305
1361
|
});
|
|
1306
1362
|
}
|
|
1307
1363
|
classVarianceAuthority.cva(
|
|
1308
|
-
"gap-2 group-has-data-[slot=item-description]/item:translate-y-0.5 group-has-data-[slot=item-description]/item:self-start
|
|
1364
|
+
"flex shrink-0 items-center justify-center gap-2 group-has-data-[slot=item-description]/item:translate-y-0.5 group-has-data-[slot=item-description]/item:self-start [&_svg]:pointer-events-none",
|
|
1309
1365
|
{
|
|
1310
1366
|
variants: {
|
|
1311
1367
|
variant: {
|
|
@@ -1324,8 +1380,8 @@ function ItemContent({ className, ...props }) {
|
|
|
1324
1380
|
"div",
|
|
1325
1381
|
{
|
|
1326
1382
|
"data-slot": "item-content",
|
|
1327
|
-
className:
|
|
1328
|
-
"gap-1 group-data-[size=xs]/item:gap-0
|
|
1383
|
+
className: cn(
|
|
1384
|
+
"flex flex-1 flex-col gap-1 group-data-[size=xs]/item:gap-0 [&+[data-slot=item-content]]:flex-none",
|
|
1329
1385
|
className
|
|
1330
1386
|
),
|
|
1331
1387
|
...props
|
|
@@ -1337,8 +1393,8 @@ function ItemTitle({ className, ...props }) {
|
|
|
1337
1393
|
"div",
|
|
1338
1394
|
{
|
|
1339
1395
|
"data-slot": "item-title",
|
|
1340
|
-
className:
|
|
1341
|
-
"gap-2 text-sm leading-snug font-medium underline-offset-4
|
|
1396
|
+
className: cn(
|
|
1397
|
+
"line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4",
|
|
1342
1398
|
className
|
|
1343
1399
|
),
|
|
1344
1400
|
...props
|
|
@@ -1350,20 +1406,20 @@ function ItemActions({ className, ...props }) {
|
|
|
1350
1406
|
"div",
|
|
1351
1407
|
{
|
|
1352
1408
|
"data-slot": "item-actions",
|
|
1353
|
-
className:
|
|
1409
|
+
className: cn("flex items-center gap-2", className),
|
|
1354
1410
|
...props
|
|
1355
1411
|
}
|
|
1356
1412
|
);
|
|
1357
1413
|
}
|
|
1358
1414
|
function useControlledState(props) {
|
|
1359
1415
|
const { value, defaultValue, onChange } = props;
|
|
1360
|
-
const [state, setInternalState] =
|
|
1416
|
+
const [state, setInternalState] = React17__namespace.useState(
|
|
1361
1417
|
value !== void 0 ? value : defaultValue
|
|
1362
1418
|
);
|
|
1363
|
-
|
|
1419
|
+
React17__namespace.useEffect(() => {
|
|
1364
1420
|
if (value !== void 0) setInternalState(value);
|
|
1365
1421
|
}, [value]);
|
|
1366
|
-
const setState =
|
|
1422
|
+
const setState = React17__namespace.useCallback(
|
|
1367
1423
|
(next, ...args) => {
|
|
1368
1424
|
setInternalState(next);
|
|
1369
1425
|
onChange?.(next, ...args);
|
|
@@ -1476,6 +1532,9 @@ function PopoverPanel({
|
|
|
1476
1532
|
function PopoverTitle2(props) {
|
|
1477
1533
|
return /* @__PURE__ */ jsxRuntime.jsx(PopoverTitle, { ...props });
|
|
1478
1534
|
}
|
|
1535
|
+
function getArraySubField(subName, subField) {
|
|
1536
|
+
return { ...subField, label: subField.label ?? subName };
|
|
1537
|
+
}
|
|
1479
1538
|
function SortableItem({
|
|
1480
1539
|
id,
|
|
1481
1540
|
index,
|
|
@@ -1562,7 +1621,7 @@ function SortableItem({
|
|
|
1562
1621
|
children: Object.entries(field.arrayFields).map(([subName, subField]) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1563
1622
|
core.AutoField,
|
|
1564
1623
|
{
|
|
1565
|
-
field:
|
|
1624
|
+
field: getArraySubField(subName, subField),
|
|
1566
1625
|
value: item[subName],
|
|
1567
1626
|
onChange: (val) => onUpdate(index, subName, val),
|
|
1568
1627
|
readOnly,
|
|
@@ -1582,13 +1641,17 @@ function ArrayField({
|
|
|
1582
1641
|
label,
|
|
1583
1642
|
id = ""
|
|
1584
1643
|
}) {
|
|
1585
|
-
const
|
|
1586
|
-
const
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1644
|
+
const [openIndex, setOpenIndex] = React17__namespace.useState(null);
|
|
1645
|
+
const stableValue = React17__namespace.useMemo(() => {
|
|
1646
|
+
const needsId = value.some((item) => !item._id);
|
|
1647
|
+
if (!needsId) return value;
|
|
1648
|
+
return value.map(
|
|
1649
|
+
(item) => item._id ? item : { ...item, _id: `${id}-${Math.random().toString(36).slice(2)}` }
|
|
1650
|
+
);
|
|
1651
|
+
}, [value, id]);
|
|
1652
|
+
const itemIds = stableValue.map((item) => item._id);
|
|
1653
|
+
const atMax = field.max !== void 0 && stableValue.length >= field.max;
|
|
1654
|
+
const atMin = field.min !== void 0 && stableValue.length <= field.min;
|
|
1592
1655
|
const sensors = core$1.useSensors(core$1.useSensor(core$1.PointerSensor));
|
|
1593
1656
|
const handleDragEnd = (event) => {
|
|
1594
1657
|
const { active, over } = event;
|
|
@@ -1596,7 +1659,7 @@ function ArrayField({
|
|
|
1596
1659
|
const from = itemIds.indexOf(active.id);
|
|
1597
1660
|
const to = itemIds.indexOf(over.id);
|
|
1598
1661
|
if (from === -1 || to === -1) return;
|
|
1599
|
-
onChange(sortable.arrayMove(
|
|
1662
|
+
onChange(sortable.arrayMove(stableValue, from, to));
|
|
1600
1663
|
};
|
|
1601
1664
|
const defaultItem = () => {
|
|
1602
1665
|
if (!field.defaultItemProps) return {};
|
|
@@ -1604,33 +1667,35 @@ function ArrayField({
|
|
|
1604
1667
|
};
|
|
1605
1668
|
const addItem = () => {
|
|
1606
1669
|
if (atMax || readOnly) return;
|
|
1607
|
-
const newIndex =
|
|
1608
|
-
onChange([...
|
|
1670
|
+
const newIndex = stableValue.length;
|
|
1671
|
+
onChange([...stableValue, defaultItem()]);
|
|
1609
1672
|
setOpenIndex(newIndex);
|
|
1610
1673
|
};
|
|
1611
1674
|
const removeItem = (i) => {
|
|
1612
1675
|
if (atMin || readOnly) return;
|
|
1613
|
-
const next = [...
|
|
1676
|
+
const next = [...stableValue];
|
|
1614
1677
|
next.splice(i, 1);
|
|
1615
1678
|
onChange(next);
|
|
1616
1679
|
};
|
|
1617
1680
|
const duplicateItem = (i) => {
|
|
1618
1681
|
if (atMax || readOnly) return;
|
|
1619
|
-
const next = [...
|
|
1620
|
-
next.splice(i + 1, 0, { ...
|
|
1682
|
+
const next = [...stableValue];
|
|
1683
|
+
next.splice(i + 1, 0, { ...stableValue[i] });
|
|
1621
1684
|
onChange(next);
|
|
1622
1685
|
};
|
|
1623
1686
|
const updateItem = (i, subName, val) => {
|
|
1624
1687
|
onChange(
|
|
1625
|
-
|
|
1688
|
+
stableValue.map(
|
|
1626
1689
|
(item, idx) => idx === i ? { ...item, [subName]: val } : item
|
|
1627
1690
|
)
|
|
1628
1691
|
);
|
|
1629
1692
|
};
|
|
1630
1693
|
const getSummary = (item, i) => {
|
|
1631
1694
|
if (field.getItemSummary) return field.getItemSummary(item, i);
|
|
1632
|
-
const first = Object.
|
|
1633
|
-
|
|
1695
|
+
const first = Object.entries(item).find(
|
|
1696
|
+
(entry) => entry[0] !== "_id" && typeof entry[1] === "string" && entry[1].length > 0
|
|
1697
|
+
);
|
|
1698
|
+
return first?.[1] ?? `Item ${i + 1}`;
|
|
1634
1699
|
};
|
|
1635
1700
|
return /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label: label ?? field.label ?? "", readOnly, el: "div", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
1636
1701
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1644,7 +1709,7 @@ function ArrayField({
|
|
|
1644
1709
|
{
|
|
1645
1710
|
items: itemIds,
|
|
1646
1711
|
strategy: sortable.verticalListSortingStrategy,
|
|
1647
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ItemGroup, { children:
|
|
1712
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ItemGroup, { children: stableValue.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1648
1713
|
SortableItem,
|
|
1649
1714
|
{
|
|
1650
1715
|
id: itemIds[i],
|
|
@@ -1697,7 +1762,7 @@ function Card({
|
|
|
1697
1762
|
"data-slot": "card",
|
|
1698
1763
|
"data-size": size,
|
|
1699
1764
|
className: cn(
|
|
1700
|
-
"group/card flex flex-col gap-
|
|
1765
|
+
"group/card flex flex-col gap-6 overflow-hidden rounded-xl bg-card py-6 text-sm text-card-foreground shadow-xs ring-1 ring-foreground/10 has-[>img:first-child]:pt-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
|
|
1701
1766
|
className
|
|
1702
1767
|
),
|
|
1703
1768
|
...props
|
|
@@ -1709,7 +1774,7 @@ function CardContent({ className, ...props }) {
|
|
|
1709
1774
|
"div",
|
|
1710
1775
|
{
|
|
1711
1776
|
"data-slot": "card-content",
|
|
1712
|
-
className: cn("px-
|
|
1777
|
+
className: cn("px-6 group-data-[size=sm]/card:px-4", className),
|
|
1713
1778
|
...props
|
|
1714
1779
|
}
|
|
1715
1780
|
);
|
|
@@ -1721,17 +1786,17 @@ function CustomField({ children, label }) {
|
|
|
1721
1786
|
return /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label: label ?? "", el: "div", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-border/60 p-3", children }) });
|
|
1722
1787
|
}
|
|
1723
1788
|
var toggleVariants = classVarianceAuthority.cva(
|
|
1724
|
-
"group/toggle inline-flex items-center justify-center gap-1 rounded-
|
|
1789
|
+
"group/toggle inline-flex items-center justify-center gap-1 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
1725
1790
|
{
|
|
1726
1791
|
variants: {
|
|
1727
1792
|
variant: {
|
|
1728
1793
|
default: "bg-transparent",
|
|
1729
|
-
outline: "border border-input bg-transparent hover:bg-muted"
|
|
1794
|
+
outline: "border border-input bg-transparent shadow-xs hover:bg-muted"
|
|
1730
1795
|
},
|
|
1731
1796
|
size: {
|
|
1732
|
-
default: "h-
|
|
1733
|
-
sm: "h-
|
|
1734
|
-
lg: "h-
|
|
1797
|
+
default: "h-9 min-w-9 px-2",
|
|
1798
|
+
sm: "h-8 min-w-8 px-1.5",
|
|
1799
|
+
lg: "h-10 min-w-10 px-2.5"
|
|
1735
1800
|
}
|
|
1736
1801
|
},
|
|
1737
1802
|
defaultVariants: {
|
|
@@ -1756,12 +1821,12 @@ function Toggle({
|
|
|
1756
1821
|
);
|
|
1757
1822
|
}
|
|
1758
1823
|
function RichtextField({ value, onChange, readOnly, label }) {
|
|
1759
|
-
const ref =
|
|
1824
|
+
const ref = React17__namespace.useRef(null);
|
|
1760
1825
|
const boldLabel = useMsg("richtext.bold");
|
|
1761
1826
|
const italicLabel = useMsg("richtext.italic");
|
|
1762
1827
|
const linkLabel = useMsg("richtext.link");
|
|
1763
1828
|
const linkPrompt = useMsg("richtext.link.prompt");
|
|
1764
|
-
|
|
1829
|
+
React17__namespace.useEffect(() => {
|
|
1765
1830
|
if (ref.current && ref.current.innerHTML !== value) {
|
|
1766
1831
|
ref.current.innerHTML = value ?? "";
|
|
1767
1832
|
}
|
|
@@ -1808,17 +1873,7 @@ function InputGroup({ className, ...props }) {
|
|
|
1808
1873
|
"data-slot": "input-group",
|
|
1809
1874
|
role: "group",
|
|
1810
1875
|
className: cn(
|
|
1811
|
-
"group/input-group
|
|
1812
|
-
"h-9 has-[>textarea]:h-auto",
|
|
1813
|
-
// Variants based on alignment.
|
|
1814
|
-
"has-[>[data-align=inline-start]]:[&>input]:pl-2",
|
|
1815
|
-
"has-[>[data-align=inline-end]]:[&>input]:pr-2",
|
|
1816
|
-
"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3",
|
|
1817
|
-
"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3",
|
|
1818
|
-
// Focus state.
|
|
1819
|
-
"has-[[data-slot=input-group-control]:focus-visible]:ring-ring has-[[data-slot=input-group-control]:focus-visible]:ring-1",
|
|
1820
|
-
// Error state.
|
|
1821
|
-
"has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
|
|
1876
|
+
"group/input-group relative flex h-9 w-full min-w-0 items-center rounded-md border border-input shadow-xs transition-[color,box-shadow] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",
|
|
1822
1877
|
className
|
|
1823
1878
|
),
|
|
1824
1879
|
...props
|
|
@@ -1826,14 +1881,14 @@ function InputGroup({ className, ...props }) {
|
|
|
1826
1881
|
);
|
|
1827
1882
|
}
|
|
1828
1883
|
var inputGroupAddonVariants = classVarianceAuthority.cva(
|
|
1829
|
-
"
|
|
1884
|
+
"flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4",
|
|
1830
1885
|
{
|
|
1831
1886
|
variants: {
|
|
1832
1887
|
align: {
|
|
1833
|
-
"inline-start": "order-first pl-
|
|
1834
|
-
"inline-end": "order-last pr-
|
|
1835
|
-
"block-start": "
|
|
1836
|
-
"block-end": "
|
|
1888
|
+
"inline-start": "order-first pl-2 has-[>button]:-ml-1 has-[>kbd]:ml-[-0.15rem]",
|
|
1889
|
+
"inline-end": "order-last pr-2 has-[>button]:-mr-1 has-[>kbd]:mr-[-0.15rem]",
|
|
1890
|
+
"block-start": "order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
|
|
1891
|
+
"block-end": "order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2"
|
|
1837
1892
|
}
|
|
1838
1893
|
},
|
|
1839
1894
|
defaultVariants: {
|
|
@@ -1868,8 +1923,8 @@ classVarianceAuthority.cva(
|
|
|
1868
1923
|
{
|
|
1869
1924
|
variants: {
|
|
1870
1925
|
size: {
|
|
1871
|
-
xs: "h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-
|
|
1872
|
-
sm: "
|
|
1926
|
+
xs: "h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
|
|
1927
|
+
sm: "",
|
|
1873
1928
|
"icon-xs": "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
|
|
1874
1929
|
"icon-sm": "size-8 p-0 has-[>svg]:p-0"
|
|
1875
1930
|
}
|
|
@@ -1953,7 +2008,7 @@ function CommandItem({
|
|
|
1953
2008
|
{
|
|
1954
2009
|
"data-slot": "command-item",
|
|
1955
2010
|
className: cn(
|
|
1956
|
-
"group/command-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none in-data-[slot=dialog-content]:rounded-lg! data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-selected:bg-muted data-selected:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-selected
|
|
2011
|
+
"group/command-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none in-data-[slot=dialog-content]:rounded-lg! data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-selected:bg-muted data-selected:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-selected:**:[svg]:text-foreground",
|
|
1957
2012
|
className
|
|
1958
2013
|
),
|
|
1959
2014
|
...props,
|
|
@@ -1975,10 +2030,10 @@ function Skeleton({ className, ...props }) {
|
|
|
1975
2030
|
);
|
|
1976
2031
|
}
|
|
1977
2032
|
function ExternalField({ value, onChange, fetchList, readOnly, label }) {
|
|
1978
|
-
const [query, setQuery] =
|
|
1979
|
-
const [results, setResults] =
|
|
1980
|
-
const [loading, setLoading] =
|
|
1981
|
-
|
|
2033
|
+
const [query, setQuery] = React17__namespace.useState("");
|
|
2034
|
+
const [results, setResults] = React17__namespace.useState([]);
|
|
2035
|
+
const [loading, setLoading] = React17__namespace.useState(false);
|
|
2036
|
+
React17__namespace.useEffect(() => {
|
|
1982
2037
|
if (!fetchList) return;
|
|
1983
2038
|
setLoading(true);
|
|
1984
2039
|
const timer = setTimeout(async () => {
|
|
@@ -2024,7 +2079,7 @@ function ExternalField({ value, onChange, fetchList, readOnly, label }) {
|
|
|
2024
2079
|
] }) });
|
|
2025
2080
|
}
|
|
2026
2081
|
|
|
2027
|
-
// src/
|
|
2082
|
+
// src/core/overrides/fields/FieldTypesRegistry.ts
|
|
2028
2083
|
var fieldTypesRegistry = {
|
|
2029
2084
|
text: TextField,
|
|
2030
2085
|
textarea: TextareaField,
|
|
@@ -2042,8 +2097,6 @@ function PuckRoot({ children }) {
|
|
|
2042
2097
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
2043
2098
|
}
|
|
2044
2099
|
var puckOverrides = {
|
|
2045
|
-
header: EditorHeader,
|
|
2046
|
-
headerActions: EditorHeaderActions,
|
|
2047
2100
|
drawer: EditorDrawer,
|
|
2048
2101
|
components: EditorComponents,
|
|
2049
2102
|
drawerItem: DrawerItem,
|
|
@@ -2063,9 +2116,9 @@ var DEFAULT_BOUNDS_OFFSET = {
|
|
|
2063
2116
|
width: 0,
|
|
2064
2117
|
height: 0
|
|
2065
2118
|
};
|
|
2066
|
-
var HighlightContext =
|
|
2119
|
+
var HighlightContext = React17__namespace.createContext(void 0);
|
|
2067
2120
|
function useHighlight() {
|
|
2068
|
-
const context =
|
|
2121
|
+
const context = React17__namespace.useContext(HighlightContext);
|
|
2069
2122
|
if (!context) {
|
|
2070
2123
|
throw new Error("useHighlight must be used within a HighlightProvider");
|
|
2071
2124
|
}
|
|
@@ -2092,21 +2145,21 @@ function Highlight({
|
|
|
2092
2145
|
exitDelay = 200,
|
|
2093
2146
|
mode = "children"
|
|
2094
2147
|
} = props;
|
|
2095
|
-
const localRef =
|
|
2096
|
-
|
|
2148
|
+
const localRef = React17__namespace.useRef(null);
|
|
2149
|
+
React17__namespace.useImperativeHandle(ref, () => localRef.current);
|
|
2097
2150
|
const propsBoundsOffset = props?.boundsOffset;
|
|
2098
2151
|
const boundsOffset = propsBoundsOffset ?? DEFAULT_BOUNDS_OFFSET;
|
|
2099
2152
|
const boundsOffsetTop = boundsOffset.top ?? 0;
|
|
2100
2153
|
const boundsOffsetLeft = boundsOffset.left ?? 0;
|
|
2101
2154
|
const boundsOffsetWidth = boundsOffset.width ?? 0;
|
|
2102
2155
|
const boundsOffsetHeight = boundsOffset.height ?? 0;
|
|
2103
|
-
const boundsOffsetRef =
|
|
2156
|
+
const boundsOffsetRef = React17__namespace.useRef({
|
|
2104
2157
|
top: boundsOffsetTop,
|
|
2105
2158
|
left: boundsOffsetLeft,
|
|
2106
2159
|
width: boundsOffsetWidth,
|
|
2107
2160
|
height: boundsOffsetHeight
|
|
2108
2161
|
});
|
|
2109
|
-
|
|
2162
|
+
React17__namespace.useEffect(() => {
|
|
2110
2163
|
boundsOffsetRef.current = {
|
|
2111
2164
|
top: boundsOffsetTop,
|
|
2112
2165
|
left: boundsOffsetLeft,
|
|
@@ -2119,11 +2172,11 @@ function Highlight({
|
|
|
2119
2172
|
boundsOffsetWidth,
|
|
2120
2173
|
boundsOffsetHeight
|
|
2121
2174
|
]);
|
|
2122
|
-
const [activeValue, setActiveValue] =
|
|
2175
|
+
const [activeValue, setActiveValue] = React17__namespace.useState(
|
|
2123
2176
|
value ?? defaultValue ?? null
|
|
2124
2177
|
);
|
|
2125
|
-
const [boundsState, setBoundsState] =
|
|
2126
|
-
const [activeClassNameState, setActiveClassNameState] =
|
|
2178
|
+
const [boundsState, setBoundsState] = React17__namespace.useState(null);
|
|
2179
|
+
const [activeClassNameState, setActiveClassNameState] = React17__namespace.useState("");
|
|
2127
2180
|
const safeSetActiveValue = (id2) => {
|
|
2128
2181
|
setActiveValue((prev) => {
|
|
2129
2182
|
if (prev !== id2) {
|
|
@@ -2133,8 +2186,8 @@ function Highlight({
|
|
|
2133
2186
|
return prev;
|
|
2134
2187
|
});
|
|
2135
2188
|
};
|
|
2136
|
-
const safeSetBoundsRef =
|
|
2137
|
-
|
|
2189
|
+
const safeSetBoundsRef = React17__namespace.useRef(void 0);
|
|
2190
|
+
React17__namespace.useEffect(() => {
|
|
2138
2191
|
safeSetBoundsRef.current = (bounds) => {
|
|
2139
2192
|
if (!localRef.current) return;
|
|
2140
2193
|
const containerRect = localRef.current.getBoundingClientRect();
|
|
@@ -2156,15 +2209,15 @@ function Highlight({
|
|
|
2156
2209
|
const safeSetBounds = (bounds) => {
|
|
2157
2210
|
safeSetBoundsRef.current?.(bounds);
|
|
2158
2211
|
};
|
|
2159
|
-
const clearBounds =
|
|
2212
|
+
const clearBounds = React17__namespace.useCallback(() => {
|
|
2160
2213
|
setBoundsState((prev) => prev === null ? prev : null);
|
|
2161
2214
|
}, []);
|
|
2162
|
-
|
|
2215
|
+
React17__namespace.useEffect(() => {
|
|
2163
2216
|
if (value !== void 0) setActiveValue(value);
|
|
2164
2217
|
else if (defaultValue !== void 0) setActiveValue(defaultValue);
|
|
2165
2218
|
}, [value, defaultValue]);
|
|
2166
|
-
const id =
|
|
2167
|
-
|
|
2219
|
+
const id = React17__namespace.useId();
|
|
2220
|
+
React17__namespace.useEffect(() => {
|
|
2168
2221
|
if (mode !== "parent") return;
|
|
2169
2222
|
const container = localRef.current;
|
|
2170
2223
|
if (!container) return;
|
|
@@ -2249,7 +2302,7 @@ function Highlight({
|
|
|
2249
2302
|
forceUpdateBounds: props?.forceUpdateBounds
|
|
2250
2303
|
},
|
|
2251
2304
|
children: enabled ? controlledItems ? render(children) : render(
|
|
2252
|
-
|
|
2305
|
+
React17__namespace.Children.map(children, (child, index) => /* @__PURE__ */ jsxRuntime.jsx(HighlightItem, { className: props?.itemsClassName, children: child }, index))
|
|
2253
2306
|
) : children
|
|
2254
2307
|
}
|
|
2255
2308
|
);
|
|
@@ -2281,7 +2334,7 @@ function HighlightItem({
|
|
|
2281
2334
|
forceUpdateBounds,
|
|
2282
2335
|
...props
|
|
2283
2336
|
}) {
|
|
2284
|
-
const itemId =
|
|
2337
|
+
const itemId = React17__namespace.useId();
|
|
2285
2338
|
const {
|
|
2286
2339
|
activeValue,
|
|
2287
2340
|
setActiveValue,
|
|
@@ -2306,12 +2359,12 @@ function HighlightItem({
|
|
|
2306
2359
|
const isActive = activeValue === childValue;
|
|
2307
2360
|
const isDisabled = disabled === void 0 ? contextDisabled : disabled;
|
|
2308
2361
|
const itemTransition = transition ?? contextTransition;
|
|
2309
|
-
const localRef =
|
|
2310
|
-
|
|
2311
|
-
const refCallback =
|
|
2362
|
+
const localRef = React17__namespace.useRef(null);
|
|
2363
|
+
React17__namespace.useImperativeHandle(ref, () => localRef.current);
|
|
2364
|
+
const refCallback = React17__namespace.useCallback((node) => {
|
|
2312
2365
|
localRef.current = node;
|
|
2313
2366
|
}, []);
|
|
2314
|
-
|
|
2367
|
+
React17__namespace.useEffect(() => {
|
|
2315
2368
|
if (mode !== "parent") return;
|
|
2316
2369
|
let rafId;
|
|
2317
2370
|
let previousBounds = null;
|
|
@@ -2345,7 +2398,7 @@ function HighlightItem({
|
|
|
2345
2398
|
forceUpdateBounds,
|
|
2346
2399
|
contextForceUpdateBounds
|
|
2347
2400
|
]);
|
|
2348
|
-
if (!
|
|
2401
|
+
if (!React17__namespace.isValidElement(children)) return children;
|
|
2349
2402
|
const dataAttributes = {
|
|
2350
2403
|
"data-active": isActive ? "true" : "false",
|
|
2351
2404
|
"aria-selected": isActive,
|
|
@@ -2370,7 +2423,7 @@ function HighlightItem({
|
|
|
2370
2423
|
} : {};
|
|
2371
2424
|
if (asChild) {
|
|
2372
2425
|
if (mode === "children") {
|
|
2373
|
-
return
|
|
2426
|
+
return React17__namespace.cloneElement(
|
|
2374
2427
|
element,
|
|
2375
2428
|
{
|
|
2376
2429
|
key: childValue,
|
|
@@ -2422,7 +2475,7 @@ function HighlightItem({
|
|
|
2422
2475
|
] })
|
|
2423
2476
|
);
|
|
2424
2477
|
}
|
|
2425
|
-
return
|
|
2478
|
+
return React17__namespace.cloneElement(element, {
|
|
2426
2479
|
ref: refCallback,
|
|
2427
2480
|
...getNonOverridingDataAttributes(element, {
|
|
2428
2481
|
...dataAttributes,
|
|
@@ -2466,7 +2519,7 @@ function HighlightItem({
|
|
|
2466
2519
|
...dataAttributes
|
|
2467
2520
|
}
|
|
2468
2521
|
) }),
|
|
2469
|
-
|
|
2522
|
+
React17__namespace.cloneElement(element, {
|
|
2470
2523
|
style: { position: "relative", zIndex: 1 },
|
|
2471
2524
|
className: element.props.className,
|
|
2472
2525
|
...getNonOverridingDataAttributes(element, {
|
|
@@ -2513,11 +2566,11 @@ function Slot({
|
|
|
2513
2566
|
...props
|
|
2514
2567
|
}) {
|
|
2515
2568
|
const isAlreadyMotion = typeof children.type === "object" && children.type !== null && react.isMotionComponent(children.type);
|
|
2516
|
-
const Base =
|
|
2569
|
+
const Base = React17__namespace.useMemo(
|
|
2517
2570
|
() => isAlreadyMotion ? children.type : react.motion.create(children.type),
|
|
2518
2571
|
[isAlreadyMotion, children.type]
|
|
2519
2572
|
);
|
|
2520
|
-
if (!
|
|
2573
|
+
if (!React17__namespace.isValidElement(children)) return null;
|
|
2521
2574
|
const { ref: childRef, ...childProps } = children.props;
|
|
2522
2575
|
const mergedProps = mergeProps4(childProps, props);
|
|
2523
2576
|
return /* @__PURE__ */ jsxRuntime.jsx(Base, { ...mergedProps, ref: mergeRefs(childRef, ref) });
|
|
@@ -2597,6 +2650,52 @@ function TabsTab2({ className, ...props }) {
|
|
|
2597
2650
|
}
|
|
2598
2651
|
) });
|
|
2599
2652
|
}
|
|
2653
|
+
var ACTIVE_TABS = [
|
|
2654
|
+
"insert",
|
|
2655
|
+
"layer",
|
|
2656
|
+
"image",
|
|
2657
|
+
"text",
|
|
2658
|
+
"copilot"
|
|
2659
|
+
];
|
|
2660
|
+
var activeTabSet = new Set(ACTIVE_TABS);
|
|
2661
|
+
function isActiveTab(value) {
|
|
2662
|
+
return activeTabSet.has(value);
|
|
2663
|
+
}
|
|
2664
|
+
function createEditorUiStore(storeId) {
|
|
2665
|
+
return zustand.createStore()(
|
|
2666
|
+
middleware.persist(
|
|
2667
|
+
(set) => ({
|
|
2668
|
+
drawerSearch: "",
|
|
2669
|
+
setDrawerSearch: (q) => set({ drawerSearch: q }),
|
|
2670
|
+
drawerCollapsed: {},
|
|
2671
|
+
toggleDrawerGroup: (group) => set((s) => ({
|
|
2672
|
+
drawerCollapsed: { ...s.drawerCollapsed, [group]: !s.drawerCollapsed[group] }
|
|
2673
|
+
})),
|
|
2674
|
+
activeTab: "insert",
|
|
2675
|
+
setActiveTab: (tab) => set({ activeTab: tab }),
|
|
2676
|
+
outlineExpanded: {},
|
|
2677
|
+
toggleOutlineItem: (id) => set((s) => ({
|
|
2678
|
+
outlineExpanded: { ...s.outlineExpanded, [id]: !s.outlineExpanded[id] }
|
|
2679
|
+
})),
|
|
2680
|
+
theme: "light",
|
|
2681
|
+
toggleTheme: () => set((s) => {
|
|
2682
|
+
const next = s.theme === "light" ? "dark" : "light";
|
|
2683
|
+
return { theme: next };
|
|
2684
|
+
})
|
|
2685
|
+
}),
|
|
2686
|
+
{
|
|
2687
|
+
name: `anvilkit-ui-${storeId}`,
|
|
2688
|
+
partialize: (s) => ({
|
|
2689
|
+
activeTab: s.activeTab,
|
|
2690
|
+
drawerCollapsed: s.drawerCollapsed,
|
|
2691
|
+
outlineExpanded: s.outlineExpanded,
|
|
2692
|
+
theme: s.theme
|
|
2693
|
+
// drawerSearch intentionally excluded — transient input
|
|
2694
|
+
})
|
|
2695
|
+
}
|
|
2696
|
+
)
|
|
2697
|
+
);
|
|
2698
|
+
}
|
|
2600
2699
|
function Aside() {
|
|
2601
2700
|
const activeTab = useActiveTab();
|
|
2602
2701
|
const setActiveTab = useSetActiveTab();
|
|
@@ -2607,10 +2706,35 @@ function Aside() {
|
|
|
2607
2706
|
{ value: "text", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Type, { className: "h-4 w-4" }), label: useMsg("aside.text") },
|
|
2608
2707
|
{ value: "copilot", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bot, { className: "h-4 w-4" }), label: useMsg("aside.copilot") }
|
|
2609
2708
|
];
|
|
2610
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-18 h-full py-4 border-r border-neutral-200 dark:border-neutral-800/80", children: /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2709
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-18 h-full py-4 border-r border-neutral-200 dark:border-neutral-800/80", children: /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2710
|
+
Tabs2,
|
|
2711
|
+
{
|
|
2712
|
+
value: activeTab,
|
|
2713
|
+
onValueChange: (value) => {
|
|
2714
|
+
if (isActiveTab(value)) {
|
|
2715
|
+
setActiveTab(value);
|
|
2716
|
+
}
|
|
2717
|
+
},
|
|
2718
|
+
className: "w-full flex items-center justify-center",
|
|
2719
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(TabsList2, { className: "flex-col h-auto bg-transparent gap-2", children: tabs.map(({ value, icon, label }) => /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
2720
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2721
|
+
TooltipTrigger,
|
|
2722
|
+
{
|
|
2723
|
+
render: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2724
|
+
TabsTab2,
|
|
2725
|
+
{
|
|
2726
|
+
value,
|
|
2727
|
+
className: "p-2",
|
|
2728
|
+
"aria-label": label
|
|
2729
|
+
}
|
|
2730
|
+
),
|
|
2731
|
+
children: icon
|
|
2732
|
+
}
|
|
2733
|
+
),
|
|
2734
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "right", children: label })
|
|
2735
|
+
] }, value)) })
|
|
2736
|
+
}
|
|
2737
|
+
) }) });
|
|
2614
2738
|
}
|
|
2615
2739
|
function AnimatedAsana({
|
|
2616
2740
|
trigger = false,
|
|
@@ -2627,15 +2751,15 @@ function AnimatedAsana({
|
|
|
2627
2751
|
// Default non-priority
|
|
2628
2752
|
...props
|
|
2629
2753
|
}) {
|
|
2630
|
-
const [isHovered, setIsHovered] =
|
|
2631
|
-
const [animationPhase, setAnimationPhase] =
|
|
2632
|
-
const animationTimerRef =
|
|
2633
|
-
const animationStartedRef =
|
|
2634
|
-
const effectiveTrigger =
|
|
2754
|
+
const [isHovered, setIsHovered] = React17.useState(false);
|
|
2755
|
+
const [animationPhase, setAnimationPhase] = React17.useState("three-circles");
|
|
2756
|
+
const animationTimerRef = React17.useRef(null);
|
|
2757
|
+
const animationStartedRef = React17.useRef(false);
|
|
2758
|
+
const effectiveTrigger = React17.useMemo(
|
|
2635
2759
|
() => trigger || useTrigger && isHovered,
|
|
2636
2760
|
[trigger, useTrigger, isHovered]
|
|
2637
2761
|
);
|
|
2638
|
-
const springTransition =
|
|
2762
|
+
const springTransition = React17.useMemo(
|
|
2639
2763
|
() => ({
|
|
2640
2764
|
type: "spring",
|
|
2641
2765
|
stiffness: springConfig.stiffness,
|
|
@@ -2644,17 +2768,17 @@ function AnimatedAsana({
|
|
|
2644
2768
|
}),
|
|
2645
2769
|
[springConfig.stiffness, springConfig.damping, springConfig.mass]
|
|
2646
2770
|
);
|
|
2647
|
-
const handleMouseEnter =
|
|
2771
|
+
const handleMouseEnter = React17.useCallback(() => {
|
|
2648
2772
|
if (useTrigger) {
|
|
2649
2773
|
setIsHovered(true);
|
|
2650
2774
|
}
|
|
2651
2775
|
}, [useTrigger]);
|
|
2652
|
-
const handleMouseLeave =
|
|
2776
|
+
const handleMouseLeave = React17.useCallback(() => {
|
|
2653
2777
|
if (useTrigger) {
|
|
2654
2778
|
setIsHovered(false);
|
|
2655
2779
|
}
|
|
2656
2780
|
}, [useTrigger]);
|
|
2657
|
-
|
|
2781
|
+
React17.useEffect(() => {
|
|
2658
2782
|
if (animationTimerRef.current) {
|
|
2659
2783
|
clearTimeout(animationTimerRef.current);
|
|
2660
2784
|
animationTimerRef.current = null;
|
|
@@ -2677,14 +2801,14 @@ function AnimatedAsana({
|
|
|
2677
2801
|
}
|
|
2678
2802
|
};
|
|
2679
2803
|
}, [effectiveTrigger, animationDuration]);
|
|
2680
|
-
const centerCircleAnimation =
|
|
2804
|
+
const centerCircleAnimation = React17.useMemo(
|
|
2681
2805
|
() => ({
|
|
2682
2806
|
opacity: animationPhase === "one-circle" ? 1 : 0,
|
|
2683
2807
|
scale: animationPhase === "one-circle" ? 1 : 0
|
|
2684
2808
|
}),
|
|
2685
2809
|
[animationPhase]
|
|
2686
2810
|
);
|
|
2687
|
-
const topCircleAnimation =
|
|
2811
|
+
const topCircleAnimation = React17.useMemo(
|
|
2688
2812
|
() => ({
|
|
2689
2813
|
opacity: animationPhase === "three-circles" ? 1 : 0,
|
|
2690
2814
|
y: animationPhase === "three-circles" ? 0 : 4.5,
|
|
@@ -2692,7 +2816,7 @@ function AnimatedAsana({
|
|
|
2692
2816
|
}),
|
|
2693
2817
|
[animationPhase]
|
|
2694
2818
|
);
|
|
2695
|
-
const leftBottomCircleAnimation =
|
|
2819
|
+
const leftBottomCircleAnimation = React17.useMemo(
|
|
2696
2820
|
() => ({
|
|
2697
2821
|
opacity: animationPhase === "three-circles" ? 1 : 0,
|
|
2698
2822
|
x: animationPhase === "three-circles" ? 0 : 5,
|
|
@@ -2701,7 +2825,7 @@ function AnimatedAsana({
|
|
|
2701
2825
|
}),
|
|
2702
2826
|
[animationPhase]
|
|
2703
2827
|
);
|
|
2704
|
-
const rightBottomCircleAnimation =
|
|
2828
|
+
const rightBottomCircleAnimation = React17.useMemo(
|
|
2705
2829
|
() => ({
|
|
2706
2830
|
opacity: animationPhase === "three-circles" ? 1 : 0,
|
|
2707
2831
|
x: animationPhase === "three-circles" ? 0 : -5,
|
|
@@ -2802,10 +2926,10 @@ function AnimatedAsana({
|
|
|
2802
2926
|
}
|
|
2803
2927
|
);
|
|
2804
2928
|
}
|
|
2805
|
-
|
|
2929
|
+
React17__namespace.default.memo(function TriggerableAsana2(props) {
|
|
2806
2930
|
return /* @__PURE__ */ jsxRuntime.jsx(AnimatedAsana, { useTrigger: true, ...props });
|
|
2807
2931
|
});
|
|
2808
|
-
|
|
2932
|
+
React17__namespace.default.memo(function ControlledAsana2(props) {
|
|
2809
2933
|
return /* @__PURE__ */ jsxRuntime.jsx(AnimatedAsana, { useTrigger: false, ...props });
|
|
2810
2934
|
});
|
|
2811
2935
|
var [GlobalTooltipProvider, useGlobalTooltip] = getStrictContext("GlobalTooltipProvider");
|
|
@@ -2831,12 +2955,12 @@ function TooltipProvider2({
|
|
|
2831
2955
|
closeDelay = 300,
|
|
2832
2956
|
transition = { type: "spring", stiffness: 300, damping: 35 }
|
|
2833
2957
|
}) {
|
|
2834
|
-
const globalId =
|
|
2835
|
-
const [currentTooltip, setCurrentTooltip] =
|
|
2836
|
-
const timeoutRef =
|
|
2837
|
-
const lastCloseTimeRef =
|
|
2838
|
-
const referenceElRef =
|
|
2839
|
-
const showTooltip =
|
|
2958
|
+
const globalId = React17__namespace.useId();
|
|
2959
|
+
const [currentTooltip, setCurrentTooltip] = React17__namespace.useState(null);
|
|
2960
|
+
const timeoutRef = React17__namespace.useRef(null);
|
|
2961
|
+
const lastCloseTimeRef = React17__namespace.useRef(0);
|
|
2962
|
+
const referenceElRef = React17__namespace.useRef(null);
|
|
2963
|
+
const showTooltip = React17__namespace.useCallback(
|
|
2840
2964
|
(data) => {
|
|
2841
2965
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
2842
2966
|
if (currentTooltip !== null) {
|
|
@@ -2852,22 +2976,22 @@ function TooltipProvider2({
|
|
|
2852
2976
|
},
|
|
2853
2977
|
[openDelay, closeDelay, currentTooltip]
|
|
2854
2978
|
);
|
|
2855
|
-
const hideTooltip =
|
|
2979
|
+
const hideTooltip = React17__namespace.useCallback(() => {
|
|
2856
2980
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
2857
2981
|
timeoutRef.current = window.setTimeout(() => {
|
|
2858
2982
|
setCurrentTooltip(null);
|
|
2859
2983
|
lastCloseTimeRef.current = Date.now();
|
|
2860
2984
|
}, closeDelay);
|
|
2861
2985
|
}, [closeDelay]);
|
|
2862
|
-
const hideImmediate =
|
|
2986
|
+
const hideImmediate = React17__namespace.useCallback(() => {
|
|
2863
2987
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
2864
2988
|
setCurrentTooltip(null);
|
|
2865
2989
|
lastCloseTimeRef.current = Date.now();
|
|
2866
2990
|
}, []);
|
|
2867
|
-
const setReferenceEl =
|
|
2991
|
+
const setReferenceEl = React17__namespace.useCallback((el) => {
|
|
2868
2992
|
referenceElRef.current = el;
|
|
2869
2993
|
}, []);
|
|
2870
|
-
|
|
2994
|
+
React17__namespace.useEffect(() => {
|
|
2871
2995
|
const onKeyDown = (e) => {
|
|
2872
2996
|
if (e.key === "Escape") hideImmediate();
|
|
2873
2997
|
};
|
|
@@ -2911,7 +3035,7 @@ function TooltipArrow({
|
|
|
2911
3035
|
const { side, align, open } = useRenderedTooltip();
|
|
2912
3036
|
const { context, arrowRef } = useFloatingContext();
|
|
2913
3037
|
const { transition, globalId } = useGlobalTooltip();
|
|
2914
|
-
|
|
3038
|
+
React17__namespace.useImperativeHandle(ref, () => arrowRef.current);
|
|
2915
3039
|
const deg = { top: 0, right: 90, bottom: 180, left: -90 }[side];
|
|
2916
3040
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2917
3041
|
MotionTooltipArrow,
|
|
@@ -2934,8 +3058,8 @@ function TooltipPortal(props) {
|
|
|
2934
3058
|
}
|
|
2935
3059
|
function TooltipOverlay() {
|
|
2936
3060
|
const { currentTooltip, transition, globalId, referenceElRef } = useGlobalTooltip();
|
|
2937
|
-
const [rendered, setRendered] =
|
|
2938
|
-
const arrowRef =
|
|
3061
|
+
const [rendered, setRendered] = React17__namespace.useState({ data: null, open: false });
|
|
3062
|
+
const arrowRef = React17__namespace.useRef(null);
|
|
2939
3063
|
const side = rendered.data?.side ?? "top";
|
|
2940
3064
|
const align = rendered.data?.align ?? "center";
|
|
2941
3065
|
const { refs, x, y, strategy, context, update } = react$1.useFloating({
|
|
@@ -2951,14 +3075,14 @@ function TooltipOverlay() {
|
|
|
2951
3075
|
react$1.arrow({ element: arrowRef })
|
|
2952
3076
|
]
|
|
2953
3077
|
});
|
|
2954
|
-
|
|
3078
|
+
React17__namespace.useEffect(() => {
|
|
2955
3079
|
if (currentTooltip) {
|
|
2956
3080
|
setRendered({ data: currentTooltip, open: true });
|
|
2957
3081
|
} else {
|
|
2958
3082
|
setRendered((p) => p.data ? { ...p, open: false } : p);
|
|
2959
3083
|
}
|
|
2960
3084
|
}, [currentTooltip]);
|
|
2961
|
-
|
|
3085
|
+
React17__namespace.useLayoutEffect(() => {
|
|
2962
3086
|
if (referenceElRef.current) {
|
|
2963
3087
|
refs.setReference(referenceElRef.current);
|
|
2964
3088
|
update();
|
|
@@ -3037,9 +3161,9 @@ function Tooltip2({
|
|
|
3037
3161
|
align = "center",
|
|
3038
3162
|
alignOffset = 0
|
|
3039
3163
|
}) {
|
|
3040
|
-
const id =
|
|
3041
|
-
const [props, setProps] =
|
|
3042
|
-
const [asChild, setAsChild] =
|
|
3164
|
+
const id = React17__namespace.useId();
|
|
3165
|
+
const [props, setProps] = React17__namespace.useState({});
|
|
3166
|
+
const [asChild, setAsChild] = React17__namespace.useState(false);
|
|
3043
3167
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3044
3168
|
LocalTooltipProvider,
|
|
3045
3169
|
{
|
|
@@ -3071,16 +3195,16 @@ function shallowEqualWithoutChildren(a, b) {
|
|
|
3071
3195
|
}
|
|
3072
3196
|
function TooltipContent2({ asChild = false, ...props }) {
|
|
3073
3197
|
const { setProps, setAsChild } = useTooltip();
|
|
3074
|
-
const lastPropsRef =
|
|
3198
|
+
const lastPropsRef = React17__namespace.useRef(
|
|
3075
3199
|
void 0
|
|
3076
3200
|
);
|
|
3077
|
-
|
|
3201
|
+
React17__namespace.useEffect(() => {
|
|
3078
3202
|
if (!shallowEqualWithoutChildren(lastPropsRef.current, props)) {
|
|
3079
3203
|
lastPropsRef.current = props;
|
|
3080
3204
|
setProps(props);
|
|
3081
3205
|
}
|
|
3082
3206
|
}, [props, setProps]);
|
|
3083
|
-
|
|
3207
|
+
React17__namespace.useEffect(() => {
|
|
3084
3208
|
setAsChild(asChild);
|
|
3085
3209
|
}, [asChild, setAsChild]);
|
|
3086
3210
|
return null;
|
|
@@ -3111,10 +3235,10 @@ function TooltipTrigger2({
|
|
|
3111
3235
|
currentTooltip,
|
|
3112
3236
|
setReferenceEl
|
|
3113
3237
|
} = useGlobalTooltip();
|
|
3114
|
-
const triggerRef =
|
|
3115
|
-
|
|
3116
|
-
const suppressNextFocusRef =
|
|
3117
|
-
const handleOpen =
|
|
3238
|
+
const triggerRef = React17__namespace.useRef(null);
|
|
3239
|
+
React17__namespace.useImperativeHandle(ref, () => triggerRef.current);
|
|
3240
|
+
const suppressNextFocusRef = React17__namespace.useRef(false);
|
|
3241
|
+
const handleOpen = React17__namespace.useCallback(() => {
|
|
3118
3242
|
if (!triggerRef.current) return;
|
|
3119
3243
|
setReferenceEl(triggerRef.current);
|
|
3120
3244
|
const rect = triggerRef.current.getBoundingClientRect();
|
|
@@ -3139,7 +3263,7 @@ function TooltipTrigger2({
|
|
|
3139
3263
|
alignOffset,
|
|
3140
3264
|
id
|
|
3141
3265
|
]);
|
|
3142
|
-
const handlePointerDown =
|
|
3266
|
+
const handlePointerDown = React17__namespace.useCallback(
|
|
3143
3267
|
(e) => {
|
|
3144
3268
|
onPointerDown?.(e);
|
|
3145
3269
|
if (currentTooltip?.id === id) {
|
|
@@ -3152,21 +3276,21 @@ function TooltipTrigger2({
|
|
|
3152
3276
|
},
|
|
3153
3277
|
[onPointerDown, currentTooltip?.id, id, hideImmediate]
|
|
3154
3278
|
);
|
|
3155
|
-
const handleMouseEnter =
|
|
3279
|
+
const handleMouseEnter = React17__namespace.useCallback(
|
|
3156
3280
|
(e) => {
|
|
3157
3281
|
onMouseEnter?.(e);
|
|
3158
3282
|
handleOpen();
|
|
3159
3283
|
},
|
|
3160
3284
|
[handleOpen, onMouseEnter]
|
|
3161
3285
|
);
|
|
3162
|
-
const handleMouseLeave =
|
|
3286
|
+
const handleMouseLeave = React17__namespace.useCallback(
|
|
3163
3287
|
(e) => {
|
|
3164
3288
|
onMouseLeave?.(e);
|
|
3165
3289
|
hideTooltip();
|
|
3166
3290
|
},
|
|
3167
3291
|
[hideTooltip, onMouseLeave]
|
|
3168
3292
|
);
|
|
3169
|
-
const handleFocus =
|
|
3293
|
+
const handleFocus = React17__namespace.useCallback(
|
|
3170
3294
|
(e) => {
|
|
3171
3295
|
onFocus?.(e);
|
|
3172
3296
|
if (suppressNextFocusRef.current) return;
|
|
@@ -3174,7 +3298,7 @@ function TooltipTrigger2({
|
|
|
3174
3298
|
},
|
|
3175
3299
|
[handleOpen, onFocus]
|
|
3176
3300
|
);
|
|
3177
|
-
const handleBlur =
|
|
3301
|
+
const handleBlur = React17__namespace.useCallback(
|
|
3178
3302
|
(e) => {
|
|
3179
3303
|
onBlur?.(e);
|
|
3180
3304
|
hideTooltip();
|
|
@@ -3276,7 +3400,7 @@ function AvatarGroup({
|
|
|
3276
3400
|
children: children?.map((child, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3277
3401
|
AvatarContainer,
|
|
3278
3402
|
{
|
|
3279
|
-
zIndex: invertOverlap ?
|
|
3403
|
+
zIndex: invertOverlap ? React17__namespace.Children.count(children) - index : index,
|
|
3280
3404
|
transition,
|
|
3281
3405
|
translate,
|
|
3282
3406
|
side,
|
|
@@ -3327,7 +3451,7 @@ function AvatarGroupTooltip2({
|
|
|
3327
3451
|
),
|
|
3328
3452
|
...props,
|
|
3329
3453
|
children: [
|
|
3330
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3454
|
+
/* @__PURE__ */ jsxRuntime.jsx(motion8__namespace.div, { layout, className: "overflow-hidden", children }),
|
|
3331
3455
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3332
3456
|
AvatarGroupTooltipArrow,
|
|
3333
3457
|
{
|
|
@@ -3350,7 +3474,7 @@ function Avatar({
|
|
|
3350
3474
|
"data-slot": "avatar",
|
|
3351
3475
|
"data-size": size,
|
|
3352
3476
|
className: cn(
|
|
3353
|
-
"
|
|
3477
|
+
"group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten",
|
|
3354
3478
|
className
|
|
3355
3479
|
),
|
|
3356
3480
|
...props
|
|
@@ -3363,7 +3487,7 @@ function AvatarImage({ className, ...props }) {
|
|
|
3363
3487
|
{
|
|
3364
3488
|
"data-slot": "avatar-image",
|
|
3365
3489
|
className: cn(
|
|
3366
|
-
"
|
|
3490
|
+
"aspect-square size-full rounded-full object-cover",
|
|
3367
3491
|
className
|
|
3368
3492
|
),
|
|
3369
3493
|
...props
|
|
@@ -3379,7 +3503,7 @@ function AvatarFallback({
|
|
|
3379
3503
|
{
|
|
3380
3504
|
"data-slot": "avatar-fallback",
|
|
3381
3505
|
className: cn(
|
|
3382
|
-
"
|
|
3506
|
+
"flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs",
|
|
3383
3507
|
className
|
|
3384
3508
|
),
|
|
3385
3509
|
...props
|
|
@@ -3406,8 +3530,8 @@ var Collaborators = () => {
|
|
|
3406
3530
|
] }, index)) });
|
|
3407
3531
|
};
|
|
3408
3532
|
var Share = () => {
|
|
3409
|
-
const [access, setAccess] =
|
|
3410
|
-
const [copied, setCopied] =
|
|
3533
|
+
const [access, setAccess] = React17__namespace.useState("private");
|
|
3534
|
+
const [copied, setCopied] = React17__namespace.useState(false);
|
|
3411
3535
|
const shareUrl = typeof window !== "undefined" ? window.location.href : "";
|
|
3412
3536
|
const shareButton = useMsg("share.button");
|
|
3413
3537
|
const shareTitle = useMsg("share.title");
|
|
@@ -3520,6 +3644,78 @@ var CollaboratorsPopover = () => {
|
|
|
3520
3644
|
] })
|
|
3521
3645
|
] });
|
|
3522
3646
|
};
|
|
3647
|
+
|
|
3648
|
+
// src/features/export/export-json.ts
|
|
3649
|
+
function getFilename(filenameBase) {
|
|
3650
|
+
const safeBase = filenameBase?.trim() || "page";
|
|
3651
|
+
return `${safeBase}.json`;
|
|
3652
|
+
}
|
|
3653
|
+
function exportDataAsJson(data, { filenameBase, document: targetDocument } = {}) {
|
|
3654
|
+
const resolvedDocument = targetDocument ?? (typeof document !== "undefined" ? document : void 0);
|
|
3655
|
+
if (!resolvedDocument) return;
|
|
3656
|
+
const blob = new Blob([JSON.stringify(data, null, 2)], {
|
|
3657
|
+
type: "application/json"
|
|
3658
|
+
});
|
|
3659
|
+
const url = URL.createObjectURL(blob);
|
|
3660
|
+
const link = resolvedDocument.createElement("a");
|
|
3661
|
+
link.href = url;
|
|
3662
|
+
link.download = getFilename(filenameBase);
|
|
3663
|
+
link.click();
|
|
3664
|
+
URL.revokeObjectURL(url);
|
|
3665
|
+
}
|
|
3666
|
+
function DropdownMenu({ ...props }) {
|
|
3667
|
+
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
3668
|
+
}
|
|
3669
|
+
function DropdownMenuTrigger({ ...props }) {
|
|
3670
|
+
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
3671
|
+
}
|
|
3672
|
+
function DropdownMenuContent({
|
|
3673
|
+
align = "start",
|
|
3674
|
+
alignOffset = 0,
|
|
3675
|
+
side = "bottom",
|
|
3676
|
+
sideOffset = 4,
|
|
3677
|
+
className,
|
|
3678
|
+
...props
|
|
3679
|
+
}) {
|
|
3680
|
+
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3681
|
+
menu.Menu.Positioner,
|
|
3682
|
+
{
|
|
3683
|
+
className: "isolate z-50 outline-none",
|
|
3684
|
+
align,
|
|
3685
|
+
alignOffset,
|
|
3686
|
+
side,
|
|
3687
|
+
sideOffset,
|
|
3688
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3689
|
+
menu.Menu.Popup,
|
|
3690
|
+
{
|
|
3691
|
+
"data-slot": "dropdown-menu-content",
|
|
3692
|
+
className: cn("z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95", className),
|
|
3693
|
+
...props
|
|
3694
|
+
}
|
|
3695
|
+
)
|
|
3696
|
+
}
|
|
3697
|
+
) });
|
|
3698
|
+
}
|
|
3699
|
+
function DropdownMenuItem({
|
|
3700
|
+
className,
|
|
3701
|
+
inset,
|
|
3702
|
+
variant = "default",
|
|
3703
|
+
...props
|
|
3704
|
+
}) {
|
|
3705
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3706
|
+
menu.Menu.Item,
|
|
3707
|
+
{
|
|
3708
|
+
"data-slot": "dropdown-menu-item",
|
|
3709
|
+
"data-inset": inset,
|
|
3710
|
+
"data-variant": variant,
|
|
3711
|
+
className: cn(
|
|
3712
|
+
"group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",
|
|
3713
|
+
className
|
|
3714
|
+
),
|
|
3715
|
+
...props
|
|
3716
|
+
}
|
|
3717
|
+
);
|
|
3718
|
+
}
|
|
3523
3719
|
var Header = () => {
|
|
3524
3720
|
const { history, appState } = core.usePuck();
|
|
3525
3721
|
const publish = useMsg("header.publish");
|
|
@@ -3534,9 +3730,7 @@ var Header = () => {
|
|
|
3534
3730
|
const themeLightLabel = useMsg("header.theme.light");
|
|
3535
3731
|
const themeDarkLabel = useMsg("header.theme.dark");
|
|
3536
3732
|
const themeLabel = theme === "dark" ? themeLightLabel : themeDarkLabel;
|
|
3537
|
-
|
|
3538
|
-
document.documentElement.classList.toggle("dark", theme === "dark");
|
|
3539
|
-
}, []);
|
|
3733
|
+
useThemeSync();
|
|
3540
3734
|
return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex overflow-hidden transition-all duration-300 backdrop-blur-xl w-full border-b border-neutral-200 dark:border-neutral-800 items-center h-[54px] py-0", children: [
|
|
3541
3735
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-18 flex items-center justify-center h-full border-r border-neutral-200 dark:border-neutral-800/80", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center w-10 h-10 bg-primary rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(AnimatedAsana, { className: "text-white text-2xl" }) }) }),
|
|
3542
3736
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-1 w-full px-2", children: [
|
|
@@ -3544,31 +3738,41 @@ var Header = () => {
|
|
|
3544
3738
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none text-sm font-medium", children: appState?.data?.root?.props?.title || "" }),
|
|
3545
3739
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 h-full ml-auto", children: [
|
|
3546
3740
|
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
3547
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3548
|
-
|
|
3741
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3742
|
+
TooltipTrigger,
|
|
3549
3743
|
{
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3744
|
+
render: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3745
|
+
Button,
|
|
3746
|
+
{
|
|
3747
|
+
variant: "ghost",
|
|
3748
|
+
size: "icon",
|
|
3749
|
+
disabled: !history.hasPast,
|
|
3750
|
+
onClick: () => history.back(),
|
|
3751
|
+
"aria-label": undo
|
|
3752
|
+
}
|
|
3753
|
+
),
|
|
3555
3754
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Undo2, { className: "h-4 w-4" })
|
|
3556
3755
|
}
|
|
3557
|
-
)
|
|
3756
|
+
),
|
|
3558
3757
|
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: undoTooltip })
|
|
3559
3758
|
] }),
|
|
3560
3759
|
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
3561
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3562
|
-
|
|
3760
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3761
|
+
TooltipTrigger,
|
|
3563
3762
|
{
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3763
|
+
render: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3764
|
+
Button,
|
|
3765
|
+
{
|
|
3766
|
+
variant: "ghost",
|
|
3767
|
+
size: "icon",
|
|
3768
|
+
disabled: !history.hasFuture,
|
|
3769
|
+
onClick: () => history.forward(),
|
|
3770
|
+
"aria-label": redo
|
|
3771
|
+
}
|
|
3772
|
+
),
|
|
3569
3773
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Redo2, { className: "h-4 w-4" })
|
|
3570
3774
|
}
|
|
3571
|
-
)
|
|
3775
|
+
),
|
|
3572
3776
|
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: redoTooltip })
|
|
3573
3777
|
] }),
|
|
3574
3778
|
/* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "h-5 mx-1" }),
|
|
@@ -3578,21 +3782,34 @@ var Header = () => {
|
|
|
3578
3782
|
/* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "h-5 mx-1" }),
|
|
3579
3783
|
/* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
|
|
3580
3784
|
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
3581
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3785
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3786
|
+
TooltipTrigger,
|
|
3787
|
+
{
|
|
3788
|
+
render: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3789
|
+
DropdownMenuTrigger,
|
|
3790
|
+
{
|
|
3791
|
+
render: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3792
|
+
Button,
|
|
3793
|
+
{
|
|
3794
|
+
variant: "ghost",
|
|
3795
|
+
size: "icon",
|
|
3796
|
+
"aria-label": exportLabel
|
|
3797
|
+
}
|
|
3798
|
+
)
|
|
3799
|
+
}
|
|
3800
|
+
),
|
|
3801
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "h-4 w-4" })
|
|
3802
|
+
}
|
|
3803
|
+
),
|
|
3582
3804
|
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: exportLabel })
|
|
3583
3805
|
] }),
|
|
3584
3806
|
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "end", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3585
3807
|
DropdownMenuItem,
|
|
3586
3808
|
{
|
|
3587
3809
|
onClick: () => {
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
const a = document.createElement("a");
|
|
3592
|
-
a.href = url;
|
|
3593
|
-
a.download = `${appState.data.root?.props?.title || "page"}.json`;
|
|
3594
|
-
a.click();
|
|
3595
|
-
URL.revokeObjectURL(url);
|
|
3810
|
+
exportDataAsJson(appState.data, {
|
|
3811
|
+
filenameBase: appState.data.root?.props?.title
|
|
3812
|
+
});
|
|
3596
3813
|
},
|
|
3597
3814
|
children: [
|
|
3598
3815
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileDown, { className: "h-4 w-4" }),
|
|
@@ -3604,21 +3821,79 @@ var Header = () => {
|
|
|
3604
3821
|
] }),
|
|
3605
3822
|
/* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "h-5 mx-1" }),
|
|
3606
3823
|
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
3607
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3824
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3825
|
+
TooltipTrigger,
|
|
3826
|
+
{
|
|
3827
|
+
render: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3828
|
+
Button,
|
|
3829
|
+
{
|
|
3830
|
+
variant: "ghost",
|
|
3831
|
+
size: "icon",
|
|
3832
|
+
onClick: toggleTheme,
|
|
3833
|
+
"aria-label": themeLabel
|
|
3834
|
+
}
|
|
3835
|
+
),
|
|
3836
|
+
children: theme === "dark" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sun, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Moon, { className: "h-4 w-4" })
|
|
3837
|
+
}
|
|
3838
|
+
),
|
|
3608
3839
|
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: themeLabel })
|
|
3609
3840
|
] }),
|
|
3610
3841
|
/* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "h-5 mx-1" }),
|
|
3611
3842
|
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
3612
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3843
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3844
|
+
TooltipTrigger,
|
|
3845
|
+
{
|
|
3846
|
+
render: /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", "aria-label": publish }),
|
|
3847
|
+
children: [
|
|
3848
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-4 w-4" }),
|
|
3849
|
+
publish
|
|
3850
|
+
]
|
|
3851
|
+
}
|
|
3852
|
+
),
|
|
3616
3853
|
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: publish })
|
|
3617
3854
|
] })
|
|
3618
3855
|
] })
|
|
3619
3856
|
] })
|
|
3620
3857
|
] }) });
|
|
3621
3858
|
};
|
|
3859
|
+
function useGhostDrag({ createGhostEl }) {
|
|
3860
|
+
const ghostRef = React17__namespace.useRef(null);
|
|
3861
|
+
function moveGhost(x, y) {
|
|
3862
|
+
if (!ghostRef.current) return;
|
|
3863
|
+
ghostRef.current.style.left = `${x + 12}px`;
|
|
3864
|
+
ghostRef.current.style.top = `${y + 12}px`;
|
|
3865
|
+
}
|
|
3866
|
+
function removeGhost() {
|
|
3867
|
+
ghostRef.current?.remove();
|
|
3868
|
+
ghostRef.current = null;
|
|
3869
|
+
}
|
|
3870
|
+
const startDrag = React17__namespace.useCallback(
|
|
3871
|
+
(e, type, payload) => {
|
|
3872
|
+
e.stopPropagation();
|
|
3873
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
3874
|
+
ghostRef.current = createGhostEl(payload);
|
|
3875
|
+
moveGhost(e.clientX, e.clientY);
|
|
3876
|
+
dispatchLibraryDragStart(type);
|
|
3877
|
+
function onMove(ev) {
|
|
3878
|
+
moveGhost(ev.clientX, ev.clientY);
|
|
3879
|
+
}
|
|
3880
|
+
function onUp(ev) {
|
|
3881
|
+
removeGhost();
|
|
3882
|
+
window.removeEventListener("pointermove", onMove);
|
|
3883
|
+
window.removeEventListener("pointerup", onUp);
|
|
3884
|
+
if (type === "image") {
|
|
3885
|
+
dispatchImageDrop({ src: payload, clientX: ev.clientX, clientY: ev.clientY });
|
|
3886
|
+
} else {
|
|
3887
|
+
dispatchTextDrop({ text: payload, clientX: ev.clientX, clientY: ev.clientY });
|
|
3888
|
+
}
|
|
3889
|
+
}
|
|
3890
|
+
window.addEventListener("pointermove", onMove);
|
|
3891
|
+
window.addEventListener("pointerup", onUp);
|
|
3892
|
+
},
|
|
3893
|
+
[createGhostEl]
|
|
3894
|
+
);
|
|
3895
|
+
return { startDrag };
|
|
3896
|
+
}
|
|
3622
3897
|
var DEFAULT_SEEDS = [
|
|
3623
3898
|
"forest",
|
|
3624
3899
|
"ocean",
|
|
@@ -3650,8 +3925,7 @@ function getSearchImages(query) {
|
|
|
3650
3925
|
id: `${query}-${i}`
|
|
3651
3926
|
}));
|
|
3652
3927
|
}
|
|
3653
|
-
|
|
3654
|
-
function createGhost(src) {
|
|
3928
|
+
function createImageGhost(src) {
|
|
3655
3929
|
const el = document.createElement("div");
|
|
3656
3930
|
el.style.cssText = `
|
|
3657
3931
|
position: fixed; top: -9999px; left: -9999px; z-index: 99999;
|
|
@@ -3665,63 +3939,31 @@ function createGhost(src) {
|
|
|
3665
3939
|
document.body.appendChild(el);
|
|
3666
3940
|
return el;
|
|
3667
3941
|
}
|
|
3668
|
-
function moveGhost(x, y) {
|
|
3669
|
-
if (!ghostEl) return;
|
|
3670
|
-
ghostEl.style.left = `${x + 12}px`;
|
|
3671
|
-
ghostEl.style.top = `${y + 12}px`;
|
|
3672
|
-
}
|
|
3673
|
-
function removeGhost() {
|
|
3674
|
-
ghostEl?.remove();
|
|
3675
|
-
ghostEl = null;
|
|
3676
|
-
}
|
|
3677
3942
|
function ImageLibrary({
|
|
3678
3943
|
seeds,
|
|
3679
3944
|
items: customImages
|
|
3680
3945
|
} = {}) {
|
|
3681
3946
|
const effectiveSeeds = seeds ?? DEFAULT_SEEDS;
|
|
3682
|
-
const [query, setQuery] =
|
|
3683
|
-
const [committed, setCommitted] =
|
|
3684
|
-
const [items, setItems] =
|
|
3947
|
+
const [query, setQuery] = React17__namespace.useState("");
|
|
3948
|
+
const [committed, setCommitted] = React17__namespace.useState("");
|
|
3949
|
+
const [items, setItems] = React17__namespace.useState(
|
|
3685
3950
|
() => customImages ?? getDefaultImages(effectiveSeeds)
|
|
3686
3951
|
);
|
|
3687
3952
|
const libraryTitle = useMsg("image-library.title");
|
|
3688
3953
|
const searchPlaceholder = useMsg("image-library.search.placeholder");
|
|
3689
|
-
|
|
3954
|
+
const { startDrag } = useGhostDrag({
|
|
3955
|
+
createGhostEl: createImageGhost
|
|
3956
|
+
});
|
|
3957
|
+
React17__namespace.useEffect(() => {
|
|
3690
3958
|
const t = setTimeout(() => setCommitted(query.trim()), 400);
|
|
3691
3959
|
return () => clearTimeout(t);
|
|
3692
3960
|
}, [query]);
|
|
3693
|
-
|
|
3961
|
+
React17__namespace.useEffect(() => {
|
|
3694
3962
|
if (customImages) return;
|
|
3695
3963
|
setItems(
|
|
3696
3964
|
committed ? getSearchImages(committed) : getDefaultImages(effectiveSeeds)
|
|
3697
3965
|
);
|
|
3698
3966
|
}, [committed, customImages, effectiveSeeds]);
|
|
3699
|
-
function handlePointerDown(e, src) {
|
|
3700
|
-
e.stopPropagation();
|
|
3701
|
-
e.currentTarget.setPointerCapture(e.pointerId);
|
|
3702
|
-
ghostEl = createGhost(src);
|
|
3703
|
-
moveGhost(e.clientX, e.clientY);
|
|
3704
|
-
window.dispatchEvent(
|
|
3705
|
-
new CustomEvent("anvilkit:librarydragstart", {
|
|
3706
|
-
detail: { type: "image" }
|
|
3707
|
-
})
|
|
3708
|
-
);
|
|
3709
|
-
function onMove(ev) {
|
|
3710
|
-
moveGhost(ev.clientX, ev.clientY);
|
|
3711
|
-
}
|
|
3712
|
-
function onUp(ev) {
|
|
3713
|
-
removeGhost();
|
|
3714
|
-
window.removeEventListener("pointermove", onMove);
|
|
3715
|
-
window.removeEventListener("pointerup", onUp);
|
|
3716
|
-
window.dispatchEvent(
|
|
3717
|
-
new CustomEvent("anvilkit:imagedrop", {
|
|
3718
|
-
detail: { src, clientX: ev.clientX, clientY: ev.clientY }
|
|
3719
|
-
})
|
|
3720
|
-
);
|
|
3721
|
-
}
|
|
3722
|
-
window.addEventListener("pointermove", onMove);
|
|
3723
|
-
window.addEventListener("pointerup", onUp);
|
|
3724
|
-
}
|
|
3725
3967
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full", children: [
|
|
3726
3968
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pt-3 pb-1 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: libraryTitle }),
|
|
3727
3969
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
@@ -3736,10 +3978,10 @@ function ImageLibrary({
|
|
|
3736
3978
|
}
|
|
3737
3979
|
)
|
|
3738
3980
|
] }) }),
|
|
3739
|
-
/* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 grid grid-cols-2 gap-2", children: items.map((item
|
|
3981
|
+
/* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 grid grid-cols-2 gap-2", children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3740
3982
|
"div",
|
|
3741
3983
|
{
|
|
3742
|
-
onPointerDown: (e) =>
|
|
3984
|
+
onPointerDown: (e) => startDrag(e, "image", item.src),
|
|
3743
3985
|
className: "rounded-md overflow-hidden border border-border bg-muted/40 cursor-grab select-none hover:ring-2 hover:ring-primary/50 active:cursor-grabbing transition-all",
|
|
3744
3986
|
children: [
|
|
3745
3987
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3754,12 +3996,27 @@ function ImageLibrary({
|
|
|
3754
3996
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-1.5 py-1 text-xs text-muted-foreground truncate capitalize", children: item.alt })
|
|
3755
3997
|
]
|
|
3756
3998
|
},
|
|
3757
|
-
|
|
3999
|
+
item.id
|
|
3758
4000
|
)) }) })
|
|
3759
4001
|
] });
|
|
3760
4002
|
}
|
|
3761
|
-
var
|
|
3762
|
-
|
|
4003
|
+
var DEFAULT_SNIPPETS = [
|
|
4004
|
+
{ category: "Headlines", label: "Bold statement", text: "The Future Starts Here" },
|
|
4005
|
+
{ category: "Headlines", label: "Question hook", text: "Ready to Transform Your Business?" },
|
|
4006
|
+
{ category: "Headlines", label: "Value prop", text: "Simple, Powerful, Built for Teams" },
|
|
4007
|
+
{ category: "Headlines", label: "Action-led", text: "Ship Faster. Break Less. Sleep Better." },
|
|
4008
|
+
{ category: "Subheadings", label: "Feature intro", text: "Everything you need, nothing you don't." },
|
|
4009
|
+
{ category: "Subheadings", label: "Social proof", text: "Trusted by over 10,000 teams worldwide." },
|
|
4010
|
+
{ category: "Subheadings", label: "CTA support", text: "Get started in minutes \u2014 no credit card required." },
|
|
4011
|
+
{ category: "Body", label: "Product description", text: "Our platform helps teams collaborate in real time, ship products faster, and stay aligned across every stage of the process." },
|
|
4012
|
+
{ category: "Body", label: "Feature benefit", text: "With built-in analytics and smart automation, you can focus on what matters most \u2014 building great products." },
|
|
4013
|
+
{ category: "Body", label: "About us", text: "We're a small team on a big mission: to make software development feel effortless for everyone." },
|
|
4014
|
+
{ category: "CTAs", label: "Primary", text: "Get Started Free" },
|
|
4015
|
+
{ category: "CTAs", label: "Secondary", text: "Learn More" },
|
|
4016
|
+
{ category: "CTAs", label: "Soft sell", text: "See How It Works" },
|
|
4017
|
+
{ category: "CTAs", label: "Urgency", text: "Start Your Free Trial Today" }
|
|
4018
|
+
];
|
|
4019
|
+
function createTextGhost(text) {
|
|
3763
4020
|
const el = document.createElement("div");
|
|
3764
4021
|
el.style.cssText = `
|
|
3765
4022
|
position: fixed; top: -9999px; left: -9999px; z-index: 99999;
|
|
@@ -3772,112 +4029,16 @@ function createGhost2(text) {
|
|
|
3772
4029
|
document.body.appendChild(el);
|
|
3773
4030
|
return el;
|
|
3774
4031
|
}
|
|
3775
|
-
function
|
|
3776
|
-
if (!ghostEl2) return;
|
|
3777
|
-
ghostEl2.style.left = `${x + 12}px`;
|
|
3778
|
-
ghostEl2.style.top = `${y + 12}px`;
|
|
3779
|
-
}
|
|
3780
|
-
function removeGhost2() {
|
|
3781
|
-
ghostEl2?.remove();
|
|
3782
|
-
ghostEl2 = null;
|
|
3783
|
-
}
|
|
3784
|
-
var DEFAULT_SNIPPETS = [
|
|
3785
|
-
// Headlines
|
|
3786
|
-
{
|
|
3787
|
-
category: "Headlines",
|
|
3788
|
-
label: "Bold statement",
|
|
3789
|
-
text: "The Future Starts Here"
|
|
3790
|
-
},
|
|
3791
|
-
{
|
|
3792
|
-
category: "Headlines",
|
|
3793
|
-
label: "Question hook",
|
|
3794
|
-
text: "Ready to Transform Your Business?"
|
|
3795
|
-
},
|
|
3796
|
-
{
|
|
3797
|
-
category: "Headlines",
|
|
3798
|
-
label: "Value prop",
|
|
3799
|
-
text: "Simple, Powerful, Built for Teams"
|
|
3800
|
-
},
|
|
3801
|
-
{
|
|
3802
|
-
category: "Headlines",
|
|
3803
|
-
label: "Action-led",
|
|
3804
|
-
text: "Ship Faster. Break Less. Sleep Better."
|
|
3805
|
-
},
|
|
3806
|
-
// Subheadings
|
|
3807
|
-
{
|
|
3808
|
-
category: "Subheadings",
|
|
3809
|
-
label: "Feature intro",
|
|
3810
|
-
text: "Everything you need, nothing you don't."
|
|
3811
|
-
},
|
|
3812
|
-
{
|
|
3813
|
-
category: "Subheadings",
|
|
3814
|
-
label: "Social proof",
|
|
3815
|
-
text: "Trusted by over 10,000 teams worldwide."
|
|
3816
|
-
},
|
|
3817
|
-
{
|
|
3818
|
-
category: "Subheadings",
|
|
3819
|
-
label: "CTA support",
|
|
3820
|
-
text: "Get started in minutes \u2014 no credit card required."
|
|
3821
|
-
},
|
|
3822
|
-
// Body
|
|
3823
|
-
{
|
|
3824
|
-
category: "Body",
|
|
3825
|
-
label: "Product description",
|
|
3826
|
-
text: "Our platform helps teams collaborate in real time, ship products faster, and stay aligned across every stage of the process."
|
|
3827
|
-
},
|
|
3828
|
-
{
|
|
3829
|
-
category: "Body",
|
|
3830
|
-
label: "Feature benefit",
|
|
3831
|
-
text: "With built-in analytics and smart automation, you can focus on what matters most \u2014 building great products."
|
|
3832
|
-
},
|
|
3833
|
-
{
|
|
3834
|
-
category: "Body",
|
|
3835
|
-
label: "About us",
|
|
3836
|
-
text: "We're a small team on a big mission: to make software development feel effortless for everyone."
|
|
3837
|
-
},
|
|
3838
|
-
// CTAs
|
|
3839
|
-
{ category: "CTAs", label: "Primary", text: "Get Started Free" },
|
|
3840
|
-
{ category: "CTAs", label: "Secondary", text: "Learn More" },
|
|
3841
|
-
{ category: "CTAs", label: "Soft sell", text: "See How It Works" },
|
|
3842
|
-
{ category: "CTAs", label: "Urgency", text: "Start Your Free Trial Today" }
|
|
3843
|
-
];
|
|
3844
|
-
function CopyLibrary({
|
|
3845
|
-
items
|
|
3846
|
-
} = {}) {
|
|
4032
|
+
function CopyLibrary({ items } = {}) {
|
|
3847
4033
|
const activeSnippets = items ?? DEFAULT_SNIPPETS;
|
|
3848
4034
|
const categories = Array.from(new Set(activeSnippets.map((s) => s.category)));
|
|
3849
|
-
const [query, setQuery] =
|
|
4035
|
+
const [query, setQuery] = React17__namespace.useState("");
|
|
3850
4036
|
const libraryTitle = useMsg("copy-library.title");
|
|
3851
4037
|
const searchPlaceholder = useMsg("copy-library.search.placeholder");
|
|
4038
|
+
const { startDrag } = useGhostDrag({ createGhostEl: createTextGhost });
|
|
3852
4039
|
const filtered = query.trim() ? activeSnippets.filter(
|
|
3853
4040
|
(s) => s.text.toLowerCase().includes(query.toLowerCase()) || s.label.toLowerCase().includes(query.toLowerCase()) || s.category.toLowerCase().includes(query.toLowerCase())
|
|
3854
4041
|
) : activeSnippets;
|
|
3855
|
-
function handlePointerDown(e, text) {
|
|
3856
|
-
e.stopPropagation();
|
|
3857
|
-
e.currentTarget.setPointerCapture(e.pointerId);
|
|
3858
|
-
ghostEl2 = createGhost2(text);
|
|
3859
|
-
moveGhost2(e.clientX, e.clientY);
|
|
3860
|
-
window.dispatchEvent(
|
|
3861
|
-
new CustomEvent("anvilkit:librarydragstart", {
|
|
3862
|
-
detail: { type: "text" }
|
|
3863
|
-
})
|
|
3864
|
-
);
|
|
3865
|
-
function onMove(ev) {
|
|
3866
|
-
moveGhost2(ev.clientX, ev.clientY);
|
|
3867
|
-
}
|
|
3868
|
-
function onUp(ev) {
|
|
3869
|
-
removeGhost2();
|
|
3870
|
-
window.removeEventListener("pointermove", onMove);
|
|
3871
|
-
window.removeEventListener("pointerup", onUp);
|
|
3872
|
-
window.dispatchEvent(
|
|
3873
|
-
new CustomEvent("anvilkit:textdrop", {
|
|
3874
|
-
detail: { text, clientX: ev.clientX, clientY: ev.clientY }
|
|
3875
|
-
})
|
|
3876
|
-
);
|
|
3877
|
-
}
|
|
3878
|
-
window.addEventListener("pointermove", onMove);
|
|
3879
|
-
window.addEventListener("pointerup", onUp);
|
|
3880
|
-
}
|
|
3881
4042
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full", children: [
|
|
3882
4043
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pt-3 pb-1 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: libraryTitle }),
|
|
3883
4044
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
@@ -3893,24 +4054,24 @@ function CopyLibrary({
|
|
|
3893
4054
|
)
|
|
3894
4055
|
] }) }),
|
|
3895
4056
|
/* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 flex flex-col gap-4", children: (query.trim() ? [null] : categories).map((cat) => {
|
|
3896
|
-
const
|
|
3897
|
-
if (!
|
|
4057
|
+
const snippets = cat ? filtered.filter((s) => s.category === cat) : filtered;
|
|
4058
|
+
if (!snippets.length) return null;
|
|
3898
4059
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
3899
4060
|
cat && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-1 pb-1 text-xs font-semibold text-muted-foreground uppercase tracking-wider flex items-center gap-1", children: [
|
|
3900
4061
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Type, { className: "h-3 w-3" }),
|
|
3901
4062
|
cat
|
|
3902
4063
|
] }),
|
|
3903
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-1", children:
|
|
4064
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-1", children: snippets.map((snippet) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3904
4065
|
"div",
|
|
3905
4066
|
{
|
|
3906
|
-
onPointerDown: (e) =>
|
|
4067
|
+
onPointerDown: (e) => startDrag(e, "text", snippet.text),
|
|
3907
4068
|
className: "rounded-md border border-border bg-muted/40 px-2.5 py-2 cursor-grab select-none hover:bg-muted hover:ring-1 hover:ring-primary/40 active:cursor-grabbing transition-all",
|
|
3908
4069
|
children: [
|
|
3909
4070
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-medium text-foreground/70 mb-0.5", children: snippet.label }),
|
|
3910
4071
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-foreground leading-snug line-clamp-2", children: snippet.text })
|
|
3911
4072
|
]
|
|
3912
4073
|
},
|
|
3913
|
-
|
|
4074
|
+
`${snippet.category}-${snippet.label}`
|
|
3914
4075
|
)) })
|
|
3915
4076
|
] }, cat ?? "results");
|
|
3916
4077
|
}) }) })
|
|
@@ -3938,42 +4099,6 @@ var EditorLayout = ({
|
|
|
3938
4099
|
] })
|
|
3939
4100
|
] });
|
|
3940
4101
|
};
|
|
3941
|
-
function createEditorUiStore(storeId) {
|
|
3942
|
-
return zustand.createStore()(
|
|
3943
|
-
middleware.persist(
|
|
3944
|
-
(set) => ({
|
|
3945
|
-
drawerSearch: "",
|
|
3946
|
-
setDrawerSearch: (q) => set({ drawerSearch: q }),
|
|
3947
|
-
drawerCollapsed: {},
|
|
3948
|
-
toggleDrawerGroup: (group) => set((s) => ({
|
|
3949
|
-
drawerCollapsed: { ...s.drawerCollapsed, [group]: !s.drawerCollapsed[group] }
|
|
3950
|
-
})),
|
|
3951
|
-
activeTab: "insert",
|
|
3952
|
-
setActiveTab: (tab) => set({ activeTab: tab }),
|
|
3953
|
-
outlineExpanded: {},
|
|
3954
|
-
toggleOutlineItem: (id) => set((s) => ({
|
|
3955
|
-
outlineExpanded: { ...s.outlineExpanded, [id]: !s.outlineExpanded[id] }
|
|
3956
|
-
})),
|
|
3957
|
-
theme: "light",
|
|
3958
|
-
toggleTheme: () => set((s) => {
|
|
3959
|
-
const next = s.theme === "light" ? "dark" : "light";
|
|
3960
|
-
document.documentElement.classList.toggle("dark", next === "dark");
|
|
3961
|
-
return { theme: next };
|
|
3962
|
-
})
|
|
3963
|
-
}),
|
|
3964
|
-
{
|
|
3965
|
-
name: `anvilkit-ui-${storeId}`,
|
|
3966
|
-
partialize: (s) => ({
|
|
3967
|
-
activeTab: s.activeTab,
|
|
3968
|
-
drawerCollapsed: s.drawerCollapsed,
|
|
3969
|
-
outlineExpanded: s.outlineExpanded,
|
|
3970
|
-
theme: s.theme
|
|
3971
|
-
// drawerSearch intentionally excluded — transient input
|
|
3972
|
-
})
|
|
3973
|
-
}
|
|
3974
|
-
)
|
|
3975
|
-
);
|
|
3976
|
-
}
|
|
3977
4102
|
function createEditorI18nStore(initial) {
|
|
3978
4103
|
return zustand.createStore()(
|
|
3979
4104
|
middleware.persist(
|
|
@@ -4047,20 +4172,33 @@ function Studio({
|
|
|
4047
4172
|
locale,
|
|
4048
4173
|
messages
|
|
4049
4174
|
}) {
|
|
4050
|
-
const uiStore2 =
|
|
4051
|
-
const i18nStore =
|
|
4175
|
+
const uiStore2 = React17__namespace.useRef(createEditorUiStore(storeId ?? "default")).current;
|
|
4176
|
+
const i18nStore = React17__namespace.useRef(
|
|
4052
4177
|
createEditorI18nStore({
|
|
4053
4178
|
locale: locale ?? "zh",
|
|
4054
4179
|
messages: messages ?? defaultMessages
|
|
4055
4180
|
})
|
|
4056
4181
|
).current;
|
|
4057
|
-
|
|
4058
|
-
()
|
|
4059
|
-
|
|
4060
|
-
);
|
|
4061
|
-
|
|
4062
|
-
()
|
|
4063
|
-
|
|
4182
|
+
React17__namespace.useEffect(() => {
|
|
4183
|
+
i18nStore.getState().setLocale(locale ?? "zh", messages ?? defaultMessages);
|
|
4184
|
+
}, [locale, messages, i18nStore]);
|
|
4185
|
+
const [aiPlugin, setAiPlugin] = React17__namespace.useState(null);
|
|
4186
|
+
React17__namespace.useEffect(() => {
|
|
4187
|
+
if (!aiHost) return;
|
|
4188
|
+
let cancelled = false;
|
|
4189
|
+
import('@puckeditor/plugin-ai').then(({ createAiPlugin }) => {
|
|
4190
|
+
if (cancelled) return;
|
|
4191
|
+
import('@puckeditor/plugin-ai/styles.css').catch(() => {
|
|
4192
|
+
});
|
|
4193
|
+
setAiPlugin(createAiPlugin({ host: aiHost }));
|
|
4194
|
+
});
|
|
4195
|
+
return () => {
|
|
4196
|
+
cancelled = true;
|
|
4197
|
+
};
|
|
4198
|
+
}, [aiHost]);
|
|
4199
|
+
const mergedOverrides = React17__namespace.useMemo(
|
|
4200
|
+
() => ({ ...aiPlugin?.overrides ?? {}, ...puckOverrides, ...overrideExtensions }),
|
|
4201
|
+
[aiPlugin, overrideExtensions]
|
|
4064
4202
|
);
|
|
4065
4203
|
return /* @__PURE__ */ jsxRuntime.jsx(EditorUiStoreProvider, { value: uiStore2, children: /* @__PURE__ */ jsxRuntime.jsx(EditorI18nStoreProvider, { value: i18nStore, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4066
4204
|
core.Puck,
|
|
@@ -4070,11 +4208,11 @@ function Studio({
|
|
|
4070
4208
|
onPublish,
|
|
4071
4209
|
onChange,
|
|
4072
4210
|
overrides: mergedOverrides,
|
|
4073
|
-
plugins: [aiPlugin],
|
|
4211
|
+
plugins: aiPlugin ? [aiPlugin] : [],
|
|
4074
4212
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4075
4213
|
EditorLayout,
|
|
4076
4214
|
{
|
|
4077
|
-
aiPanel: aiPlugin
|
|
4215
|
+
aiPanel: aiPlugin?.render(),
|
|
4078
4216
|
images,
|
|
4079
4217
|
copywritings
|
|
4080
4218
|
}
|
|
@@ -4084,10 +4222,14 @@ function Studio({
|
|
|
4084
4222
|
}
|
|
4085
4223
|
|
|
4086
4224
|
// src/store/index.ts
|
|
4087
|
-
|
|
4225
|
+
createEditorUiStore("default");
|
|
4088
4226
|
|
|
4227
|
+
exports.EditorI18nStoreProvider = EditorI18nStoreProvider;
|
|
4228
|
+
exports.EditorUiStoreProvider = EditorUiStoreProvider;
|
|
4089
4229
|
exports.Studio = Studio;
|
|
4090
4230
|
exports.createEditorI18nStore = createEditorI18nStore;
|
|
4091
4231
|
exports.createEditorUiStore = createEditorUiStore;
|
|
4232
|
+
exports.defaultMessages = defaultMessages;
|
|
4092
4233
|
exports.puckOverrides = puckOverrides;
|
|
4093
|
-
exports.
|
|
4234
|
+
exports.useEditorI18nStoreApi = useEditorI18nStoreApi;
|
|
4235
|
+
exports.useEditorUiStoreApi = useEditorUiStoreApi;
|