compote-ui 0.61.0 → 0.61.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { Select } from '@ark-ui/svelte/select';
|
|
3
3
|
import { Portal } from '@ark-ui/svelte/portal';
|
|
4
|
+
import { useFilter } from '@ark-ui/svelte/locale';
|
|
4
5
|
import { TelInput, countries } from 'svelte-tel-input';
|
|
5
6
|
import type { CountryCode } from 'svelte-tel-input/types';
|
|
6
7
|
import type { PhoneInputProps } from './types';
|
|
@@ -22,28 +23,35 @@
|
|
|
22
23
|
flagClass: `flag-${c.iso2.toLowerCase()}`,
|
|
23
24
|
dialCode: c.dialCode
|
|
24
25
|
}));
|
|
25
|
-
const
|
|
26
|
+
const baseCollection = createListCollection(countryItems);
|
|
27
|
+
|
|
28
|
+
let filterText = $state('');
|
|
29
|
+
const filters = useFilter({ sensitivity: 'base' });
|
|
30
|
+
const collection = $derived(
|
|
31
|
+
filterText
|
|
32
|
+
? baseCollection.filter((label) => filters().contains(label, filterText))
|
|
33
|
+
: baseCollection
|
|
34
|
+
);
|
|
26
35
|
|
|
27
36
|
let {
|
|
28
37
|
value = $bindable(''),
|
|
29
38
|
country = $bindable(null),
|
|
30
39
|
valid = $bindable(false),
|
|
31
40
|
label,
|
|
32
|
-
placeholder,
|
|
33
|
-
name,
|
|
34
41
|
layout = 'vertical',
|
|
35
42
|
disabled,
|
|
36
43
|
readonly,
|
|
37
44
|
invalid,
|
|
38
45
|
required,
|
|
39
46
|
class: className,
|
|
40
|
-
|
|
47
|
+
...restProps
|
|
41
48
|
}: PhoneInputProps = $props();
|
|
42
49
|
|
|
43
50
|
const id = $props.id();
|
|
44
51
|
const numberId = `${id}-number`;
|
|
45
52
|
|
|
46
53
|
const selectedItem = $derived(countryItems.find((c) => c.value === country));
|
|
54
|
+
const showInvalid = $derived(invalid ?? (value.length > 0 && !valid));
|
|
47
55
|
|
|
48
56
|
const rootClass = $derived(
|
|
49
57
|
layout === 'horizontal'
|
|
@@ -63,7 +71,7 @@
|
|
|
63
71
|
class={cn(
|
|
64
72
|
'flex h-9 w-full items-center rounded-md border bg-surface-1 shadow-sm transition-shadow focus-within:ring-1 focus-within:ring-ring',
|
|
65
73
|
'data-disabled:cursor-not-allowed data-disabled:opacity-50',
|
|
66
|
-
|
|
74
|
+
showInvalid && 'border-danger focus-within:ring-danger',
|
|
67
75
|
className
|
|
68
76
|
)}
|
|
69
77
|
data-disabled={disabled ? '' : undefined}
|
|
@@ -74,6 +82,9 @@
|
|
|
74
82
|
onValueChange={(details) => {
|
|
75
83
|
country = (details.items[0]?.value as CountryCode | undefined) ?? null;
|
|
76
84
|
}}
|
|
85
|
+
onOpenChange={(details) => {
|
|
86
|
+
if (!details.open) filterText = '';
|
|
87
|
+
}}
|
|
77
88
|
{disabled}
|
|
78
89
|
readOnly={readonly}
|
|
79
90
|
class="h-9 shrink-0"
|
|
@@ -87,7 +98,6 @@
|
|
|
87
98
|
<span
|
|
88
99
|
class="flag {selectedItem.flagClass} shrink-0 rounded-xs shadow-[inset_0_0_0_1px_var(--compote-border)]"
|
|
89
100
|
></span>
|
|
90
|
-
<span class="font-medium tabular-nums">+{selectedItem.dialCode}</span>
|
|
91
101
|
{:else}
|
|
92
102
|
<span class="text-ink-dim">Country</span>
|
|
93
103
|
{/if}
|
|
@@ -97,22 +107,33 @@
|
|
|
97
107
|
<Portal>
|
|
98
108
|
<Select.Positioner>
|
|
99
109
|
<Select.Content
|
|
100
|
-
class="z-200 max-h-
|
|
110
|
+
class="z-200 flex max-h-72 min-w-52 flex-col overflow-hidden rounded-md border bg-surface-document p-1 shadow-md data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95"
|
|
101
111
|
>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
<Select.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
<input
|
|
113
|
+
type="text"
|
|
114
|
+
bind:value={filterText}
|
|
115
|
+
placeholder="Search"
|
|
116
|
+
class="mb-1 shrink-0 rounded-sm border bg-surface-1 px-2 py-1 text-sm outline-none focus:ring-1 focus:ring-ring"
|
|
117
|
+
onkeydown={(e) => e.stopPropagation()}
|
|
118
|
+
/>
|
|
119
|
+
<div class="overflow-auto">
|
|
120
|
+
{#each collection.items as item (item.value)}
|
|
121
|
+
<Select.Item
|
|
122
|
+
{item}
|
|
123
|
+
class="relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm text-ink transition-colors select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-surface-1 data-[state=checked]:bg-surface-1"
|
|
124
|
+
>
|
|
125
|
+
<span
|
|
126
|
+
class="flag {item.flagClass} shrink-0 rounded-xs shadow-[inset_0_0_0_1px_var(--compote-border)]"
|
|
127
|
+
></span>
|
|
128
|
+
<Select.ItemText class="flex-1 truncate">{item.label}</Select.ItemText>
|
|
129
|
+
<Select.ItemIndicator class="absolute right-2 flex items-center justify-center">
|
|
130
|
+
<PhCheck class="size-3.5" />
|
|
131
|
+
</Select.ItemIndicator>
|
|
132
|
+
</Select.Item>
|
|
133
|
+
{:else}
|
|
134
|
+
<div class="py-2 text-center text-sm text-ink-dim">No results found</div>
|
|
135
|
+
{/each}
|
|
136
|
+
</div>
|
|
116
137
|
</Select.Content>
|
|
117
138
|
</Select.Positioner>
|
|
118
139
|
</Portal>
|
|
@@ -122,12 +143,10 @@
|
|
|
122
143
|
bind:value
|
|
123
144
|
bind:country
|
|
124
145
|
bind:valid
|
|
125
|
-
{name}
|
|
126
|
-
{placeholder}
|
|
127
146
|
{disabled}
|
|
128
147
|
{readonly}
|
|
129
148
|
{required}
|
|
130
|
-
{
|
|
149
|
+
{...restProps}
|
|
131
150
|
class="h-full min-w-0 flex-1 bg-transparent px-3 text-sm outline-none placeholder:text-ink-dim disabled:cursor-not-allowed"
|
|
132
151
|
/>
|
|
133
152
|
</div>
|
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export interface PhoneInputProps {
|
|
1
|
+
import type { Props as TelInputProps } from 'svelte-tel-input/types';
|
|
2
|
+
export interface PhoneInputProps extends Omit<TelInputProps, 'value' | 'class' | 'id' | 'readonly'> {
|
|
3
3
|
value?: string;
|
|
4
|
-
country?: CountryCode | null;
|
|
5
|
-
valid?: boolean;
|
|
6
4
|
label?: string;
|
|
7
|
-
placeholder?: string;
|
|
8
|
-
name?: string;
|
|
9
5
|
layout?: 'vertical' | 'horizontal';
|
|
10
|
-
disabled?: boolean;
|
|
11
6
|
readonly?: boolean;
|
|
12
7
|
invalid?: boolean;
|
|
13
|
-
required?: boolean;
|
|
14
8
|
class?: string;
|
|
15
|
-
options?: TelInputOptions;
|
|
16
9
|
}
|