compote-ui 0.61.0 → 0.62.0
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.
- package/dist/components/password-input/password-input.svelte +45 -0
- package/dist/components/password-input/password-input.svelte.d.ts +5 -0
- package/dist/components/password-input/types.d.ts +7 -0
- package/dist/components/password-input/types.js +1 -0
- package/dist/components/phone-input/phone-input.svelte +43 -24
- package/dist/components/phone-input/types.d.ts +2 -9
- package/dist/icons/PhEye.svelte +19 -0
- package/dist/icons/PhEye.svelte.d.ts +5 -0
- package/dist/icons/PhEyeSlash.svelte +19 -0
- package/dist/icons/PhEyeSlash.svelte.d.ts +5 -0
- package/dist/icons/index.d.ts +2 -0
- package/dist/icons/index.js +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Field } from '@ark-ui/svelte/field';
|
|
3
|
+
import { PasswordInput } from '@ark-ui/svelte/password-input';
|
|
4
|
+
import type { PasswordInputProps } from './types';
|
|
5
|
+
import { PhEye, PhEyeSlash } from '../../icons';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
label,
|
|
9
|
+
layout = 'vertical',
|
|
10
|
+
placeholder,
|
|
11
|
+
class: className,
|
|
12
|
+
...restProps
|
|
13
|
+
}: PasswordInputProps = $props();
|
|
14
|
+
|
|
15
|
+
const rootClass = $derived(
|
|
16
|
+
layout === 'horizontal'
|
|
17
|
+
? 'flex items-center justify-between gap-1.5 w-full data-disabled:opacity-50 data-disabled:grayscale'
|
|
18
|
+
: 'flex flex-col gap-1.5 w-full max-w-72 data-disabled:opacity-50 data-disabled:grayscale'
|
|
19
|
+
);
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<PasswordInput.Root {...restProps} class={className ? `${rootClass} ${className}` : rootClass}>
|
|
23
|
+
{#if label}
|
|
24
|
+
<PasswordInput.Label class="text-sm leading-none font-medium">
|
|
25
|
+
{label}
|
|
26
|
+
<Field.RequiredIndicator />
|
|
27
|
+
</PasswordInput.Label>
|
|
28
|
+
{/if}
|
|
29
|
+
<PasswordInput.Control class="relative isolate">
|
|
30
|
+
<PasswordInput.Input
|
|
31
|
+
{placeholder}
|
|
32
|
+
class="h-9 w-full rounded-md border bg-surface-1 px-3 pr-9 text-sm shadow-sm placeholder:text-ink-dim focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none data-invalid:border-danger data-invalid:focus-visible:ring-danger"
|
|
33
|
+
/>
|
|
34
|
+
<PasswordInput.VisibilityTrigger
|
|
35
|
+
class="absolute top-1/2 right-2 -translate-y-1/2 text-ink-dim hover:text-ink focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
36
|
+
>
|
|
37
|
+
<PasswordInput.Indicator class="flex items-center justify-center">
|
|
38
|
+
{#snippet fallback()}
|
|
39
|
+
<PhEyeSlash class="size-4" />
|
|
40
|
+
{/snippet}
|
|
41
|
+
<PhEye class="size-4" />
|
|
42
|
+
</PasswordInput.Indicator>
|
|
43
|
+
</PasswordInput.VisibilityTrigger>
|
|
44
|
+
</PasswordInput.Control>
|
|
45
|
+
</PasswordInput.Root>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { PasswordInput } from '@ark-ui/svelte/password-input';
|
|
2
|
+
import type { PasswordInputProps } from './types';
|
|
3
|
+
declare const PasswordInput: import("svelte").Component<PasswordInputProps, {}, "">;
|
|
4
|
+
type PasswordInput = ReturnType<typeof PasswordInput>;
|
|
5
|
+
export default PasswordInput;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
let { class: className = '', ...restProps } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<svg
|
|
6
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
+
width="1em"
|
|
8
|
+
height="1em"
|
|
9
|
+
viewBox="0 0 256 256"
|
|
10
|
+
class={className}
|
|
11
|
+
{...restProps}
|
|
12
|
+
>
|
|
13
|
+
<path
|
|
14
|
+
fill="currentColor"
|
|
15
|
+
d="M247.31,124.76c-.35-.79-8.82-19.58-27.65-38.41C194.57,61.26,162.88,48,128,48S61.43,61.26,36.34,86.35C17.51,105.18,9.04,124,8.69,124.76a8,8,0,0,0,0,6.5c.35.79,8.82,19.57,27.65,38.4C61.43,194.74,93.12,208,128,208s66.57-13.26,91.66-38.34c18.83-18.83,27.3-37.61,27.65-38.4A8,8,0,0,0,247.31,124.76ZM128,192c-30.78,0-57.67-11.19-79.93-33.25A133.47,133.47,0,0,1,25,128,133.33,133.33,0,0,1,48.07,97.25C70.33,75.19,97.22,64,128,64s57.67,11.19,79.93,33.25A133.46,133.46,0,0,1,231.05,128C223.84,141.46,192.43,192,128,192Zm0-112a48,48,0,1,0,48,48A48.05,48.05,0,0,0,128,80Zm0,80a32,32,0,1,1,32-32A32,32,0,0,1,128,160Z"
|
|
16
|
+
/>
|
|
17
|
+
</svg>
|
|
18
|
+
|
|
19
|
+
<!-- Icon from Phosphor by Phosphor Icons - https://github.com/phosphor-icons/core/blob/main/LICENSE -->
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
let { class: className = '', ...restProps } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<svg
|
|
6
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
+
width="1em"
|
|
8
|
+
height="1em"
|
|
9
|
+
viewBox="0 0 256 256"
|
|
10
|
+
class={className}
|
|
11
|
+
{...restProps}
|
|
12
|
+
>
|
|
13
|
+
<path
|
|
14
|
+
fill="currentColor"
|
|
15
|
+
d="M53.92,34.62A8,8,0,1,0,42.08,45.38L61.32,66.55C25,88.84,9.38,123.2,8.69,124.76a8,8,0,0,0,0,6.5c.35.79,8.82,19.57,27.65,38.4C61.43,194.74,93.12,208,128,208a127.11,127.11,0,0,0,52.07-10.83l21.41,23.55a8,8,0,1,0,11.84-10.76Zm84.16,114.84-37.6-41.36a24,24,0,0,1,37.6,41.36ZM128,192c-30.78,0-57.67-11.19-79.93-33.25A133.47,133.47,0,0,1,25,128c4.69-8.79,19.66-33.39,47.35-49.38l18.81,20.69a40,40,0,0,0,54.75,54.75l14.6,16.07A111.59,111.59,0,0,1,128,192Zm6-95.43a8,8,0,0,1,3.07-15.72,40.07,40.07,0,0,1,32.49,32.5,8,8,0,0,1-6.6,9.2,8.1,8.1,0,0,1-1.31.11,8,8,0,0,1-7.89-6.71A24,24,0,0,0,134,96.57Zm113.28,34.69c-.42.94-10.55,23.37-33.36,43.8a8,8,0,1,1-10.59-12c17.54-15.52,26.4-32.32,28.97-37.06A133.46,133.46,0,0,0,207.93,97.25,135.05,135.05,0,0,0,128,64a121.7,121.7,0,0,0-26.15,2.93,8,8,0,1,1-3.46-15.62A137.39,137.39,0,0,1,128,48c34.88,0,66.57,13.26,91.66,38.35,18.83,18.83,27.3,37.61,27.65,38.41A8,8,0,0,1,247.31,131.26Z"
|
|
16
|
+
/>
|
|
17
|
+
</svg>
|
|
18
|
+
|
|
19
|
+
<!-- Icon from Phosphor by Phosphor Icons - https://github.com/phosphor-icons/core/blob/main/LICENSE -->
|
package/dist/icons/index.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export { default as PhCaretDown } from './PhCaretDown.svelte';
|
|
|
9
9
|
export { default as PhCaretRight } from './PhCaretRight.svelte';
|
|
10
10
|
export { default as PhCaretUp } from './PhCaretUp.svelte';
|
|
11
11
|
export { default as PhCheck } from './PhCheck.svelte';
|
|
12
|
+
export { default as PhEye } from './PhEye.svelte';
|
|
13
|
+
export { default as PhEyeSlash } from './PhEyeSlash.svelte';
|
|
12
14
|
export { default as PhFile } from './PhFile.svelte';
|
|
13
15
|
export { default as PhFileArchive } from './PhFileArchive.svelte';
|
|
14
16
|
export { default as PhFileText } from './PhFileText.svelte';
|
package/dist/icons/index.js
CHANGED
|
@@ -9,6 +9,8 @@ export { default as PhCaretDown } from './PhCaretDown.svelte';
|
|
|
9
9
|
export { default as PhCaretRight } from './PhCaretRight.svelte';
|
|
10
10
|
export { default as PhCaretUp } from './PhCaretUp.svelte';
|
|
11
11
|
export { default as PhCheck } from './PhCheck.svelte';
|
|
12
|
+
export { default as PhEye } from './PhEye.svelte';
|
|
13
|
+
export { default as PhEyeSlash } from './PhEyeSlash.svelte';
|
|
12
14
|
export { default as PhFile } from './PhFile.svelte';
|
|
13
15
|
export { default as PhFileArchive } from './PhFileArchive.svelte';
|
|
14
16
|
export { default as PhFileText } from './PhFileText.svelte';
|
package/dist/index.d.ts
CHANGED
|
@@ -37,6 +37,8 @@ export { default as JsonTreeView } from './components/json-tree-view/json-tree-v
|
|
|
37
37
|
export * as Listbox from './components/listbox';
|
|
38
38
|
export { default as NumberInput } from './components/number-input/number-input.svelte';
|
|
39
39
|
export type { NumberInputProps } from './components/number-input/types';
|
|
40
|
+
export { default as PasswordInput } from './components/password-input/password-input.svelte';
|
|
41
|
+
export type { PasswordInputProps } from './components/password-input/types';
|
|
40
42
|
export { default as PhoneInput } from './components/phone-input/phone-input.svelte';
|
|
41
43
|
export type { PhoneInputProps } from './components/phone-input/types';
|
|
42
44
|
export * as Popover from './components/popover';
|
package/dist/index.js
CHANGED
|
@@ -27,6 +27,7 @@ export { default as ImageCropDialog } from './components/image-crop-dialog/image
|
|
|
27
27
|
export { default as JsonTreeView } from './components/json-tree-view/json-tree-view.svelte';
|
|
28
28
|
export * as Listbox from './components/listbox';
|
|
29
29
|
export { default as NumberInput } from './components/number-input/number-input.svelte';
|
|
30
|
+
export { default as PasswordInput } from './components/password-input/password-input.svelte';
|
|
30
31
|
export { default as PhoneInput } from './components/phone-input/phone-input.svelte';
|
|
31
32
|
export * as Popover from './components/popover';
|
|
32
33
|
export { default as QrCode } from './components/qr-code/qr-code.svelte';
|