Skip to content

Commit

Permalink
Merge pull request #2 from tannguyencse19/v0.0.1
Browse files Browse the repository at this point in the history
Update to V0.0.1
  • Loading branch information
tannguyencse19 authored Jan 3, 2022
2 parents 6e7ea44 + fac4c51 commit bc97f44
Show file tree
Hide file tree
Showing 11 changed files with 511 additions and 85 deletions.
85 changes: 53 additions & 32 deletions components/common/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,43 @@
import {
Divider,
Grid,
Box,
Text,
useColorModeValue,
Center,
} from "@chakra-ui/react";
import NextImage from "next/image";
import { motion } from "framer-motion";
import NextLink from "next/link";
import { useRouter } from "next/router";
import React from "react";
import { nav } from "utils";
import {
_afterUnderlineStyle,
_sxHoverAfterUnderlineStyle,
RotateWithZoomVariantProps,
routerShallowPush,
} from "@/components/helper";

const logoVariants: RotateWithZoomVariantProps = {
visible: {
rotate: [0, 360],
transition: { duration: 2, ease: "linear", repeat: Infinity }, // for rotate
},
hover: {
scale: 1.3,
},
// for hover
hoverTransition: {
duration: 1,
ease: "linear",
},
};

// console.log(nav._bordorColor);
export interface NavbarProps {}

export const Navbar = ({}: NavbarProps) => {
const router = useRouter();


return (
<Grid
autoFlow="column"
Expand All @@ -28,13 +48,33 @@ export const Navbar = ({}: NavbarProps) => {
tablet: "0 0 0 24px",
desktop: "20px 22.5px", // py px
}}

>
<NextImage
{/* Ko dung vi logo size nho
<motion.div
variants={logoVariants}
animate="visible"
whileHover="hover"
transition={logoVariants.hoverTransition}
>
<NextImage
src="/assets/shared/logo.svg"
alt="logo"
width="48"
height="48"
/>
</motion.div> */}
<motion.img
src="/assets/shared/logo.svg"
alt="logo"
width="48"
height="48"
layout="fixed"
variants={logoVariants}
animate="visible"
whileHover="hover"
transition={logoVariants.hoverTransition}
onClick={() => routerShallowPush(router, "/")}
style={{
cursor: "pointer",
}}
/>

<Grid
Expand All @@ -52,17 +92,16 @@ export const Navbar = ({}: NavbarProps) => {
<Center
key={`nav-${name}`}
position="relative"
_after={_afterUnderlineStyle(
router.pathname === `/${name}` ||
(router.pathname === `/` && name === "home")
)}
// https://github.com/chakra-ui/chakra-ui/discussions/5306
sx={{
"&:hover hr": {
borderBottom: `2px solid ${nav._bordorColor?.hover}`,
transform: "scaleX(1) !important",
mixBlendMode: "normal",
opacity: "0.5",
},
"&:hover:after": _sxHoverAfterUnderlineStyle(),
}}
>
<NextLink href={`/${name}`} as={name === "home" ? "/" : undefined}>
<NextLink href={name === "home" ? "/" : `/${name}`}>
<a>
<Text
{...nav.return()}
Expand All @@ -76,24 +115,6 @@ export const Navbar = ({}: NavbarProps) => {
</Text>
</a>
</NextLink>
<Divider
{...(router.pathname === name || name === "home"
? {
opacity: "1",
borderBottom: `2px solid ${nav._bordorColor?.active}`,
transform: "scaleX(1)",
}
: {
opacity: "0.5",
borderBottom: `2px solid ${nav._bordorColor?.hover}`,
transform: "scaleX(0)",
})}
position="absolute"
bottom="0"
overflow="hidden"
transition="transform 275ms ease"
aria-hidden="true"
/>
</Center>
))}
<Divider
Expand Down
113 changes: 113 additions & 0 deletions components/helper/DynamicStyle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { CSSObject } from "@chakra-ui/react";
import { nav } from "utils";

/**
* @description CSSStyleObject for `_after, ::after` pseudo-element
* @param condition Condition to generate underline
* @returns
*
* _**NOTES**_
*
* * Element contain `_after` must have style: `position: relative`
* @example
* ```jsx
* <Box
* position="relative"
* _after={_afterUnderlineStyle(your_condition)}
* >
* ```
*
* * To display animation, use `:hover:after` with `_sxHoverAfterUnderlineStyle`. See below.
*
* ---
* * Basic usage
* @example
* ```jsx
* _after={_afterUnderlineStyle(your_condition)}
* ```
* * Extend/Override style. If overrideStyle don't work, try to use `!important`
* @example
* ```jsx
* _after={_afterUnderlineStyle(your_condition, {
* transition: "transform 1s ease-in-out !important",
* })}
* ```
*
* * Animation
* @example
* ```jsx
* _after={_afterUnderlineStyle(your_condition)}
* sx={{
* "&:hover:after": _sxHoverAfterUnderlineStyle()
* }}
* ```
*/
export function _afterUnderlineStyle(
condition: boolean,
overrideStyle?: CSSObject
) {
const baseStyle: CSSObject = {
content: `""`,
width: "100%",
height: "2px",
position: "absolute",
bottom: "0",
overflow: "hidden",
transition: "transform 275ms ease",
};
const conditionStyle: CSSObject = condition
? {
// active state
opacity: "1",
backgroundColor: nav._bordorColor?.active,
transform: "scaleX(1)",
}
: {
// hover state
opacity: "0.5",
backgroundColor: nav._bordorColor?.hover,
transform: "scaleX(0)",
};

return Object.assign(baseStyle, conditionStyle, overrideStyle);
}

