Skip to content

Commit

Permalink
SwapSettings
Browse files Browse the repository at this point in the history
  • Loading branch information
0xAlec committed Aug 14, 2024
1 parent b893919 commit 95839ce
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 10 deletions.
24 changes: 14 additions & 10 deletions src/swap/components/Swap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { SwapAmountInput } from './SwapAmountInput';
import { SwapButton } from './SwapButton';
import { SwapMessage } from './SwapMessage';
import { SwapProvider } from './SwapProvider';
import { SwapSettings } from './SwapSettings';
import { SwapToggleButton } from './SwapToggleButton';

export function Swap({
Expand All @@ -15,15 +16,17 @@ export function Swap({
title = 'Swap',
className,
}: SwapReact) {
const { inputs, toggleButton, swapButton, swapMessage } = useMemo(() => {
const childrenArray = Children.toArray(children);
return {
inputs: childrenArray.filter(findComponent(SwapAmountInput)),
toggleButton: childrenArray.find(findComponent(SwapToggleButton)),
swapButton: childrenArray.find(findComponent(SwapButton)),
swapMessage: childrenArray.find(findComponent(SwapMessage)),
};
}, [children]);
const { inputs, toggleButton, swapButton, swapMessage, swapSettings } =
useMemo(() => {
const childrenArray = Children.toArray(children);
return {
inputs: childrenArray.filter(findComponent(SwapAmountInput)),
toggleButton: childrenArray.find(findComponent(SwapToggleButton)),
swapButton: childrenArray.find(findComponent(SwapButton)),
swapMessage: childrenArray.find(findComponent(SwapMessage)),
swapSettings: childrenArray.find(findComponent(SwapSettings)),
};
}, [children]);

return (
<SwapProvider address={address} experimental={experimental}>
Expand All @@ -35,10 +38,11 @@ export function Swap({
)}
data-testid="ockSwap_Container"
>
<div className="mb-4">
<div className="mb-4 flex items-center justify-between">
<h3 className={text.title3} data-testid="ockSwap_Title">
{title}
</h3>
<div className="flex justify-end">{swapSettings}</div>
</div>
{inputs[0]}
<div className="relative h-1">{toggleButton}</div>
Expand Down
35 changes: 35 additions & 0 deletions src/swap/components/SwapSettings.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { render, screen } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { SwapSettings } from './SwapSettings';

describe('SwapSettings', () => {
it('renders with default title', () => {
render(<SwapSettings />);
expect(screen.getByText('Auto')).toBeInTheDocument();
});

it('renders with custom title', () => {
render(<SwapSettings title="Custom" />);
expect(screen.getByText('Custom')).toBeInTheDocument();
});

it('renders custom icon when provided', () => {
const CustomIcon = () => (
<svg data-testid="custom-icon" aria-hidden="true" focusable="false">
<title>Custom Icon</title>
</svg>
);
render(<SwapSettings icon={<CustomIcon />} />);
expect(screen.getByTestId('custom-icon')).toBeInTheDocument();
});

it('applies correct classes to the button', () => {
render(<SwapSettings />);
const button = screen.getByRole('button', {
name: /toggle swap settings/i,
});
expect(button).toHaveClass(
'rounded-full p-2 opacity-50 transition-opacity hover:opacity-100',
);
});
});
32 changes: 32 additions & 0 deletions src/swap/components/SwapSettings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { isValidElement, useMemo } from 'react';
import { SwapSettingsSvg } from '../../internal/svg/swapSettings';
import type { SwapSettingsReact } from '../types';

export function SwapSettings({ icon, title = 'Auto' }: SwapSettingsReact) {
const iconSvg = useMemo(() => {
if (icon === undefined) {
return SwapSettingsSvg;
}
if (isValidElement(icon)) {
return icon;
}
}, [icon]);

return (
<div
className="flex w-full items-center justify-between"
data-testid="ockSwapSettings_Settings"
>
<div className="flex items-center space-x-1">
<h4 className="font-medium text-base">{title}</h4>
<button
type="button"
aria-label="Toggle swap settings"
className="rounded-full p-2 opacity-50 transition-opacity hover:opacity-100"
>
{iconSvg}
</button>
</div>
</div>
);
}
2 changes: 2 additions & 0 deletions src/swap/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ export { Swap } from './components/Swap';
export { SwapAmountInput } from './components/SwapAmountInput';
export { SwapButton } from './components/SwapButton';
export { SwapMessage } from './components/SwapMessage';
export { SwapSettings } from './components/SwapSettings';
export { SwapSettingsContainer } from './components/SwapSettingsContainer';
export { SwapToggleButton } from './components/SwapToggleButton';
export { buildSwapTransaction } from './utils/buildSwapTransaction';
export { getSwapQuote } from './utils/getSwapQuote';
Expand Down
9 changes: 9 additions & 0 deletions src/swap/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,15 @@ export type SwapReact = {
title?: string; // Title for the Swap component. (default: "Swap")
};

export type SwapSettingsReact = {
icon: ReactNode;
title: string;
};

export type SwapSettingsContainerReact = {
className?: string; // Optional className override for top div element.
};

/**
* Note: exported as public Type
*/
Expand Down

0 comments on commit 95839ce

Please sign in to comment.