diff --git a/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryAgentList/LibraryAgentList.tsx b/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryAgentList/LibraryAgentList.tsx
index 3e0dcfe525..fd5163d8e4 100644
--- a/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryAgentList/LibraryAgentList.tsx
+++ b/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryAgentList/LibraryAgentList.tsx
@@ -11,11 +11,72 @@ import { Button } from "@/components/atoms/Button/Button";
import { ArrowLeftIcon, HeartIcon } from "@phosphor-icons/react";
import { Text } from "@/components/atoms/Text/Text";
import { Tab } from "../LibraryTabs/LibraryTabs";
-import { LayoutGroup } from "framer-motion";
+import {
+ AnimatePresence,
+ LayoutGroup,
+ motion,
+ useReducedMotion,
+} from "framer-motion";
import { LibraryFolderEditDialog } from "../LibraryFolderEditDialog/LibraryFolderEditDialog";
import { LibraryFolderDeleteDialog } from "../LibraryFolderDeleteDialog/LibraryFolderDeleteDialog";
import { useLibraryAgentList } from "./useLibraryAgentList";
+const containerVariants = {
+ hidden: {},
+ show: {
+ transition: {
+ staggerChildren: 0.04,
+ delayChildren: 0.04,
+ },
+ },
+ exit: {
+ opacity: 0,
+ filter: "blur(4px)",
+ transition: {
+ duration: 0.15,
+ ease: [0.25, 0.1, 0.25, 1],
+ },
+ },
+};
+
+const itemVariants = {
+ hidden: {
+ opacity: 0,
+ y: 8,
+ scale: 0.96,
+ filter: "blur(4px)",
+ },
+ show: {
+ opacity: 1,
+ y: 0,
+ scale: 1,
+ filter: "blur(0px)",
+ transition: {
+ duration: 0.25,
+ ease: [0.25, 0.1, 0.25, 1],
+ },
+ },
+};
+
+const reducedContainerVariants = {
+ hidden: {},
+ show: {
+ transition: { staggerChildren: 0.02 },
+ },
+ exit: {
+ opacity: 0,
+ transition: { duration: 0.15 },
+ },
+};
+
+const reducedItemVariants = {
+ hidden: { opacity: 0 },
+ show: {
+ opacity: 1,
+ transition: { duration: 0.2 },
+ },
+};
+
interface Props {
searchTerm: string;
librarySort: LibraryAgentSort;
@@ -37,6 +98,14 @@ export function LibraryAgentList({
activeTab,
onTabChange,
}: Props) {
+ const shouldReduceMotion = useReducedMotion();
+ const activeContainerVariants = shouldReduceMotion
+ ? reducedContainerVariants
+ : containerVariants;
+ const activeItemVariants = shouldReduceMotion
+ ? reducedItemVariants
+ : itemVariants;
+
const {
isFavoritesTab,
agentLoading,
@@ -112,26 +181,38 @@ export function LibraryAgentList({
loader={}
>
-
- {showFolders &&
- foldersData?.folders.map((folder) => (
-
onFolderSelect(folder.id)}
- onEdit={() => setEditingFolder(folder)}
- onDelete={() => setDeletingFolder(folder)}
- />
+
+
+ {showFolders &&
+ foldersData?.folders.map((folder) => (
+
+ onFolderSelect(folder.id)}
+ onEdit={() => setEditingFolder(folder)}
+ onDelete={() => setDeletingFolder(folder)}
+ />
+
+ ))}
+ {agents.map((agent) => (
+
+
+
))}
- {agents.map((agent) => (
-
- ))}
-
+
+
)}
diff --git a/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryFolder/LibraryFolder.tsx b/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryFolder/LibraryFolder.tsx
index 7af688f230..e1f9e2f734 100644
--- a/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryFolder/LibraryFolder.tsx
+++ b/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryFolder/LibraryFolder.tsx
@@ -57,7 +57,7 @@ export function LibraryFolder({
({
- queryKey: getGetV2ListLibraryFoldersQueryKey(),
- });
+ const previousData =
+ queryClient.getQueriesData({
+ queryKey: getGetV2ListLibraryFoldersQueryKey(),
+ });
queryClient.setQueriesData(
{ queryKey: getGetV2ListLibraryFoldersQueryKey() },
@@ -123,8 +122,7 @@ export function LibraryFolderEditDialog({ folder, isOpen, setIsOpen }: Props) {
queryClient.setQueryData(queryKey, data);
}
}
- const detail =
- error.detail ?? error.response?.detail ?? "";
+ const detail = error.detail ?? error.response?.detail ?? "";
if (
typeof detail === "string" &&
detail.toLowerCase().includes("already exists")
@@ -191,7 +189,7 @@ export function LibraryFolderEditDialog({ folder, isOpen, setIsOpen }: Props) {
diff --git a/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryTabs/LibraryTabs.tsx b/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryTabs/LibraryTabs.tsx
index 59925ccd07..88fd29bc0f 100644
--- a/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryTabs/LibraryTabs.tsx
+++ b/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryTabs/LibraryTabs.tsx
@@ -19,11 +19,16 @@ interface Props {
layoutId?: string;
}
-export function LibraryTabs({ tabs, activeTab, onTabChange, layoutId = "library-tabs" }: Props) {
+export function LibraryTabs({
+ tabs,
+ activeTab,
+ onTabChange,
+ layoutId = "library-tabs",
+}: Props) {
const { registerFavoritesTabRef } = useFavoriteAnimation();
return (
-
+
{tabs.map((tab) => (
))}
@@ -46,7 +53,13 @@ interface TabButtonProps {
onRefReady?: (element: HTMLElement | null) => void;
}
-function TabButton({ tab, isActive, onSelect, layoutId, onRefReady }: TabButtonProps) {
+function TabButton({
+ tab,
+ isActive,
+ onSelect,
+ layoutId,
+ onRefReady,
+}: TabButtonProps) {
const [isLoaded, setIsLoaded] = useState(false);
const buttonRef = useRef
(null);
@@ -82,7 +95,7 @@ function TabButton({ tab, isActive, onSelect, layoutId, onRefReady }: TabButtonP
onSelect(tab.id);
setIsLoaded(true);
}}
- className="w-fit h-fit flex"
+ className="flex h-fit w-fit"
style={{ willChange: "transform" }}
>
{tab.title}