-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
194 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,3 +33,4 @@ vite.config.ts.timestamp-* | |
|
||
# Stats directory | ||
stats | ||
_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<script lang="ts"> | ||
import clsx from "clsx" | ||
import { toast } from "svelte-sonner" | ||
import { watch, Debounced } from "runed" | ||
import type { ValidState } from "./index.ts" | ||
import { isValidBech32Address } from "./validator.ts" | ||
import type { HTMLInputAttributes } from "svelte/elements" | ||
interface Props extends HTMLInputAttributes { | ||
class?: string | ||
onValidation: (valid: ValidState) => ValidState | ||
} | ||
let { onValidation, class: className = "", ...props }: Props = $props() | ||
let inputText = $state("") | ||
const debouncedInputText = new Debounced( | ||
() => inputText, | ||
/** | ||
* TODO: change this to 1s and during debounce, show a loading state | ||
*/ | ||
0 | ||
) | ||
let validState: ValidState = $state("PENDING") | ||
$effect(() => { | ||
if (validState === "INVALID") toast.error(`Address is not valid`) | ||
}) | ||
const onAddressSubmit = (event: Event) => { | ||
event.preventDefault() | ||
if (!debouncedInputText.current) return | ||
const addressValidation = isValidBech32Address(debouncedInputText.current) | ||
validState = addressValidation ? "VALID" : "INVALID" | ||
onValidation(validState) | ||
} | ||
</script> | ||
|
||
<form class="flex flex-col gap-2 min-w-[355px]"> | ||
<input | ||
{...props} | ||
type="text" | ||
autocorrect="off" | ||
autocomplete="off" | ||
spellcheck="false" | ||
autocapitalize="none" | ||
bind:value={inputText} | ||
placeholder="union1qp0wtsfltjk9rnvyu3fkdv0s0skp4y5y3py96f" | ||
class={clsx([ | ||
className, | ||
'text-md font-supermolot h-9 px-2 outline-none border-2', | ||
validState === 'VALID' | ||
? 'border-2 border-green-500' | ||
: validState === 'INVALID' | ||
? 'border-2 border-red-500' | ||
: 'border-transparent', | ||
])} | ||
/> | ||
<button | ||
type="button" | ||
onclick={onAddressSubmit} | ||
disabled={inputText.length === 0} | ||
class={clsx([ | ||
'hover:font-bold hover:bg-[#5FDFFC]', | ||
'uppercase text-black w-full bg-[#A0ECFD] text-md font-supermolot h-9 px-2 font-semibold', | ||
])} | ||
> | ||
submit | ||
</button> | ||
</form> | ||
|
||
<style lang="postcss"></style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import AddressForm from "./AddressForm.svelte" | ||
|
||
export type ValidState = "PENDING" | "VALID" | "INVALID" | ||
|
||
export { AddressForm } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { bech32 } from "@scure/base" | ||
|
||
type Bech32Address<T extends string = string> = `${T}1${string}` | ||
export function isValidBech32Address(address: unknown): address is Bech32Address { | ||
if (typeof address !== "string") return false | ||
|
||
try { | ||
const { prefix: _, words } = bech32.decode(address as Bech32Address) | ||
const size = words.length | ||
if ([20, 32].indexOf(size) === -1) return false | ||
return true | ||
} catch { | ||
return false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,63 @@ | ||
<script lang="ts"> | ||
import H1 from "$lib/components/typography/H1.svelte" | ||
import { onMount } from "svelte" | ||
// | ||
// let imageVisible = false | ||
// onMount(() => { | ||
// imageVisible = true | ||
// }) | ||
import { AddressForm, type ValidState } from "$lib/components/address/index.ts" | ||
let addressValidState: ValidState = $state("PENDING") | ||
$effect(() => { | ||
console.info(`ADDRESS VALIDITY STATE: ${addressValidState}`) | ||
}) | ||
</script> | ||
|
||
<section class="relative w-full h-full flex items-center justify-center overflow-hidden"> | ||
<AddressForm class="" onValidation={result => (addressValidState = result)} /> | ||
<div class="max-w-7xl sm:px-6 lg:px-8"> | ||
<div class="max-w-7xl sm:px-6 lg:px-8 fade-in-text"> | ||
<H1 class="text-center"> | ||
Welcome to<br>Union Ceremony | ||
Welcome to<br />Union Ceremony | ||
</H1> | ||
</div> | ||
</div> | ||
<!-- <img--> | ||
<!-- src="/images/whale.png"--> | ||
<!-- alt=""--> | ||
<!-- class="absolute -z-10 w-full h-full object-cover deep-sea-rise"--> | ||
<!-- class:visible={imageVisible}/>--> | ||
</section> | ||
|
||
<style> | ||
.deep-sea-rise { | ||
opacity: 0; | ||
transform: scale(0.5) translateY(140px); | ||
filter: brightness(0.1); | ||
animation: riseFromDepth 2.5s ease-out forwards; | ||
} | ||
.deep-sea-rise { | ||
opacity: 0; | ||
transform: scale(0.5) translateY(140px); | ||
filter: brightness(0.1); | ||
animation: riseFromDepth 2.5s ease-out forwards; | ||
} | ||
.deep-sea-rise.visible { | ||
opacity: 1; | ||
} | ||
.deep-sea-rise.visible { | ||
opacity: 1; | ||
} | ||
@keyframes riseFromDepth { | ||
0% { | ||
opacity: 0; | ||
transform: scale(0.5) translateY(140px); | ||
filter: brightness(0.1); | ||
} | ||
100% { | ||
opacity: 1; | ||
transform: scale(1) translateY(0); | ||
filter: brightness(1); | ||
} | ||
@keyframes riseFromDepth { | ||
0% { | ||
opacity: 0; | ||
transform: scale(0.5) translateY(140px); | ||
filter: brightness(0.1); | ||
} | ||
.fade-in-text { | ||
opacity: 0; | ||
animation: fadeInText 1.5s ease-out forwards; | ||
animation-delay: 2s; | ||
100% { | ||
opacity: 1; | ||
transform: scale(1) translateY(0); | ||
filter: brightness(1); | ||
} | ||
} | ||
.fade-in-text { | ||
opacity: 0; | ||
animation: fadeInText 1.5s ease-out forwards; | ||
animation-delay: 2s; | ||
} | ||
@keyframes fadeInText { | ||
0% { | ||
opacity: 0; | ||
} | ||
100% { | ||
opacity: 1; | ||
} | ||
@keyframes fadeInText { | ||
0% { | ||
opacity: 0; | ||
} | ||
100% { | ||
opacity: 1; | ||
} | ||
} | ||
</style> |