Skip to content

Commit

Permalink
Merge branch 'main' into 2025-01-22-selected-deployment-context
Browse files Browse the repository at this point in the history
  • Loading branch information
hardyjosh authored Jan 23, 2025
2 parents 7a140ff + d3e715b commit 7004c1d
Show file tree
Hide file tree
Showing 14 changed files with 353 additions and 122 deletions.
22 changes: 22 additions & 0 deletions packages/ui-components/src/__tests__/InputHex.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/svelte';
import InputHex from '../lib/components/input/InputHex.svelte';

describe('InputHex', () => {
it('renders an input element', () => {
render(InputHex);
expect(screen.getByRole('textbox')).toBeTruthy();
});

it('initializes with empty string when no value provided', () => {
render(InputHex);
const input = screen.getByRole('textbox') as HTMLInputElement;
expect(input.value).toBe('');
});

it('displays hex value when bigint is provided', () => {
render(InputHex, { props: { value: 255n } });
const input = screen.getByRole('textbox') as HTMLInputElement;
expect(input.value).toBe('0xff');
});
});
50 changes: 50 additions & 0 deletions packages/ui-components/src/lib/components/input/InputHex.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<script lang="ts">
import type { InputMask } from 'imask';
import { imask } from '@imask/svelte';
import { fromHex, toHex } from 'viem';
import { HEX_INPUT_REGEX } from '../../utils/hex';
let valueRaw: string = '';
export let value: bigint | undefined;
export let required = true;
$: {
if (value !== undefined) {
valueRaw = toHex(value);
}
}
const maskOptions = {
// hexadecimal string, optionally starting with 0x
mask: HEX_INPUT_REGEX,
lazy: false
};
function complete({ detail }: { detail: InputMask }) {
valueRaw = detail.value;
if (detail.unmaskedValue.length === 0) {
value = 0n;
} else {
let valuePrefixed = detail.unmaskedValue;
if (detail.unmaskedValue.substring(0, 2) !== '0x') {
valuePrefixed = `0x${valuePrefixed}`;
}
try {
value = fromHex(valuePrefixed as `0x${string}`, 'bigint');
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (e) {
value = 0n;
}
}
}
</script>

<input
{required}
type="text"
value={valueRaw}
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={maskOptions}
on:complete={complete}
/>
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 @@ -60,6 +60,7 @@ export { default as InputToken } from './components/input/InputToken.svelte';
export { default as CodeMirrorDotrain } from './components/CodeMirrorDotrain.svelte';
export { default as License } from './components/License.svelte';
export { default as ButtonDarkMode } from './components/ButtonDarkMode.svelte';
export { default as InputHex } from './components/input/InputHex.svelte';

//Types
export type { AppStoresInterface } from './types/appStores.ts';
Expand Down
6 changes: 6 additions & 0 deletions packages/webapp/src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap"
rel="stylesheet"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
Expand Down
6 changes: 6 additions & 0 deletions packages/webapp/src/lib/__mocks__/MockComponent.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<script lang="ts">
import { props } from './MockComponent';
// whenever the props update, we want to update the store with those
$: $props = $$props;
</script>
3 changes: 3 additions & 0 deletions packages/webapp/src/lib/__mocks__/MockComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { writable } from 'svelte/store';

export const props = writable<unknown>();
187 changes: 120 additions & 67 deletions packages/webapp/src/lib/components/Sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,81 +4,134 @@
SidebarGroup,
SidebarItem,
SidebarWrapper,
SidebarBrand
SidebarBrand,
CloseButton,
Button
} from 'flowbite-svelte';
import { WalletSolid, ReceiptSolid, FileLinesSolid, PlusOutline } from 'flowbite-svelte-icons';
import { page } from '$app/stores';
import {
WalletSolid,
ReceiptSolid,
FileLinesSolid,
PlusOutline,
BarsSolid
} from 'flowbite-svelte-icons';
import {
ButtonDarkMode,
IconTelegram,
IconExternalLink,
logoDark,
logoLight
} from '@rainlanguage/ui-components';
import { onMount } from 'svelte';
export let colorTheme;
export let page;
let sideBarHidden: boolean = false;
let breakPoint: number = 1024;
let width: number;
$: sideBarHidden = width < breakPoint;
onMount(() => {
sideBarHidden = width < breakPoint;
});
const toggleSide = () => {
if (width < breakPoint) {
sideBarHidden = !sideBarHidden;
}
};
</script>

