Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions src/lib/components/HeroBanner.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,44 @@ Hero banner used as heading on various pages (Community, Trading data, Blog roll
```
-->
<script lang="ts">
export let image: string | undefined = undefined;
export let title: string;
export let subtitle = '';
export let hr = false;
import type { Snippet } from 'svelte';

interface Props {
title: string | Snippet;
subtitle?: string | Snippet;
image?: string;
hr?: boolean;
children?: Snippet;
}

let { image, title, subtitle, hr = false, children }: Props = $props();
</script>

<div class="hero-banner" class:has-image={image}>
<div class="content">
<h1>{@html title}</h1>
<h1>
{#if typeof title === 'function'}
{@render title()}
{:else}
{title}
{/if}
</h1>
<div class="subtitle">
<slot name="subtitle">{@html subtitle}</slot>
{#if typeof subtitle === 'function'}
{@render subtitle()}
{:else}
{subtitle}
{/if}
</div>
{#if hr}
<hr />
{/if}
<slot />
{@render children?.()}
</div>

{#if image}
<div class="media">
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
{@html image}
</div>
{/if}
Expand Down
41 changes: 41 additions & 0 deletions src/lib/top-vaults/DepositEventsCell.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script lang="ts">
import { notFilledMarker } from '$lib/helpers/formatters';

interface Props {
value: number | null;
}

let { value }: Props = $props();

const formatter = new Intl.NumberFormat('en-US', {
notation: 'compact',
compactDisplay: 'short'
});

let { number, unit } = $derived.by(() => {
if (value === null) return { number: notFilledMarker, unit: '' };

const parts = formatter.formatToParts(value);

const number = parts
.filter((p) => p.type === 'integer' || p.type === 'decimal' || p.type === 'fraction')
.map((p) => p.value)
.join('');

const unit = parts.find((p) => p.type === 'compact')?.value || null;

return { number, unit };
});
</script>

<div>
<span>{number}</span>
<span class="unit">{unit}</span>
</div>

<style>
div {
display: inline-flex;
gap: 0.5ex;
}
</style>
6 changes: 2 additions & 4 deletions src/lib/top-vaults/FeesCell.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@
<div class="multiline" slot="trigger">
{#if !isNumber(mgmt_fee) && !isNumber(perf_fee)}
{notFilledMarker}
{:else if mgmt_fee === 0 && perf_fee === 0}
0.0%
{:else}
<div>{formatPercent(mgmt_fee, 1)}</div>
<div>{formatPercent(perf_fee, 1)}</div>
<span>{formatPercent(mgmt_fee, 1)}/</span>
<span>{formatPercent(perf_fee, 1)}</span>
{/if}
</div>
<dl slot="popup" class="fees-popup">
Expand Down
38 changes: 15 additions & 23 deletions src/lib/top-vaults/RiskCell.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,45 @@
const riskClass = risk?.toLowerCase().replace(/ /g, '-') ?? 'unknown';
</script>

<div class={['risk', riskClass]}>
<span class={['risk', riskClass]}>
{risk ?? 'Unknown'}
</div>
</span>

<style>
.risk {
display: inline-grid;
align-items: center;
height: 1.375rem;
padding: 0 0.625rem;
border-radius: 1rem;
font: var(--f-ui-xs-medium);
letter-spacing: 0.02em;
background: var(--c-text-ultra-light);

/* custom text color defs that ignore light/dark mode (always light or dark color) */
--c-always-light: var(--cm-light, var(--c-text-inverted)) var(--cm-dark, var(--c-text));
--c-always-dark: var(--cm-light, var(--c-text)) var(--cm-dark, var(--c-text-inverted));
--c-text-base: var(--c-text-light);
color: color-mix(in srgb, var(--c-text-base), var(--c-risk) 75%);

&.negligible {
background-color: #2d7a2e;
color: var(--c-always-light);
--c-risk: #13b1c0;
}

&.minimal {
background-color: #4caf50;
color: var(--c-text-inverted);
--c-risk: var(--c-success);
}

&.low {
background-color: #fbc02d;
color: var(--c-always-dark);
--c-risk: var(--c-warning);
}

&.high {
background-color: #ff9800;
color: var(--c-text-inverted);
--c-risk: color-mix(in srgb, var(--c-warning), var(--c-error));
}

&.severe {
background-color: #f4511e;
color: var(--c-always-light);
--c-risk: var(--c-error);
}

&.dangerous {
background-color: #c62828;
color: var(--c-always-light);
--c-risk: #c62847;
--c-text-base: var(--c-text);
}

&.unknown {
color: var(--c-text-light);
}
}
</style>
21 changes: 9 additions & 12 deletions src/lib/top-vaults/TopVaultsTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
import { addSortBy, addHiddenColumns, addTableFilter } from 'svelte-headless-table/plugins';
import { createRender } from '$lib/components/datatable/utils';
import { readable } from 'svelte/store';
import { formatDollar, formatNumber, formatPercent, formatTokenAmount, formatValue } from '$lib/helpers/formatters';
import { formatDollar, formatNumber, formatPercent, formatValue } from '$lib/helpers/formatters';
import RiskCell from './RiskCell.svelte';
import DepositEventsCell from './DepositEventsCell.svelte';

interface Props {
topVaults: TopVaults;
Expand Down Expand Up @@ -180,7 +181,7 @@
table.column({
accessor: 'event_count',
header: 'Deposit events',
cell: ({ value }) => formatTokenAmount(value, 0, 1),
cell: ({ value }) => createRender(DepositEventsCell, { value }),
plugins: { filter: { exclude: true } }
}),
table.column({
Expand All @@ -200,7 +201,7 @@
accessor: ({ address, chain_id }) => ({ address, chain_id }),
cell: ({ value: { address, chain_id } }) =>
createRender(CryptoAddressWidget, {
class: 'vault-address tile c',
class: 'vault-address',
size: 'sm',
address,
href: getExplorerUrl(getChain(chain_id), address)
Expand Down Expand Up @@ -410,11 +411,11 @@
}

:global(.vault-address) {
min-width: 8rem;
height: 1.375rem;
padding: 0 0.625rem;
border-radius: 1rem;
font: var(--f-ui-xs-medium);
min-width: 7rem;
padding: 0;
border-radius: 0;
background: transparent !important;
font: var(--f-ui-xs-roman);
letter-spacing: var(--ls-ui-xs, normal);

:global(a):not(:hover) {
Expand Down Expand Up @@ -442,10 +443,6 @@
:global(td.denomination) {
text-align: center;
}

:global(td.risk) {
white-space: nowrap;
}
}
}
</style>
3 changes: 1 addition & 2 deletions src/lib/top-vaults/VaultCell.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

<style>
.protocol {
color: var(--c-text-light);
text-transform: uppercase;
opacity: 0.7;
}
</style>
4 changes: 2 additions & 2 deletions src/routes/glossary/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<main class="glossary-main">
<Section tag="header" padding="md">
<HeroBanner title="DeFi and trading dictionary">
<div slot="subtitle">
{#snippet subtitle()}
<p>Browser explanations for different decentralised finance (DeFi) and technical trading terms.</p>

<p class="glossary-introduction">
Expand All @@ -37,7 +37,7 @@
<a class="body-link" href="/glossary/trading-strategy">trading strategies</a> and
<a class="body-link" href="/glossary/algorithmic-trading">algorithmic trading</a>.
</p>
</div>
{/snippet}
</HeroBanner>
</Section>

Expand Down
4 changes: 2 additions & 2 deletions src/routes/trading-view/[chain=slug]/exchanges/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
<main class="chain-exchanges-page">
<Section tag="header">
<HeroBanner title="{chain.chain_name} DEXes">
<svelte:fragment slot="subtitle">
{#snippet subtitle()}
Browse {exchanges.length} decentralised exchanges on
<a class="body-link" href=".">{chain.chain_name} blockchain</a>.
</svelte:fragment>
{/snippet}
</HeroBanner>
</Section>

Expand Down
4 changes: 2 additions & 2 deletions src/routes/trading-view/[chain=slug]/lending/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
<main class="reserves-index-page">
<Section tag="header">
<HeroBanner title="{chain.chain_name} lending reserves">
<svelte:fragment slot="subtitle">
{#snippet subtitle()}
Browse {formatAmount(totalRowCount)} lending reserves on
<a class="body-link" href=".">{chain.chain_name} blockchain</a>.
</svelte:fragment>
{/snippet}
</HeroBanner>
</Section>

Expand Down
4 changes: 2 additions & 2 deletions src/routes/trading-view/[chain=slug]/tokens/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
<main class="token-index-page">
<Section tag="header">
<HeroBanner title="{chain.chain_name} tokens">
<svelte:fragment slot="subtitle">
{#snippet subtitle()}
Browse {formatAmount(tokens.totalRowCount)} tokens on
<a class="body-link" href=".">{chain.chain_name} blockchain</a>.
</svelte:fragment>
{/snippet}
</HeroBanner>
</Section>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
<main class="pair-index-page">
<Section tag="header">
<HeroBanner title="{chain.chain_name} trading pairs">
<svelte:fragment slot="subtitle">
{#snippet subtitle()}
Browse {formatAmount(pairs.totalRowCount)} trading pairs on
<a class="body-link" href=".">{chain.chain_name} blockchain</a>.
</svelte:fragment>
{/snippet}
</HeroBanner>
</Section>

Expand Down
34 changes: 30 additions & 4 deletions src/routes/trading-view/[chain=slug]/vaults/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<script lang="ts">
import Breadcrumbs from '$lib/breadcrumb/Breadcrumbs.svelte';
import DataBadge from '$lib/components/DataBadge.svelte';
import HeroBanner from '$lib/components/HeroBanner.svelte';
import Section from '$lib/components/Section.svelte';
import { getLogoUrl } from '$lib/helpers/assets';
import TopVaultsTable from '$lib/top-vaults/TopVaultsTable.svelte';

const { data } = $props();
Expand All @@ -18,13 +20,37 @@

<main class="chain-vaults ds-3">
<Section tag="header">
<HeroBanner
title="Top {chainName} Vaults"
subtitle="The best performing DeFi vaults on {chainName} with minimum $50k USD TVL"
/>
<HeroBanner subtitle="The best performing DeFi vaults on {chainName} with minimum $50k USD TVL">
{#snippet title()}
<span>
<img src={getLogoUrl('blockchain', chain.chain_slug)} alt={chain.chain_name} />
<span>Top {chainName} Vaults</span>
<DataBadge class="badge" status="warning">Beta</DataBadge>
</span>
{/snippet}
</HeroBanner>
</Section>

<Section>
<TopVaultsTable {topVaults} apiChain={chain} />
</Section>
</main>

<style>
.chain-vaults {
span {
display: inline-flex;
flex-wrap: wrap;
gap: 0.25em;
align-items: center;
}

img {
height: 1em;
}

:global(.badge) {
font-size: 0.5em;
}
}
</style>
4 changes: 2 additions & 2 deletions src/routes/trading-view/backtesting/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
<main class="backtesting-page">
<Section tag="header">
<HeroBanner title="Historical DEX trading data">
<svelte:fragment slot="subtitle">
{#snippet subtitle()}
<p>
The following datasets are available for historical DEX trading data.
<a class="body-link" href="/trading-view/api">Sign up for a free API key to download the data.</a>
Expand All @@ -91,7 +91,7 @@
how to get started with Trading Strategy Python library for algorithmic trading
</a>.
</p>
</svelte:fragment>
{/snippet}
</HeroBanner>
</Section>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
<main>
<Section tag="header">
<HeroBanner title="Trading pairs with the most {up ? 'profit' : 'loss'} for the last 24h">
<svelte:fragment slot="subtitle">
{#snippet subtitle()}
<a class="body-link" href="/trading-view/trading-pairs">Trading pairs</a>
with the highest {up ? 'profit' : 'drawdown'} on
<a class="body-link" href="/trading-view/exchanges">decentralised exchanges</a>
today. Showing only the pairs with minimum $1M liquidity. All trading pairs are benchmarked against the US Dollar.
</svelte:fragment>
{/snippet}
</HeroBanner>
</Section>

Expand Down
Loading
Loading