Skip to content
This repository has been archived by the owner on Aug 7, 2024. It is now read-only.

Solved Issue #10209 : Create Sidebar drawer and Add Navbar Animation #10321

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions components/layouts/DocsLayout.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { MDXProvider } from "@mdx-js/react";
import Head from "next/head";

import { useState } from "react";
import BreadCrumb from "@components/BreadCrumb";
import Page from "@components/Page";
import { ComponentStyle } from "@components/mdx/ComponentStyle";
import SideNav from "@components/navbar/SideNav";
import { PROJECT_NAME } from "@constants/index";
import { HiOutlineMenuAlt3 } from "react-icons/hi";
import SideDrawer from "@components/navbar/SideDrawer";
import { IoMdClose } from "react-icons/io";

export const navigation = [
{
Expand All @@ -23,7 +26,7 @@ export const navigation = [
},
{
name: "Getting Started",
// icon: FolderIcon,
// icon: FolderDocumentationIcon,
children: [
{ name: "Editing with JSON", href: "/docs/how-to-guides/editing-json" },
{ name: "Editing with Forms", href: "/docs/how-to-guides/editing-forms" },
Expand Down Expand Up @@ -126,6 +129,7 @@ export const navigation = [
];

export default function DocsLayout({ children, title, section, name }) {
const [showSideNav, setShowSideNav] = useState(false);
return (
<>
<Head>
Expand All @@ -140,7 +144,18 @@ export default function DocsLayout({ children, title, section, name }) {
<BreadCrumb section={section} name={name} />

<div className="flex flex-grow flex-col sm:flex-row">
<SideNav navigation={navigation} />
<div className={`p-3 z-50 bg-primary-high text-white md:hidden rounded-full dark:text-gray-400 cursor-pointer fixed bottom-5 right-5`}
onClick={() => setShowSideNav(!showSideNav)}
>
{
showSideNav ? <IoMdClose className="w-7 h-7"/> : <HiOutlineMenuAlt3 className="w-7 h-7"/>
}
</div>
{
showSideNav &&
<SideDrawer navigation={navigation} showSideNav={showSideNav} setShowSideNav={setShowSideNav}/>
}
<SideNav navigation={navigation} />
<div className="float-none my-0 w-[100%] sm:w-[65%] md:w-[68%] lg:w-[100%] mt-12 overflow-auto">
<MDXProvider components={ComponentStyle}>
<div className="w-full max-w-7xl px-4 sm:px-6 lg:px-8 dark:text-white prose">
Expand Down
16 changes: 15 additions & 1 deletion components/navbar/Navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,21 @@ export default function Navbar() {
const { data: session } = useSession();
const { systemTheme, theme, setTheme } = useTheme();


const [stickyClass, setStickyClass] = useState(false);

function stickNavbar() {
let windowHeight = window.scrollY;
if (windowHeight > 80) {
console.log(windowHeight)
setStickyClass(true);
} else {
setStickyClass(false);
}
}

useEffect(() => {
window.addEventListener("scroll", stickNavbar);
setMounted(true);
}, []);

Expand Down Expand Up @@ -137,7 +151,7 @@ export default function Navbar() {
);

return (
<header className="min-h-full" ref={navConRef}>
<header className={`min-h-full ${stickyClass && "sticky top-0 z-50 animate-navbar-animation"}`} ref={navConRef}>
<nav
className={classNames(
"relative top-0 bg-primary-high dark:bg-primary-medium",
Expand Down
90 changes: 90 additions & 0 deletions components/navbar/SideDrawer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { Disclosure } from "@headlessui/react";
import ChevronRightIcon from "@heroicons/react/20/solid/ChevronRightIcon";
import EditOnGitHub from "@components/EditOnGithub";
import { useRouter } from "next/router";
import { classNames } from "@services/utils/classNames";
import Link from "@components/Link";

export default function SideNav({ navigation, showSideNav, setShowSideNav }) {
const { pathname } = useRouter();
return (
<ul
role="list"
className={`sm:w-64 overflow-auto flex-none fixed h-screen top-0 px-4 left-0 w-[80%] bg-primary-medium z-40 rounded border border-primary-high dark:border-primary-low border-t-0 sm:border-none mt-3 rounded-t-none sm:mt-12 ${showSideNav ? "animate-sideBar-in" : "animate-sideBar-out"}`}
>
<li>
<ul role="list">
{navigation.map((item) => (
<li key={item.name} className="my-2">
{!item.children ? (
<Link
href={item.href}
className={classNames(
item.href == pathname &&
"bg-slate-200 dark:bg-primary-low !text-secondary-high",
"group flex gap-x-3 rounded-md py-2 pl-3 pr-2 text-md leading-6 font-semibold text-primary-high dark:text-primary-low-medium hover:text-secondary-high dark:hover:text-secondary-high hover:bg-slate-200 dark:hover:bg-primary-low duration-200",
)}
>
{/* <item.icon
className="h-6 w-6 shrink-0 text-primary-low-medium"
aria-hidden="true"
/> */}
{item.name}
</Link>
) : (
<Disclosure defaultOpen={item.children.some(subItem => subItem.href === pathname)}>
{({ open }) => (
<>
<Disclosure.Button
className={classNames(
item.children?.filter(
(subItem) => subItem.href == pathname,
)?.[0]?.href == pathname &&
"bg-slate-200 dark:bg-primary-low !text-secondary-high",
"group flex items-center w-full text-left rounded-md py-2 pl-3 pr-2 gap-x-3 text-sm leading-6 font-semibold text-primary-high dark:text-primary-low-medium hover:text-secondary-high dark:hover:text-secondary-high hover:bg-slate-200 dark:hover:bg-primary-low duration-200",
)}
>
{/* <item.icon
className="h-6 w-6 shrink-0 text-primary-low-medium"
aria-hidden="true"
/> */}
{item.name}
<ChevronRightIcon
className={classNames(
open && "rotate-90",
"ml-auto h-5 w-5 shrink-0 text-primary-low-medium group-hover:text-secondary-high",
)}
aria-hidden="true"
/>
</Disclosure.Button>

<Disclosure.Panel as="ul" className="mt-1 pl-5 pr-2">
{item.children.map((subItem) => (
<li key={subItem.name}>
{/* 44px */}
<Link
onClick={() => setShowSideNav(false)}
href={subItem.href}
className={classNames(
subItem.href.toLowerCase() == pathname &&
"text-secondary-medium dark:!text-secondary-medium font-semibold",
"block hover:font-semibold hover:text-secondary-medium dark:hover:text-secondary-medium rounded-md my-[6px] py-[6px] pr-2 pl-4 text-sm leading-6 text-primary-high dark:text-primary-low-medium duration-200",
)}
>
{subItem.name}
</Link>
</li>
))}
</Disclosure.Panel>
</>
)}
</Disclosure>
)}
</li>
))}
</ul>
</li>
<EditOnGitHub />
</ul>
);
}
2 changes: 1 addition & 1 deletion components/navbar/SideNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function SideNav({ navigation }) {
return (
<ul
role="list"
className="sm:w-64 flex-none block rounded border border-primary-high dark:border-primary-low sm:border-none mt-4 sm:mt-12"
className="sm:w-64 hidden flex-none md:block rounded border border-primary-high dark:border-primary-low sm:border-none mt-4 sm:mt-12"
>
<li>
<ul role="list">
Expand Down
30 changes: 30 additions & 0 deletions hooks/useElementOnScreen.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useRef, useEffect, useState } from "react";

const useElementOnScreen = (options) => {
const containerRef = useRef(null);
const [isVisible, setIsVisible] = useState(false);

const callbackFunction = (entries) => {
const [entry] = entries;
setIsVisible(entry.isIntersecting);
};

useEffect(() => {
const observer = new IntersectionObserver(callbackFunction, options);
const currentRef = containerRef.current;

if (currentRef) {
observer.observe(currentRef);
}

return () => {
if (currentRef) {
observer.unobserve(currentRef);
}
};
}, [options]);

return [containerRef, isVisible];
};

export default useElementOnScreen;
48 changes: 37 additions & 11 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import ThemedImage from "@components/ThemedImage";
import { serverEnv } from "@config/schemas/serverSchema";
import { PROJECT_NAME } from "@constants/index";
import Button from "@components/Button";
import useElementOnScreen from "../hooks/useElementOnScreen.jsx";

export async function getStaticProps() {
const pageConfig = config.isr.homepage;
Expand Down Expand Up @@ -160,6 +161,12 @@ export default function Home({
},
];

const featureRefs = featuresDetails.map(() => useElementOnScreen({
root: null,
rootMargin: "0px",
threshold: 0.4,
}));

return (
<>
<PageHead />
Expand Down Expand Up @@ -275,16 +282,26 @@ export default function Home({
<div className="mt-16 mb-8 space-y-16">
{featuresDetails.map((feature, featureIdx) => (
<div
ref={featureRefs[featureIdx][0]}
key={feature.name}
className="flex flex-col-reverse lg:grid lg:grid-cols-12 lg:items-center lg:gap-x-8"
className="flex flex-col-reverse overflow-x-hidden lg:grid lg:grid-cols-12 lg:items-center lg:gap-x-8"
>
<div
className={classNames(
className={classNames(`
${
featureIdx % 2 === 0
? "lg:col-start-1"
: "lg:col-start-8 xl:col-start-9",
"mt-6 lg:mt-0 lg:row-start-1 lg:col-span-5 xl:col-span-4",
)}
? `lg:col-start-1 ${
featureRefs[featureIdx][1]
? "animate-fade-right"
: ""
}`
: `lg:col-start-8 xl:col-start-9 ${
featureRefs[featureIdx][1]
? "animate-fade-left"
: ""
}`
}
mt-6 lg:mt-0 opacity-0 lg:row-start-1 lg:col-span-5 xl:col-span-4`)}
>
<h3 className="text-lg sm:text-2xl font-bold text-primary-low">
{feature.name}
Expand All @@ -299,12 +316,21 @@ export default function Home({
)}
</div>
<div
className={classNames(
className={classNames(`
${
featureIdx % 2 === 0
? "lg:col-start-6 xl:col-start-5"
: "lg:col-start-1",
"flex-auto lg:row-start-1 lg:col-span-7 xl:col-span-8",
)}
? `lg:col-start-6 xl:col-start-5 ${
featureRefs[featureIdx][1]
? "animate-fade-left"
: ""
}`
: `lg:col-start-1 ${
featureRefs[featureIdx][1]
? "animate-fade-right"
: ""
}`
}
flex-auto lg:row-start-1 opacity-0 lg:col-span-7 xl:col-span-8`)}
>
<div className="aspect-w-5 aspect-h-2 overflow-hidden rounded-lg bg-primary-low relative">
<ThemedImage
Expand Down
72 changes: 72 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,78 @@ module.exports = {
high: "#770d14",
},
},
keyframes: {
"fade-left": {
"0%": {
opacity: "0",
transform: "translateX(100px)",
},
"100%": {
opacity: "1",
transform: "translateX(0)",
},
},
"fade-right": {
"0%": {
opacity: "0",
transform: "translateX(-100px)",
},
"100%": {
opacity: "1",
transform: "translateX(0)",
},
},
"navbar-animation": {
"0%": {
opacity: "0.7",
transform: "translateY(-10px)",
},
"100%": {
opacity: "1",
transform: "translateY(0)",

},
},
"sideBar-in": {
"0%": {
opacity: "0",
transform: "translateX(-80%)",
},
"100%": {
opacity: "1",
transform: "translateX(0)",
},
},
"sideBar-out": {
"0%": {
opacity: "1",
transform: "translateX(0)",
},
"100%": {
opacity: "0",
transform: "translateX(-80%)",
},
},
"fade-up": {
"0%": {
opacity: "0",
transform: "translateY(10px)",
},
"100%": {
opacity: "1",
transform: "translateY(0)",
},
},
},
animation: {
"fade-left": "fade-left 0.5s both",
"fade-right": "fade-right 0.5s both",
"navbar-animation": "navbar-animation 0.5s both",
"sideBar-in": "sideBar-in 0.5s both",
"sideBar-out": "sideBar-out 0.5s both",
"fade-up": "fade-up 0.5s both",
},

},
},
corePlugins: {
Expand Down
Loading