@rainlanguage/ui-components 0.0.1-alpha.154 → 0.0.1-alpha.155

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/components/ListViewOrderbookFilters.svelte +1 -1
  2. package/dist/components/ListViewOrderbookFilters.svelte.d.ts +11 -9
  3. package/dist/components/OrderOrVaultHash.svelte.d.ts +1 -1
  4. package/dist/components/TanstackAppTable.svelte +9 -4
  5. package/dist/components/TanstackAppTable.svelte.d.ts +8 -7
  6. package/dist/components/VaultCard.svelte +18 -0
  7. package/dist/components/VaultCard.svelte.d.ts +19 -0
  8. package/dist/components/charts/LightweightChart.svelte +1 -1
  9. package/dist/components/charts/LightweightChart.svelte.d.ts +5 -5
  10. package/dist/components/charts/VaultBalanceChart.svelte +7 -16
  11. package/dist/components/charts/VaultBalanceChart.svelte.d.ts +1 -5
  12. package/dist/components/deployment/DeploymentSteps.svelte +1 -26
  13. package/dist/components/deployment/DepositInput.svelte +4 -4
  14. package/dist/components/deployment/SelectToken.svelte +20 -69
  15. package/dist/components/deployment/SelectToken.svelte.d.ts +1 -3
  16. package/dist/components/deployment/TokenSelectionModal.svelte +72 -45
  17. package/dist/components/deployment/TokenSelectionModal.svelte.d.ts +0 -3
  18. package/dist/components/detail/OrderDetail.svelte +58 -16
  19. package/dist/components/detail/OrderDetail.svelte.d.ts +4 -1
  20. package/dist/components/detail/TanstackOrderQuote.svelte +1 -1
  21. package/dist/components/detail/TanstackOrderQuote.svelte.d.ts +12 -10
  22. package/dist/components/detail/VaultDetail.svelte +3 -4
  23. package/dist/components/detail/VaultDetail.svelte.d.ts +0 -3
  24. package/dist/components/input/InputTokenAmount.svelte +15 -20
  25. package/dist/components/input/InputTokenAmount.svelte.d.ts +3 -3
  26. package/dist/components/tables/OrderAPY.svelte +5 -25
  27. package/dist/components/tables/OrderAPY.svelte.d.ts +1 -4
  28. package/dist/components/tables/OrderTradesListTable.svelte +3 -2
  29. package/dist/components/tables/OrderVaultsVolTable.svelte +30 -23
  30. package/dist/components/tables/OrderVaultsVolTable.svelte.d.ts +1 -4
  31. package/dist/components/tables/OrdersListTable.svelte +31 -8
  32. package/dist/components/tables/OrdersListTable.svelte.d.ts +11 -9
  33. package/dist/components/tables/VaultBalanceChangesTable.svelte +1 -1
  34. package/dist/components/tables/VaultBalanceChangesTable.svelte.d.ts +11 -9
  35. package/dist/components/tables/VaultsListTable.svelte +119 -7
  36. package/dist/components/tables/VaultsListTable.svelte.d.ts +13 -10
  37. package/dist/providers/transactions/TransactionManager.d.ts +26 -2
  38. package/dist/providers/transactions/TransactionManager.js +61 -4
  39. package/dist/types/modal.d.ts +2 -2
  40. package/dist/types/transaction.d.ts +1 -0
  41. package/dist/types/transaction.js +1 -0
  42. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- <script generics="T">import { useRaindexClient } from "../hooks/useRaindexClient";
1
+ <script>import { useRaindexClient } from "../hooks/useRaindexClient";
2
2
  import DropdownActiveNetworks from "./dropdown/DropdownActiveNetworks.svelte";
3
3
  import { page } from "$app/stores";
4
4
  import { isEmpty } from "lodash";
@@ -3,8 +3,8 @@ import type { QueryObserverResult } from '@tanstack/svelte-query';
3
3
  import type { Readable } from 'svelte/store';
4
4
  import type { Address, RaindexVaultToken } from '@rainlanguage/orderbook';
5
5
  import type { AppStoresInterface } from '../types/appStores';
6
- declare class __sveltets_Render<T> {
7
- props(): {
6
+ declare const __propDef: {
7
+ props: {
8
8
  hideZeroBalanceVaults: AppStoresInterface["hideZeroBalanceVaults"];
9
9
  activeAccountsItems: AppStoresInterface["activeAccountsItems"];
10
10
  showMyItemsOnly: AppStoresInterface["showMyItemsOnly"];
@@ -15,14 +15,16 @@ declare class __sveltets_Render<T> {
15
15
  selectedTokens: Address[];
16
16
  tokensQuery: Readable<QueryObserverResult<RaindexVaultToken[], Error>>;
17
17
  };
18
- events(): {} & {
18
+ events: {
19
19
  [evt: string]: CustomEvent<any>;
20
20
  };
21
- slots(): {};
22
- }
23
- export type ListViewOrderbookFiltersProps<T> = ReturnType<__sveltets_Render<T>['props']>;
24
- export type ListViewOrderbookFiltersEvents<T> = ReturnType<__sveltets_Render<T>['events']>;
25
- export type ListViewOrderbookFiltersSlots<T> = ReturnType<__sveltets_Render<T>['slots']>;
26
- export default class ListViewOrderbookFilters<T> extends SvelteComponent<ListViewOrderbookFiltersProps<T>, ListViewOrderbookFiltersEvents<T>, ListViewOrderbookFiltersSlots<T>> {
21
+ slots: {};
22
+ exports?: {} | undefined;
23
+ bindings?: string | undefined;
24
+ };
25
+ export type ListViewOrderbookFiltersProps = typeof __propDef.props;
26
+ export type ListViewOrderbookFiltersEvents = typeof __propDef.events;
27
+ export type ListViewOrderbookFiltersSlots = typeof __propDef.slots;
28
+ export default class ListViewOrderbookFilters extends SvelteComponent<ListViewOrderbookFiltersProps, ListViewOrderbookFiltersEvents, ListViewOrderbookFiltersSlots> {
27
29
  }
28
30
  export {};
@@ -2,7 +2,7 @@ import { SvelteComponent } from "svelte";
2
2
  import type { Address, RaindexOrder, RaindexOrderAsIO, RaindexVault } from '@rainlanguage/orderbook';
3
3
  declare const __propDef: {
4
4
  props: {
5
- orderOrVault: RaindexOrder | RaindexVault | RaindexOrderAsIO;
5
+ orderOrVault: RaindexVault | RaindexOrder | RaindexOrderAsIO;
6
6
  type: "orders" | "vaults";
7
7
  chainId: number;
8
8
  orderbookAddress: Address;
@@ -1,4 +1,4 @@
1
- <script generics="T">import { invalidateTanstackQueries } from "../queries/queryClient";
1
+ <script generics="DataItem, InputData = DataItem[]">import { invalidateTanstackQueries } from "../queries/queryClient";
2
2
  import Refresh from "./icon/Refresh.svelte";
3
3
  import { Button, Table, TableBody, TableBodyRow, TableHead } from "flowbite-svelte";
4
4
  import { createEventDispatcher } from "svelte";
@@ -9,6 +9,11 @@ export let queryKey;
9
9
  export let query;
10
10
  export let emptyMessage = "None found";
11
11
  export let rowHoverable = true;
12
+ export let dataSelector = (pageData) => Array.isArray(pageData) ? pageData : [];
13
+ $: data = $query.data ? {
14
+ ...$query.data,
15
+ pages: $query.data.pages.map((page) => dataSelector(page))
16
+ } : void 0;
12
17
  </script>
13
18
 
14
19
  <div data-testid="title" class="flex h-16 w-full items-center justify-end">
@@ -26,11 +31,11 @@ export let rowHoverable = true;
26
31
  }}
27
32
  />
28
33
  </div>
29
- {#if $query.data?.pages[0].length === 0}
34
+ {#if (data?.pages?.[0]?.length ?? 0) === 0}
30
35
  <div data-testid="emptyMessage" class="text-center text-gray-900 dark:text-white">
31
36
  {emptyMessage}
32
37
  </div>
33
- {:else if $query.data}
38
+ {:else if data}
34
39
  <Table
35
40
  divClass="cursor-pointer rounded-lg overflow-auto dark:border-none border"
36
41
  hoverable={rowHoverable}
@@ -39,7 +44,7 @@ export let rowHoverable = true;
39
44
  <slot name="head" />
40
45
  </TableHead>
41
46
  <TableBody>
42
- {#each $query.data?.pages as page}
47
+ {#each data.pages as page}
43
48
  {#each page as item}
44
49
  <TableBodyRow
45
50
  class="whitespace-nowrap"
@@ -1,11 +1,12 @@
1
1
  import { SvelteComponent } from "svelte";
2
2
  import type { CreateInfiniteQueryResult, InfiniteData } from '@tanstack/svelte-query';
3
- declare class __sveltets_Render<T> {
3
+ declare class __sveltets_Render<DataItem, InputData = DataItem[]> {
4
4
  props(): {
5
5
  queryKey: string;
6
- query: CreateInfiniteQueryResult<InfiniteData<T[], unknown>, Error>;
6
+ query: CreateInfiniteQueryResult<InfiniteData<InputData, unknown>, Error>;
7
7
  emptyMessage?: string;
8
8
  rowHoverable?: boolean;
9
+ dataSelector?: ((pageData: InputData) => DataItem[]) | undefined;
9
10
  };
10
11
  events(): {
11
12
  clickRow: CustomEvent<any>;
@@ -18,13 +19,13 @@ declare class __sveltets_Render<T> {
18
19
  title: {};
19
20
  head: {};
20
21
  bodyRow: {
21
- item: T;
22
+ item: DataItem;
22
23
  };
23
24
  };
24
25
  }
25
- export type TanstackAppTableProps<T> = ReturnType<__sveltets_Render<T>['props']>;
26
- export type TanstackAppTableEvents<T> = ReturnType<__sveltets_Render<T>['events']>;
27
- export type TanstackAppTableSlots<T> = ReturnType<__sveltets_Render<T>['slots']>;
28
- export default class TanstackAppTable<T> extends SvelteComponent<TanstackAppTableProps<T>, TanstackAppTableEvents<T>, TanstackAppTableSlots<T>> {
26
+ export type TanstackAppTableProps<DataItem, InputData = DataItem[]> = ReturnType<__sveltets_Render<DataItem, InputData>['props']>;
27
+ export type TanstackAppTableEvents<DataItem, InputData = DataItem[]> = ReturnType<__sveltets_Render<DataItem, InputData>['events']>;
28
+ export type TanstackAppTableSlots<DataItem, InputData = DataItem[]> = ReturnType<__sveltets_Render<DataItem, InputData>['slots']>;
29
+ export default class TanstackAppTable<DataItem, InputData = DataItem[]> extends SvelteComponent<TanstackAppTableProps<DataItem, InputData>, TanstackAppTableEvents<DataItem, InputData>, TanstackAppTableSlots<DataItem, InputData>> {
29
30
  }
30
31
  export {};
@@ -0,0 +1,18 @@
1
+ <script>import { goto } from "$app/navigation";
2
+ export let vault;
3
+ const handleClick = (event) => {
4
+ event.stopPropagation();
5
+ event.preventDefault();
6
+ goto(`/vaults/${vault.chainId}-${vault.orderbook}-${vault.id}`);
7
+ };
8
+ </script>
9
+
10
+ <button
11
+ type="button"
12
+ class="flex w-full flex-col rounded-xl border border-gray-200 bg-gray-50 px-4 py-3 text-left shadow-sm transition-colors hover:bg-gray-100 dark:border-gray-600 dark:bg-gray-700 dark:hover:bg-gray-600"
13
+ on:click={handleClick}
14
+ data-testid="vault-card"
15
+ >
16
+ <span class="font-semibold text-gray-800 dark:text-gray-200">{vault.token.symbol}</span>
17
+ <span class="text-xs text-gray-500 dark:text-gray-400">{vault.formattedBalance}</span>
18
+ </button>
@@ -0,0 +1,19 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { RaindexVault } from '@rainlanguage/orderbook';
3
+ declare const __propDef: {
4
+ props: {
5
+ vault: RaindexVault;
6
+ };
7
+ events: {
8
+ [evt: string]: CustomEvent<any>;
9
+ };
10
+ slots: {};
11
+ exports?: {} | undefined;
12
+ bindings?: string | undefined;
13
+ };
14
+ export type VaultCardProps = typeof __propDef.props;
15
+ export type VaultCardEvents = typeof __propDef.events;
16
+ export type VaultCardSlots = typeof __propDef.slots;
17
+ export default class VaultCard extends SvelteComponent<VaultCardProps, VaultCardEvents, VaultCardSlots> {
18
+ }
19
+ export {};
@@ -1,4 +1,4 @@
1
- <script generics="T extends keyof SeriesOptionsMap, D, O">import { Spinner } from "flowbite-svelte";
1
+ <script generics="T extends keyof SeriesOptionsMap, O">import { Spinner } from "flowbite-svelte";
2
2
  import {
3
3
  createChart
4
4
  } from "lightweight-charts";
@@ -1,7 +1,7 @@
1
1
  import { SvelteComponent } from "svelte";
2
2
  import type { Readable } from 'svelte/store';
3
3
  import { type IChartApi, type UTCTimestamp, type ISeriesApi, type WhitespaceData, type Time, type DeepPartial, type SeriesOptionsCommon, type SeriesOptionsMap } from 'lightweight-charts';
4
- declare class __sveltets_Render<T extends keyof SeriesOptionsMap, D, O> {
4
+ declare class __sveltets_Render<T extends keyof SeriesOptionsMap, O> {
5
5
  props(): {
6
6
  [x: string]: any;
7
7
  data?: {
@@ -21,9 +21,9 @@ declare class __sveltets_Render<T extends keyof SeriesOptionsMap, D, O> {
21
21
  };
22
22
  slots(): {};
23
23
  }
24
- export type LightweightChartProps<T extends keyof SeriesOptionsMap, D, O> = ReturnType<__sveltets_Render<T, D, O>['props']>;
25
- export type LightweightChartEvents<T extends keyof SeriesOptionsMap, D, O> = ReturnType<__sveltets_Render<T, D, O>['events']>;
26
- export type LightweightChartSlots<T extends keyof SeriesOptionsMap, D, O> = ReturnType<__sveltets_Render<T, D, O>['slots']>;
27
- export default class LightweightChart<T extends keyof SeriesOptionsMap, D, O> extends SvelteComponent<LightweightChartProps<T, D, O>, LightweightChartEvents<T, D, O>, LightweightChartSlots<T, D, O>> {
24
+ export type LightweightChartProps<T extends keyof SeriesOptionsMap, O> = ReturnType<__sveltets_Render<T, O>['props']>;
25
+ export type LightweightChartEvents<T extends keyof SeriesOptionsMap, O> = ReturnType<__sveltets_Render<T, O>['events']>;
26
+ export type LightweightChartSlots<T extends keyof SeriesOptionsMap, O> = ReturnType<__sveltets_Render<T, O>['slots']>;
27
+ export default class LightweightChart<T extends keyof SeriesOptionsMap, O> extends SvelteComponent<LightweightChartProps<T, O>, LightweightChartEvents<T, O>, LightweightChartSlots<T, O>> {
28
28
  }
29
29
  export {};
@@ -1,20 +1,7 @@
1
- <script>import { timestampSecondsToUTCTimestamp } from "../../services/time";
2
- import { createQuery } from "@tanstack/svelte-query";
3
- import TanstackLightweightChartLine from "../charts/TanstackLightweightChartLine.svelte";
4
- import { QKEY_VAULT_CHANGES } from "../../queries/keys";
5
- export let vault;
6
- export let lightweightChartsTheme;
7
- $: query = createQuery({
8
- queryKey: [vault.id, QKEY_VAULT_CHANGES + vault.id, QKEY_VAULT_CHANGES],
9
- queryFn: async () => {
10
- const result = await vault.getBalanceChanges(1);
11
- if (result.error) throw new Error(result.error.msg);
12
- return result.value;
13
- }
14
- });
15
- const Chart = TanstackLightweightChartLine;
16
- </script>
1
+ <!-- TODO: Issue #1989 -->
2
+ <script></script>
17
3
 
4
+ <!--
18
5
  {#if vault && $query.data}
19
6
  <Chart
20
7
  title="Balance history"
@@ -25,4 +12,8 @@ const Chart = TanstackLightweightChartLine;
25
12
  emptyMessage="No deposits or withdrawals found"
26
13
  {lightweightChartsTheme}
27
14
  />
15
+ {/if} -->
16
+
17
+ {#if false}
18
+ <div>TODO: Issue #1989</div>
28
19
  {/if}
@@ -1,10 +1,6 @@
1
1
  import { SvelteComponent } from "svelte";
2
- import type { RaindexVault } from '@rainlanguage/orderbook';
3
2
  declare const __propDef: {
4
- props: {
5
- vault: RaindexVault;
6
- lightweightChartsTheme: any;
7
- };
3
+ props: Record<string, never>;
8
4
  events: {
9
5
  [evt: string]: CustomEvent<any>;
10
6
  };
@@ -36,8 +36,6 @@ let showAdvancedOptions = false;
36
36
  let allTokenInfos = [];
37
37
  let selectTokens = void 0;
38
38
  let checkingDeployment = false;
39
- let availableTokens = [];
40
- let loadingTokens = false;
41
39
  let tokenBalances = /* @__PURE__ */ new Map();
42
40
  const gui = useGui();
43
41
  const registry = useRegistry();
@@ -50,7 +48,6 @@ onMount(async () => {
50
48
  }
51
49
  selectTokens = selectTokensResult.value;
52
50
  await areAllTokensSelected();
53
- await loadAvailableTokens();
54
51
  });
55
52
  $: if (selectTokens?.length === 0 || allTokensSelected) {
56
53
  updateFields();
@@ -71,22 +68,6 @@ let unsubscribeAccount = account.subscribe((account2) => {
71
68
  onDestroy(() => {
72
69
  unsubscribeAccount();
73
70
  });
74
- async function loadAvailableTokens() {
75
- if (loadingTokens) return;
76
- loadingTokens = true;
77
- try {
78
- const result = await gui.getAllTokens();
79
- if (result.error) {
80
- throw new Error(result.error.msg);
81
- }
82
- availableTokens = result.value;
83
- } catch (error) {
84
- DeploymentStepsError.catch(error, DeploymentStepsErrorCode.NO_AVAILABLE_TOKENS);
85
- availableTokens = [];
86
- } finally {
87
- loadingTokens = false;
88
- }
89
- }
90
71
  function getAllGuiConfig() {
91
72
  try {
92
73
  let result = gui.getAllGuiConfig();
@@ -239,13 +220,7 @@ async function handleDeployButtonClick() {
239
220
  description="Select the tokens that you want to use in your order."
240
221
  />
241
222
  {#each selectTokens as token}
242
- <SelectToken
243
- {token}
244
- {onSelectTokenSelect}
245
- {availableTokens}
246
- loading={loadingTokens}
247
- {tokenBalances}
248
- />
223
+ <SelectToken {token} {onSelectTokenSelect} {tokenBalances} />
249
224
  {/each}
250
225
  </div>
251
226
  {/if}
@@ -43,10 +43,10 @@ const getTokenSymbol = async () => {
43
43
  error = errorMessage;
44
44
  }
45
45
  };
46
- function handlePresetClick(preset) {
46
+ async function handlePresetClick(preset) {
47
47
  if (deposit.token?.key) {
48
48
  inputValue = preset;
49
- gui.setDeposit(deposit.token?.key, preset);
49
+ await gui.setDeposit(deposit.token?.key, preset);
50
50
  try {
51
51
  currentDeposit = getCurrentDeposit();
52
52
  } catch (e) {
@@ -54,11 +54,11 @@ function handlePresetClick(preset) {
54
54
  }
55
55
  }
56
56
  }
57
- function handleInput(e) {
57
+ async function handleInput(e) {
58
58
  if (deposit.token?.key) {
59
59
  if (e.currentTarget instanceof HTMLInputElement) {
60
60
  inputValue = e.currentTarget.value;
61
- gui.setDeposit(deposit.token.key, e.currentTarget.value);
61
+ await gui.setDeposit(deposit.token.key, e.currentTarget.value);
62
62
  try {
63
63
  currentDeposit = getCurrentDeposit();
64
64
  } catch (e2) {
@@ -8,15 +8,12 @@ import TokenSelectionModal from "./TokenSelectionModal.svelte";
8
8
  import TokenBalanceComponent from "./TokenBalance.svelte";
9
9
  export let token;
10
10
  export let onSelectTokenSelect;
11
- export let availableTokens = [];
12
- export let loading = false;
13
11
  export let tokenBalances = /* @__PURE__ */ new Map();
14
12
  let inputValue = null;
15
13
  let tokenInfo = null;
16
14
  let error = "";
17
15
  let checking = false;
18
16
  let selectionMode = "dropdown";
19
- let searchQuery = "";
20
17
  let selectedToken = null;
21
18
  const gui = useGui();
22
19
  onMount(async () => {
@@ -33,43 +30,13 @@ onMount(async () => {
33
30
  } catch {
34
31
  }
35
32
  });
36
- $: if (tokenInfo?.address && availableTokens.length > 0) {
37
- const foundToken = availableTokens.find(
38
- (t) => t.address.toLowerCase() === tokenInfo?.address.toLowerCase()
39
- );
40
- selectedToken = foundToken || null;
41
- if (inputValue === null) {
42
- inputValue = tokenInfo.address;
43
- }
44
- if (!foundToken && selectionMode === "dropdown") {
45
- selectionMode = "custom";
46
- }
47
- } else if (tokenInfo?.address && inputValue === null) {
33
+ $: if (tokenInfo?.address && inputValue === null) {
48
34
  inputValue = tokenInfo.address;
49
35
  }
50
36
  function setMode(mode) {
51
37
  selectionMode = mode;
52
38
  error = "";
53
- if (mode === "dropdown") {
54
- searchQuery = "";
55
- if (inputValue && tokenInfo) {
56
- const foundToken = availableTokens.find(
57
- (t) => t.address.toLowerCase() === inputValue?.toLowerCase()
58
- );
59
- if (foundToken) {
60
- selectedToken = foundToken;
61
- } else {
62
- inputValue = null;
63
- tokenInfo = null;
64
- selectedToken = null;
65
- clearTokenSelection();
66
- }
67
- } else {
68
- inputValue = null;
69
- tokenInfo = null;
70
- selectedToken = null;
71
- }
72
- } else if (mode === "custom") {
39
+ if (mode === "custom") {
73
40
  selectedToken = null;
74
41
  tokenInfo = null;
75
42
  inputValue = "";
@@ -82,9 +49,6 @@ function handleTokenSelect(token2) {
82
49
  inputValue = token2.address;
83
50
  saveTokenSelection(token2.address);
84
51
  }
85
- function handleSearch(query) {
86
- searchQuery = query;
87
- }
88
52
  async function saveTokenSelection(address) {
89
53
  checking = true;
90
54
  error = "";
@@ -153,34 +117,26 @@ async function handleInput(event) {
153
117
  {/if}
154
118
  </div>
155
119
 
156
- {#if availableTokens.length > 0 && !loading}
157
- <div class="selection-mode flex gap-2">
158
- <ButtonSelectOption
159
- active={selectionMode === 'dropdown'}
160
- buttonText="Select from list"
161
- clickHandler={() => setMode('dropdown')}
162
- dataTestId="dropdown-mode-button"
163
- />
164
- <ButtonSelectOption
165
- active={selectionMode === 'custom'}
166
- buttonText="Custom address"
167
- clickHandler={() => setMode('custom')}
168
- dataTestId="custom-mode-button"
169
- />
170
- </div>
171
- {/if}
172
-
173
- {#if selectionMode === 'dropdown' && availableTokens.length > 0 && !loading}
174
- <TokenSelectionModal
175
- tokens={availableTokens}
176
- {selectedToken}
177
- onSelect={handleTokenSelect}
178
- searchValue={searchQuery}
179
- onSearch={handleSearch}
120
+ <div class="selection-mode flex gap-2">
121
+ <ButtonSelectOption
122
+ active={selectionMode === 'dropdown'}
123
+ buttonText="Select from list"
124
+ clickHandler={() => setMode('dropdown')}
125
+ dataTestId="dropdown-mode-button"
180
126
  />
127
+ <ButtonSelectOption
128
+ active={selectionMode === 'custom'}
129
+ buttonText="Custom address"
130
+ clickHandler={() => setMode('custom')}
131
+ dataTestId="custom-mode-button"
132
+ />
133
+ </div>
134
+
135
+ {#if selectionMode === 'dropdown'}
136
+ <TokenSelectionModal {selectedToken} onSelect={handleTokenSelect} />
181
137
  {/if}
182
138
 
183
- {#if selectionMode === 'custom' || availableTokens.length === 0}
139
+ {#if selectionMode === 'custom'}
184
140
  <div class="custom-input">
185
141
  <Input
186
142
  type="text"
@@ -193,12 +149,7 @@ async function handleInput(event) {
193
149
  {/if}
194
150
 
195
151
  <div class="token-status">
196
- {#if loading}
197
- <div class="flex h-5 flex-row items-center gap-2">
198
- <Spinner class="h-5 w-5" />
199
- <span>Loading tokens...</span>
200
- </div>
201
- {:else if checking}
152
+ {#if checking}
202
153
  <div class="flex h-5 flex-row items-center gap-2">
203
154
  <Spinner class="h-5 w-5" />
204
155
  <span>Checking...</span>
@@ -1,12 +1,10 @@
1
1
  import { SvelteComponent } from "svelte";
2
- import type { GuiSelectTokensCfg, TokenInfo } from '@rainlanguage/orderbook';
2
+ import type { GuiSelectTokensCfg } from '@rainlanguage/orderbook';
3
3
  import type { TokenBalance } from '../../types/tokenBalance';
4
4
  declare const __propDef: {
5
5
  props: {
6
6
  token: GuiSelectTokensCfg;
7
7
  onSelectTokenSelect: (key: string) => void;
8
- availableTokens?: TokenInfo[];
9
- loading?: boolean;
10
8
  tokenBalances?: Map<string, TokenBalance>;
11
9
  };
12
10
  events: {
@@ -1,20 +1,30 @@
1
1
  <script>import { Input, Button, Modal } from "flowbite-svelte";
2
2
  import { SearchOutline, CheckCircleSolid, ChevronDownSolid } from "flowbite-svelte-icons";
3
- export let tokens = [];
3
+ import { useGui } from "../../hooks/useGui";
4
+ import { onMount, tick } from "svelte";
4
5
  export let selectedToken = null;
5
6
  export let onSelect;
6
- export let searchValue = "";
7
- export let onSearch;
8
7
  let modalOpen = false;
9
- $: filteredTokens = tokens.filter((token) => {
10
- if (!searchValue) return true;
11
- const query = searchValue.toLowerCase();
12
- return token.name.toLowerCase().includes(query) || token.symbol.toLowerCase().includes(query) || token.address.toLowerCase().includes(query);
13
- });
8
+ let searchQuery = "";
9
+ let tokens = [];
10
+ let isSearching = false;
11
+ const gui = useGui();
12
+ async function loadTokens(search) {
13
+ isSearching = true;
14
+ const result = await gui.getAllTokens(search);
15
+ if (result.error) {
16
+ tokens = [];
17
+ } else {
18
+ tokens = result.value;
19
+ }
20
+ isSearching = false;
21
+ }
14
22
  function handleSearch(event) {
15
23
  const target = event.target;
16
- onSearch(target.value);
24
+ searchQuery = target.value;
25
+ loadTokens(searchQuery || void 0);
17
26
  }
27
+ onMount(() => loadTokens());
18
28
  function formatAddress(address) {
19
29
  return `${address.slice(0, 6)}...${address.slice(-4)}`;
20
30
  }
@@ -23,6 +33,14 @@ function handleTokenSelect(token) {
23
33
  modalOpen = false;
24
34
  }
25
35
  $: displayText = selectedToken ? `${selectedToken.name} (${selectedToken.symbol})` : "Select a token...";
36
+ $: if (modalOpen) {
37
+ tick().then(() => {
38
+ const input = document.querySelector(".token-search-input");
39
+ if (input) {
40
+ input.focus();
41
+ }
42
+ });
43
+ }
26
44
  </script>
27
45
 
28
46
  <div class="token-dropdown">
@@ -50,50 +68,59 @@ $: displayText = selectedToken ? `${selectedToken.name} (${selectedToken.symbol}
50
68
  <Input
51
69
  type="text"
52
70
  placeholder="Search tokens..."
53
- bind:value={searchValue}
71
+ bind:value={searchQuery}
54
72
  on:input={handleSearch}
55
- class="pl-10"
73
+ class="token-search-input pl-10"
56
74
  />
57
75
  </div>
58
76
 
59
77
  <div class="token-list max-h-80 overflow-y-auto">
60
- {#each filteredTokens as token (token.address)}
61
- <div
62
- class="token-item flex cursor-pointer items-center border-b border-gray-100 p-3 last:border-b-0 hover:bg-gray-50 dark:border-gray-600 dark:hover:bg-gray-700"
63
- class:bg-blue-50={selectedToken?.address === token.address}
64
- class:dark:bg-blue-900={selectedToken?.address === token.address}
65
- class:border-l-4={selectedToken?.address === token.address}
66
- class:border-l-blue-500={selectedToken?.address === token.address}
67
- on:click={() => handleTokenSelect(token)}
68
- on:keydown={(e) => e.key === 'Enter' && handleTokenSelect(token)}
69
- role="button"
70
- tabindex="0"
71
- >
72
- <div class="token-info flex-grow">
73
- <div class="token-name font-medium text-gray-900 dark:text-white">
74
- {token.name}
75
- </div>
76
- <div class="token-details flex gap-2 text-sm text-gray-500 dark:text-gray-400">
77
- <span class="symbol font-medium">{token.symbol}</span>
78
- <span class="address">{formatAddress(token.address)}</span>
78
+ {#if isSearching}
79
+ <div class="p-4 text-center text-gray-500 dark:text-gray-400">
80
+ <p>Searching tokens...</p>
81
+ </div>
82
+ {:else}
83
+ {#each tokens as token (token.address)}
84
+ <div
85
+ class="token-item flex cursor-pointer items-center border-b border-gray-100 p-3 last:border-b-0 hover:bg-gray-50 dark:border-gray-600 dark:hover:bg-gray-700"
86
+ class:bg-blue-50={selectedToken?.address === token.address}
87
+ class:dark:bg-blue-900={selectedToken?.address === token.address}
88
+ class:border-l-4={selectedToken?.address === token.address}
89
+ class:border-l-blue-500={selectedToken?.address === token.address}
90
+ on:click={() => handleTokenSelect(token)}
91
+ on:keydown={(e) => e.key === 'Enter' && handleTokenSelect(token)}
92
+ role="button"
93
+ tabindex="0"
94
+ >
95
+ <div class="token-info flex-grow">
96
+ <div class="token-name font-medium text-gray-900 dark:text-white">
97
+ {token.name}
98
+ </div>
99
+ <div class="token-details flex gap-2 text-sm text-gray-500 dark:text-gray-400">
100
+ <span class="symbol font-medium">{token.symbol}</span>
101
+ <span class="address">{formatAddress(token.address)}</span>
102
+ </div>
79
103
  </div>
104
+ {#if selectedToken?.address === token.address}
105
+ <CheckCircleSolid class="selected-icon h-5 w-5 text-green-500" />
106
+ {/if}
80
107
  </div>
81
- {#if selectedToken?.address === token.address}
82
- <CheckCircleSolid class="selected-icon h-5 w-5 text-green-500" />
83
- {/if}
84
- </div>
85
- {/each}
108
+ {/each}
86
109
 
87
- {#if filteredTokens.length === 0}
88
- <div class="no-results p-4 text-center text-gray-500 dark:text-gray-400">
89
- <p>No tokens found matching your search.</p>
90
- <button
91
- class="mt-2 text-blue-600 underline hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300"
92
- on:click={() => onSearch('')}
93
- >
94
- Clear search
95
- </button>
96
- </div>
110
+ {#if tokens.length === 0}
111
+ <div class="no-results p-4 text-center text-gray-500 dark:text-gray-400">
112
+ <p>No tokens found matching your search.</p>
113
+ <button
114
+ class="mt-2 text-blue-600 underline hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300"
115
+ on:click={() => {
116
+ searchQuery = '';
117
+ loadTokens();
118
+ }}
119
+ >
120
+ Clear search
121
+ </button>
122
+ </div>
123
+ {/if}
97
124
  {/if}
98
125
  </div>
99
126
  </Modal>
@@ -2,11 +2,8 @@ import { SvelteComponent } from "svelte";
2
2
  import type { TokenInfo } from '@rainlanguage/orderbook';
3
3
  declare const __propDef: {
4
4
  props: {
5
- tokens?: TokenInfo[];
6
5
  selectedToken?: TokenInfo | null;
7
6
  onSelect: (token: TokenInfo) => void;
8
- searchValue?: string;
9
- onSearch: (query: string) => void;
10
7
  };
11
8
  events: {
12
9
  [evt: string]: CustomEvent<any>;