Skip to content

Commit

Permalink
useIcon hook
Browse files Browse the repository at this point in the history
  • Loading branch information
0xAlec committed Aug 14, 2024
1 parent 09e82f7 commit 56a243a
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/internal/svg/fundWallet.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { fill } from '../../styles/theme';

export const FundWalletSvg = (
export const fundWalletSvg = (
<svg
role="img"
aria-label="fund-wallet-svg"
Expand Down
15 changes: 4 additions & 11 deletions src/wallet/components/WalletDropdownFundLink.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
import { isValidElement, useCallback, useMemo } from 'react';
import { FundWalletSvg } from '../../internal/svg/fundWallet';
import { useCallback, useMemo } from 'react';
import { cn, pressable, text as themeText } from '../../styles/theme';
import { version } from '../../version';
import { useIcon } from '../hooks/useIcon';
import type { WalletDropdownFundLinkReact } from '../types';
import { getWindowDimensions } from '../utils/getWindowDimensions';

export function WalletDropdownFundLink({
className,
icon,
icon = 'fundWallet',
rel,
popupFeatures,
openIn = 'tab',
target,
text = 'Fund wallet',
popupSize = 'md',
}: WalletDropdownFundLinkReact) {
const iconSvg = useMemo(() => {
if (icon === undefined) {
return FundWalletSvg;
}
if (isValidElement(icon)) {
return icon;
}
}, [icon]);
const iconSvg = useIcon({ icon });

const currentURL = window.location.href;
const tabName = document.title;
Expand Down
16 changes: 2 additions & 14 deletions src/wallet/components/WalletDropdownLink.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { isValidElement, useMemo } from 'react';
import { walletSvg } from '../../internal/svg/walletSvg';
import { cn, pressable, text } from '../../styles/theme';
import { useIcon } from '../hooks/useIcon';
import type { WalletDropdownLinkReact } from '../types';

export function WalletDropdownLink({
Expand All @@ -11,18 +10,7 @@ export function WalletDropdownLink({
rel,
target,
}: WalletDropdownLinkReact) {
const iconSvg = useMemo(() => {
if (icon === undefined) {
return null;
}
switch (icon) {
case 'wallet':
return walletSvg;
}
if (isValidElement(icon)) {
return icon;
}
}, [icon]);
const iconSvg = useIcon({ icon });

return (
<a
Expand Down
63 changes: 63 additions & 0 deletions src/wallet/hooks/useIcon.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { renderHook } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { fundWalletSvg } from '../../internal/svg/fundWallet';
import { walletSvg } from '../../internal/svg/walletSvg';
import { useIcon } from './useIcon';

describe('useIcon', () => {
it('should return null when icon is undefined', () => {
const { result } = renderHook(() => useIcon({ icon: undefined }));
expect(result.current).toBeNull();
});

it('should return walletSvg when icon is "wallet"', () => {
const { result } = renderHook(() => useIcon({ icon: 'wallet' }));
expect(result.current).toBe(walletSvg);
});

it('should return fundWalletSvg when icon is "fundWallet"', () => {
const { result } = renderHook(() => useIcon({ icon: 'fundWallet' }));
expect(result.current).toBe(fundWalletSvg);
});

it('should memoize the result for undefined', () => {
const { result, rerender } = renderHook(() => useIcon({}), {
initialProps: {},
});

const initialResult = result.current;
rerender({});
expect(result.current).toBe(initialResult);
});

it('should memoize the result for wallet', () => {
const { result, rerender } = renderHook(({ icon }) => useIcon({ icon }), {
initialProps: { icon: 'wallet' },
});

const initialResult = result.current;
rerender({ icon: 'wallet' });
expect(result.current).toBe(initialResult);
});

it('should memoize the result for fundWallet', () => {
const { result, rerender } = renderHook(({ icon }) => useIcon({ icon }), {
initialProps: { icon: 'fundWallet' },
});

const initialResult = result.current;
rerender({ icon: 'fundWallet' });
expect(result.current).toBe(initialResult);
});

it('should memoize the result for custom icon', () => {
const customIcon = <svg aria-label="custom-icon" />;
const { result, rerender } = renderHook(({ icon }) => useIcon({ icon }), {
initialProps: { icon: customIcon },
});

const initialResult = result.current;
rerender({ icon: customIcon });
expect(result.current).toBe(initialResult);
});
});
20 changes: 20 additions & 0 deletions src/wallet/hooks/useIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { isValidElement, useMemo } from 'react';
import { fundWalletSvg } from '../../internal/svg/fundWallet';
import { walletSvg } from '../../internal/svg/walletSvg';

export const useIcon = ({ icon }: { icon?: React.ReactNode }) => {
return useMemo(() => {
if (icon === undefined) {
return null;
}
switch (icon) {
case 'wallet':
return walletSvg;
case 'fundWallet':
return fundWalletSvg;
}
if (isValidElement(icon)) {
return icon;
}
}, [icon]);
};

0 comments on commit 56a243a

Please sign in to comment.