@@ -218,9 +218,14 @@ export const ProviderTh = ({ name }) => {
218218 return <img src = { src } alt = { name } className = " rate-explorer-provider-logo" />;
219219};
220220
221- export const DropdownList = ({ currencies , highlightIdx , setHighlightIdx , addCurrency , dropdownQuery , setDropdownQuery , setShowDropdown }) => {
221+ export const DropdownList = ({ currencies , highlightIdx , setHighlightIdx , addCurrency , dropdownQuery , setDropdownQuery , setShowDropdown , disabledCodes }) => {
222222 const listRef = React .useRef (null );
223223 const [scrollState, setScrollState] = React .useState (' top' );
224+ const disabled = disabledCodes || new Set ();
225+ const hasDisabled = disabled .size > 0 ;
226+ const enabledItems = hasDisabled ? currencies .filter (c => ! disabled .has (c .code )) : currencies ;
227+ const disabledItems = hasDisabled ? currencies .filter (c => disabled .has (c .code )) : [];
228+ const sortedCurrencies = hasDisabled ? [... enabledItems , ... disabledItems ] : currencies ;
224229
225230 const updateScroll = React .useCallback (() => {
226231 const el = listRef .current ;
@@ -259,14 +264,16 @@ export const DropdownList = ({ currencies, highlightIdx, setHighlightIdx, addCur
259264 onKeyDown = { (e ) => {
260265 if (e .key === ' ArrowDown' ) {
261266 e .preventDefault ();
262- setHighlightIdx (i => Math .min (i + 1 , currencies .length - 1 ));
267+ setHighlightIdx (i => Math .min (i + 1 , sortedCurrencies .length - 1 ));
263268 } else if (e .key === ' ArrowUp' ) {
264269 e .preventDefault ();
265270 setHighlightIdx (i => Math .max (i - 1 , - 1 ));
266- } else if (e .key === ' Enter' && currencies .length > 0 ) {
271+ } else if (e .key === ' Enter' && sortedCurrencies .length > 0 ) {
267272 e .preventDefault ();
268273 const idx = highlightIdx >= 0 ? highlightIdx : 0 ;
269- addCurrency (currencies [idx ].code );
274+ if (! disabled .has (sortedCurrencies [idx ].code )) {
275+ addCurrency (sortedCurrencies [idx ].code );
276+ }
270277 } else if (e .key === ' Escape' ) {
271278 setShowDropdown (false );
272279 setDropdownQuery (' ' );
@@ -281,14 +288,33 @@ export const DropdownList = ({ currencies, highlightIdx, setHighlightIdx, addCur
281288 onScroll = { updateScroll }
282289 style = { mask ? { WebkitMaskImage: mask , maskImage: mask } : undefined }
283290 >
284- { currencies .map ((c , idx ) => (
285- <button key = { c .code } className = { ' rate-explorer-dropdown-item' + (idx === highlightIdx ? ' rate-explorer-dropdown-item-active' : ' ' )} onClick = { () => addCurrency (c .code )} onMouseEnter = { () => setHighlightIdx (idx )} >
291+ { enabledItems .map ((c , idx ) => (
292+ <button
293+ key = { c .code }
294+ className = { ' rate-explorer-dropdown-item' + (idx === highlightIdx ? ' rate-explorer-dropdown-item-active' : ' ' )}
295+ onClick = { () => addCurrency (c .code )}
296+ onMouseEnter = { () => setHighlightIdx (idx )}
297+ >
286298 <img src = { flagUrl (c .code )} width = " 20" height = " 20" alt = " " className = " rate-explorer-flag-img" />
287299 <span className = " rate-explorer-dropdown-code" >{ c .code } </span >
288300 <span className = " rate-explorer-dropdown-name" >{ c .name } </span >
289301 </button >
290302 ))}
291- { currencies .length === 0 && (
303+ { disabledItems .length > 0 && (
304+ <div className = " rate-explorer-dropdown-divider" >Coming soon</div >
305+ )}
306+ { disabledItems .map ((c , idx ) => (
307+ <button
308+ key = { c .code }
309+ className = { ' rate-explorer-dropdown-item rate-explorer-dropdown-item-disabled' + ((idx + enabledItems .length ) === highlightIdx ? ' rate-explorer-dropdown-item-active' : ' ' )}
310+ onMouseEnter = { () => setHighlightIdx (idx + enabledItems .length )}
311+ >
312+ <img src = { flagUrl (c .code )} width = " 20" height = " 20" alt = " " className = " rate-explorer-flag-img" />
313+ <span className = " rate-explorer-dropdown-code" >{ c .code } </span >
314+ <span className = " rate-explorer-dropdown-name" >{ c .name } </span >
315+ </button >
316+ ))}
317+ { sortedCurrencies .length === 0 && (
292318 <div className = " rate-explorer-dropdown-empty" >No currencies found</div >
293319 )}
294320 </div >
@@ -414,10 +440,14 @@ export const RateExplorer = () => {
414440 } catch (e ) {}
415441 return null ;
416442 });
443+ const [showSourceDropdown, setShowSourceDropdown] = React .useState (false );
444+ const [sourceDropdownQuery, setSourceDropdownQuery] = React .useState (' ' );
445+ const [sourceHighlightIdx, setSourceHighlightIdx] = React .useState (- 1 );
417446 const [debouncedAmount, setDebouncedAmount] = React .useState (1000 );
418447 const [isVisible, setIsVisible] = React .useState (false );
419448 const containerRef = React .useRef (null );
420449 const dropdownRef = React .useRef (null );
450+ const sourceDropdownRef = React .useRef (null );
421451 const explorerRef = React .useRef (null );
422452 const headerBarRef = React .useRef (null );
423453
@@ -517,6 +547,10 @@ export const RateExplorer = () => {
517547 setShowDropdown (false );
518548 setDropdownQuery (' ' );
519549 }
550+ if (sourceDropdownRef .current && ! sourceDropdownRef .current .contains (e .target )) {
551+ setShowSourceDropdown (false );
552+ setSourceDropdownQuery (' ' );
553+ }
520554 };
521555 document .addEventListener (' mousedown' , handleClick );
522556 return () => document .removeEventListener (' mousedown' , handleClick );
@@ -716,6 +750,20 @@ export const RateExplorer = () => {
716750 ! dropdownQuery || c .code .toLowerCase ().includes (dropdownQuery .toLowerCase ()) || c .name .toLowerCase ().includes (dropdownQuery .toLowerCase ())
717751 );
718752
753+ const sourceDropdownCurrencies = CURRENCIES .filter (c =>
754+ ! sourceDropdownQuery || c .code .toLowerCase ().includes (sourceDropdownQuery .toLowerCase ()) || c .name .toLowerCase ().includes (sourceDropdownQuery .toLowerCase ())
755+ );
756+
757+ const disabledSourceCodes = new Set (
758+ CURRENCIES .filter (c => ! SOURCE_CODES .includes (c .code )).map (c => c .code )
759+ );
760+
761+ const selectSource = (code ) => {
762+ setSourceCurrency (code );
763+ setShowSourceDropdown (false );
764+ setSourceDropdownQuery (' ' );
765+ };
766+
719767 return (
720768 <div ref = { containerRef } >
721769 <div ref = { explorerRef } className = " rate-explorer not-prose" >
@@ -733,19 +781,24 @@ export const RateExplorer = () => {
733781 onFocus = { handleAmountFocus }
734782 />
735783 </div >
736- <div className = " rate-explorer-source-trigger" >
737- <img src = { flagUrl (sourceCurrency )} width = " 16" height = " 16" alt = " " className = " rate-explorer-flag-img" />
738- <select
739- className = " rate-explorer-source-select"
740- value = { sourceCurrency }
741- onChange = { (e ) => setSourceCurrency (e .target .value )}
742- >
743- { SOURCE_OPTIONS .map ((opt ) => (
744- <option key = { opt .value } value = { opt .value } >{ opt .label } </option >
745- ))}
746- </select >
747- <span className = " rate-explorer-source-label" >{ sourceCurrency } </span >
748- <svg width = " 12" height = " 12" viewBox = " 0 0 12 12" fill = " none" className = " rate-explorer-chevron" ><path d = " M3 4.5L6 7.5L9 4.5" stroke = " currentColor" strokeWidth = " 1.5" strokeLinecap = " round" strokeLinejoin = " round" /></svg >
784+ <div className = " rate-explorer-dropdown-anchor" ref = { sourceDropdownRef } >
785+ <button className = " rate-explorer-source-trigger" onClick = { () => { setShowSourceDropdown (! showSourceDropdown ); setSourceHighlightIdx (- 1 ); }} >
786+ <img src = { flagUrl (sourceCurrency )} width = " 16" height = " 16" alt = " " className = " rate-explorer-flag-img" />
787+ <span className = " rate-explorer-source-label" >{ sourceCurrency } </span >
788+ <svg width = " 12" height = " 12" viewBox = " 0 0 12 12" fill = " none" className = " rate-explorer-chevron" ><path d = " M3 4.5L6 7.5L9 4.5" stroke = " currentColor" strokeWidth = " 1.5" strokeLinecap = " round" strokeLinejoin = " round" /></svg >
789+ </button >
790+ { showSourceDropdown && (
791+ <DropdownList
792+ currencies = { sourceDropdownCurrencies }
793+ highlightIdx = { sourceHighlightIdx }
794+ setHighlightIdx = { setSourceHighlightIdx }
795+ addCurrency = { selectSource }
796+ dropdownQuery = { sourceDropdownQuery }
797+ setDropdownQuery = { setSourceDropdownQuery }
798+ setShowDropdown = { setShowSourceDropdown }
799+ disabledCodes = { disabledSourceCodes }
800+ />
801+ )}
749802 </div >
750803 </div >
751804 <div className = " rate-explorer-header-mid" >
0 commit comments