Skip to content

Commit

Permalink
refactor all Dropdowns to use DropdownSelector component
Browse files Browse the repository at this point in the history
  • Loading branch information
Sharqiewicz committed Jan 28, 2025
1 parent 7d4fcfa commit ec4b2c6
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 45 deletions.
2 changes: 1 addition & 1 deletion src/components/Selector/AssetSelector/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export function generateAssetSelectorItem(
}

export interface AssetItem {
displayName: string;
displayName: string | React.JSX.Element;
id: string;
name: string;
icon?: string;
Expand Down
11 changes: 8 additions & 3 deletions src/components/Selector/DropdownSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@ interface Props<T> {
onChange: (item: T) => void;
value?: T;
children: JSX.Element;
dropdownMenuClassName?: string;
}

export function DropdownSelector<T extends AssetItem>(props: Props<T>) {
const { items, onChange, children } = props;
const { items, onChange, children, dropdownMenuClassName } = props;
return (
<div className="dropdown flex min-w-[95px] justify-end">
{children}
<ul tabIndex={0} className="menu dropdown-content z-[1] w-52 rounded-box bg-base-100 p-2 shadow">
<ul
tabIndex={0}
className={`menu dropdown-content z-[1] min-w-52 rounded-box bg-base-100 p-2 shadow ${dropdownMenuClassName || ''}`}
>
{items.map((item) => (
<li key={item.id}>
<li key={item.id} className="w-full">
<a
className="flex w-full"
onClick={() => {
const elem = document.activeElement;
if (elem && elem instanceof HTMLElement) {
Expand Down
102 changes: 63 additions & 39 deletions src/components/Selector/VaultSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { ChevronDownIcon } from '@heroicons/react/20/solid';
import { Button, Dropdown } from 'react-daisyui';
import { Button } from 'react-daisyui';
import { BridgeDirection } from '../../pages/spacewalk/bridge';
import { convertCurrencyToStellarAsset } from '../../helpers/spacewalk';
import { ExtendedRegistryVault } from '../../hooks/spacewalk/useVaultRegistryPallet';
import { nativeToDecimal } from '../../shared/parseNumbers/metric';
import { PublicKey } from '../PublicKey';
import { DropdownSelector } from './DropdownSelector';
import { AssetItem } from './AssetSelector/helpers';

interface VaultSelectorProps {
vaults: ExtendedRegistryVault[];
Expand All @@ -25,48 +27,70 @@ function getMaxTokensForVault(vault: ExtendedRegistryVault, type: 'issue' | 'red
}
}

function VaultSelector(props: VaultSelectorProps): JSX.Element {
interface VaultItem extends AssetItem {
vault: ExtendedRegistryVault;
}

export function VaultSelector(props: VaultSelectorProps): JSX.Element {
const { vaults, selectedVault, bridgeDirection, onChange } = props;

const items: VaultItem[] = vaults.map((vault) => {
const displayContent = (
<div className="flex w-full items-center justify-between">
<PublicKey publicKey={vault.id.accountId.toString()} variant="short" />
{bridgeDirection && (
<div className="content-end">
{getMaxTokensForVault(vault, bridgeDirection)}
{convertCurrencyToStellarAsset(vault.id.currencies.wrapped)?.getCode()}
</div>
)}
</div>
);

return {
id: vault.id.accountId.toString(),
name: vault.id.accountId.toString(),
displayName: displayContent,
vault,
};
});

const selectedItem = selectedVault
? {
id: selectedVault.id.accountId.toString(),
name: selectedVault.id.accountId.toString(),
displayName: selectedVault.id.accountId.toString(),
vault: selectedVault,
}
: undefined;

return (
<div className="dropdown mt-3 w-full">
<Button
type="button"
color="ghost"
className="no-animation flex w-full place-content-between content-center rounded-md border-base-200 bg-base-300"
<div className="mt-3 w-full">
<DropdownSelector<AssetItem & { vault: ExtendedRegistryVault }>
dropdownMenuClassName="w-full"
items={items}
value={selectedItem}
onChange={(item) => onChange(item.vault)}
>
<PublicKey publicKey={selectedVault ? selectedVault.id.accountId.toString() : ''} variant="full" />
<ChevronDownIcon className="h-3 w-3" strokeWidth="2" />
</Button>
<Dropdown.Menu className="dropdown-content mt-1.5 w-full rounded-md border border-base-200 bg-base-300 p-1 shadow-none">
{vaults.map((vault) => (
<Dropdown.Item
key={vault.id.accountId.toString()}
onClick={() => {
const elem = document.activeElement;
if (elem && elem instanceof HTMLElement) {
elem.blur();
}
onChange(vault);
}}
className="flex w-full rounded-md"
>
<span className="flex w-full place-content-between">
<span className="flex">
<PublicKey publicKey={vault.id.accountId.toString()} variant="short" />
</span>
{bridgeDirection && (
<span className="content-end">
{getMaxTokensForVault(vault, bridgeDirection)}{' '}
{convertCurrencyToStellarAsset(vault.id.currencies.wrapped)?.getCode()}
</span>
)}
</span>
</Dropdown.Item>
))}
</Dropdown.Menu>
<Button
tabIndex={0}
type="button"
color="ghost"
className="no-animation flex w-full place-content-between content-center rounded-md border-base-200 bg-base-300"
>
<PublicKey
className="hidden sm:block"
publicKey={selectedVault ? selectedVault.id.accountId.toString() : ''}
variant="full"
/>
<PublicKey
className="block sm:hidden"
publicKey={selectedVault ? selectedVault.id.accountId.toString() : ''}
variant="short"
/>
<ChevronDownIcon className="h-3 w-3" strokeWidth="2" />
</Button>
</DropdownSelector>
</div>
);
}

export default VaultSelector;
2 changes: 1 addition & 1 deletion src/components/Selector/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import AssetSelector from './AssetSelector';
import { DropdownSelector } from './DropdownSelector';
import VaultSelector from './VaultSelector';
import { VaultSelector } from './VaultSelector';

export { AssetSelector, DropdownSelector, VaultSelector };
2 changes: 1 addition & 1 deletion src/pages/spacewalk/bridge/Issue/SettingsDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button, Checkbox } from 'react-daisyui';
import { useMemo } from 'react';
import { ChangeEvent } from 'react';
import VaultSelector from '../../../../components/Selector/VaultSelector';
import { VaultSelector } from '../../../../components/Selector/VaultSelector';
import useBridgeSettings from '../../../../hooks/spacewalk/useBridgeSettings';
import { Dialog } from '../../../../components/Dialog';
import { BridgeDirection } from '../index';
Expand Down

0 comments on commit ec4b2c6

Please sign in to comment.