@alpaca-editor/core 1.0.3812 → 1.0.3815
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ui/context-menu.d.ts +25 -0
- package/dist/components/ui/context-menu.js +51 -0
- package/dist/components/ui/context-menu.js.map +1 -0
- package/dist/config/config.js +3 -2
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +4 -2
- package/dist/editor/ComponentInfo.js +1 -1
- package/dist/editor/ComponentInfo.js.map +1 -1
- package/dist/editor/ConfirmationDialog.d.ts +1 -1
- package/dist/editor/ContextMenu.d.ts +1 -1
- package/dist/editor/ContextMenu.js +24 -9
- package/dist/editor/ContextMenu.js.map +1 -1
- package/dist/editor/ImageEditor.js +2 -2
- package/dist/editor/ImageEditor.js.map +1 -1
- package/dist/editor/ItemInfo.js +2 -2
- package/dist/editor/ItemInfo.js.map +1 -1
- package/dist/editor/MainLayout.js +3 -3
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/Titlebar.js +1 -1
- package/dist/editor/Titlebar.js.map +1 -1
- package/dist/editor/ai/AiTerminal.js +19 -12
- package/dist/editor/ai/AiTerminal.js.map +1 -1
- package/dist/editor/client/EditorClient.js +19 -4
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +1 -1
- package/dist/editor/client/operations.js +15 -14
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/client/pageModelBuilder.js +8 -5
- package/dist/editor/client/pageModelBuilder.js.map +1 -1
- package/dist/editor/commands/componentCommands.js +15 -13
- package/dist/editor/commands/componentCommands.js.map +1 -1
- package/dist/editor/componentTreeHelper.js +3 -3
- package/dist/editor/componentTreeHelper.js.map +1 -1
- package/dist/editor/control-center/ControlCenterMenu.js +3 -3
- package/dist/editor/control-center/ControlCenterMenu.js.map +1 -1
- package/dist/editor/field-types/TreeListEditor.js +4 -4
- package/dist/editor/field-types/TreeListEditor.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +52 -14
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +5 -5
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +114 -45
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.d.ts +0 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +119 -215
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/page-viewer/pageModelBuilder.d.ts +3 -0
- package/dist/editor/page-viewer/pageModelBuilder.js +299 -0
- package/dist/editor/page-viewer/pageModelBuilder.js.map +1 -0
- package/dist/editor/pageModel.d.ts +5 -0
- package/dist/editor/sidebar/ComponentPalette.js +30 -30
- package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
- package/dist/editor/sidebar/ComponentTree.js +7 -6
- package/dist/editor/sidebar/ComponentTree.js.map +1 -1
- package/dist/editor/sidebar/MainContentTree.js +1 -1
- package/dist/editor/sidebar/MainContentTree.js.map +1 -1
- package/dist/editor/sidebar/SidebarView.js +3 -3
- package/dist/editor/sidebar/SidebarView.js.map +1 -1
- package/dist/editor/ui/CopyToClipboardButton.js +2 -1
- package/dist/editor/ui/CopyToClipboardButton.js.map +1 -1
- package/dist/editor/ui/Icons.d.ts +0 -1
- package/dist/editor/ui/Icons.js +0 -3
- package/dist/editor/ui/Icons.js.map +1 -1
- package/dist/editor/ui/Section.js +1 -1
- package/dist/editor/ui/Section.js.map +1 -1
- package/dist/editor/ui/SimpleMenu.d.ts +1 -8
- package/dist/editor/ui/SimpleMenu.js +1 -1
- package/dist/editor/ui/SimpleMenu.js.map +1 -1
- package/dist/editor/utils.d.ts +2 -2
- package/dist/editor/utils.js +57 -9
- package/dist/editor/utils.js.map +1 -1
- package/dist/lib/safelist.js +1 -1
- package/dist/lib/safelist.js.map +1 -1
- package/dist/splash-screen/SplashScreen.js +0 -1
- package/dist/splash-screen/SplashScreen.js.map +1 -1
- package/dist/styles.css +242 -59
- package/dist/types.d.ts +2 -2
- package/package.json +3 -2
- package/src/components/ui/context-menu.tsx +250 -0
- package/src/config/config.tsx +2 -2
- package/src/config/types.ts +4 -2
- package/src/editor/ComponentInfo.tsx +3 -5
- package/src/editor/ConfirmationDialog.tsx +1 -1
- package/src/editor/ContextMenu.tsx +68 -19
- package/src/editor/ImageEditor.tsx +2 -2
- package/src/editor/ItemInfo.tsx +4 -4
- package/src/editor/MainLayout.tsx +3 -4
- package/src/editor/Titlebar.tsx +1 -1
- package/src/editor/ai/AiTerminal.tsx +31 -24
- package/src/editor/client/EditorClient.tsx +23 -6
- package/src/editor/client/editContext.ts +1 -1
- package/src/editor/client/operations.ts +16 -14
- package/src/editor/client/pageModelBuilder.ts +26 -18
- package/src/editor/commands/componentCommands.tsx +58 -39
- package/src/editor/componentTreeHelper.tsx +3 -2
- package/src/editor/control-center/ControlCenterMenu.tsx +4 -4
- package/src/editor/field-types/TreeListEditor.tsx +11 -11
- package/src/editor/page-editor-chrome/FrameMenu.tsx +81 -17
- package/src/editor/page-editor-chrome/InlineEditor.tsx +5 -5
- package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +12 -15
- package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +159 -68
- package/src/editor/page-viewer/PageViewerFrame.tsx +131 -300
- package/src/editor/page-viewer/pageModelBuilder.ts +412 -0
- package/src/editor/pageModel.ts +5 -0
- package/src/editor/sidebar/ComponentPalette.tsx +108 -106
- package/src/editor/sidebar/ComponentTree.tsx +10 -5
- package/src/editor/sidebar/MainContentTree.tsx +1 -1
- package/src/editor/sidebar/SidebarView.tsx +9 -9
- package/src/editor/ui/CopyToClipboardButton.tsx +2 -1
- package/src/editor/ui/Icons.tsx +0 -18
- package/src/editor/ui/Section.tsx +4 -4
- package/src/editor/ui/SimpleMenu.tsx +5 -13
- package/src/editor/utils.ts +74 -17
- package/src/lib/safelist.tsx +2 -0
- package/src/splash-screen/SplashScreen.tsx +0 -1
- package/src/types.ts +2 -4
- package/styles.css +58 -17
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
|
|
3
|
+
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../../lib/utils";
|
|
6
|
+
|
|
7
|
+
function ContextMenu({
|
|
8
|
+
...props
|
|
9
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {
|
|
10
|
+
return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function ContextMenuTrigger({
|
|
14
|
+
...props
|
|
15
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {
|
|
16
|
+
return (
|
|
17
|
+
<ContextMenuPrimitive.Trigger data-slot="context-menu-trigger" {...props} />
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function ContextMenuGroup({
|
|
22
|
+
...props
|
|
23
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {
|
|
24
|
+
return (
|
|
25
|
+
<ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function ContextMenuPortal({
|
|
30
|
+
...props
|
|
31
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Portal>) {
|
|
32
|
+
return (
|
|
33
|
+
<ContextMenuPrimitive.Portal data-slot="context-menu-portal" {...props} />
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function ContextMenuSub({
|
|
38
|
+
...props
|
|
39
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {
|
|
40
|
+
return <ContextMenuPrimitive.Sub data-slot="context-menu-sub" {...props} />;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function ContextMenuRadioGroup({
|
|
44
|
+
...props
|
|
45
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>) {
|
|
46
|
+
return (
|
|
47
|
+
<ContextMenuPrimitive.RadioGroup
|
|
48
|
+
data-slot="context-menu-radio-group"
|
|
49
|
+
{...props}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function ContextMenuSubTrigger({
|
|
55
|
+
className,
|
|
56
|
+
inset,
|
|
57
|
+
children,
|
|
58
|
+
...props
|
|
59
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & {
|
|
60
|
+
inset?: boolean;
|
|
61
|
+
}) {
|
|
62
|
+
return (
|
|
63
|
+
<ContextMenuPrimitive.SubTrigger
|
|
64
|
+
data-slot="context-menu-sub-trigger"
|
|
65
|
+
data-inset={inset}
|
|
66
|
+
className={cn(
|
|
67
|
+
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
68
|
+
className,
|
|
69
|
+
)}
|
|
70
|
+
{...props}
|
|
71
|
+
>
|
|
72
|
+
{children}
|
|
73
|
+
<ChevronRightIcon className="ml-auto" />
|
|
74
|
+
</ContextMenuPrimitive.SubTrigger>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function ContextMenuSubContent({
|
|
79
|
+
className,
|
|
80
|
+
...props
|
|
81
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {
|
|
82
|
+
return (
|
|
83
|
+
<ContextMenuPrimitive.SubContent
|
|
84
|
+
data-slot="context-menu-sub-content"
|
|
85
|
+
className={cn(
|
|
86
|
+
"bg-popover text-popover-foreground 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 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
|
|
87
|
+
className,
|
|
88
|
+
)}
|
|
89
|
+
{...props}
|
|
90
|
+
/>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function ContextMenuContent({
|
|
95
|
+
className,
|
|
96
|
+
...props
|
|
97
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Content>) {
|
|
98
|
+
return (
|
|
99
|
+
<ContextMenuPrimitive.Portal>
|
|
100
|
+
<ContextMenuPrimitive.Content
|
|
101
|
+
data-slot="context-menu-content"
|
|
102
|
+
className={cn(
|
|
103
|
+
"bg-popover text-popover-foreground 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 z-50 max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
|
|
104
|
+
className,
|
|
105
|
+
)}
|
|
106
|
+
{...props}
|
|
107
|
+
/>
|
|
108
|
+
</ContextMenuPrimitive.Portal>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function ContextMenuItem({
|
|
113
|
+
className,
|
|
114
|
+
inset,
|
|
115
|
+
variant = "default",
|
|
116
|
+
...props
|
|
117
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {
|
|
118
|
+
inset?: boolean;
|
|
119
|
+
variant?: "default" | "destructive";
|
|
120
|
+
}) {
|
|
121
|
+
return (
|
|
122
|
+
<ContextMenuPrimitive.Item
|
|
123
|
+
data-slot="context-menu-item"
|
|
124
|
+
data-inset={inset}
|
|
125
|
+
data-variant={variant}
|
|
126
|
+
className={cn(
|
|
127
|
+
"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 [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
128
|
+
className,
|
|
129
|
+
)}
|
|
130
|
+
{...props}
|
|
131
|
+
/>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function ContextMenuCheckboxItem({
|
|
136
|
+
className,
|
|
137
|
+
children,
|
|
138
|
+
checked,
|
|
139
|
+
...props
|
|
140
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>) {
|
|
141
|
+
return (
|
|
142
|
+
<ContextMenuPrimitive.CheckboxItem
|
|
143
|
+
data-slot="context-menu-checkbox-item"
|
|
144
|
+
className={cn(
|
|
145
|
+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
146
|
+
className,
|
|
147
|
+
)}
|
|
148
|
+
checked={checked}
|
|
149
|
+
{...props}
|
|
150
|
+
>
|
|
151
|
+
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
|
152
|
+
<ContextMenuPrimitive.ItemIndicator>
|
|
153
|
+
<CheckIcon className="size-4" />
|
|
154
|
+
</ContextMenuPrimitive.ItemIndicator>
|
|
155
|
+
</span>
|
|
156
|
+
{children}
|
|
157
|
+
</ContextMenuPrimitive.CheckboxItem>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function ContextMenuRadioItem({
|
|
162
|
+
className,
|
|
163
|
+
children,
|
|
164
|
+
...props
|
|
165
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>) {
|
|
166
|
+
return (
|
|
167
|
+
<ContextMenuPrimitive.RadioItem
|
|
168
|
+
data-slot="context-menu-radio-item"
|
|
169
|
+
className={cn(
|
|
170
|
+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
171
|
+
className,
|
|
172
|
+
)}
|
|
173
|
+
{...props}
|
|
174
|
+
>
|
|
175
|
+
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
|
176
|
+
<ContextMenuPrimitive.ItemIndicator>
|
|
177
|
+
<CircleIcon className="size-2 fill-current" />
|
|
178
|
+
</ContextMenuPrimitive.ItemIndicator>
|
|
179
|
+
</span>
|
|
180
|
+
{children}
|
|
181
|
+
</ContextMenuPrimitive.RadioItem>
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function ContextMenuLabel({
|
|
186
|
+
className,
|
|
187
|
+
inset,
|
|
188
|
+
...props
|
|
189
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Label> & {
|
|
190
|
+
inset?: boolean;
|
|
191
|
+
}) {
|
|
192
|
+
return (
|
|
193
|
+
<ContextMenuPrimitive.Label
|
|
194
|
+
data-slot="context-menu-label"
|
|
195
|
+
data-inset={inset}
|
|
196
|
+
className={cn(
|
|
197
|
+
"text-foreground px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
|
|
198
|
+
className,
|
|
199
|
+
)}
|
|
200
|
+
{...props}
|
|
201
|
+
/>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function ContextMenuSeparator({
|
|
206
|
+
className,
|
|
207
|
+
...props
|
|
208
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {
|
|
209
|
+
return (
|
|
210
|
+
<ContextMenuPrimitive.Separator
|
|
211
|
+
data-slot="context-menu-separator"
|
|
212
|
+
className={cn("bg-border -mx-1 my-1 h-px", className)}
|
|
213
|
+
{...props}
|
|
214
|
+
/>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function ContextMenuShortcut({
|
|
219
|
+
className,
|
|
220
|
+
...props
|
|
221
|
+
}: React.ComponentProps<"span">) {
|
|
222
|
+
return (
|
|
223
|
+
<span
|
|
224
|
+
data-slot="context-menu-shortcut"
|
|
225
|
+
className={cn(
|
|
226
|
+
"text-muted-foreground ml-auto text-xs tracking-widest",
|
|
227
|
+
className,
|
|
228
|
+
)}
|
|
229
|
+
{...props}
|
|
230
|
+
/>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export {
|
|
235
|
+
ContextMenu,
|
|
236
|
+
ContextMenuTrigger,
|
|
237
|
+
ContextMenuContent,
|
|
238
|
+
ContextMenuItem,
|
|
239
|
+
ContextMenuCheckboxItem,
|
|
240
|
+
ContextMenuRadioItem,
|
|
241
|
+
ContextMenuLabel,
|
|
242
|
+
ContextMenuSeparator,
|
|
243
|
+
ContextMenuShortcut,
|
|
244
|
+
ContextMenuGroup,
|
|
245
|
+
ContextMenuPortal,
|
|
246
|
+
ContextMenuSub,
|
|
247
|
+
ContextMenuSubContent,
|
|
248
|
+
ContextMenuSubTrigger,
|
|
249
|
+
ContextMenuRadioGroup,
|
|
250
|
+
};
|
package/src/config/config.tsx
CHANGED
|
@@ -31,7 +31,6 @@ import {
|
|
|
31
31
|
EditIcon,
|
|
32
32
|
GraphQLIcon,
|
|
33
33
|
JsonIcon,
|
|
34
|
-
NavigatorIcon,
|
|
35
34
|
PageWizardIcon,
|
|
36
35
|
WizardIcon,
|
|
37
36
|
} from "../editor/ui/Icons";
|
|
@@ -91,6 +90,7 @@ import { getWizards } from "../page-wizard/service";
|
|
|
91
90
|
import { startPageWizardCommand } from "../page-wizard/startPageWizardCommand";
|
|
92
91
|
import { ImageFieldEditor } from "../editor/field-types/ImageFieldEditor";
|
|
93
92
|
import { FieldAction } from "./types";
|
|
93
|
+
import { Layers } from "lucide-react";
|
|
94
94
|
|
|
95
95
|
const defaultRichTextEditorProfile: RichTextEditorProfile = {
|
|
96
96
|
toolbar: {
|
|
@@ -129,7 +129,7 @@ const pageEditorRightSidebar = {
|
|
|
129
129
|
panels: [
|
|
130
130
|
{
|
|
131
131
|
name: "component-tree",
|
|
132
|
-
icon: <
|
|
132
|
+
icon: <Layers size={14} />,
|
|
133
133
|
title: "Component Navigator",
|
|
134
134
|
content: <ComponentTree />,
|
|
135
135
|
initialSize: 20,
|
package/src/config/types.ts
CHANGED
|
@@ -85,10 +85,12 @@ export type ViewPanel = {
|
|
|
85
85
|
|
|
86
86
|
export type MenuItem = {
|
|
87
87
|
id: string;
|
|
88
|
-
label
|
|
89
|
-
icon
|
|
88
|
+
label?: string;
|
|
89
|
+
icon?: ReactNode;
|
|
90
90
|
items?: MenuItem[];
|
|
91
91
|
command?: (event: any) => Promise<void>;
|
|
92
|
+
disabled?: boolean;
|
|
93
|
+
separator?: boolean;
|
|
92
94
|
};
|
|
93
95
|
|
|
94
96
|
export type EditorConfiguration = {
|
|
@@ -47,13 +47,11 @@ export function ComponentInfo({ component }: { component: Component | null }) {
|
|
|
47
47
|
|
|
48
48
|
return (
|
|
49
49
|
<div>
|
|
50
|
-
<h2 className="
|
|
51
|
-
{component.name}
|
|
52
|
-
</h2>
|
|
50
|
+
<h2 className="text-l my-2 px-3 py-3 font-bold">{component.name}</h2>
|
|
53
51
|
<Section title="Info">
|
|
54
|
-
<div className="grid grid-cols-[min-content_1fr] gap-3
|
|
52
|
+
<div className="grid grid-cols-[min-content_1fr] gap-3 bg-gray-100 text-xs">
|
|
55
53
|
<div className="font-bold">ID:</div>
|
|
56
|
-
<div>
|
|
54
|
+
<div className="flex items-center gap-1">
|
|
57
55
|
{component.id} <CopyToClipboardButton text={component.id} />
|
|
58
56
|
</div>
|
|
59
57
|
<div className="font-bold">Template</div>
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import { MenuItem, MenuItemCommandEvent } from "primereact/menuitem";
|
|
2
|
-
|
|
3
1
|
import { EditContextType } from "./client/editContext";
|
|
4
2
|
import { forwardRef, useImperativeHandle, useRef, useState } from "react";
|
|
5
|
-
import { ContextMenu } from "primereact/contextmenu";
|
|
6
3
|
|
|
7
4
|
import { FieldDescriptor } from "../types";
|
|
8
5
|
import { Component, FieldButton } from "./pageModel";
|
|
6
|
+
import {
|
|
7
|
+
ContextMenu,
|
|
8
|
+
ContextMenuContent,
|
|
9
|
+
ContextMenuItem,
|
|
10
|
+
ContextMenuSeparator,
|
|
11
|
+
ContextMenuTrigger,
|
|
12
|
+
} from "../components/ui/context-menu";
|
|
13
|
+
import { MenuItem } from "../config/types";
|
|
9
14
|
|
|
10
15
|
// export function getFieldContextMenu(
|
|
11
16
|
// field: Field,
|
|
@@ -64,11 +69,11 @@ export function showComponentContextMenu(
|
|
|
64
69
|
components: Component[],
|
|
65
70
|
editContext: EditContextType,
|
|
66
71
|
field?: FieldDescriptor,
|
|
67
|
-
fieldButtons?: FieldButton[]
|
|
72
|
+
fieldButtons?: FieldButton[],
|
|
68
73
|
) {
|
|
69
74
|
const componentCommandMenuItems = getComponentMenuItems(
|
|
70
75
|
editContext,
|
|
71
|
-
components
|
|
76
|
+
components,
|
|
72
77
|
);
|
|
73
78
|
|
|
74
79
|
const menuItems = componentCommandMenuItems;
|
|
@@ -76,28 +81,29 @@ export function showComponentContextMenu(
|
|
|
76
81
|
if (!editContext.readonly && field && fieldButtons?.length) {
|
|
77
82
|
if (menuItems.length)
|
|
78
83
|
menuItems.push({
|
|
84
|
+
id: "separator",
|
|
79
85
|
separator: true,
|
|
80
86
|
});
|
|
81
87
|
|
|
82
88
|
fieldButtons.forEach((button) => {
|
|
83
89
|
menuItems.push({
|
|
90
|
+
id: button.id,
|
|
84
91
|
label: button.label,
|
|
85
|
-
command: () => {
|
|
92
|
+
command: async () => {
|
|
86
93
|
editContext!.triggerFieldAction(field, button);
|
|
87
94
|
},
|
|
88
|
-
icon: button.icon ?
|
|
95
|
+
icon: button.icon ? <img src={button.icon} width={16} /> : undefined,
|
|
89
96
|
});
|
|
90
97
|
});
|
|
91
98
|
}
|
|
92
99
|
|
|
93
100
|
return (e: any) => {
|
|
94
|
-
if (!e.shiftKey && !e.altKey) {
|
|
95
|
-
if(menuItems.length) {
|
|
96
|
-
|
|
97
|
-
// editContext.select([component.id]);
|
|
101
|
+
if (!e.shiftKey && !e.altKey) {
|
|
102
|
+
if (menuItems.length) {
|
|
103
|
+
// editContext.select([component.id]);
|
|
98
104
|
editContext!.showContextMenu(e, menuItems);
|
|
99
105
|
}
|
|
100
|
-
|
|
106
|
+
|
|
101
107
|
return true;
|
|
102
108
|
}
|
|
103
109
|
return false;
|
|
@@ -115,7 +121,8 @@ export const EditContextMenu = forwardRef<
|
|
|
115
121
|
EditContextMenuRef,
|
|
116
122
|
EditContextMenuProps
|
|
117
123
|
>((props, ref) => {
|
|
118
|
-
const
|
|
124
|
+
const canvasRef = useRef<HTMLSpanElement>(null);
|
|
125
|
+
|
|
119
126
|
const [menuItems, setMenuItems] = useState<MenuItem[]>([]);
|
|
120
127
|
if (!props) return;
|
|
121
128
|
useImperativeHandle(ref, () => ({
|
|
@@ -123,30 +130,72 @@ export const EditContextMenu = forwardRef<
|
|
|
123
130
|
if (!e.ctrlKey && !e.shiftKey && !e.altKey) {
|
|
124
131
|
setMenuItems(items);
|
|
125
132
|
e.preventDefault();
|
|
126
|
-
|
|
133
|
+
triggerRightClick(canvasRef.current!, {
|
|
134
|
+
position: { x: e.clientX, y: e.clientY },
|
|
135
|
+
});
|
|
127
136
|
}
|
|
128
137
|
},
|
|
129
138
|
close: (event: any) => {
|
|
130
|
-
cm.current?.hide(event);
|
|
139
|
+
// cm.current?.hide(event);
|
|
131
140
|
},
|
|
132
141
|
}));
|
|
133
142
|
|
|
134
|
-
|
|
143
|
+
const triggerRightClick = (
|
|
144
|
+
element: HTMLSpanElement,
|
|
145
|
+
{ position }: { position: any },
|
|
146
|
+
) => {
|
|
147
|
+
const event = new MouseEvent("contextmenu", {
|
|
148
|
+
bubbles: true,
|
|
149
|
+
cancelable: true,
|
|
150
|
+
clientX: position.x,
|
|
151
|
+
clientY: position.y,
|
|
152
|
+
});
|
|
153
|
+
element.dispatchEvent(event);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<ContextMenu>
|
|
158
|
+
<ContextMenuTrigger>
|
|
159
|
+
<span id="contextmenu_canvas" ref={canvasRef}>
|
|
160
|
+
CM trigger
|
|
161
|
+
</span>
|
|
162
|
+
</ContextMenuTrigger>
|
|
163
|
+
<ContextMenuContent>
|
|
164
|
+
{menuItems.map((item, index) =>
|
|
165
|
+
item.separator ? (
|
|
166
|
+
<ContextMenuSeparator />
|
|
167
|
+
) : (
|
|
168
|
+
<ContextMenuItem
|
|
169
|
+
key={index}
|
|
170
|
+
onClick={item.command}
|
|
171
|
+
disabled={item.disabled}
|
|
172
|
+
className="cursor-pointer"
|
|
173
|
+
>
|
|
174
|
+
{item.icon}
|
|
175
|
+
{item.label}
|
|
176
|
+
</ContextMenuItem>
|
|
177
|
+
),
|
|
178
|
+
)}
|
|
179
|
+
</ContextMenuContent>
|
|
180
|
+
</ContextMenu>
|
|
181
|
+
);
|
|
182
|
+
// return <ContextMenu model={menuItems} ref={cm} />;
|
|
135
183
|
});
|
|
136
184
|
function getComponentMenuItems(
|
|
137
185
|
editContext: EditContextType,
|
|
138
|
-
components: Component[]
|
|
186
|
+
components: Component[],
|
|
139
187
|
): MenuItem[] {
|
|
140
188
|
const componentCommands = editContext.getComponentCommands(components);
|
|
141
189
|
|
|
142
190
|
const componentCommandMenuItems = componentCommands.map((x) => {
|
|
143
191
|
return {
|
|
192
|
+
id: x.id,
|
|
144
193
|
label: x.label,
|
|
145
194
|
icon: x.icon,
|
|
146
|
-
command: (ev:
|
|
195
|
+
command: (ev: React.SyntheticEvent) =>
|
|
147
196
|
editContext.executeCommand({
|
|
148
197
|
command: x,
|
|
149
|
-
event: ev
|
|
198
|
+
event: ev,
|
|
150
199
|
}),
|
|
151
200
|
disabled: editContext.isCommandDisabled({ command: x }),
|
|
152
201
|
};
|
|
@@ -11,7 +11,7 @@ export function ImageEditor({
|
|
|
11
11
|
field: ImageField;
|
|
12
12
|
style?: React.CSSProperties;
|
|
13
13
|
}) {
|
|
14
|
-
const [showMenu, setShowMenu] = useState(
|
|
14
|
+
const [showMenu, setShowMenu] = useState(true);
|
|
15
15
|
const editContext = useEditContext();
|
|
16
16
|
const dialogContext = useDialog();
|
|
17
17
|
|
|
@@ -72,7 +72,7 @@ export function ImageEditor({
|
|
|
72
72
|
/>
|
|
73
73
|
)}
|
|
74
74
|
{showMenu && (
|
|
75
|
-
<div className="absolute inset-0 grid grid-cols-1 items-
|
|
75
|
+
<div className="absolute inset-0 grid grid-cols-1 items-center justify-center gap-1.5 bg-black/50 p-3 text-sm">
|
|
76
76
|
<Btn
|
|
77
77
|
label={getImageSrc() ? "Change Image" : "Select Image"}
|
|
78
78
|
icon="pi pi-image"
|
package/src/editor/ItemInfo.tsx
CHANGED
|
@@ -20,7 +20,7 @@ export function ItemInfo({ item }: { item: FullItem | null }) {
|
|
|
20
20
|
|
|
21
21
|
return (
|
|
22
22
|
<div>
|
|
23
|
-
<div className="flex items-center
|
|
23
|
+
<div className="my-2 flex items-center px-3 py-2">
|
|
24
24
|
<img
|
|
25
25
|
src={item.largeIcon}
|
|
26
26
|
alt="Icon"
|
|
@@ -45,11 +45,11 @@ export function ItemInfo({ item }: { item: FullItem | null }) {
|
|
|
45
45
|
<Section title="Info">
|
|
46
46
|
<div className="grid grid-cols-[min-content_1fr] gap-3 text-xs">
|
|
47
47
|
<div className="font-bold">ID:</div>
|
|
48
|
-
<div>
|
|
48
|
+
<div className="flex items-center gap-1">
|
|
49
49
|
{item.id} <CopyToClipboardButton text={item.id} />
|
|
50
50
|
</div>
|
|
51
51
|
<div className="font-bold">Path:</div>
|
|
52
|
-
<div>
|
|
52
|
+
<div className="flex items-center gap-1">
|
|
53
53
|
{item.path} <CopyToClipboardButton text={item.path} />
|
|
54
54
|
</div>
|
|
55
55
|
<div className="font-bold">Language:</div>
|
|
@@ -57,7 +57,7 @@ export function ItemInfo({ item }: { item: FullItem | null }) {
|
|
|
57
57
|
<div className="font-bold">Version:</div>
|
|
58
58
|
<div>{item.versions > 0 ? item.version : "No versions"}</div>
|
|
59
59
|
<div className="font-bold">Template:</div>
|
|
60
|
-
<div>
|
|
60
|
+
<div className="flex items-center gap-1">
|
|
61
61
|
<span
|
|
62
62
|
className="cursor-pointer hover:underline"
|
|
63
63
|
onClick={() => {
|
|
@@ -4,11 +4,11 @@ import { EditorView } from "../config/types";
|
|
|
4
4
|
|
|
5
5
|
import { classNames } from "primereact/utils";
|
|
6
6
|
import { useEditContext } from "./client/editContext";
|
|
7
|
-
import { NavigatorIcon } from "./ui/Icons";
|
|
8
7
|
|
|
9
8
|
import { SidebarView } from "./sidebar/SidebarView";
|
|
10
9
|
import { Splitter, SplitterPanel } from "./ui/Splitter";
|
|
11
10
|
import { ViewSelector } from "./sidebar/ViewSelector";
|
|
11
|
+
import { Layers } from "lucide-react";
|
|
12
12
|
|
|
13
13
|
export default function MainLayout({
|
|
14
14
|
view,
|
|
@@ -36,7 +36,7 @@ export default function MainLayout({
|
|
|
36
36
|
defaultSize: 350,
|
|
37
37
|
content: (
|
|
38
38
|
<div
|
|
39
|
-
className="
|
|
39
|
+
className="h-full w-full"
|
|
40
40
|
ref={leftSidebarRef}
|
|
41
41
|
style={{ wordBreak: "normal" }}
|
|
42
42
|
>
|
|
@@ -80,8 +80,7 @@ export default function MainLayout({
|
|
|
80
80
|
localStorageKey="editor.panelSizes"
|
|
81
81
|
expandLabel={
|
|
82
82
|
<div className="flex items-center justify-center">
|
|
83
|
-
<
|
|
84
|
-
|
|
83
|
+
<Layers size={14} />
|
|
85
84
|
<div className="mt-3">{rightSidebarTitle} </div>
|
|
86
85
|
</div>
|
|
87
86
|
}
|
package/src/editor/Titlebar.tsx
CHANGED
|
@@ -14,7 +14,7 @@ export function Titlebar() {
|
|
|
14
14
|
>
|
|
15
15
|
<i className="pi pi-sparkles text-pink-400" />
|
|
16
16
|
</a>{" "}
|
|
17
|
-
<span className="ml-2 font-mono">
|
|
17
|
+
<span className="ml-2 font-mono">workbench</span>
|
|
18
18
|
</div>
|
|
19
19
|
<div>{editContext?.view.primaryControls}</div>
|
|
20
20
|
<div>{editContext?.view.secondaryControls}</div>
|