@alpaca-editor/core 1.0.3959 → 1.0.3962
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/FilterInput.d.ts +21 -0
- package/dist/components/FilterInput.js +33 -0
- package/dist/components/FilterInput.js.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.js +2 -0
- package/dist/components/index.js.map +1 -0
- package/dist/config/config.js +4 -2
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +1 -1
- package/dist/editor/ContextMenu.js +1 -1
- package/dist/editor/ContextMenu.js.map +1 -1
- package/dist/editor/FieldList.js +2 -3
- package/dist/editor/FieldList.js.map +1 -1
- package/dist/editor/ImageEditButton.d.ts +26 -0
- package/dist/editor/ImageEditButton.js +15 -0
- package/dist/editor/ImageEditButton.js.map +1 -0
- package/dist/editor/ImageEditor.js +25 -21
- package/dist/editor/ImageEditor.js.map +1 -1
- package/dist/editor/ItemInfo.js +1 -1
- package/dist/editor/ItemInfo.js.map +1 -1
- package/dist/editor/MainLayout.js +1 -1
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/MobileLayout.js +1 -1
- package/dist/editor/MobileLayout.js.map +1 -1
- package/dist/editor/PictureEditor.js +60 -36
- package/dist/editor/PictureEditor.js.map +1 -1
- package/dist/editor/client/EditorClient.js +7 -8
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/context-menu/InsertMenu.js +3 -5
- package/dist/editor/context-menu/InsertMenu.js.map +1 -1
- package/dist/editor/field-types/DropListEditor.js +1 -1
- package/dist/editor/field-types/DropListEditor.js.map +1 -1
- package/dist/editor/menubar/VersionSelector.js +8 -8
- package/dist/editor/menubar/VersionSelector.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +1 -1
- package/dist/editor/page-viewer/PageViewer.js +7 -2
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/sidebar/ComponentPalette.js +3 -5
- package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
- package/dist/editor/sidebar/Insert.js +1 -1
- package/dist/editor/sidebar/Insert.js.map +1 -1
- package/dist/editor/sidebar/SidebarView.js +1 -1
- package/dist/editor/sidebar/SidebarView.js.map +1 -1
- package/dist/editor/ui/Icons.d.ts +3 -0
- package/dist/editor/ui/Icons.js +4 -1
- package/dist/editor/ui/Icons.js.map +1 -1
- package/dist/editor/ui/ItemSearch.js +3 -4
- package/dist/editor/ui/ItemSearch.js.map +1 -1
- package/dist/editor/ui/SimpleTabs.js +2 -2
- package/dist/editor/ui/SimpleTabs.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/styles.css +25 -18
- package/package.json +1 -1
- package/src/components/FilterInput.tsx +102 -0
- package/src/components/index.ts +2 -0
- package/src/config/config.tsx +4 -2
- package/src/config/types.ts +2 -1
- package/src/editor/ContextMenu.tsx +1 -3
- package/src/editor/FieldList.tsx +6 -15
- package/src/editor/ImageEditButton.tsx +78 -0
- package/src/editor/ImageEditor.tsx +43 -91
- package/src/editor/ItemInfo.tsx +1 -1
- package/src/editor/MainLayout.tsx +2 -2
- package/src/editor/MobileLayout.tsx +1 -1
- package/src/editor/PictureEditor.tsx +60 -134
- package/src/editor/client/EditorClient.tsx +8 -8
- package/src/editor/context-menu/InsertMenu.tsx +5 -14
- package/src/editor/field-types/DropListEditor.tsx +1 -1
- package/src/editor/menubar/VersionSelector.tsx +28 -28
- package/src/editor/page-editor-chrome/FrameMenu.tsx +3 -3
- package/src/editor/page-viewer/PageViewer.tsx +8 -4
- package/src/editor/page-viewer/PageViewerFrame.tsx +1 -1
- package/src/editor/sidebar/ComponentPalette.tsx +9 -32
- package/src/editor/sidebar/Insert.tsx +1 -1
- package/src/editor/sidebar/SidebarView.tsx +2 -2
- package/src/editor/ui/Icons.tsx +23 -0
- package/src/editor/ui/ItemSearch.tsx +10 -23
- package/src/editor/ui/SimpleTabs.tsx +3 -3
- package/src/revision.ts +2 -2
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MouseEventHandler,
|
|
3
|
-
useCallback,
|
|
4
|
-
useEffect,
|
|
5
|
-
useRef,
|
|
6
|
-
useState,
|
|
7
|
-
} from "react";
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
8
2
|
import { useEditContext } from "./client/editContext";
|
|
9
3
|
import { PictureCropper } from "./PictureCropper";
|
|
10
4
|
import { PictureField, PictureRawValue } from "./fieldTypes";
|
|
@@ -15,12 +9,7 @@ import {
|
|
|
15
9
|
FieldActionsOverlay,
|
|
16
10
|
FieldActionsOverlayRef,
|
|
17
11
|
} from "./FieldActionsOverlay";
|
|
18
|
-
import {
|
|
19
|
-
DropdownMenu,
|
|
20
|
-
DropdownMenuContent,
|
|
21
|
-
DropdownMenuItem,
|
|
22
|
-
DropdownMenuTrigger,
|
|
23
|
-
} from "../components/ui/dropdown-menu";
|
|
12
|
+
import { ImageEditButton, MenuAction } from "./ImageEditButton";
|
|
24
13
|
|
|
25
14
|
export function PictureEditor({
|
|
26
15
|
field,
|
|
@@ -35,7 +24,6 @@ export function PictureEditor({
|
|
|
35
24
|
forwardScrollevents?: boolean;
|
|
36
25
|
isPageEditor?: boolean;
|
|
37
26
|
}) {
|
|
38
|
-
const [showMenu, setShowMenu] = useState(false);
|
|
39
27
|
const [showCropper, setShowCropper] = useState(false);
|
|
40
28
|
const [fieldButtons, setFieldButtons] = useState<FieldButton[]>([]);
|
|
41
29
|
const fieldActionsOverlay = useRef<FieldActionsOverlayRef>(null);
|
|
@@ -159,6 +147,63 @@ export function PictureEditor({
|
|
|
159
147
|
|
|
160
148
|
const notEmpty = variant?.mediaId;
|
|
161
149
|
|
|
150
|
+
// Build actions for the dropdown menu
|
|
151
|
+
const menuActions: MenuAction[] = [
|
|
152
|
+
{
|
|
153
|
+
id: "select",
|
|
154
|
+
label: "Select",
|
|
155
|
+
icon: "pi pi-image",
|
|
156
|
+
onClick: () => selectMedia("images"),
|
|
157
|
+
},
|
|
158
|
+
...(field.value?.allowVideos
|
|
159
|
+
? [
|
|
160
|
+
{
|
|
161
|
+
id: "video",
|
|
162
|
+
label: "Video",
|
|
163
|
+
icon: "pi pi-video",
|
|
164
|
+
onClick: () => selectVideo(),
|
|
165
|
+
},
|
|
166
|
+
]
|
|
167
|
+
: []),
|
|
168
|
+
...(notEmpty
|
|
169
|
+
? [
|
|
170
|
+
{
|
|
171
|
+
id: "crop",
|
|
172
|
+
label: "Crop",
|
|
173
|
+
icon: "pi pi-expand",
|
|
174
|
+
onClick: () => setShowCropper(true),
|
|
175
|
+
},
|
|
176
|
+
]
|
|
177
|
+
: []),
|
|
178
|
+
...(rawVariant
|
|
179
|
+
? [
|
|
180
|
+
{
|
|
181
|
+
id: "reset",
|
|
182
|
+
label: "Reset",
|
|
183
|
+
icon: "pi pi-times",
|
|
184
|
+
onClick: () => reset(),
|
|
185
|
+
},
|
|
186
|
+
]
|
|
187
|
+
: []),
|
|
188
|
+
...fieldButtons.map((button) => ({
|
|
189
|
+
id: button.id,
|
|
190
|
+
label: button.label,
|
|
191
|
+
icon: button.isGenerator
|
|
192
|
+
? "pi pi-cog"
|
|
193
|
+
: button.icon && button.icon.trim() !== ""
|
|
194
|
+
? button.icon
|
|
195
|
+
: "pi pi-bolt",
|
|
196
|
+
onClick: (e?: React.MouseEvent) => {
|
|
197
|
+
if (button.parameters && button.parameters.length > 0) {
|
|
198
|
+
fieldActionsOverlay.current?.show(e, button);
|
|
199
|
+
} else {
|
|
200
|
+
handleActionClick(button);
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
parameters: button.parameters,
|
|
204
|
+
})),
|
|
205
|
+
];
|
|
206
|
+
|
|
162
207
|
return (
|
|
163
208
|
<div
|
|
164
209
|
className="absolute inset-0 flex items-center justify-center"
|
|
@@ -187,92 +232,7 @@ export function PictureEditor({
|
|
|
187
232
|
style={style}
|
|
188
233
|
data-testid="select-media"
|
|
189
234
|
>
|
|
190
|
-
{
|
|
191
|
-
<DropdownMenu open={showMenu} onOpenChange={setShowMenu}>
|
|
192
|
-
<DropdownMenuTrigger asChild>
|
|
193
|
-
<button
|
|
194
|
-
className="absolute right-2 bottom-2 flex h-8 w-8 items-center justify-center rounded-full border bg-gray-500 text-white opacity-70 shadow-lg transition-opacity hover:opacity-85"
|
|
195
|
-
onClick={(e) => {
|
|
196
|
-
e.stopPropagation();
|
|
197
|
-
}}
|
|
198
|
-
data-testid="menu-toggle-button"
|
|
199
|
-
>
|
|
200
|
-
<i className="pi pi-ellipsis-v text-xs" />
|
|
201
|
-
</button>
|
|
202
|
-
</DropdownMenuTrigger>
|
|
203
|
-
<DropdownMenuContent align="end" side="top" sideOffset={8}>
|
|
204
|
-
<DropdownMenuItem
|
|
205
|
-
onClick={() => {
|
|
206
|
-
selectMedia("images");
|
|
207
|
-
setShowMenu(false);
|
|
208
|
-
}}
|
|
209
|
-
>
|
|
210
|
-
<i className="pi pi-image" />
|
|
211
|
-
Select
|
|
212
|
-
</DropdownMenuItem>
|
|
213
|
-
|
|
214
|
-
{field.value?.allowVideos && (
|
|
215
|
-
<DropdownMenuItem
|
|
216
|
-
onClick={() => {
|
|
217
|
-
selectVideo();
|
|
218
|
-
setShowMenu(false);
|
|
219
|
-
}}
|
|
220
|
-
>
|
|
221
|
-
<i className="pi pi-video" />
|
|
222
|
-
Video
|
|
223
|
-
</DropdownMenuItem>
|
|
224
|
-
)}
|
|
225
|
-
|
|
226
|
-
{notEmpty && (
|
|
227
|
-
<DropdownMenuItem
|
|
228
|
-
onClick={() => {
|
|
229
|
-
setShowCropper(true);
|
|
230
|
-
setShowMenu(false);
|
|
231
|
-
}}
|
|
232
|
-
>
|
|
233
|
-
<i className="pi pi-expand" />
|
|
234
|
-
Crop
|
|
235
|
-
</DropdownMenuItem>
|
|
236
|
-
)}
|
|
237
|
-
|
|
238
|
-
{rawVariant && (
|
|
239
|
-
<DropdownMenuItem
|
|
240
|
-
onClick={() => {
|
|
241
|
-
reset();
|
|
242
|
-
setShowMenu(false);
|
|
243
|
-
}}
|
|
244
|
-
>
|
|
245
|
-
<i className="pi pi-times" />
|
|
246
|
-
Reset
|
|
247
|
-
</DropdownMenuItem>
|
|
248
|
-
)}
|
|
249
|
-
|
|
250
|
-
{fieldButtons.map((button) => (
|
|
251
|
-
<DropdownMenuItem
|
|
252
|
-
key={button.id}
|
|
253
|
-
onClick={(e) => {
|
|
254
|
-
if (button.parameters && button.parameters.length > 0) {
|
|
255
|
-
fieldActionsOverlay.current?.show(e, button);
|
|
256
|
-
} else {
|
|
257
|
-
handleActionClick(button);
|
|
258
|
-
}
|
|
259
|
-
setShowMenu(false);
|
|
260
|
-
}}
|
|
261
|
-
>
|
|
262
|
-
<i
|
|
263
|
-
className={
|
|
264
|
-
button.isGenerator
|
|
265
|
-
? "pi pi-cog"
|
|
266
|
-
: button.icon && button.icon.trim() !== ""
|
|
267
|
-
? button.icon
|
|
268
|
-
: "pi pi-bolt"
|
|
269
|
-
}
|
|
270
|
-
/>
|
|
271
|
-
{button.label}
|
|
272
|
-
</DropdownMenuItem>
|
|
273
|
-
))}
|
|
274
|
-
</DropdownMenuContent>
|
|
275
|
-
</DropdownMenu>
|
|
235
|
+
<ImageEditButton actions={menuActions} compact={true} />
|
|
276
236
|
|
|
277
237
|
{showCropper && (
|
|
278
238
|
<PictureCropper
|
|
@@ -294,37 +254,3 @@ export function PictureEditor({
|
|
|
294
254
|
</div>
|
|
295
255
|
);
|
|
296
256
|
}
|
|
297
|
-
|
|
298
|
-
function Btn({
|
|
299
|
-
label,
|
|
300
|
-
icon,
|
|
301
|
-
onClick,
|
|
302
|
-
testId,
|
|
303
|
-
className,
|
|
304
|
-
}: {
|
|
305
|
-
label: string;
|
|
306
|
-
icon: string;
|
|
307
|
-
onClick: MouseEventHandler<HTMLButtonElement>;
|
|
308
|
-
testId?: string;
|
|
309
|
-
className?: string;
|
|
310
|
-
}) {
|
|
311
|
-
const isImageUrl =
|
|
312
|
-
icon.startsWith("http://") ||
|
|
313
|
-
icon.startsWith("https://") ||
|
|
314
|
-
icon.startsWith("/");
|
|
315
|
-
|
|
316
|
-
return (
|
|
317
|
-
<button
|
|
318
|
-
className={`btn flex cursor-pointer items-center gap-1.5 rounded-lg border bg-gray-500 p-1.5 text-white opacity-70 hover:opacity-85 ${className} text-2xs`}
|
|
319
|
-
onClick={onClick}
|
|
320
|
-
data-testid={testId}
|
|
321
|
-
>
|
|
322
|
-
{isImageUrl ? (
|
|
323
|
-
<img src={icon} alt="" className="h-3 w-3" />
|
|
324
|
-
) : (
|
|
325
|
-
<i className={icon} />
|
|
326
|
-
)}{" "}
|
|
327
|
-
{label}
|
|
328
|
-
</button>
|
|
329
|
-
);
|
|
330
|
-
}
|
|
@@ -408,8 +408,6 @@ export function EditorClient({
|
|
|
408
408
|
}, [currentView]);
|
|
409
409
|
|
|
410
410
|
const sendClientInfo = async () => {
|
|
411
|
-
const socket = (globalThis as any).editorSocket;
|
|
412
|
-
|
|
413
411
|
const clientInfoMessage = {
|
|
414
412
|
type: "client-info",
|
|
415
413
|
sessionId: sessionId,
|
|
@@ -423,12 +421,14 @@ export function EditorClient({
|
|
|
423
421
|
: null,
|
|
424
422
|
};
|
|
425
423
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
}
|
|
424
|
+
// const socket = (globalThis as any).editorSocket;
|
|
425
|
+
|
|
426
|
+
//if (socket.readyState !== WebSocket.OPEN) {
|
|
427
|
+
const url = "/alpaca/editor/client";
|
|
428
|
+
await post(url, clientInfoMessage);
|
|
429
|
+
//} else {
|
|
430
|
+
// socket.send(JSON.stringify(clientInfoMessage));
|
|
431
|
+
//}
|
|
432
432
|
};
|
|
433
433
|
|
|
434
434
|
const startTour = () => {
|
|
@@ -3,7 +3,7 @@ import { ItemTreeNodeData } from "../services/contentService";
|
|
|
3
3
|
import { useEditContext } from "../../client-components";
|
|
4
4
|
import { useRef, useState, useEffect } from "react";
|
|
5
5
|
import { FullItem } from "../pageModel";
|
|
6
|
-
import {
|
|
6
|
+
import { FilterInput, highlightMatch } from "../../components/FilterInput";
|
|
7
7
|
import { ScrollingContentTree } from "../ScrollingContentTree";
|
|
8
8
|
import { SimpleTabs, Tab } from "../ui/SimpleTabs";
|
|
9
9
|
import ItemSearch, { ResultItem } from "../ui/ItemSearch";
|
|
@@ -127,11 +127,12 @@ export const InsertMenuTemplate = ({
|
|
|
127
127
|
label: "Options",
|
|
128
128
|
content: (
|
|
129
129
|
<div className="flex h-full flex-col gap-2">
|
|
130
|
-
<
|
|
130
|
+
<FilterInput
|
|
131
131
|
ref={filterRef}
|
|
132
132
|
className="w-full text-sm"
|
|
133
133
|
placeholder="Filter"
|
|
134
|
-
|
|
134
|
+
value={filter}
|
|
135
|
+
onChange={setFilter}
|
|
135
136
|
/>
|
|
136
137
|
<div className="relative flex-1">
|
|
137
138
|
<div className="absolute inset-0 overflow-auto">
|
|
@@ -152,17 +153,7 @@ export const InsertMenuTemplate = ({
|
|
|
152
153
|
>
|
|
153
154
|
{option.icon}
|
|
154
155
|
<span className="flex-1">
|
|
155
|
-
{option.label
|
|
156
|
-
.split(new RegExp(`(${filter})`, "i"))
|
|
157
|
-
.map((part: string, i: number) =>
|
|
158
|
-
part.toLowerCase() === filter.toLowerCase() ? (
|
|
159
|
-
<u className="font-bold" key={i}>
|
|
160
|
-
{part}
|
|
161
|
-
</u>
|
|
162
|
-
) : (
|
|
163
|
-
part
|
|
164
|
-
),
|
|
165
|
-
)}
|
|
156
|
+
{highlightMatch(option.label, filter)}
|
|
166
157
|
</span>
|
|
167
158
|
</div>
|
|
168
159
|
))}
|
|
@@ -92,7 +92,7 @@ export function VersionSelector({
|
|
|
92
92
|
</PopoverTrigger>
|
|
93
93
|
<PopoverContent className="w-64 p-0" align="start">
|
|
94
94
|
<Command>
|
|
95
|
-
<CommandList className="max-h-[
|
|
95
|
+
<CommandList className="max-h-[30vh]">
|
|
96
96
|
<CommandEmpty>No versions available</CommandEmpty>
|
|
97
97
|
<CommandGroup>
|
|
98
98
|
{versions.length > 0 && (
|
|
@@ -132,34 +132,34 @@ export function VersionSelector({
|
|
|
132
132
|
</CommandItem>
|
|
133
133
|
))}
|
|
134
134
|
</CommandGroup>
|
|
135
|
-
{!readOnly && (
|
|
136
|
-
<>
|
|
137
|
-
<CommandSeparator />
|
|
138
|
-
<CommandGroup>
|
|
139
|
-
<CommandItem
|
|
140
|
-
onSelect={handleCreateVersion}
|
|
141
|
-
className="flex items-center gap-2 px-2 py-2"
|
|
142
|
-
>
|
|
143
|
-
<Plus className="h-4 w-4" />
|
|
144
|
-
<span>Add Version</span>
|
|
145
|
-
</CommandItem>
|
|
146
|
-
<CommandItem
|
|
147
|
-
onSelect={handleDeleteVersion}
|
|
148
|
-
disabled={versions.length === 0}
|
|
149
|
-
className={cn(
|
|
150
|
-
"flex items-center gap-2 px-2 py-2",
|
|
151
|
-
versions.length === 0
|
|
152
|
-
? "cursor-not-allowed opacity-50"
|
|
153
|
-
: "text-red-600 hover:text-red-700",
|
|
154
|
-
)}
|
|
155
|
-
>
|
|
156
|
-
<X className="h-4 w-4" />
|
|
157
|
-
<span>Delete Version</span>
|
|
158
|
-
</CommandItem>
|
|
159
|
-
</CommandGroup>
|
|
160
|
-
</>
|
|
161
|
-
)}
|
|
162
135
|
</CommandList>
|
|
136
|
+
{!readOnly && (
|
|
137
|
+
<>
|
|
138
|
+
<div className="border-t border-gray-200" />
|
|
139
|
+
<div className="p-1">
|
|
140
|
+
<CommandItem
|
|
141
|
+
onSelect={handleCreateVersion}
|
|
142
|
+
className="flex items-center gap-2 px-2 py-2"
|
|
143
|
+
>
|
|
144
|
+
<Plus className="h-4 w-4" />
|
|
145
|
+
<span>Add Version</span>
|
|
146
|
+
</CommandItem>
|
|
147
|
+
<CommandItem
|
|
148
|
+
onSelect={handleDeleteVersion}
|
|
149
|
+
disabled={versions.length === 0}
|
|
150
|
+
className={cn(
|
|
151
|
+
"flex items-center gap-2 px-2 py-2",
|
|
152
|
+
versions.length === 0
|
|
153
|
+
? "cursor-not-allowed opacity-50"
|
|
154
|
+
: "text-red-600 hover:text-red-700",
|
|
155
|
+
)}
|
|
156
|
+
>
|
|
157
|
+
<X className="h-4 w-4" />
|
|
158
|
+
<span>Delete Version</span>
|
|
159
|
+
</CommandItem>
|
|
160
|
+
</div>
|
|
161
|
+
</>
|
|
162
|
+
)}
|
|
163
163
|
</Command>
|
|
164
164
|
</PopoverContent>
|
|
165
165
|
</Popover>
|
|
@@ -252,12 +252,12 @@ export function FrameMenu({
|
|
|
252
252
|
<>
|
|
253
253
|
<div
|
|
254
254
|
className={cn(
|
|
255
|
-
"pointer-events-none absolute inset-0 rounded-b-
|
|
255
|
+
"pointer-events-none absolute inset-0 rounded-b-xs border-2",
|
|
256
256
|
colorVariants[color],
|
|
257
257
|
"tour-frame-menu opacity-70 hover:opacity-100",
|
|
258
258
|
!isMultiSelected && isHeaderWiderThanComponent && "border-t-0",
|
|
259
|
-
!isMultiSelected && !isHeaderWiderThanComponent && "rounded-tl-
|
|
260
|
-
isMultiSelected && "rounded-t-
|
|
259
|
+
!isMultiSelected && !isHeaderWiderThanComponent && "rounded-tl-xs",
|
|
260
|
+
isMultiSelected && "rounded-t-xs",
|
|
261
261
|
)}
|
|
262
262
|
style={{
|
|
263
263
|
left: componentRect.x,
|
|
@@ -2,10 +2,8 @@ import { PageViewContext } from "./pageViewContext";
|
|
|
2
2
|
import { EditorForm } from "./EditorForm";
|
|
3
3
|
import { PageViewerFrame } from "./PageViewerFrame";
|
|
4
4
|
import { useEffect, useState } from "react";
|
|
5
|
-
import { useRef } from "react";
|
|
6
5
|
import { SimpleIconButton } from "../ui/SimpleIconButton";
|
|
7
6
|
import { useEditContext } from "../client/editContext";
|
|
8
|
-
import { useDebouncedCallback } from "use-debounce";
|
|
9
7
|
import { Ellipsis, PanelLeftClose, PanelLeftOpen } from "lucide-react";
|
|
10
8
|
import { cn } from "../../lib/utils";
|
|
11
9
|
import { Splitter, SplitterPanel } from "../ui/Splitter";
|
|
@@ -32,6 +30,12 @@ export function PageViewer({
|
|
|
32
30
|
|
|
33
31
|
if (!pageViewContext) return null;
|
|
34
32
|
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (editContext?.insertMode) {
|
|
35
|
+
setFormEditorCollapsed(false);
|
|
36
|
+
}
|
|
37
|
+
}, [editContext?.insertMode]);
|
|
38
|
+
|
|
35
39
|
useEffect(() => {
|
|
36
40
|
if (
|
|
37
41
|
followEdits &&
|
|
@@ -79,7 +83,7 @@ export function PageViewer({
|
|
|
79
83
|
defaultSize: 300,
|
|
80
84
|
collapsible: true,
|
|
81
85
|
content: (
|
|
82
|
-
<div className="h-full w-full
|
|
86
|
+
<div className="h-full w-full py-2 pl-2">
|
|
83
87
|
<div className="border-gray-3 flex h-full w-full flex-col rounded-2xl border bg-white">
|
|
84
88
|
<div className="flex-1">
|
|
85
89
|
<EditorForm
|
|
@@ -134,7 +138,7 @@ export function PageViewer({
|
|
|
134
138
|
<div className={cn("h-full w-full", className)}>
|
|
135
139
|
<Splitter
|
|
136
140
|
panels={panels}
|
|
137
|
-
splitterClassName="bg-transparent -
|
|
141
|
+
splitterClassName="bg-transparent -mr-2 md:w-[8px]"
|
|
138
142
|
direction={editContext?.isMobile ? "vertical" : "horizontal"}
|
|
139
143
|
localStorageKey={`editor.pageViewer.${name}`}
|
|
140
144
|
/>
|
|
@@ -803,7 +803,7 @@ export function PageViewerFrame({
|
|
|
803
803
|
: pageViewContext.deviceHeight || 640;
|
|
804
804
|
|
|
805
805
|
return (
|
|
806
|
-
<div className="relative mt-2 flex h-full w-full flex-col items-center select-none">
|
|
806
|
+
<div className="relative mt-2 mr-2 ml-2 flex h-full w-full flex-col items-center select-none">
|
|
807
807
|
{!editContext.pageView.fullscreen && (
|
|
808
808
|
<EditorWarnings item={pageViewContext.page?.item} />
|
|
809
809
|
)}
|
|
@@ -6,7 +6,7 @@ import { classNames } from "primereact/utils";
|
|
|
6
6
|
import { InsertOption } from "../../types";
|
|
7
7
|
|
|
8
8
|
import { useEditContext } from "../client/editContext";
|
|
9
|
-
import {
|
|
9
|
+
import { FilterInput, highlightMatch } from "../../components/FilterInput";
|
|
10
10
|
import { useState, useRef } from "react";
|
|
11
11
|
|
|
12
12
|
export function ComponentPalette({}: {}) {
|
|
@@ -31,25 +31,13 @@ export function ComponentPalette({}: {}) {
|
|
|
31
31
|
return (
|
|
32
32
|
<div className="tour-component-palette relative flex h-full flex-col">
|
|
33
33
|
<div className="p-4">
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
placeholder="Filter..."
|
|
42
|
-
/>
|
|
43
|
-
{!filter && (
|
|
44
|
-
<i className="pi pi-search absolute right-2 text-xs text-gray-400" />
|
|
45
|
-
)}
|
|
46
|
-
{filter && (
|
|
47
|
-
<i
|
|
48
|
-
className="pi pi-times absolute right-2 cursor-pointer text-xs text-gray-400 hover:text-gray-600"
|
|
49
|
-
onClick={() => setFilter("")}
|
|
50
|
-
/>
|
|
51
|
-
)}
|
|
52
|
-
</div>
|
|
34
|
+
<FilterInput
|
|
35
|
+
ref={filterRef}
|
|
36
|
+
value={filter}
|
|
37
|
+
onChange={setFilter}
|
|
38
|
+
className="border-gray-300"
|
|
39
|
+
placeholder="Filter..."
|
|
40
|
+
/>
|
|
53
41
|
</div>
|
|
54
42
|
<div className="relative flex-1">
|
|
55
43
|
<div className="absolute inset-0 overflow-y-auto">
|
|
@@ -127,18 +115,7 @@ export function ComponentPalette({}: {}) {
|
|
|
127
115
|
)}
|
|
128
116
|
|
|
129
117
|
<div className="text-xs">
|
|
130
|
-
{option.name
|
|
131
|
-
.split(new RegExp(`(${filter})`, "i"))
|
|
132
|
-
.map((part: string, i: number) =>
|
|
133
|
-
part.toLowerCase() === filter.toLowerCase() &&
|
|
134
|
-
part ? (
|
|
135
|
-
<u className="font-bold" key={i}>
|
|
136
|
-
{part}
|
|
137
|
-
</u>
|
|
138
|
-
) : (
|
|
139
|
-
part && <span key={i}>{part}</span>
|
|
140
|
-
),
|
|
141
|
-
)}
|
|
118
|
+
{highlightMatch(option.name, filter)}
|
|
142
119
|
</div>
|
|
143
120
|
|
|
144
121
|
{option.isInvalid && (
|
|
@@ -27,7 +27,7 @@ export function Insert() {
|
|
|
27
27
|
<SimpleTabs
|
|
28
28
|
key="insert-tabs"
|
|
29
29
|
tabs={tabs}
|
|
30
|
-
className="flex items-center justify-center gap-4 border-b
|
|
30
|
+
className="border-gray-3 flex items-center justify-center gap-4 border-b pt-3 text-xs"
|
|
31
31
|
activeTab={activeTab}
|
|
32
32
|
setActiveTab={(index) => setActiveTab(index)}
|
|
33
33
|
/>
|
|
@@ -60,11 +60,11 @@ export function SidebarView({
|
|
|
60
60
|
if (!panel) return <div className="hidden h-full" />;
|
|
61
61
|
|
|
62
62
|
return (
|
|
63
|
-
<div className={cn("h-full", detached ? "
|
|
63
|
+
<div className={cn("h-full", detached ? "p-2" : "")}>
|
|
64
64
|
<div
|
|
65
65
|
className={cn(
|
|
66
66
|
"flex h-full flex-col bg-white",
|
|
67
|
-
detached ? "rounded-xl" : "",
|
|
67
|
+
detached ? "border-gray-3 rounded-xl border" : "",
|
|
68
68
|
)}
|
|
69
69
|
>
|
|
70
70
|
{getHeader(panel, 0)}
|
package/src/editor/ui/Icons.tsx
CHANGED
|
@@ -715,7 +715,29 @@ export function Logo({ className }: { className?: string }) {
|
|
|
715
715
|
</svg>
|
|
716
716
|
);
|
|
717
717
|
}
|
|
718
|
+
|
|
718
719
|
export function MagicEditIcon() {
|
|
720
|
+
return (
|
|
721
|
+
<svg
|
|
722
|
+
width="21"
|
|
723
|
+
height="17"
|
|
724
|
+
viewBox="0 0 21 17"
|
|
725
|
+
fill="none"
|
|
726
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
727
|
+
>
|
|
728
|
+
<path
|
|
729
|
+
d="M20.4141 5.70117C20.7921 5.32317 21.0001 4.82117 21.0001 4.28717C21.0001 3.75317 20.7921 3.25117 20.4141 2.87317L18.8281 1.28717C18.4501 0.909172 17.9481 0.701172 17.4141 0.701172C16.8801 0.701172 16.3781 0.909172 16.0011 1.28617L5.36914 11.8852V16.3002H9.78214L20.4141 5.70117ZM7.36914 14.3002V12.7152L14.4091 5.69717L15.9951 7.28317L8.95614 14.3002H7.36914Z"
|
|
730
|
+
fill="white"
|
|
731
|
+
/>
|
|
732
|
+
<path
|
|
733
|
+
d="M0.376146 4.6906C0.63534 4.62716 0.873518 4.56373 1.1117 4.50029C1.39891 4.42276 1.69313 4.35932 1.97334 4.26064C3.05916 3.85183 3.74567 3.0765 4.03989 1.9558C4.14497 1.54699 4.25005 1.13818 4.35513 0.736414C4.35513 0.722317 4.35513 0.715269 4.37615 0.701172C4.39716 0.771656 4.41117 0.842141 4.43219 0.912625C4.54427 1.34258 4.63534 1.77254 4.77545 2.19544C5.15373 3.3232 5.93131 4.04919 7.07317 4.36637C7.47947 4.47915 7.89278 4.57782 8.29909 4.6906C8.3201 4.6906 8.33411 4.69765 8.36914 4.71174C8.21502 4.75403 8.07492 4.78928 7.92781 4.82452C7.54953 4.93025 7.16424 5.00778 6.79296 5.13465C5.71415 5.52232 5.02063 6.2906 4.7124 7.40426C4.59331 7.83421 4.48823 8.26417 4.36214 8.70117C4.36214 8.68003 4.34813 8.65888 4.34112 8.63774C4.22904 8.20073 4.13096 7.76373 3.99786 7.33377C3.64059 6.14258 2.85601 5.3743 1.65811 5.04302C1.2518 4.93025 0.845498 4.83157 0.439193 4.72584C0.418178 4.72584 0.404167 4.71879 0.369141 4.7047L0.376146 4.6906Z"
|
|
734
|
+
fill="white"
|
|
735
|
+
/>
|
|
736
|
+
</svg>
|
|
737
|
+
);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
export function MagicEditImageIcon({ className }: { className?: string }) {
|
|
719
741
|
return (
|
|
720
742
|
<svg
|
|
721
743
|
width="15"
|
|
@@ -724,6 +746,7 @@ export function MagicEditIcon() {
|
|
|
724
746
|
fill="none"
|
|
725
747
|
strokeWidth={1}
|
|
726
748
|
xmlns="http://www.w3.org/2000/svg"
|
|
749
|
+
className={className}
|
|
727
750
|
>
|
|
728
751
|
<path
|
|
729
752
|
d="M9.49999 13.915H14M5 13.915H5.83727C6.08186 13.915 6.20416 13.915 6.31925 13.886C6.42128 13.8602 6.51883 13.8178 6.6083 13.7601C6.70922 13.6951 6.79569 13.6042 6.96865 13.4224L13.25 6.81862C13.6642 6.38315 13.6642 5.67711 13.25 5.24164C12.8358 4.80617 12.1642 4.80617 11.75 5.24164L5.46863 11.8454C5.29568 12.0272 5.2092 12.1181 5.14736 12.2242C5.09253 12.3183 5.05213 12.4208 5.02763 12.5281C5 12.6491 5 12.7777 5 13.0348V13.915Z"
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { InputText } from "primereact/inputtext";
|
|
2
1
|
import { useEffect, useRef, useState } from "react";
|
|
3
2
|
import { useEditContext } from "../client/editContext";
|
|
4
3
|
import { executeSearch } from "../services/aiService";
|
|
@@ -7,6 +6,7 @@ import { ProgressSpinner } from "primereact/progressspinner";
|
|
|
7
6
|
import { ItemDescriptor } from "../pageModel";
|
|
8
7
|
import { getItemDescriptor } from "../utils";
|
|
9
8
|
import { ItemList } from "./ItemList";
|
|
9
|
+
import { FilterInput } from "../../components/FilterInput";
|
|
10
10
|
|
|
11
11
|
export type ResultItem = {
|
|
12
12
|
id: string;
|
|
@@ -117,28 +117,15 @@ export const ItemSearch: React.FC<SearchProps> = ({
|
|
|
117
117
|
return (
|
|
118
118
|
<>
|
|
119
119
|
<div className="relative">
|
|
120
|
-
<
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
{
|
|
128
|
-
|
|
129
|
-
)}
|
|
130
|
-
{!loading && query && (
|
|
131
|
-
<i
|
|
132
|
-
className="pi pi-times cursor-pointer px-3 text-gray-500"
|
|
133
|
-
onClick={() => setQuery("")}
|
|
134
|
-
/>
|
|
135
|
-
)}
|
|
136
|
-
{loading && (
|
|
137
|
-
<ProgressSpinner
|
|
138
|
-
style={{ width: "24px", height: "24px", margin: "0 12px" }}
|
|
139
|
-
/>
|
|
140
|
-
)}
|
|
141
|
-
</div>
|
|
120
|
+
<FilterInput
|
|
121
|
+
className="focus:border-blue-400 focus:ring-blue-400"
|
|
122
|
+
onChange={setQuery}
|
|
123
|
+
value={query}
|
|
124
|
+
ref={inputRef}
|
|
125
|
+
autoFocus={autoFocus}
|
|
126
|
+
placeholder="Search..."
|
|
127
|
+
loading={loading}
|
|
128
|
+
/>
|
|
142
129
|
</div>
|
|
143
130
|
{results.length > 0 && (
|
|
144
131
|
<ItemList
|
|
@@ -31,12 +31,12 @@ export function SimpleTabs({
|
|
|
31
31
|
|
|
32
32
|
return (
|
|
33
33
|
<>
|
|
34
|
-
<div className={twMerge("flex gap-
|
|
34
|
+
<div className={twMerge("flex flex-wrap gap-2", className)}>
|
|
35
35
|
{tabs.map((tab, index) => (
|
|
36
36
|
<button
|
|
37
37
|
id={tab.id}
|
|
38
38
|
className={twMerge(
|
|
39
|
-
"flex cursor-pointer items-center gap-2 px-
|
|
39
|
+
"flex min-w-0 flex-shrink cursor-pointer items-center gap-2 px-3 pb-2 whitespace-nowrap",
|
|
40
40
|
activeTab === index ? "active-tab" : "",
|
|
41
41
|
)}
|
|
42
42
|
key={tab.id}
|
|
@@ -50,7 +50,7 @@ export function SimpleTabs({
|
|
|
50
50
|
}}
|
|
51
51
|
>
|
|
52
52
|
{tab.icon && <i className={tab.icon} />}
|
|
53
|
-
{tab.label}
|
|
53
|
+
<span className="truncate">{tab.label}</span>
|
|
54
54
|
</button>
|
|
55
55
|
))}
|
|
56
56
|
</div>
|
package/src/revision.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = "1.0.
|
|
2
|
-
export const buildDate = "2025-06-
|
|
1
|
+
export const version = "1.0.3962";
|
|
2
|
+
export const buildDate = "2025-06-23 12:43:13";
|