feat: component SelectCommon

This commit is contained in:
unknown 2021-08-26 18:08:32 +07:00
parent 7d55bbf46e
commit b35d48d248
5 changed files with 149 additions and 35 deletions

View File

@ -26,18 +26,11 @@ export default function Home() {
return ( return (
<> <>
<div>This is home page</div> <div>This is home page</div>
<ButtonCommon loading={true}>Button default</ButtonCommon>
<ButtonCommon type={ButonType.light} >{ButonType.light} - Button light</ButtonCommon>
<ButtonCommon type={ButonType.light} disabled>{ButonType.light} - Button light</ButtonCommon>
<ButtonCommon type={ButonType.light} loading = {true}>{ButonType.light} - Button light</ButtonCommon>
<ButtonCommon size={ButtonSize.large} icon={<IconBuy/>}>{ButtonSize.large} - Button default large</ButtonCommon>
<ButtonCommon icon={<IconBuy/>} disabled isIconSuffix={true}>Button with icon disabled</ButtonCommon>
<ButtonCommon icon={<IconBuy/>} type={ButonType.light}>Button with icon</ButtonCommon>
<ViewAllItem link="/all"/> <ViewAllItem link="/all"/>
<ItemWishList /> <ItemWishList />
<Logo /> <Logo />
<SelectCommon option={OPTION_SORT} placeHolder={"Sort By"}/> <SelectCommon option={OPTION_SORT}>Sort by</SelectCommon>
<SelectCommon option={OPTION_STATES} placeHolder={"States"} type="custom" size="large"/> <SelectCommon option={OPTION_STATES} size={"large"} type={"custom"}>States</SelectCommon>
</> </>
) )
} }

View File

@ -1,32 +1,81 @@
@import "../../../styles/utilities"; @import "../../../styles/utilities";
.select{ .select{
@apply rounded-lg border-solid; background-color: var(--white);
display: flex; margin-left: 2rem;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 1.2rem 1.6rem;
&.base{ &.base{
width: 18.6rem; width: 20.6rem;
height: 4.8rem; .selectTrigger{
width: 20.6rem;
padding: 1.2rem 1.6rem;
}
} }
&.large{ &.large{
width: 34.25rem; width: 34.25rem;
height: 5.6rem; .selectTrigger{
width: 34.25rem;
padding: 1.6rem 1.6rem;
}
} }
&.default{ &.default{
@apply border; .selectTrigger{
@apply border-solid border border-current;
}
}
&.custom{
.selectTrigger{
@apply border-2;
border-color: var(--border-line);
color: var(--text-label);
}
}
&.isActive{
.selectOptionWrapper{
@apply block;
}
}
}
.selectTrigger{
@apply outline-none flex justify-between;
color: var(--text-active);
border-radius: 0.8rem;
}
.selectOptionWrapper{
@apply outline-none hidden z-10 absolute;
border-radius: 0.8rem;
background-color: var(--white);
padding: 0.4rem 0rem 0.4rem 0rem;
margin-top: 0.6rem;
&.base{
width: 20.6rem;
.selectOption{
padding: 1.2rem 1.6rem;
}
}
&.large{
width: 34.25rem;
.selectOption{
padding: 1.6rem 1.6rem;
}
}
&.default{
@apply border-solid border border-current;
} }
&.custom{ &.custom{
@apply border-2; @apply border-2;
border-color: var(--border-line); border-color: var(--border-line);
color: var(--text-label); color: var(--text-label);
} }
.option{ &.active{
@apply hidden;
}
.selectOption{
&:hover{ &:hover{
background-color: black; background-color: var(--background);
} }
} }
} }

View File

