parent
9e45d0e8dd
commit
fb18608356
7 changed files with 360 additions and 1 deletions
@ -0,0 +1,97 @@ |
||||
.checkbox-symbol { |
||||
position: absolute; |
||||
width: 0; |
||||
height: 0; |
||||
pointer-events: none; |
||||
user-select: none; |
||||
} |
||||
|
||||
.checkbox-container { |
||||
box-sizing: border-box; |
||||
color: #222; |
||||
height: 30px; |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
flex-flow: row wrap; |
||||
} |
||||
|
||||
.checkbox-container * { |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
.checkbox-input { |
||||
position: absolute; |
||||
visibility: hidden; |
||||
} |
||||
|
||||
.checkbox { |
||||
user-select: none; |
||||
cursor: pointer; |
||||
padding: 6px 8px; |
||||
border-radius: 6px; |
||||
overflow: hidden; |
||||
transition: all 0.3s ease; |
||||
display: flex; |
||||
} |
||||
|
||||
.checkbox:not(:last-child) { |
||||
margin-right: 6px; |
||||
} |
||||
|
||||
.checkbox:hover { |
||||
background: inherit; |
||||
} |
||||
|
||||
.checkbox span { |
||||
vertical-align: middle; |
||||
transform: translate3d(0, 0, 0); |
||||
} |
||||
|
||||
.checkbox span:first-child { |
||||
position: relative; |
||||
flex: 0 0 18px; |
||||
width: 18px; |
||||
height: 18px; |
||||
border-radius: 4px; |
||||
transform: scale(1); |
||||
border: 1px solid #cccfdb; |
||||
transition: all 0.3s ease; |
||||
} |
||||
|
||||
.checkbox span:first-child svg { |
||||
position: absolute; |
||||
top: 3px; |
||||
left: 2px; |
||||
fill: none; |
||||
stroke: #fff; |
||||
stroke-dasharray: 16px; |
||||
stroke-dashoffset: 16px; |
||||
transition: all 0.3s ease; |
||||
transform: translate3d(0, 0, 0); |
||||
} |
||||
|
||||
.checkbox span:last-child { |
||||
padding-left: 8px; |
||||
line-height: 18px; |
||||
} |
||||
|
||||
.checkbox:hover span:first-child { |
||||
border-color: #0077ff; |
||||
} |
||||
|
||||
.checkbox-input:checked + .checkbox span:first-child { |
||||
background: #0077ff; |
||||
border-color: #0077ff; |
||||
animation: zoom-in-out 0.3s ease; |
||||
} |
||||
|
||||
.checkbox-input:checked + .checkbox span:first-child svg { |
||||
stroke-dashoffset: 0; |
||||
} |
||||
|
||||
@keyframes zoom-in-out { |
||||
50% { |
||||
transform: scale(0.9); |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
import React from "react"; |
||||
import './index.css'; |
||||
|
||||
export default function Checkbox(props) { |
||||
return ( |
||||
<div> |
||||
<svg className="checkbox-symbol"> |
||||
<symbol id="check" viewBox="0 0 12 10"> |
||||
<polyline |
||||
points="1.5 6 4.5 9 10.5 1" |
||||
strokeLinecap="round" |
||||
strokeLinejoin="round" |
||||
strokeWidth="2" |
||||
></polyline> |
||||
</symbol> |
||||
</svg> |
||||
|
||||
<div className="checkbox-container"> |
||||
<input className="checkbox-input" id="apples" type="checkbox" checked={props.checked} /> |
||||
<label className="checkbox" htmlFor="apples"> |
||||
<span> |
||||
<svg width="12px" height="10px"> |
||||
<use xlinkHref="#check"></use> |
||||
</svg> |
||||
</span> |
||||
</label> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
After Width: | Height: | Size: 229 B |
@ -0,0 +1,173 @@ |
||||
import React, { useState, useEffect } from "react"; |
||||
import searchIcon from "./search.png"; |
||||
import _ from "lodash"; |
||||
import Checkbox from "../Checkbox"; |
||||
import arrowIcon from "./arrow-top.png"; |
||||
|
||||
const langDetector = (lang = "fa", option1, option2) => { |
||||
return lang === "fa" ? option1 : option2; |
||||
}; |
||||
|
||||
export default function VerticalExpandableProductFilter(props) { |
||||
const [text, setText] = useState(""); |
||||
const [searchResult, setSearchResult] = useState([]); |
||||
useEffect(() => { |
||||
let fakeSearchResult; |
||||
fakeSearchResult = props.list.filter( |
||||
(item1) => item1.name.indexOf(text) !== -1 |
||||
); |
||||
setSearchResult(fakeSearchResult); |
||||
}, [text]); |
||||
|
||||
return ( |
||||
<div className="flex flex-col w-full border border-solid border-gray-100 rounded-md pt-6 bg-transparent max-h-screen bg-white my-3"> |
||||
<strong className="text-md text-gray-500 w-full mb-3 text-right px-3"> |
||||
{props.title} |
||||
</strong> |
||||
{props.searchAble && <form className="relative w-full px-3 mb-3"> |
||||
<input |
||||
type="text" |
||||
placeholder={_.join( |
||||
[langDetector(props.lang, "جستجو...", "Search...")], |
||||
" " |
||||
)} |
||||
className="border rounded-md py-1 px-2 w-full placeholder-gray-300 outline-none text-gray-500" |
||||
onChange={(e) => setText(e.target.value)} |
||||
/> |
||||
<span |
||||
className={_.join( |
||||
[ |
||||
"absolute inset-y-0 flex items-center", |
||||
langDetector(props.lang, "left-4", "right-4"), |
||||
], |
||||
" " |
||||
)} |
||||
> |
||||
<button |
||||
type="submit" |
||||
className="p-1 focus:outline-none focus:shadow-outline" |
||||
> |
||||
<img src={searchIcon} className="w-5 h-5" alt="" /> |
||||
</button> |
||||
</span> |
||||
</form>} |
||||
<ul className="w-full list-none flex flex-col divide-y divide-gray-100"> |
||||
{(searchResult.length > 0 ? searchResult : props.list)?.map( |
||||
(item1, i) => ( |
||||
<li |
||||
key={i} |
||||
className="hover:bg-gray-100 px-3 flex flex-row items-center justify-between py-2" |
||||
> |
||||
<div className="flex flex-row items-center"> |
||||
<Checkbox /> |
||||
<strong className="text-xs font-light text-gray-500"> |
||||
{item1.name} |
||||
</strong> |
||||
</div> |
||||
|
||||
{item1.subList?.length > 0 && ( |
||||
<img |
||||
src={arrowIcon} |
||||
alt="" |
||||
className={_.join( |
||||
[ |
||||
"cursor-pointer w-5 transform transition-all duration-300", |
||||
item1.expaneded ? "" : "rotate-180", |
||||
], |
||||
" " |
||||
)} |
||||
/> |
||||
)} |
||||
</li> |
||||
) |
||||
)} |
||||
</ul> |
||||
{props.btnTitle && <div className="flex align-center justify-center"> |
||||
<button className="my-4 bg-blueFFOP text-sm bg-opacity-40 transition-all w-4/5 py-3 px-6 rounded text-blueC0 hover:text-white hover:bg-blueC0" onClick={props.btnClicked}>{props.btnTitle}</button> |
||||
</div>} |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
VerticalExpandableProductFilter.defaultProps = { |
||||
list: [ |
||||
{ |
||||
id: 0, |
||||
name: "وسایل آشپزخانه", |
||||
expaneded: false, |
||||
subList: [], |
||||
}, |
||||
{ |
||||
id: 3, |
||||
name: "ماشین و موتور سیکلت", |
||||
expaneded: false, |
||||
subList: [ |
||||
{ |
||||
id: 4, |
||||
name: "ماشین", |
||||
}, |
||||
{ |
||||
id: 5, |
||||
name: "موتور", |
||||
}, |
||||
], |
||||
}, |
||||
{ |
||||
id: 6, |
||||
name: "اتاق خواب", |
||||
expaneded: false, |
||||
subList: [ |
||||
{ |
||||
id: 7, |
||||
name: "کمد", |
||||
}, |
||||
{ |
||||
id: 8, |
||||
name: "تخت خواب", |
||||
}, |
||||
], |
||||
}, |
||||
{ |
||||
id: 9, |
||||
name: "دکوراسیون و چیدمان", |
||||
expaneded: false, |
||||
subList: [], |
||||
}, |
||||
{ |
||||
id: 10, |
||||
name: "وسایل بهداشت شخصی", |
||||
expaneded: false, |
||||
subList: [ |
||||
{ |
||||
id: 11, |
||||
name: "مسواک", |
||||
}, |
||||
{ |
||||
id: 12, |
||||
name: "حوله", |
||||
}, |
||||
], |
||||
}, |
||||
{ |
||||
id: 13, |
||||
name: "وسایل بهداشت شخصی", |
||||
expaneded: false, |
||||
subList: [ |
||||
{ |
||||
id: 14, |
||||
name: "مسواک", |
||||
}, |
||||
{ |
||||
id: 15, |
||||
name: "حوله", |
||||
}, |
||||
], |
||||
}, |
||||
{ |
||||
id: 16, |
||||
name: "وسایل بهداشت شخصی", |
||||
expaneded: false, |
||||
subList: [], |
||||
}, |
||||
], |
||||
}; |
After Width: | Height: | Size: 857 B |
Loading…
Reference in new issue