@dyrected/admin 2.0.1 → 2.4.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/CHANGELOG.md +29 -0
- package/package.json +4 -4
- package/scripts/prefix-tailwind-precision.py +98 -0
- package/scripts/prefix-tailwind.py +67 -0
- package/src/components/auth/auth-gate.tsx +4 -4
- package/src/components/error-boundary.tsx +4 -4
- package/src/components/forms/fields/block-builder.tsx +24 -24
- package/src/components/forms/fields/date-picker.tsx +7 -7
- package/src/components/forms/fields/json-editor.tsx +5 -5
- package/src/components/forms/fields/media-picker.tsx +39 -39
- package/src/components/forms/fields/multi-select.tsx +12 -12
- package/src/components/forms/fields/radio-field.tsx +8 -8
- package/src/components/forms/fields/relationship-picker.tsx +13 -13
- package/src/components/forms/fields/rich-text-editor.tsx +22 -22
- package/src/components/forms/fields/select-field.tsx +3 -3
- package/src/components/forms/form-engine.tsx +3 -3
- package/src/components/forms/form-field-renderer.tsx +37 -37
- package/src/components/layout/admin-shell.tsx +60 -60
- package/src/components/live-preview/LivePreviewPane.tsx +14 -14
- package/src/components/media/focal-point-picker.tsx +9 -9
- package/src/components/media/media-card.tsx +10 -10
- package/src/components/media/media-grid.tsx +3 -3
- package/src/components/media/media-library-dialog.tsx +105 -105
- package/src/components/ui/badge.tsx +5 -5
- package/src/components/ui/button.tsx +11 -11
- package/src/components/ui/calendar.tsx +36 -36
- package/src/components/ui/card.tsx +6 -6
- package/src/components/ui/checkbox.tsx +3 -3
- package/src/components/ui/command.tsx +12 -12
- package/src/components/ui/data-table.tsx +18 -18
- package/src/components/ui/dialog.tsx +9 -9
- package/src/components/ui/dropdown-menu.tsx +16 -16
- package/src/components/ui/form.tsx +4 -4
- package/src/components/ui/input.tsx +3 -3
- package/src/components/ui/label.tsx +1 -1
- package/src/components/ui/page-header.tsx +6 -6
- package/src/components/ui/pagination.tsx +6 -6
- package/src/components/ui/popover.tsx +1 -1
- package/src/components/ui/progress.tsx +2 -2
- package/src/components/ui/radio-group.tsx +4 -4
- package/src/components/ui/render-cell.tsx +16 -16
- package/src/components/ui/scroll-area.tsx +6 -6
- package/src/components/ui/select.tsx +14 -14
- package/src/components/ui/separator.tsx +2 -2
- package/src/components/ui/sheet.tsx +13 -13
- package/src/components/ui/sidebar.tsx +60 -60
- package/src/components/ui/skeleton.tsx +1 -1
- package/src/components/ui/sonner.tsx +1 -1
- package/src/components/ui/switch.tsx +2 -2
- package/src/components/ui/table.tsx +7 -7
- package/src/components/ui/tabs.tsx +3 -3
- package/src/components/ui/textarea.tsx +1 -1
- package/src/components/ui/toggle.tsx +6 -6
- package/src/components/ui/tooltip.tsx +1 -1
- package/src/index.css +27 -27
- package/src/index.tsx +4 -4
- package/src/lib/utils.ts +7 -3
- package/src/pages/auth/first-user-page.tsx +18 -18
- package/src/pages/auth/login-page.tsx +14 -14
- package/src/pages/collections/edit-page.tsx +37 -37
- package/src/pages/collections/list-page.tsx +23 -23
- package/src/pages/dashboard/dashboard.tsx +49 -49
- package/src/pages/globals/editor-page.tsx +13 -13
- package/src/pages/media/media-page.tsx +106 -106
- package/src/pages/setup/setup-prompt.tsx +48 -48
- package/tailwind.config.ts +1 -0
- package/vite.config.ts +0 -1
|
@@ -61,8 +61,8 @@ export function MultiSelect({
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
return (
|
|
64
|
-
<div className="flex flex-col gap-2">
|
|
65
|
-
{label && <label className="text-sm font-medium leading-none">{label}</label>}
|
|
64
|
+
<div className="dy-flex dy-flex-col dy-gap-2">
|
|
65
|
+
{label && <label className="dy-text-sm dy-font-medium dy-leading-none">{label}</label>}
|
|
66
66
|
<Popover open={disabled ? false : open} onOpenChange={setOpen}>
|
|
67
67
|
<PopoverTrigger asChild>
|
|
68
68
|
<Button
|
|
@@ -70,11 +70,11 @@ export function MultiSelect({
|
|
|
70
70
|
role="combobox"
|
|
71
71
|
aria-expanded={open}
|
|
72
72
|
disabled={disabled}
|
|
73
|
-
className="w-full justify-between h-auto min-h-10 font-normal"
|
|
73
|
+
className="dy-w-full dy-justify-between dy-h-auto dy-min-h-10 dy-font-normal"
|
|
74
74
|
>
|
|
75
|
-
<div className="flex flex-wrap gap-1 items-center">
|
|
75
|
+
<div className="dy-flex dy-flex-wrap dy-gap-1 dy-items-center">
|
|
76
76
|
{value.length === 0 && (
|
|
77
|
-
<span className="text-muted-foreground">{placeholder}</span>
|
|
77
|
+
<span className="dy-text-muted-foreground">{placeholder}</span>
|
|
78
78
|
)}
|
|
79
79
|
{value.map((val) => {
|
|
80
80
|
const option = options.find((opt) => opt.value === val)
|
|
@@ -82,14 +82,14 @@ export function MultiSelect({
|
|
|
82
82
|
<Badge
|
|
83
83
|
key={val}
|
|
84
84
|
variant="secondary"
|
|
85
|
-
className="mr-1 mb-1 items-center gap-1"
|
|
85
|
+
className="dy-mr-1 dy-mb-1 dy-items-center dy-gap-1"
|
|
86
86
|
>
|
|
87
87
|
{option?.label || val}
|
|
88
88
|
{!disabled && (
|
|
89
89
|
<div
|
|
90
90
|
role="button"
|
|
91
91
|
tabIndex={0}
|
|
92
|
-
className="ring-offset-background rounded-full outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
|
|
92
|
+
className="dy-ring-offset-background dy-rounded-full dy-outline-none focus:dy-ring-2 focus:dy-ring-ring focus:dy-ring-offset-2"
|
|
93
93
|
onKeyDown={(e) => {
|
|
94
94
|
if (e.key === "Enter") {
|
|
95
95
|
handleRemove(val)
|
|
@@ -101,17 +101,17 @@ export function MultiSelect({
|
|
|
101
101
|
}}
|
|
102
102
|
onClick={() => handleRemove(val)}
|
|
103
103
|
>
|
|
104
|
-
<X className="h-3 w-3 text-muted-foreground hover:text-foreground" />
|
|
104
|
+
<X className="dy-h-3 dy-w-3 dy-text-muted-foreground hover:dy-text-foreground" />
|
|
105
105
|
</div>
|
|
106
106
|
)}
|
|
107
107
|
</Badge>
|
|
108
108
|
)
|
|
109
109
|
})}
|
|
110
110
|
</div>
|
|
111
|
-
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
|
111
|
+
<ChevronsUpDown className="dy-ml-2 dy-h-4 dy-w-4 dy-shrink-0 dy-opacity-50" />
|
|
112
112
|
</Button>
|
|
113
113
|
</PopoverTrigger>
|
|
114
|
-
<PopoverContent className="w-[400px] p-0" align="start">
|
|
114
|
+
<PopoverContent className="dy-w-[400px] dy-p-0" align="start">
|
|
115
115
|
<Command>
|
|
116
116
|
<CommandInput placeholder="Search options..." />
|
|
117
117
|
<CommandList>
|
|
@@ -127,8 +127,8 @@ export function MultiSelect({
|
|
|
127
127
|
>
|
|
128
128
|
<Check
|
|
129
129
|
className={cn(
|
|
130
|
-
"mr-2 h-4 w-4",
|
|
131
|
-
isSelected ? "opacity-100" : "opacity-0"
|
|
130
|
+
"dy-mr-2 dy-h-4 dy-w-4",
|
|
131
|
+
isSelected ? "dy-opacity-100" : "dy-opacity-0"
|
|
132
132
|
)}
|
|
133
133
|
/>
|
|
134
134
|
{option.label}
|
|
@@ -20,26 +20,26 @@ export function RadioField({ schema, field, disabled }: RadioFieldProps) {
|
|
|
20
20
|
defaultValue={field.value}
|
|
21
21
|
disabled={disabled}
|
|
22
22
|
className={cn(
|
|
23
|
-
"gap-4",
|
|
24
|
-
isHorizontal ? "flex flex-wrap items-center" : "flex flex-col"
|
|
23
|
+
"dy-gap-4",
|
|
24
|
+
isHorizontal ? "dy-flex dy-flex-wrap dy-items-center" : "dy-flex dy-flex-col"
|
|
25
25
|
)}
|
|
26
26
|
>
|
|
27
27
|
{options.map((opt) => (
|
|
28
28
|
<div key={opt.value} className={cn(
|
|
29
|
-
"relative flex items-center",
|
|
30
|
-
isHorizontal ? "min-w-[120px]" : "w-full"
|
|
29
|
+
"dy-relative dy-flex dy-items-center",
|
|
30
|
+
isHorizontal ? "dy-min-w-[120px]" : "dy-w-full"
|
|
31
31
|
)}>
|
|
32
32
|
<RadioGroupItem
|
|
33
33
|
value={opt.value}
|
|
34
34
|
id={`${field.name}-${opt.value}`}
|
|
35
|
-
className="peer absolute left-4 z-10"
|
|
35
|
+
className="dy-peer dy-absolute dy-left-4 dy-z-10"
|
|
36
36
|
/>
|
|
37
37
|
<Label
|
|
38
38
|
htmlFor={`${field.name}-${opt.value}`}
|
|
39
39
|
className={cn(
|
|
40
|
-
"flex flex-1 items-center pl-12 pr-4 py-3 rounded-xl border border-border/40 bg-white/50 cursor-pointer transition-all hover:bg-white/80 hover:shadow-sm",
|
|
41
|
-
"peer-data-[state=checked]:border-primary peer-data-[state=checked]:bg-primary/5 peer-data-[state=checked]:shadow-md peer-data-[state=checked]:ring-1 peer-data-[state=checked]:ring-primary/20",
|
|
42
|
-
"text-sm font-medium text-foreground/70 peer-data-[state=checked]:text-primary"
|
|
40
|
+
"dy-flex dy-flex-1 dy-items-center dy-pl-12 dy-pr-4 dy-py-3 dy-rounded-xl dy-border dy-border-border/40 dy-bg-white/50 dy-cursor-pointer dy-transition-all hover:dy-bg-white/80 hover:dy-shadow-sm",
|
|
41
|
+
"dy-peer-data-[state=checked]:dy-border-primary dy-peer-data-[state=checked]:dy-bg-primary/5 dy-peer-data-[state=checked]:dy-shadow-md dy-peer-data-[state=checked]:dy-ring-1 dy-peer-data-[state=checked]:dy-ring-primary/20",
|
|
42
|
+
"dy-text-sm dy-font-medium dy-text-foreground/70 dy-peer-data-[state=checked]:dy-text-primary"
|
|
43
43
|
)}
|
|
44
44
|
>
|
|
45
45
|
{opt.label}
|
|
@@ -61,8 +61,8 @@ export function RelationshipPicker({ value, onChange, label, relationTo, multipl
|
|
|
61
61
|
const selectedItems = values.map(v => data?.find((item: any) => item.id === v)).filter(Boolean)
|
|
62
62
|
|
|
63
63
|
return (
|
|
64
|
-
<div className="flex flex-col gap-2">
|
|
65
|
-
{label && <label className="text-sm font-medium leading-none">{label}</label>}
|
|
64
|
+
<div className="dy-flex dy-flex-col dy-gap-2">
|
|
65
|
+
{label && <label className="dy-text-sm dy-font-medium dy-leading-none">{label}</label>}
|
|
66
66
|
<Popover open={disabled ? false : open} onOpenChange={setOpen}>
|
|
67
67
|
<PopoverTrigger asChild>
|
|
68
68
|
<Button
|
|
@@ -70,25 +70,25 @@ export function RelationshipPicker({ value, onChange, label, relationTo, multipl
|
|
|
70
70
|
role="combobox"
|
|
71
71
|
aria-expanded={open}
|
|
72
72
|
disabled={disabled}
|
|
73
|
-
className="w-full justify-between font-normal"
|
|
73
|
+
className="dy-w-full dy-justify-between dy-font-normal"
|
|
74
74
|
>
|
|
75
75
|
{isLoading ? (
|
|
76
76
|
"Loading..."
|
|
77
77
|
) : selectedItems.length > 0 ? (
|
|
78
|
-
<div className="flex flex-wrap gap-1">
|
|
78
|
+
<div className="dy-flex dy-flex-wrap dy-gap-1">
|
|
79
79
|
{selectedItems.map((item: any) => (
|
|
80
|
-
<Badge key={item.id} variant="secondary" className="text-[10px] h-5 px-1.5">
|
|
80
|
+
<Badge key={item.id} variant="secondary" className="dy-text-[10px] dy-h-5 dy-px-1.5">
|
|
81
81
|
{getDisplayLabel(item)}
|
|
82
82
|
</Badge>
|
|
83
83
|
))}
|
|
84
84
|
</div>
|
|
85
85
|
) : (
|
|
86
|
-
<span className="text-muted-foreground">Select {relationTo}...</span>
|
|
86
|
+
<span className="dy-text-muted-foreground">Select {relationTo}...</span>
|
|
87
87
|
)}
|
|
88
|
-
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
|
88
|
+
<ChevronsUpDown className="dy-ml-2 dy-h-4 dy-w-4 dy-shrink-0 dy-opacity-50" />
|
|
89
89
|
</Button>
|
|
90
90
|
</PopoverTrigger>
|
|
91
|
-
<PopoverContent className="w-[400px] p-0" align="start">
|
|
91
|
+
<PopoverContent className="dy-w-[400px] dy-p-0" align="start">
|
|
92
92
|
<Command>
|
|
93
93
|
<CommandInput
|
|
94
94
|
placeholder={`Search ${relationTo}...`}
|
|
@@ -113,20 +113,20 @@ export function RelationshipPicker({ value, onChange, label, relationTo, multipl
|
|
|
113
113
|
}
|
|
114
114
|
}}
|
|
115
115
|
>
|
|
116
|
-
<div className="flex items-center gap-3 flex-1">
|
|
116
|
+
<div className="dy-flex dy-items-center dy-gap-3 dy-flex-1">
|
|
117
117
|
{isUpload && (
|
|
118
|
-
<div className="h-6 w-6 rounded border bg-muted overflow-hidden flex-shrink-0">
|
|
118
|
+
<div className="dy-h-6 dy-w-6 dy-rounded dy-border dy-bg-muted dy-overflow-hidden dy-flex-shrink-0">
|
|
119
119
|
<img
|
|
120
120
|
src={getMediaUrl(item, client?.getBaseUrl() || "")}
|
|
121
|
-
className="h-full w-full object-cover"
|
|
121
|
+
className="dy-h-full dy-w-full dy-object-cover"
|
|
122
122
|
alt=""
|
|
123
123
|
/>
|
|
124
124
|
</div>
|
|
125
125
|
)}
|
|
126
|
-
<span className="flex-1">{getDisplayLabel(item)}</span>
|
|
126
|
+
<span className="dy-flex-1">{getDisplayLabel(item)}</span>
|
|
127
127
|
<Check
|
|
128
128
|
className={cn(
|
|
129
|
-
"h-4 w-4",
|
|
129
|
+
"dy-h-4 dy-w-4",
|
|
130
130
|
values.includes(item.id) ? "opacity-100" : "opacity-0"
|
|
131
131
|
)}
|
|
132
132
|
/>
|
|
@@ -45,109 +45,109 @@ const MenuBar = ({ editor, collection = "media" }: { editor: Editor | null, coll
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
return (
|
|
48
|
-
<div className="border border-input rounded-t-md p-1 flex flex-wrap gap-1 items-center bg-muted/50">
|
|
48
|
+
<div className="dy-border dy-border-input dy-rounded-t-md dy-p-1 dy-flex dy-flex-wrap dy-gap-1 dy-items-center dy-bg-muted/50">
|
|
49
49
|
<Toggle
|
|
50
50
|
size="sm"
|
|
51
51
|
pressed={editor.isActive("bold")}
|
|
52
52
|
onPressedChange={() => editor.chain().focus().toggleBold().run()}
|
|
53
53
|
>
|
|
54
|
-
<Bold className="h-4 w-4" />
|
|
54
|
+
<Bold className="dy-h-4 dy-w-4" />
|
|
55
55
|
</Toggle>
|
|
56
56
|
<Toggle
|
|
57
57
|
size="sm"
|
|
58
58
|
pressed={editor.isActive("italic")}
|
|
59
59
|
onPressedChange={() => editor.chain().focus().toggleItalic().run()}
|
|
60
60
|
>
|
|
61
|
-
<Italic className="h-4 w-4" />
|
|
61
|
+
<Italic className="dy-h-4 dy-w-4" />
|
|
62
62
|
</Toggle>
|
|
63
63
|
<Toggle
|
|
64
64
|
size="sm"
|
|
65
65
|
pressed={editor.isActive("underline")}
|
|
66
66
|
onPressedChange={() => editor.chain().focus().toggleUnderline().run()}
|
|
67
67
|
>
|
|
68
|
-
<UnderlineIcon className="h-4 w-4" />
|
|
68
|
+
<UnderlineIcon className="dy-h-4 dy-w-4" />
|
|
69
69
|
</Toggle>
|
|
70
70
|
<Toggle
|
|
71
71
|
size="sm"
|
|
72
72
|
pressed={editor.isActive("strike")}
|
|
73
73
|
onPressedChange={() => editor.chain().focus().toggleStrike().run()}
|
|
74
74
|
>
|
|
75
|
-
<Strikethrough className="h-4 w-4" />
|
|
75
|
+
<Strikethrough className="dy-h-4 dy-w-4" />
|
|
76
76
|
</Toggle>
|
|
77
77
|
|
|
78
|
-
<div className="w-[1px] h-6 bg-border mx-1" />
|
|
78
|
+
<div className="dy-w-[1px] dy-h-6 dy-bg-border dy-mx-1" />
|
|
79
79
|
|
|
80
80
|
<Toggle
|
|
81
81
|
size="sm"
|
|
82
82
|
pressed={editor.isActive("heading", { level: 1 })}
|
|
83
83
|
onPressedChange={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
|
|
84
84
|
>
|
|
85
|
-
<Heading1 className="h-4 w-4" />
|
|
85
|
+
<Heading1 className="dy-h-4 dy-w-4" />
|
|
86
86
|
</Toggle>
|
|
87
87
|
<Toggle
|
|
88
88
|
size="sm"
|
|
89
89
|
pressed={editor.isActive("heading", { level: 2 })}
|
|
90
90
|
onPressedChange={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
|
|
91
91
|
>
|
|
92
|
-
<Heading2 className="h-4 w-4" />
|
|
92
|
+
<Heading2 className="dy-h-4 dy-w-4" />
|
|
93
93
|
</Toggle>
|
|
94
94
|
<Toggle
|
|
95
95
|
size="sm"
|
|
96
96
|
pressed={editor.isActive("bulletList")}
|
|
97
97
|
onPressedChange={() => editor.chain().focus().toggleBulletList().run()}
|
|
98
98
|
>
|
|
99
|
-
<List className="h-4 w-4" />
|
|
99
|
+
<List className="dy-h-4 dy-w-4" />
|
|
100
100
|
</Toggle>
|
|
101
101
|
<Toggle
|
|
102
102
|
size="sm"
|
|
103
103
|
pressed={editor.isActive("orderedList")}
|
|
104
104
|
onPressedChange={() => editor.chain().focus().toggleOrderedList().run()}
|
|
105
105
|
>
|
|
106
|
-
<ListOrdered className="h-4 w-4" />
|
|
106
|
+
<ListOrdered className="dy-h-4 dy-w-4" />
|
|
107
107
|
</Toggle>
|
|
108
108
|
<Toggle
|
|
109
109
|
size="sm"
|
|
110
110
|
pressed={editor.isActive("blockquote")}
|
|
111
111
|
onPressedChange={() => editor.chain().focus().toggleBlockquote().run()}
|
|
112
112
|
>
|
|
113
|
-
<Quote className="h-4 w-4" />
|
|
113
|
+
<Quote className="dy-h-4 dy-w-4" />
|
|
114
114
|
</Toggle>
|
|
115
115
|
|
|
116
|
-
<div className="w-[1px] h-6 bg-border mx-1" />
|
|
116
|
+
<div className="dy-w-[1px] dy-h-6 dy-bg-border dy-mx-1" />
|
|
117
117
|
|
|
118
118
|
<Toggle
|
|
119
119
|
size="sm"
|
|
120
120
|
pressed={editor.isActive({ textAlign: "left" })}
|
|
121
121
|
onPressedChange={() => editor.chain().focus().setTextAlign("left").run()}
|
|
122
122
|
>
|
|
123
|
-
<AlignLeft className="h-4 w-4" />
|
|
123
|
+
<AlignLeft className="dy-h-4 dy-w-4" />
|
|
124
124
|
</Toggle>
|
|
125
125
|
<Toggle
|
|
126
126
|
size="sm"
|
|
127
127
|
pressed={editor.isActive({ textAlign: "center" })}
|
|
128
128
|
onPressedChange={() => editor.chain().focus().setTextAlign("center").run()}
|
|
129
129
|
>
|
|
130
|
-
<AlignCenter className="h-4 w-4" />
|
|
130
|
+
<AlignCenter className="dy-h-4 dy-w-4" />
|
|
131
131
|
</Toggle>
|
|
132
132
|
<Toggle
|
|
133
133
|
size="sm"
|
|
134
134
|
pressed={editor.isActive({ textAlign: "right" })}
|
|
135
135
|
onPressedChange={() => editor.chain().focus().setTextAlign("right").run()}
|
|
136
136
|
>
|
|
137
|
-
<AlignRight className="h-4 w-4" />
|
|
137
|
+
<AlignRight className="dy-h-4 dy-w-4" />
|
|
138
138
|
</Toggle>
|
|
139
139
|
|
|
140
|
-
<div className="w-[1px] h-6 bg-border mx-1" />
|
|
140
|
+
<div className="dy-w-[1px] dy-h-6 dy-bg-border dy-mx-1" />
|
|
141
141
|
|
|
142
142
|
<Toggle
|
|
143
143
|
size="sm"
|
|
144
144
|
pressed={editor.isActive("link")}
|
|
145
145
|
onPressedChange={addLink}
|
|
146
146
|
>
|
|
147
|
-
<LinkIcon className="h-4 w-4" />
|
|
147
|
+
<LinkIcon className="dy-h-4 dy-w-4" />
|
|
148
148
|
</Toggle>
|
|
149
149
|
|
|
150
|
-
<div className="ml-auto">
|
|
150
|
+
<div className="dy-ml-auto">
|
|
151
151
|
<MediaPicker
|
|
152
152
|
collection={collection}
|
|
153
153
|
variant="icon"
|
|
@@ -213,11 +213,11 @@ export function RichTextEditor({ value, onChange, label, disabled, collection =
|
|
|
213
213
|
}, [value, editor])
|
|
214
214
|
|
|
215
215
|
return (
|
|
216
|
-
<div className="space-y-2">
|
|
217
|
-
{label && <label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">{label}</label>}
|
|
218
|
-
<div className="flex flex-col w-full">
|
|
216
|
+
<div className="dy-space-y-2">
|
|
217
|
+
{label && <label className="dy-text-sm dy-font-medium dy-leading-none dy-peer-disabled:dy-cursor-not-allowed dy-peer-disabled:dy-opacity-70">{label}</label>}
|
|
218
|
+
<div className="dy-flex dy-flex-col dy-w-full">
|
|
219
219
|
{!disabled && <MenuBar editor={editor} collection={collection} />}
|
|
220
|
-
<EditorContent editor={editor} className={cn(disabled && "opacity-80")} />
|
|
220
|
+
<EditorContent editor={editor} className={cn(disabled && "dy-opacity-80")} />
|
|
221
221
|
</div>
|
|
222
222
|
</div>
|
|
223
223
|
)
|
|
@@ -20,12 +20,12 @@ export function SelectField({ schema, field, disabled }: SelectFieldProps) {
|
|
|
20
20
|
|
|
21
21
|
return (
|
|
22
22
|
<Select onValueChange={field.onChange} defaultValue={field.value} disabled={disabled}>
|
|
23
|
-
<SelectTrigger className="h-12 rounded-xl border-border/40 bg-white/50 focus:ring-0 focus:ring-offset-0 focus:bg-white shadow-sm transition-all hover:shadow-md">
|
|
23
|
+
<SelectTrigger className="dy-h-12 dy-rounded-xl dy-border-border/40 dy-bg-white/50 focus:dy-ring-0 focus:dy-ring-offset-0 focus:dy-bg-white dy-shadow-sm dy-transition-all hover:dy-shadow-md">
|
|
24
24
|
<SelectValue placeholder={schema.admin?.placeholder || `Select ${label.toLowerCase()}`} />
|
|
25
25
|
</SelectTrigger>
|
|
26
|
-
<SelectContent className="rounded-xl border-border/40 shadow-xl animate-in fade-in zoom-in-95">
|
|
26
|
+
<SelectContent className="dy-rounded-xl dy-border-border/40 dy-shadow-xl dy-animate-in dy-fade-in dy-zoom-in-95">
|
|
27
27
|
{options.map((opt) => (
|
|
28
|
-
<SelectItem key={opt.value} value={opt.value} className="rounded-lg focus:bg-primary/5 focus:text-primary transition-colors">
|
|
28
|
+
<SelectItem key={opt.value} value={opt.value} className="dy-rounded-lg focus:dy-bg-primary/5 focus:dy-text-primary dy-transition-colors">
|
|
29
29
|
{opt.label}
|
|
30
30
|
</SelectItem>
|
|
31
31
|
))}
|
|
@@ -62,8 +62,8 @@ export function FormEngine({
|
|
|
62
62
|
|
|
63
63
|
return (
|
|
64
64
|
<Form {...form}>
|
|
65
|
-
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
|
66
|
-
<div className="grid gap-6">
|
|
65
|
+
<form onSubmit={form.handleSubmit(onSubmit)} className="dy-space-y-8">
|
|
66
|
+
<div className="dy-grid dy-gap-6">
|
|
67
67
|
{fields.filter(f => !f.admin?.hidden).map((field) => (
|
|
68
68
|
<FormFieldRenderer
|
|
69
69
|
key={field.name}
|
|
@@ -74,7 +74,7 @@ export function FormEngine({
|
|
|
74
74
|
/>
|
|
75
75
|
))}
|
|
76
76
|
</div>
|
|
77
|
-
<div className="flex justify-end gap-4">
|
|
77
|
+
<div className="dy-flex dy-justify-end dy-gap-4">
|
|
78
78
|
{!readOnly && (
|
|
79
79
|
<Button type="submit" disabled={isLoading}>
|
|
80
80
|
{isLoading ? "Saving..." : submitLabel}
|
|
@@ -80,14 +80,14 @@ export function FormFieldRenderer({ schema, basePath, control, collection }: For
|
|
|
80
80
|
|
|
81
81
|
if (schema.type === "object") {
|
|
82
82
|
return (
|
|
83
|
-
<div className="left-accent space-y-6">
|
|
84
|
-
<div className="flex items-center gap-2 mb-2">
|
|
85
|
-
<h4 className="font-bold text-sm text-foreground/80 tracking-tight">{schema.label || schema.name.charAt(0).toUpperCase() + schema.name.slice(1)}</h4>
|
|
83
|
+
<div className="dy-left-accent dy-space-y-6">
|
|
84
|
+
<div className="dy-flex dy-items-center dy-gap-2 dy-mb-2">
|
|
85
|
+
<h4 className="dy-font-bold dy-text-sm dy-text-foreground/80 dy-tracking-tight">{schema.label || schema.name.charAt(0).toUpperCase() + schema.name.slice(1)}</h4>
|
|
86
86
|
{schema.admin?.description && (
|
|
87
|
-
<p className="text-[10px] text-muted-foreground/50 italic">{schema.admin.description}</p>
|
|
87
|
+
<p className="dy-text-[10px] dy-text-muted-foreground/50 dy-italic">{schema.admin.description}</p>
|
|
88
88
|
)}
|
|
89
89
|
</div>
|
|
90
|
-
<div className="space-y-6">
|
|
90
|
+
<div className="dy-space-y-6">
|
|
91
91
|
{schema.fields?.map(subField => (
|
|
92
92
|
<FormFieldRenderer key={subField.name} schema={subField} basePath={fullPath} control={control} collection={collection} />
|
|
93
93
|
))}
|
|
@@ -113,24 +113,24 @@ export function FormFieldRenderer({ schema, basePath, control, collection }: For
|
|
|
113
113
|
render={({ field: formField }: { field: any }) => (
|
|
114
114
|
<FormItem className={cn(
|
|
115
115
|
isBoolean
|
|
116
|
-
? "flex flex-row items-center justify-between rounded-xl border border-border/40 p-4 bg-white/50 shadow-sm space-y-0"
|
|
117
|
-
: "space-y-3"
|
|
116
|
+
? "dy-flex dy-flex-row dy-items-center dy-justify-between dy-rounded-xl dy-border dy-border-border/40 dy-p-4 dy-bg-white/50 dy-shadow-sm dy-space-y-0"
|
|
117
|
+
: "dy-space-y-3"
|
|
118
118
|
)}>
|
|
119
|
-
<div className={cn(isBoolean ? "space-y-1" : "flex items-center gap-2 mb-1")}>
|
|
120
|
-
<FormLabel className="text-sm font-semibold text-foreground/80 cursor-pointer">
|
|
119
|
+
<div className={cn(isBoolean ? "dy-space-y-1" : "dy-flex dy-items-center dy-gap-2 dy-mb-1")}>
|
|
120
|
+
<FormLabel className="dy-text-sm dy-font-semibold dy-text-foreground/80 dy-cursor-pointer">
|
|
121
121
|
{schema.label || schema.name.charAt(0).toUpperCase() + schema.name.slice(1)}
|
|
122
|
-
{schema.required && <span className="text-destructive ml-1">*</span>}
|
|
122
|
+
{schema.required && <span className="dy-text-destructive dy-ml-1">*</span>}
|
|
123
123
|
</FormLabel>
|
|
124
124
|
{schema.admin?.description && (
|
|
125
125
|
<p className={cn(
|
|
126
|
-
"text-muted-foreground/60 italic",
|
|
127
|
-
isBoolean ? "text-[11px] leading-tight" : "text-[11px] leading-relaxed"
|
|
126
|
+
"dy-text-muted-foreground/60 dy-italic",
|
|
127
|
+
isBoolean ? "dy-text-[11px] dy-leading-tight" : "dy-text-[11px] dy-leading-relaxed"
|
|
128
128
|
)}>
|
|
129
129
|
{schema.admin.description}
|
|
130
130
|
</p>
|
|
131
131
|
)}
|
|
132
132
|
{!isBoolean && schema.unique && (
|
|
133
|
-
<span className="inline-flex items-center rounded-full bg-primary/10 px-1.5 py-0.5 text-[10px] font-medium text-primary ring-1 ring-inset ring-primary/10">
|
|
133
|
+
<span className="dy-inline-flex dy-items-center dy-rounded-full dy-bg-primary/10 dy-px-1.5 dy-py-0.5 dy-text-[10px] dy-font-medium dy-text-primary dy-ring-1 dy-ring-inset dy-ring-primary/10">
|
|
134
134
|
Unique
|
|
135
135
|
</span>
|
|
136
136
|
)}
|
|
@@ -139,9 +139,9 @@ export function FormFieldRenderer({ schema, basePath, control, collection }: For
|
|
|
139
139
|
<FieldRenderer schema={schema} field={formField} collection={collection} context={{ user, schemas, siblingData: conditionData }} />
|
|
140
140
|
</FormControl>
|
|
141
141
|
{!isBoolean && schema.admin?.description && (
|
|
142
|
-
<p className="text-[11px] text-muted-foreground/70 leading-relaxed italic">{schema.admin.description}</p>
|
|
142
|
+
<p className="dy-text-[11px] dy-text-muted-foreground/70 dy-leading-relaxed dy-italic">{schema.admin.description}</p>
|
|
143
143
|
)}
|
|
144
|
-
<FormMessage className="text-xs font-medium" />
|
|
144
|
+
<FormMessage className="dy-text-xs dy-font-medium" />
|
|
145
145
|
</FormItem>
|
|
146
146
|
)}
|
|
147
147
|
/>
|
|
@@ -179,45 +179,45 @@ function ArrayFieldRenderer({ schema, basePath, control, collection }: { schema:
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
return (
|
|
182
|
-
<div className="space-y-6 transition-all py-6">
|
|
183
|
-
<div className="flex justify-between items-end pb-2">
|
|
184
|
-
<div className="space-y-1">
|
|
185
|
-
<div className="flex items-center gap-2">
|
|
186
|
-
<Layers className="h-4 w-4 text-primary" />
|
|
187
|
-
<h4 className="font-serif font-bold text-base text-foreground tracking-tight">{schema.label || schema.name.charAt(0).toUpperCase() + schema.name.slice(1)}</h4>
|
|
182
|
+
<div className="dy-space-y-6 dy-transition-all dy-py-6">
|
|
183
|
+
<div className="dy-flex dy-justify-between dy-items-end dy-pb-2">
|
|
184
|
+
<div className="dy-space-y-1">
|
|
185
|
+
<div className="dy-flex dy-items-center dy-gap-2">
|
|
186
|
+
<Layers className="dy-h-4 dy-w-4 dy-text-primary" />
|
|
187
|
+
<h4 className="dy-font-serif dy-font-bold dy-text-base dy-text-foreground dy-tracking-tight">{schema.label || schema.name.charAt(0).toUpperCase() + schema.name.slice(1)}</h4>
|
|
188
188
|
</div>
|
|
189
189
|
{schema.admin?.description && (
|
|
190
|
-
<p className="text-[11px] text-muted-foreground/60 italic leading-relaxed">{schema.admin.description}</p>
|
|
190
|
+
<p className="dy-text-[11px] dy-text-muted-foreground/60 dy-italic dy-leading-relaxed">{schema.admin.description}</p>
|
|
191
191
|
)}
|
|
192
192
|
</div>
|
|
193
|
-
<div className="flex items-center gap-2">
|
|
193
|
+
<div className="dy-flex dy-items-center dy-gap-2">
|
|
194
194
|
<Button
|
|
195
195
|
type="button"
|
|
196
196
|
variant="outline"
|
|
197
197
|
size="sm"
|
|
198
|
-
className="h-9 text-[11px] font-bold rounded-xl border-primary/20 hover:bg-primary/5 hover:text-primary transition-all shadow-sm"
|
|
198
|
+
className="dy-h-9 dy-text-[11px] dy-font-bold dy-rounded-xl dy-border-primary/20 hover:dy-bg-primary/5 hover:dy-text-primary dy-transition-all dy-shadow-sm"
|
|
199
199
|
onClick={() => append(buildDefaultValues(schema.fields || [], {}))}
|
|
200
200
|
>
|
|
201
|
-
<Plus className="w-3.5 h-3.5 mr-1.5" />
|
|
201
|
+
<Plus className="dy-w-3.5 dy-h-3.5 dy-mr-1.5" />
|
|
202
202
|
Add Item
|
|
203
203
|
</Button>
|
|
204
204
|
</div>
|
|
205
205
|
</div>
|
|
206
206
|
|
|
207
|
-
<div className="space-y-8 pl-0 border-l border-muted/30">
|
|
207
|
+
<div className="dy-space-y-8 dy-pl-0 dy-border-l dy-border-muted/30">
|
|
208
208
|
{fields.map((item, index) => (
|
|
209
|
-
<div key={item.id} className="relative group animate-in slide-in-from-left-2 duration-300">
|
|
210
|
-
<div className="bg-muted/5 left-accent transition-all relative">
|
|
209
|
+
<div key={item.id} className="dy-relative dy-group dy-animate-in dy-slide-in-from-left-2 dy-duration-300">
|
|
210
|
+
<div className="dy-bg-muted/5 dy-left-accent dy-transition-all dy-relative">
|
|
211
211
|
<Button
|
|
212
212
|
type="button"
|
|
213
213
|
variant="ghost"
|
|
214
214
|
size="icon"
|
|
215
|
-
className="absolute top-4 right-4 h-8 w-8 text-muted-foreground/20 hover:text-destructive hover:bg-destructive/10 rounded-xl opacity-0 group-hover:opacity-100 transition-all"
|
|
215
|
+
className="dy-absolute dy-top-4 dy-right-4 dy-h-8 dy-w-8 dy-text-muted-foreground/20 hover:dy-text-destructive hover:dy-bg-destructive/10 dy-rounded-xl dy-opacity-0 dy-group-hover:dy-opacity-100 dy-transition-all"
|
|
216
216
|
onClick={() => remove(index)}
|
|
217
217
|
>
|
|
218
|
-
<Trash2 className="w-4 h-4" />
|
|
218
|
+
<Trash2 className="dy-w-4 dy-h-4" />
|
|
219
219
|
</Button>
|
|
220
|
-
<div className="space-y-6">
|
|
220
|
+
<div className="dy-space-y-6">
|
|
221
221
|
{schema.fields?.map(subField => (
|
|
222
222
|
<FormFieldRenderer
|
|
223
223
|
key={subField.name}
|
|
@@ -233,11 +233,11 @@ function ArrayFieldRenderer({ schema, basePath, control, collection }: { schema:
|
|
|
233
233
|
))}
|
|
234
234
|
|
|
235
235
|
{fields.length === 0 && (
|
|
236
|
-
<div className="flex flex-col items-center justify-center py-12 border-2 border-dashed border-muted rounded-3xl bg-muted/5 space-y-3">
|
|
237
|
-
<div className="p-3 bg-muted rounded-full">
|
|
238
|
-
<Layers className="h-6 w-6 text-muted-foreground/40" />
|
|
236
|
+
<div className="dy-flex dy-flex-col dy-items-center dy-justify-center dy-py-12 dy-border-2 dy-border-dashed dy-border-muted dy-rounded-3xl dy-bg-muted/5 dy-space-y-3">
|
|
237
|
+
<div className="dy-p-3 dy-bg-muted dy-rounded-full">
|
|
238
|
+
<Layers className="dy-h-6 dy-w-6 dy-text-muted-foreground/40" />
|
|
239
239
|
</div>
|
|
240
|
-
<p className="text-xs font-medium text-muted-foreground/50">No items added yet</p>
|
|
240
|
+
<p className="dy-text-xs dy-font-medium dy-text-muted-foreground/50">No items added yet</p>
|
|
241
241
|
</div>
|
|
242
242
|
)}
|
|
243
243
|
|
|
@@ -245,10 +245,10 @@ function ArrayFieldRenderer({ schema, basePath, control, collection }: { schema:
|
|
|
245
245
|
type="button"
|
|
246
246
|
variant="outline"
|
|
247
247
|
size="sm"
|
|
248
|
-
className="w-full h-10 text-xs font-bold rounded-2xl border-dashed border-primary/20 hover:bg-primary/5 hover:text-primary transition-all shadow-sm"
|
|
248
|
+
className="dy-w-full dy-h-10 dy-text-xs dy-font-bold dy-rounded-2xl dy-border-dashed dy-border-primary/20 hover:dy-bg-primary/5 hover:dy-text-primary dy-transition-all dy-shadow-sm"
|
|
249
249
|
onClick={() => append(buildDefaultValues(schema.fields || [], {}))}
|
|
250
250
|
>
|
|
251
|
-
<Plus className="w-4 h-4 mr-2" />
|
|
251
|
+
<Plus className="dy-w-4 dy-h-4 dy-mr-2" />
|
|
252
252
|
Add Item
|
|
253
253
|
</Button>
|
|
254
254
|
</div>
|