Skip to content

Commit

Permalink
feat(blog): tagMenu 컴포넌트 구현 #37
Browse files Browse the repository at this point in the history
  • Loading branch information
nyeoni committed Apr 24, 2022
1 parent a81898f commit 552c539
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 0 deletions.
43 changes: 43 additions & 0 deletions packages/blog/components/TagMenu/TagMenu.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react'
import { ComponentMeta, ComponentStory } from '@storybook/react'
import TagMenu from './TagMenu'

export default {
title: 'Components/TagMenu',
component: TagMenu,
parameters: {
layout: 'fullscreen',
},
} as ComponentMeta<typeof TagMenu>

const Template: ComponentStory<typeof TagMenu> = (args) => (
<div style={{ padding: '20px 30px' }}>
<TagMenu {...args} />
</div>
)

export const Default = Template.bind({})
Default.args = {
tags: [
'ALL',
'javascript',
'typescript',
'react',
'vue',
'Angular',
'Node',
'Express',
'MongoDB',
'MySQL',
'PostgreSQL',
'SQL',
'NoSQL',
'GraphQL',
'Apollo',
'Gatsby',
'Next',
'Git',
'GitHub',
'GitLab',
],
}
63 changes: 63 additions & 0 deletions packages/blog/components/TagMenu/TagMenu.styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import styled from 'styled-components'

const Styled = {
container: styled.div`
position: relative;
width: 100%;
height: 65px;
background-color: ${({ theme }) => theme.color.grey200};
border-radius: 7px;
`,
scrollbar: styled.div`
position: relative;
z-index: 1;
display: flex;
width: 100%;
height: 100%;
padding: 16px 20px;
overflow-x: scroll;
column-gap: 9px;
scroll-behavior: smooth;
-ms-overflow-style: none;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
`,
leftShadow: styled.div`
position: absolute;
top: 0;
left: 0;
z-index: 2;
width: 100%;
height: 100%;
border-radius: 7px 0 0 7px;
box-shadow: inset 7px 0 9px -7px rgba(0, 0, 0, 0.4);
pointer-events: none;
`,
rightShadow: styled.div`
position: absolute;
top: 0;
right: 0;
z-index: 2;
width: 100%;
height: 100%;
border-radius: 0px 7px 7px 0;
box-shadow: inset -7px 0 9px -7px rgba(0, 0, 0, 0.4);
pointer-events: none;
`,
}

export default Styled
60 changes: 60 additions & 0 deletions packages/blog/components/TagMenu/TagMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useEffect, useState, useRef, useCallback } from 'react'
import { theme } from '../../styles/theme'
import Tag from '../Tag/Tag'
import Styled from './TagMenu.styled'

export interface TagMenuProps {
tags: string[]
}

type edgeType = 'left' | 'right' | 'both' | 'none'

const TagMenu: React.FC<TagMenuProps> = ({ tags }) => {
const scrollRef = useRef<any>()
const [edge, setEdge] = useState<edgeType>('none')
const [selectedTag, setSelectedTag] = useState(0)
const activeStyle = {
color: theme.color.white,
backgroundColor: theme.color.main,
}

const handleEdge = useCallback(
({ scrollLeft, scrollWidth, clientWidth }: { scrollLeft: number; scrollWidth: number; clientWidth: number }) => {
const scrollRange = scrollWidth - clientWidth
if (scrollRange === 0) setEdge('none')
else if (scrollLeft === 0) setEdge('right')
else if (scrollLeft === scrollRange) setEdge('left')
else setEdge('both')
},
[]
)

useEffect(() => {
handleEdge(scrollRef.current)
}, [handleEdge, scrollRef])

const onTagMenuScroll = (e: React.UIEvent<HTMLElement>) => {
handleEdge(e.currentTarget)
e.stopPropagation()
}

return (
<Styled.container>
{edge === 'left' || edge === 'both' ? <Styled.leftShadow /> : <></>}
{edge === 'right' || edge === 'both' ? <Styled.rightShadow /> : <></>}
<Styled.scrollbar ref={scrollRef} onScroll={onTagMenuScroll}>
{tags.map((tag, idx) => (
<Tag
key={idx}
name={tag}
onClick={(e) => setSelectedTag(idx)}
view={'menu'}
style={selectedTag === idx ? activeStyle : {}}
/>
))}
</Styled.scrollbar>
</Styled.container>
)
}

export default TagMenu
2 changes: 2 additions & 0 deletions packages/blog/components/TagMenu/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './TagMenu'
export type { TagMenuProps } from './TagMenu'

0 comments on commit 552c539

Please sign in to comment.