@ -0,0 +1,10 @@ |
|||||||
|
module.exports = { |
||||||
|
style: { |
||||||
|
postcss: { |
||||||
|
plugins: [ |
||||||
|
require('tailwindcss'), |
||||||
|
require('autoprefixer'), |
||||||
|
], |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
import React from "react"; |
||||||
|
import './index.scss'; |
||||||
|
|
||||||
|
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" |
||||||
|
stroke-linecap="round" |
||||||
|
stroke-linejoin="round" |
||||||
|
stroke-width="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> |
||||||
|
); |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 860 B |
@ -0,0 +1,162 @@ |
|||||||
|
import React, { useState } from "react"; |
||||||
|
import _ from "lodash"; |
||||||
|
import "./index.scss"; |
||||||
|
|
||||||
|
import tick from "./tick.png"; |
||||||
|
import danger from "./danger.png"; |
||||||
|
|
||||||
|
const langDetector = (lang, option1, option2) => { |
||||||
|
return lang === "fa" ? option1 : option2; |
||||||
|
}; |
||||||
|
|
||||||
|
const inputStatusHandler = (value, focus, status, primary, success, danger) => { |
||||||
|
if (!focus) { |
||||||
|
return ""; |
||||||
|
} else { |
||||||
|
if (!value) { |
||||||
|
return primary; |
||||||
|
} else { |
||||||
|
if (status) { |
||||||
|
return success; |
||||||
|
} else { |
||||||
|
return danger; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
export default function Input(props) { |
||||||
|
const [value, setValue] = useState(""); |
||||||
|
const [focusToggle, setFocusToggle] = useState(false); |
||||||
|
|
||||||
|
const { lang, theme, inputMode, label, status, maxLength, message } = props; |
||||||
|
|
||||||
|
const onChange = (val) => { |
||||||
|
setValue(val); |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<div |
||||||
|
className={_.join( |
||||||
|
["input flex flex-col relative mb-6", langDetector(lang, "fa", "en")], |
||||||
|
" " |
||||||
|
)} |
||||||
|
> |
||||||
|
<label |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"absolute top-1/2 transform -translate-y-1/2 text-gray-500 bg-white px-2 text-xs transition-all duration-300", |
||||||
|
langDetector(lang, "right-2", "left-2"), |
||||||
|
inputStatusHandler( |
||||||
|
value, |
||||||
|
focusToggle, |
||||||
|
status, |
||||||
|
"input__labelFocus", |
||||||
|
"input__labelSuccess", |
||||||
|
"input__labelDanger" |
||||||
|
), |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
onClick={() => setFocusToggle(true)} |
||||||
|
> |
||||||
|
{label} |
||||||
|
</label> |
||||||
|
<input |
||||||
|
type="text" |
||||||
|
inputMode={inputMode} |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"flex-1 border rounded-sm outline-none p-2", |
||||||
|
inputStatusHandler( |
||||||
|
value, |
||||||
|
focusToggle, |
||||||
|
status, |
||||||
|
"input__inputActive", |
||||||
|
"input__inputSuccess", |
||||||
|
"input__inputDanger" |
||||||
|
), |
||||||
|
"transition", |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
onChange={(e) => onChange(e.target.value)} |
||||||
|
value={value} |
||||||
|
onFocus={() => setFocusToggle(true)} |
||||||
|
onBlur={() => !value ? setFocusToggle(false) : setFocusToggle(true)} |
||||||
|
maxLength={maxLength} |
||||||
|
/> |
||||||
|
{!status && value && ( |
||||||
|
<img |
||||||
|
src={danger} |
||||||
|
alt={langDetector(lang, "اشتباه", "wrong")} |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"w-4 h-4 absolute top-1/2 transform -translate-y-1/2", |
||||||
|
langDetector(lang, "left-2", "right-2"), |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
/> |
||||||
|
)} |
||||||
|
{status && value && ( |
||||||
|
<img |
||||||
|
src={tick} |
||||||
|
alt={langDetector(lang, "درست", "right")} |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"w-4 h-4 absolute top-1/2 transform -translate-y-1/2", |
||||||
|
langDetector(lang, "left-2", "right-2"), |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
/> |
||||||
|
)} |
||||||
|
|
||||||
|
{value && !status && ( |
||||||
|
<span |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"input__message text-xs absolute -bottom-5", |
||||||
|
langDetector(lang, "right-2", "left-2"), |
||||||
|
inputStatusHandler( |
||||||
|
value, |
||||||
|
focusToggle, |
||||||
|
status, |
||||||
|
"", |
||||||
|
"input__messageSuccess", |
||||||
|
"input__messageDanger" |
||||||
|
), |
||||||
|
"transition", |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
> |
||||||
|
{message} |
||||||
|
</span> |
||||||
|
)} |
||||||
|
{value && ( |
||||||
|
<span |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"input__length absolute -bottom-5 text-xs", |
||||||
|
langDetector(lang, "left-2", "right-2"), |
||||||
|
inputStatusHandler( |
||||||
|
value, |
||||||
|
focusToggle, |
||||||
|
status, |
||||||
|
"", |
||||||
|
"input__lengthSuccess", |
||||||
|
"input__lengthDanger" |
||||||
|
), |
||||||
|
"transition", |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
> |
||||||
|
{value.length + "/" + maxLength} |
||||||
|
</span> |
||||||
|
)} |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
$primary: #06BACE; |
||||||
|
$gray: #dbdbdb; |
||||||
|
$danger: #E00A0A; |
||||||
|
$success: #23C933; |
||||||
|
|
||||||
|
.input { |
||||||
|
&__labelFocus{ |
||||||
|
top: 0px !important; |
||||||
|
font-size: 9px !important; |
||||||
|
color: $primary !important; |
||||||
|
} |
||||||
|
&__labelDanger{ |
||||||
|
top: 0px !important; |
||||||
|
font-size: 9px !important; |
||||||
|
color: $danger !important; |
||||||
|
} |
||||||
|
&__labelSuccess{ |
||||||
|
top: 0px !important; |
||||||
|
font-size: 9px !important; |
||||||
|
color: $success !important; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
&__inputActive{ |
||||||
|
border-color: $primary !important; |
||||||
|
} |
||||||
|
&__inputSuccess{ |
||||||
|
border-color: $success !important; |
||||||
|
} |
||||||
|
&__inputDanger{ |
||||||
|
border-color: $danger !important; |
||||||
|
} |
||||||
|
|
||||||
|
&__message{ |
||||||
|
&Success{ |
||||||
|
color: $success; |
||||||
|
} |
||||||
|
&Danger{ |
||||||
|
color: $danger; |
||||||
|
} |
||||||
|
} |
||||||
|
&__length{ |
||||||
|
&Success{ |
||||||
|
color: $success; |
||||||
|
} |
||||||
|
&Danger{ |
||||||
|
color: $danger; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.en { |
||||||
|
direction: ltr; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
.fa { |
||||||
|
direction: rtl; |
||||||
|
text-align: right; |
||||||
|
} |
After Width: | Height: | Size: 411 B |
@ -0,0 +1,13 @@ |
|||||||
|
import React from "react"; |
||||||
|
import './index.scss'; |
||||||
|
|
||||||
|
export default function Radio(props) { |
||||||
|
return ( |
||||||
|
<div className="container"> |
||||||
|
<div className="radio flex items-center"> |
||||||
|
<input id="radio-1" name={props.name} type="radio" /> |
||||||
|
<label htmlFor="radio-1" className="radio-label text-xs">{props.label}</label> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
$color1: #f4f4f4; |
||||||
|
$color2: #3197EE; |
||||||
|
|
||||||
|
.radio { |
||||||
|
input[type="radio"] { |
||||||
|
position: absolute; |
||||||
|
opacity: 0; |
||||||
|
+ .radio-label { |
||||||
|
&:before { |
||||||
|
content: ''; |
||||||
|
background: $color1; |
||||||
|
border-radius: 100%; |
||||||
|
border: 1px solid darken($color1, 25%); |
||||||
|
display: inline-block; |
||||||
|
width: 1.4em; |
||||||
|
height: 1.4em; |
||||||
|
position: relative; |
||||||
|
vertical-align: top; |
||||||
|
margin-left: 0.5em; |
||||||
|
cursor: pointer; |
||||||
|
text-align: center; |
||||||
|
transition: all 250ms ease; |
||||||
|
} |
||||||
|
} |
||||||
|
&:checked { |
||||||
|
+ .radio-label { |
||||||
|
&:before { |
||||||
|
background-color: $color2; |
||||||
|
box-shadow: inset 0 0 0 4px $color1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
&:focus { |
||||||
|
+ .radio-label { |
||||||
|
&:before { |
||||||
|
outline: none; |
||||||
|
border-color: $color2; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
&:disabled { |
||||||
|
+ .radio-label { |
||||||
|
&:before { |
||||||
|
box-shadow: inset 0 0 0 4px $color1; |
||||||
|
border-color: darken($color1, 25%); |
||||||
|
background: darken($color1, 25%); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
+ .radio-label { |
||||||
|
&:empty { |
||||||
|
&:before { |
||||||
|
margin-right: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
import React from "react"; |
||||||
|
import _ from "lodash"; |
||||||
|
import searchIcon from "./search.png"; |
||||||
|
|
||||||
|
const langDetector = (lang = 'fa', option1, option2) => { |
||||||
|
return lang === "fa" ? option1 : option2; |
||||||
|
}; |
||||||
|
|
||||||
|
export default function Search(props) { |
||||||
|
return ( |
||||||
|
<div className="flex items-center justify-center w-full"> |
||||||
|
<div className="relative text-gray-600 focus-within:text-gray-400 w-full"> |
||||||
|
<span className={_.join(["absolute inset-y-0 flex items-center pl-2", langDetector(props.lang, "left-0", "right-0")], " ")}> |
||||||
|
<button |
||||||
|
type="submit" |
||||||
|
className="p-1 focus:outline-none focus:shadow-outline" |
||||||
|
> |
||||||
|
<img src={searchIcon} className="w-6 h-6" alt="" /> |
||||||
|
</button> |
||||||
|
</span> |
||||||
|
<input |
||||||
|
type="search" |
||||||
|
name="q" |
||||||
|
className="w-full py-2 text-sm text-white border rounded-sm pr-5 outline-none focus:ring-1 focus:text-gray-900" |
||||||
|
placeholder={_.join([langDetector(props.lang , "جستجو...", "Search...")], " ")} |
||||||
|
autocomplete="off" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
After Width: | Height: | Size: 857 B |
After Width: | Height: | Size: 229 B |
@ -0,0 +1,108 @@ |
|||||||
|
import React, { useState } from "react"; |
||||||
|
import _ from "lodash"; |
||||||
|
import Checkbox from "../Checkbox"; |
||||||
|
|
||||||
|
import arrowIcon from "./arrow-top.png"; |
||||||
|
|
||||||
|
const langDetector = (lang, option1, option2) => { |
||||||
|
return lang === "fa" ? option1 : option2; |
||||||
|
}; |
||||||
|
export default function SelectCheckbox(props) { |
||||||
|
const [selectedItem, setSelectedItem] = useState(""); |
||||||
|
const [value, setValue] = useState(""); |
||||||
|
|
||||||
|
const [toggle, setToggle] = useState(false); |
||||||
|
const { lang, theme, list, label } = props; |
||||||
|
|
||||||
|
const onChangeItem = (val) => { |
||||||
|
setSelectedItem(val); |
||||||
|
}; |
||||||
|
|
||||||
|
const onChangeText = (val) => { |
||||||
|
setValue(val); |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<div |
||||||
|
className={_.join( |
||||||
|
["select-search flex flex-col relative", langDetector(lang, "fa", "en")], |
||||||
|
" " |
||||||
|
)} |
||||||
|
> |
||||||
|
<div |
||||||
|
className={_.join( |
||||||
|
["search flex flex-column relative", langDetector(lang, "fa", "en")], |
||||||
|
" " |
||||||
|
)} |
||||||
|
onClick={() => setToggle(() => !toggle)} |
||||||
|
> |
||||||
|
<input |
||||||
|
type="search" |
||||||
|
className="w-full py-3 px-3 text-xs border rounded-sm bg-transparent placeholder-gray-500" |
||||||
|
onChange={(e) => onChangeText(e.target.value)} |
||||||
|
placeholder={langDetector(lang, "تنظیمات", "setting")} |
||||||
|
disabled |
||||||
|
/> |
||||||
|
<img |
||||||
|
src={arrowIcon} |
||||||
|
alt="" |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"cursor-pointer w-5 absolute top-1/2 transform -translate-y-1/2 transition-all duration-300", |
||||||
|
langDetector(lang, "left-3", "right-3"), |
||||||
|
toggle ? '-rotate-180' : '', |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
{toggle && ( |
||||||
|
<div |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"select-search__list absolute top-12 left-0 flex flex-col px-5 border rounded-sm w-full bg-white z-20", |
||||||
|
toggle ? "select-search__listActive" : "", |
||||||
|
"transition", |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
> |
||||||
|
<ul className="list-none p-0 divide-y divide-gray-200 w-full"> |
||||||
|
{list?.map((item, i) => ( |
||||||
|
<> |
||||||
|
<li key={i} className="w-full py-1 text-gray-700 flex items-start flex-col"> |
||||||
|
<div className="flex items-center"> |
||||||
|
<Checkbox checked={false} /> |
||||||
|
<span className="text-xs">{item?.name}</span> |
||||||
|
</div> |
||||||
|
<ul className="w-full p-0 mx-auto my-0"> |
||||||
|
{item.sublist?.map((item1, j) => ( |
||||||
|
<> |
||||||
|
<li className="flex flex-row flex-1 pt-1 px-5 pb-0 items-center" key={j}> |
||||||
|
<Checkbox checked={false} /> |
||||||
|
<span className="text-xs">{item1?.name}</span> |
||||||
|
</li> |
||||||
|
</> |
||||||
|
))} |
||||||
|
</ul> |
||||||
|
</li> |
||||||
|
</> |
||||||
|
))} |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
)} |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
SelectCheckbox.defaultProps = { |
||||||
|
lang: "fa", |
||||||
|
theme: "light", |
||||||
|
label: "کشور خود را انتخاب کنید", |
||||||
|
list: [ |
||||||
|
{ name: "وسایل آشپزخانه", sublist: [{ name: "اتو" }] }, |
||||||
|
{ name: "غریق نجات از تمام جهات" }, |
||||||
|
{ name: "قاشق و چنگال" }, |
||||||
|
{ name: "وسایل آشپزخانه" }, |
||||||
|
], |
||||||
|
}; |
After Width: | Height: | Size: 229 B |
@ -0,0 +1,100 @@ |
|||||||
|
import React, { useState } from "react"; |
||||||
|
import _ from "lodash"; |
||||||
|
import Radio from "../Radio"; |
||||||
|
|
||||||
|
import xIcon from "./x.png"; |
||||||
|
import arrowIcon from "./arrow-top.png"; |
||||||
|
|
||||||
|
|
||||||
|
const langDetector = (lang, option1, option2) => { |
||||||
|
return lang === "fa" ? option1 : option2; |
||||||
|
}; |
||||||
|
|
||||||
|
export default function SelectRadio(props) { |
||||||
|
const [selectedItem, setSelectedItem] = useState(""); |
||||||
|
const [value, setValue] = useState(""); |
||||||
|
|
||||||
|
const [toggle, setToggle] = useState(false); |
||||||
|
const { lang, theme, list, label } = props; |
||||||
|
|
||||||
|
const onChangeItem = (val) => { |
||||||
|
setSelectedItem(val); |
||||||
|
}; |
||||||
|
|
||||||
|
const onChangeText = (val) => { |
||||||
|
setValue(val); |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<div |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"flex flex-col relative", |
||||||
|
langDetector(lang, "fa", "en"), |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
> |
||||||
|
<div |
||||||
|
className={_.join( |
||||||
|
["flex flex-col relative", langDetector(lang, "fa", "en")], |
||||||
|
" " |
||||||
|
)} |
||||||
|
onClick={() => setToggle(() => !toggle)} |
||||||
|
> |
||||||
|
<input |
||||||
|
type="search" |
||||||
|
className="py-3 px-3 text-xs border rounded-sm bg-transparent focus:ring-1 outline-none focus:placeholder-blue-500 placeholder-gray-500" |
||||||
|
onChange={(e) => onChangeText(e.target.value)} |
||||||
|
placeholder={langDetector(lang, "تنظیمات", "setting")} |
||||||
|
disabled |
||||||
|
/> |
||||||
|
<img |
||||||
|
src={arrowIcon} |
||||||
|
alt="" |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"w-5 absolute top-1/2 transform -translate-y-1/2 cursor-pointer transition-all duration-300", |
||||||
|
langDetector(lang, "left-3", "right-3"), |
||||||
|
toggle ? '-rotate-180' : '' |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
{toggle && ( |
||||||
|
<div |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"w-full absolute top-12 left-0 flex flex-col border rounded-sm bg-white z-20", |
||||||
|
toggle ? "select-search__listActive" : "", |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
> |
||||||
|
<ul className="list-none divide-y divide-gray-200 py-1 text-gray-700 w-full px-3"> |
||||||
|
{list?.map((item, i) => ( |
||||||
|
<> |
||||||
|
<li key={i} className="transition w-full text-gray-700 items-center py-3 flex-col justify-center"> |
||||||
|
<Radio label={item?.name} name="reza" /> |
||||||
|
</li> |
||||||
|
</> |
||||||
|
))} |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
)} |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
SelectRadio.defaultProps = { |
||||||
|
lang: "fa", |
||||||
|
theme: "light", |
||||||
|
label: "کشور خود را انتخاب کنید", |
||||||
|
list: [ |
||||||
|
{ name: "وسایل آشپزخانه", sublist: [{ name: "اتو" }] }, |
||||||
|
{ name: "غریق نجات از تمام جهات" }, |
||||||
|
{ name: "قاشق و چنگال" }, |
||||||
|
{ name: "وسایل آشپزخانه" }, |
||||||
|
], |
||||||
|
}; |
After Width: | Height: | Size: 346 B |
@ -0,0 +1,9 @@ |
|||||||
|
import React from 'react' |
||||||
|
|
||||||
|
export default function Col() { |
||||||
|
return ( |
||||||
|
<div> |
||||||
|
|
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
import React, { useState } from "react"; |
||||||
|
import category from "./data"; |
||||||
|
import _ from "lodash"; |
||||||
|
|
||||||
|
export default function SidebarCategoryHover() { |
||||||
|
const [activeItem, setActiveItem] = useState(null); |
||||||
|
|
||||||
|
const arrayLength = category.length; |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="flex flex-col w-60 relative" onMouseOut={() => setActiveItem(null)}> |
||||||
|
<ul className="list-none w-full divide-y border divide-gray-200"> |
||||||
|
{category.map((item, i) => ( |
||||||
|
<> |
||||||
|
<li |
||||||
|
className="p-4 w-full text-gray-500 font-normal text-sm hover:bg-blue-100 text-right" |
||||||
|
key={i} |
||||||
|
onMouseOver={() => setActiveItem(item.id)} |
||||||
|
> |
||||||
|
{item.name} |
||||||
|
</li> |
||||||
|
<ul |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"absolute right-60 top-0 h-full border flex-row divide-x divide-gray-200", |
||||||
|
activeItem === item.id ? "flex" : "hidden", |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
onMouseOver={() => setActiveItem(item.id)} |
||||||
|
// style={{width : 1000}}
|
||||||
|
> |
||||||
|
<li className="h-full w-52 bg-red-50 flex flex-col text-right"> |
||||||
|
<li className="flex items-center" style={{ minHeight: "calc(100% / 9)" }}> |
||||||
|
{item.categories[0].name} |
||||||
|
</li> |
||||||
|
{item.categories[0].list.map((item1, i) => ( |
||||||
|
<li |
||||||
|
key={i} |
||||||
|
className="text-normal flex text-sm items-center" |
||||||
|
style={{ minHeight: "calc(100% / 9)" }} |
||||||
|
> |
||||||
|
{item1.name} |
||||||
|
</li> |
||||||
|
))} |
||||||
|
<li className="flex items-center" style={{ minHeight: "calc(100% / 9)" }}> |
||||||
|
{item.categories[1].name} |
||||||
|
</li> |
||||||
|
{item.categories[1].list.map((item1, i) => ( |
||||||
|
<li key={i} className="flex items-center" style={{ minHeight: "calc(100% / 9)" }}> |
||||||
|
{item1.name} |
||||||
|
</li> |
||||||
|
))} |
||||||
|
</li> |
||||||
|
<li className="h-full w-52 bg-green-50"></li> |
||||||
|
<li className="h-full w-52 bg-blue-50"></li> |
||||||
|
<li className="h-full w-52 bg-red-50"></li> |
||||||
|
<li className="h-full w-52 bg-green-50"></li> |
||||||
|
<li className="h-full w-52 bg-blue-50"></li> |
||||||
|
</ul> |
||||||
|
</> |
||||||
|
))} |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
import React from "react"; |
||||||
|
import "./index.scss"; |
||||||
|
|
||||||
|
export default function index() { |
||||||
|
return ( |
||||||
|
<div className="switch"> |
||||||
|
<input type="checkbox" id="toggle" /> |
||||||
|
<label for="toggle"></label> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,52 @@ |
|||||||
|
// *, *:after, *:before { |
||||||
|
// // box-sizing: border-box; |
||||||
|
// } |
||||||
|
|
||||||
|
// body { |
||||||
|
// min-height: 100vh; |
||||||
|
// display: flex; |
||||||
|
// align-items: center; |
||||||
|
// justify-content: center; |
||||||
|
// } |
||||||
|
|
||||||
|
.switch { |
||||||
|
position: relative; |
||||||
|
input[type="checkbox"] { |
||||||
|
visibility: hidden; |
||||||
|
position : absolute; |
||||||
|
&:checked + label { |
||||||
|
transform: rotate(0deg); |
||||||
|
background-color: #000; |
||||||
|
&:before { |
||||||
|
transform: translateX(35.5px); |
||||||
|
background-color: #fff; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
label { |
||||||
|
display: flex; |
||||||
|
width: 70px; |
||||||
|
height: 34px; |
||||||
|
border: 3px solid; |
||||||
|
border-radius: 99em; |
||||||
|
position: relative; |
||||||
|
transition: transform 0.3s ease-in-out; |
||||||
|
transform-origin: 50% 50%; |
||||||
|
cursor: pointer; |
||||||
|
|
||||||
|
&:before { |
||||||
|
transition: transform 0.3s ease; |
||||||
|
transition-delay: 0s; |
||||||
|
content: ""; |
||||||
|
display: block; |
||||||
|
position: absolute; |
||||||
|
width: 24px; |
||||||
|
height: 24px; |
||||||
|
background-color: #000; |
||||||
|
border-radius: 50%; |
||||||
|
top: 2px; |
||||||
|
left: 3px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 229 B |
@ -0,0 +1,170 @@ |
|||||||
|
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 rounded-md pt-6 bg-transparent max-h-screen"> |
||||||
|
<strong className="text-md text-gray-500 w-full mb-3 text-right px-3"> |
||||||
|
دسته بندی |
||||||
|
</strong> |
||||||
|
<form className="relative w-full px-3 mb-3"> |
||||||
|
<input |
||||||
|
type="text" |
||||||
|
placeholder={_.join( |
||||||
|
[langDetector(props.lang, "جستجو...", "Search...")], |
||||||
|
" " |
||||||
|
)} |
||||||
|
className="border rounded-sm 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> |
||||||
|
</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 |
@ -0,0 +1,88 @@ |
|||||||
|
import React, { useState } from "react"; |
||||||
|
import _ from "lodash"; |
||||||
|
import searchIcon from "./search.png"; |
||||||
|
|
||||||
|
const langDetector = (lang, option1, option2) => { |
||||||
|
return lang === "fa" ? option1 : option2; |
||||||
|
}; |
||||||
|
|
||||||
|
export default function PopularSearch(props) { |
||||||
|
const [value, setValue] = useState(""); |
||||||
|
const [popularsToggle, setPopularsToggle] = useState(false); |
||||||
|
const { lang, theme, populars } = props; |
||||||
|
|
||||||
|
const onChange = (val) => { |
||||||
|
setValue(val); |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<div |
||||||
|
className={_.join( |
||||||
|
["flex flex-col relative search", langDetector(lang, "fa", "en")], |
||||||
|
" " |
||||||
|
)} |
||||||
|
> |
||||||
|
<input |
||||||
|
type="search" |
||||||
|
className="transition py-2 pr-4 pl-2 mx-0 border rounded-sm outline-none focus:ring-1 placeholder-gray-500 placeholder-opacity-40 focus:placeholder-blue-300" |
||||||
|
onChange={(e) => onChange(e.target.value)} |
||||||
|
value={value} |
||||||
|
placeholder={langDetector( |
||||||
|
lang, |
||||||
|
"نام کالا را جستجو کنید", |
||||||
|
"search product name" |
||||||
|
)} |
||||||
|
onFocus={() => setPopularsToggle(true)} |
||||||
|
onBlur={() => |
||||||
|
setTimeout(() => { |
||||||
|
setPopularsToggle(false); |
||||||
|
}, 250) |
||||||
|
} |
||||||
|
/> |
||||||
|
<img |
||||||
|
src={searchIcon} |
||||||
|
alt={langDetector(lang, "جستجو", "search")} |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"search__icon absolute w-6 h-6 top-1/2 transform -translate-y-1/2", |
||||||
|
langDetector(lang, "left-3", "right-3"), |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
/> |
||||||
|
<div |
||||||
|
className={_.join( |
||||||
|
[ |
||||||
|
"search__populars w-full mt-0 border rounded-sm top-12 left-0 absolute z-10 px-4 bg-white", |
||||||
|
popularsToggle ? "flex flex-col" : "hidden", |
||||||
|
"transition", |
||||||
|
], |
||||||
|
" " |
||||||
|
)} |
||||||
|
> |
||||||
|
<strong className="py-3"> |
||||||
|
{langDetector(lang, "جستجوهای پرطرفدار", "Popular search")} |
||||||
|
</strong> |
||||||
|
<ul className="divide-y divide-gray-200"> |
||||||
|
{populars?.map((item, i) => ( |
||||||
|
<> |
||||||
|
<li |
||||||
|
key={i} |
||||||
|
className="transition py-3 px-1 hover:bg-blue-100" |
||||||
|
onClick={() => setValue(() => item)} |
||||||
|
> |
||||||
|
{item} |
||||||
|
</li> |
||||||
|
</> |
||||||
|
))} |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
PopularSearch.defaultProps = { |
||||||
|
lang: "fa", |
||||||
|
theme: "light", |
||||||
|
populars: ["علی", "علیرضا", "محمد", "محمدرضا"], |
||||||
|
}; |
After Width: | Height: | Size: 857 B |
@ -0,0 +1 @@ |
|||||||
|
/// <reference types="react-scripts" />
|
@ -0,0 +1,11 @@ |
|||||||
|
module.exports = { |
||||||
|
purge: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'], |
||||||
|
darkMode: 'class', // or 'media' or 'class'
|
||||||
|
theme: { |
||||||
|
extend: {}, |
||||||
|
}, |
||||||
|
variants: { |
||||||
|
extend: {}, |
||||||
|
}, |
||||||
|
plugins: [], |
||||||
|
} |