Skip to content

animation module workshop #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
39 changes: 17 additions & 22 deletions src/components/Header/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React from 'react';
import styled from 'styled-components';

import { QUERIES, WEIGHTS } from '../../constants';
import Logo from '../Logo';
import Icon from '../Icon';
import UnstyledButton from '../UnstyledButton';
import SuperHeader from '../SuperHeader';
import MobileMenu from '../MobileMenu';
import VisuallyHidden from '../VisuallyHidden';
import React from "react";
import styled from "styled-components";

import { QUERIES } from "../../constants";
import Logo from "../Logo";
import Icon from "../Icon";
import UnstyledButton from "../UnstyledButton";
import SuperHeader from "../SuperHeader";
import MobileMenu from "../MobileMenu";
import VisuallyHidden from "../VisuallyHidden";
import NavLink from "../Navlink";

const Header = () => {
const [showMobileMenu, setShowMobileMenu] = React.useState(false);
Expand Down Expand Up @@ -81,6 +82,12 @@ const DesktopNav = styled.nav`
}
`;

const HoverDesktopNav = styled.nav`
display: none;
&:hover:

`;

const MobileActions = styled.div`
display: none;

Expand Down Expand Up @@ -114,16 +121,4 @@ const Filler = styled.div`
}
`;

const NavLink = styled.a`
font-size: 1.125rem;
text-transform: uppercase;
text-decoration: none;
color: var(--color-gray-900);
font-weight: ${WEIGHTS.medium};

&:first-of-type {
color: var(--color-secondary);
}
`;

export default Header;
99 changes: 67 additions & 32 deletions src/components/MobileMenu/MobileMenu.jsx
Original file line number Diff line number Diff line change
@@ -1,70 +1,105 @@
import React from 'react';
import styled from 'styled-components';
import * as Dialog from '@radix-ui/react-dialog';
import React from "react";
import styled, { keyframes } from "styled-components";
import * as Dialog from "@radix-ui/react-dialog";

import { QUERIES, WEIGHTS } from '../../constants';
import { QUERIES, WEIGHTS } from "../../constants";

import UnstyledButton from '../UnstyledButton';
import Icon from '../Icon';
import VisuallyHidden from '../VisuallyHidden';
import UnstyledButton from "../UnstyledButton";
import Icon from "../Icon";
import VisuallyHidden from "../VisuallyHidden";

const MobileMenu = ({ isOpen, onDismiss }) => {
return (
<Dialog.Root open={isOpen} onOpenChange={onDismiss}>
<Dialog.Portal>
<Overlay />
<Content>
<CloseButton onClick={onDismiss}>
<Icon id="close" />
<VisuallyHidden>Dismiss menu</VisuallyHidden>
</CloseButton>
<VisuallyHidden>
<Dialog.Title>Mobile navigation</Dialog.Title>
<Dialog.Description>Mobile navigation</Dialog.Description>
</VisuallyHidden>
<Filler />
<Nav>
<NavLink href="/sale">Sale</NavLink>
<NavLink href="/new">New&nbsp;Releases</NavLink>
<NavLink href="/men">Men</NavLink>
<NavLink href="/women">Women</NavLink>
<NavLink href="/kids">Kids</NavLink>
<NavLink href="/collections">Collections</NavLink>
</Nav>
<Footer>
<SubLink href="/terms">Terms and Conditions</SubLink>
<SubLink href="/privacy">Privacy Policy</SubLink>
<SubLink href="/contact">Contact Us</SubLink>
</Footer>
<Wrapper>
<CloseButton onClick={onDismiss}>
<Icon id="close" />
<VisuallyHidden>Dismiss menu</VisuallyHidden>
</CloseButton>
<VisuallyHidden>
<Dialog.Title>Mobile navigation</Dialog.Title>
<Dialog.Description>Mobile navigation</Dialog.Description>
</VisuallyHidden>
<Filler />
<Nav>
<NavLink href="/sale">Sale</NavLink>
<NavLink href="/new">New&nbsp;Releases</NavLink>
<NavLink href="/men">Men</NavLink>
<NavLink href="/women">Women</NavLink>
<NavLink href="/kids">Kids</NavLink>
<NavLink href="/collections">Collections</NavLink>
</Nav>
<Footer>
<SubLink href="/terms">Terms and Conditions</SubLink>
<SubLink href="/privacy">Privacy Policy</SubLink>
<SubLink href="/contact">Contact Us</SubLink>
</Footer>
</Wrapper>
</Content>
</Dialog.Portal>
</Dialog.Root>
);
};

const fadeIn = keyframes`
from {
opacity: 0;
}
to {
opacity: 1;
}
`;
const slideIn = keyframes`
from {
transform: translateX(100%);
}
to {
transform: translateX(0%);
}
`;

const Overlay = styled(Dialog.Overlay)`
position: fixed;
inset: 0;
background: var(--color-backdrop);
animation: ${fadeIn} 750ms;
`;

const Content = styled(Dialog.Content)`
--overfill: 16px;
position: fixed;
top: 0;
right: 0;
bottom: 0;
background: white;
width: 300px;
display: flex;
flex-direction: column;
width: calc(300px + var(--overfill));
margin-right: calc(var(--overfill) * -1);
height: 100%;
padding: 24px 32px;
background: white;

