Skip to content

Commit

Permalink
Merge pull request #1087 from rainlanguage/1086-migrate-inputtoken-co…
Browse files Browse the repository at this point in the history
…mponents-to-ui-components

Move InputToken.svelte to ui-components
  • Loading branch information
hardyjosh authored Dec 27, 2024
2 parents 90d5712 + 24d7a5a commit e652f55
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 61 deletions.
39 changes: 39 additions & 0 deletions packages/ui-components/src/__tests__/InputToken.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { render, fireEvent } from '@testing-library/svelte';
import InputToken from '../lib/components/input/InputToken.svelte';

describe('InputToken', () => {
it('renders with initial values', () => {
const address = '0xc0D477556c25C9d67E1f57245C7453DA776B51cf';
const decimals = 10;
const { getByTestId } = render(InputToken, { props: { address, decimals } });

const input = getByTestId('token-address').querySelector('input');
expect(input?.value).toBe('0xc0D477556c25C9d67E1f57245C7453DA776B51cf');
const decimalsInput = getByTestId('token-decimals-input').querySelector('input');
expect(decimalsInput?.value).toBe('10');
});

it('shows error for invalid address', async () => {
const address = 'abc';
const decimals = 0;
const { getByTestId, getByText } = render(InputToken, { props: { address, decimals } });

const addressInput = getByTestId('token-address').querySelector('input') as HTMLInputElement;
await fireEvent.input(addressInput, { target: { value: 'invalidAddress' } });

expect(getByText('Invalid Address')).toBeInTheDocument();
});

it('does not show error for valid address', async () => {
const address = '';
const decimals = 0;
const { getByTestId, queryByText } = render(InputToken, { props: { address, decimals } });

const addressInput = getByTestId('token-address').querySelector('input') as HTMLInputElement;
await fireEvent.input(addressInput, {
target: { value: '0xc0D477556c25C9d67E1f57245C7453DA776B51cf' }
});

expect(queryByText('Invalid Address')).toBeNull();
});
});
7 changes: 7 additions & 0 deletions packages/ui-components/src/additional-svelte-typings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
declare namespace svelteHTML {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface HTMLAttributes<T> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
'on:complete'?: (event: any) => any;
}
}
60 changes: 60 additions & 0 deletions packages/ui-components/src/lib/components/input/InputToken.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<script lang="ts">
import { Helper, Input } from 'flowbite-svelte';
import type { InputMask } from 'imask';
import { imask } from '@imask/svelte';
import { isAddress } from 'viem';
let decimalsRaw: string = '';
export let decimals: number | undefined;
export let address: string = '';
$: isAddressValid = address && address.length > 0 && isAddress(address);
$: {
if (decimals !== undefined) {
decimalsRaw = decimals.toString();
}
}
const decimalsMaskOptions = {
mask: Number,
min: 0,
lazy: false,
scale: 0,
thousandsSeparator: '',
radix: '.'
};
function decimalsComplete({ detail }: { detail: InputMask }) {
decimalsRaw = detail.value;
if (detail.unmaskedValue.length === 0) {
decimals = 0;
} else {
decimals = parseInt(detail.unmaskedValue);
}
}
</script>

<div class="flex w-full items-start justify-start space-x-2">
<div class="grow" data-testid="token-address">
<div class="relative flex">
<Input label="Token Address" name="address" required bind:value={address} />
</div>

{#if !isAddressValid && address.length > 0}
<Helper class="mt-2 text-sm" color="red">Invalid Address</Helper>
{/if}

<Helper class="mt-2 text-sm">Token Address</Helper>
</div>
<div class="w-32 grow-0 break-all" data-testid="token-decimals-input">
<input
type="text"
value={decimalsRaw}
class="focus:border-primary-500 focus:ring-primary-500 dark:focus:border-primary-500 dark:focus:ring-primary-500 block w-full rounded-lg border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 disabled:cursor-not-allowed disabled:opacity-50 rtl:text-right dark:border-gray-500 dark:bg-gray-600 dark:text-white dark:placeholder-gray-400"
use:imask={decimalsMaskOptions}
on:complete={decimalsComplete}
/>
<Helper class="break-word mt-2 text-sm">Decimals</Helper>
</div>
</div>
1 change: 1 addition & 0 deletions packages/ui-components/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export { default as IconSuccess } from './components/IconSuccess.svelte';
export { default as IconTelegram } from './components/IconTelegram.svelte';
export { default as IconWalletConnect } from './components/IconWalletConnect.svelte';
export { default as IconWarning } from './components/IconWarning.svelte';
export { default as InputToken } from './components/input/InputToken.svelte';

//Types
export type { AppStoresInterface } from './types/appStores.ts';
Expand Down
60 changes: 0 additions & 60 deletions tauri-app/src/lib/components/InputToken.svelte

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
vaultDepositApproveCalldata,
vaultDepositCalldata,
} from '$lib/services/vault';
import InputToken from '$lib/components/InputToken.svelte';
import { InputToken } from '@rainlanguage/ui-components';
import InputVaultId from '$lib/components/InputVaultId.svelte';
import { orderbookAddress } from '$lib/stores/settings';
import { checkAllowance, ethersExecute } from '$lib/services/ethersTx';
Expand Down

0 comments on commit e652f55

Please sign in to comment.