Skip to content

Commit

Permalink
refactored ChainSelect into a generic Select component
Browse files Browse the repository at this point in the history
  • Loading branch information
mikestarrdev committed Apr 17, 2024
1 parent bdbc377 commit d8b1406
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 70 deletions.
85 changes: 17 additions & 68 deletions src/features/ui/ChainSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import * as RadixSelect from '@radix-ui/react-select';
import { useCallback, useEffect, useState } from 'react';
import { FaChevronDown } from 'react-icons/fa';
import { chainIdOptions } from '@/lib/chainIdOptions';
import { useAppStore } from '@/store/store';
import { Select } from './select';
import { chainIdOptions } from '@/lib/chainIdOptions';
import { chainIdInOptions } from '@/utils/chainIdInOptions';
import { useCallback, useEffect, useState } from 'react';
import { matchNetworkNameWithId } from '@/utils/matchNetworkNamesWithId';

export const ChainSelector = () => {
const [isSelectOpen, setIsSelectOpen] = useState(false);
const [placeholder, setPlaceholder] = useState('Select chain id');
const [networkName, setNetworkName] = useState<string>('');
const { isSelectDisabled, selectedChainId, setSelectedChainId } =
useAppStore();

const handleIsSelectOpen = () => {
setIsSelectOpen((isSelectOpen) => !isSelectOpen);
};

const handleSelectChange = (chain: number) => {
const handleSelectChange = (chain: number): void => {
if (!isSelectDisabled) {
setSelectedChainId(Number(chain));
}
Expand All @@ -35,6 +29,12 @@ export const ChainSelector = () => {
}
}, [isSelectDisabled, isChainIdInOptions, selectedChainId]);

const placeholderFiller = selectedChainId ? (
`${networkName}: ${placeholder}`
) : (
<span className="placeholder">Select chain id</span>
);

useEffect(() => {
const updatedPlaceholder = chainIdPlaceholder();
setPlaceholder(updatedPlaceholder);
Expand All @@ -44,63 +44,12 @@ export const ChainSelector = () => {
}, [chainIdPlaceholder, placeholder]);

return (
<>
<RadixSelect.Root
disabled={isSelectDisabled}
onValueChange={(val: string) => {
handleSelectChange(Number(val));
}}
onOpenChange={handleIsSelectOpen}
>
<RadixSelect.Trigger
className={`flex items-center ${isSelectOpen && 'py-3 px-5 border border-blueExtraDark'} bg-blueGray rounded-sm font-semibold uppercase`}
aria-label="chain id"
>
<RadixSelect.Value placeholder={`${networkName}: ${placeholder}`}>
{selectedChainId ? (
`${networkName}: ${placeholder}`
) : (
<span className="placeholder">Select chain id</span>
)}
</RadixSelect.Value>

<RadixSelect.Icon className="ml-2">
<div
className={`${
isSelectOpen
? 'transition-transform rotate-180'
: 'transition-transform rotate-0'
} ${isSelectDisabled ? 'hidden' : 'block'}`}
>
<FaChevronDown />
</div>
</RadixSelect.Icon>
</RadixSelect.Trigger>
<RadixSelect.Portal>
<RadixSelect.Content
position="popper"
className="h-fit rounded-md border"
>
<RadixSelect.ScrollUpButton className="SelectScrollButton">
<RadixSelect.ScrollUpButton />
</RadixSelect.ScrollUpButton>
<RadixSelect.Viewport className="max-h-[200px] overflow-y-auto">
{chainIdOptions.map((chain) => (
<RadixSelect.Item
value={chain.value}
key={chain.value}
className="py-3 px-5 bg-background text-lightGray border border-b-0.5 first:rounded-t-md last:rounded-b-sm hover:bg-blueExtraDark"
>
<RadixSelect.ItemText>
{chain.label}: {chain.value}
</RadixSelect.ItemText>
</RadixSelect.Item>
))}
</RadixSelect.Viewport>
<RadixSelect.Arrow />
</RadixSelect.Content>
</RadixSelect.Portal>
</RadixSelect.Root>
</>
<Select
isSelectDisabled={isSelectDisabled}
handleSelectChange={(val: string) => handleSelectChange(Number(val))}
placeholderValue={`${networkName}: ${placeholder}`}
placeholderFiller={placeholderFiller}
selectOptions={chainIdOptions}
/>
);
};
79 changes: 79 additions & 0 deletions src/features/ui/select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import * as RadixSelect from '@radix-ui/react-select';
import { useState } from 'react';
import { FaChevronDown } from 'react-icons/fa';
import { SelectOption, SelectOptions } from '@/lib/chainIdOptions';

export const Select = ({
isSelectDisabled,
handleSelectChange,
placeholderValue,
placeholderFiller,
selectOptions,
}: {
isSelectDisabled: boolean;
handleSelectChange: (val: string) => void;
placeholderValue: string;
placeholderFiller: string | JSX.Element;
selectOptions: SelectOptions;
}) => {
const [isSelectOpen, setIsSelectOpen] = useState(false);

const handleIsSelectOpen = (): void => {
setIsSelectOpen((isSelectOpen) => !isSelectOpen);
};

return (
<>
<RadixSelect.Root
disabled={isSelectDisabled}
onValueChange={(val: string) => handleSelectChange(val)}
onOpenChange={handleIsSelectOpen}
>
<RadixSelect.Trigger
className={`flex items-center ${isSelectOpen && 'py-3 px-5 border border-blueExtraDark'} bg-blueGray rounded-sm font-semibold uppercase`}
aria-label="chain id"
>
<RadixSelect.Value placeholder={placeholderValue}>
{placeholderFiller}
</RadixSelect.Value>

<RadixSelect.Icon className="ml-2">
<div
className={`${
isSelectOpen
? 'transition-transform rotate-180'
: 'transition-transform rotate-0'
} ${isSelectDisabled ? 'hidden' : 'block'}`}
>
<FaChevronDown />
</div>
</RadixSelect.Icon>
</RadixSelect.Trigger>
<RadixSelect.Portal>
<RadixSelect.Content
position="popper"
className="h-fit rounded-md border"
>
<RadixSelect.ScrollUpButton className="SelectScrollButton">
<RadixSelect.ScrollUpButton />
</RadixSelect.ScrollUpButton>
<RadixSelect.Viewport className="max-h-[200px] overflow-y-auto">
{selectOptions.map((option: SelectOption) => (
<RadixSelect.Item
value={option.value}
key={option.value}
className="py-3 px-5 bg-background text-lightGray border border-b-0.5 first:rounded-t-md last:rounded-b-sm hover:bg-blueExtraDark"
>
<RadixSelect.ItemText>
{option.label}: {option.value}
</RadixSelect.ItemText>
</RadixSelect.Item>
))}
</RadixSelect.Viewport>
<RadixSelect.Arrow />
</RadixSelect.Content>
</RadixSelect.Portal>
</RadixSelect.Root>
</>
);
};
6 changes: 4 additions & 2 deletions src/lib/chainIdOptions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export type SelectOptions = {
export type SelectOption = {
value: string;
label: string;
}[];
};

export type SelectOptions = SelectOption[];

export const chainIdOptions: SelectOptions = [
{ value: '1', label: 'Ethereum' },
Expand Down

0 comments on commit d8b1406

Please sign in to comment.