@alpaca-editor/core 1.0.3938 → 1.0.3939
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/editor/ContentTree.js +12 -8
- package/dist/editor/ContentTree.js.map +1 -1
- package/dist/editor/ContextMenu.d.ts +1 -1
- package/dist/editor/ContextMenu.js +17 -3
- package/dist/editor/ContextMenu.js.map +1 -1
- package/dist/editor/FieldActionsOverlay.d.ts +17 -0
- package/dist/editor/FieldActionsOverlay.js +148 -0
- package/dist/editor/FieldActionsOverlay.js.map +1 -0
- package/dist/editor/FieldHistory.d.ts +2 -1
- package/dist/editor/FieldHistory.js +11 -8
- package/dist/editor/FieldHistory.js.map +1 -1
- package/dist/editor/FieldListField.js +14 -17
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/PictureEditor.js +28 -2
- package/dist/editor/PictureEditor.js.map +1 -1
- package/dist/editor/Titlebar.js +18 -9
- package/dist/editor/Titlebar.js.map +1 -1
- package/dist/editor/ai/AiTerminal.js +27 -41
- package/dist/editor/ai/AiTerminal.js.map +1 -1
- package/dist/editor/client/EditorClient.js +48 -18
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +1 -1
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/itemsRepository.js +126 -90
- package/dist/editor/client/itemsRepository.js.map +1 -1
- package/dist/editor/menubar/BrowseHistory.js +3 -4
- package/dist/editor/menubar/BrowseHistory.js.map +1 -1
- package/dist/editor/menubar/PageSelector.js +37 -9
- package/dist/editor/menubar/PageSelector.js.map +1 -1
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js +1 -1
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +98 -2
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/pageModel.d.ts +14 -0
- package/dist/editor/reviews/Comment.js +3 -2
- package/dist/editor/reviews/Comment.js.map +1 -1
- package/dist/editor/services/editService.d.ts +1 -1
- package/dist/editor/services/editService.js +2 -1
- package/dist/editor/services/editService.js.map +1 -1
- package/dist/editor/ui/Icons.js +1 -1
- package/dist/editor/ui/Icons.js.map +1 -1
- package/dist/editor/ui/ItemList.d.ts +16 -0
- package/dist/editor/ui/ItemList.js +19 -0
- package/dist/editor/ui/ItemList.js.map +1 -0
- package/dist/editor/ui/ItemSearch.js +2 -12
- package/dist/editor/ui/ItemSearch.js.map +1 -1
- package/dist/editor/ui/SimpleTabs.js +1 -1
- 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 +3 -8
- package/package.json +1 -1
- package/src/editor/ContentTree.tsx +15 -12
- package/src/editor/ContextMenu.tsx +20 -2
- package/src/editor/FieldActionsOverlay.tsx +307 -0
- package/src/editor/FieldHistory.tsx +9 -8
- package/src/editor/FieldListField.tsx +29 -29
- package/src/editor/PictureEditor.tsx +66 -1
- package/src/editor/Titlebar.tsx +22 -11
- package/src/editor/ai/AiTerminal.tsx +42 -53
- package/src/editor/client/EditorClient.tsx +62 -18
- package/src/editor/client/editContext.ts +5 -1
- package/src/editor/client/itemsRepository.ts +151 -115
- package/src/editor/menubar/BrowseHistory.tsx +7 -16
- package/src/editor/menubar/PageSelector.tsx +91 -66
- package/src/editor/page-editor-chrome/FieldActionIndicator.tsx +1 -1
- package/src/editor/page-viewer/PageViewerFrame.tsx +143 -0
- package/src/editor/pageModel.ts +12 -0
- package/src/editor/reviews/Comment.tsx +5 -6
- package/src/editor/services/editService.ts +2 -0
- package/src/editor/ui/Icons.tsx +1 -0
- package/src/editor/ui/ItemList.tsx +76 -0
- package/src/editor/ui/ItemSearch.tsx +9 -46
- package/src/editor/ui/SimpleTabs.tsx +1 -1
- package/src/revision.ts +2 -2
|
@@ -23,6 +23,11 @@ import { showComponentContextMenu } from "../ContextMenu";
|
|
|
23
23
|
import { loadFieldButtons } from "../services/editService";
|
|
24
24
|
import { usePathname } from "next/navigation";
|
|
25
25
|
import { EditorWarnings } from "../EditorWarnings";
|
|
26
|
+
import {
|
|
27
|
+
FieldActionsOverlay,
|
|
28
|
+
FieldActionsOverlayRef,
|
|
29
|
+
} from "../FieldActionsOverlay";
|
|
30
|
+
import { FieldButton, FieldDescriptor } from "../pageModel";
|
|
26
31
|
|
|
27
32
|
import { Component, ItemDescriptor } from "../pageModel";
|
|
28
33
|
import { NoLayout } from "../page-editor-chrome/NoLayout";
|
|
@@ -61,6 +66,29 @@ export function PageViewerFrame({
|
|
|
61
66
|
const [showSpinner, setShowSpinner] = useState(false);
|
|
62
67
|
const [scroll, setScroll] = useState(0);
|
|
63
68
|
const [showMiniMap, setShowMiniMap] = useState(false);
|
|
69
|
+
const fieldActionsOverlay = useRef<FieldActionsOverlayRef>(null);
|
|
70
|
+
const [contextMenuFieldButtons, setContextMenuFieldButtons] = useState<
|
|
71
|
+
FieldButton[]
|
|
72
|
+
>([]);
|
|
73
|
+
const [contextMenuField, setContextMenuField] = useState<
|
|
74
|
+
FieldDescriptor | undefined
|
|
75
|
+
>();
|
|
76
|
+
const [contextMenuPosition, setContextMenuPosition] = useState<
|
|
77
|
+
{ x: number; y: number } | undefined
|
|
78
|
+
>();
|
|
79
|
+
const [preSelectedAction, setPreSelectedAction] = useState<
|
|
80
|
+
FieldButton | undefined
|
|
81
|
+
>();
|
|
82
|
+
|
|
83
|
+
// Clear preSelectedAction when overlay is closed
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
if (
|
|
86
|
+
editContext?.currentOverlay !==
|
|
87
|
+
`${contextMenuField?.fieldId || ""}_generators`
|
|
88
|
+
) {
|
|
89
|
+
setPreSelectedAction(undefined);
|
|
90
|
+
}
|
|
91
|
+
}, [editContext?.currentOverlay, contextMenuField?.fieldId]);
|
|
64
92
|
|
|
65
93
|
const zoom = pageViewContext.zoom;
|
|
66
94
|
const blockBlurEventRef = useRef(0);
|
|
@@ -68,6 +96,25 @@ export function PageViewerFrame({
|
|
|
68
96
|
ItemDescriptor | undefined
|
|
69
97
|
>(undefined);
|
|
70
98
|
|
|
99
|
+
// Field action handlers for the overlay
|
|
100
|
+
const handleActionClick = async (action: FieldButton): Promise<void> => {
|
|
101
|
+
if (contextMenuField) {
|
|
102
|
+
editContext?.triggerFieldAction(contextMenuField, action);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const handleParameterizedActionExecute = async (
|
|
107
|
+
action: FieldButton,
|
|
108
|
+
parameters: Record<string, string>,
|
|
109
|
+
): Promise<void> => {
|
|
110
|
+
if (contextMenuField) {
|
|
111
|
+
editContext?.triggerFieldAction(contextMenuField, action, parameters);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// Note: handleParameterizedActionFromContextMenu is now created inline in handleContextMenu
|
|
116
|
+
// to avoid React state timing issues with contextMenuPosition
|
|
117
|
+
|
|
71
118
|
const pageItemDescriptor = pageViewContext.pageItemDescriptor;
|
|
72
119
|
|
|
73
120
|
useEffect(() => {
|
|
@@ -505,17 +552,103 @@ export function PageViewerFrame({
|
|
|
505
552
|
clientY: event.clientY + iframeRect.y,
|
|
506
553
|
});
|
|
507
554
|
|
|
555
|
+
// Store the original context menu position for overlay positioning
|
|
556
|
+
const menuPosition = {
|
|
557
|
+
x: event.clientX + iframeRect.x,
|
|
558
|
+
y: event.clientY + iframeRect.y,
|
|
559
|
+
};
|
|
560
|
+
setContextMenuPosition(menuPosition);
|
|
561
|
+
|
|
562
|
+
console.log("Original event:", event);
|
|
563
|
+
console.log("Adjusted event:", adjustedEvent);
|
|
564
|
+
console.log("Menu position:", menuPosition);
|
|
565
|
+
|
|
508
566
|
const field = fieldElement
|
|
509
567
|
? getFieldDescriptorFromElement(fieldElement)
|
|
510
568
|
: undefined;
|
|
511
569
|
|
|
512
570
|
const fieldButtons = field ? await loadFieldButtons(field) : [];
|
|
513
571
|
|
|
572
|
+
// Create a handler that has access to the current menu position
|
|
573
|
+
const handleParameterizedActionWithPosition = (
|
|
574
|
+
field: FieldDescriptor,
|
|
575
|
+
action: FieldButton,
|
|
576
|
+
allFieldButtons: FieldButton[],
|
|
577
|
+
event: any,
|
|
578
|
+
) => {
|
|
579
|
+
setContextMenuField(field);
|
|
580
|
+
setContextMenuFieldButtons([action]);
|
|
581
|
+
setPreSelectedAction(action);
|
|
582
|
+
|
|
583
|
+
// Create a new MouseEvent with the captured position
|
|
584
|
+
const syntheticEvent = new MouseEvent("click", {
|
|
585
|
+
bubbles: true,
|
|
586
|
+
cancelable: true,
|
|
587
|
+
view: window,
|
|
588
|
+
clientX: menuPosition.x,
|
|
589
|
+
clientY: menuPosition.y,
|
|
590
|
+
screenX: menuPosition.x,
|
|
591
|
+
screenY: menuPosition.y,
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
// Add target property to the event for proper positioning
|
|
595
|
+
Object.defineProperty(syntheticEvent, "target", {
|
|
596
|
+
value: document.body,
|
|
597
|
+
enumerable: true,
|
|
598
|
+
});
|
|
599
|
+
console.log("About to show overlay with position:", {
|
|
600
|
+
menuPosition,
|
|
601
|
+
syntheticEvent,
|
|
602
|
+
preSelectedAction: action,
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
// Add a small delay to ensure context menu has closed
|
|
606
|
+
setTimeout(() => {
|
|
607
|
+
console.log("Showing overlay with position:", {
|
|
608
|
+
menuPosition,
|
|
609
|
+
syntheticEvent,
|
|
610
|
+
preSelectedAction: action,
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
// Create a temporary element at the exact position for better positioning
|
|
614
|
+
const tempElement = document.createElement("div");
|
|
615
|
+
tempElement.style.position = "fixed";
|
|
616
|
+
tempElement.style.left = menuPosition.x + "px";
|
|
617
|
+
tempElement.style.top = menuPosition.y + "px";
|
|
618
|
+
tempElement.style.width = "1px";
|
|
619
|
+
tempElement.style.height = "1px";
|
|
620
|
+
tempElement.style.visibility = "hidden";
|
|
621
|
+
tempElement.style.pointerEvents = "none";
|
|
622
|
+
document.body.appendChild(tempElement);
|
|
623
|
+
|
|
624
|
+
// Create event targeting the positioned element
|
|
625
|
+
const positionedEvent = new MouseEvent("click", {
|
|
626
|
+
bubbles: true,
|
|
627
|
+
cancelable: true,
|
|
628
|
+
view: window,
|
|
629
|
+
clientX: menuPosition.x,
|
|
630
|
+
clientY: menuPosition.y,
|
|
631
|
+
});
|
|
632
|
+
Object.defineProperty(positionedEvent, "target", {
|
|
633
|
+
value: tempElement,
|
|
634
|
+
enumerable: true,
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
fieldActionsOverlay.current?.show(positionedEvent, action);
|
|
638
|
+
|
|
639
|
+
// Clean up the temporary element after overlay is shown
|
|
640
|
+
setTimeout(() => {
|
|
641
|
+
document.body.removeChild(tempElement);
|
|
642
|
+
}, 1000);
|
|
643
|
+
}, 100);
|
|
644
|
+
};
|
|
645
|
+
|
|
514
646
|
const showMenu = await showComponentContextMenu(
|
|
515
647
|
selectedComponents,
|
|
516
648
|
editContextRef.current!,
|
|
517
649
|
field,
|
|
518
650
|
fieldButtons,
|
|
651
|
+
handleParameterizedActionWithPosition,
|
|
519
652
|
);
|
|
520
653
|
if (showMenu) showMenu(adjustedEvent);
|
|
521
654
|
};
|
|
@@ -734,6 +867,16 @@ export function PageViewerFrame({
|
|
|
734
867
|
</>
|
|
735
868
|
)}
|
|
736
869
|
</div>
|
|
870
|
+
<FieldActionsOverlay
|
|
871
|
+
ref={fieldActionsOverlay}
|
|
872
|
+
generatorButtons={contextMenuFieldButtons}
|
|
873
|
+
onActionClick={handleActionClick}
|
|
874
|
+
onParameterizedActionExecute={handleParameterizedActionExecute}
|
|
875
|
+
currentOverlay={editContext?.currentOverlay}
|
|
876
|
+
fieldId={contextMenuField?.fieldId || ""}
|
|
877
|
+
setCurrentOverlay={editContext?.setCurrentOverlay || (() => {})}
|
|
878
|
+
preSelectedAction={preSelectedAction}
|
|
879
|
+
/>
|
|
737
880
|
</div>
|
|
738
881
|
);
|
|
739
882
|
}
|
package/src/editor/pageModel.ts
CHANGED
|
@@ -74,6 +74,17 @@ export type ItemRef = {
|
|
|
74
74
|
name?: string;
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
+
export type FieldButtonParameter = {
|
|
78
|
+
id: string;
|
|
79
|
+
label: string;
|
|
80
|
+
placeholder?: string;
|
|
81
|
+
type?: "text" | "textarea" | "number" | "select";
|
|
82
|
+
required?: boolean;
|
|
83
|
+
defaultValue?: string;
|
|
84
|
+
options?: { value: string; label: string }[]; // for select type
|
|
85
|
+
rows?: number; // for textarea type
|
|
86
|
+
};
|
|
87
|
+
|
|
77
88
|
export type FieldButton = {
|
|
78
89
|
id: string;
|
|
79
90
|
label: string;
|
|
@@ -81,6 +92,7 @@ export type FieldButton = {
|
|
|
81
92
|
action?: string;
|
|
82
93
|
icon?: string;
|
|
83
94
|
isGenerator: boolean;
|
|
95
|
+
parameters?: FieldButtonParameter[];
|
|
84
96
|
};
|
|
85
97
|
|
|
86
98
|
export type LockSession = {
|
|
@@ -13,6 +13,7 @@ import { SimpleIconButton } from "../ui/SimpleIconButton";
|
|
|
13
13
|
import { OverlayPanel } from "primereact/overlaypanel";
|
|
14
14
|
import { ProgressSpinner } from "primereact/progressspinner";
|
|
15
15
|
import { useDebouncedCallback } from "use-debounce";
|
|
16
|
+
import { ActionButton } from "../../components/ActionButton";
|
|
16
17
|
|
|
17
18
|
export function Comment({ comment }: { comment: CommentType }) {
|
|
18
19
|
const editContext = useEditContext();
|
|
@@ -257,8 +258,7 @@ export function Comment({ comment }: { comment: CommentType }) {
|
|
|
257
258
|
)}
|
|
258
259
|
{!isSaving && (
|
|
259
260
|
<div className="mt-1 flex justify-end gap-2">
|
|
260
|
-
<
|
|
261
|
-
variant="outline"
|
|
261
|
+
<ActionButton
|
|
262
262
|
onClick={() => {
|
|
263
263
|
if (comment.isNew) {
|
|
264
264
|
if (editContext?.setComments) {
|
|
@@ -272,11 +272,10 @@ export function Comment({ comment }: { comment: CommentType }) {
|
|
|
272
272
|
}}
|
|
273
273
|
>
|
|
274
274
|
Cancel
|
|
275
|
-
</
|
|
275
|
+
</ActionButton>
|
|
276
276
|
|
|
277
|
-
<
|
|
277
|
+
<ActionButton
|
|
278
278
|
className="tour-submit-comment-button"
|
|
279
|
-
variant="outline"
|
|
280
279
|
onClick={async () => {
|
|
281
280
|
comment.text = commentText;
|
|
282
281
|
setIsSaving(true);
|
|
@@ -299,7 +298,7 @@ export function Comment({ comment }: { comment: CommentType }) {
|
|
|
299
298
|
}}
|
|
300
299
|
>
|
|
301
300
|
{comment.isNew ? "Comment" : "Save"}
|
|
302
|
-
</
|
|
301
|
+
</ActionButton>
|
|
303
302
|
</div>
|
|
304
303
|
)}
|
|
305
304
|
{renderContextInfo()}
|
|
@@ -184,6 +184,7 @@ export async function executeFieldAction(
|
|
|
184
184
|
action: string,
|
|
185
185
|
sessionId: string,
|
|
186
186
|
selectedText: string,
|
|
187
|
+
parameters: Record<string, string>,
|
|
187
188
|
callback: (data: any) => void,
|
|
188
189
|
): Promise<ExecutionResult<any>> {
|
|
189
190
|
const response = await fetch(
|
|
@@ -197,6 +198,7 @@ export async function executeFieldAction(
|
|
|
197
198
|
action,
|
|
198
199
|
selectedText,
|
|
199
200
|
sessionId,
|
|
201
|
+
parameters,
|
|
200
202
|
}),
|
|
201
203
|
credentials: "include",
|
|
202
204
|
headers: {
|
package/src/editor/ui/Icons.tsx
CHANGED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { ResultItem } from "./ItemSearch";
|
|
2
|
+
import { ItemDescriptor } from "../pageModel";
|
|
3
|
+
|
|
4
|
+
interface ItemListProps {
|
|
5
|
+
items: ResultItem[];
|
|
6
|
+
onItemHover?: (item: ResultItem | undefined) => void;
|
|
7
|
+
onItemClick: (
|
|
8
|
+
item: ItemDescriptor & { path?: string; idPath?: string; icon?: string },
|
|
9
|
+
) => void;
|
|
10
|
+
maxItems?: number;
|
|
11
|
+
className?: string;
|
|
12
|
+
showPath?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const ItemList: React.FC<ItemListProps> = ({
|
|
16
|
+
items,
|
|
17
|
+
onItemHover,
|
|
18
|
+
onItemClick,
|
|
19
|
+
maxItems = 6,
|
|
20
|
+
className = "",
|
|
21
|
+
showPath = true,
|
|
22
|
+
}) => {
|
|
23
|
+
const filteredItems = items.filter((x) => x.language).slice(0, maxItems);
|
|
24
|
+
|
|
25
|
+
const handleItemClick = (item: ResultItem) => {
|
|
26
|
+
onItemClick({
|
|
27
|
+
id: item.id,
|
|
28
|
+
language: item.language,
|
|
29
|
+
version: 0,
|
|
30
|
+
path: item.path,
|
|
31
|
+
icon: item.icon,
|
|
32
|
+
idPath: item.idPath,
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
if (filteredItems.length === 0) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div className={`flex flex-1 flex-col gap-1 overflow-y-auto ${className}`}>
|
|
42
|
+
{filteredItems.map((item) => (
|
|
43
|
+
<div
|
|
44
|
+
key={item.id + item.language}
|
|
45
|
+
className="flex cursor-pointer items-start gap-2 rounded p-1 text-xs hover:bg-gray-50"
|
|
46
|
+
onMouseEnter={() => onItemHover?.(item)}
|
|
47
|
+
onMouseLeave={() => onItemHover?.(undefined)}
|
|
48
|
+
onClick={() => handleItemClick(item)}
|
|
49
|
+
>
|
|
50
|
+
{item.icon && (
|
|
51
|
+
<img
|
|
52
|
+
src={item.icon}
|
|
53
|
+
width="16"
|
|
54
|
+
height="16"
|
|
55
|
+
className="mt-0.5 flex-shrink-0"
|
|
56
|
+
/>
|
|
57
|
+
)}
|
|
58
|
+
|
|
59
|
+
<div className="flex min-w-0 flex-1 flex-col gap-0.5">
|
|
60
|
+
<div className="truncate font-medium text-gray-900">
|
|
61
|
+
{item.name}
|
|
62
|
+
<span className="text-2xs ml-1 text-gray-400">
|
|
63
|
+
({item.language})
|
|
64
|
+
</span>
|
|
65
|
+
</div>
|
|
66
|
+
{showPath && (
|
|
67
|
+
<div className="text-2xs break-words text-gray-500">
|
|
68
|
+
{item.path}
|
|
69
|
+
</div>
|
|
70
|
+
)}
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
))}
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
@@ -6,6 +6,7 @@ import { useDebouncedCallback } from "use-debounce";
|
|
|
6
6
|
import { ProgressSpinner } from "primereact/progressspinner";
|
|
7
7
|
import { ItemDescriptor } from "../pageModel";
|
|
8
8
|
import { getItemDescriptor } from "../utils";
|
|
9
|
+
import { ItemList } from "./ItemList";
|
|
9
10
|
|
|
10
11
|
export type ResultItem = {
|
|
11
12
|
id: string;
|
|
@@ -112,7 +113,7 @@ export const ItemSearch: React.FC<SearchProps> = ({
|
|
|
112
113
|
<div className="relative">
|
|
113
114
|
<div className="flex items-center">
|
|
114
115
|
<InputText
|
|
115
|
-
className="w-full
|
|
116
|
+
className="w-full rounded border border-gray-300 px-2 py-1 pr-6 text-xs focus:border-blue-400 focus:ring-1 focus:ring-blue-400 focus:outline-none"
|
|
116
117
|
onChange={(e) => setQuery(e.target.value)}
|
|
117
118
|
value={query}
|
|
118
119
|
ref={inputRef}
|
|
@@ -134,51 +135,13 @@ export const ItemSearch: React.FC<SearchProps> = ({
|
|
|
134
135
|
</div>
|
|
135
136
|
</div>
|
|
136
137
|
{results.length > 0 && (
|
|
137
|
-
<
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
{
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
<div
|
|
145
|
-
key={x.id + x.language}
|
|
146
|
-
className="flex cursor-pointer items-start gap-2 rounded p-2 text-xs hover:bg-gray-50"
|
|
147
|
-
onMouseEnter={() => setHoveredItem?.(x)}
|
|
148
|
-
onMouseLeave={() => setHoveredItem?.(undefined)}
|
|
149
|
-
onClick={() =>
|
|
150
|
-
itemSelected({
|
|
151
|
-
id: x.id,
|
|
152
|
-
language: x.language,
|
|
153
|
-
version: 0,
|
|
154
|
-
path: x.path,
|
|
155
|
-
icon: x.icon,
|
|
156
|
-
idPath: x.idPath,
|
|
157
|
-
})
|
|
158
|
-
}
|
|
159
|
-
>
|
|
160
|
-
{x.icon && (
|
|
161
|
-
<img
|
|
162
|
-
src={x.icon}
|
|
163
|
-
width="16"
|
|
164
|
-
height="16"
|
|
165
|
-
className="mt-0.5 flex-shrink-0"
|
|
166
|
-
/>
|
|
167
|
-
)}
|
|
168
|
-
<div className="flex min-w-0 flex-1 flex-col gap-0.5">
|
|
169
|
-
<div className="truncate font-medium text-gray-900">
|
|
170
|
-
{x.name}
|
|
171
|
-
<span className="text-2xs ml-1 text-gray-400">
|
|
172
|
-
({x.language})
|
|
173
|
-
</span>
|
|
174
|
-
</div>
|
|
175
|
-
<div className="text-2xs truncate text-gray-500">
|
|
176
|
-
{x.path}
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
</div>
|
|
180
|
-
))}
|
|
181
|
-
</div>
|
|
138
|
+
<ItemList
|
|
139
|
+
items={results}
|
|
140
|
+
onItemHover={setHoveredItem}
|
|
141
|
+
onItemClick={itemSelected}
|
|
142
|
+
maxItems={6}
|
|
143
|
+
className={`mt-1 ${resultClassName}`}
|
|
144
|
+
/>
|
|
182
145
|
)}
|
|
183
146
|
{results.length === 0 && !loading && query && (
|
|
184
147
|
<div className="mt-1 text-xs text-gray-500">No results found</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.3939";
|
|
2
|
+
export const buildDate = "2025-06-07 12:23:08";
|