Skip to content

Commit

Permalink
Merge pull request #138 from greymass/ram-polishing
Browse files Browse the repository at this point in the history
RAM pages polishing
  • Loading branch information
aaroncox authored Oct 1, 2024
2 parents dd58de2 + e38a22c commit 6b405a2
Show file tree
Hide file tree
Showing 26 changed files with 570 additions and 211 deletions.
Binary file modified bun.lockb
Binary file not shown.
18 changes: 5 additions & 13 deletions src/lib/components/chart/rampricehistory.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,29 @@
import { Card, Stack } from '$lib/components/layout';
import { Asset } from '@wharfkit/antelope';
import Select from '../select/select.svelte';
import type { ExtendedSelectOption } from '../select/types';
interface Props {
data: { date: Date; value: Asset }[];
debug?: boolean;
}
let { data, debug = true }: Props = $props();
let { data }: Props = $props();
let ctx: HTMLCanvasElement;
let chart: Chart<'line'>;
const range = [
const range: ExtendedSelectOption[] = [
{ label: '1D', value: 1 },
{ label: '1W', value: 7 },
{ label: '1M', value: 30 },
{ label: '1Y', value: 365 }
];
let selectedRange = $state(range[1]);
let selectedRange: ExtendedSelectOption = $state(range[1]);
let dataRange = $derived.by(() => {
const rangeEndDate = dayjs(data[0].date);
const rangeStartDate = rangeEndDate.subtract(selectedRange.value, 'day');
debug && $inspect({ rangeStartDate, rangeEndDate });
const rangeStartDate = rangeEndDate.subtract(Number(selectedRange.value), 'day');
return data.filter(({ date }) => dayjs(date).isAfter(rangeStartDate));
});
Expand Down Expand Up @@ -96,10 +95,6 @@
legend: {
display: false
}
// decimation: {
// enabled: true,
// algorithm: 'lttb'
// }
}
}
});
Expand All @@ -110,9 +105,6 @@
chart.data.datasets[0].data = values;
chart.update();
});
debug &&
$inspect({ dataRangeLength: dataRange.length, currentDate: currentPoint.date, percentChange });
</script>

<Card>
Expand Down
3 changes: 3 additions & 0 deletions src/lib/components/select/elements/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as SelectMenu } from './menu.svelte';
export { default as SelectTrigger } from './trigger.svelte';
export { default as SelectItem } from './item.svelte';
53 changes: 53 additions & 0 deletions src/lib/components/select/elements/item.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<script lang="ts">
import { melt } from '@melt-ui/svelte';
import { Check } from 'lucide-svelte';
import type { Readable } from 'svelte/store';
import type { ExtendedSelectOption } from '../types';
interface Props {
variant?: 'pill' | 'form';
id: string;
// Upstream bug: https://github.com/melt-ui/melt-ui/issues/974
// eslint-disable-next-line @typescript-eslint/no-explicit-any
option: any;
item: ExtendedSelectOption;
isSelected: Readable<(value: unknown) => boolean>;
}
const { option, isSelected, ...props }: Props = $props();
</script>

