chore: update dropdown

This commit is contained in:
jinhojang6 2024-10-01 22:25:27 +09:00
parent a6b413be24
commit b131782a77
4 changed files with 213 additions and 11 deletions

View File

@ -0,0 +1,5 @@
<svg width="15" height="14" viewBox="0 0 15 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="ic:sharp-download">
<path id="Vector" d="M11.5834 5.25H9.25008V1.75H5.75008V5.25H3.41675L7.50008 9.33333L11.5834 5.25ZM3.41675 10.5V11.6667H11.5834V10.5H3.41675Z" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 293 B

View File

@ -0,0 +1,195 @@
import styled from '@emotion/styled'
import Image from 'next/image'
import { useState } from 'react'
interface Props {
operator: any
}
function updateImageUrl(inputUrl: string): string {
const urlParts = inputUrl.split('/')
if (urlParts.length > 4 && urlParts[4] === '400') {
urlParts[4] = '1024'
}
return urlParts.join('/')
}
const DownloadDropdown = ({ operator }: Props) => {
const [isOpen, setIsOpen] = useState(false)
const toggleDropdown = () => {
setIsOpen((prev) => !prev)
}
return (
<DropdownWrapper>
<DropdownButton onClick={toggleDropdown} isOpen={isOpen}>
<span>Download</span>
<ChevronIconWrapper isOpen={isOpen}>
<Image
src="/assets/chevron-down.svg"
alt="Chevron"
width={12}
height={12}
/>
</ChevronIconWrapper>
</DropdownButton>
<DropdownContent isOpen={isOpen}>
<DropdownItem href={operator.gif} download>
<Left>
<Icon>
<Image
src="/assets/download.svg"
alt="Download"
width={12}
height={12}
/>
</Icon>
<span>Low Resolution</span>
</Left>
<FileType>.gif</FileType>
</DropdownItem>
<DropdownItem href={updateImageUrl(operator.gif)} download>
<Left>
<Icon>
<Image
src="/assets/download.svg"
alt="Download"
width={12}
height={12}
/>
</Icon>
<span>High Resolution</span>
</Left>
<FileType>.gif</FileType>
</DropdownItem>
<DropdownItem href={operator.image} download>
<Left>
<Icon>
<Image
src="/assets/download.svg"
alt="Download"
width={12}
height={12}
/>
</Icon>
<span>Low Resolution</span>
</Left>
<FileType>.jpeg</FileType>
</DropdownItem>
<DropdownItem href={updateImageUrl(operator.image)} download>
<Left>
<Icon>
<Image
src="/assets/download.svg"
alt="Download"
width={12}
height={12}
/>
</Icon>
<span>High Resolution</span>
</Left>
<FileType>.jpeg</FileType>
</DropdownItem>
</DropdownContent>
</DropdownWrapper>
)
}
// Styled Components
const DropdownWrapper = styled.div`
position: relative;
display: flex;
flex-direction: column;
width: 100%;
`
const DropdownButton = styled.button<{ isOpen: boolean }>`
padding: 10px 20px;
height: 40px;
border-left: none;
border-right: 1px solid #fff !important;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
background: transparent;
position: relative;
width: 100%;
color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
& > span {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 14px;
font-weight: 400;
line-height: 20px;
letter-spacing: 0.14px;
}
`
const ChevronIconWrapper = styled.div<{ isOpen: boolean }>`
display: flex;
position: absolute;
right: 14px;
align-items: center;
justify-content: center;
transition: transform 0.3s ease;
transform: ${({ isOpen }) => (isOpen ? 'rotate(180deg)' : 'rotate(0deg)')};
`
const DropdownContent = styled.div<{ isOpen: boolean }>`
display: ${({ isOpen }) => (isOpen ? 'flex' : 'none')};
flex-direction: column;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
z-index: 1;
border-left: 1px solid #fff;
margin-left: -1px;
`
const DropdownItem = styled.a`
color: #fff !important;
padding: 12px 16px;
text-decoration: none;
display: flex;
align-items: center;
font-size: 12px;
line-height: 16px;
justify-content: space-between;
border-bottom: 1px solid #fff;
border-right: 1px solid #fff;
&:hover {
color: #fff;
}
`
const Left = styled.div`
display: flex;
align-items: center;
`
const Icon = styled.span`
margin-right: 8px;
display: flex;
align-items: center;
gap: 16px;
* {
color: #fff;
}
`
const FileType = styled.span`
font-size: 12px;
line-height: 16px;
`
export default DownloadDropdown

View File

@ -4,6 +4,7 @@ import 'lazysizes'
import React from 'react' import React from 'react'
import operators from '../../../../data/operators.json' import operators from '../../../../data/operators.json'
import { findOperatorById, processOperators } from '../../../../utils/operators' import { findOperatorById, processOperators } from '../../../../utils/operators'
import DownloadDropdown from './DownloadDropdown'
interface OperatorDetailsProps { interface OperatorDetailsProps {
id: number id: number
@ -36,10 +37,6 @@ const OperatorDetails: React.FC<OperatorDetailsProps> = ({
const operator = findOperatorById(processedOperators, id) const operator = findOperatorById(processedOperators, id)
const handleDownload = () => {
window.open(`/dashboard/mock/operators/${id % 7}.gif`, '_blank')
}
const handleShare = async () => { const handleShare = async () => {
if (navigator.share) { if (navigator.share) {
try { try {
@ -68,7 +65,7 @@ const OperatorDetails: React.FC<OperatorDetailsProps> = ({
/> />
<ActionButtons> <ActionButtons>
<Button onClick={handleShare}>Share</Button> <Button onClick={handleShare}>Share</Button>
<Button onClick={handleDownload}>Download</Button> <DownloadDropdown operator={operator} />
</ActionButtons> </ActionButtons>
</OperatorImage> </OperatorImage>
<OperatorInfo> <OperatorInfo>
@ -135,7 +132,7 @@ const Container = styled.section`
const OperatorImage = styled.div` const OperatorImage = styled.div`
position: relative; position: relative;
img { & > img {
width: 100%; width: 100%;
height: auto; height: auto;
min-height: 400px; min-height: 400px;
@ -158,17 +155,22 @@ const OperatorInfo = styled.div`
const ActionButtons = styled.div` const ActionButtons = styled.div`
display: flex; display: flex;
gap: -1px;
margin-top: 16px; margin-top: 16px;
button:first-of-type { width: 100%;
& > * {
flex: 1;
}
* > button:first-of-type {
border-right: none; border-right: none;
} }
` `
const Button = styled.button` const Button = styled.button`
flex: 1; flex: 1;
padding: 10px 40px; height: 40px;
border: 1px solid #fff; border: 1px solid #fff;
background: transparent; background: transparent;
color: #fff; color: #fff;

View File

@ -83,13 +83,13 @@ export default function App({ Component, pageProps }: AppLayoutProps) {
margin-right: auto; margin-right: auto;
} }
a, /* a,
a:visited, a:visited,
a:hover, a:hover,
a:active, a:active,
a:focus { a:focus {
color: black; color: black;
} } */
h1, h1,
h2, h2,