@ -1,26 +1,76 @@
import s from './SelectCommon.module.scss' import s from './SelectCommon.module.scss'
import classNames from 'classnames' import classNames from 'classnames'
import { useState, useRef, useEffect } from 'react'
import { IconVectorDown } from 'src/components/icons'
interface Props { interface Props {
placeHolder? : string, children? : React.ReactNode,
size?: 'base' | 'large', size?: 'base' | 'large',
type?: 'default' | 'custom', type?: 'default' | 'custom',
option: {name: string}[], option: {name: string}[],
} }
const SelectCommon = ({ type = 'default', size = 'base', option, placeHolder }: Props) => { const SelectCommon = ({ type = 'default', size = 'base', option, children }: Props) => {
const [isActive, setActive] = useState(false)
const [selectedName, setSelectedName] = useState(children)
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
const handleClick = (event: MouseEvent) => {
const { target } = event;
if (!ref?.current || ref?.current.contains(target as Node)) {
return
}
else{
setActive(false)
}
}
document.addEventListener('click', handleClick)
return () => {
document.removeEventListener('click', handleClick)
}
}, [ref])
const changeActiveStatus = () => {
setActive(!isActive)
}
return( return(
<select className={classNames({ <>
<div className={classNames({
[s.select] : true, [s.select] : true,
[s[size]] : !!size,
[s[type]] : !!type,
[s.isActive] : isActive,
})}
onClick = { changeActiveStatus }
ref = {ref}
>
<div className={classNames({
[s.selectTrigger] : true,
})}
>{selectedName}<IconVectorDown /></div>
<div className={classNames({
[s.selectOptionWrapper] : true,
[s[type]] : !!type, [s[type]] : !!type,
[s[size]] : !!size, [s[size]] : !!size,
})} })}
> >
<option disabled selected hidden>{placeHolder}</option>
{ {
option.map(item => <option className={s.option} value={item.name}> {item.name} </option>) option.map(item =>
<div className={classNames({
[s.selectOption] : true,
[s[size]] : !!size,
})}
onClick = { () => setSelectedName(item.name)}
>{item.name}</div>
)
} }
</select> </div>
</div>
</>
) )
} }

View File

@ -0,0 +1,21 @@
const IconVectorDown = ({ ...props }) => {
return (
<svg
width="24"
height="24"
viewBox="-6 -9 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M10.9999 1.16994C10.8126 0.983692 10.5591 0.87915 10.2949 0.87915C10.0308 0.87915 9.77731 0.983692 9.58995 1.16994L5.99995 4.70994L2.45995 1.16994C2.27259 0.983692 2.01913 0.87915 1.75495 0.87915C1.49076 0.87915 1.23731 0.983692 1.04995 1.16994C0.95622 1.26291 0.881826 1.37351 0.831057 1.49537C0.780288 1.61723 0.75415 1.74793 0.75415 1.87994C0.75415 2.01195 0.780288 2.14266 0.831057 2.26452C0.881826 2.38638 0.95622 2.49698 1.04995 2.58994L5.28995 6.82994C5.38291 6.92367 5.49351 6.99806 5.61537 7.04883C5.73723 7.0996 5.86794 7.12574 5.99995 7.12574C6.13196 7.12574 6.26267 7.0996 6.38453 7.04883C6.50638 6.99806 6.61699 6.92367 6.70995 6.82994L10.9999 2.58994C11.0937 2.49698 11.1681 2.38638 11.2188 2.26452C11.2696 2.14266 11.2957 2.01195 11.2957 1.87994C11.2957 1.74793 11.2696 1.61723 11.2188 1.49537C11.1681 1.37351 11.0937 1.26291 10.9999 1.16994Z"
fill="#141414"
/>
</svg>
)
}
export default IconVectorDown

View File

@ -1,3 +1,4 @@
export { default as IconBuy } from './IconBuy' export { default as IconBuy } from './IconBuy'
export { default as IconHeart } from './IconHeart' export { default as IconHeart } from './IconHeart'
export { default as IconVector } from './IconVector' export { default as IconVector } from './IconVector'
export { default as IconVectorDown } from './IconVectorDown'