<Sidebar activeUrl={$page.url.pathname} asideClass="w-64 fixed z-10">
<SidebarWrapper divClass="overflow-y-auto py-11 px-3 bg-gray-100 dark:bg-gray-800 min-h-screen">
<SidebarGroup ulClass="">
<SidebarBrand
site={{
name: '',
href: '/',
img: $colorTheme == 'light' ? logoLight : logoDark
}}
imgClass="m-auto"
></SidebarBrand>
</SidebarGroup>
<SidebarGroup border>
<SidebarItem label="Deploy" href="/deploy">
<svelte:fragment slot="icon">
<PlusOutline class="h-5 w-5" />
<span data-testid="sidebar-deploy"></span>
</svelte:fragment>
</SidebarItem>
</SidebarGroup>
<SidebarGroup border>
<SidebarItem label="Orders" href="/orders">
<svelte:fragment slot="icon">
<ReceiptSolid class="h-5 w-5" />
<span data-testid="sidebar-orders"></span>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Vaults" href="/vaults">
<svelte:fragment slot="icon">
<WalletSolid class="h-5 w-5" />
<span data-testid="sidebar-vaults"></span>
</svelte:fragment>
</SidebarItem>
</SidebarGroup>
<SidebarGroup border>
<SidebarItem
label="Documentation"
target="_blank"
href="https://docs.rainlang.xyz/raindex/overview"
>
<svelte:fragment slot="icon">
<IconExternalLink />
<span data-testid="sidebar-documentation"></span>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Ask for help" target="_blank" href="https://t.me/+W0aQ36ptN_E2MjZk">
<svelte:fragment slot="icon">
<IconTelegram />
<span data-testid="sidebar-telegram"></span>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="License" href="/license">
<svelte:fragment slot="icon">
<FileLinesSolid />
<span data-testid="sidebar-license"></span>
</svelte:fragment>
</SidebarItem>
</SidebarGroup>
<SidebarGroup border class="flex justify-start">
<ButtonDarkMode {colorTheme} />
</SidebarGroup>
</SidebarWrapper>
</Sidebar>
<svelte:window bind:innerWidth={width} />
<div>
{#if sideBarHidden}
<Button
on:click={() => (sideBarHidden = false)}
color="alternative"
class="absolute left-2 top-2 flex size-8 items-center p-5 lg:hidden"
data-testid="sidebar-bars"
>
<BarsSolid class="" />
</Button>
{/if}
<Sidebar
activeUrl={page.url.pathname}
asideClass="w-64 z-10 fixed"
bind:hidden={sideBarHidden}
data-testid="sidebar"
>
{#if !sideBarHidden}
<CloseButton
data-testid="close-button"
class="absolute right-3 top-2 z-20 flex size-8 items-center lg:hidden"
on:click={() => (sideBarHidden = true)}
/>
{/if}
<SidebarWrapper divClass="overflow-y-auto py-11 px-3 bg-gray-100 dark:bg-gray-800 min-h-screen">
<SidebarGroup ulClass="">
<SidebarBrand
site={{
name: '',
href: '/',
img: $colorTheme === 'light' ? logoLight : logoDark
}}
imgClass="m-auto"
aClass="mb-0"
></SidebarBrand>
</SidebarGroup>
<SidebarGroup border>
<SidebarItem label="Deploy" href="/deploy" on:click={toggleSide}>
<svelte:fragment slot="icon">
<PlusOutline class="h-5 w-5" />
<span data-testid="sidebar-deploy"></span>
</svelte:fragment>
</SidebarItem>
</SidebarGroup>
<SidebarGroup border>
<SidebarItem label="Orders" href="/orders" on:click={toggleSide}>
<svelte:fragment slot="icon">
<ReceiptSolid class="h-5 w-5" />
<span data-testid="sidebar-orders"></span>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Vaults" href="/vaults" on:click={toggleSide}>
<svelte:fragment slot="icon">
<WalletSolid class="h-5 w-5" />
<span data-testid="sidebar-vaults"></span>
</svelte:fragment>
</SidebarItem>
</SidebarGroup>
<SidebarGroup border>
<SidebarItem
on:click={toggleSide}
label="Documentation"
target="_blank"
href="https://docs.rainlang.xyz/raindex/overview"
>
<svelte:fragment slot="icon">
<IconExternalLink />
<span data-testid="sidebar-documentation"></span>
</svelte:fragment>
</SidebarItem>
<SidebarItem
on:click={toggleSide}
label="Ask for help"
target="_blank"
href="https://t.me/+W0aQ36ptN_E2MjZk"
>
<svelte:fragment slot="icon">
<IconTelegram />
<span data-testid="sidebar-telegram"></span>
</svelte:fragment>
</SidebarItem>
<SidebarItem on:click={toggleSide} label="License" href="/license">
<svelte:fragment slot="icon">
<FileLinesSolid />
<span data-testid="sidebar-license"></span>
</svelte:fragment>
</SidebarItem>
</SidebarGroup>
<SidebarGroup border class="flex justify-start">
<ButtonDarkMode {colorTheme} />
</SidebarGroup>
</SidebarWrapper>
</Sidebar>
</div>
5 changes: 3 additions & 2 deletions packages/webapp/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { QueryClient, QueryClientProvider } from '@tanstack/svelte-query';
import Sidebar from '$lib/components/Sidebar.svelte';
import { colorTheme } from '$lib/darkMode';
import { page } from '$app/stores';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
Expand All @@ -14,8 +15,8 @@

<QueryClientProvider client={queryClient}>
<div class="flex min-h-screen w-full justify-start bg-white dark:bg-gray-900 dark:text-gray-400">
<Sidebar {colorTheme} />
<main class="ml-64 h-full w-full grow overflow-x-auto p-8">
<Sidebar {colorTheme} page={$page} />
<main class="mx-auto h-full w-full grow overflow-x-auto pl-20 pt-8 lg:ml-64 lg:p-8">
<slot />
</main>
</div>
Expand Down
Loading

0 comments on commit 7004c1d

Please sign in to comment.