/**
* @description Animation for `_afterUnderlineStyle()`
* @returns CSSObject
*
* ---
*
* * Basic usage
* @example
* ```jsx
* _after={_afterUnderlineStyle(your_condition)}
* sx={{
* "&:hover:after": _sxHoverAfterUnderlineStyle()
* }}
* ```
*
* * Extend/Override style. If overrideStyle don't work, try to use `!important`
* @example
* ```jsx
* "&:hover:after": _sxHoverAfterUnderlineStyle({
* transform: "unset",
transformOrigin: "0% 50% !important",
* })
* ```
*
* ---
*
* Animation example
* @see https://stackoverflow.com/questions/28623446/hover-effect-expand-bottom-border
*/
export function _sxHoverAfterUnderlineStyle(overrideStyle?: CSSObject) {
const baseStyle = {
backgroundColor: nav._bordorColor?.hover,
transform: "scaleX(1) !important",
mixBlendMode: "normal",
opacity: "0.5",
};

return Object.assign(baseStyle, overrideStyle);
}
64 changes: 64 additions & 0 deletions components/helper/FramerMotionHelper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Variant } from "framer-motion";

// type Merge<P, T> = Omit<P, keyof T> & T;

// type BoxMotionProps = Merge<BoxProps, HTMLMotionProps<"div">>;
// export const BoxMotion: React.FC<BoxMotionProps> = motion(Box);

/**
* @description Strengthen _framer-motion_ `Variants, Variant` type
* @example
* ```jsx
* const boxVariants: CustomVariantsProps = {
* // syntax --> key_name: { properties }
* hidden: { transform: "translateY(25%)", opacity: 0 },
* visible: {
* transform: "translateY(0%)",
* opacity: 1,
* transition: { duration: 1.5, ease: "linear" },
* },
* };
* ```
*/
export interface CustomVariantsProps {
[key: string]: Variant | any;
}

/**
* @description Use to create Rotate with Zoom animation
*
* * Defining
* @example
* ```jsx
* const planetVariant: RotateWithZoomVariantProps = {
* visible: {
* rotate: [0, 360],
* transition: { duration: 60, ease: "linear", repeat: Infinity }, // for rotate
* },
* hover: {
* scale: 1.1,
* },
* // for hover
* hoverTransition: {
* duration: 0.6,
* ease: "easeOut",
* },
* };
* ```
*
* * Usage
* @example
* ```jsx
* <motion.div
* variants={planetVariant}
* animate="visible"
* whileHover="hover"
* transition={planetVariant.hoverTransition}
* >
* ```
*/
export interface RotateWithZoomVariantProps extends CustomVariantsProps {
visible: Variant;
hover: Variant;
hoverTransition: Variant | any;
}
37 changes: 37 additions & 0 deletions components/helper/NextHelper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { chakra, shouldForwardProp } from "@chakra-ui/react";
import NextLink from "next/link";
import { NextRouter } from "next/router";

export const NextLinkHelper = chakra(NextLink, {
shouldForwardProp: (prop) => {
// don't forward Chakra's props
const isChakraProp = !shouldForwardProp(prop);
if (isChakraProp) return false;

// else, only forward `sample` prop
return [
"href",
"as",
"replace",
"scroll",
"shallow",
"passHref",
"prefetch",
"locale",
].includes(prop);
},
});

// https://stackoverflow.com/questions/43335962/purpose-of-declare-keyword-in-typescript
// Summary: declare fix loi bien nay da khai bao roi --> khai bao lai
declare type Url = URL | string;

/**
* Strengthen original router.push()
* @param router Component's current using router
* @param url
* @returns `router.push(url, undefined, { shallow: true })`
*/
export function routerShallowPush(router: NextRouter, url: Url) {
return router.push(url, undefined, { shallow: true });
}
22 changes: 0 additions & 22 deletions components/helper/NextLinkHelper.tsx

This file was deleted.

10 changes: 0 additions & 10 deletions components/helper/framer-motion/index.ts

This file was deleted.

5 changes: 3 additions & 2 deletions components/helper/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./NextLinkHelper"
export * from "./framer-motion"
export * from "./NextHelper"
export * from "./FramerMotionHelper"
export * from "./DynamicStyle"
2 changes: 1 addition & 1 deletion pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import '../styles/globals.css'
import "../styles/globals.css";
import type { AppProps } from "next/app";
import { ChakraProvider } from "@chakra-ui/react";
import { theme } from "utils";
Expand Down
Loading

1 comment on commit bc97f44

@vercel
Copy link

@vercel vercel bot commented on bc97f44 Jan 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.