diff --git a/src/App.tsx b/src/App.tsx index 64d11c0..2655dc8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,10 +1,22 @@ -import './global.scss'; -import Search from './components/Search'; +import "./global.scss"; +import Search from "./components/Search"; +import PopularSearch from "./components/PopularSearch"; +import Input from "./components/Input"; function App() { return (
+
+ +
+
); } diff --git a/src/components/Input/danger.png b/src/components/Input/danger.png new file mode 100644 index 0000000..a171ed0 Binary files /dev/null and b/src/components/Input/danger.png differ diff --git a/src/components/Input/index.scss b/src/components/Input/index.scss new file mode 100644 index 0000000..436fa94 --- /dev/null +++ b/src/components/Input/index.scss @@ -0,0 +1,116 @@ +$primary: #06BACE; +$gray: #dbdbdb; +$danger: #E00A0A; +$success: #23C933; + +.input { + display: flex; + flex-direction: column; + position: relative; + input{ + flex: 1; + border-radius: 5px; + border: 1.7px solid $gray; + padding: 15px 11px 15px 30px; + font-size: 14px; + outline: 0px; + } + label{ + position: absolute; + top: 50%; + font-size: 13px; + transform: translateY(-50%); + color: $gray; + background-color: white; + padding: 0px 5px; + } + &__labelFa{ + right: 15px; + } + &__labelEn{ + left: 15px; + } + &__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; + } + + & img{ + width : 18px; + position: absolute; + top: 50%; + transform: translateY(-50%); + } + &__iconFa{ + left: 15px; + } + &__iconEn{ + right: 15px; + } + &__message{ + position: absolute; + bottom: -25px; + font-size: 12px; + &En{ + left: 5px; + } + &Fa{ + right: 5px; + } + &Success{ + color: $success; + } + &Danger{ + color: $danger; + } + } + &__length{ + position: absolute; + bottom: -25px; + font-size: 12px; + &En{ + right: 5px; + } + &Fa{ + left: 5px; + } + &Success{ + color: $success; + } + &Danger{ + color: $danger; + } + } +} + +.en { + direction: ltr; + text-align: left; +} + +.fa { + direction: rtl; + text-align: right; +} diff --git a/src/components/Input/index.tsx b/src/components/Input/index.tsx new file mode 100644 index 0000000..2d7ba78 --- /dev/null +++ b/src/components/Input/index.tsx @@ -0,0 +1,179 @@ +import React, { useState } from "react"; +import _ from "lodash"; + +import tick from "./tick.png"; +import danger from "./danger.png"; + +interface Types { + lang?: string; + theme?: string; + inputMode?: any; + label?: string; + status?: boolean; + maxLength?: number; + message?: string; +} + +const langDetector = (lang: string, option1: any, option2: any) => { + return lang === "fa" ? option1 : option2; +}; + +const inputStatusHandler = ( + value: string, + focus: boolean, + status: boolean, + primary: string, + success: string, + danger: string +) => { + if (!focus) { + return ""; + } else { + if (!value) { + return primary; + } else { + if (status) { + return success; + } else { + return danger; + } + } + } +}; + +export default function Input(props: Types) { + const [value, setValue] = useState(""); + const [focusToggle, setFocusToggle] = useState(false); + + const { lang, theme, inputMode, label, status, maxLength, message } = props; + + const onChange = (val: string) => { + setValue(val); + }; + + return ( +
+ + onChange(e.target.value)} + value={value} + onFocus={() => setFocusToggle(true)} + onBlur={() => !value && setFocusToggle(false)} + maxLength={maxLength} + /> + {!status && value && ( + {langDetector(lang + )} + {status && value && ( + {langDetector(lang + )} + + {value && !status && ( + + {message} + + )} + {value && ( + + {value.length + '/' + maxLength} + + )} +
+ ); +} diff --git a/src/components/Input/tick.png b/src/components/Input/tick.png new file mode 100644 index 0000000..805f74a Binary files /dev/null and b/src/components/Input/tick.png differ diff --git a/src/components/PopularSearch/icon.png b/src/components/PopularSearch/icon.png new file mode 100644 index 0000000..81d586c Binary files /dev/null and b/src/components/PopularSearch/icon.png differ diff --git a/src/components/PopularSearch/index.scss b/src/components/PopularSearch/index.scss new file mode 100644 index 0000000..73d7abc --- /dev/null +++ b/src/components/PopularSearch/index.scss @@ -0,0 +1,115 @@ +$primary: #246e8a; +$gray: #dbdbdb; +$primary1: #EEFAFF; + +.search { + display: flex; + flex-direction: column; + position: relative; + img{ + cursor: pointer; + } + &__icon { + width: 27px; + position: absolute; + top: 50%; + transform: translateY(-50%); + &Fa { + left: 20px; + } + &En { + right: 20px; + } + } + + &__x { + width: 15px; + position: absolute; + top: 50%; + transform: translateY(-50%); + opacity: 0; + &Fa { + right: 15px; + } + &En { + left: 10px; + } + &Active{ + opacity: 1; + } + } + + input { + padding: 15px 40px 15px 30px; + font-size: 14px; + border: 1.7px solid $gray; + border-radius: 5px; + background-color: inherit; + &::placeholder { + color: $gray; + } + &:focus { + border-color: $primary; + outline: 0px; + color: $primary; + &::placeholder { + color: $primary; + } + } + } + + &__populars{ + margin-top: 10px; + width: 100%; + border: 1.7px solid $gray; + border-radius: 5px; + background-color: white; + display: flex; + flex-direction: column; + list-style: none; + position: absolute; + top: 50px; + left: 0px; + opacity: 0; + display: none; + z-index: 100; + &Active{ + opacity: 1; + display: flex; + } + strong{ + width: 100%; + padding: 15px 40px; + font-size: 15px; + } + ul{ + width : calc(100% - 80px); + list-style: none; + margin: 0px auto; + padding: 0px; + li{ + padding: 15px 5px; + &:hover{ + background-color: $primary1; + } + cursor: pointer; + font-size: 13px; + } + hr{ + margin: 0px auto; + margin: 0px; + border: 0.5px solid #eee; + } + } + } +} + +.en { + direction: ltr; + text-align: left; +} + +.fa { + direction: rtl; + text-align: right; +} diff --git a/src/components/PopularSearch/index.tsx b/src/components/PopularSearch/index.tsx new file mode 100644 index 0000000..0b0a7bb --- /dev/null +++ b/src/components/PopularSearch/index.tsx @@ -0,0 +1,102 @@ +import React, { useState } from "react"; +import _ from "lodash"; +import searchIcon from "./icon.png"; +import xIcon from "./x.png"; + +interface Types { + lang?: string; + theme?: string; + populars?: Array; +} + +const langDetector = (lang: string, option1: any, option2: any) => { + return lang === "fa" ? option1 : option2; +}; + +export default function PopularSearch(props: Types) { + const [value, setValue] = useState(""); + const [popularsToggle, setPopularsToggle] = useState(false); + const { lang, theme, populars } = props; + + const onChange = (val: string) => { + setValue(val); + }; + + return ( +
+ onChange(e.target.value)} + value={value} + placeholder={langDetector( + lang as string, + "نام کالا را جستجو کنید", + "search product name" + )} + onFocus={() => setPopularsToggle(true)} + onBlur={() => setPopularsToggle(false)} + /> + {langDetector(lang + {langDetector(lang setValue("")} + /> +
+ + {langDetector(lang as string, "جستجوهای پرطرفدار", "Popular search")} + +
    + {populars?.map((item: string, i: any) => ( + <> +
  • setValue(() => item)}> + {item} +
  • + {i !== populars?.length - 1 &&
    } + + ))} +
+
+
+ ); +} + +PopularSearch.defaultProps = { + lang: "fa", + theme: "light", + populars: ["علی", "علیرضا", "محمد", "محمدرضا"], +}; diff --git a/src/components/PopularSearch/x.png b/src/components/PopularSearch/x.png new file mode 100644 index 0000000..df19f25 Binary files /dev/null and b/src/components/PopularSearch/x.png differ diff --git a/src/components/Search/index.scss b/src/components/Search/index.scss index e6ea206..64e978b 100644 --- a/src/components/Search/index.scss +++ b/src/components/Search/index.scss @@ -5,6 +5,9 @@ $gray: #dbdbdb; display: flex; flex-direction: column; position: relative; + img{ + cursor: pointer; + } &__icon { width: 27px; position: absolute; diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index d50d6ec..d1d2f22 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -13,17 +13,11 @@ const langDetector = (lang: string, option1: any, option2: any) => { }; export default function Search(props: Types) { - const [clear, setClear] = useState(false); const [value, setValue] = useState(""); const { lang, theme } = props; const onChange = (val: string) => { setValue(val); - if (val.length) { - setClear(true); - } else { - setClear(false); - } }; return ( @@ -61,6 +55,7 @@ export default function Search(props: Types) { langDetector(lang as string, "search__xFa", "search__xEn"), value ? "search__xActive" : "", ], " ")} + onClick={() => setValue("")} /> ); diff --git a/src/global.scss b/src/global.scss index 7a5cccd..e4703a2 100644 --- a/src/global.scss +++ b/src/global.scss @@ -1,11 +1,12 @@ @import './components/Search/index.scss'; +@import './components/PopularSearch/index.scss'; +@import './components/Input/index.scss'; .app{ padding: 50px 20px; min-height: 100vh; display: flex; flex-direction: column; - background-color: black; } .transition{