update animation sub menu

This commit is contained in:
iqbal024 2025-03-11 20:47:00 +07:00
parent c0e4500756
commit b9a5434d97
4 changed files with 7461 additions and 10498 deletions

70
package-lock.json generated
View File

@ -18,10 +18,12 @@
"animejs": "^3.2.2", "animejs": "^3.2.2",
"bootstrap": "^5.1.3", "bootstrap": "^5.1.3",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"framer-motion": "^12.4.13",
"graphql": "^16.10.0", "graphql": "^16.10.0",
"imagesloaded": "^5.0.0", "imagesloaded": "^5.0.0",
"isotope-layout": "^3.0.6", "isotope-layout": "^3.0.6",
"jarallax": "^2.2.1", "jarallax": "^2.2.1",
"motion": "^12.4.13",
"next": "15.2.0-canary.30", "next": "15.2.0-canary.30",
"payload": "^3.20.0", "payload": "^3.20.0",
"photoswipe": "^5.4.4", "photoswipe": "^5.4.4",
@ -8092,6 +8094,33 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/framer-motion": {
"version": "12.4.13",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.4.13.tgz",
"integrity": "sha512-JHSXIdL7WOTCSEb2UUurHURV85pWTn6UIg+iWLBhH5SFndbjni8CEQcxwsBwOs3RHZ83TkE4xoxb9cHsFPY9yQ==",
"license": "MIT",
"dependencies": {
"motion-dom": "^12.4.11",
"motion-utils": "^12.4.10",
"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/fsevents": { "node_modules/fsevents": {
"version": "2.3.3", "version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@ -10289,6 +10318,47 @@
"license": "MIT", "license": "MIT",
"peer": true "peer": true
}, },
"node_modules/motion": {
"version": "12.4.13",
"resolved": "https://registry.npmjs.org/motion/-/motion-12.4.13.tgz",
"integrity": "sha512-8ehpE6Sd8ack6jLLzweW6RwCBQoASf+yVu8aUPFNKHsJIVejJaBPGsMiswcpfzHeCusZ/ztNIKbgoEn7ruJaOw==",
"license": "MIT",
"dependencies": {
"framer-motion": "^12.4.13",
"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/motion-dom": {
"version": "12.4.11",
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.4.11.tgz",
"integrity": "sha512-wstlyV3pktgFjqsjbXMo1NX9hQD9XTVqxQNvfc+FREAgxr3GVzgWIEKvbyyNlki3J1jmmh+et9X3aCKeqFPcxA==",
"license": "MIT",
"dependencies": {
"motion-utils": "^12.4.10"
}
},
"node_modules/motion-utils": {
"version": "12.4.10",
"resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.4.10.tgz",
"integrity": "sha512-NPwZd94V013SwRf++jMrk2+HEBgPkeIE2RiOzhAuuQlqxMJPkKt/LXVh6Upl+iN8oarSGD2dlY5/bqgsYXDABA==",
"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",

View File

@ -24,10 +24,12 @@
"animejs": "^3.2.2", "animejs": "^3.2.2",
"bootstrap": "^5.1.3", "bootstrap": "^5.1.3",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"framer-motion": "^12.4.13",
"graphql": "^16.10.0", "graphql": "^16.10.0",
"imagesloaded": "^5.0.0", "imagesloaded": "^5.0.0",
"isotope-layout": "^3.0.6", "isotope-layout": "^3.0.6",
"jarallax": "^2.2.1", "jarallax": "^2.2.1",
"motion": "^12.4.13",
"next": "15.2.0-canary.30", "next": "15.2.0-canary.30",
"payload": "^3.20.0", "payload": "^3.20.0",
"photoswipe": "^5.4.4", "photoswipe": "^5.4.4",

View File

@ -7,18 +7,12 @@ import { scrollToElement } from "@/utils/scrollToElement";
import { toggleMobileMenu } from "@/utils/toggleMobileMenu"; import { toggleMobileMenu } from "@/utils/toggleMobileMenu";
import Link from "next/link"; import Link from "next/link";
import { Fragment, useEffect, useRef, useState } from "react"; import { Fragment, useEffect, useRef, useState } from "react";
import { motion } from "framer-motion";
export default function HeaderNav({ links, animateY = false }: { links: typeof navMenuData; animateY?: boolean }) { export default function HeaderNav({ links, animateY = false }: { links: typeof navMenuData; animateY?: boolean }) {
const [isDropdownOpen, setIsDropdownOpen] = useState([""]); const [isDropdownOpen, setIsDropdownOpen] = useState<string[]>([]);
const dropdownRef = useRef(null); const dropdownRef = useRef(null);
const toggleDropdown = (section: string[]) => {
if (section == isDropdownOpen) {
setIsDropdownOpen([""]);
}
setIsDropdownOpen(section);
};
useEffect(() => { useEffect(() => {
setTimeout(() => { setTimeout(() => {
scrollToElement(); scrollToElement();
@ -38,9 +32,14 @@ export default function HeaderNav({ links, animateY = false }: { links: typeof n
<> <>
{links.map((link, index) => ( {links.map((link, index) => (
<Fragment key={index}> <Fragment key={index}>
<li> <motion.li
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3, delay: index * 0.1 }}
>
{!Array.isArray(link?.child) && ( {!Array.isArray(link?.child) && (
<Link href={link.href}> <Link href={link.href}>
<span className="text-white">
{animateY ? ( {animateY ? (
<span className="btn-animate-y"> <span className="btn-animate-y">
<span className="btn-animate-y-1">{link.text}</span> <span className="btn-animate-y-1">{link.text}</span>
@ -51,53 +50,83 @@ export default function HeaderNav({ links, animateY = false }: { links: typeof n
) : ( ) : (
link.text link.text
)} )}
</span>
</Link> </Link>
)} )}
{Array.isArray(link?.child) && ( {Array.isArray(link?.child) && (
<> <>
<Link href={link?.href ?? "#"} className="mn-has-sub flex justify-between"> <motion.div
{link.text} <i className="mi-chevron-down" onClick={() => toggleDropdown([link.text])} /> className="mn-has-sub flex justify-between text-white"
whileHover={{ scale: 1.05 }}
transition={{ duration: 0.3 }}
>
<Link href={link?.href ?? "#"}>
{link.text} <i className="mi-chevron-down" />
</Link> </Link>
</motion.div>
<ul <motion.ul
className={`mn-sub to-right ${isDropdownOpen.includes(link.text) && "open"} !bg-extColorPrimary8`} className={`mn-sub to-right ${isDropdownOpen.includes(link.text) && "open"} !bg-extColorPrimary8 text-white`}
ref={dropdownRef} ref={dropdownRef}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3 }}
whileHover={{ opacity: 1 }}
> >
{link.child.map((subLink: any, subLinkIdx: number) => ( {link.child.map((subLink: any, subLinkIdx: number) => (
<li key={subLinkIdx}> <motion.li
key={subLinkIdx}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3, delay: subLinkIdx * 0.1 }}
>
{!Array.isArray(subLink?.child) && ( {!Array.isArray(subLink?.child) && (
<Link href={subLink?.href} onClick={() => toggleMobileMenu()}> <Link href={subLink?.href} onClick={() => toggleMobileMenu()}>
{subLink?.text} <span className="text-white">{subLink?.text}</span>
</Link> </Link>
)} )}
{Array.isArray(subLink?.child) && ( {Array.isArray(subLink?.child) && (
<> <>
<Link href={subLink?.href ?? "#"} className="mn-has-sub !flex !justify-between"> <motion.div
className="mn-has-sub !flex !justify-between"
whileHover={{ scale: 1.05 }}
transition={{ duration: 0.3 }}
>
<Link href={subLink?.href ?? "#"}>
<span>{subLink.text}</span> <span>{subLink.text}</span>
<i className="mi-chevron-down" onClick={() => toggleDropdown([link.text, subLink.text])} /> <i className="mi-chevron-down" />
</Link> </Link>
</motion.div>
<ul <motion.ul
className={`mn-sub to-right ${isDropdownOpen.includes(subLink.text) && "open"} !bg-extColorPrimary8`} className={`mn-sub to-right ${isDropdownOpen.includes(subLink.text) && "open"} !bg-extColorPrimary8`}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3 }}
> >
{subLink.child.map((subLink2: any, subLinkIdx2: number) => ( {subLink.child.map((subLink2: any, subLinkIdx2: number) => (
<li key={subLinkIdx2}> <motion.li
key={subLinkIdx2}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3, delay: subLinkIdx2 * 0.1 }}
>
<Link href={subLink2?.href} onClick={() => toggleMobileMenu()}> <Link href={subLink2?.href} onClick={() => toggleMobileMenu()}>
{subLink2?.text} <span className="text-white">{subLink2?.text}</span>
</Link> </Link>
</li> </motion.li>
))} ))}
</ul> </motion.ul>
</> </>
)} )}
</li> </motion.li>
))} ))}
</ul> </motion.ul>
</> </>
)} )}
</li> </motion.li>
{index != links.length - 1 && ( {index !== links.length - 1 && (
<div <div
className="text-white bg-white h-[1px] md:h-[25px] mx-2 opacity-[0.3]" className="text-white bg-white h-[1px] md:h-[25px] mx-2 opacity-[0.3]"
style={{ border: "1px solid white" }} style={{ border: "1px solid white" }}

17782
yarn.lock

File diff suppressed because it is too large Load Diff