noph-ui 0.24.12 → 0.24.14
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 +74 -66
- package/dist/autocomplete/AutoComplete.svelte.d.ts +1 -1
- package/dist/autocomplete/types.d.ts +1 -0
- package/dist/chip/InputChip.svelte +1 -1
- package/dist/menu/Menu.svelte +1 -1
- package/dist/select/Select.svelte +83 -82
- package/dist/select/VirtualList.svelte +1 -0
- package/dist/select/types.d.ts +1 -0
- package/dist/text-field/TextField.svelte +8 -7
- package/package.json +1 -1
|
@@ -16,9 +16,7 @@
|
|
|
16
16
|
clampMenuWidth = false,
|
|
17
17
|
children,
|
|
18
18
|
optionsFilter,
|
|
19
|
-
|
|
20
|
-
hidePopover = $bindable(),
|
|
21
|
-
onoptionselect = (option) => {
|
|
19
|
+
onoptionselect = (option: AutoCompleteOption) => {
|
|
22
20
|
value = option.label
|
|
23
21
|
finalPopulated = populated
|
|
24
22
|
menuElement?.hidePopover()
|
|
@@ -26,43 +24,41 @@
|
|
|
26
24
|
onkeydown,
|
|
27
25
|
onclick,
|
|
28
26
|
oninput,
|
|
27
|
+
virtualThreshold = 300,
|
|
29
28
|
...attributes
|
|
30
29
|
}: AutoCompleteProps = $props()
|
|
31
30
|
|
|
32
|
-
showPopover = () => {
|
|
33
|
-
menuElement?.showPopover()
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
hidePopover = () => {
|
|
37
|
-
menuElement?.hidePopover()
|
|
38
|
-
}
|
|
39
31
|
const uid = $props.id()
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
const query = $derived(value ? value.toLocaleLowerCase() : '')
|
|
33
|
+
const filterFn = $derived(
|
|
34
|
+
optionsFilter ||
|
|
35
|
+
((option: AutoCompleteOption) => !query || option.label.toLocaleLowerCase().includes(query)),
|
|
36
|
+
)
|
|
37
|
+
const NO_INDEX = -1
|
|
38
|
+
let displayOptions = $derived(query === '' && !optionsFilter ? options : options.filter(filterFn))
|
|
39
|
+
let useVirtualList = $derived(displayOptions.length > virtualThreshold)
|
|
40
|
+
let widthProp = $derived(clampMenuWidth || useVirtualList ? 'width' : 'min-width')
|
|
45
41
|
let clientWidth = $state(0)
|
|
46
42
|
let menuElement = $state<HTMLDivElement>()
|
|
47
43
|
let menuOpen = $state(false)
|
|
48
44
|
let finalPopulated = $state(populated)
|
|
49
|
-
let activeIndex = $state(
|
|
45
|
+
let activeIndex = $state(NO_INDEX)
|
|
50
46
|
|
|
51
|
-
|
|
47
|
+
const setActive = (index: number) => {
|
|
52
48
|
if (index < 0 || index >= displayOptions.length) {
|
|
53
|
-
activeIndex =
|
|
49
|
+
activeIndex = NO_INDEX
|
|
54
50
|
return
|
|
55
51
|
}
|
|
56
52
|
activeIndex = index
|
|
57
53
|
}
|
|
58
54
|
|
|
59
|
-
|
|
55
|
+
const moveActive = (delta: number) => {
|
|
60
56
|
if (!displayOptions.length) {
|
|
61
|
-
activeIndex =
|
|
57
|
+
activeIndex = NO_INDEX
|
|
62
58
|
return
|
|
63
59
|
}
|
|
64
60
|
const next =
|
|
65
|
-
activeIndex ===
|
|
61
|
+
activeIndex === NO_INDEX
|
|
66
62
|
? delta > 0
|
|
67
63
|
? 0
|
|
68
64
|
: displayOptions.length - 1
|
|
@@ -70,35 +66,39 @@
|
|
|
70
66
|
setActive(next)
|
|
71
67
|
}
|
|
72
68
|
|
|
69
|
+
const selectOption = (option: AutoCompleteOption) => {
|
|
70
|
+
onoptionselect(option)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
73
|
$effect(() => {
|
|
74
74
|
if (activeIndex >= displayOptions.length) {
|
|
75
|
-
activeIndex =
|
|
75
|
+
activeIndex = NO_INDEX
|
|
76
|
+
return
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
78
|
+
if (!menuOpen || activeIndex < 0) return
|
|
79
|
+
const id = `${uid}-opt-${activeIndex}`
|
|
80
|
+
const optEl = document.getElementById(id)
|
|
81
|
+
if (optEl) {
|
|
82
|
+
optEl.scrollIntoView({ block: 'nearest' })
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
if (useVirtualList && menuElement) {
|
|
86
|
+
const viewport = menuElement.querySelector(
|
|
87
|
+
'svelte-virtual-list-viewport',
|
|
88
|
+
) as HTMLElement | null
|
|
89
|
+
if (!viewport) return
|
|
90
|
+
let rowHeight = 48
|
|
91
|
+
const firstRow = viewport.querySelector('[id^="' + uid + '-opt-"]') as HTMLElement | null
|
|
92
|
+
if (firstRow) {
|
|
93
|
+
rowHeight = firstRow.offsetHeight || rowHeight
|
|
94
|
+
}
|
|
95
|
+
const top = activeIndex * rowHeight
|
|
96
|
+
const bottom = top + rowHeight
|
|
97
|
+
const { scrollTop, clientHeight } = viewport
|
|
98
|
+
if (top < scrollTop) {
|
|
99
|
+
viewport.scrollTop = top
|
|
100
|
+
} else if (bottom > scrollTop + clientHeight) {
|
|
101
|
+
viewport.scrollTop = bottom - clientHeight
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
})
|
|
@@ -111,14 +111,14 @@
|
|
|
111
111
|
aria-selected={index === activeIndex}
|
|
112
112
|
role="option"
|
|
113
113
|
tabindex={-1}
|
|
114
|
-
|
|
114
|
+
onpointerdown={(e) => {
|
|
115
115
|
e.preventDefault()
|
|
116
116
|
}}
|
|
117
117
|
onmouseenter={() => setActive(index)}
|
|
118
118
|
onclick={(event) => {
|
|
119
119
|
event.preventDefault()
|
|
120
120
|
setActive(index)
|
|
121
|
-
|
|
121
|
+
selectOption(option)
|
|
122
122
|
}}
|
|
123
123
|
variant="button"
|
|
124
124
|
>{option.label}
|
|
@@ -138,46 +138,57 @@
|
|
|
138
138
|
aria-controls="listbox-{uid}"
|
|
139
139
|
aria-expanded={menuOpen}
|
|
140
140
|
aria-autocomplete="list"
|
|
141
|
-
aria-activedescendant={activeIndex >= 0 ? `${uid}-opt-${activeIndex}` : undefined}
|
|
141
|
+
aria-activedescendant={menuOpen && activeIndex >= 0 ? `${uid}-opt-${activeIndex}` : undefined}
|
|
142
142
|
aria-haspopup="listbox"
|
|
143
143
|
onclick={(event) => {
|
|
144
144
|
finalPopulated = true
|
|
145
|
-
showPopover()
|
|
145
|
+
menuElement?.showPopover()
|
|
146
146
|
onclick?.(event)
|
|
147
147
|
}}
|
|
148
148
|
oninput={(event) => {
|
|
149
|
-
showPopover()
|
|
150
|
-
activeIndex =
|
|
149
|
+
menuElement?.showPopover()
|
|
150
|
+
activeIndex = NO_INDEX
|
|
151
151
|
oninput?.(event)
|
|
152
152
|
}}
|
|
153
153
|
onkeydown={(event) => {
|
|
154
154
|
if (event.key === 'Tab') {
|
|
155
|
+
menuElement?.hidePopover()
|
|
155
156
|
return
|
|
156
157
|
}
|
|
157
|
-
if (event.key === 'Escape') {
|
|
158
|
-
hidePopover()
|
|
159
|
-
activeIndex =
|
|
158
|
+
if (event.key === 'Escape' && menuOpen) {
|
|
159
|
+
menuElement?.hidePopover()
|
|
160
|
+
activeIndex = NO_INDEX
|
|
160
161
|
event.preventDefault()
|
|
161
162
|
return
|
|
162
163
|
}
|
|
163
164
|
if (event.key === 'ArrowDown') {
|
|
164
165
|
finalPopulated = true
|
|
165
|
-
showPopover()
|
|
166
|
+
menuElement?.showPopover()
|
|
166
167
|
moveActive(1)
|
|
167
168
|
event.preventDefault()
|
|
168
169
|
return
|
|
169
170
|
}
|
|
171
|
+
if (event.key === 'Home') {
|
|
172
|
+
setActive(0)
|
|
173
|
+
event.preventDefault()
|
|
174
|
+
return
|
|
175
|
+
}
|
|
176
|
+
if (event.key === 'End') {
|
|
177
|
+
setActive(displayOptions.length - 1)
|
|
178
|
+
event.preventDefault()
|
|
179
|
+
return
|
|
180
|
+
}
|
|
170
181
|
if (event.key === 'ArrowUp') {
|
|
171
182
|
finalPopulated = true
|
|
172
|
-
showPopover()
|
|
183
|
+
menuElement?.showPopover()
|
|
173
184
|
moveActive(-1)
|
|
174
185
|
event.preventDefault()
|
|
175
186
|
return
|
|
176
187
|
}
|
|
177
|
-
if (event.key === 'Enter' && activeIndex >= 0) {
|
|
188
|
+
if (event.key === 'Enter' && menuOpen && activeIndex >= 0) {
|
|
178
189
|
const opt = displayOptions[activeIndex]
|
|
179
190
|
if (opt) {
|
|
180
|
-
|
|
191
|
+
selectOption(opt)
|
|
181
192
|
}
|
|
182
193
|
event.preventDefault()
|
|
183
194
|
return
|
|
@@ -191,9 +202,7 @@
|
|
|
191
202
|
</TextField>
|
|
192
203
|
<Menu
|
|
193
204
|
id="listbox-{uid}"
|
|
194
|
-
style="position-anchor:--{uid};{
|
|
195
|
-
? 'width'
|
|
196
|
-
: 'min-width'}:{clientWidth}px"
|
|
205
|
+
style="position-anchor:--{uid};{widthProp}:{clientWidth}px"
|
|
197
206
|
role="listbox"
|
|
198
207
|
class={[!displayOptions.length && 'np-auto-complete-empty']}
|
|
199
208
|
--np-menu-justify-self="none"
|
|
@@ -206,15 +215,14 @@
|
|
|
206
215
|
ontoggle={(e) => {
|
|
207
216
|
if (e.newState === 'closed') {
|
|
208
217
|
menuOpen = false
|
|
209
|
-
activeIndex =
|
|
218
|
+
activeIndex = NO_INDEX
|
|
210
219
|
if (!populated && finalPopulated && !value) {
|
|
211
220
|
finalPopulated = false
|
|
212
221
|
}
|
|
213
222
|
} else {
|
|
214
223
|
menuOpen = true
|
|
215
|
-
// Ensure activeIndex valid when opening
|
|
216
224
|
if (activeIndex >= displayOptions.length) {
|
|
217
|
-
activeIndex =
|
|
225
|
+
activeIndex = NO_INDEX
|
|
218
226
|
}
|
|
219
227
|
}
|
|
220
228
|
}}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { AutoCompleteProps } from './types.ts';
|
|
2
|
-
declare const AutoComplete: import("svelte").Component<AutoCompleteProps, {}, "element" | "value" | "
|
|
2
|
+
declare const AutoComplete: import("svelte").Component<AutoCompleteProps, {}, "element" | "value" | "reportValidity" | "checkValidity">;
|
|
3
3
|
type AutoComplete = ReturnType<typeof AutoComplete>;
|
|
4
4
|
export default AutoComplete;
|
package/dist/menu/Menu.svelte
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
reportValidity = $bindable(),
|
|
33
33
|
checkValidity = $bindable(),
|
|
34
34
|
multiple,
|
|
35
|
+
virtualThreshold = 300,
|
|
35
36
|
clampMenuWidth = false,
|
|
36
37
|
...attributes
|
|
37
38
|
}: SelectProps = $props()
|
|
@@ -45,17 +46,18 @@
|
|
|
45
46
|
value = options.find((option) => option.selected)?.value
|
|
46
47
|
}
|
|
47
48
|
}
|
|
49
|
+
|
|
50
|
+
let valueArray = $derived<unknown[]>(
|
|
51
|
+
Array.isArray(value) ? value : value === undefined || value === null ? [] : [value],
|
|
52
|
+
)
|
|
53
|
+
let selectedSet = $derived.by<Set<unknown>>(() => new Set(valueArray))
|
|
48
54
|
let selectedOption: SelectOption[] = $derived(
|
|
49
|
-
options
|
|
50
|
-
.filter(
|
|
51
|
-
(option) =>
|
|
52
|
-
option.selected ||
|
|
53
|
-
(Array.isArray(value) ? value.includes(option.value) : value === option.value),
|
|
54
|
-
)
|
|
55
|
-
.map((option) => ({ ...option, selected: true })),
|
|
55
|
+
options.filter((o) => selectedSet.has(o.value)).map((o) => ({ ...o, selected: true })),
|
|
56
56
|
)
|
|
57
57
|
|
|
58
|
-
let useVirtualList = $derived(options.length >
|
|
58
|
+
let useVirtualList = $derived(options.length > virtualThreshold)
|
|
59
|
+
|
|
60
|
+
let widthProp = $derived(clampMenuWidth || useVirtualList ? 'width' : 'min-width')
|
|
59
61
|
|
|
60
62
|
let errorTextRaw: string = $state(errorText)
|
|
61
63
|
let errorRaw = $state(error)
|
|
@@ -129,64 +131,70 @@
|
|
|
129
131
|
}
|
|
130
132
|
}
|
|
131
133
|
})
|
|
132
|
-
|
|
134
|
+
|
|
135
|
+
let cachedRowHeight = 0
|
|
136
|
+
const ensureRowHeight = () => {
|
|
137
|
+
if (!cachedRowHeight && menuElement) {
|
|
138
|
+
const viewport = menuElement.querySelector(
|
|
139
|
+
'svelte-virtual-list-viewport',
|
|
140
|
+
) as HTMLElement | null
|
|
141
|
+
if (viewport) {
|
|
142
|
+
const firstRow = viewport.querySelector('[id^="' + uid + '-opt-"]') as HTMLElement | null
|
|
143
|
+
cachedRowHeight = firstRow?.offsetHeight || 48
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (!cachedRowHeight) cachedRowHeight = 48
|
|
147
|
+
return cachedRowHeight
|
|
148
|
+
}
|
|
149
|
+
const scrollOptionIntoView = (index: number) => {
|
|
150
|
+
if (!useVirtualList || !menuElement) return
|
|
151
|
+
const viewport = menuElement.querySelector('svelte-virtual-list-viewport') as HTMLElement | null
|
|
152
|
+
if (!viewport) return
|
|
153
|
+
const rowHeight = ensureRowHeight()
|
|
154
|
+
const top = index * rowHeight
|
|
155
|
+
const bottom = top + rowHeight
|
|
156
|
+
const { scrollTop, clientHeight } = viewport
|
|
157
|
+
if (top < scrollTop) viewport.scrollTop = top
|
|
158
|
+
else if (bottom > scrollTop + clientHeight) viewport.scrollTop = bottom - clientHeight
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const finalizeSelection = async () => {
|
|
162
|
+
await tick()
|
|
163
|
+
if (doValidity && checkValidity()) {
|
|
164
|
+
errorRaw = error
|
|
165
|
+
errorTextRaw = errorText
|
|
166
|
+
}
|
|
167
|
+
selectElement?.dispatchEvent(new Event('change', { bubbles: true }))
|
|
168
|
+
}
|
|
169
|
+
const toggleValue = (option: SelectOption) => {
|
|
133
170
|
if (multiple) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
} else {
|
|
139
|
-
selectedOption = [...selectedOption, option]
|
|
140
|
-
value = [...value, option.value]
|
|
141
|
-
}
|
|
171
|
+
let arr = Array.isArray(value) ? [...value] : []
|
|
172
|
+
const idx = arr.indexOf(option.value)
|
|
173
|
+
if (idx !== -1) {
|
|
174
|
+
arr.splice(idx, 1)
|
|
142
175
|
} else {
|
|
143
|
-
|
|
144
|
-
value = [option.value]
|
|
176
|
+
arr.push(option.value)
|
|
145
177
|
}
|
|
178
|
+
value = arr
|
|
146
179
|
} else {
|
|
147
|
-
selectedOption = [option]
|
|
148
180
|
value = option.value
|
|
149
|
-
menuElement?.hidePopover()
|
|
150
181
|
}
|
|
182
|
+
}
|
|
183
|
+
const handleOptionSelect = async (event: Event, option: SelectOption) => {
|
|
184
|
+
if (option.disabled) return
|
|
185
|
+
toggleValue(option)
|
|
186
|
+
if (!multiple) menuElement?.hidePopover()
|
|
151
187
|
event.preventDefault()
|
|
152
|
-
|
|
153
|
-
if (doValidity && checkValidity()) {
|
|
154
|
-
errorRaw = error
|
|
155
|
-
errorTextRaw = errorText
|
|
156
|
-
}
|
|
157
|
-
selectElement?.dispatchEvent(new Event('change', { bubbles: true }))
|
|
158
|
-
})
|
|
188
|
+
await finalizeSelection()
|
|
159
189
|
}
|
|
160
190
|
|
|
161
191
|
const openMenuAndFocus = async (index: number) => {
|
|
162
|
-
if (!menuOpen)
|
|
163
|
-
menuElement?.showPopover()
|
|
164
|
-
}
|
|
192
|
+
if (!menuOpen) menuElement?.showPopover()
|
|
165
193
|
focusIndex = Math.min(Math.max(index, 0), options.length - 1)
|
|
166
194
|
await tick()
|
|
167
195
|
const el = document.getElementById(`${uid}-opt-${focusIndex}`)
|
|
168
|
-
if (el)
|
|
169
|
-
|
|
170
|
-
} else if (useVirtualList && menuElement) {
|
|
171
|
-
const viewport = menuElement.querySelector(
|
|
172
|
-
'svelte-virtual-list-viewport',
|
|
173
|
-
) as HTMLElement | null
|
|
174
|
-
if (viewport) {
|
|
175
|
-
let rowHeight = 48
|
|
176
|
-
const firstRow = viewport.querySelector('[id^="' + uid + '-opt-"]') as HTMLElement | null
|
|
177
|
-
if (firstRow) {
|
|
178
|
-
rowHeight = firstRow.offsetHeight || rowHeight
|
|
179
|
-
}
|
|
180
|
-
const top = focusIndex * rowHeight
|
|
181
|
-
const bottom = top + rowHeight
|
|
182
|
-
const { scrollTop, clientHeight } = viewport
|
|
183
|
-
if (top < scrollTop) {
|
|
184
|
-
viewport.scrollTop = top
|
|
185
|
-
} else if (bottom > scrollTop + clientHeight) {
|
|
186
|
-
viewport.scrollTop = bottom - clientHeight
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
196
|
+
if (el) el.focus()
|
|
197
|
+
else scrollOptionIntoView(focusIndex)
|
|
190
198
|
}
|
|
191
199
|
|
|
192
200
|
const moveFocus = (delta: number) => {
|
|
@@ -254,6 +262,23 @@
|
|
|
254
262
|
performTypeahead('')
|
|
255
263
|
}
|
|
256
264
|
}
|
|
265
|
+
|
|
266
|
+
const handleInvalid = (
|
|
267
|
+
event: Event & {
|
|
268
|
+
currentTarget: EventTarget & HTMLSelectElement
|
|
269
|
+
},
|
|
270
|
+
) => {
|
|
271
|
+
event.preventDefault()
|
|
272
|
+
const { currentTarget } = event
|
|
273
|
+
errorRaw = true
|
|
274
|
+
doValidity = true
|
|
275
|
+
if (errorText === '') {
|
|
276
|
+
errorTextRaw = currentTarget.validationMessage
|
|
277
|
+
}
|
|
278
|
+
if (isFirstInvalidControlInForm(currentTarget.form, currentTarget)) {
|
|
279
|
+
field?.focus()
|
|
280
|
+
}
|
|
281
|
+
}
|
|
257
282
|
</script>
|
|
258
283
|
|
|
259
284
|
{#snippet arrows()}
|
|
@@ -345,7 +370,6 @@
|
|
|
345
370
|
}
|
|
346
371
|
return
|
|
347
372
|
}
|
|
348
|
-
// Printable character for typeahead
|
|
349
373
|
if (key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
|
350
374
|
performTypeahead(key)
|
|
351
375
|
return
|
|
@@ -400,18 +424,7 @@
|
|
|
400
424
|
multiple
|
|
401
425
|
{onchange}
|
|
402
426
|
{oninput}
|
|
403
|
-
oninvalid={
|
|
404
|
-
event.preventDefault()
|
|
405
|
-
const { currentTarget } = event
|
|
406
|
-
errorRaw = true
|
|
407
|
-
doValidity = true
|
|
408
|
-
if (errorText === '') {
|
|
409
|
-
errorTextRaw = currentTarget.validationMessage
|
|
410
|
-
}
|
|
411
|
-
if (isFirstInvalidControlInForm(currentTarget.form, currentTarget)) {
|
|
412
|
-
field?.focus()
|
|
413
|
-
}
|
|
414
|
-
}}
|
|
427
|
+
oninvalid={handleInvalid}
|
|
415
428
|
bind:value
|
|
416
429
|
bind:this={selectElement}
|
|
417
430
|
>
|
|
@@ -430,18 +443,7 @@
|
|
|
430
443
|
{form}
|
|
431
444
|
{onchange}
|
|
432
445
|
{oninput}
|
|
433
|
-
oninvalid={
|
|
434
|
-
event.preventDefault()
|
|
435
|
-
const { currentTarget } = event
|
|
436
|
-
errorRaw = true
|
|
437
|
-
doValidity = true
|
|
438
|
-
if (errorText === '') {
|
|
439
|
-
errorTextRaw = currentTarget.validationMessage
|
|
440
|
-
}
|
|
441
|
-
if (isFirstInvalidControlInForm(currentTarget.form, currentTarget)) {
|
|
442
|
-
field?.focus()
|
|
443
|
-
}
|
|
444
|
-
}}
|
|
446
|
+
oninvalid={handleInvalid}
|
|
445
447
|
bind:value
|
|
446
448
|
bind:this={selectElement}
|
|
447
449
|
>
|
|
@@ -565,9 +567,7 @@
|
|
|
565
567
|
|
|
566
568
|
<Menu
|
|
567
569
|
id="listbox-{uid}"
|
|
568
|
-
style=
|
|
569
|
-
? 'width'
|
|
570
|
-
: 'min-width'}:{clientWidth}px"
|
|
570
|
+
style={`position-anchor:--${uid};${widthProp}:${clientWidth}px`}
|
|
571
571
|
role="listbox"
|
|
572
572
|
aria-multiselectable={multiple}
|
|
573
573
|
--np-menu-justify-self="none"
|
|
@@ -608,7 +608,8 @@
|
|
|
608
608
|
rendered={({ start, end }) => {
|
|
609
609
|
if (focusIndex >= start && focusIndex < end) {
|
|
610
610
|
const el = document.getElementById(`${uid}-opt-${focusIndex}`)
|
|
611
|
-
el
|
|
611
|
+
if (el) el.focus()
|
|
612
|
+
else scrollOptionIntoView(focusIndex)
|
|
612
613
|
}
|
|
613
614
|
}}
|
|
614
615
|
>
|
package/dist/select/types.d.ts
CHANGED
|
@@ -222,12 +222,11 @@
|
|
|
222
222
|
></textarea>
|
|
223
223
|
{:else}
|
|
224
224
|
<div class="input-wrapper">
|
|
225
|
-
{#if
|
|
226
|
-
<span class="
|
|
227
|
-
{
|
|
225
|
+
{#if suffixText}
|
|
226
|
+
<span class="suffix">
|
|
227
|
+
{suffixText}
|
|
228
228
|
</span>
|
|
229
229
|
{/if}
|
|
230
|
-
{@render children?.()}
|
|
231
230
|
<input
|
|
232
231
|
aria-describedby={supportingText || (errorTextRaw && errorRaw)
|
|
233
232
|
? `supporting-text-${uid}`
|
|
@@ -242,9 +241,10 @@
|
|
|
242
241
|
class="input"
|
|
243
242
|
aria-invalid={errorRaw}
|
|
244
243
|
/>
|
|
245
|
-
{
|
|
246
|
-
|
|
247
|
-
|
|
244
|
+
{@render children?.()}
|
|
245
|
+
{#if prefixText}
|
|
246
|
+
<span class="prefix">
|
|
247
|
+
{prefixText}
|
|
248
248
|
</span>
|
|
249
249
|
{/if}
|
|
250
250
|
</div>
|
|
@@ -444,6 +444,7 @@
|
|
|
444
444
|
flex-wrap: wrap;
|
|
445
445
|
align-items: baseline;
|
|
446
446
|
min-width: 0;
|
|
447
|
+
flex-direction: row-reverse;
|
|
447
448
|
}
|
|
448
449
|
|
|
449
450
|
.input-wrapper > * {
|