mirror of
https://github.com/vercel/commerce.git
synced 2025-07-21 03:41:22 +00:00
feat: SelectCommon
This commit is contained in:
parent
0e12b716c7
commit
807fbff177
@ -1,18 +1,28 @@
|
||||
|
||||
import { Layout } from 'src/components/common'
|
||||
import { Layout, SelectCommon } from 'src/components/common'
|
||||
import { HomeBanner, HomeCollection, HomeCTA, HomeSubscribe, HomeVideo, HomeCategories, HomeFeature, HomeRecipe } from 'src/components/modules/home';
|
||||
|
||||
const OPTION_TEST = [
|
||||
{
|
||||
name: "By Name",
|
||||
value: "Name"
|
||||
},
|
||||
{
|
||||
name: "Price (High to Low)",
|
||||
value: "Price"
|
||||
},
|
||||
{
|
||||
name: "On Sale",
|
||||
value: "Sale"
|
||||
}
|
||||
]
|
||||
const handleChange = (value:string) => {
|
||||
console.log(value)
|
||||
}
|
||||
export default function Home() {
|
||||
return (
|
||||
<>
|
||||
<HomeBanner />
|
||||
<HomeFeature />
|
||||
<HomeCategories />
|
||||
<HomeCollection />
|
||||
<HomeVideo />
|
||||
<HomeCTA />
|
||||
<HomeRecipe />
|
||||
<HomeSubscribe />
|
||||
<SelectCommon option={OPTION_TEST} placeholder="Sort By" onChange={handleChange} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -1,32 +1,81 @@
|
||||
@import "../../../styles/utilities";
|
||||
|
||||
.select{
|
||||
@apply rounded-lg border-solid;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 1.2rem 1.6rem;
|
||||
background-color: var(--white);
|
||||
&.base{
|
||||
width: 18.6rem;
|
||||
height: 4.8rem;
|
||||
width: 20.6rem;
|
||||
.selectTrigger{
|
||||
width: 20.6rem;
|
||||
padding: 1.2rem 1.6rem;
|
||||
}
|
||||
}
|
||||
&.large{
|
||||
width: 34.25rem;
|
||||
height: 5.6rem;
|
||||
.selectTrigger{
|
||||
width: 34.25rem;
|
||||
padding: 1.6rem 1.6rem;
|
||||
}
|
||||
}
|
||||
&.default{
|
||||
@apply border;
|
||||
.selectTrigger{
|
||||
@apply border-solid border border-current;
|
||||
}
|
||||
}
|
||||
&.custom{
|
||||
.selectTrigger{
|
||||
@apply border-2;
|
||||
border-color: var(--border-line);
|
||||
color: var(--text-label);
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
.hoverWrapper{
|
||||
@apply block;
|
||||
animation: SelectAnimation 0.2s ease-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
.selectTrigger{
|
||||
@apply outline-none flex justify-between;
|
||||
color: var(--text-active);
|
||||
border-radius: 0.8rem;
|
||||
|
||||
}
|
||||
.hoverWrapper{
|
||||
@apply hidden;
|
||||
padding-top: 0.6rem;
|
||||
&:hover{
|
||||
@apply block;
|
||||
}
|
||||
}
|
||||
.selectOptionWrapper{
|
||||
@apply outline-none z-10 absolute;
|
||||
border-radius: 0.8rem;
|
||||
background-color: var(--white);
|
||||
padding: 0.4rem 0rem 0.4rem 0rem;
|
||||
&.base{
|
||||
width: 20.6rem;
|
||||
}
|
||||
&.large{
|
||||
width: 34.25rem;
|
||||
}
|
||||
&.default{
|
||||
@apply border-solid border border-current;
|
||||
}
|
||||
&.custom{
|
||||
@apply border-2;
|
||||
border-color: var(--border-line);
|
||||
color: var(--text-label);
|
||||
}
|
||||
.option{
|
||||
&:hover{
|
||||
background-color: black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes SelectAnimation {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(1.6rem);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
}
|
@ -1,26 +1,54 @@
|
||||
import s from './SelectCommon.module.scss'
|
||||
import classNames from 'classnames'
|
||||
import { useState } from 'react'
|
||||
import { IconVectorDown } from 'src/components/icons'
|
||||
import SelectOption from './SelectOption/SelectOption'
|
||||
|
||||
interface Props {
|
||||
placeHolder? : string,
|
||||
placeholder? : string,
|
||||
size?: 'base' | 'large',
|
||||
type?: 'default' | 'custom',
|
||||
option: {name: string}[],
|
||||
option: {name: string, value: string}[],
|
||||
onChange?: (value: string) => void,
|
||||
}
|
||||
|
||||
const SelectCommon = ({ type = 'default', size = 'base', option, placeHolder }: Props) => {
|
||||
const SelectCommon = ({ type = 'default', size = 'base', option, placeholder, onChange }: Props) => {
|
||||
const [selectedName, setSelectedName] = useState(placeholder)
|
||||
|
||||
const changeSelectedName = (item:string, value: string) => {
|
||||
setSelectedName(item)
|
||||
onChange && onChange(value)
|
||||
}
|
||||
return(
|
||||
<select className={classNames({
|
||||
[s.select] : true,
|
||||
[s[type]]: !!type,
|
||||
[s[size]]: !!size,
|
||||
})}
|
||||
>
|
||||
<option disabled selected hidden>{placeHolder}</option>
|
||||
{
|
||||
option.map(item => <option className={s.option} value={item.name}> {item.name} </option>)
|
||||
}
|
||||
</select>
|
||||
<>
|
||||
<div className={classNames({
|
||||
[s.select] : true,
|
||||
[s[size]] : !!size,
|
||||
[s[type]] : !!type,
|
||||
})}
|
||||
>
|
||||
<div className={classNames({
|
||||
[s.selectTrigger] : true,
|
||||
|
||||
})}
|
||||
>{selectedName}<IconVectorDown /></div>
|
||||
<div className={s.hoverWrapper}>
|
||||
<div className={classNames({
|
||||
[s.selectOptionWrapper] : true,
|
||||
[s[type]] : !!type,
|
||||
[s[size]] : !!size,
|
||||
})}
|
||||
>
|
||||
{
|
||||
option.map(item =>
|
||||
<SelectOption itemName={item.name} value={item.value} onClick={changeSelectedName} size={size} selected={(selectedName === item.name) ? true : false} />
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,20 @@
|
||||
@import "../../../../styles/utilities";
|
||||
|
||||
.selectOption {
|
||||
@apply outline-none;
|
||||
background-color: var(--white);
|
||||
&.base{
|
||||
width: 20.4rem;
|
||||
padding: 0.8rem 1.6rem;
|
||||
}
|
||||
&.large{
|
||||
width: 33.75rem;
|
||||
padding: 0.8rem 1.6rem;
|
||||
}
|
||||
&:hover{
|
||||
background-color: var(--gray);
|
||||
}
|
||||
&.isChoose{
|
||||
background-color: var(--gray);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
import s from './SelectOption.module.scss'
|
||||
import classNames from 'classnames'
|
||||
import { useState } from 'react'
|
||||
|
||||
interface Props{
|
||||
onClick: (name: string, value: string) => void,
|
||||
itemName: string,
|
||||
size: 'base' | 'large',
|
||||
value: string,
|
||||
selected?: boolean,
|
||||
}
|
||||
|
||||
const SelectOption = ({onClick, itemName, size, value, selected} : Props) => {
|
||||
const changeName = () => {
|
||||
onClick(itemName, value)
|
||||
}
|
||||
return(
|
||||
<div className={classNames({
|
||||
[s.selectOption] : true,
|
||||
[s[size]] : !!size,
|
||||
[s.isChoose] : selected ,
|
||||
})}
|
||||
onClick = {changeName}
|
||||
>{itemName}</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SelectOption
|
19
src/components/icons/IconVectorDown.tsx
Normal file
19
src/components/icons/IconVectorDown.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
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
|
@ -15,3 +15,4 @@ export { default as IconApple } from './IconApple'
|
||||
export { default as ArrowLeft } from './ArrowLeft'
|
||||
export { default as ArrowRight } from './ArrowRight'
|
||||
export { default as Close } from './Close'
|
||||
export { default as IconVectorDown} from './IconVectorDown'
|
Loading…
x
Reference in New Issue
Block a user