@media (prefers-reduced-motion: no-preference) {
animation: ${slideIn} 500ms both cubic-bezier(0, 0.6, 0.32, 1.06);
animation-delay: 200ms;
}
`;

const Wrapper = styled.div`
display: flex;
flex-direction: column;
height: 100%;
animation: ${fadeIn} 600ms both;
animation-delay: 400ms;
`;

const CloseButton = styled(UnstyledButton)`
position: absolute;
top: 10px;
right: 0;
right: var(--overfill);
padding: 16px;
`;

Expand Down
60 changes: 60 additions & 0 deletions src/components/Navlink/Navlink.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from "react";
import styled from "styled-components";

import { WEIGHTS } from "../../constants";

const NavLink = ({ children, ...delegated }) => {
return (
<Wrapper {...delegated}>
<MainText>{children}</MainText>
<HoverText aria-hidden={true}>{children}</HoverText>
</Wrapper>
);
};

const Wrapper = styled.a`
position: relative;
display: block;
font-size: 1.125rem;
text-transform: uppercase;
text-decoration: none;
color: var(--color-gray-900);
font-weight: ${WEIGHTS.medium};
/* Text slide-up effect */
overflow: hidden;

&:first-of-type {
color: var(--color-secondary);
}
`;

const Text = styled.span`
display: block;
transform: translateY(var(--translate-from));
transition: transform 500ms;

@media (prefers-reduced-motion: no-preference) {
${Wrapper}:hover & {
transition: transform 250ms;
transform: translateY(var(--translate-to));
}
}
`;

const MainText = styled(Text)`
--translate-from: 0%;
--translate-to: -100%;
`;

const HoverText = styled(Text)`
--translate-from: 100%;
--translate-to: 0%;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
font-weight: ${WEIGHTS.bold};
`;

export default NavLink;
1 change: 1 addition & 0 deletions src/components/Navlink/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./Navlink";
52 changes: 31 additions & 21 deletions src/components/ShoeCard/ShoeCard.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import styled from 'styled-components';
import React from "react";
import styled from "styled-components";

import { WEIGHTS } from '../../constants';
import { formatPrice, pluralize, isNewShoe } from '../../utils';
import Spacer from '../Spacer';
import { WEIGHTS } from "../../constants";
import { formatPrice, pluralize, isNewShoe } from "../../utils";
import Spacer from "../Spacer";

const ShoeCard = ({
slug,
Expand Down Expand Up @@ -36,30 +36,26 @@ const ShoeCard = ({
<Wrapper>
<ImageWrapper>
<Image alt="" src={imageSrc} />
{variant === 'on-sale' && <SaleFlag>Sale</SaleFlag>}
{variant === 'new-release' && (
<NewFlag>Just released!</NewFlag>
)}
{variant === "on-sale" && <SaleFlag>Sale</SaleFlag>}
{variant === "new-release" && <NewFlag>Just released!</NewFlag>}
</ImageWrapper>
<Spacer size={12} />
<Row>
<Name>{name}</Name>
<Price
style={{
'--color':
variant === 'on-sale'
? 'var(--color-gray-700)'
: undefined,
'--text-decoration':
variant === 'on-sale' ? 'line-through' : undefined,
"--color":
variant === "on-sale" ? "var(--color-gray-700)" : undefined,
"--text-decoration":
variant === "on-sale" ? "line-through" : undefined,
}}
>
{formatPrice(price)}
</Price>
</Row>
<Row>
<ColorInfo>{pluralize('Color', numOfColors)}</ColorInfo>
{variant === 'on-sale' ? (
<ColorInfo>{pluralize("Color", numOfColors)}</ColorInfo>
{variant === "on-sale" ? (
<SalePrice>{formatPrice(salePrice)}</SalePrice>
) : undefined}
</Row>
Expand All @@ -73,15 +69,29 @@ const Link = styled.a`
color: inherit;
`;

const Wrapper = styled.article``;
const Wrapper = styled.article`
position: relative;
`;

const ImageWrapper = styled.div`
position: relative;
border-radius: 16px 16px 4px 4px;
overflow: hidden;
`;

const Image = styled.img`
display: block;
width: 100%;
border-radius: 16px 16px 4px 4px;
transform-origin: 50% 75%;
transition: transform 500ms;
will-change: transform;
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
${Link}:hover &,
${Link}:focus & {
transform: scale(1.1);
transition: transform 200ms;
opacity: 75%;
}
}
`;

const Row = styled.div`
Expand All @@ -92,7 +102,7 @@ const Row = styled.div`

const Name = styled.h3`
font-weight: ${WEIGHTS.medium};
color: var(--color-gray-900);
color: var(--color-gray-900);\
`;

const Price = styled.span`
Expand Down