created animated tabs component, it has some errors tho and messes with the themeing of the given tabs

This commit is contained in:
Carter 2025-03-26 16:28:28 -06:00
parent 0a62a3a879
commit f15f753b90
5 changed files with 77 additions and 23 deletions

43
package-lock.json generated
View file

@ -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",

View file

@ -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",

View file

@ -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": {

View file

@ -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 (
<Tabs {...props}>
<AnimatePresence>
{(Array.isArray(children) ? children : [children]).map((child, index) => (
<motion.div
key={(child as ReactElement).key || index}
layout // Enables smooth movement when order changes
transition={{ type: "spring", stiffness: 300, damping: 30 }}
>
{cloneElement(child as ReactElement)}
</motion.div>
))}
</AnimatePresence>
</Tabs>
);
}

View file

@ -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 <Tabs {...tabsProps} value={selectedValue} >{allTabs}</Tabs>;
return <AnimatedTabs {...tabsProps} value={selectedValue}>{allTabs}</AnimatedTabs>;
}