Skip to content
Merged
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
2 changes: 1 addition & 1 deletion public/page-data/index/page-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"componentChunkName": "component---src-pages-index-js",
"path": "/",
"result": {"pageContext":{}},
"staticQueryHashes": ["1128713364","1279924571","1292738615","1693928026","176670904","1868451474","1921816282","2499611023","2898073905","416013508","770242822","882490824"]}
"staticQueryHashes": ["1128713364","1279924571","1292738615","1693928026","176670904","1868451474","2499611023","2898073905","3298386516","416013508","651390938","770242822","882490824"]}
158 changes: 158 additions & 0 deletions src/components/NavBar/AnimatedNavBar/AnimatedNavbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import React, { useState } from "react"
import Navbar from "./Navbar"
import NavbarItem from "./Navbar/NavbarItem"
import { Flipper } from "react-flip-toolkit"
import DropdownContainer from "./DropdownContainer"
import Dropdown from "./DropdownContainer/Dropdown"

const getComponentTitle = component => {
// falta definir los titulos para cada componente y arreglar los vinculos internos
const titleReference = {
"home.hero": () => "Bitlogic",
"components.banner-list": () => "Dual section",
"components.selected-grid": () => "Selected grid",
"components.cases-section": () => " Cases section",
"home.quote": () => "Quote",
"home.video-background": () => "Video background",
"home.dual-section": () => "Dual section",
}
return (
(titleReference[component.strapi_component] &&
titleReference[component.strapi_component]()) ||
"Titulo no definido"
)
}

const AnimatedNavbar = ({
homeComponents,
landingComponents,
navbarItems,
duration,
}) => {
const navbarConfig = [
{
title: "Home",
slug: "",
dropdown: () => (
<Dropdown
sections={homeComponents
.filter(
component => component.strapi_component !== "home.transition"
)
.map(component => ({
name: getComponentTitle(component),
href: "#" + component.strapi_component + "-" + component.id,
}))}
/>
),
},
...navbarItems.map(navItem => {
if (navItem.landing) {
return {
title: navItem.label,
slug: navItem.landing.slug,
dropdown: () => (
<Dropdown
sections={landingComponents
.find(landing => landing.name === navItem.landing.name)
.body.map(component => ({
name: getComponentTitle(component),
href:
"/" +
navItem.landing.slug +
"#" +
component.strapi_component +
"-" +
component.id,
}))}
/>
),
}
} else if (navItem.url) {
return {
title: navItem.label,
slug: navItem.url,
dropdown: () => <Dropdown sections={[]} />,
}
}
}),
]

const [activeIndex, setActiveIndex] = useState([])
const [animationOut, setAnimationOut] = useState(null)

const [animatingOutTimeout, setAnimatingOutTimeout] = useState(null)

const resetDropdownState = i => {
setActiveIndex(typeof i === "number" ? [i] : [])
setAnimationOut(false)

setAnimatingOutTimeout(null)
}

const onMouseEnter = i => {
if (animatingOutTimeout) {
clearTimeout(animatingOutTimeout)
resetDropdownState(i)
return
}
if (activeIndex[activeIndex.length - 1] === i) return

setActiveIndex(prev => prev.concat(i))
setAnimationOut(false)
}

const onMouseLeave = () => {
setAnimationOut(true)
setAnimatingOutTimeout(setTimeout(resetDropdownState, duration))
}

let CurrentDropdown
let PrevDropdown
let direction

const currentIndex = activeIndex[activeIndex.length - 1]
const prevIndex =
activeIndex.length > 1 && activeIndex[activeIndex.length - 2]

if (typeof currentIndex === "number")
CurrentDropdown = navbarConfig[currentIndex].dropdown
if (typeof prevIndex === "number") {
PrevDropdown = navbarConfig[prevIndex].dropdown
direction = currentIndex > prevIndex ? "right" : "left"
}

return (
<Flipper
flipKey={currentIndex}
spring={duration === 300 ? "noWobble" : { stiffness: 10, damping: 10 }}
>
<Navbar onMouseLeave={onMouseLeave}>
{navbarConfig.map((n, index) => {
return (
<NavbarItem
to={"/" + n.slug}
key={n.title}
title={n.title}
index={index}
onMouseEnter={onMouseEnter}
>
{currentIndex === index && (
<DropdownContainer
direction={direction}
animatingOut={animationOut}
duration={duration}
>
<CurrentDropdown />
{PrevDropdown && <PrevDropdown />}
</DropdownContainer>
)}
</NavbarItem>
)
})}
</Navbar>
</Flipper>
)
}

