diff --git a/package-lock.json b/package-lock.json index 16398c2..1eda9b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "axios": "^1.7.7", "dayjs": "^1.11.13", "deep-object-diff": "^1.1.9", + "framer-motion": "^12.6.2", "geojson": "^0.5.0", "json-2-csv": "^5.5.8", "lodash": "^4.17.21", @@ -8391,6 +8392,33 @@ "node": ">= 6" } }, + "node_modules/framer-motion": { + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.6.2.tgz", + "integrity": "sha512-7LgPRlPs5aG8UxeZiMCMZz8firC53+2+9TnWV22tuSi38D3IFRxHRUqOREKckAkt6ztX+Dn6weLcatQilJTMcg==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.6.1", + "motion-utils": "^12.5.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -10161,6 +10189,21 @@ "node": "*" } }, + "node_modules/motion-dom": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.6.1.tgz", + "integrity": "sha512-8XVsriTUEVOepoIDgE/LDGdg7qaKXWdt+wQA/8z0p8YzJDLYL8gbimZ3YkCLlj7bB2i/4UBD/g+VO7y9ZY0zHQ==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.5.0" + } + }, + "node_modules/motion-utils": { + "version": "12.5.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.5.0.tgz", + "integrity": "sha512-+hFFzvimn0sBMP9iPxBa9OtRX35ZQ3py0UHnb8U29VD+d8lQ8zH3dTygJWqK7av2v6yhg7scj9iZuvTS0f4+SA==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", diff --git a/package.json b/package.json index 1bf2a15..0c7d29d 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "axios": "^1.7.7", "dayjs": "^1.11.13", "deep-object-diff": "^1.1.9", + "framer-motion": "^12.6.2", "geojson": "^0.5.0", "json-2-csv": "^5.5.8", "lodash": "^4.17.21", diff --git a/src/bin/BinYards.tsx b/src/bin/BinYards.tsx index 98afa4b..f0dfb3a 100644 --- a/src/bin/BinYards.tsx +++ b/src/bin/BinYards.tsx @@ -44,7 +44,7 @@ import { openSnackbar } from "providers/Snackbar"; import { binScope, binYardScope } from "models/Scope"; import ShareObject from "user/ShareObject"; import { Bin, Team, User } from "models"; -import { Dictionary } from "lodash"; +import { Dictionary, transform } from "lodash"; import ObjectUsers from "user/ObjectUsers"; import ObjectTeams from "teams/ObjectTeams"; import { GrainBag } from "models/GrainBag"; @@ -57,6 +57,8 @@ const parentTab = { marginTop: "4px", marginLeft: "4px", animationDuration: "10s", + transform: "0.3s ease-in-out", + // transition: transform 0.3s ease-in-out, // background: "rgba(150, 150, 150, 0)", borderRadius: "-5px", @@ -112,12 +114,14 @@ const useStyles = makeStyles((theme: Theme) => { }, tab: { ...parentTab, - color: theme.palette.text.primary + color: theme.palette.text.primary, + transform: "0.3s ease-in-out", }, smallTab: { ...parentTab, width: theme.spacing(8), minWidth: theme.spacing(8), + transform: "0.3s ease-in-out", // background: theme.palette.background.paper }, selectedTab: { @@ -125,6 +129,7 @@ const useStyles = makeStyles((theme: Theme) => { borderTopLeftRadius: "6px", borderTopRightRadius: "6px", background: theme.palette.background.default, + transform: "0.3s ease-in-out", // "linear-gradient(rgba(150, 150, 150, 0.3)," // + theme.palette.background.default + " 80%)" "&:hover": { diff --git a/src/common/AnimatedTabs.tsx b/src/common/AnimatedTabs.tsx new file mode 100644 index 0000000..07acc1a --- /dev/null +++ b/src/common/AnimatedTabs.tsx @@ -0,0 +1,23 @@ +import { Tabs, TabsProps } from "@mui/material"; +import { motion, AnimatePresence } from "framer-motion"; +import { ReactElement, cloneElement } from "react"; + +interface AnimatedTabsProps extends TabsProps {} + +export default function AnimatedTabs({ children, ...props }: AnimatedTabsProps) { + return ( + + + {(Array.isArray(children) ? children : [children]).map((child, index) => ( + + {cloneElement(child as ReactElement)} + + ))} + + + ); +} diff --git a/src/common/DraggableTabs.tsx b/src/common/DraggableTabs.tsx index b203319..c7d8112 100644 --- a/src/common/DraggableTabs.tsx +++ b/src/common/DraggableTabs.tsx @@ -1,5 +1,6 @@ import { Tabs, TabsProps } from "@mui/material"; import React, { useEffect, useState, useRef } from "react"; +import AnimatedTabs from "./AnimatedTabs"; interface DraggableTabsProps extends TabsProps { children: React.ReactNode; @@ -67,17 +68,9 @@ export default function DraggableTabs(props: DraggableTabsProps) { } if (draggedIndex !== dropIndex && draggedIndex >= 0 && dropIndex >= 0 && draggedIndex < tabOrder.length && dropIndex < tabOrder.length) { - - // console.log("draggedItem: ", draggedItem) - // console.log("props value: ", tabsProps.value) - // console.log("draggedTabValue: ", draggedTabValue) - console.log("dropIndex: ", dropIndex) - // console.log("startTabs.length: ", startTabs.length) - const newOrder = [...tabOrder]; const [draggedItem] = newOrder.splice(draggedIndex, 1); newOrder.splice(dropIndex, 0, draggedItem); - setTabOrder(newOrder); const selectedIndex = selectedValue-startTabs.length @@ -87,24 +80,13 @@ export default function DraggableTabs(props: DraggableTabsProps) { setSelectedValue(selectedValue+1) else if (draggedIndex < selectedIndex && dropIndex >= selectedIndex) setSelectedValue(selectedValue-1) + } else { console.log("Drop skipped: invalid indices or same position"); } setHoveredIndex(-1); // Reset hovered index }; - // useEffect(() => { - // console.log(hoveredIndex) - // }, [hoveredIndex]) - - // useEffect(() => { - // console.log(props.value) - // }, [props.value]) - - // useEffect(() => { - // console.log(selectedValue) - // }, [selectedValue]) - const enhancedChildren = React.Children.map(initialChildren, (child, originalIndex) => { if (React.isValidElement(child)) { const currentIndex = tabOrder.indexOf(originalIndex); @@ -122,5 +104,5 @@ export default function DraggableTabs(props: DraggableTabsProps) { const orderedChildren = tabOrder.map((index) => enhancedChildren[index]); const allTabs = [...startTabs, ...orderedChildren, ...endTabs]; - return {allTabs}; + return {allTabs}; } \ No newline at end of file