mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-21 17:17:41 +02:00
89 lines
2.8 KiB
TypeScript
89 lines
2.8 KiB
TypeScript
import React, { createContext, useContext, useState, useRef, useCallback, RefObject } from 'react';
|
|
|
|
export interface SelectedElement {
|
|
id: string;
|
|
selectorPath: string;
|
|
tagName: string;
|
|
className: string;
|
|
outerHTML: string;
|
|
computedStyles: Record<string, string>;
|
|
screenshot?: string;
|
|
boundingRect: { x: number; y: number; width: number; height: number };
|
|
semanticType?: 'agent-card' | 'message' | 'tool-call' | 'tool-group' | 'view-card' | 'browser-card' | 'dom-element';
|
|
semanticLabel?: string;
|
|
semanticData?: Record<string, any>;
|
|
}
|
|
|
|
interface ElementSelectionContextValue {
|
|
selectMode: boolean;
|
|
toggleSelectMode: () => void;
|
|
setSelectMode: (active: boolean) => void;
|
|
excludeSelectId: string | null;
|
|
setExcludeSelectId: (id: string | null) => void;
|
|
selectedElements: SelectedElement[];
|
|
addSelectedElement: (el: SelectedElement) => void;
|
|
updateSelectedElement: (id: string, patch: Partial<SelectedElement>) => void;
|
|
removeSelectedElement: (id: string) => void;
|
|
clearSelectedElements: () => void;
|
|
iframeRef: RefObject<HTMLIFrameElement | null>;
|
|
}
|
|
|
|
const ElementSelectionContext = createContext<ElementSelectionContextValue | null>(null);
|
|
|
|
export function useElementSelection() {
|
|
return useContext(ElementSelectionContext);
|
|
}
|
|
|
|
export const ElementSelectionProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
const [selectMode, setSelectMode] = useState(false);
|
|
const [excludeSelectId, setExcludeSelectId] = useState<string | null>(null);
|
|
const [selectedElements, setSelectedElements] = useState<SelectedElement[]>([]);
|
|
const iframeRef = useRef<HTMLIFrameElement | null>(null);
|
|
|
|
const toggleSelectMode = useCallback(() => {
|
|
setSelectMode((prev) => {
|
|
if (prev) setExcludeSelectId(null);
|
|
return !prev;
|
|
});
|
|
}, []);
|
|
|
|
const addSelectedElement = useCallback((el: SelectedElement) => {
|
|
setSelectedElements((prev) => {
|
|
if (prev.some((e) => e.id === el.id)) return prev;
|
|
return [...prev, el];
|
|
});
|
|
}, []);
|
|
|
|
const updateSelectedElement = useCallback((id: string, patch: Partial<SelectedElement>) => {
|
|
setSelectedElements((prev) => prev.map((e) => e.id === id ? { ...e, ...patch } : e));
|
|
}, []);
|
|
|
|
const removeSelectedElement = useCallback((id: string) => {
|
|
setSelectedElements((prev) => prev.filter((e) => e.id !== id));
|
|
}, []);
|
|
|
|
const clearSelectedElements = useCallback(() => {
|
|
setSelectedElements([]);
|
|
}, []);
|
|
|
|
return (
|
|
<ElementSelectionContext.Provider
|
|
value={{
|
|
selectMode,
|
|
toggleSelectMode,
|
|
setSelectMode,
|
|
excludeSelectId,
|
|
setExcludeSelectId,
|
|
selectedElements,
|
|
addSelectedElement,
|
|
updateSelectedElement,
|
|
removeSelectedElement,
|
|
clearSelectedElements,
|
|
iframeRef,
|
|
}}
|
|
>
|
|
{children}
|
|
</ElementSelectionContext.Provider>
|
|
);
|
|
};
|