created animated tabs component, it has some errors tho and messes with the themeing of the given tabs
This commit is contained in:
parent
0a62a3a879
commit
f15f753b90
5 changed files with 77 additions and 23 deletions
43
package-lock.json
generated
43
package-lock.json
generated
|
|
@ -27,6 +27,7 @@
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"deep-object-diff": "^1.1.9",
|
"deep-object-diff": "^1.1.9",
|
||||||
|
"framer-motion": "^12.6.2",
|
||||||
"geojson": "^0.5.0",
|
"geojson": "^0.5.0",
|
||||||
"json-2-csv": "^5.5.8",
|
"json-2-csv": "^5.5.8",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
|
@ -8391,6 +8392,33 @@
|
||||||
"node": ">= 6"
|
"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": {
|
"node_modules/fs-extra": {
|
||||||
"version": "9.1.0",
|
"version": "9.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||||
|
|
@ -10161,6 +10189,21 @@
|
||||||
"node": "*"
|
"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": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"deep-object-diff": "^1.1.9",
|
"deep-object-diff": "^1.1.9",
|
||||||
|
"framer-motion": "^12.6.2",
|
||||||
"geojson": "^0.5.0",
|
"geojson": "^0.5.0",
|
||||||
"json-2-csv": "^5.5.8",
|
"json-2-csv": "^5.5.8",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ import { openSnackbar } from "providers/Snackbar";
|
||||||
import { binScope, binYardScope } from "models/Scope";
|
import { binScope, binYardScope } from "models/Scope";
|
||||||
import ShareObject from "user/ShareObject";
|
import ShareObject from "user/ShareObject";
|
||||||
import { Bin, Team, User } from "models";
|
import { Bin, Team, User } from "models";
|
||||||
import { Dictionary } from "lodash";
|
import { Dictionary, transform } from "lodash";
|
||||||
import ObjectUsers from "user/ObjectUsers";
|
import ObjectUsers from "user/ObjectUsers";
|
||||||
import ObjectTeams from "teams/ObjectTeams";
|
import ObjectTeams from "teams/ObjectTeams";
|
||||||
import { GrainBag } from "models/GrainBag";
|
import { GrainBag } from "models/GrainBag";
|
||||||
|
|
@ -57,6 +57,8 @@ const parentTab = {
|
||||||
marginTop: "4px",
|
marginTop: "4px",
|
||||||
marginLeft: "4px",
|
marginLeft: "4px",
|
||||||
animationDuration: "10s",
|
animationDuration: "10s",
|
||||||
|
transform: "0.3s ease-in-out",
|
||||||
|
// transition: transform 0.3s ease-in-out,
|
||||||
// background: "rgba(150, 150, 150, 0)",
|
// background: "rgba(150, 150, 150, 0)",
|
||||||
|
|
||||||
borderRadius: "-5px",
|
borderRadius: "-5px",
|
||||||
|
|
@ -112,12 +114,14 @@ const useStyles = makeStyles((theme: Theme) => {
|
||||||
},
|
},
|
||||||
tab: {
|
tab: {
|
||||||
...parentTab,
|
...parentTab,
|
||||||
color: theme.palette.text.primary
|
color: theme.palette.text.primary,
|
||||||
|
transform: "0.3s ease-in-out",
|
||||||
},
|
},
|
||||||
smallTab: {
|
smallTab: {
|
||||||
...parentTab,
|
...parentTab,
|
||||||
width: theme.spacing(8),
|
width: theme.spacing(8),
|
||||||
minWidth: theme.spacing(8),
|
minWidth: theme.spacing(8),
|
||||||
|
transform: "0.3s ease-in-out",
|
||||||
// background: theme.palette.background.paper
|
// background: theme.palette.background.paper
|
||||||
},
|
},
|
||||||
selectedTab: {
|
selectedTab: {
|
||||||
|
|
@ -125,6 +129,7 @@ const useStyles = makeStyles((theme: Theme) => {
|
||||||
borderTopLeftRadius: "6px",
|
borderTopLeftRadius: "6px",
|
||||||
borderTopRightRadius: "6px",
|
borderTopRightRadius: "6px",
|
||||||
background: theme.palette.background.default,
|
background: theme.palette.background.default,
|
||||||
|
transform: "0.3s ease-in-out",
|
||||||
// "linear-gradient(rgba(150, 150, 150, 0.3),"
|
// "linear-gradient(rgba(150, 150, 150, 0.3),"
|
||||||
// + theme.palette.background.default + " 80%)"
|
// + theme.palette.background.default + " 80%)"
|
||||||
"&:hover": {
|
"&:hover": {
|
||||||
|
|
|
||||||
23
src/common/AnimatedTabs.tsx
Normal file
23
src/common/AnimatedTabs.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Tabs, TabsProps } from "@mui/material";
|
import { Tabs, TabsProps } from "@mui/material";
|
||||||
import React, { useEffect, useState, useRef } from "react";
|
import React, { useEffect, useState, useRef } from "react";
|
||||||
|
import AnimatedTabs from "./AnimatedTabs";
|
||||||
|
|
||||||
interface DraggableTabsProps extends TabsProps {
|
interface DraggableTabsProps extends TabsProps {
|
||||||
children: React.ReactNode;
|
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) {
|
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 newOrder = [...tabOrder];
|
||||||
const [draggedItem] = newOrder.splice(draggedIndex, 1);
|
const [draggedItem] = newOrder.splice(draggedIndex, 1);
|
||||||
newOrder.splice(dropIndex, 0, draggedItem);
|
newOrder.splice(dropIndex, 0, draggedItem);
|
||||||
|
|
||||||
setTabOrder(newOrder);
|
setTabOrder(newOrder);
|
||||||
|
|
||||||
const selectedIndex = selectedValue-startTabs.length
|
const selectedIndex = selectedValue-startTabs.length
|
||||||
|
|
@ -87,24 +80,13 @@ export default function DraggableTabs(props: DraggableTabsProps) {
|
||||||
setSelectedValue(selectedValue+1)
|
setSelectedValue(selectedValue+1)
|
||||||
else if (draggedIndex < selectedIndex && dropIndex >= selectedIndex)
|
else if (draggedIndex < selectedIndex && dropIndex >= selectedIndex)
|
||||||
setSelectedValue(selectedValue-1)
|
setSelectedValue(selectedValue-1)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.log("Drop skipped: invalid indices or same position");
|
console.log("Drop skipped: invalid indices or same position");
|
||||||
}
|
}
|
||||||
setHoveredIndex(-1); // Reset hovered index
|
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) => {
|
const enhancedChildren = React.Children.map(initialChildren, (child, originalIndex) => {
|
||||||
if (React.isValidElement(child)) {
|
if (React.isValidElement(child)) {
|
||||||
const currentIndex = tabOrder.indexOf(originalIndex);
|
const currentIndex = tabOrder.indexOf(originalIndex);
|
||||||
|
|
@ -122,5 +104,5 @@ export default function DraggableTabs(props: DraggableTabsProps) {
|
||||||
const orderedChildren = tabOrder.map((index) => enhancedChildren[index]);
|
const orderedChildren = tabOrder.map((index) => enhancedChildren[index]);
|
||||||
const allTabs = [...startTabs, ...orderedChildren, ...endTabs];
|
const allTabs = [...startTabs, ...orderedChildren, ...endTabs];
|
||||||
|
|
||||||
return <Tabs {...tabsProps} value={selectedValue} >{allTabs}</Tabs>;
|
return <AnimatedTabs {...tabsProps} value={selectedValue}>{allTabs}</AnimatedTabs>;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue