|
1 | 1 | <script lang="ts"> |
2 | | - import AssetText from '$lib/components/elements/asset.svelte'; |
3 | 2 | import { Asset } from '@wharfkit/antelope'; |
| 3 | + import { getContext } from 'svelte'; |
| 4 | + import { Info } from 'lucide-svelte'; |
| 5 | +
|
| 6 | + import AssetText from '$lib/components/elements/asset.svelte'; |
4 | 7 | import TradingPair from '$lib/components/elements/tradingpair.svelte'; |
5 | | - import { cn } from '$lib/utils/style'; |
6 | 8 | import type { NetworkState } from '$lib/state/network.svelte'; |
7 | 9 | import { |
8 | 10 | TokenBalance, |
|
11 | 13 | ZeroUnits, |
12 | 14 | type TokenPair |
13 | 15 | } from '$lib/types/token'; |
14 | | - import { ChevronRight, Info } from 'lucide-svelte'; |
15 | 16 | import * as m from '$lib/paraglide/messages'; |
16 | | - import Button from '../button/button.svelte'; |
17 | | - import { getContext } from 'svelte'; |
| 17 | + import Button from '$lib/components/button/button.svelte'; |
18 | 18 | import type { UnicoveContext } from '$lib/state/client.svelte'; |
19 | | - import Code from '../code.svelte'; |
20 | | - import Link from '../elements/link.svelte'; |
| 19 | + import Code from '$lib/components/code.svelte'; |
| 20 | + import Link from '$lib/components/elements/link.svelte'; |
| 21 | + import Accordion from '$lib/components/accordion.svelte'; |
21 | 22 |
|
22 | 23 | const context = getContext<UnicoveContext>('state'); |
23 | 24 |
|
|
67 | 68 | const balanceDelegated = $derived(_balance.child('delegated')); |
68 | 69 | const balanceUsed = $derived(_balance.child('used')); |
69 | 70 | const balanceWRAM = $derived(_balance.child('wram')); |
70 | | -
|
71 | | - let detailsElement = $state<HTMLDetailsElement>(); |
72 | | -
|
73 | | - const syncOpen = () => { |
74 | | - if (!detailsElement) return; |
75 | | - if (detailsElement.open) { |
76 | | - open = true; |
77 | | - } else { |
78 | | - open = false; |
79 | | - } |
80 | | - }; |
81 | 71 | </script> |
82 | 72 |
|
83 | 73 | {#snippet SubBalance(label: string, value: Asset, action?: { text: string; href: string })} |
|
98 | 88 | </div> |
99 | 89 | {/snippet} |
100 | 90 |
|
101 | | -<details |
102 | | - bind:this={detailsElement} |
103 | | - class={cn('group token-balance-card bg-surface-container rounded-xl', className)} |
104 | | - open={open && _balance instanceof TokenBalance} |
105 | | -> |
106 | | - <summary |
107 | | - class="focus-visible:outline-solar-500 @container flex cursor-pointer justify-between gap-4 rounded-xl p-5 select-none focus-visible:outline" |
108 | | - onclick={syncOpen} |
109 | | - > |
110 | | - <div class="text-muted flex flex-1 flex-wrap justify-between gap-y-4 text-nowrap"> |
111 | | - <!-- Left --> |
112 | | - <div class="left flex flex-col justify-center gap-2"> |
113 | | - <h4 |
114 | | - class="text-on-surface inline-flex items-center gap-2 text-xl leading-none font-bold capitalize" |
| 91 | +{#snippet AccordionHeader()} |
| 92 | + <!-- Left --> |
| 93 | + <div class="left flex flex-col justify-center gap-2"> |
| 94 | + <h4 |
| 95 | + class="text-on-surface inline-flex items-center gap-2 text-xl leading-none font-bold capitalize" |
| 96 | + > |
| 97 | + <img |
| 98 | + class="size-6 object-contain" |
| 99 | + alt="{_balance.token.name} Logo" |
| 100 | + src={_balance.token.media?.logo?.light} |
| 101 | + /> |
| 102 | + {#if isRamToken} |
| 103 | + <Link class="text-on-surface" href="/{network}/ram"> |
| 104 | + {balance.token.name} (RAM) |
| 105 | + </Link> |
| 106 | + {:else} |
| 107 | + <Link |
| 108 | + class="text-on-surface" |
| 109 | + href="/{network}/token/{balance.token.contract}/{balance.token.name}" |
115 | 110 | > |
116 | | - <img |
117 | | - class="size-6 object-contain" |
118 | | - alt="{_balance.token.name} Logo" |
119 | | - src={_balance.token.media?.logo?.light} |
120 | | - /> |
121 | | - {#if isRamToken} |
122 | | - <Link class="text-on-surface" href="/{network}/ram"> |
123 | | - {balance.token.name} (RAM) |
124 | | - </Link> |
125 | | - {:else} |
126 | | - <Link |
127 | | - class="text-on-surface" |
128 | | - href="/{network}/token/{balance.token.contract}/{balance.token.name}" |
129 | | - > |
130 | | - {balance.token.name} |
131 | | - <Info class="text-muted size-5" /> |
132 | | - </Link> |
133 | | - {/if} |
134 | | - </h4> |
135 | | - |
136 | | - {#if pair && hasValue} |
137 | | - {#if pair.price.units.gt(ZeroUnits)} |
138 | | - <TradingPair class="leading-none" {historic} {historicTimeframe} value={pair} /> |
139 | | - {:else} |
140 | | - <div class="bg-surface-container-high h-4 w-32 animate-pulse rounded"> </div> |
141 | | - {/if} |
142 | | - {/if} |
143 | | - </div> |
144 | | - |
145 | | - <!-- Right --> |
146 | | - <div class="right text-muted flex flex-col justify-between gap-2"> |
147 | | - <div class="h-6 w-full content-center"> |
148 | | - <h4 class="text-on-surface text-right text-xl leading-none font-bold capitalize"> |
149 | | - <AssetText value={balance.balance} /> |
150 | | - </h4> |
151 | | - </div> |
152 | | - |
153 | | - {#if pair && hasValue} |
154 | | - {#if value.units.gt(ZeroUnits)} |
155 | | - <AssetText class="leading-none" variant="full" {value} /> |
156 | | - {:else} |
157 | | - <div class="bg-surface-container-high max-w-48 animate-pulse rounded-md"> </div> |
158 | | - {/if} |
159 | | - {/if} |
160 | | - </div> |
161 | | - </div> |
162 | | - |
163 | | - <ChevronRight class="text-muted transition-transform duration-100 group-open:rotate-90" /> |
164 | | - </summary> |
165 | | - |
166 | | - <div class="bg-surface-container-low grid grid-cols-[auto_1fr_auto] rounded-b-xl p-5 pt-3"> |
167 | | - {@render SubBalance( |
168 | | - m.common_available(), |
169 | | - _balance.balance, |
170 | | - !_balance.locked |
171 | | - ? { |
172 | | - text: m.common_send(), |
173 | | - href: `/${network}/send/${balance.token.id.url}` |
174 | | - } |
175 | | - : undefined |
176 | | - )} |
177 | | - |
178 | | - {#if tokenEquals(balance.token.id, network.token.id)} |
179 | | - {#if network.supports('staking') && balanceStaked} |
180 | | - {@render SubBalance(m.common_staked(), balanceStaked.balance, { |
181 | | - text: m.common_staking(), |
182 | | - href: `/${network}/staking` |
183 | | - })} |
| 111 | + {balance.token.name} |
| 112 | + <Info class="text-muted size-5" /> |
| 113 | + </Link> |
184 | 114 | {/if} |
| 115 | + </h4> |
185 | 116 |
|
186 | | - {#if balanceUnstaked && balanceUnstaked.balance.value > 0} |
187 | | - {@render SubBalance(m.common_unstaked(), balanceUnstaked.balance, { |
188 | | - text: m.common_withdraw(), |
189 | | - href: `/${network}/staking/withdraw` |
190 | | - })} |
| 117 | + {#if pair && hasValue} |
| 118 | + {#if pair.price.units.gt(ZeroUnits)} |
| 119 | + <TradingPair class="leading-none" {historic} {historicTimeframe} value={pair} /> |
| 120 | + {:else} |
| 121 | + <div class="bg-surface-container-high h-4 w-32 animate-pulse rounded"> </div> |
191 | 122 | {/if} |
| 123 | + {/if} |
| 124 | + </div> |
192 | 125 |
|
193 | | - {#if balanceDelegated && balanceDelegated.balance.value > 0} |
194 | | - {@render SubBalance(m.common_delegated(), balanceDelegated.balance, { |
195 | | - text: m.common_reclaim(), |
196 | | - href: `/${network}/undelegate` |
197 | | - })} |
198 | | - {/if} |
| 126 | + <!-- Right --> |
| 127 | + <div class="right text-muted flex flex-col justify-between gap-2"> |
| 128 | + <div class="h-6 w-full content-center"> |
| 129 | + <h4 class="text-on-surface text-right text-xl leading-none font-bold capitalize"> |
| 130 | + <AssetText value={balance.balance} /> |
| 131 | + </h4> |
| 132 | + </div> |
199 | 133 |
|
200 | | - {#if balanceRefunding && balanceRefunding.balance.value > 0} |
201 | | - {@render SubBalance(m.common_refunding(), balanceRefunding.balance, { |
202 | | - text: m.common_claim(), |
203 | | - href: `/${network}/refund` |
204 | | - })} |
| 134 | + {#if pair && hasValue} |
| 135 | + {#if value.units.gt(ZeroUnits)} |
| 136 | + <AssetText class="leading-none" variant="full" {value} /> |
| 137 | + {:else} |
| 138 | + <div class="bg-surface-container-high max-w-48 animate-pulse rounded-md"> </div> |
205 | 139 | {/if} |
206 | 140 | {/if} |
| 141 | + </div> |
| 142 | +{/snippet} |
207 | 143 |
|
208 | | - {#if balanceUsed && balanceUsed.balance.value > 0} |
209 | | - {@render SubBalance(m.common_used(), balanceUsed.balance)} |
| 144 | +<Accordion class={className} header={AccordionHeader} {open}> |
| 145 | + {@render SubBalance( |
| 146 | + m.common_available(), |
| 147 | + _balance.balance, |
| 148 | + !_balance.locked |
| 149 | + ? { |
| 150 | + text: m.common_send(), |
| 151 | + href: `/${network}/send/${balance.token.id.url}` |
| 152 | + } |
| 153 | + : undefined |
| 154 | + )} |
| 155 | + |
| 156 | + {#if tokenEquals(balance.token.id, network.token.id)} |
| 157 | + {#if network.supports('staking') && balanceStaked} |
| 158 | + {@render SubBalance(m.common_staked(), balanceStaked.balance, { |
| 159 | + text: m.common_staking(), |
| 160 | + href: `/${network}/staking` |
| 161 | + })} |
210 | 162 | {/if} |
211 | 163 |
|
212 | | - {#if isRamToken && balanceWRAM} |
213 | | - {@render SubBalance('WRAM', balanceWRAM.balance, { |
214 | | - text: m.common_swap(), |
215 | | - href: `/${network}/swap/${balanceWRAM.token.id.url}/${network.getRamToken().id.url}` |
| 164 | + {#if balanceUnstaked && balanceUnstaked.balance.value > 0} |
| 165 | + {@render SubBalance(m.common_unstaked(), balanceUnstaked.balance, { |
| 166 | + text: m.common_withdraw(), |
| 167 | + href: `/${network}/staking/withdraw` |
216 | 168 | })} |
217 | 169 | {/if} |
218 | 170 |
|
219 | | - {#if cta && cta.length} |
220 | | - <div class="col-span-full flex gap-6"> |
221 | | - {#each cta as action} |
222 | | - <Button |
223 | | - class="mt-4 {action.visible ? '' : 'hidden'}" |
224 | | - variant={action.variant || 'secondary'} |
225 | | - href={action.href} |
226 | | - > |
227 | | - {action.text} |
228 | | - </Button> |
229 | | - {/each} |
230 | | - </div> |
| 171 | + {#if balanceDelegated && balanceDelegated.balance.value > 0} |
| 172 | + {@render SubBalance(m.common_delegated(), balanceDelegated.balance, { |
| 173 | + text: m.common_reclaim(), |
| 174 | + href: `/${network}/undelegate` |
| 175 | + })} |
231 | 176 | {/if} |
232 | | - </div> |
233 | 177 |
|
234 | | - {#if debug} |
235 | | - <Code json={_balance} /> |
| 178 | + {#if balanceRefunding && balanceRefunding.balance.value > 0} |
| 179 | + {@render SubBalance(m.common_refunding(), balanceRefunding.balance, { |
| 180 | + text: m.common_claim(), |
| 181 | + href: `/${network}/refund` |
| 182 | + })} |
| 183 | + {/if} |
| 184 | + {/if} |
| 185 | + |
| 186 | + {#if balanceUsed && balanceUsed.balance.value > 0} |
| 187 | + {@render SubBalance(m.common_used(), balanceUsed.balance)} |
| 188 | + {/if} |
| 189 | + |
| 190 | + {#if isRamToken && balanceWRAM} |
| 191 | + {@render SubBalance('WRAM', balanceWRAM.balance, { |
| 192 | + text: m.common_swap(), |
| 193 | + href: `/${network}/swap/${balanceWRAM.token.id.url}/${network.getRamToken().id.url}` |
| 194 | + })} |
236 | 195 | {/if} |
237 | | -</details> |
| 196 | + |
| 197 | + {#if cta && cta.length} |
| 198 | + <div class="col-span-full flex gap-6"> |
| 199 | + {#each cta as action} |
| 200 | + <Button |
| 201 | + class="mt-4 {action.visible ? '' : 'hidden'}" |
| 202 | + variant={action.variant || 'secondary'} |
| 203 | + href={action.href} |
| 204 | + > |
| 205 | + {action.text} |
| 206 | + </Button> |
| 207 | + {/each} |
| 208 | + </div> |
| 209 | + {/if} |
| 210 | +</Accordion> |
| 211 | + |
| 212 | +{#if debug} |
| 213 | + <Code json={_balance} /> |
| 214 | +{/if} |
0 commit comments