noph-ui 0.17.11 → 0.17.12
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/autocomplete/AutoComplete.svelte +146 -0
- package/dist/autocomplete/AutoComplete.svelte.d.ts +4 -0
- package/dist/autocomplete/index.d.ts +1 -0
- package/dist/autocomplete/index.js +1 -0
- package/dist/autocomplete/types.d.ts +12 -0
- package/dist/autocomplete/types.js +1 -0
- package/dist/checkbox/Checkbox.svelte.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/menu/Menu.svelte +2 -1
- package/dist/text-field/TextField.svelte +11 -2
- package/dist/text-field/TextField.svelte.d.ts +1 -1
- package/dist/text-field/types.d.ts +2 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +1 -0
- package/package.json +9 -9
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Item from '../list/Item.svelte'
|
|
3
|
+
import Menu from '../menu/Menu.svelte'
|
|
4
|
+
import VirtualList from '../select/VirtualList.svelte'
|
|
5
|
+
import { tick } from 'svelte'
|
|
6
|
+
import type { AutoCompleteOption, AutoCompleteProps } from './types.ts'
|
|
7
|
+
import TextField from '../text-field/TextField.svelte'
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
options = [],
|
|
11
|
+
value = $bindable(),
|
|
12
|
+
variant = 'filled',
|
|
13
|
+
element = $bindable(),
|
|
14
|
+
onchange,
|
|
15
|
+
oninput,
|
|
16
|
+
reportValidity = $bindable(),
|
|
17
|
+
checkValidity = $bindable(),
|
|
18
|
+
clampMenuWidth = false,
|
|
19
|
+
children,
|
|
20
|
+
optionsFilter = (option) => {
|
|
21
|
+
return !value || option.value.includes(value)
|
|
22
|
+
},
|
|
23
|
+
oncomplete = (option) => {
|
|
24
|
+
value = option.value
|
|
25
|
+
console.log(menuElement)
|
|
26
|
+
menuElement?.hidePopover()
|
|
27
|
+
},
|
|
28
|
+
onblur,
|
|
29
|
+
onclick,
|
|
30
|
+
...attributes
|
|
31
|
+
}: AutoCompleteProps = $props()
|
|
32
|
+
|
|
33
|
+
const uid = $props.id()
|
|
34
|
+
let displayOptions = $derived(options.filter(optionsFilter))
|
|
35
|
+
let useVirtualList = $derived(displayOptions.length > 4000)
|
|
36
|
+
let clientWidth = $state(0)
|
|
37
|
+
let menuOpen = $state(false)
|
|
38
|
+
let menuElement: HTMLDivElement | undefined = $state()
|
|
39
|
+
|
|
40
|
+
const handleOptionSelect = (event: Event, option: AutoCompleteOption) => {
|
|
41
|
+
value = option.value
|
|
42
|
+
menuElement?.hidePopover()
|
|
43
|
+
event.preventDefault()
|
|
44
|
+
// tick().then(() => {
|
|
45
|
+
// if (checkValidity?.()) {
|
|
46
|
+
// errorRaw = error
|
|
47
|
+
// errorTextRaw = errorText
|
|
48
|
+
// }
|
|
49
|
+
// element?.dispatchEvent(new Event('change', { bubbles: true }))
|
|
50
|
+
// })
|
|
51
|
+
}
|
|
52
|
+
$effect(() => {
|
|
53
|
+
if (displayOptions.length) {
|
|
54
|
+
menuElement?.showPopover()
|
|
55
|
+
} else {
|
|
56
|
+
menuElement?.hidePopover()
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
{#snippet item(option: AutoCompleteOption)}
|
|
62
|
+
<Item
|
|
63
|
+
onclick={() => {
|
|
64
|
+
oncomplete(option)
|
|
65
|
+
element?.focus()
|
|
66
|
+
}}
|
|
67
|
+
disabled={option.disabled}
|
|
68
|
+
onkeydown={(event) => {
|
|
69
|
+
if (event.key === 'ArrowDown') {
|
|
70
|
+
;(event.currentTarget?.nextElementSibling as HTMLElement)?.focus()
|
|
71
|
+
event.preventDefault()
|
|
72
|
+
}
|
|
73
|
+
if (event.key === 'ArrowUp') {
|
|
74
|
+
;(event.currentTarget?.previousElementSibling as HTMLElement)?.focus()
|
|
75
|
+
event.preventDefault()
|
|
76
|
+
}
|
|
77
|
+
if (event.key === 'Enter') {
|
|
78
|
+
oncomplete(option)
|
|
79
|
+
}
|
|
80
|
+
if (event.key === 'Tab') {
|
|
81
|
+
menuElement?.hidePopover()
|
|
82
|
+
}
|
|
83
|
+
}}
|
|
84
|
+
variant="button"
|
|
85
|
+
>{option.value}
|
|
86
|
+
</Item>
|
|
87
|
+
{/snippet}
|
|
88
|
+
|
|
89
|
+
<TextField
|
|
90
|
+
{variant}
|
|
91
|
+
bind:clientWidth
|
|
92
|
+
bind:value
|
|
93
|
+
style="anchor-name:--{uid};"
|
|
94
|
+
onclick={async (
|
|
95
|
+
event: MouseEvent & {
|
|
96
|
+
currentTarget: EventTarget & HTMLInputElement
|
|
97
|
+
},
|
|
98
|
+
) => {
|
|
99
|
+
if (displayOptions.length) {
|
|
100
|
+
menuElement?.showPopover()
|
|
101
|
+
}
|
|
102
|
+
onclick?.(event)
|
|
103
|
+
}}
|
|
104
|
+
onfocus={() => {
|
|
105
|
+
if (displayOptions.length) {
|
|
106
|
+
menuElement?.showPopover()
|
|
107
|
+
}
|
|
108
|
+
}}
|
|
109
|
+
bind:reportValidity
|
|
110
|
+
bind:checkValidity
|
|
111
|
+
bind:element
|
|
112
|
+
{...attributes}>{@render children?.()}</TextField
|
|
113
|
+
>
|
|
114
|
+
<Menu
|
|
115
|
+
style="position-anchor:--{uid};{clampMenuWidth || useVirtualList
|
|
116
|
+
? 'width'
|
|
117
|
+
: 'min-width'}:{clientWidth}px"
|
|
118
|
+
role="listbox"
|
|
119
|
+
--np-menu-justify-self="none"
|
|
120
|
+
--np-menu-position-area="bottom span-right"
|
|
121
|
+
--np-menu-margin="2px 0"
|
|
122
|
+
--np-menu-container-shape={variant === 'outlined'
|
|
123
|
+
? 'var(--np-outlined-select-text-field-container-shape)'
|
|
124
|
+
: 'var(--np-filled-select-text-field-container-shape)'}
|
|
125
|
+
anchor={element}
|
|
126
|
+
ontoggle={({ newState }) => {
|
|
127
|
+
if (newState === 'open') {
|
|
128
|
+
menuOpen = true
|
|
129
|
+
} else {
|
|
130
|
+
menuOpen = false
|
|
131
|
+
}
|
|
132
|
+
}}
|
|
133
|
+
bind:element={menuElement}
|
|
134
|
+
>
|
|
135
|
+
{#if useVirtualList}
|
|
136
|
+
<VirtualList height="250px" itemHeight={56} items={displayOptions}>
|
|
137
|
+
{#snippet row(option)}
|
|
138
|
+
{@render item(option)}
|
|
139
|
+
{/snippet}
|
|
140
|
+
</VirtualList>
|
|
141
|
+
{:else}
|
|
142
|
+
{#each displayOptions as option, index (index)}
|
|
143
|
+
{@render item(option)}
|
|
144
|
+
{/each}
|
|
145
|
+
{/if}
|
|
146
|
+
</Menu>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AutoCompleteProps } from './types.ts';
|
|
2
|
+
declare const AutoComplete: import("svelte").Component<AutoCompleteProps, {}, "element" | "value" | "reportValidity" | "checkValidity">;
|
|
3
|
+
type AutoComplete = ReturnType<typeof AutoComplete>;
|
|
4
|
+
export default AutoComplete;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as AutoComplete } from './AutoComplete.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as AutoComplete } from './AutoComplete.svelte';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { InputFieldProps } from '../types.ts';
|
|
2
|
+
export interface AutoCompleteOption {
|
|
3
|
+
value: string;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
selected?: boolean | undefined | null;
|
|
6
|
+
}
|
|
7
|
+
export interface AutoCompleteProps extends Omit<InputFieldProps, 'clientWidth' | 'clientHeight'> {
|
|
8
|
+
options: AutoCompleteOption[];
|
|
9
|
+
optionsFilter?: (option: AutoCompleteOption) => boolean;
|
|
10
|
+
oncomplete?: (option: AutoCompleteOption) => void;
|
|
11
|
+
clampMenuWidth?: boolean;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { CheckboxProps } from './types.ts';
|
|
2
|
-
declare const Checkbox: import("svelte").Component<CheckboxProps, {}, "element" | "group" | "
|
|
2
|
+
declare const Checkbox: import("svelte").Component<CheckboxProps, {}, "element" | "group" | "checked" | "indeterminate">;
|
|
3
3
|
type Checkbox = ReturnType<typeof Checkbox>;
|
|
4
4
|
export default Checkbox;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/menu/Menu.svelte
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
showPopover = $bindable(),
|
|
9
9
|
hidePopover = $bindable(),
|
|
10
10
|
style,
|
|
11
|
+
popover = 'auto',
|
|
11
12
|
...attributes
|
|
12
13
|
}: MenuProps = $props()
|
|
13
14
|
|
|
@@ -119,7 +120,7 @@
|
|
|
119
120
|
menuOpen = newState === 'open'
|
|
120
121
|
attributes.ontoggle?.(event)
|
|
121
122
|
}}
|
|
122
|
-
popover
|
|
123
|
+
{popover}
|
|
123
124
|
class={['np-menu-container', attributes.class]}
|
|
124
125
|
>
|
|
125
126
|
<div class="np-menu">
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
children,
|
|
25
25
|
onfocus,
|
|
26
26
|
onblur,
|
|
27
|
+
clientWidth = $bindable(),
|
|
28
|
+
clientHeight = $bindable(),
|
|
27
29
|
...attributes
|
|
28
30
|
}: TextFieldProps = $props()
|
|
29
31
|
|
|
@@ -95,6 +97,7 @@
|
|
|
95
97
|
})
|
|
96
98
|
</script>
|
|
97
99
|
|
|
100
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
98
101
|
<div
|
|
99
102
|
style={(variant === 'outlined'
|
|
100
103
|
? '--_label-text-color:var(--np-outlined-text-field-label-text-color);--top-space:1rem;--bottom-space:1rem;--floating-label-top:-0.5rem;--floating-label-left:-2.25rem;--_focus-outline-width:3px;'
|
|
@@ -104,11 +107,16 @@
|
|
|
104
107
|
(children ? '--top-space:2rem;--bottom-space:1rem;' : '')) + style}
|
|
105
108
|
class={['text-field', attributes.class]}
|
|
106
109
|
bind:this={element}
|
|
110
|
+
bind:clientWidth
|
|
111
|
+
bind:clientHeight
|
|
107
112
|
role="button"
|
|
108
|
-
tabindex="
|
|
113
|
+
tabindex="0"
|
|
109
114
|
onfocus={() => {
|
|
110
115
|
inputElement?.focus()
|
|
111
116
|
}}
|
|
117
|
+
onclick={() => {
|
|
118
|
+
inputElement?.click()
|
|
119
|
+
}}
|
|
112
120
|
>
|
|
113
121
|
<div
|
|
114
122
|
class="field"
|
|
@@ -403,6 +411,7 @@
|
|
|
403
411
|
|
|
404
412
|
.input-wrapper {
|
|
405
413
|
display: flex;
|
|
414
|
+
flex-wrap: wrap;
|
|
406
415
|
align-items: baseline;
|
|
407
416
|
min-width: 0;
|
|
408
417
|
}
|
|
@@ -484,7 +493,7 @@
|
|
|
484
493
|
margin-bottom: var(--bottom-space, 0.5rem);
|
|
485
494
|
}
|
|
486
495
|
.content .input-wrapper .input {
|
|
487
|
-
min-width:
|
|
496
|
+
min-width: 20px;
|
|
488
497
|
}
|
|
489
498
|
:global(.content .input-wrapper .np-chip-set) {
|
|
490
499
|
margin-top: calc(var(--top-space, 1.5rem) - 4px);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { TextFieldProps } from './types.ts';
|
|
2
|
-
declare const TextField: import("svelte").Component<TextFieldProps, {}, "element" | "value" | "reportValidity" | "checkValidity" | "inputElement">;
|
|
2
|
+
declare const TextField: import("svelte").Component<TextFieldProps, {}, "element" | "value" | "reportValidity" | "checkValidity" | "inputElement" | "clientWidth" | "clientHeight">;
|
|
3
3
|
type TextField = ReturnType<typeof TextField>;
|
|
4
4
|
export default TextField;
|
|
@@ -16,6 +16,8 @@ interface FieldProps {
|
|
|
16
16
|
populated?: boolean;
|
|
17
17
|
reportValidity?: () => boolean;
|
|
18
18
|
checkValidity?: () => boolean;
|
|
19
|
+
clientWidth?: number;
|
|
20
|
+
clientHeight?: number;
|
|
19
21
|
}
|
|
20
22
|
export interface InputFieldProps extends HTMLInputAttributes, FieldProps {
|
|
21
23
|
type?: 'text' | 'password' | 'email' | 'number' | 'search' | 'tel' | 'url' | 'datetime-local';
|
package/dist/types.d.ts
CHANGED
package/dist/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "noph-ui",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.12",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"homepage": "https://noph.dev",
|
|
6
6
|
"repository": {
|
|
@@ -53,27 +53,27 @@
|
|
|
53
53
|
"svelte": "^5.32.1"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@eslint/js": "^9.
|
|
56
|
+
"@eslint/js": "^9.29.0",
|
|
57
57
|
"@material/material-color-utilities": "^0.3.0",
|
|
58
|
-
"@playwright/test": "^1.
|
|
58
|
+
"@playwright/test": "^1.53.0",
|
|
59
59
|
"@sveltejs/adapter-vercel": "^5.7.2",
|
|
60
|
-
"@sveltejs/kit": "^2.21.
|
|
60
|
+
"@sveltejs/kit": "^2.21.5",
|
|
61
61
|
"@sveltejs/package": "^2.3.11",
|
|
62
62
|
"@sveltejs/vite-plugin-svelte": "^5.1.0",
|
|
63
63
|
"@types/eslint": "^9.6.1",
|
|
64
|
-
"eslint": "^9.
|
|
64
|
+
"eslint": "^9.29.0",
|
|
65
65
|
"eslint-config-prettier": "^10.1.5",
|
|
66
|
-
"eslint-plugin-svelte": "^3.9.
|
|
66
|
+
"eslint-plugin-svelte": "^3.9.2",
|
|
67
67
|
"globals": "^16.2.0",
|
|
68
68
|
"prettier": "^3.5.3",
|
|
69
69
|
"prettier-plugin-svelte": "^3.4.0",
|
|
70
70
|
"publint": "^0.3.12",
|
|
71
|
-
"svelte": "^5.
|
|
71
|
+
"svelte": "^5.34.3",
|
|
72
72
|
"svelte-check": "^4.2.1",
|
|
73
73
|
"typescript": "^5.8.3",
|
|
74
|
-
"typescript-eslint": "^8.
|
|
74
|
+
"typescript-eslint": "^8.34.1",
|
|
75
75
|
"vite": "^6.3.5",
|
|
76
|
-
"vitest": "^3.2.
|
|
76
|
+
"vitest": "^3.2.3"
|
|
77
77
|
},
|
|
78
78
|
"svelte": "./dist/index.js",
|
|
79
79
|
"types": "./dist/index.d.ts",
|