- {items.map((item) => (
-
handleItemToggle(item.id)}
- >
-
handleItemToggle(item.id)}
- />
-
- {selectedItems.includes(item.id) && }
-
- {item.name}
+ if (onSelectionChange) {
+ onSelectionChange(updatedSelection);
+ }
+
+ return updatedSelection;
+ });
+ };
+
+ // Close menu if clicked outside
+ useEffect(() => {
+ const handleClickOutside = (event: MouseEvent) => {
+ if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
+ setIsOpen(false);
+ }
+ };
+
+ document.addEventListener("mousedown", handleClickOutside);
+ return () => {
+ document.removeEventListener("mousedown", handleClickOutside);
+ };
+ }, []);
+
+ return (
+
+
+
- ))}
+ {isOpen && (
+
+ {items.map((item) => (
+
handleItemToggle(item.id)}>
+
handleItemToggle(item.id)} />
+
{selectedItems.includes(item.id) && }
+ {item.name}
+
+ ))}
+
+ )}
- )}
-
- );
+ );
};
export default KebabMenuListMultiSelect;
diff --git a/app/src/types/uiTypes.d.ts b/app/src/types/uiTypes.d.ts
index 92fa7b0..500b72e 100644
--- a/app/src/types/uiTypes.d.ts
+++ b/app/src/types/uiTypes.d.ts
@@ -78,3 +78,60 @@ interface Tutorial {
thumbnail?: string;
createdAt: string;
}
+
+// Base interface for all list items
+interface BaseListItem {
+ id: string;
+ name: string;
+ type: "zone" | "asset" | "wall" | "floor" | "point" | "decal";
+ isLocked?: boolean;
+ isVisible?: boolean;
+ isActive?: boolean;
+ canEdit?: boolean;
+ children?: ListItem[]; // For nested relationships
+ metadata?: {
+ position?: [number, number, number];
+ rotation?: [number, number, number];
+ scale?: [number, number, number];
+ color?: string;
+ height?: number;
+ thickness?: number;
+ // ... other type-specific properties
+ };
+}
+
+// Extended interfaces for specific types
+interface ZoneListItem extends BaseListItem {
+ type: "zone";
+ metadata: {
+ zoneHeight: number;
+ zoneColor: string;
+ viewPortPosition: [number, number, number];
+ viewPortTarget: [number, number, number];
+ };
+}
+
+interface AssetListItem extends BaseListItem {
+ type: "asset";
+ metadata: {
+ modelUuid: string;
+ position: [number, number, number];
+ rotation: [number, number, number];
+ scale: [number, number, number];
+ isCollidable: boolean;
+ opacity: number;
+ animations?: string[];
+ };
+}
+
+interface WallListItem extends BaseListItem {
+ type: "wall";
+ metadata: {
+ wallThickness: number;
+ wallHeight: number;
+ outsideMaterial: string;
+ insideMaterial: string;
+ };
+}
+
+type ListItem = ZoneListItem | AssetListItem | WallListItem | BaseListItem;