export default AnimatedNavbar
23 changes: 23 additions & 0 deletions src/components/NavBar/AnimatedNavBar/DropdownContainer/Dropdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react"
import "./dropdown.scss"

const Dropdown = ({ sections }) => {
return (
<div className="dropdown_elem">
<div className="dropdown_elem-section" data-first-dropdown-section>
<ul>
{sections &&
sections.map(section => (
<p className="dropdown_elem-link">
<a href={section.href}>{section.name}</a>
</p>
))}
</ul>
</div>
</div>
)
}



export default Dropdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { forwardRef } from "react"
import PropTypes from "prop-types"

const FadeContents = forwardRef(
({ children, animatingOut, direction }, ref) => (
<div
// prevent screen readers from reading out hidden content
aria-hidden={animatingOut}
ref={ref}
style={{
opacity: direction && !animatingOut ? 0 : 1,
animationName: animatingOut ? "fade-backward" : "fade-forward",
}}
className="fade_content"
>
{children}
</div>
)
)

const propTypes = {
duration: PropTypes.number,
direction: PropTypes.oneOf(["right", "left"]),
animatingOut: PropTypes.bool,
children: PropTypes.node,
}

FadeContents.propTypes = propTypes

export default FadeContents
108 changes: 108 additions & 0 deletions src/components/NavBar/AnimatedNavBar/DropdownContainer/dropdown.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
.dropdown {
&_elem {
width: 18.5rem;
&-section {
padding: 28px;
position: relative;
z-index: 1;
}
&-link {
text-transform: uppercase;
font-size: 18px;
margin-top: 0;
margin-bottom: 1rem;
}
}
}

.promote_layer {
will-change: transform;
}

.fade_content {
@extend .promote_layer;
animation-duration: 300ms;
animation-fill-mode: forwards;
top: 0;
left: 0;
}

@keyframes fade-forward {
to {
transform: translateX(0px);
opacity: 1;
}
}

@keyframes fade-backward {
to {
transform: translateX(0px);
opacity: 0;
}
}

.dropdown_root {
transform-origin: 0 0;
@extend .promote_layer;
animation-duration: 300ms;
animation-fill-mode: forwards;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
top: -20px;
&-background {
transform-origin: 0 0;
background-color: white;
border-radius: 4px;
overflow: hidden;
position: relative;
box-shadow: 0 50px 100px rgba(50, 50, 93, 0.1);
margin-top: 10px;
@extend .promote_layer;
&-alt {
background-color: #f1f4f8b0;
width: 300%;
height: 100%;
position: absolute;
top: 0;
left: -100%;
transform-origin: 0 0;
z-index: 0;
transition: transform 300ms;
}
}
&-inverted {
@extend .promote_layer;
top: 0;
left: 0;
&:first-of-type {
z-index: 1;
}
&:not(:first-of-type) {
z-index: -1;
}
}
}

@keyframes dropdown_root-forward {
from {
transform: rotateX(-15deg);
opacity: 0;
}
to {
transform: rotateX(0);
opacity: 1;
}
}

@keyframes dropdown_root-backward {
from {
transform: rotateX(0);
opacity: 1;
}
to {
transform: rotateX(-15deg);
opacity: 0;
}
}
Loading