@simple-builder/react 1.0.1 → 1.0.3

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.
@@ -1,1268 +0,0 @@
1
- import { cn, buttonVariants, Button, useBuilder, spacing } from './chunk-YHA5XZL4.mjs';
2
- import { builder } from './chunk-7K7IGTF3.mjs';
3
- import * as React15 from 'react';
4
- import { PlusIcon, ArrowUp, ArrowDown, Edit2Icon, AlignHorizontalSpaceAroundIcon, AlignHorizontalJustifyStartIcon, ScanIcon, CalendarIcon, Trash2Icon, ImageIcon, Loader2Icon, PaintbrushIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';
5
- import { zodResolver } from '@hookform/resolvers/zod';
6
- import { format } from 'date-fns';
7
- import { useFormContext, useForm, FormProvider, Controller } from 'react-hook-form';
8
- import { z } from 'zod';
9
- import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
10
- import { Slot } from '@radix-ui/react-slot';
11
- import * as LabelPrimitive from '@radix-ui/react-label';
12
- import { cva } from 'class-variance-authority';
13
- import * as PopoverPrimitive from '@radix-ui/react-popover';
14
- import * as TabsPrimitive from '@radix-ui/react-tabs';
15
- import NextImage from 'next/image';
16
- import { DayPicker } from 'react-day-picker';
17
- import * as SwitchPrimitives from '@radix-ui/react-switch';
18
- import * as TogglePrimitive from '@radix-ui/react-toggle';
19
-
20
- var AlertDialog = AlertDialogPrimitive.Root;
21
- var AlertDialogTrigger = AlertDialogPrimitive.Trigger;
22
- var AlertDialogPortal = AlertDialogPrimitive.Portal;
23
- var AlertDialogOverlay = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React15.createElement(
24
- AlertDialogPrimitive.Overlay,
25
- {
26
- className: cn(
27
- "fixed inset-0 z-50 bg-sb-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
28
- className
29
- ),
30
- ...props,
31
- ref
32
- }
33
- ));
34
- AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
35
- var AlertDialogContent = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React15.createElement(AlertDialogPortal, null, /* @__PURE__ */ React15.createElement(AlertDialogOverlay, null), /* @__PURE__ */ React15.createElement(
36
- AlertDialogPrimitive.Content,
37
- {
38
- ref,
39
- className: cn(
40
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-sb-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
41
- className
42
- ),
43
- ...props
44
- }
45
- )));
46
- AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
47
- var AlertDialogFooter = ({
48
- className,
49
- ...props
50
- }) => /* @__PURE__ */ React15.createElement(
51
- "div",
52
- {
53
- className: cn(
54
- "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
55
- className
56
- ),
57
- ...props
58
- }
59
- );
60
- AlertDialogFooter.displayName = "AlertDialogFooter";
61
- var AlertDialogTitle = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React15.createElement(
62
- AlertDialogPrimitive.Title,
63
- {
64
- ref,
65
- className: cn("text-lg font-semibold", className),
66
- ...props
67
- }
68
- ));
69
- AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
70
- var AlertDialogDescription = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React15.createElement(
71
- AlertDialogPrimitive.Description,
72
- {
73
- ref,
74
- className: cn("text-sm text-sb-muted-foreground", className),
75
- ...props
76
- }
77
- ));
78
- AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
79
- var AlertDialogAction = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React15.createElement(
80
- AlertDialogPrimitive.Action,
81
- {
82
- ref,
83
- className: cn(buttonVariants(), className),
84
- ...props
85
- }
86
- ));
87
- AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
88
- var AlertDialogCancel = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React15.createElement(
89
- AlertDialogPrimitive.Cancel,
90
- {
91
- ref,
92
- className: cn(
93
- buttonVariants({ variant: "outline" }),
94
- "mt-2 sm:mt-0",
95
- className
96
- ),
97
- ...props
98
- }
99
- ));
100
- AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
101
- var labelVariants = cva(
102
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
103
- );
104
- var Label = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React15.createElement(
105
- LabelPrimitive.Root,
106
- {
107
- ref,
108
- className: cn(labelVariants(), className),
109
- ...props
110
- }
111
- ));
112
- Label.displayName = LabelPrimitive.Root.displayName;
113
-
114
- // src/components/ui/form.tsx
115
- var Form = FormProvider;
116
- var FormFieldContext = React15.createContext(
117
- {}
118
- );
119
- var FormField = ({
120
- ...props
121
- }) => {
122
- return /* @__PURE__ */ React15.createElement(FormFieldContext.Provider, { value: { name: props.name } }, /* @__PURE__ */ React15.createElement(Controller, { ...props }));
123
- };
124
- var useFormField = () => {
125
- const fieldContext = React15.useContext(FormFieldContext);
126
- const itemContext = React15.useContext(FormItemContext);
127
- const { getFieldState, formState } = useFormContext();
128
- const fieldState = getFieldState(fieldContext.name, formState);
129
- if (!fieldContext) {
130
- throw new Error("useFormField should be used within <FormField>");
131
- }
132
- const { id } = itemContext;
133
- return {
134
- id,
135
- name: fieldContext.name,
136
- formItemId: `${id}-form-item`,
137
- formDescriptionId: `${id}-form-item-description`,
138
- formMessageId: `${id}-form-item-message`,
139
- ...fieldState
140
- };
141
- };
142
- var FormItemContext = React15.createContext(
143
- {}
144
- );
145
- var FormItem = React15.forwardRef(({ className, ...props }, ref) => {
146
- const id = React15.useId();
147
- return /* @__PURE__ */ React15.createElement(FormItemContext.Provider, { value: { id } }, /* @__PURE__ */ React15.createElement("div", { ref, className: cn("space-y-2", className), ...props }));
148
- });
149
- FormItem.displayName = "FormItem";
150
- var FormLabel = React15.forwardRef(({ className, ...props }, ref) => {
151
- const { error, formItemId } = useFormField();
152
- return /* @__PURE__ */ React15.createElement(
153
- Label,
154
- {
155
- ref,
156
- className: cn(error && "text-sb-destructive", className),
157
- htmlFor: formItemId,
158
- ...props
159
- }
160
- );
161
- });
162
- FormLabel.displayName = "FormLabel";
163
- var FormControl = React15.forwardRef(({ ...props }, ref) => {
164
- const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
165
- return /* @__PURE__ */ React15.createElement(
166
- Slot,
167
- {
168
- ref,
169
- id: formItemId,
170
- "aria-describedby": !error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`,
171
- "aria-invalid": !!error,
172
- ...props
173
- }
174
- );
175
- });
176
- FormControl.displayName = "FormControl";
177
- var FormDescription = React15.forwardRef(({ className, ...props }, ref) => {
178
- const { formDescriptionId } = useFormField();
179
- return /* @__PURE__ */ React15.createElement(
180
- "p",
181
- {
182
- ref,
183
- id: formDescriptionId,
184
- className: cn("text-sm text-sb-muted-foreground", className),
185
- ...props
186
- }
187
- );
188
- });
189
- FormDescription.displayName = "FormDescription";
190
- var FormMessage = React15.forwardRef(({ className, children, ...props }, ref) => {
191
- const { error, formMessageId } = useFormField();
192
- const body = error ? String(error?.message) : children;
193
- if (!body) {
194
- return null;
195
- }
196
- return /* @__PURE__ */ React15.createElement(
197
- "p",
198
- {
199
- ref,
200
- id: formMessageId,
201
- className: cn("text-sm font-medium text-sb-destructive", className),
202
- ...props
203
- },
204
- body
205
- );
206
- });
207
- FormMessage.displayName = "FormMessage";
208
- var Popover = PopoverPrimitive.Root;
209
- var PopoverTrigger = PopoverPrimitive.Trigger;
210
- var PopoverClose = PopoverPrimitive.Close;
211
- var PopoverContent = React15.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ React15.createElement(PopoverPrimitive.Portal, null, /* @__PURE__ */ React15.createElement(
212
- PopoverPrimitive.Content,
213
- {
214
- ref,
215
- align,
216
- sideOffset,
217
- className: cn(
218
- "z-50 w-72 rounded-md border bg-sb-popover p-4 text-sb-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
219
- className
220
- ),
221
- ...props
222
- }
223
- )));
224
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
225
- var Tabs = TabsPrimitive.Root;
226
- var TabsList = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React15.createElement(
227
- TabsPrimitive.List,
228
- {
229
- ref,
230
- className: cn("flex items-center border-b px-4 space-x-6", className),
231
- ...props
232
- }
233
- ));
234
- TabsList.displayName = TabsPrimitive.List.displayName;
235
- var TabsTrigger = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React15.createElement(
236
- TabsPrimitive.Trigger,
237
- {
238
- ref,
239
- className: cn(
240
- "inline-flex items-center justify-center whitespace-nowrap py-3 text-sm font-medium transition-all focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=active]:border-black border-b-2 border-transparent data-[state=active]:text-sb-foreground text-sb-muted-sb-foreground",
241
- className
242
- ),
243
- ...props
244
- }
245
- ));
246
- TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
247
- var TabsContent = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React15.createElement(
248
- TabsPrimitive.Content,
249
- {
250
- ref,
251
- className: cn(
252
- "ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
253
- className
254
- ),
255
- ...props
256
- }
257
- ));
258
- TabsContent.displayName = TabsPrimitive.Content.displayName;
259
- var Image = (props) => {
260
- if (typeof NextImage !== "undefined") {
261
- return /* @__PURE__ */ React15.createElement(NextImage.default, { ...props });
262
- }
263
- return /* @__PURE__ */ React15.createElement("img", { ...props });
264
- };
265
-
266
- // src/components/ui/media-input.tsx
267
- var MediaInput = (props) => {
268
- const { onFilesChange, limit = 32, multiple = false, onError } = props;
269
- const id = React15.useId();
270
- const [queue, setQueue] = React15.useState([]);
271
- const [sources, setSources] = React15.useState(props.files ?? []);
272
- const maxConcurrentUploads = 3;
273
- const uploadingCountRef = React15.useRef(0);
274
- const handleFilesAdd = async (e) => {
275
- const files = e.target.files;
276
- if (!files || files.length === 0) {
277
- return;
278
- }
279
- if (files.length + sources.length > (multiple ? limit : 1)) {
280
- onError?.(
281
- new MediaInputError(
282
- `Maximaal ${limit} bestanden.`,
283
- `Je probeerde nu ${files.length + sources.length} bestanden toe te voegen, maar je mag er maximaal ${limit} toevoegen.`
284
- )
285
- );
286
- return;
287
- }
288
- const queue2 = Array.from(files);
289
- setQueue(queue2);
290
- for (const file of queue2) {
291
- try {
292
- while (uploadingCountRef.current >= maxConcurrentUploads && uploadingCountRef.current > 0) {
293
- await new Promise((resolve) => setTimeout(resolve, 300));
294
- }
295
- uploadingCountRef.current++;
296
- const formData = new FormData();
297
- formData.append("file", file);
298
- const res = await fetch("/api/simple-builder/file/upload", {
299
- method: "POST",
300
- body: formData
301
- });
302
- if (res === void 0 || !res.ok) {
303
- onError?.(
304
- new MediaInputError(
305
- "Bestand uploaden misulukt",
306
- `Bestand ${file.name} kon niet worden ge\xFCpload.`
307
- )
308
- );
309
- continue;
310
- }
311
- const { data: url } = await res.json();
312
- if (!url) {
313
- onError?.(
314
- new MediaInputError(
315
- "Bestand uploaden misulukt",
316
- `De URL van bestand ${file.name} kon niet worden opgehaald.`
317
- )
318
- );
319
- continue;
320
- }
321
- setSources((prev) => [...prev, url]);
322
- onFilesChange?.([...sources, url]);
323
- } catch (e2) {
324
- onError?.(
325
- new MediaInputError(
326
- "Bestand uploaden misulukt",
327
- `Bestand ${file.name} kon niet worden ge\xFCpload.`
328
- )
329
- );
330
- } finally {
331
- setQueue((prev) => prev.filter((f) => f !== file));
332
- uploadingCountRef.current--;
333
- }
334
- }
335
- };
336
- const handleSourceDelete = async (src) => {
337
- setSources((prev) => prev.filter((s) => s !== src));
338
- onFilesChange?.(sources.filter((s) => s !== src));
339
- await fetch("/api/uploadthing/delete", {
340
- method: "POST",
341
- body: JSON.stringify({ src })
342
- });
343
- };
344
- return /* @__PURE__ */ React15.createElement("div", { className: cn("flex flex-wrap gap-4", props.className) }, sources.map((src) => /* @__PURE__ */ React15.createElement(MediaInputItem, { key: src, className: cn("group", props.itemClassName) }, /* @__PURE__ */ React15.createElement(
345
- Image,
346
- {
347
- src,
348
- alt: "",
349
- fill: true,
350
- className: "absolute inset-0 object-cover pointer-events-none"
351
- }
352
- ), /* @__PURE__ */ React15.createElement("div", { className: "absolute right-1 top-1 z-30 flex items-center justify-end gap-3 opacity-0 transition-opacity group-hover:opacity-100" }, /* @__PURE__ */ React15.createElement(
353
- "button",
354
- {
355
- className: "flex h-8 w-8 items-center justify-center rounded-full border bg-sb-secondary text-sb-secondary-foreground opacity-90 shadow transition-opacity hover:opacity-100",
356
- onClick: () => handleSourceDelete(src)
357
- },
358
- /* @__PURE__ */ React15.createElement(Trash2Icon, { className: "h-4 w-4" })
359
- )))), queue.map((_, i) => /* @__PURE__ */ React15.createElement(
360
- MediaInputItem,
361
- {
362
- key: i,
363
- className: cn(
364
- "flex h-28 w-28 items-center justify-center",
365
- props.itemClassName
366
- )
367
- },
368
- /* @__PURE__ */ React15.createElement(Loader2Icon, { className: "h-6 w-6 animate-spin" })
369
- )), multiple || !multiple && !sources.length && !queue.length ? /* @__PURE__ */ React15.createElement(
370
- "label",
371
- {
372
- htmlFor: id,
373
- className: cn(
374
- "flex h-28 w-28 cursor-pointer items-center justify-center rounded-lg border",
375
- props.itemClassName
376
- )
377
- },
378
- /* @__PURE__ */ React15.createElement(PlusIcon, { className: "h-6 w-6" }),
379
- /* @__PURE__ */ React15.createElement(
380
- "input",
381
- {
382
- id,
383
- type: "file",
384
- onChange: handleFilesAdd,
385
- multiple,
386
- accept: ".png,.jpg,.jpeg,.webp,.gif,.svg",
387
- className: "hidden"
388
- }
389
- )
390
- ) : null);
391
- };
392
- var MediaInputItem = (props) => {
393
- return /* @__PURE__ */ React15.createElement(
394
- "div",
395
- {
396
- className: cn(
397
- "relative h-28 w-28 overflow-hidden rounded-lg border",
398
- props.className
399
- )
400
- },
401
- props.children
402
- );
403
- };
404
- var MediaInputError = class extends Error {
405
- title;
406
- description;
407
- constructor(message, description) {
408
- super(message);
409
- this.title = message;
410
- this.description = description;
411
- }
412
- };
413
-
414
- // src/components/ui/background-picker.tsx
415
- var BackgroundPicker = (props) => {
416
- const { background, onBackgroundChange, className } = props;
417
- const solids = props.solids ?? [
418
- "#000000",
419
- "#ffffff",
420
- "#0f172a",
421
- "#F1F5F9",
422
- "#64748B",
423
- "#E6007E",
424
- "#F8FAFC",
425
- "#009DD1",
426
- "#FF0000"
427
- ];
428
- const gradients = props.gradients ?? [
429
- "linear-gradient(to top left,#accbee,#e7f0fd)",
430
- "linear-gradient(to top left,#d5d4d0,#d5d4d0,#eeeeec)"
431
- ];
432
- const images = props.images ?? [
433
- "url(https://images.unsplash.com/photo-1688822863426-8c5f9b257090?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2532&q=90)",
434
- "url(https://images.unsplash.com/photo-1691225850735-6e4e51834cad?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2532&q=90)"
435
- ];
436
- const defaultTab = React15.useMemo(() => {
437
- if (background.includes("url"))
438
- return "image";
439
- if (background.includes("gradient"))
440
- return "gradient";
441
- return "solid";
442
- }, [background]);
443
- return /* @__PURE__ */ React15.createElement(Popover, null, /* @__PURE__ */ React15.createElement(PopoverTrigger, { asChild: true }, /* @__PURE__ */ React15.createElement(
444
- Button,
445
- {
446
- variant: "outline",
447
- size: "sm",
448
- className: cn(
449
- "justify-start text-left font-normal normal-case w-full",
450
- !background && "text-sb-muted-foreground",
451
- className
452
- )
453
- },
454
- /* @__PURE__ */ React15.createElement("div", { className: "w-full flex items-center gap-2" }, background ? /* @__PURE__ */ React15.createElement(
455
- "div",
456
- {
457
- className: "h-4 w-4 rounded !bg-center !bg-cover transition-all border",
458
- style: { background }
459
- }
460
- ) : /* @__PURE__ */ React15.createElement(PaintbrushIcon, { className: "h-4 w-4" }), /* @__PURE__ */ React15.createElement("div", { className: "truncate flex-1" }, background ? background : "Kies een achtergrond"))
461
- )), /* @__PURE__ */ React15.createElement(PopoverContent, { className: "w-64 p-0" }, /* @__PURE__ */ React15.createElement(Tabs, { defaultValue: defaultTab }, /* @__PURE__ */ React15.createElement(TabsList, { className: "w-full" }, /* @__PURE__ */ React15.createElement(TabsTrigger, { className: "flex-1", value: "solid" }, "Solid"), /* @__PURE__ */ React15.createElement(TabsTrigger, { className: "flex-1", value: "gradient" }, "Gradient"), /* @__PURE__ */ React15.createElement(TabsTrigger, { className: "flex-1", value: "image" }, "Image")), /* @__PURE__ */ React15.createElement(
462
- TabsContent,
463
- {
464
- value: "solid",
465
- className: "data-[state=active]:flex flex-wrap gap-1 p-4"
466
- },
467
- solids.map((s) => /* @__PURE__ */ React15.createElement(
468
- "div",
469
- {
470
- key: s,
471
- style: { background: s },
472
- className: "rounded-md h-6 w-6 cursor-pointer active:scale-105 border",
473
- onClick: () => onBackgroundChange(s)
474
- }
475
- ))
476
- ), /* @__PURE__ */ React15.createElement(
477
- TabsContent,
478
- {
479
- value: "gradient",
480
- className: "data-[state=active]:flex flex-wrap gap-1 p-4"
481
- },
482
- gradients.map((s) => /* @__PURE__ */ React15.createElement(
483
- "div",
484
- {
485
- key: s,
486
- style: { background: s },
487
- className: "rounded-md h-6 w-6 cursor-pointer active:scale-105 border",
488
- onClick: () => onBackgroundChange(s)
489
- }
490
- ))
491
- ), /* @__PURE__ */ React15.createElement(TabsContent, { value: "image" }, /* @__PURE__ */ React15.createElement("div", { className: "p-4 border-b" }, /* @__PURE__ */ React15.createElement(
492
- MediaInput,
493
- {
494
- className: "grid grid-cols-2 gap-1",
495
- itemClassName: "aspect-video h-auto w-full",
496
- multiple: false,
497
- onFilesChange: (files) => {
498
- if (!files.length)
499
- return;
500
- onBackgroundChange(`url(${files[0]})`);
501
- },
502
- onError: (e) => console.error(
503
- "[media-input]: Title: " + e?.title,
504
- "media-input: Error: " + e?.description
505
- )
506
- }
507
- )), /* @__PURE__ */ React15.createElement("div", { className: "grid grid-cols-2 gap-1 p-4" }, images.map((s) => /* @__PURE__ */ React15.createElement(
508
- "div",
509
- {
510
- key: s,
511
- style: { backgroundImage: s },
512
- className: "rounded-md bg-cover bg-center aspect-video w-full cursor-pointer border active:scale-105",
513
- onClick: () => onBackgroundChange(s)
514
- }
515
- )))))));
516
- };
517
- function Calendar({
518
- className,
519
- classNames,
520
- showOutsideDays = true,
521
- ...props
522
- }) {
523
- return /* @__PURE__ */ React15.createElement(
524
- DayPicker,
525
- {
526
- showOutsideDays,
527
- className: cn("p-3", className),
528
- classNames: {
529
- months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
530
- month: "space-y-4",
531
- caption: "flex justify-center pt-1 relative items-center",
532
- caption_label: "text-sm font-medium",
533
- nav: "space-x-1 flex items-center",
534
- nav_button: cn(
535
- buttonVariants({ variant: "outline" }),
536
- "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
537
- ),
538
- nav_button_previous: "absolute left-1",
539
- nav_button_next: "absolute right-1",
540
- table: "w-full border-collapse space-y-1",
541
- head_row: "flex",
542
- head_cell: "text-sb-muted-foreground rounded-md w-8 font-normal text-[0.8rem]",
543
- row: "flex w-full mt-2",
544
- cell: cn(
545
- "relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-sb-accent [&:has([aria-selected].day-outside)]:bg-sb-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md",
546
- props.mode === "range" ? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md" : "[&:has([aria-selected])]:rounded-md"
547
- ),
548
- day: cn(
549
- buttonVariants({ variant: "ghost" }),
550
- "h-8 w-8 p-0 font-normal aria-selected:opacity-100"
551
- ),
552
- day_range_start: "day-range-start",
553
- day_range_end: "day-range-end",
554
- day_selected: "bg-sb-primary text-sb-primary-foreground hover:bg-sb-primary hover:text-sb-primary-foreground focus:bg-sb-primary focus:text-sb-primary-foreground",
555
- day_today: "bg-sb-accent text-sb-accent-foreground",
556
- day_outside: "day-outside text-sb-muted-foreground opacity-50 aria-selected:bg-sb-accent/50 aria-selected:text-sb-muted-foreground aria-selected:opacity-30",
557
- day_disabled: "text-sb-muted-foreground opacity-50",
558
- day_range_middle: "aria-selected:bg-sb-accent aria-selected:text-sb-accent-foreground",
559
- day_hidden: "invisible",
560
- ...classNames
561
- },
562
- components: {
563
- IconLeft: () => /* @__PURE__ */ React15.createElement(ChevronLeftIcon, { className: "h-4 w-4" }),
564
- IconRight: () => /* @__PURE__ */ React15.createElement(ChevronRightIcon, { className: "h-4 w-4" })
565
- },
566
- ...props
567
- }
568
- );
569
- }
570
- Calendar.displayName = "Calendar";
571
- var ColorPicker = (props) => {
572
- const { color, onColorChange, className } = props;
573
- const colors = props.colors ?? [
574
- "#000000",
575
- "#ffffff",
576
- "#0f172a",
577
- "#F1F5F9",
578
- "#64748B",
579
- "#E6007E",
580
- "#F8FAFC",
581
- "#009DD1",
582
- "#FF0000"
583
- ];
584
- return /* @__PURE__ */ React15.createElement(Popover, null, /* @__PURE__ */ React15.createElement(PopoverTrigger, { asChild: true }, /* @__PURE__ */ React15.createElement(
585
- Button,
586
- {
587
- variant: "outline",
588
- size: "sm",
589
- className: cn(
590
- "justify-start text-left font-normal normal-case w-full",
591
- !color && "text-sb-muted-foreground",
592
- className
593
- )
594
- },
595
- /* @__PURE__ */ React15.createElement("div", { className: "w-full flex items-center gap-2" }, color ? /* @__PURE__ */ React15.createElement(
596
- "div",
597
- {
598
- className: "h-4 w-4 rounded !bg-center !bg-cover transition-all border",
599
- style: { background: color }
600
- }
601
- ) : /* @__PURE__ */ React15.createElement(PaintbrushIcon, { className: "h-4 w-4" }), /* @__PURE__ */ React15.createElement("div", { className: "truncate flex-1" }, color ? color : "Kies een kleur"))
602
- )), /* @__PURE__ */ React15.createElement(PopoverContent, { className: "w-64 p-4 flex flex-wrap gap-1" }, colors.map((s) => /* @__PURE__ */ React15.createElement(
603
- "div",
604
- {
605
- key: s,
606
- style: { background: s },
607
- className: "rounded-md h-6 w-6 cursor-pointer active:scale-105 border",
608
- onClick: () => onColorChange(s)
609
- }
610
- ))));
611
- };
612
- var Input = React15.forwardRef(
613
- ({ className, type, ...props }, ref) => {
614
- return /* @__PURE__ */ React15.createElement(
615
- "input",
616
- {
617
- type,
618
- className: cn(
619
- "flex h-8 w-full rounded-md border border-sb-input bg-sb-background px-3 py-1 text-sm ring-offset-sb-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-sb-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-sb-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
620
- className
621
- ),
622
- ref,
623
- ...props
624
- }
625
- );
626
- }
627
- );
628
- Input.displayName = "Input";
629
- var AdvancedInput = React15.forwardRef(
630
- ({ prepend, append, ...props }, ref) => {
631
- return /* @__PURE__ */ React15.createElement("div", { className: "relative" }, /* @__PURE__ */ React15.createElement(Input, { ref, className: "pl-9 pr-7 text-right", ...props }), prepend && /* @__PURE__ */ React15.createElement("div", { className: "absolute top-1/2 left-3 -translate-y-1/2" }, prepend), append && /* @__PURE__ */ React15.createElement("div", { className: "absolute top-1/2 right-3 -translate-y-1/2" }, append));
632
- }
633
- );
634
- AdvancedInput.displayName = "AdvancedInput";
635
- var Switch = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React15.createElement(
636
- SwitchPrimitives.Root,
637
- {
638
- className: cn(
639
- "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sb-ring focus-visible:ring-offset-2 focus-visible:ring-offset-sb-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-sb-primary data-[state=unchecked]:bg-sb-input",
640
- className
641
- ),
642
- ...props,
643
- ref
644
- },
645
- /* @__PURE__ */ React15.createElement(
646
- SwitchPrimitives.Thumb,
647
- {
648
- className: cn(
649
- "pointer-events-none block h-5 w-5 rounded-full bg-sb-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
650
- )
651
- }
652
- )
653
- ));
654
- Switch.displayName = SwitchPrimitives.Root.displayName;
655
- var Textarea = React15.forwardRef(
656
- ({ className, ...props }, ref) => {
657
- return /* @__PURE__ */ React15.createElement(
658
- "textarea",
659
- {
660
- className: cn(
661
- "flex min-h-[60px] w-full rounded-md border border-sb-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-sb-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-sb-ring disabled:cursor-not-allowed disabled:opacity-50",
662
- className
663
- ),
664
- ref,
665
- ...props
666
- }
667
- );
668
- }
669
- );
670
- Textarea.displayName = "Textarea";
671
- var toggleVariants = cva(
672
- "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-sb-background transition-colors hover:bg-sb-muted hover:text-sb-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-sb-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-sb-accent data-[state=on]:text-sb-accent-foreground",
673
- {
674
- variants: {
675
- variant: {
676
- default: "bg-transparent",
677
- outline: "border border-input bg-transparent hover:bg-sb-accent hover:text-sb-accent-foreground"
678
- },
679
- size: {
680
- default: "h-10 px-3",
681
- sm: "h-9 px-2.5",
682
- lg: "h-11 px-5"
683
- }
684
- },
685
- defaultVariants: {
686
- variant: "default",
687
- size: "default"
688
- }
689
- }
690
- );
691
- var Toggle = React15.forwardRef(({ className, variant, size, ...props }, ref) => /* @__PURE__ */ React15.createElement(
692
- TogglePrimitive.Root,
693
- {
694
- ref,
695
- className: cn(toggleVariants({ variant, size, className })),
696
- ...props
697
- }
698
- ));
699
- Toggle.displayName = TogglePrimitive.Root.displayName;
700
-
701
- // src/components/container-item-toolbar.tsx
702
- var ContainerItemToolbar = (props) => {
703
- const { contentId, canBringUp = false, canBringDown = false } = props;
704
- const { bringUp, bringDown } = useBuilder();
705
- return /* @__PURE__ */ React15.createElement("div", { className: "absolute z-20 top-1 right-1 rounded-md shadow flex flex-col gap-1 p-1 bg-sb-card text-sb-card-sb-foreground sb-item-toolbar opacity-0 transition-opacity" }, /* @__PURE__ */ React15.createElement("div", { className: "h-10 p-1 border border-sb-input bg-sb-background rounded-md text-sm font-medium flex gap-1 items-center justify-start" }, /* @__PURE__ */ React15.createElement(EditButton, { id: contentId }), /* @__PURE__ */ React15.createElement(
706
- Button,
707
- {
708
- variant: "ghost",
709
- className: "w-8 h-8 p-0",
710
- onClick: () => bringUp(contentId),
711
- disabled: !canBringUp
712
- },
713
- /* @__PURE__ */ React15.createElement(ArrowUp, { className: "h-5 w-5" })
714
- ), /* @__PURE__ */ React15.createElement(
715
- Button,
716
- {
717
- variant: "ghost",
718
- className: "w-8 h-8 p-0",
719
- onClick: () => bringDown(contentId),
720
- disabled: !canBringDown
721
- },
722
- /* @__PURE__ */ React15.createElement(ArrowDown, { className: "h-5 w-5" })
723
- ), /* @__PURE__ */ React15.createElement(DeleteButton, { contentId })));
724
- };
725
- var EditButton = ({ id }) => {
726
- return /* @__PURE__ */ React15.createElement(Popover, null, /* @__PURE__ */ React15.createElement(PopoverTrigger, { asChild: true }, /* @__PURE__ */ React15.createElement(Button, { variant: "ghost", className: "w-8 h-8 p-0" }, /* @__PURE__ */ React15.createElement(Edit2Icon, { className: "h-5 w-5" }))), /* @__PURE__ */ React15.createElement(
727
- PopoverContent,
728
- {
729
- side: "left",
730
- align: "start",
731
- sideOffset: 16,
732
- alignOffset: -8,
733
- className: "p-0",
734
- collisionPadding: 16
735
- },
736
- /* @__PURE__ */ React15.createElement(EditPopoverInner, { id })
737
- ));
738
- };
739
- var EditPopoverInner = (props) => {
740
- const { id } = props;
741
- const { getItem } = useBuilder();
742
- const item = getItem(id);
743
- if (!item) {
744
- throw new Error(
745
- `[simple-builder]: Item with id ${id} not found in container item form component`
746
- );
747
- }
748
- return /* @__PURE__ */ React15.createElement(Tabs, null, /* @__PURE__ */ React15.createElement(TabsList, { defaultValue: "content" }, /* @__PURE__ */ React15.createElement(TabsTrigger, { value: "content" }, "Inhoud"), /* @__PURE__ */ React15.createElement(TabsTrigger, { value: "design" }, "Design")), /* @__PURE__ */ React15.createElement(TabsContent, { value: "content" }, /* @__PURE__ */ React15.createElement(ContainerItemForm, { item })), /* @__PURE__ */ React15.createElement(TabsContent, { value: "design" }, /* @__PURE__ */ React15.createElement(ItemDesignForm, { item })));
749
- };
750
- var ContainerItemForm = (props) => {
751
- const { item } = props;
752
- const { patchItem } = useBuilder();
753
- const component = builder.getComponent(item.component);
754
- if (!component) {
755
- throw new Error(
756
- `[simple-builder]: Component with id ${item.component} not found in container item form component`
757
- );
758
- }
759
- const form = useForm({
760
- defaultValues: (component.inputs || []).reduce(
761
- (acc, input) => ({
762
- ...acc,
763
- [input.name]: item?.props?.[input.name] ?? input.defaultValue
764
- }),
765
- {}
766
- )
767
- });
768
- const onSubmit = (values) => {
769
- patchItem(item.id, {
770
- props: values
771
- });
772
- };
773
- React15.useEffect(() => {
774
- const subscription = form.watch(() => form.handleSubmit(onSubmit)());
775
- return () => subscription.unsubscribe();
776
- }, [form.watch, form.handleSubmit]);
777
- return /* @__PURE__ */ React15.createElement(Form, { ...form }, /* @__PURE__ */ React15.createElement("form", { onSubmit: form.handleSubmit(onSubmit) }, /* @__PURE__ */ React15.createElement("div", { className: "space-y-4 p-4" }, (component.inputs || []).map((input) => /* @__PURE__ */ React15.createElement(
778
- FormField,
779
- {
780
- key: input.name,
781
- control: form.control,
782
- name: input.name,
783
- render: ({ field }) => /* @__PURE__ */ React15.createElement(RenderInput, { type: input.type, input, field })
784
- }
785
- )))));
786
- };
787
- var spacingSchema = z.discriminatedUnion("indipendent", [
788
- z.object({
789
- indipendent: z.literal(false),
790
- horizontal: z.coerce.number(),
791
- vertical: z.coerce.number()
792
- }),
793
- z.object({
794
- indipendent: z.literal(true),
795
- left: z.coerce.number(),
796
- right: z.coerce.number(),
797
- top: z.coerce.number(),
798
- bottom: z.coerce.number()
799
- })
800
- ]);
801
- var designSchema = z.object({
802
- container: z.boolean(),
803
- background: z.string(),
804
- color: z.string(),
805
- padding: spacingSchema,
806
- margin: spacingSchema
807
- });
808
- var ItemDesignForm = (props) => {
809
- const { item } = props;
810
- const { patchItem } = useBuilder();
811
- const initialPadding = spacing.parse(item.styles?.padding ?? "");
812
- const initialMargin = spacing.parse(item.styles?.margin ?? "");
813
- const form = useForm({
814
- resolver: zodResolver(designSchema),
815
- defaultValues: {
816
- container: item.styles?.container ?? true,
817
- background: item.styles?.background ?? "",
818
- color: item.styles?.color ?? "",
819
- padding: {
820
- indipendent: spacing.isIndipendent(
821
- item.styles?.padding ?? ""
822
- ),
823
- horizontal: initialPadding.left,
824
- vertical: initialPadding.top,
825
- left: initialPadding.left,
826
- right: initialPadding.right,
827
- top: initialPadding.top,
828
- bottom: initialPadding.bottom
829
- },
830
- margin: {
831
- indipendent: spacing.isIndipendent(
832
- item.styles?.margin ?? ""
833
- ),
834
- horizontal: initialMargin.left,
835
- vertical: initialMargin.top,
836
- left: initialMargin.left,
837
- right: initialMargin.right,
838
- top: initialMargin.top,
839
- bottom: initialMargin.bottom
840
- }
841
- }
842
- });
843
- console.log("ERRORS", form.formState.errors);
844
- console.log("VALUES", form.getValues());
845
- const onSubmit = (values) => {
846
- const { container, background, color, padding: p, margin: m } = values;
847
- const padding = !p.indipendent ? `${p.vertical}px ${p.horizontal}px` : `${p.top}px ${p.right}px ${p.bottom}px ${p.left}px`;
848
- const margin = !m.indipendent ? `${m.vertical}px ${m.horizontal}px` : `${m.top}px ${m.right}px ${m.bottom}px ${m.left}px`;
849
- console.log("CALLING_PATCH_ITEM", "ITEM_ID: " + item.id);
850
- patchItem(item.id, {
851
- styles: {
852
- container,
853
- background,
854
- color,
855
- padding,
856
- margin
857
- }
858
- });
859
- };
860
- React15.useEffect(() => {
861
- const subscription = form.watch(() => form.handleSubmit(onSubmit)());
862
- return () => subscription.unsubscribe();
863
- }, [form.watch, form.handleSubmit]);
864
- const [indipendentPadding, indipendentMargin] = form.watch([
865
- "padding.indipendent",
866
- "margin.indipendent"
867
- ]);
868
- return /* @__PURE__ */ React15.createElement(Form, { ...form }, /* @__PURE__ */ React15.createElement("form", { onSubmit: form.handleSubmit(onSubmit) }, /* @__PURE__ */ React15.createElement("div", { className: "space-y-4 p-4" }, /* @__PURE__ */ React15.createElement(
869
- FormField,
870
- {
871
- control: form.control,
872
- name: "background",
873
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormLabel, null, "Achtergrond"), /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
874
- BackgroundPicker,
875
- {
876
- background: field.value,
877
- onBackgroundChange: field.onChange
878
- }
879
- )), /* @__PURE__ */ React15.createElement(FormMessage, null))
880
- }
881
- ), /* @__PURE__ */ React15.createElement(
882
- FormField,
883
- {
884
- control: form.control,
885
- name: "color",
886
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormLabel, null, "Inhoud kleur"), /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
887
- ColorPicker,
888
- {
889
- color: field.value,
890
- onColorChange: field.onChange
891
- }
892
- )), /* @__PURE__ */ React15.createElement(FormMessage, null))
893
- }
894
- ), /* @__PURE__ */ React15.createElement("hr", null), /* @__PURE__ */ React15.createElement(
895
- FormField,
896
- {
897
- control: form.control,
898
- name: "container",
899
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, { className: "flex flex-row items-center justify-between space-y-0" }, /* @__PURE__ */ React15.createElement(FormLabel, null, "Volledige breedte"), /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
900
- Switch,
901
- {
902
- checked: !field.value,
903
- onCheckedChange: (v) => field.onChange(!v)
904
- }
905
- )), /* @__PURE__ */ React15.createElement(FormMessage, null))
906
- }
907
- ), /* @__PURE__ */ React15.createElement("hr", null), /* @__PURE__ */ React15.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15.createElement(FormLabel, null, "Padding"), /* @__PURE__ */ React15.createElement("div", { className: "grid grid-cols-[1fr,auto] gap-3" }, /* @__PURE__ */ React15.createElement("div", { className: "grid grid-cols-2 items-center gap-3" }, !indipendentPadding ? /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(
908
- FormField,
909
- {
910
- control: form.control,
911
- name: "padding.horizontal",
912
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
913
- AdvancedInput,
914
- {
915
- ...field,
916
- prepend: /* @__PURE__ */ React15.createElement(AlignHorizontalSpaceAroundIcon, { className: "h-4 w-4" }),
917
- append: /* @__PURE__ */ React15.createElement("span", { className: "text-sb-muted-sb-foreground" }, "px")
918
- }
919
- )))
920
- }
921
- ), /* @__PURE__ */ React15.createElement(
922
- FormField,
923
- {
924
- control: form.control,
925
- name: "padding.vertical",
926
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
927
- AdvancedInput,
928
- {
929
- ...field,
930
- prepend: /* @__PURE__ */ React15.createElement(AlignHorizontalSpaceAroundIcon, { className: "h-4 w-4 rotate-90" }),
931
- append: /* @__PURE__ */ React15.createElement("span", { className: "text-sb-muted-sb-foreground" }, "px")
932
- }
933
- )))
934
- }
935
- )) : /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(
936
- FormField,
937
- {
938
- control: form.control,
939
- name: "padding.left",
940
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
941
- AdvancedInput,
942
- {
943
- ...field,
944
- prepend: /* @__PURE__ */ React15.createElement(AlignHorizontalJustifyStartIcon, { className: "h-4 w-4" }),
945
- append: /* @__PURE__ */ React15.createElement("span", { className: "text-sb-muted-sb-foreground" }, "px")
946
- }
947
- )))
948
- }
949
- ), /* @__PURE__ */ React15.createElement(
950
- FormField,
951
- {
952
- control: form.control,
953
- name: "padding.top",
954
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
955
- AdvancedInput,
956
- {
957
- ...field,
958
- prepend: /* @__PURE__ */ React15.createElement(AlignHorizontalJustifyStartIcon, { className: "h-4 w-4 rotate-90" }),
959
- append: /* @__PURE__ */ React15.createElement("span", { className: "text-sb-muted-sb-foreground" }, "px")
960
- }
961
- )))
962
- }
963
- ), /* @__PURE__ */ React15.createElement(
964
- FormField,
965
- {
966
- control: form.control,
967
- name: "padding.right",
968
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
969
- AdvancedInput,
970
- {
971
- ...field,
972
- prepend: /* @__PURE__ */ React15.createElement(AlignHorizontalJustifyStartIcon, { className: "h-4 w-4 rotate-180" }),
973
- append: /* @__PURE__ */ React15.createElement("span", { className: "text-sb-muted-sb-foreground" }, "px")
974
- }
975
- )))
976
- }
977
- ), /* @__PURE__ */ React15.createElement(
978
- FormField,
979
- {
980
- control: form.control,
981
- name: "padding.bottom",
982
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
983
- AdvancedInput,
984
- {
985
- ...field,
986
- prepend: /* @__PURE__ */ React15.createElement(AlignHorizontalJustifyStartIcon, { className: "h-4 w-4 -rotate-90" }),
987
- append: /* @__PURE__ */ React15.createElement("span", { className: "text-sb-muted-sb-foreground" }, "px")
988
- }
989
- )))
990
- }
991
- ))), /* @__PURE__ */ React15.createElement("div", { className: "shrink-0" }, /* @__PURE__ */ React15.createElement(
992
- FormField,
993
- {
994
- control: form.control,
995
- name: "padding.indipendent",
996
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
997
- Toggle,
998
- {
999
- className: "shrink-0 flex w-8 h-8 p-0",
1000
- variant: "outline",
1001
- size: "sm",
1002
- pressed: field.value,
1003
- onPressedChange: field.onChange
1004
- },
1005
- /* @__PURE__ */ React15.createElement(ScanIcon, { className: "h-4 w-4" })
1006
- ))
1007
- }
1008
- ))), /* @__PURE__ */ React15.createElement(FormMessage, null)), /* @__PURE__ */ React15.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15.createElement(FormLabel, null, "Margin"), /* @__PURE__ */ React15.createElement("div", { className: "grid grid-cols-[1fr,auto] gap-3" }, /* @__PURE__ */ React15.createElement("div", { className: "grid grid-cols-2 items-center gap-3" }, !indipendentMargin ? /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(
1009
- FormField,
1010
- {
1011
- control: form.control,
1012
- name: "margin.horizontal",
1013
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
1014
- AdvancedInput,
1015
- {
1016
- ...field,
1017
- prepend: /* @__PURE__ */ React15.createElement(AlignHorizontalSpaceAroundIcon, { className: "h-4 w-4" }),
1018
- append: /* @__PURE__ */ React15.createElement("span", { className: "text-sb-muted-sb-foreground" }, "px")
1019
- }
1020
- )))
1021
- }
1022
- ), /* @__PURE__ */ React15.createElement(
1023
- FormField,
1024
- {
1025
- control: form.control,
1026
- name: "margin.vertical",
1027
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
1028
- AdvancedInput,
1029
- {
1030
- ...field,
1031
- prepend: /* @__PURE__ */ React15.createElement(AlignHorizontalSpaceAroundIcon, { className: "h-4 w-4 rotate-90" }),
1032
- append: /* @__PURE__ */ React15.createElement("span", { className: "text-sb-muted-sb-foreground" }, "px")
1033
- }
1034
- )))
1035
- }
1036
- )) : /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(
1037
- FormField,
1038
- {
1039
- control: form.control,
1040
- name: "margin.left",
1041
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
1042
- AdvancedInput,
1043
- {
1044
- ...field,
1045
- prepend: /* @__PURE__ */ React15.createElement(AlignHorizontalJustifyStartIcon, { className: "h-4 w-4" }),
1046
- append: /* @__PURE__ */ React15.createElement("span", { className: "text-sb-muted-sb-foreground" }, "px")
1047
- }
1048
- )))
1049
- }
1050
- ), /* @__PURE__ */ React15.createElement(
1051
- FormField,
1052
- {
1053
- control: form.control,
1054
- name: "margin.top",
1055
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
1056
- AdvancedInput,
1057
- {
1058
- ...field,
1059
- prepend: /* @__PURE__ */ React15.createElement(AlignHorizontalJustifyStartIcon, { className: "h-4 w-4 rotate-90" }),
1060
- append: /* @__PURE__ */ React15.createElement("span", { className: "text-sb-muted-sb-foreground" }, "px")
1061
- }
1062
- )))
1063
- }
1064
- ), /* @__PURE__ */ React15.createElement(
1065
- FormField,
1066
- {
1067
- control: form.control,
1068
- name: "margin.right",
1069
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
1070
- AdvancedInput,
1071
- {
1072
- ...field,
1073
- prepend: /* @__PURE__ */ React15.createElement(AlignHorizontalJustifyStartIcon, { className: "h-4 w-4 rotate-180" }),
1074
- append: /* @__PURE__ */ React15.createElement("span", { className: "text-sb-muted-sb-foreground" }, "px")
1075
- }
1076
- )))
1077
- }
1078
- ), /* @__PURE__ */ React15.createElement(
1079
- FormField,
1080
- {
1081
- control: form.control,
1082
- name: "margin.bottom",
1083
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
1084
- AdvancedInput,
1085
- {
1086
- ...field,
1087
- prepend: /* @__PURE__ */ React15.createElement(AlignHorizontalJustifyStartIcon, { className: "h-4 w-4 -rotate-90" }),
1088
- append: /* @__PURE__ */ React15.createElement("span", { className: "text-sb-muted-sb-foreground" }, "px")
1089
- }
1090
- )))
1091
- }
1092
- ))), /* @__PURE__ */ React15.createElement("div", { className: "shrink-0" }, /* @__PURE__ */ React15.createElement(
1093
- FormField,
1094
- {
1095
- control: form.control,
1096
- name: "margin.indipendent",
1097
- render: ({ field }) => /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
1098
- Toggle,
1099
- {
1100
- className: "shrink-0 flex w-8 h-8 p-0",
1101
- variant: "outline",
1102
- size: "sm",
1103
- pressed: field.value,
1104
- onPressedChange: field.onChange
1105
- },
1106
- /* @__PURE__ */ React15.createElement(ScanIcon, { className: "h-4 w-4" })
1107
- ))
1108
- }
1109
- ))), /* @__PURE__ */ React15.createElement(FormMessage, null)))));
1110
- };
1111
- var RenderInput = (props) => {
1112
- const { type, input, field } = props;
1113
- switch (type) {
1114
- case "string":
1115
- return /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormLabel, null, input.friendlyName || input.name), /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(Input, { ...field })), input.helperText && /* @__PURE__ */ React15.createElement(FormDescription, null, input.helperText), /* @__PURE__ */ React15.createElement(FormMessage, null));
1116
- case "longText":
1117
- return /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormLabel, null, input.friendlyName || input.name), /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(Textarea, { ...field })), input.helperText && /* @__PURE__ */ React15.createElement(FormDescription, null, input.helperText), /* @__PURE__ */ React15.createElement(FormMessage, null));
1118
- case "richText":
1119
- return /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormLabel, null, input.friendlyName || input.name), /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(Textarea, { ...field })), input.helperText && /* @__PURE__ */ React15.createElement(FormDescription, null, input.helperText), /* @__PURE__ */ React15.createElement(FormMessage, null));
1120
- case "number":
1121
- return /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormLabel, null, input.friendlyName || input.name), /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(Input, { type: "number", ...field })), input.helperText && /* @__PURE__ */ React15.createElement(FormDescription, null, input.helperText), /* @__PURE__ */ React15.createElement(FormMessage, null));
1122
- case "color":
1123
- return /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormLabel, null, input.friendlyName || input.name), /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(ColorPicker, { color: field.value, onColorChange: field.onChange })), input.helperText && /* @__PURE__ */ React15.createElement(FormDescription, null, input.helperText), /* @__PURE__ */ React15.createElement(FormMessage, null));
1124
- case "date":
1125
- return /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormLabel, null, input.friendlyName || input.name), /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(Popover, null, /* @__PURE__ */ React15.createElement(PopoverTrigger, { asChild: true }, /* @__PURE__ */ React15.createElement(
1126
- Button,
1127
- {
1128
- variant: "outline",
1129
- size: "sm",
1130
- className: cn(
1131
- "w-full flex justify-start text-left font-normal",
1132
- !field.value && "text-muted-foreground"
1133
- )
1134
- },
1135
- /* @__PURE__ */ React15.createElement(CalendarIcon, { className: "mr-2 h-4 w-4" }),
1136
- field.value ? format(field.value, "PPP") : /* @__PURE__ */ React15.createElement("span", null, "Pick a date")
1137
- )), /* @__PURE__ */ React15.createElement(PopoverContent, { className: "w-auto p-0", align: "start" }, /* @__PURE__ */ React15.createElement(
1138
- Calendar,
1139
- {
1140
- mode: "single",
1141
- selected: field.value,
1142
- onSelect: field.onChange,
1143
- initialFocus: true
1144
- }
1145
- )))), input.helperText && /* @__PURE__ */ React15.createElement(FormDescription, null, input.helperText), /* @__PURE__ */ React15.createElement(FormMessage, null));
1146
- case "boolean":
1147
- return /* @__PURE__ */ React15.createElement(FormItem, { className: "flex flex-row items-center justify-between space-y-0" }, /* @__PURE__ */ React15.createElement(FormLabel, null, input.friendlyName || input.name), /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(Switch, { checked: field.value, onCheckedChange: field.onChange })), input.helperText && /* @__PURE__ */ React15.createElement(FormDescription, null, input.helperText), /* @__PURE__ */ React15.createElement(FormMessage, null));
1148
- case "file":
1149
- return /* @__PURE__ */ React15.createElement(FormItem, null, /* @__PURE__ */ React15.createElement(FormLabel, null, input.friendlyName || input.name), /* @__PURE__ */ React15.createElement(FormControl, null, /* @__PURE__ */ React15.createElement(
1150
- MediaInput,
1151
- {
1152
- className: "grid grid-cols-2 gap-1",
1153
- itemClassName: "aspect-video h-auto w-full",
1154
- multiple: false,
1155
- onFilesChange: (files) => field.onChange(files[0]),
1156
- onError: (e) => console.error(
1157
- "[media-input]: Title: " + e?.title,
1158
- "media-input: Error: " + e?.description
1159
- )
1160
- }
1161
- )), input.helperText && /* @__PURE__ */ React15.createElement(FormDescription, null, input.helperText), /* @__PURE__ */ React15.createElement(FormMessage, null));
1162
- default:
1163
- throw new Error(
1164
- `[simple-builder]: Input type "${props.type}" not supported`
1165
- );
1166
- }
1167
- };
1168
- var DeleteButton = ({ contentId }) => {
1169
- const { deleteContent } = useBuilder();
1170
- return /* @__PURE__ */ React15.createElement(AlertDialog, null, /* @__PURE__ */ React15.createElement(AlertDialogTrigger, { asChild: true }, /* @__PURE__ */ React15.createElement(Button, { variant: "ghost", className: "w-8 h-8 p-0 text-sb-destructive" }, /* @__PURE__ */ React15.createElement(Trash2Icon, { className: "h-5 w-5" }))), /* @__PURE__ */ React15.createElement(AlertDialogContent, null, /* @__PURE__ */ React15.createElement(AlertDialogDescription, null, "Weet je zeker dat je dit blok wilt verwijderen?"), /* @__PURE__ */ React15.createElement(AlertDialogFooter, null, /* @__PURE__ */ React15.createElement(AlertDialogCancel, null, "Annuleren"), /* @__PURE__ */ React15.createElement(
1171
- AlertDialogAction,
1172
- {
1173
- className: buttonVariants({ variant: "destructive" }),
1174
- onClick: () => deleteContent(contentId)
1175
- },
1176
- "Verwijderen"
1177
- ))));
1178
- };
1179
- var DesignWrapper = (props) => {
1180
- const { children, className, styles } = props;
1181
- const { container = true, background, ...rest } = styles || {};
1182
- const matches = typeof background === "string" ? background.match(/url\(["']?(.*?)["']?\)/) : void 0;
1183
- const src = matches ? matches[1] : void 0;
1184
- return /* @__PURE__ */ React15.createElement(
1185
- "div",
1186
- {
1187
- className: cn("relative", className),
1188
- style: { ...!src && { background }, ...rest }
1189
- },
1190
- src && /* @__PURE__ */ React15.createElement(
1191
- Image,
1192
- {
1193
- src,
1194
- alt: "",
1195
- fill: true,
1196
- className: "object-cover absolute inset-0 pointer-events-none -z-[1]"
1197
- }
1198
- ),
1199
- container ? /* @__PURE__ */ React15.createElement("div", { className: "container mx-auto" }, children) : children
1200
- );
1201
- };
1202
-
1203
- // src/components/build-container-client.tsx
1204
- var BuildContainerInner = (props) => {
1205
- const { id, name, content, multiple = false } = props;
1206
- const items = Array.isArray(content) ? content : content?.[name] || [];
1207
- if (!multiple && items.length > 1) {
1208
- console.error(
1209
- "[simple-builder]: Multiple content blocks detected when using property multiple false."
1210
- );
1211
- }
1212
- return /* @__PURE__ */ React15.createElement("div", null, items.length <= 0 ? /* @__PURE__ */ React15.createElement(AddContentPlaceholder, { parent: id, container: name, index: 0 }) : multiple && /* @__PURE__ */ React15.createElement(AddContentDividerButton, { parent: id, container: name, index: 0 }), items.map((item, i) => /* @__PURE__ */ React15.createElement(React15.Fragment, { key: item.id }, /* @__PURE__ */ React15.createElement("div", { className: "relative sb-container-item" }, /* @__PURE__ */ React15.createElement(DesignWrapper, { styles: item.styles }, builder.bindComponent(item, true)), /* @__PURE__ */ React15.createElement(
1213
- ContainerItemToolbar,
1214
- {
1215
- contentId: item.id,
1216
- canBringUp: i > 0,
1217
- canBringDown: i < items.length - 1
1218
- }
1219
- )), multiple && /* @__PURE__ */ React15.createElement(
1220
- AddContentDividerButton,
1221
- {
1222
- parent: id,
1223
- container: name,
1224
- index: i + 1
1225
- }
1226
- ))));
1227
- };
1228
- var build_container_client_default = BuildContainerInner;
1229
- var AddContentButton = (props) => {
1230
- const components = builder.getComponents();
1231
- const { addContent } = useBuilder();
1232
- return /* @__PURE__ */ React15.createElement(Popover, null, /* @__PURE__ */ React15.createElement(PopoverTrigger, { asChild: true }, props.children), /* @__PURE__ */ React15.createElement(PopoverContent, { className: "p-1" }, /* @__PURE__ */ React15.createElement("div", { className: "grid grid-cols-2 gap-2" }, components.map((component) => {
1233
- const Icon = component.icon ?? ImageIcon;
1234
- return /* @__PURE__ */ React15.createElement(PopoverClose, { key: component.name, asChild: true }, /* @__PURE__ */ React15.createElement(
1235
- Button,
1236
- {
1237
- variant: "ghost",
1238
- className: "justify-start",
1239
- onClick: () => {
1240
- addContent(
1241
- component.name,
1242
- props.container,
1243
- props.parent,
1244
- props.index
1245
- );
1246
- }
1247
- },
1248
- /* @__PURE__ */ React15.createElement(Icon, { className: "mr-2 h-4 w-4 shrink-0" }),
1249
- component.friendlyName ?? component.name
1250
- ));
1251
- }))));
1252
- };
1253
- var AddContentPlaceholder = (props) => {
1254
- return /* @__PURE__ */ React15.createElement(AddContentButton, { ...props }, /* @__PURE__ */ React15.createElement("div", { className: "flex justify-center bg-sb-primary/50 p-4" }, /* @__PURE__ */ React15.createElement(Button, { size: "sm" }, /* @__PURE__ */ React15.createElement(PlusIcon, { className: "mr-2 h-4 w-4" }), "Blok Toevoegen")));
1255
- };
1256
- var AddContentDividerButton = (props) => {
1257
- return /* @__PURE__ */ React15.createElement(AddContentButton, { ...props }, /* @__PURE__ */ React15.createElement("div", { className: "w-full h-1 -my-[2px] bg-sb-primary relative z-20 opacity-0 add-content-divider-button transition-opacity" }, /* @__PURE__ */ React15.createElement(
1258
- Button,
1259
- {
1260
- size: "sm",
1261
- className: "absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 shadow"
1262
- },
1263
- /* @__PURE__ */ React15.createElement(PlusIcon, { className: "mr-2 h-4 w-4" }),
1264
- "Blok Toevoegen"
1265
- )));
1266
- };
1267
-
1268
- export { BuildContainerInner, build_container_client_default as default };