Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pair selector improvements #166

Merged
merged 17 commits into from
Oct 27, 2023
Merged
2 changes: 1 addition & 1 deletion e2e/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ test("connects to AlphaDEX", async ({ page }) => {
);

// A pair should appear in the pair selector
await expect(page.locator("#pair-selector-text")).toHaveText(/^.* - .*$/);
await expect(page.locator("#pair-selector-text")).toHaveValue(/^.* - .*$/);
});

// TODO: after MVP
Expand Down
137 changes: 103 additions & 34 deletions src/app/components/PairSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { useAppSelector, useAppDispatch } from "../hooks";
import { selectPairAddress } from "../redux/pairSelectorSlice";
import { useRef, useState } from "react";

interface PairInfo {
name: string;
address: string;
}
function displayName(name?: string) {
return name?.replace("/", " - ");
}
Expand All @@ -11,44 +16,108 @@ export function PairSelector() {
const selectPair = (pairAddress: string) => {
dispatch(selectPairAddress(pairAddress));
};
const options = pairSelector.pairsList;
const id = "pairOption";
const handleChange = (val: PairInfo | null) => {
if (val == null) return;
selectPair(val["address"]);
};

const [query, setQuery] = useState("");
const [isOpen, setIsOpen] = useState(false);

const inputRef = useRef(null);
const dropdownRef = useRef(null);

const selectOption = (option: PairInfo) => {
setQuery(() => "");
handleChange(option);
setIsOpen((isOpen) => !isOpen);
};

function toggle(e: React.MouseEvent<HTMLInputElement>) {
setIsOpen(e && e.target === inputRef.current);
}

const getDisplayValue = () => {
if (query) return displayName(query);
if (pairSelector.name) return displayName(pairSelector.name);

return "";
};

const filter = (options: PairInfo[]) => {
return options.filter(
(option) => option["name"].toLowerCase().indexOf(query.toLowerCase()) > -1
);
};

return (
<div className="dropdown w-full">
<label
tabIndex={0}
className="justify-between btn btn-block px-8 text-xl font-bold"
>
<span id="pair-selector-text">
{displayName(pairSelector.name) || "Loading"}
</span>
<span className="float-right">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="white"
viewBox="0 0 16 16"
>
<path d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" />
</svg>
</span>
</label>
<ul
tabIndex={0}
className="dropdown-content z-[1] menu bg-base-200 shadow rounded-box w-full !my-0 !p-0"
>
{pairSelector.pairsList.map((pair, index) => (
<li className="font-bold !pl-0" key={index}>
<button
className="justify-between"
onClick={() => selectPair(pair.address)}
<div className="w-full">
<div className="dropdown dropdown-end w-full">
<label className="btn btn-block text-xl font-bold no-animation">
<div className="flex justify-between selected-value w-full">
<input
id="pair-selector-text"
ref={inputRef}
type="text"
value={getDisplayValue()}
name="searchTerm"
onChange={(e) => {
setQuery(e.target.value);
handleChange(null);
}}
onClick={toggle}
className="flex-initial !bg-transparent"
/>
<span className="flex-none order-last pt-2">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="white"
viewBox="0 0 16 16"
>
<path d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" />
</svg>
</span>
</div>
</label>
<ul
ref={dropdownRef}
tabIndex={0}
className={
`options ${isOpen ? "" : "hidden"}` +
" dropdown-content z-[1] menu bg-base-200 shadow rounded-box w-full !my-0 !p-0"
}
>
{filter(options).map((option, index) => {
return (
<li
onClick={() => selectOption(option)}
className=" font-bold !pl-0"
key={`${id}-${index}`}
>
<div className="flex justify-between">
<span className="flex-1">{displayName(option["name"])}</span>
<span className="flex-none">+</span>
</div>
</li>
);
})}
<li>
<div
className={
filter(options).length == 0
? "flex justify-between"
: "flex justify-between hidden"
}
>
{displayName(pair.name)}
<span>+</span>
</button>
<span className="flex-1">No Results</span>
</div>
</li>
))}
</ul>
</ul>
</div>
</div>
);
}