<div
class="
relative
grid
cursor-pointer
grid-cols-[16px_1fr]
items-center
gap-2
rounded-xl
px-2
py-1
font-medium
hover:bg-solar-500
hover:text-black/95
focus:z-10
focus:text-solar-950
data-[variant=form]:rounded-sm
data-[variant=pill]:rounded-xl
data-[highlighted=true]:bg-solar-500
data-[highlighted=true]:text-solar-950
data-[disabled]:opacity-50
"
data-variant={props.variant}
use:melt={$option(props.item)}
>
{#if props.item.image && typeof props.item.image === 'string'}
<img src={props.item.image} alt={props.item.label} class="mr-2 size-4 object-contain" />
{:else}
<div class="check">
<Check class="size-4 {$isSelected(props.item.value) ? 'block' : 'hidden'}" />
</div>
{/if}
{props.item.label}
</div>
45 changes: 45 additions & 0 deletions src/lib/components/select/elements/menu.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script lang="ts">
import { type AnyMeltElement, melt } from '@melt-ui/svelte';
import { type Snippet } from 'svelte';
import type { Readable } from 'svelte/store';
import { fade } from 'svelte/transition';
interface Props {
variant: 'pill' | 'form';
id: string;
children: Snippet;
open: Readable<boolean>;
menu: AnyMeltElement;
}
const { menu, ...props }: Props = $props();
</script>

{#if props.open}
<div
class="
z-10
flex
max-h-[300px]
flex-col
overflow-y-auto
border-2
border-mineShaft-600
bg-shark-950
py-1
shadow
focus:!ring-0
data-[variant=form]:rounded-lg
data-[variant=pill]:rounded-2xl
data-[variant=form]:px-2
data-[variant=form]:py-2
data-[variant=pill]:px-1
data-[variant=pill]:py-1
"
data-variant={props.variant}
use:melt={$menu}
transition:fade={{ duration: 100 }}
id={props.id + '-menu'}
>
{@render props.children()}
</div>
{/if}
53 changes: 53 additions & 0 deletions src/lib/components/select/elements/trigger.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<script lang="ts">
import { type AnyMeltElement, melt } from '@melt-ui/svelte';
import { ChevronDown } from 'lucide-svelte';
import { type Snippet } from 'svelte';
import { type Readable } from 'svelte/store';
interface Props {
variant?: 'pill' | 'form';
id: string;
children: Snippet;
open: Readable<boolean>;
trigger: AnyMeltElement;
}
const { trigger, open, ...props }: Props = $props();
</script>

<button
class="
flex
items-center
justify-between
gap-2
border-2
border-mineShaft-600
bg-transparent
pl-4
pr-3
font-medium
transition-opacity
hover:opacity-90
focus:outline-2
focus:outline-solar-500
focus-visible:border-transparent
focus-visible:outline
data-[variant=pill]:h-10
data-[variant=form]:rounded-lg
data-[variant=pill]:rounded-full
data-[variant=form]:py-4
"
data-variant={props.variant}
use:melt={$trigger}
aria-label="{props.id}-label"
id={props.id}
>
<div class="flex items-center">
{@render props.children()}
</div>
<ChevronDown
data-open={$open}
class="size-5 transition-transform duration-100 data-[open=true]:rotate-180"
/>
</button>
141 changes: 21 additions & 120 deletions src/lib/components/select/select.svelte
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
<script lang="ts" context="module">
export interface OptionWithImage<T = unknown> extends SelectOption<T> {
image?: string;
}
</script>

<script lang="ts">
import { createSelect, createSync, melt, type SelectOption } from '@melt-ui/svelte';
import { fade } from 'svelte/transition';
import Check from 'lucide-svelte/icons/check';
import ChevronDown from 'lucide-svelte/icons/chevron-down';
import { createSelect, createSync } from '@melt-ui/svelte';
import type { ChangeFn } from '@melt-ui/svelte/internal/helpers';
import { SelectTrigger, SelectMenu, SelectItem } from './elements';
import type { ExtendedSelectOption, SelectOptionVariant } from './types';
interface Props {
options: OptionWithImage[];
selected: OptionWithImage;
variant?: 'pill' | 'form';
options: ExtendedSelectOption[];
selected: ExtendedSelectOption;
onSelectedChange?: ChangeFn<ExtendedSelectOption | undefined>;
variant?: SelectOptionVariant;
id: string;
onSelectedChange?: ChangeFn<SelectOption | undefined>;
required?: boolean;
disabled?: boolean;
multiple?: boolean;
Expand All @@ -40,7 +33,6 @@
states: { open, selected, selectedLabel },
helpers: { isSelected }
} = createSelect({
defaultSelected: _selected || options[0],
onSelectedChange,
required,
disabled,
Expand All @@ -53,120 +45,29 @@
}
});
// Sync the selected option with the passed in selected prop
const sync = createSync({ selected });
$effect(() => {
sync.selected(_selected, (v) => (_selected = v || options[0]));
});
/** Set the value from a parent */
export function set(option: OptionWithImage | null) {
if (!option) {
_selected = options[0];
} else {
_selected = option;
}
}
let selectedOption = $derived.by(() => options.find((o) => o.label === $selectedLabel));
// Get the whole option object
let selectedOption = $derived.by(
() => options.find((o) => o.label === $selectedLabel) || options[0]
);
</script>

<button
class="
flex
items-center
justify-between
gap-2
border-2
border-mineShaft-600
bg-transparent
pl-4
pr-3
font-medium
transition-opacity
hover:opacity-90
focus:outline-2
focus:outline-solar-500
focus-visible:border-transparent
focus-visible:outline
"
class:rounded-full={variant === 'pill'}
class:rounded-lg={variant === 'form'}
class:h-10={variant === 'pill'}
class:py-4={variant === 'form'}
use:melt={$trigger}
aria-label="{id}-label"
{id}
>
<div class="flex items-center">
{#if selectedOption?.image}
<img
src={selectedOption.image}
alt={selectedOption.label}
class="mr-2 size-5 object-contain"
/>
{/if}
{$selectedLabel || 'Select an option'}
</div>
<ChevronDown class="size-5 transition-transform duration-100 {$open ? 'rotate-180' : ''}" />
</button>
<SelectTrigger {variant} {id} {open} {trigger}>
{#if selectedOption.image && typeof selectedOption.image === 'string'}
<img src={selectedOption.image} alt={selectedOption.label} class="mr-2 size-5 object-contain" />
{/if}
{$selectedLabel || 'Select an option'}
</SelectTrigger>

{#if $open}
<div
class="
z-10
flex
max-h-[300px]
flex-col
overflow-y-auto
border-2
border-mineShaft-600
bg-shark-950
py-1
shadow
focus:!ring-0
"
class:px-1={variant === 'pill'}
class:px-2={variant === 'form'}
class:py-1={variant === 'pill'}
class:py-2={variant === 'form'}
class:rounded-2xl={variant === 'pill'}
class:rounded-lg={variant === 'form'}
use:melt={$menu}
transition:fade={{ duration: 100 }}
>
<SelectMenu {id} {variant} {menu} {open}>
{#each options as item}
<div
class="
relative
grid
cursor-pointer
grid-cols-[16px_1fr]
items-center
gap-2
rounded-xl
px-2
py-1
font-medium
hover:bg-solar-500
focus:z-10
focus:text-solar-950
data-[highlighted]:bg-solar-500
data-[highlighted]:text-solar-950
data-[disabled]:opacity-50
"
class:rounded-xl={variant === 'pill'}
class:rounded-sm={variant === 'form'}
use:melt={$option(item)}
>
{#if item.image}
<img src={item.image} alt={item.label} class="mr-2 size-4 object-contain" />
{:else}
<div class="check">
<Check class="size-4 {$isSelected(item.value) ? 'block' : 'hidden'}" />
</div>
{/if}
{item.label}
</div>
<SelectItem {id} {option} {variant} {item} {isSelected} />
{/each}
</div>
</SelectMenu>
{/if}
Loading

0 comments on commit 6b405a2

Please sign in to comment.