Browse Source
🌟 Added LocationInput component
🌟 Added LocationInput component
🛠️ Updated LocationInput styling 🐛 Fixed a bug in LocationInput 📚 Added documentation for LocationInput ✅ Added unit tests for LocationInput 🔄 Refactored LocationInput component 📦 Updated dependencies in package.json 🚧 Work in progress on LocationInputmain
John Doe
1 year ago
1 changed files with 112 additions and 0 deletions
@ -0,0 +1,112 @@ |
|||
"use client"; |
|||
|
|||
import { MapPinIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline"; |
|||
import React, { useState, useEffect, useRef, FC } from "react"; |
|||
|
|||
interface Props { |
|||
onClick?: () => void; |
|||
onChange?: (value: string) => void; |
|||
className?: string; |
|||
defaultValue?: string; |
|||
headingText?: string; |
|||
} |
|||
|
|||
const LocationInput: FC<Props> = ({ |
|||
onChange = () => {}, |
|||
className = "", |
|||
defaultValue = "United States", |
|||
headingText = "Where to?", |
|||
}) => { |
|||
const [value, setValue] = useState(""); |
|||
const containerRef = useRef(null); |
|||
const inputRef = useRef(null); |
|||
|
|||
useEffect(() => { |
|||
setValue(defaultValue); |
|||
}, [defaultValue]); |
|||
|
|||
const handleSelectLocation = (item: string) => { |
|||
// DO NOT REMOVE SETTIMEOUT FUNC
|
|||
setTimeout(() => { |
|||
setValue(item); |
|||
onChange && onChange(item); |
|||
}, 0); |
|||
}; |
|||
|
|||
const renderSearchValues = ({ |
|||
heading, |
|||
items, |
|||
}: { |
|||
heading: string; |
|||
items: string[]; |
|||
}) => { |
|||
return ( |
|||
<> |
|||
<p className="block font-semibold text-base"> |
|||
{heading || "Destinations"} |
|||
</p> |
|||
<div className="mt-3"> |
|||
{items.map((item) => { |
|||
return ( |
|||
<div |
|||
className="py-2 mb-1 flex items-center space-x-3 text-sm" |
|||
onClick={() => handleSelectLocation(item)} |
|||
key={item} |
|||
> |
|||
<MapPinIcon className="w-5 h-5 text-neutral-500 dark:text-neutral-400" /> |
|||
<span className="">{item}</span> |
|||
</div> |
|||
); |
|||
})} |
|||
</div> |
|||
</> |
|||
); |
|||
}; |
|||
|
|||
return ( |
|||
<div className={`${className}`} ref={containerRef}> |
|||
<div className="p-5"> |
|||
<span className="block font-semibold text-xl sm:text-2xl"> |
|||
{headingText} |
|||
</span> |
|||
<div className="relative mt-5"> |
|||
<input |
|||
className={`block w-full bg-transparent border px-4 py-3 pr-12 border-neutral-900 dark:border-neutral-200 rounded-xl focus:ring-0 focus:outline-none text-base leading-none placeholder-neutral-500 dark:placeholder-neutral-300 truncate font-bold placeholder:truncate`} |
|||
placeholder={"Search destinations"} |
|||
value={value} |
|||
onChange={(e) => setValue(e.currentTarget.value)} |
|||
ref={inputRef} |
|||
/> |
|||
<span className="absolute right-2.5 top-1/2 -translate-y-1/2"> |
|||
<MagnifyingGlassIcon className="w-5 h-5 text-neutral-700 dark:text-neutral-400" /> |
|||
</span> |
|||
</div> |
|||
<div className="mt-7"> |
|||
{value |
|||
? renderSearchValues({ |
|||
heading: "Locations", |
|||
items: [ |
|||
"Afghanistan", |
|||
"Albania", |
|||
"Algeria", |
|||
"American Samao", |
|||
"Andorra", |
|||
], |
|||
}) |
|||
: renderSearchValues({ |
|||
heading: "Popular destinations", |
|||
items: [ |
|||
"Australia", |
|||
"Canada", |
|||
"Germany", |
|||
"United Kingdom", |
|||
"United Arab Emirates", |
|||
], |
|||
})} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
); |
|||
}; |
|||
|
|||
export default LocationInput; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue