Our Personal Data Server from scratch!
tranquil.farm
oauth
atproto
pds
rust
postgresql
objectstorage
fun
1<script lang="ts">
2 interface Props {
3 value: string
4 domains: string[]
5 selectedDomain: string
6 disabled?: boolean
7 placeholder?: string
8 id?: string
9 autocomplete?: string
10 onInput: (value: string) => void
11 onDomainChange: (domain: string) => void
12 }
13
14 let {
15 value,
16 domains,
17 selectedDomain,
18 disabled = false,
19 placeholder = 'username',
20 id = 'handle',
21 autocomplete = 'off',
22 onInput,
23 onDomainChange,
24 }: Props = $props()
25
26 const showDomainSelect = $derived(domains.length > 1 && !value.includes('.'))
27</script>
28
29<div class="handle-input-group">
30 <input
31 {id}
32 type="text"
33 value={value}
34 {placeholder}
35 {disabled}
36 autocomplete={autocomplete}
37 required
38 oninput={(e) => onInput((e.target as HTMLInputElement).value)}
39 />
40 {#if showDomainSelect}
41 <select value={selectedDomain} onchange={(e) => onDomainChange((e.target as HTMLSelectElement).value)}>
42 {#each domains as domain}
43 <option value={domain}>.{domain}</option>
44 {/each}
45 </select>
46 {:else if domains.length === 1 && !value.includes('.')}
47 <span class="domain-suffix">.{domains[0]}</span>
48 {/if}
49</div>
50
51<style>
52 .handle-input-group {
53 display: flex;
54 gap: var(--space-2);
55 align-items: center;
56 }
57
58 .handle-input-group input {
59 flex: 1;
60 }
61
62 .handle-input-group select {
63 width: auto;
64 }
65
66 .domain-suffix {
67 color: var(--text-secondary);
68 font-size: var(--text-sm);
69 white-space: nowrap;
70 }
71</style>