diff --git a/package-lock.json b/package-lock.json index fda07aa1f..5f4f3574e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,8 @@ "@tauri-apps/plugin-dialog": "^2.2.0", "@tauri-apps/plugin-log": "^2.3.1", "@tauri-apps/plugin-shell": "^2.2.0", - "@tauri-apps/plugin-window-state": "^2.2.1" + "@tauri-apps/plugin-window-state": "^2.2.1", + "zod": "^3.24.4" }, "devDependencies": { "@eslint/js": "^9.22.0", @@ -4837,6 +4838,14 @@ "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz", "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==", "dev": true + }, + "node_modules/zod": { + "version": "3.24.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", + "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 120e44ca0..3354e1681 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,8 @@ "@tauri-apps/plugin-dialog": "^2.2.0", "@tauri-apps/plugin-log": "^2.3.1", "@tauri-apps/plugin-shell": "^2.2.0", - "@tauri-apps/plugin-window-state": "^2.2.1" + "@tauri-apps/plugin-window-state": "^2.2.1", + "zod": "^3.24.4" }, "devDependencies": { "@eslint/js": "^9.22.0", diff --git a/src/components/Border.svelte b/src/components/Border.svelte index fc969a179..6966d6b96 100644 --- a/src/components/Border.svelte +++ b/src/components/Border.svelte @@ -9,6 +9,7 @@ stylePosition?: string; stylePadding?: string; styleHeight?: string; + styleMaxHeight?: string; styleMinHeight?: string; styleMinWidth?: string; styleWidth?: string; @@ -31,6 +32,7 @@ onclick, stylePadding, styleHeight, + styleMaxHeight, styleMinHeight, stylePosition, styleWidth, @@ -245,6 +247,7 @@
+ import type { Snippet } from "svelte"; + import Clipboard from "./Clipboard.svelte"; - const { id }: { id: string } = $props(); + const { + inline = false, + children, + id, + }: { inline?: boolean; children?: Snippet; id: string } = $props(); let clipboard: Clipboard; @@ -10,11 +16,17 @@ .copyable-id { cursor: pointer; color: var(--color-foreground-dim); + gap: 0.25rem; } .copyable-id:hover { color: var(--color-foreground-contrast); } + .inline { + display: inline-flex; + gap: 0; + white-space: nowrap; + } @@ -22,7 +34,12 @@ role="button" tabindex="0" onclick={() => clipboard.copy()} + class:inline class="copyable-id global-flex txt-small txt-monospace"> - {id} + {#if children} + {@render children()} + {:else} + {id} + {/if}
diff --git a/src/components/Header.svelte b/src/components/Header.svelte index e636c2b32..56e11c0b6 100644 --- a/src/components/Header.svelte +++ b/src/components/Header.svelte @@ -1,23 +1,59 @@
@@ -61,7 +106,7 @@ void router.push({ resource: "home" }); }} stylePadding="0 4px"> - + + + {#snippet toggle(onclick)} + + + + {/snippet} + {#snippet popover()} + +
+
+ Getting started +
+
+ Hello + , + + your identity has been created and stored on your machine. +
+
+ Your public key is + {truncateDid(config.publicKey)} + + you can share this with anyone to find you on the network. +
+
+ {#if radicleInstalled()} +
+ Radicle CLI is setup +
+ {:else} +
+
+ Make sure to install + Radicle CLI +
+
+ To be able to interact with repos on the Radicle network + you'll need to install a node on your computer. This node + will identify itself on the network with your keys to push + and pull changes. +
+
+ To install the node and other Radicle CLI tooling, simply + run the command below from your shell: +
+ +
+ {/if} +
+
Guide
+ + +
+ {/snippet} +
+ {:else if name === "checkbox-checked"} + + + + + + {:else if name === "checkbox-unchecked"} + + + + {:else if name === "attachment"} diff --git a/src/components/NodeId.svelte b/src/components/NodeId.svelte index 889d64bf8..61b1dc319 100644 --- a/src/components/NodeId.svelte +++ b/src/components/NodeId.svelte @@ -6,6 +6,7 @@ interface Props { publicKey: string; alias?: string; + inline?: boolean; styleFontSize?: string; styleFontWeight?: string; } @@ -13,6 +14,7 @@ const { publicKey, alias, + inline = false, styleFontSize = "var(--font-size-small)", styleFontWeight = "var(--font-weight-semibold)", }: Props = $props(); @@ -27,15 +29,24 @@ .no-alias { color: var(--color-foreground-dim); } + .inline { + display: inline-flex; + align-items: center; + gap: 0.375rem; + } + .inline .alias { + align-self: baseline; + }
{#if alias} - + {alias} {:else} diff --git a/src/components/OutlineButton.svelte b/src/components/OutlineButton.svelte index 89adebc08..318cf210a 100644 --- a/src/components/OutlineButton.svelte +++ b/src/components/OutlineButton.svelte @@ -2,6 +2,7 @@ import type { Snippet } from "svelte"; interface Props { + popoverToggle?: string; active?: boolean; children: Snippet; disabled?: boolean; @@ -12,6 +13,7 @@ } const { + popoverToggle, active = false, children, disabled = false, @@ -271,6 +273,7 @@
- import { writable } from "svelte/store"; - const focused = writable(undefined); + let focused = $state<{ element: HTMLDivElement; id: string } | undefined>( + undefined, + ); export function closeFocused() { - focused.set(undefined); + focused = undefined; + } + + export function setFocused(id: string) { + const thisComponent = document.querySelector(`[data-popover-id="${id}"]`); + if (thisComponent) { + if (focused?.element === thisComponent) { + closeFocused(); + } else { + focused = { element: thisComponent as HTMLDivElement, id }; + } + } } @@ -13,49 +25,55 @@ interface Props { toggle: Snippet<[() => void]>; popover: Snippet; + popoverId?: string; popoverContainerMinWidth?: string; popoverPadding?: string; popoverPositionBottom?: string; popoverPositionLeft?: string; popoverPositionRight?: string; popoverPositionTop?: string; - expanded?: boolean; } /* eslint-disable prefer-const */ let { toggle, popover, + popoverId, popoverContainerMinWidth, popoverPadding, popoverPositionBottom, popoverPositionLeft, popoverPositionRight, popoverPositionTop, - expanded = $bindable(false), }: Props = $props(); /* eslint-enable prefer-const */ + const id = popoverId ?? crypto.randomUUID(); let thisComponent: HTMLDivElement | undefined = $state(); function clickOutside(ev: MouseEvent | TouchEvent) { - if ($focused && !ev.composedPath().includes($focused)) { - closeFocused(); + const toggleElement = document.querySelector( + `[data-popover-toggle="${id}"]`, + ); + if (focused && !ev.composedPath().includes(focused.element)) { + if ( + thisComponent === focused.element && + !ev.composedPath().includes(toggleElement!) + ) { + closeFocused(); + } } } function toggleFn() { - expanded = !expanded; - if ($focused === thisComponent) { - closeFocused(); - } else { - focused.set(thisComponent); + if (thisComponent) { + if (focused?.element === thisComponent) { + closeFocused(); + } else { + focused = { element: thisComponent, id }; + } } } - - $effect(() => { - expanded = $focused === thisComponent; - }); { if (activeTab) { await loadMoreContent(); } }} hideSidebar - styleSecondColumnOverflow="visible" - publicKey={config.publicKey}> + styleSecondColumnOverflow="visible"> {#snippet headerCenter()} {/snippet} diff --git a/src/views/home/Onboarding.svelte b/src/views/home/Onboarding.svelte deleted file mode 100644 index db868e5c0..000000000 --- a/src/views/home/Onboarding.svelte +++ /dev/null @@ -1,226 +0,0 @@ - - - - -{#snippet tabSnippet(name: typeof tab, content: string)} - { - tab = name; - }}> - {content} - -{/snippet} - -
- You don't have any repositories in your Radicle storage yet. To get started, - try one of the options below. -
- - {@render tabSnippet("create", "Create a new repo")} - {@render tabSnippet("init", "Initialize existing repo")} - - - - {#if tab === "create"} -
-
-
Create a new repo initialized with Radicle.
- -
-
-
Repository name (required)
- { - errors.repoName = []; - validateInput("name"); - }} - placeholder="Name of your repo" /> - {#if errors.repoName.length > 0} - {#each errors.repoName as error} - {#if error.code === "ProjectError.InvalidName" && repoName.length > 0} -
- - - Only alphanumeric characters, '-', '_' and '.' are - allowed. - -
- {/if} - {/each} - {/if} -
- -
-
Description
-