@oslokommune/punkt-elements 15.4.5 → 16.0.2
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/CHANGELOG.md +34 -0
- package/dist/{card-CnPjrdre.js → card-CmfUyl_s.js} +1 -1
- package/dist/{card-5S2r9UD1.cjs → card-Db9QSEqh.cjs} +1 -1
- package/dist/{checkbox-D98_NjcU.cjs → checkbox-Cpyay9_l.cjs} +1 -1
- package/dist/{checkbox-BSz71IeT.js → checkbox-D6nltMuc.js} +1 -1
- package/dist/combobox-Bv37b6cI.cjs +135 -0
- package/dist/combobox-CoO8T-F-.js +818 -0
- package/dist/{datepicker-SEKblnRR.cjs → datepicker-CrvQ5Y5w.cjs} +1 -1
- package/dist/{datepicker-nnyTW0vf.js → datepicker-DbsIuC5Z.js} +2 -2
- package/dist/index.d.ts +157 -90
- package/dist/{input-element-Bkv6Yxld.js → input-element-BGNbdzy2.js} +1 -1
- package/dist/{input-element-DM0tY799.cjs → input-element-CSDVA3Y6.cjs} +1 -1
- package/dist/listbox-Dm2mKp6_.cjs +101 -0
- package/dist/listbox-OdkIn9_A.js +431 -0
- package/dist/pkt-card.cjs +1 -1
- package/dist/pkt-card.js +1 -1
- package/dist/pkt-checkbox.cjs +1 -1
- package/dist/pkt-checkbox.js +1 -1
- package/dist/pkt-combobox.cjs +1 -1
- package/dist/pkt-combobox.js +1 -1
- package/dist/pkt-datepicker.cjs +1 -1
- package/dist/pkt-datepicker.js +2 -2
- package/dist/pkt-header.cjs +1 -1
- package/dist/pkt-header.js +1 -1
- package/dist/pkt-index.cjs +1 -1
- package/dist/pkt-index.js +9 -9
- package/dist/pkt-listbox.cjs +1 -1
- package/dist/pkt-listbox.js +1 -1
- package/dist/pkt-options-controller-BogGk-6J.cjs +1 -0
- package/dist/{pkt-options-controller-BcGywCmf.js → pkt-options-controller-Z-bPox7n.js} +2 -2
- package/dist/pkt-radiobutton.cjs +1 -1
- package/dist/pkt-radiobutton.js +1 -1
- package/dist/pkt-select.cjs +1 -1
- package/dist/pkt-select.js +1 -1
- package/dist/pkt-tag.cjs +1 -1
- package/dist/pkt-tag.js +1 -1
- package/dist/pkt-textarea.cjs +1 -1
- package/dist/pkt-textarea.js +1 -1
- package/dist/pkt-textinput.cjs +1 -1
- package/dist/pkt-textinput.js +1 -1
- package/dist/{radiobutton-95wp024h.cjs → radiobutton-CNHCpKn0.cjs} +1 -1
- package/dist/{radiobutton-CTFAV5GU.js → radiobutton-DgC27mb0.js} +1 -1
- package/dist/{select-YLvYAQX6.js → select-7VuYtPZv.js} +2 -2
- package/dist/{select-CZ_Lx5W6.cjs → select-PWPy5gTB.cjs} +1 -1
- package/dist/{tag-68q0_Sn0.js → tag-DZPqFiem.js} +37 -33
- package/dist/tag-DmbgBCKu.cjs +27 -0
- package/dist/{textarea-CuTsE1WX.cjs → textarea-CO7Ikug5.cjs} +1 -1
- package/dist/{textarea-DhWH99qN.js → textarea-VpCEjVFx.js} +1 -1
- package/dist/{textinput-BCi9p0Du.js → textinput-C2AZ9ss2.js} +1 -1
- package/dist/{textinput-st4Vml5J.cjs → textinput-DRFZU3dA.cjs} +1 -1
- package/package.json +4 -4
- package/src/components/card/card.ts +1 -0
- package/src/components/combobox/combobox-base.ts +158 -0
- package/src/components/combobox/combobox-handlers.ts +419 -0
- package/src/components/combobox/combobox-types.ts +10 -0
- package/src/components/combobox/combobox-utils.ts +135 -0
- package/src/components/combobox/combobox-value.ts +248 -0
- package/src/components/combobox/combobox.accessibility.test.ts +243 -0
- package/src/components/combobox/{combobox.test.ts → combobox.core.test.ts} +104 -46
- package/src/components/combobox/combobox.interaction.test.ts +436 -0
- package/src/components/combobox/combobox.selection.test.ts +543 -0
- package/src/components/combobox/combobox.ts +260 -734
- package/src/components/listbox/index.ts +2 -0
- package/src/components/listbox/listbox.interaction.test.ts +580 -0
- package/src/components/listbox/listbox.test.ts +32 -6
- package/src/components/listbox/listbox.ts +109 -126
- package/src/components/tag/tag.ts +3 -0
- package/dist/combobox-C5YcNVSZ.cjs +0 -128
- package/dist/combobox-cer7PLSE.js +0 -533
- package/dist/listbox-C7NEa9SU.cjs +0 -96
- package/dist/listbox-Cykec1bj.js +0 -361
- package/dist/pkt-options-controller-BnTmkl3g.cjs +0 -1
- package/dist/tag-BnT5onW2.cjs +0 -26
|
@@ -5,8 +5,23 @@ import strings from '@/translations/no.json'
|
|
|
5
5
|
import { PktElement } from '@/base-elements/element'
|
|
6
6
|
import { repeat } from 'lit/directives/repeat.js'
|
|
7
7
|
import { classMap } from 'lit/directives/class-map.js'
|
|
8
|
-
import { IPktComboboxOption } from '
|
|
8
|
+
import type { IPktComboboxOption } from 'shared-types/combobox'
|
|
9
9
|
import { uuidish } from 'shared-utils/utils'
|
|
10
|
+
import { filterOptionsBySearch } from 'shared-utils/combobox/option-utils'
|
|
11
|
+
import {
|
|
12
|
+
isLetterOrSpace,
|
|
13
|
+
createTypeaheadHandler,
|
|
14
|
+
findTypeaheadOptionMatch,
|
|
15
|
+
} from 'shared-utils/combobox/typeahead'
|
|
16
|
+
import {
|
|
17
|
+
focusAndScrollIntoView,
|
|
18
|
+
getOptionElements,
|
|
19
|
+
focusNextOption as navFocusNext,
|
|
20
|
+
focusPreviousOption as navFocusPrev,
|
|
21
|
+
focusFirstOption as navFocusFirst,
|
|
22
|
+
focusLastOption as navFocusLast,
|
|
23
|
+
focusFirstOrSelectedOption as navFocusFirstOrSelected,
|
|
24
|
+
} from 'shared-utils/combobox/keyboard-navigation'
|
|
10
25
|
|
|
11
26
|
declare global {
|
|
12
27
|
interface HTMLElementTagNameMap {
|
|
@@ -34,19 +49,21 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
34
49
|
@property({ type: String }) id: string = uuidish()
|
|
35
50
|
@property({ type: String }) label: string | null = null
|
|
36
51
|
@property({ type: Array }) options: IPktComboboxOption[] = []
|
|
37
|
-
@property({ type: Boolean, reflect: true }) isOpen: boolean = false
|
|
52
|
+
@property({ type: Boolean, reflect: true, attribute: 'is-open' }) isOpen: boolean = false
|
|
38
53
|
@property({ type: Boolean }) disabled: boolean = false
|
|
39
|
-
@property({ type: Boolean }) includeSearch: boolean = false
|
|
40
|
-
@property({ type: Boolean }) isMultiSelect: boolean = false
|
|
41
|
-
@property({ type: Boolean }) allowUserInput: boolean = false
|
|
42
|
-
@property({ type: Boolean }) maxIsReached: boolean = false
|
|
43
|
-
@property({ type: String }) customUserInput: string | null = null
|
|
44
|
-
@property({ type: String }) searchPlaceholder: string | null =
|
|
45
|
-
|
|
46
|
-
@property({ type:
|
|
47
|
-
@property({ type:
|
|
54
|
+
@property({ type: Boolean, attribute: 'include-search' }) includeSearch: boolean = false
|
|
55
|
+
@property({ type: Boolean, attribute: 'is-multi-select' }) isMultiSelect: boolean = false
|
|
56
|
+
@property({ type: Boolean, attribute: 'allow-user-input' }) allowUserInput: boolean = false
|
|
57
|
+
@property({ type: Boolean, attribute: 'max-is-reached' }) maxIsReached: boolean = false
|
|
58
|
+
@property({ type: String, attribute: 'custom-user-input' }) customUserInput: string | null = null
|
|
59
|
+
@property({ type: String, attribute: 'search-placeholder' }) searchPlaceholder: string | null =
|
|
60
|
+
null
|
|
61
|
+
@property({ type: String, attribute: 'search-value' }) searchValue: string | null = null
|
|
62
|
+
@property({ type: Number, attribute: 'max-length' }) maxLength: number = 0
|
|
63
|
+
@property({ type: String, attribute: 'user-message' }) userMessage: string | null = null
|
|
48
64
|
|
|
49
65
|
private _selectedOptions: number = 0
|
|
66
|
+
private typeahead = createTypeaheadHandler()
|
|
50
67
|
|
|
51
68
|
@state() private _filteredOptions: IPktComboboxOption[] = []
|
|
52
69
|
|
|
@@ -63,6 +80,11 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
63
80
|
this.addEventListener('focus', this.focusFirstOrSelectedOption)
|
|
64
81
|
}
|
|
65
82
|
|
|
83
|
+
disconnectedCallback(): void {
|
|
84
|
+
super.disconnectedCallback()
|
|
85
|
+
this.typeahead.reset()
|
|
86
|
+
}
|
|
87
|
+
|
|
66
88
|
updated(changedProperties: PropertyValues) {
|
|
67
89
|
if (changedProperties.has('options') || changedProperties.has('searchValue')) {
|
|
68
90
|
this.filterOptions()
|
|
@@ -71,13 +93,17 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
71
93
|
}
|
|
72
94
|
|
|
73
95
|
attributeChangedCallback(name: string, _old: string | null, value: string | null): void {
|
|
74
|
-
if (name === 'options' || name === '
|
|
96
|
+
if (name === 'options' || name === 'search-value') {
|
|
75
97
|
this.filterOptions()
|
|
76
98
|
}
|
|
77
99
|
super.attributeChangedCallback(name, _old, value)
|
|
78
100
|
}
|
|
79
101
|
|
|
80
102
|
// Render methods
|
|
103
|
+
private get _hasOptions(): boolean {
|
|
104
|
+
return this._filteredOptions.length > 0 || this.options.length > 0
|
|
105
|
+
}
|
|
106
|
+
|
|
81
107
|
render() {
|
|
82
108
|
return html`
|
|
83
109
|
<div
|
|
@@ -86,22 +112,25 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
86
112
|
'pkt-listbox__open': this.isOpen,
|
|
87
113
|
'pkt-txt-16-light': true,
|
|
88
114
|
})}
|
|
89
|
-
role
|
|
90
|
-
aria-multiselectable=${ifDefined(
|
|
91
|
-
|
|
115
|
+
role=${ifDefined(this._hasOptions ? 'listbox' : undefined)}
|
|
116
|
+
aria-multiselectable=${ifDefined(
|
|
117
|
+
this._hasOptions && this.isMultiSelect ? 'true' : undefined,
|
|
118
|
+
)}
|
|
119
|
+
aria-label=${ifDefined(this._hasOptions ? (this.label ?? undefined) : undefined)}
|
|
92
120
|
>
|
|
93
121
|
<div class="pkt-listbox__banners">
|
|
94
|
-
${this.renderMaximumReachedBanner()} ${this.renderUserMessage()}
|
|
95
|
-
${this.
|
|
122
|
+
${this.renderSearch()} ${this.renderMaximumReachedBanner()} ${this.renderUserMessage()}
|
|
123
|
+
${this.renderEmptyMessage()} ${this.renderNewOptionBanner()}
|
|
96
124
|
</div>
|
|
97
125
|
<ul class="pkt-listbox__options" role="presentation">
|
|
98
126
|
${this.renderList()}
|
|
99
127
|
</ul>
|
|
100
128
|
</div>
|
|
129
|
+
<div aria-live="polite" class="pkt-visually-hidden">${this.userMessage}</div>
|
|
101
130
|
`
|
|
102
131
|
}
|
|
103
132
|
|
|
104
|
-
renderCheckboxOrCheckIcon(option: IPktComboboxOption, index: number) {
|
|
133
|
+
private renderCheckboxOrCheckIcon(option: IPktComboboxOption, index: number) {
|
|
105
134
|
return this.isMultiSelect
|
|
106
135
|
? html`
|
|
107
136
|
<input
|
|
@@ -120,7 +149,17 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
120
149
|
: nothing
|
|
121
150
|
}
|
|
122
151
|
|
|
123
|
-
|
|
152
|
+
private renderEmptyMessage() {
|
|
153
|
+
if (this.options.length > 0 || this._filteredOptions.length > 0 || this.userMessage) {
|
|
154
|
+
return nothing
|
|
155
|
+
}
|
|
156
|
+
return html`<div class="pkt-listbox__banner pkt-listbox__banner--empty">
|
|
157
|
+
<pkt-icon class="pkt-listbox__banner-icon" name="exclamation-mark-circle" size="large"></pkt-icon>
|
|
158
|
+
Tom liste
|
|
159
|
+
</div>`
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private renderList() {
|
|
124
163
|
return html`
|
|
125
164
|
${repeat(
|
|
126
165
|
this._filteredOptions,
|
|
@@ -144,6 +183,11 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
144
183
|
?data-disabled=${this.disabled ||
|
|
145
184
|
option.disabled ||
|
|
146
185
|
(this.maxIsReached && !option.selected)}
|
|
186
|
+
aria-disabled=${this.disabled ||
|
|
187
|
+
option.disabled ||
|
|
188
|
+
(this.maxIsReached && !option.selected)
|
|
189
|
+
? 'true'
|
|
190
|
+
: 'false'}
|
|
147
191
|
role="option"
|
|
148
192
|
id=${`${this.id}-${index}`}
|
|
149
193
|
>
|
|
@@ -165,7 +209,7 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
165
209
|
`
|
|
166
210
|
}
|
|
167
211
|
|
|
168
|
-
renderNewOptionBanner() {
|
|
212
|
+
private renderNewOptionBanner() {
|
|
169
213
|
return this.allowUserInput && this.customUserInput
|
|
170
214
|
? html`
|
|
171
215
|
<div
|
|
@@ -181,13 +225,13 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
181
225
|
@keydown=${this.handleOptionKeydown}
|
|
182
226
|
>
|
|
183
227
|
<pkt-icon class="pkt-listbox__banner-icon" name="plus-sign" size="large"></pkt-icon>
|
|
184
|
-
Legg til
|
|
228
|
+
Legg til "${this.customUserInput}"
|
|
185
229
|
</div>
|
|
186
230
|
`
|
|
187
231
|
: nothing
|
|
188
232
|
}
|
|
189
233
|
|
|
190
|
-
renderMaximumReachedBanner() {
|
|
234
|
+
private renderMaximumReachedBanner() {
|
|
191
235
|
this._selectedOptions = this.options.filter((option) => option.selected).length
|
|
192
236
|
|
|
193
237
|
return this.isMultiSelect && this._selectedOptions > 0 && this.maxLength > 0
|
|
@@ -199,7 +243,7 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
199
243
|
: nothing
|
|
200
244
|
}
|
|
201
245
|
|
|
202
|
-
renderUserMessage() {
|
|
246
|
+
private renderUserMessage() {
|
|
203
247
|
return this.userMessage
|
|
204
248
|
? html`<div class="pkt-listbox__banner pkt-listbox__banner--user-message">
|
|
205
249
|
<pkt-icon
|
|
@@ -212,7 +256,7 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
212
256
|
: nothing
|
|
213
257
|
}
|
|
214
258
|
|
|
215
|
-
renderSearch() {
|
|
259
|
+
private renderSearch() {
|
|
216
260
|
return this.includeSearch
|
|
217
261
|
? html`
|
|
218
262
|
<div class="pkt-listbox__search">
|
|
@@ -239,7 +283,7 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
239
283
|
}
|
|
240
284
|
|
|
241
285
|
// Event handlers
|
|
242
|
-
handleSearchInput(e: InputEvent) {
|
|
286
|
+
private handleSearchInput(e: InputEvent) {
|
|
243
287
|
this.searchValue = (e.target as HTMLInputElement).value
|
|
244
288
|
this.dispatchEvent(
|
|
245
289
|
new CustomEvent('search', {
|
|
@@ -249,7 +293,7 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
249
293
|
)
|
|
250
294
|
}
|
|
251
295
|
|
|
252
|
-
handleSearchKeydown(e: KeyboardEvent) {
|
|
296
|
+
private handleSearchKeydown(e: KeyboardEvent) {
|
|
253
297
|
switch (e.key) {
|
|
254
298
|
case 'Enter':
|
|
255
299
|
e.preventDefault()
|
|
@@ -260,20 +304,22 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
260
304
|
e.preventDefault()
|
|
261
305
|
break
|
|
262
306
|
case 'ArrowDown':
|
|
263
|
-
case 'Tab':
|
|
264
307
|
this.focusFirstOrSelectedOption()
|
|
265
308
|
break
|
|
309
|
+
case 'Tab':
|
|
310
|
+
this.tabClose()
|
|
311
|
+
break
|
|
266
312
|
}
|
|
267
313
|
}
|
|
268
314
|
|
|
269
|
-
handleOptionKeydown(e: KeyboardEvent) {
|
|
315
|
+
private handleOptionKeydown(e: KeyboardEvent) {
|
|
270
316
|
const target = e.currentTarget as HTMLElement
|
|
271
317
|
const value = target.dataset.value
|
|
272
318
|
const itemType = target.dataset.type
|
|
273
319
|
const isValueSelected = target.dataset.selected === 'true'
|
|
274
320
|
|
|
275
321
|
if (
|
|
276
|
-
!
|
|
322
|
+
!getOptionElements(this).length &&
|
|
277
323
|
(!this.customUserInput || (!this.allowUserInput && this.customUserInput)) &&
|
|
278
324
|
itemType !== 'new-option' &&
|
|
279
325
|
itemType !== 'searchbox'
|
|
@@ -300,18 +346,22 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
300
346
|
break
|
|
301
347
|
|
|
302
348
|
case 'Escape':
|
|
303
|
-
case 'Tab':
|
|
304
349
|
this.closeOptions()
|
|
350
|
+
e.preventDefault()
|
|
351
|
+
break
|
|
352
|
+
case 'Tab':
|
|
353
|
+
// Don't preventDefault — let Tab move focus naturally
|
|
354
|
+
this.tabClose()
|
|
305
355
|
break
|
|
306
356
|
|
|
307
357
|
case 'ArrowDown':
|
|
308
358
|
if (e.altKey) {
|
|
309
|
-
this
|
|
359
|
+
navFocusLast(this)
|
|
310
360
|
} else {
|
|
311
361
|
if (itemType === 'searchbox' || itemType === 'new-option') {
|
|
312
|
-
this
|
|
362
|
+
navFocusFirst(this)
|
|
313
363
|
} else {
|
|
314
|
-
|
|
364
|
+
navFocusNext(target)
|
|
315
365
|
}
|
|
316
366
|
}
|
|
317
367
|
e.preventDefault()
|
|
@@ -319,7 +369,7 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
319
369
|
|
|
320
370
|
case 'ArrowUp':
|
|
321
371
|
if (e.altKey) {
|
|
322
|
-
this
|
|
372
|
+
navFocusFirst(this)
|
|
323
373
|
} else {
|
|
324
374
|
if (target.dataset.index === '0' && this.includeSearch) {
|
|
325
375
|
const searchInput = this.querySelector('[role="searchbox"]') as HTMLElement
|
|
@@ -328,19 +378,19 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
328
378
|
const newOption = this.querySelector('[data-type="new-option"]') as HTMLElement
|
|
329
379
|
newOption && newOption.focus()
|
|
330
380
|
} else {
|
|
331
|
-
this.
|
|
381
|
+
navFocusPrev(target, this, this.includeSearch)
|
|
332
382
|
}
|
|
333
383
|
}
|
|
334
384
|
e.preventDefault()
|
|
335
385
|
break
|
|
336
386
|
|
|
337
387
|
case 'Home':
|
|
338
|
-
this
|
|
388
|
+
navFocusFirst(this)
|
|
339
389
|
e.preventDefault()
|
|
340
390
|
break
|
|
341
391
|
|
|
342
392
|
case 'End':
|
|
343
|
-
this
|
|
393
|
+
navFocusLast(this)
|
|
344
394
|
e.preventDefault()
|
|
345
395
|
break
|
|
346
396
|
|
|
@@ -349,7 +399,7 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
349
399
|
this.selectAll()
|
|
350
400
|
e.preventDefault()
|
|
351
401
|
}
|
|
352
|
-
if (
|
|
402
|
+
if (isLetterOrSpace(e.key)) {
|
|
353
403
|
this.handleTypeAhead(e.key)
|
|
354
404
|
e.preventDefault()
|
|
355
405
|
}
|
|
@@ -357,57 +407,18 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
357
407
|
}
|
|
358
408
|
}
|
|
359
409
|
|
|
360
|
-
// Focus management methods
|
|
361
|
-
focusAndScrollIntoView(el: HTMLElement) {
|
|
362
|
-
el.scrollIntoView({ block: 'nearest' })
|
|
363
|
-
window.setTimeout(() => el.focus(), 0)
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
focusNextOption(target: HTMLElement) {
|
|
367
|
-
const nextOption = target.nextElementSibling as HTMLElement
|
|
368
|
-
nextOption && this.focusAndScrollIntoView(nextOption)
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
focusPreviousOption(target: HTMLElement) {
|
|
372
|
-
const previousOption = target.previousElementSibling as HTMLElement
|
|
373
|
-
if (target.dataset.index === '0' && this.includeSearch) {
|
|
374
|
-
const searchInput = this.querySelector('[role="searchbox"]') as HTMLElement
|
|
375
|
-
searchInput && this.focusAndScrollIntoView(searchInput)
|
|
376
|
-
} else if (previousOption) {
|
|
377
|
-
this.focusAndScrollIntoView(previousOption)
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
focusFirstOption() {
|
|
382
|
-
const firstOption = this.getOptionElements()[0]
|
|
383
|
-
firstOption && this.focusAndScrollIntoView(firstOption)
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
focusLastOption() {
|
|
387
|
-
const lastOption = this.getOptionElements().pop()
|
|
388
|
-
lastOption && this.focusAndScrollIntoView(lastOption)
|
|
389
|
-
}
|
|
390
|
-
|
|
410
|
+
// Focus management methods (delegates to shared utils)
|
|
391
411
|
focusFirstOrSelectedOption() {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
this.focusAndScrollIntoView(newOption)
|
|
399
|
-
} else if (selectedOption) {
|
|
400
|
-
this.focusAndScrollIntoView(selectedOption)
|
|
401
|
-
} else if (this.includeSearch && !(document.activeElement instanceof HTMLInputElement)) {
|
|
402
|
-
const searchInput = this.querySelector('[role="searchbox"]') as HTMLElement
|
|
403
|
-
window.setTimeout(() => searchInput.focus(), 0)
|
|
404
|
-
} else {
|
|
405
|
-
this.focusFirstOption()
|
|
406
|
-
}
|
|
412
|
+
navFocusFirstOrSelected(this, {
|
|
413
|
+
disabled: this.disabled,
|
|
414
|
+
allowUserInput: this.allowUserInput,
|
|
415
|
+
customUserInput: this.customUserInput,
|
|
416
|
+
includeSearch: this.includeSearch,
|
|
417
|
+
})
|
|
407
418
|
}
|
|
408
419
|
|
|
409
420
|
// Event dispatching methods
|
|
410
|
-
toggleOption(option: IPktComboboxOption | HTMLElement) {
|
|
421
|
+
private toggleOption(option: IPktComboboxOption | HTMLElement) {
|
|
411
422
|
const optionDisabled = option instanceof HTMLElement ? option.dataset.disabled : option.disabled
|
|
412
423
|
if (this.disabled || optionDisabled) return
|
|
413
424
|
const value = option instanceof HTMLElement ? option.dataset.value : option.value
|
|
@@ -419,57 +430,29 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
419
430
|
)
|
|
420
431
|
}
|
|
421
432
|
|
|
422
|
-
selectAll() {
|
|
433
|
+
private selectAll() {
|
|
423
434
|
this.dispatchEvent(new CustomEvent('select-all', { bubbles: false }))
|
|
424
435
|
}
|
|
425
436
|
|
|
426
|
-
closeOptions() {
|
|
437
|
+
private closeOptions() {
|
|
427
438
|
this.dispatchEvent(new CustomEvent('close-options', { bubbles: false }))
|
|
428
439
|
}
|
|
429
440
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
filterOptions() {
|
|
433
|
-
if (this.searchValue) {
|
|
434
|
-
this._filteredOptions = this.options.filter((option) => {
|
|
435
|
-
const fulltext = option.fulltext || option.label + option.value + (option.prefix || '')
|
|
436
|
-
return fulltext.toLowerCase().includes(this.searchValue?.toLowerCase() || '')
|
|
437
|
-
})
|
|
438
|
-
} else {
|
|
439
|
-
this._filteredOptions = [...this.options]
|
|
440
|
-
}
|
|
441
|
+
private tabClose() {
|
|
442
|
+
this.dispatchEvent(new CustomEvent('tab-close', { bubbles: false }))
|
|
441
443
|
}
|
|
442
444
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
handleTypeAhead(char: string) {
|
|
448
|
-
this.typeAheadString += char.toLowerCase()
|
|
449
|
-
|
|
450
|
-
if (this.typeAheadTimeout) {
|
|
451
|
-
clearTimeout(this.typeAheadTimeout)
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
this.typeAheadTimeout = window.setTimeout(() => {
|
|
455
|
-
this.typeAheadString = ''
|
|
456
|
-
}, 500)
|
|
457
|
-
|
|
458
|
-
const options = this.getOptionElements()
|
|
459
|
-
const match = options.find((option) =>
|
|
460
|
-
option.textContent?.trim().toLowerCase().startsWith(this.typeAheadString),
|
|
461
|
-
)
|
|
462
|
-
|
|
463
|
-
match && this.focusAndScrollIntoView(match)
|
|
445
|
+
// Filtering and typeahead methods
|
|
446
|
+
filterOptions() {
|
|
447
|
+
this._filteredOptions = filterOptionsBySearch(this.options, this.searchValue)
|
|
464
448
|
}
|
|
465
449
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
450
|
+
private handleTypeAhead(char: string) {
|
|
451
|
+
const searchString = this.typeahead.append(char)
|
|
452
|
+
const options = getOptionElements(this)
|
|
453
|
+
const matchIndex = findTypeaheadOptionMatch(options, searchString)
|
|
454
|
+
if (matchIndex >= 0) {
|
|
455
|
+
focusAndScrollIntoView(options[matchIndex])
|
|
470
456
|
}
|
|
471
|
-
return Array.from(
|
|
472
|
-
this.querySelectorAll('[role="option"]:not([data-disabled])') || [],
|
|
473
|
-
) as HTMLElement[]
|
|
474
457
|
}
|
|
475
458
|
}
|
|
@@ -56,6 +56,8 @@ export class PktTag extends PktElement<IPktTag> implements IPktTag {
|
|
|
56
56
|
@property({ type: String, reflect: true }) iconName: string | undefined = undefined
|
|
57
57
|
@property({ type: String }) type: TTagType = specs.props.type.default as TTagType
|
|
58
58
|
@property({ type: String }) ariaLabel: string | null = null
|
|
59
|
+
@property({ type: Number, attribute: 'button-tabindex' }) buttonTabindex: number | undefined =
|
|
60
|
+
undefined
|
|
59
61
|
|
|
60
62
|
/**
|
|
61
63
|
* Element state
|
|
@@ -116,6 +118,7 @@ export class PktTag extends PktElement<IPktTag> implements IPktTag {
|
|
|
116
118
|
<button
|
|
117
119
|
class=${classMap(btnClasses)}
|
|
118
120
|
type=${this.type}
|
|
121
|
+
tabindex=${ifDefined(this.buttonTabindex)}
|
|
119
122
|
@click=${this.close}
|
|
120
123
|
aria-label=${ifDefined(this.ariaLabel || undefined)}
|
|
121
124
|
aria-description=${ifDefined(this._ariaDescription || undefined)}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
"use strict";const o=require("./element-CMTfByxQ.cjs"),c=require("./if-defined-hKKmbsI8.cjs"),d=require("./state-BNgpvY-A.cjs"),r=require("./ref-CxLwrCxt.cjs"),y=require("./class-map-Bokp1SoS.cjs"),O=require("./repeat-C-FJ2vfy.cjs"),I=require("./input-element-DM0tY799.cjs"),$=require("./pkt-options-controller-BnTmkl3g.cjs"),w=require("./pkt-slot-controller-D4nKlom5.cjs");require("./input-wrapper-JU4D2TGu.cjs");require("./icon-Dj0oZZSa.cjs");require("./tag-BnT5onW2.cjs");require("./listbox-C7NEa9SU.cjs");const C={displayValueAs:{default:"label"}},R={props:C};var V=Object.defineProperty,A=Object.getOwnPropertyDescriptor,n=(b,t,e,i)=>{for(var s=i>1?void 0:i?A(t,e):t,a=b.length-1,l;a>=0;a--)(l=b[a])&&(s=(i?l(t,e,s):l(s))||s);return i&&s&&V(t,e,s),s};exports.PktCombobox=class extends I.PktInputElement{constructor(){super(),this.helptextSlot=r.e(),this.value="",this.options=[],this.defaultOptions=[],this.allowUserInput=!1,this.typeahead=!1,this.includeSearch=!1,this.searchPlaceholder="",this.multiple=!1,this.maxlength=null,this.displayValueAs=R.props.displayValueAs.default,this.tagPlacement=null,this._options=[],this._value=[],this._isOptionsOpen=!1,this._userInfoMessage="",this._addValueText=null,this._maxIsReached=!1,this._search="",this._inputFocus=!1,this._editingSingleValue=!1,this.inputRef=r.e(),this.arrowRef=r.e(),this.listboxRef=r.e(),this.focusRef=r.e(),this.optionTagRef=r.e(),this.optionsController=new $.PktOptionsSlotController(this),this.slotController=new w.PktSlotController(this,this.helptextSlot),this.slotController.skipOptions=!0}connectedCallback(){var t,e;if(super.connectedCallback(),document&&document.body.addEventListener("click",i=>{this._isOptionsOpen&&!this.contains(i.target)&&this.handleFocusOut(i)}),this._options=[],this.defaultOptions&&this.defaultOptions.length){const i=((t=this.options)==null?void 0:t.filter(s=>s.userAdded))||[];this.options=[...i,...JSON.parse(JSON.stringify(this.defaultOptions))],this._options=Array.isArray(this.options)?[...this.options]:[]}if((e=this.optionsController)!=null&&e.nodes&&this.optionsController.nodes.length){const i=[];this.optionsController.nodes.forEach(s=>{if(!s.textContent&&!s.getAttribute("value"))return null;const a={value:s.getAttribute("value")||s.textContent||"",label:s.textContent||s.getAttribute("value")||""};s.getAttribute("data-prefix")&&(a.prefix=s.getAttribute("data-prefix")||void 0),s.getAttribute("tagskincolor")&&(a.tagSkinColor=s.getAttribute("tagskincolor")),s.getAttribute("description")&&(a.description=s.getAttribute("description")||void 0),a.fulltext=a.value+a.label+(a.prefix||""),i.push(a)}),i.length&&(this.options=[...i],this._options=[...i])}}updated(t){if(t.has("_value")&&this.valueChanged(this._value,t.get("_value")),t.has("value")&&(Array.isArray(this.value)?this._value=this.value:this.value&&this.multiple?this._value=this.value.split(","):this.value?this._value=[this.value]:this._value=[],!this.multiple&&this._value.length>1&&(this._value=[this._value[0]]),this.isMaxItemsReached()),t.has("defaultOptions")&&this.defaultOptions.length){const e=(Array.isArray(this.options)?this.options:[]).filter(i=>i.userAdded)||[];this.options=[...e,...JSON.parse(JSON.stringify(this.defaultOptions))],this._options=Array.isArray(this.options)?[...this.options]:[]}if(t.has("options")){const s=(t.get("options")||this._options||[]).filter(l=>l&&l.userAdded).filter(l=>!(Array.isArray(this.options)?this.options:[]).some(h=>h.value===l.value)),a=[...s,...this.options];this._options=a,s.length>0&&(this.options=a),this._options.forEach(l=>{if(l.value&&!l.label&&(l.label=l.value),l.selected&&!this._value.includes(l.value)){const h=[...this._value];this._value=[...this._value,l.value],this.valueChanged(this._value,h)}l.fulltext=l.value+l.label+(l.prefix||""),l.selected=l.selected||this._value.includes(l.value)})}t.has("_search")&&this.dispatchEvent(new CustomEvent("search",{detail:this._search,bubbles:!1})),super.updated(t)}attributeChangedCallback(t,e,i){t==="value"&&(Array.isArray(this.value)?this._value=this.value:this.value&&this.multiple?this._value=this.value.split(","):this.value?this._value=[this.value]:this._value=[],!this.multiple&&this._value.length>1&&(this._value=[this._value[0]])),t==="options"&&(this._options=Array.isArray(this.options)?[...this.options]:[],this._options.forEach(s=>{s.value&&!s.label&&(s.label=s.value),s.selected&&!this._value.includes(s.value)&&(this._value=[...this._value,s.value]),s.fulltext=s.value+s.label+(s.prefix||"")}),this._search=""),super.attributeChangedCallback(t,e,i)}render(){return o.b`
|
|
2
|
-
<pkt-input-wrapper
|
|
3
|
-
.label=${this.label}
|
|
4
|
-
.helptext=${this.helptext}
|
|
5
|
-
.helptextDropdown=${c.o(this.helptextDropdown)}
|
|
6
|
-
.helptextDropdownButton=${c.o(this.helptextDropdownButton)}
|
|
7
|
-
?fullwidth=${this.fullwidth}
|
|
8
|
-
?hasError=${this.hasError}
|
|
9
|
-
?inline=${this.inline}
|
|
10
|
-
?disabled=${this.disabled}
|
|
11
|
-
.errorMessage=${this.errorMessage}
|
|
12
|
-
?optionalTag=${this.optionalTag}
|
|
13
|
-
.optionalText=${this.optionalText}
|
|
14
|
-
?requiredTag=${this.requiredTag}
|
|
15
|
-
.requiredText=${this.requiredText}
|
|
16
|
-
.tagText=${this.tagText}
|
|
17
|
-
useWrapper=${this.useWrapper}
|
|
18
|
-
.forId=${this.allowUserInput||this.typeahead?this.id+"-input":this.id+"-arrow"}
|
|
19
|
-
class="pkt-combobox__wrapper"
|
|
20
|
-
@labelClick=${this.handleInputClick}
|
|
21
|
-
>
|
|
22
|
-
<div class="pkt-contents" ${r.n(this.helptextSlot)} name="helptext" slot="helptext"></div>
|
|
23
|
-
<div class="pkt-combobox" @focusout=${this.handleFocusOut}>
|
|
24
|
-
<div
|
|
25
|
-
class=${y.e({"pkt-combobox__input":!0,"pkt-combobox__input--fullwidth":this.fullwidth,"pkt-combobox__input--open":this._isOptionsOpen,"pkt-combobox__input--error":this.hasError,"pkt-combobox__input--disabled":this.disabled})}
|
|
26
|
-
tabindex="-1"
|
|
27
|
-
@click=${this.handleInputClick}
|
|
28
|
-
>
|
|
29
|
-
${this.placeholder&&(!this._value.length||this.multiple&&this.tagPlacement=="outside")&&!this._inputFocus?o.b`<span class="pkt-combobox__placeholder" @click=${this.handlePlaceholderClick}
|
|
30
|
-
>${this.placeholder}</span
|
|
31
|
-
>`:this.tagPlacement!=="outside"?this.renderSingleOrMultipleValues():o.A}
|
|
32
|
-
${this.renderInputField()}
|
|
33
|
-
<div
|
|
34
|
-
class="pkt-btn pkt-btn--tertiary pkt-combobox__arrow"
|
|
35
|
-
@click=${this.handleArrowClick}
|
|
36
|
-
@keydown=${this.handleArrowClick}
|
|
37
|
-
id="${this.id}-arrow"
|
|
38
|
-
${r.n(this.arrowRef)}
|
|
39
|
-
aria-expanded=${this._isOptionsOpen}
|
|
40
|
-
aria-controls="${this.id}-listbox"
|
|
41
|
-
aria-haspopup="listbox"
|
|
42
|
-
aria-label="Åpne liste"
|
|
43
|
-
?disabled=${this.disabled}
|
|
44
|
-
?data-disabled=${this.disabled}
|
|
45
|
-
role="button"
|
|
46
|
-
tabindex="${this.disabled?"-1":"0"}"
|
|
47
|
-
>
|
|
48
|
-
<pkt-icon
|
|
49
|
-
class=${y.e({"pkt-combobox__arrow-icon":!0,"pkt-combobox__arrow-icon--open":this._isOptionsOpen})}
|
|
50
|
-
name="chevron-thin-down"
|
|
51
|
-
></pkt-icon>
|
|
52
|
-
</div>
|
|
53
|
-
<div
|
|
54
|
-
${r.n(this.focusRef)}
|
|
55
|
-
tabindex="-1"
|
|
56
|
-
@keydown=${this.handleArrowClick}
|
|
57
|
-
class="pkt-contents"
|
|
58
|
-
></div>
|
|
59
|
-
</div>
|
|
60
|
-
|
|
61
|
-
<pkt-listbox
|
|
62
|
-
id="${this.id}-listbox"
|
|
63
|
-
.options=${this._options}
|
|
64
|
-
.isOpen=${this._isOptionsOpen}
|
|
65
|
-
.searchPlaceholder=${this.searchPlaceholder}
|
|
66
|
-
.label="Liste: ${this.label||""}"
|
|
67
|
-
?includeSearch=${this.includeSearch}
|
|
68
|
-
?isMultiSelect=${this.multiple}
|
|
69
|
-
?allowUserInput=${this.allowUserInput&&!this._maxIsReached}
|
|
70
|
-
?maxIsReached=${this._maxIsReached}
|
|
71
|
-
.customUserInput=${c.o(this._addValueText)}
|
|
72
|
-
.userMessage=${this._userInfoMessage}
|
|
73
|
-
@search=${this.handleSearch}
|
|
74
|
-
@option-toggle=${this.handleOptionToggled}
|
|
75
|
-
@select-all=${this.addAllOptions}
|
|
76
|
-
@close-options=${()=>this._isOptionsOpen=!1}
|
|
77
|
-
.searchValue=${this._search||null}
|
|
78
|
-
.maxLength=${this.maxlength||0}
|
|
79
|
-
${r.n(this.listboxRef)}
|
|
80
|
-
></pkt-listbox>
|
|
81
|
-
</div>
|
|
82
|
-
|
|
83
|
-
${this.tagPlacement==="outside"&&this.multiple?o.b`<div class="pkt-combobox__tags-outside">
|
|
84
|
-
${this.renderSingleOrMultipleValues()}
|
|
85
|
-
</div>`:o.A}
|
|
86
|
-
</pkt-input-wrapper>
|
|
87
|
-
`}renderInputField(){return this.typeahead||this.allowUserInput?o.b`
|
|
88
|
-
<div class="pkt-combobox__input-div combobox__input">
|
|
89
|
-
<input
|
|
90
|
-
type="text"
|
|
91
|
-
id="${this.id}-input"
|
|
92
|
-
name=${(this.name||this.id)+"-input"}
|
|
93
|
-
@input=${this.handleInput}
|
|
94
|
-
@keydown=${this.handleInputKeydown}
|
|
95
|
-
@focus=${this.handleFocus}
|
|
96
|
-
@blur=${this.handleBlur}
|
|
97
|
-
autocomplete="off"
|
|
98
|
-
role="combobox"
|
|
99
|
-
aria-label=${c.o(this.label)}
|
|
100
|
-
aria-autocomplete=${this.typeahead?"both":"list"}
|
|
101
|
-
aria-controls="${this.id}-listbox"
|
|
102
|
-
aria-activedescendant=${c.o(this._value[0]&&this.findValueInOptions(this._value[0])?`${this.id}-listbox-${this.findIndexInOptions(this._value[0])}`:void 0)}
|
|
103
|
-
${r.n(this.inputRef)}
|
|
104
|
-
/>
|
|
105
|
-
</div>
|
|
106
|
-
`:o.b`
|
|
107
|
-
<input
|
|
108
|
-
type="hidden"
|
|
109
|
-
id="${this.id}-input"
|
|
110
|
-
name=${(this.name||this.id)+"-input"}
|
|
111
|
-
.value=${this._value.join(",")}
|
|
112
|
-
${r.n(this.inputRef)}
|
|
113
|
-
/>
|
|
114
|
-
`}renderSingleOrMultipleValues(){const t=!this.multiple,e=this._editingSingleValue?null:this.renderValueTag(this.findValueInOptions(this._value[0])),i=O.c(this._value,s=>s,s=>{var h;const a=this.findValueInOptions(s),l=(h=this.options.find(u=>u.value===s))==null?void 0:h.tagSkinColor;return o.b`
|
|
115
|
-
<pkt-tag
|
|
116
|
-
skin=${l||"blue-dark"}
|
|
117
|
-
?closeTag=${!this.disabled}
|
|
118
|
-
@close=${()=>this.handleTagRemove(s)}
|
|
119
|
-
>
|
|
120
|
-
${this.renderValueTag(a)}
|
|
121
|
-
</pkt-tag>
|
|
122
|
-
`});return t?e:i}renderValueTag(t){if(!t)return"";switch(this.displayValueAs){case"prefixAndValue":return o.b`<span class="pkt-combobox__value" data-focusfix=${this.id}
|
|
123
|
-
>${t.prefix||""} ${t.value}</span
|
|
124
|
-
>`;case"value":return o.b`<span class="pkt-combobox__value" data-focusfix=${this.id}
|
|
125
|
-
>${t.value}</span
|
|
126
|
-
>`;case"label":default:return o.b`<span class="pkt-combobox__value" data-focusfix=${this.id}
|
|
127
|
-
>${t.label||t.value}</span
|
|
128
|
-
>`}}handleInput(t){if(t.stopPropagation(),t.stopImmediatePropagation(),this.disabled)return;this.touched=!0;const e=t.target;if(this._search=e.value,this.checkForMatches(),this.typeahead)if(this._search){if(this._options=this.options.filter(i=>{var s;return(s=i.fulltext)==null?void 0:s.toLowerCase().includes(this._search.toLowerCase())}),t.inputType!=="deleteContentBackward"){const i=this._options.filter(s=>{var a;return!s.selected&&((a=s.label)==null?void 0:a.toLowerCase().startsWith(this._search.toLowerCase()))});if(i.length>0&&this.inputRef.value&&this.inputRef.value.type!=="hidden"){const s=i[0];s!=null&&s.label&&(e.value=s.label,window.setTimeout(()=>e.setSelectionRange(this._search.length,e.value.length),0),e.selectionDirection="backward")}}}else this._options=[...this.options]}handleFocus(){if(!this.disabled){if(!this.multiple&&this._value[0]&&this.inputRef.value&&this.inputRef.value.type!=="hidden"){const t=this.findValueInOptions(this._value[0]);this._editingSingleValue=!0,this.inputRef.value.value=this.displayValueAs==="label"&&(t!=null&&t.label)?t.label:this._value[0]}this._inputFocus=!0,this._search="",this._options=[...this.options],this._isOptionsOpen=!0,this.onFocus(),this.requestUpdate()}}handleFocusOut(t){var e,i,s,a,l;if(!this.disabled&&((i=(e=t.relatedTarget)==null?void 0:e.closest("pkt-combobox"))==null?void 0:i.id)!==this.id&&((a=(s=t.relatedTarget)==null?void 0:s.closest("pkt-combobox"))==null?void 0:a.id)!==this.id&&((l=t.target)==null?void 0:l.getAttribute("data-focusfix"))!==this.id&&t.relatedTarget!==this.focusRef.value&&t.relatedTarget!==this.inputRef.value&&t.relatedTarget!==this.arrowRef.value&&this._isOptionsOpen){if(this._inputFocus=!1,this._addValueText=null,this._userInfoMessage="",this._search="",this.inputRef.value&&this.inputRef.value.type!=="hidden"&&this.inputRef.value.value!==""){const h=this.inputRef.value.value,u=this.findValueInOptions(h);!this._value.includes(h)&&!u?this.allowUserInput?this.addNewUserValue(h):this.multiple||this.removeValue(this._value[0]):u&&!this._value.includes(u.value)&&this.setSelected(u.value),this.inputRef.value.value=""}this._isOptionsOpen=!1,this.onBlur()}}handleBlur(){this._inputFocus=!1,this._editingSingleValue=!1,this.onBlur()}handleInputClick(t){var e,i;if(this.disabled){t.preventDefault(),t.stopImmediatePropagation();return}t.currentTarget&&t.currentTarget!==this.arrowRef.value&&((e=this.inputRef.value)==null?void 0:e.type)!=="hidden"?((i=this.inputRef.value)==null||i.focus(),this.requestUpdate()):this.handleArrowClick(t)}handlePlaceholderClick(t){this.disabled||(t.stopPropagation(),this.inputRef.value&&this.inputRef.value.type!=="hidden"&&(this.inputRef.value.focus(),this._inputFocus=!0,this.requestUpdate()))}handleArrowClick(t){var e,i;this.disabled||t instanceof KeyboardEvent&&t.key&&t.key!=="Enter"&&t.key!==" "&&t.key!=="ArrowDown"||(t.stopImmediatePropagation(),t.preventDefault(),this._isOptionsOpen=!this._isOptionsOpen,this._isOptionsOpen?(e=this.listboxRef.value)==null||e.focusFirstOrSelectedOption():(i=this.arrowRef.value)==null||i.focus())}handleOptionToggled(t){this.toggleValue(t.detail)}handleSearch(t){t.stopPropagation(),this._search=t.detail.toLowerCase()}handleInputKeydown(t){var e,i,s;switch(t.key){case",":this.multiple&&(t.preventDefault(),this.addValue());break;case"Enter":t.preventDefault(),this.addValue();break;case"Backspace":!this._search&&((e=this.inputRef.value)==null?void 0:e.type)==="hidden"&&this.removeLastValue(t);break;case"Tab":case"ArrowDown":t.shiftKey||((i=this.listboxRef.value)==null||i.focusFirstOrSelectedOption(),t.preventDefault());break;case"Escape":this._isOptionsOpen=!1,(s=this.arrowRef.value)==null||s.focus(),t.preventDefault();break}}handleTagRemove(t){this.removeSelected(t)}blurInput(){this.inputRef.value&&this.inputRef.value.matches(":focus")&&this.inputRef.value.blur()}checkForMatches(){var l;const t=((l=this.inputRef.value)==null?void 0:l.value)||this._search||"",e=t.trim().toLowerCase()||"";if(!e){!this.multiple&&this._value[0]&&this.removeValue(this._value[0]),this.resetComboboxInput(!1);return}const i=this._value.find(h=>h.toLowerCase()===e),s=this._options.filter(h=>{var u;return((u=h.label)==null?void 0:u.toLowerCase().includes(e))??!1}),a=s.find(h=>{var u;return((u=h.label)==null?void 0:u.toLowerCase())===e||h.value.toLowerCase()===e});switch(!0){case((s.length===0||!a)&&this.allowUserInput):this._addValueText=t,this._userInfoMessage="";break;case(s.length===0&&!this._options.length&&!this.allowUserInput):this._addValueText=null,this._userInfoMessage="Ingen match i søket";break;case!!i:this._addValueText=null,this._userInfoMessage="Verdien er allerede valgt";break;case s.length>1:this._addValueText=null,this._userInfoMessage="";break;default:this._addValueText=null,this._userInfoMessage=""}}findValueInOptions(t){return this.options.find(e=>e.value===t||e.label===t)||null}findIndexInOptions(t){return this._options.findIndex(e=>e.value===t||e.label===t)}isMaxItemsReached(){const t=this.maxlength!==null&&this._value.length>=this.maxlength;return t?this._maxIsReached=!0:this._maxIsReached=!1,t}toggleValue(t){var x,k;if(this.disabled)return;this.touched=!0,this._userInfoMessage="",this._addValueText=null;const e=((x=this.findValueInOptions(t))==null?void 0:x.value)||null,i=this._value.includes(t||e||""),s=!!e,a=((k=this._options.find(_=>_.value===t))==null?void 0:k.disabled)||!1,l=!(t!=null&&t.trim()),h=!this.multiple,u=this.multiple,g=this.isMaxItemsReached();let p=!1,f=!0,v="",m="";a||(!s&&this.allowUserInput&&!l?(this.addNewUserValue(t),v="Ny verdi lagt til",p=!u):!s&&!this.allowUserInput?(h&&this._value[0]&&this.removeValue(this._value[0]),f=!1,p=!0,v="Ingen treff i søket"):i?(this.removeValue(e),p=!0):l&&h?(this.removeAllSelected(),p=!0):h?(this._value[0]&&this.removeSelected(this._value[0]),this.setSelected(e),p=!1,this.inputRef.value&&this.inputRef.value.type!=="hidden"&&(this.inputRef.value.value="",this.inputRef.value.blur())):u&&!g?(this.setSelected(e),p=!0):u&&g?(this._userInfoMessage="Maks antall valg nådd",f=!1,m=t):(h&&this.removeAllSelected(),this._userInfoMessage="Ingen gyldig verdi valgt",f=!1,p=!0,m=t),this._isOptionsOpen=p,p||window.setTimeout(()=>{var _;(_=this.focusRef.value)==null||_.focus()},0),this._userInfoMessage=v,this._search=m||"",this.resetComboboxInput(f),u&&this.isMaxItemsReached())}setSelected(t){if(!this._value.includes(t)){if(this.multiple&&this.isMaxItemsReached()){this._userInfoMessage="Maks antall valg nådd";return}!this.multiple&&this.removeAllSelected(),this._value=t?[...this._value,t]:this._value,this._options=this._options.map(e=>(e.value===t&&(e.selected=!0),e)),this.resetComboboxInput(!0)}}removeSelected(t){if(!t)return;this._value=this._value.filter(i=>i!==t);const e=this.findValueInOptions(t);e?(e.selected=!1,e.userAdded?(this._options=[...this._options.filter(i=>i.value!==t)],this.options=[...this.options.filter(i=>i.value!==t)]):this._options=[...this._options,e]):!t&&!this.multiple&&(this._options=this._options.map(i=>(i.selected=!1,i)))}addAllOptions(){if(this.multiple){if(this.maxlength&&this._options.length>this.maxlength){this._userInfoMessage="For mange valgt";return}this._value=this._options.map(t=>t.value),this._options=this._options.map(t=>(t.selected=!0,t)),this.requestUpdate()}}removeAllSelected(){this._value=[],this._options=this._options.map(t=>(t.selected=!1,t)),this._options=this._options.filter(t=>!t.userAdded),this.requestUpdate()}addValue(){var e;const t=((e=this.inputRef.value)==null?void 0:e.value.trim())||"";this._search=t,this.toggleValue(t)}removeValue(t){this._value=this.multiple?this._value.filter(e=>e!==t):[],this.removeSelected(t)}addNewUserValue(t){if(!t||t.trim()==="")return;if(!this.multiple)this._value[0]&&this.removeSelected(this._value[0]),this._value=[t],this._isOptionsOpen=!1,this.blurInput();else if(!this.findValueInOptions(t)){if(this.isMaxItemsReached())return;this._value=[...this._value,t]}const e={value:t,label:t,userAdded:!0};this.options=[e,...this.options],this._options=[e,...this._options],this.setSelected(t),this.requestUpdate()}resetComboboxInput(t=!0){if(this._addValueText=null,this.inputRef.value&&this.inputRef.value.type!=="hidden"&&t)if(this._search="",this.multiple)this.inputRef.value.value="";else{const e=this.findValueInOptions(this._value[0]);window.setTimeout(()=>{!this.inputRef.value||this.inputRef.value.type==="hidden"||(this.inputRef.value.value=this.displayValueAs==="label"&&(e!=null&&e.label)?e.label:this._value[0]||"")},0),this._userInfoMessage=""}this._options=[...this.options]}removeLastValue(t){if(this._value.length===0)return;t.preventDefault();const e=this._value[this._value.length-1];e&&this.removeSelected(e),this.isMaxItemsReached()}};n([o.n({type:String,reflect:!0})],exports.PktCombobox.prototype,"value",2);n([o.n({type:Array})],exports.PktCombobox.prototype,"options",2);n([o.n({type:Array})],exports.PktCombobox.prototype,"defaultOptions",2);n([o.n({type:Boolean})],exports.PktCombobox.prototype,"allowUserInput",2);n([o.n({type:Boolean})],exports.PktCombobox.prototype,"typeahead",2);n([o.n({type:Boolean})],exports.PktCombobox.prototype,"includeSearch",2);n([o.n({type:String})],exports.PktCombobox.prototype,"searchPlaceholder",2);n([o.n({type:Boolean})],exports.PktCombobox.prototype,"multiple",2);n([o.n({type:Number})],exports.PktCombobox.prototype,"maxlength",2);n([o.n({type:String})],exports.PktCombobox.prototype,"displayValueAs",2);n([o.n({type:String})],exports.PktCombobox.prototype,"tagPlacement",2);n([d.r()],exports.PktCombobox.prototype,"_options",2);n([d.r()],exports.PktCombobox.prototype,"_value",2);n([d.r()],exports.PktCombobox.prototype,"_isOptionsOpen",2);n([d.r()],exports.PktCombobox.prototype,"_userInfoMessage",2);n([d.r()],exports.PktCombobox.prototype,"_addValueText",2);n([d.r()],exports.PktCombobox.prototype,"_maxIsReached",2);n([d.r()],exports.PktCombobox.prototype,"_search",2);n([d.r()],exports.PktCombobox.prototype,"_inputFocus",2);n([d.r()],exports.PktCombobox.prototype,"_editingSingleValue",2);exports.PktCombobox=n([o.t("pkt-combobox")],exports.PktCombobox);
|