update FramelessButton, PhoneInput, TextInput

- FramelessButton: use cursor-pointer
- PhoneInput: add setCountryByIP with geo lookup
- TextInput: add $bindable ref property
This commit is contained in:
Elijah Duffy
2025-05-06 10:59:42 -07:00
parent be7ef6bdfd
commit 8c27737404
3 changed files with 26 additions and 7 deletions

View File

@@ -23,7 +23,7 @@
<button
class={[
'text-accent hover:text-primary inline-flex items-center gap-1.5 transition-colors',
'text-accent hover:text-primary inline-flex cursor-pointer items-center gap-1.5 transition-colors',
disabled && 'pointer-events-none cursor-not-allowed opacity-50'
]}
{onclick}

View File

@@ -63,6 +63,20 @@
}
};
// setCountryByIP queries ip-api.com for user location based on IP
export const setCountryByIP = async (ip: string) => {
const res = await fetch(`http://ip-api.com/json/${ip}`);
const locationData = await res.json();
let country = 'CA'; // default to Canada
if (locationData.status !== 'fail') {
const { countryCode } = locationData;
country = countryCode;
console.log('updating country code according to IP', country);
}
setCountryByISO(country);
};
// set the default country based on the provided ISO code
if (defaultISO) {
setCountryByISO(defaultISO);

View File

@@ -10,7 +10,8 @@
placeholder,
type,
validate: validateOpts,
invalidMessage
invalidMessage = 'Field is required',
ref = $bindable<HTMLInputElement | null>(null)
}: {
name: string;
label?: string;
@@ -19,6 +20,7 @@
type?: HTMLInputElement['type'];
validate?: ValidatorOptions;
invalidMessage?: string;
ref?: HTMLInputElement | null;
} = $props();
let valid: boolean = $state(true);
@@ -34,15 +36,18 @@
{name}
{type}
bind:value
bind:ref
validate={validateOpts}
onvalidate={(e) => {
valid = e.detail.valid;
}}
/>
<div class={['opacity-0 transition-opacity', !valid && 'opacity-100']}>
<Label for={name} error>
{invalidMessage !== undefined && invalidMessage != '' ? invalidMessage : 'Field is required'}
</Label>
</div>
{#if validateOpts}
<div class={['opacity-0 transition-opacity', !valid && 'opacity-100']}>
<Label for={name} error>
{invalidMessage}
</Label>
</div>
{/if}
</div>