@oslokommune/punkt-elements 15.4.3 → 15.4.5
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 +17 -0
- package/dist/{combobox-CZsCRADa.cjs → combobox-C5YcNVSZ.cjs} +1 -2
- package/dist/{combobox-CXBYVeh-.js → combobox-cer7PLSE.js} +15 -16
- package/dist/{listbox-TRqKskJT.cjs → listbox-C7NEa9SU.cjs} +6 -5
- package/dist/{listbox-CI7Wfn_e.js → listbox-Cykec1bj.js} +12 -11
- package/dist/pkt-combobox.cjs +1 -1
- package/dist/pkt-combobox.js +1 -1
- package/dist/pkt-index.cjs +1 -1
- package/dist/pkt-index.js +1 -1
- package/dist/pkt-listbox.cjs +1 -1
- package/dist/pkt-listbox.js +1 -1
- package/package.json +3 -3
- package/src/components/combobox/combobox.test.ts +0 -10
- package/src/components/combobox/combobox.ts +0 -1
- package/src/components/listbox/listbox.test.ts +113 -0
- package/src/components/listbox/listbox.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ og skriver commits ca etter [Conventional Commits](https://conventionalcommits.o
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
## [15.4.5](https://github.com/oslokommune/punkt/compare/15.4.4...15.4.5) (2026-03-02)
|
|
9
|
+
|
|
10
|
+
### ⚠ BREAKING CHANGES
|
|
11
|
+
Ingen
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
Ingen
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
Ingen
|
|
18
|
+
|
|
19
|
+
### Chores
|
|
20
|
+
Ingen
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
|
|
8
25
|
## [15.4.3](https://github.com/oslokommune/punkt/compare/15.4.2...15.4.3) (2026-02-26)
|
|
9
26
|
|
|
10
27
|
### ⚠ BREAKING CHANGES
|
|
@@ -1,4 +1,4 @@
|
|
|
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")
|
|
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
2
|
<pkt-input-wrapper
|
|
3
3
|
.label=${this.label}
|
|
4
4
|
.helptext=${this.helptext}
|
|
@@ -99,7 +99,6 @@
|
|
|
99
99
|
aria-label=${c.o(this.label)}
|
|
100
100
|
aria-autocomplete=${this.typeahead?"both":"list"}
|
|
101
101
|
aria-controls="${this.id}-listbox"
|
|
102
|
-
aria-multiselectable=${c.o(this.multiple?"true":void 0)}
|
|
103
102
|
aria-activedescendant=${c.o(this._value[0]&&this.findValueInOptions(this._value[0])?`${this.id}-listbox-${this.findIndexInOptions(this._value[0])}`:void 0)}
|
|
104
103
|
${r.n(this.inputRef)}
|
|
105
104
|
/>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { A as I, b as d, n as r, t as w } from "./element-CV9utnHJ.js";
|
|
2
|
-
import { o as
|
|
2
|
+
import { o as v } from "./if-defined-rXcLNTzN.js";
|
|
3
3
|
import { r as c } from "./state-l4hGZdFJ.js";
|
|
4
|
-
import { e as
|
|
4
|
+
import { e as f, n as _ } from "./ref-Dma3n3i8.js";
|
|
5
5
|
import { e as k } from "./class-map-3ADKve8g.js";
|
|
6
6
|
import { c as R } from "./repeat-DnlRNf63.js";
|
|
7
7
|
import { P as V } from "./input-element-Bkv6Yxld.js";
|
|
@@ -10,7 +10,7 @@ import { P as C } from "./pkt-slot-controller-D7CrjM52.js";
|
|
|
10
10
|
import "./input-wrapper-CaUY90qz.js";
|
|
11
11
|
import "./icon-D0IQAVwS.js";
|
|
12
12
|
import "./tag-68q0_Sn0.js";
|
|
13
|
-
import "./listbox-
|
|
13
|
+
import "./listbox-Cykec1bj.js";
|
|
14
14
|
const S = { displayValueAs: { default: "label" } }, T = {
|
|
15
15
|
props: S
|
|
16
16
|
};
|
|
@@ -21,7 +21,7 @@ var M = Object.defineProperty, P = Object.getOwnPropertyDescriptor, n = (t, e, i
|
|
|
21
21
|
};
|
|
22
22
|
let o = class extends V {
|
|
23
23
|
constructor() {
|
|
24
|
-
super(), this.helptextSlot =
|
|
24
|
+
super(), this.helptextSlot = f(), 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 = T.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 = f(), this.arrowRef = f(), this.listboxRef = f(), this.focusRef = f(), this.optionTagRef = f(), this.optionsController = new A(this), this.slotController = new C(this, this.helptextSlot), this.slotController.skipOptions = !0;
|
|
25
25
|
}
|
|
26
26
|
// Lifecycle methods
|
|
27
27
|
connectedCallback() {
|
|
@@ -81,8 +81,8 @@ let o = class extends V {
|
|
|
81
81
|
<pkt-input-wrapper
|
|
82
82
|
.label=${this.label}
|
|
83
83
|
.helptext=${this.helptext}
|
|
84
|
-
.helptextDropdown=${
|
|
85
|
-
.helptextDropdownButton=${
|
|
84
|
+
.helptextDropdown=${v(this.helptextDropdown)}
|
|
85
|
+
.helptextDropdownButton=${v(this.helptextDropdownButton)}
|
|
86
86
|
?fullwidth=${this.fullwidth}
|
|
87
87
|
?hasError=${this.hasError}
|
|
88
88
|
?inline=${this.inline}
|
|
@@ -98,7 +98,7 @@ let o = class extends V {
|
|
|
98
98
|
class="pkt-combobox__wrapper"
|
|
99
99
|
@labelClick=${this.handleInputClick}
|
|
100
100
|
>
|
|
101
|
-
<div class="pkt-contents" ${
|
|
101
|
+
<div class="pkt-contents" ${_(this.helptextSlot)} name="helptext" slot="helptext"></div>
|
|
102
102
|
<div class="pkt-combobox" @focusout=${this.handleFocusOut}>
|
|
103
103
|
<div
|
|
104
104
|
class=${k({
|
|
@@ -120,7 +120,7 @@ let o = class extends V {
|
|
|
120
120
|
@click=${this.handleArrowClick}
|
|
121
121
|
@keydown=${this.handleArrowClick}
|
|
122
122
|
id="${this.id}-arrow"
|
|
123
|
-
${
|
|
123
|
+
${_(this.arrowRef)}
|
|
124
124
|
aria-expanded=${this._isOptionsOpen}
|
|
125
125
|
aria-controls="${this.id}-listbox"
|
|
126
126
|
aria-haspopup="listbox"
|
|
@@ -139,7 +139,7 @@ let o = class extends V {
|
|
|
139
139
|
></pkt-icon>
|
|
140
140
|
</div>
|
|
141
141
|
<div
|
|
142
|
-
${
|
|
142
|
+
${_(this.focusRef)}
|
|
143
143
|
tabindex="-1"
|
|
144
144
|
@keydown=${this.handleArrowClick}
|
|
145
145
|
class="pkt-contents"
|
|
@@ -156,7 +156,7 @@ let o = class extends V {
|
|
|
156
156
|
?isMultiSelect=${this.multiple}
|
|
157
157
|
?allowUserInput=${this.allowUserInput && !this._maxIsReached}
|
|
158
158
|
?maxIsReached=${this._maxIsReached}
|
|
159
|
-
.customUserInput=${
|
|
159
|
+
.customUserInput=${v(this._addValueText)}
|
|
160
160
|
.userMessage=${this._userInfoMessage}
|
|
161
161
|
@search=${this.handleSearch}
|
|
162
162
|
@option-toggle=${this.handleOptionToggled}
|
|
@@ -164,7 +164,7 @@ let o = class extends V {
|
|
|
164
164
|
@close-options=${() => this._isOptionsOpen = !1}
|
|
165
165
|
.searchValue=${this._search || null}
|
|
166
166
|
.maxLength=${this.maxlength || 0}
|
|
167
|
-
${
|
|
167
|
+
${_(this.listboxRef)}
|
|
168
168
|
></pkt-listbox>
|
|
169
169
|
</div>
|
|
170
170
|
|
|
@@ -187,14 +187,13 @@ let o = class extends V {
|
|
|
187
187
|
@blur=${this.handleBlur}
|
|
188
188
|
autocomplete="off"
|
|
189
189
|
role="combobox"
|
|
190
|
-
aria-label=${
|
|
190
|
+
aria-label=${v(this.label)}
|
|
191
191
|
aria-autocomplete=${this.typeahead ? "both" : "list"}
|
|
192
192
|
aria-controls="${this.id}-listbox"
|
|
193
|
-
aria-
|
|
194
|
-
aria-activedescendant=${f(
|
|
193
|
+
aria-activedescendant=${v(
|
|
195
194
|
this._value[0] && this.findValueInOptions(this._value[0]) ? `${this.id}-listbox-${this.findIndexInOptions(this._value[0])}` : void 0
|
|
196
195
|
)}
|
|
197
|
-
${
|
|
196
|
+
${_(this.inputRef)}
|
|
198
197
|
/>
|
|
199
198
|
</div>
|
|
200
199
|
` : d`
|
|
@@ -203,7 +202,7 @@ let o = class extends V {
|
|
|
203
202
|
id="${this.id}-input"
|
|
204
203
|
name=${(this.name || this.id) + "-input"}
|
|
205
204
|
.value=${this._value.join(",")}
|
|
206
|
-
${
|
|
205
|
+
${_(this.inputRef)}
|
|
207
206
|
/>
|
|
208
207
|
`;
|
|
209
208
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
"use strict";const s=require("./element-CMTfByxQ.cjs"),p=require("./state-BNgpvY-A.cjs"),
|
|
1
|
+
"use strict";const s=require("./element-CMTfByxQ.cjs"),p=require("./state-BNgpvY-A.cjs"),c=require("./if-defined-hKKmbsI8.cjs"),u=require("./repeat-C-FJ2vfy.cjs"),h=require("./class-map-Bokp1SoS.cjs"),d=require("./utils-byXsEz1u.cjs");var b=Object.defineProperty,f=Object.getOwnPropertyDescriptor,l=(r,e,t,i)=>{for(var n=i>1?void 0:i?f(e,t):e,o=r.length-1,a;o>=0;o--)(a=r[o])&&(n=(i?a(e,t,n):a(n))||n);return i&&n&&b(e,t,n),n};exports.PktListbox=class extends s.PktElement{constructor(){super(...arguments),this.id=d.uuidish(),this.label=null,this.options=[],this.isOpen=!1,this.disabled=!1,this.includeSearch=!1,this.isMultiSelect=!1,this.allowUserInput=!1,this.maxIsReached=!1,this.customUserInput=null,this.searchPlaceholder=null,this.searchValue=null,this.maxLength=0,this.userMessage=null,this._selectedOptions=0,this._filteredOptions=[]}connectedCallback(){super.connectedCallback(),this.includeSearch&&!this.searchValue&&(this.searchValue=""),this.options.length>0&&this.filterOptions(),this.setAttribute("tabindex","-1"),this.addEventListener("focus",this.focusFirstOrSelectedOption)}updated(e){(e.has("options")||e.has("searchValue"))&&this.filterOptions(),super.updated(e)}attributeChangedCallback(e,t,i){(e==="options"||e==="searchValue"||e==="search-value")&&this.filterOptions(),super.attributeChangedCallback(e,t,i)}render(){return s.b`
|
|
2
2
|
<div
|
|
3
|
-
class=${
|
|
3
|
+
class=${h.e({"pkt-listbox":!0,"pkt-listbox__open":this.isOpen,"pkt-txt-16-light":!0})}
|
|
4
4
|
role="listbox"
|
|
5
|
-
aria-
|
|
5
|
+
aria-multiselectable=${c.o(this.isMultiSelect?"true":void 0)}
|
|
6
|
+
aria-label=${c.o(this.label)}
|
|
6
7
|
>
|
|
7
8
|
<div class="pkt-listbox__banners">
|
|
8
9
|
${this.renderMaximumReachedBanner()} ${this.renderUserMessage()}
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
@click=${()=>{this.toggleOption(e)}}
|
|
30
31
|
aria-selected=${e.selected?"true":"false"}
|
|
31
32
|
@keydown=${this.handleOptionKeydown}
|
|
32
|
-
class=${
|
|
33
|
+
class=${h.e({"pkt-listbox__option":!0,"pkt-listbox__option--selected":!!(!this.isMultiSelect&&e.selected),"pkt-listbox__option--checkBox":this.isMultiSelect})}
|
|
33
34
|
tabindex="${this.disabled||e.disabled?"-1":"0"}"
|
|
34
35
|
data-index=${t}
|
|
35
36
|
data-value=${e.value}
|
|
@@ -92,4 +93,4 @@
|
|
|
92
93
|
role="searchbox"
|
|
93
94
|
/>
|
|
94
95
|
</div>
|
|
95
|
-
`:s.A}handleSearchInput(e){this.searchValue=e.target.value,this.dispatchEvent(new CustomEvent("search",{detail:this.searchValue,bubbles:!1}))}handleSearchKeydown(e){switch(e.key){case"Enter":e.preventDefault();break;case"ArrowUp":case"Escape":this.closeOptions(),e.preventDefault();break;case"ArrowDown":case"Tab":this.focusFirstOrSelectedOption();break}}handleOptionKeydown(e){const t=e.currentTarget,i=t.dataset.value,
|
|
96
|
+
`:s.A}handleSearchInput(e){this.searchValue=e.target.value,this.dispatchEvent(new CustomEvent("search",{detail:this.searchValue,bubbles:!1}))}handleSearchKeydown(e){switch(e.key){case"Enter":e.preventDefault();break;case"ArrowUp":case"Escape":this.closeOptions(),e.preventDefault();break;case"ArrowDown":case"Tab":this.focusFirstOrSelectedOption();break}}handleOptionKeydown(e){const t=e.currentTarget,i=t.dataset.value,n=t.dataset.type,o=t.dataset.selected==="true";if(!(!this.getOptionElements().length&&(!this.customUserInput||!this.allowUserInput&&this.customUserInput)&&n!=="new-option"&&n!=="searchbox"))switch(e.key){case" ":case"Enter":this.toggleOption(t),e.preventDefault();break;case"Backspace":i&&(o?this.toggleOption(t):this.closeOptions()),e.preventDefault();break;case"Escape":case"Tab":this.closeOptions();break;case"ArrowDown":e.altKey?this.focusLastOption():n==="searchbox"||n==="new-option"?this.focusFirstOption():this.focusNextOption(t),e.preventDefault();break;case"ArrowUp":if(e.altKey)this.focusFirstOption();else if(t.dataset.index==="0"&&this.includeSearch){const a=this.querySelector('[role="searchbox"]');a&&a.focus()}else if(t.dataset.index==="0"&&this.customUserInput){const a=this.querySelector('[data-type="new-option"]');a&&a.focus()}else this.focusPreviousOption(t);e.preventDefault();break;case"Home":this.focusFirstOption(),e.preventDefault();break;case"End":this.focusLastOption(),e.preventDefault();break;default:(e.metaKey||e.ctrlKey)&&e.key==="a"&&(this.selectAll(),e.preventDefault()),this.isLetterOrSpace(e.key)&&(this.handleTypeAhead(e.key),e.preventDefault());break}}focusAndScrollIntoView(e){e.scrollIntoView({block:"nearest"}),window.setTimeout(()=>e.focus(),0)}focusNextOption(e){const t=e.nextElementSibling;t&&this.focusAndScrollIntoView(t)}focusPreviousOption(e){const t=e.previousElementSibling;if(e.dataset.index==="0"&&this.includeSearch){const i=this.querySelector('[role="searchbox"]');i&&this.focusAndScrollIntoView(i)}else t&&this.focusAndScrollIntoView(t)}focusFirstOption(){const e=this.getOptionElements()[0];e&&this.focusAndScrollIntoView(e)}focusLastOption(){const e=this.getOptionElements().pop();e&&this.focusAndScrollIntoView(e)}focusFirstOrSelectedOption(){if(this.disabled)return;const e=this.getOptionElements().find(t=>t.dataset.selected==="true");if(this.allowUserInput&&this.customUserInput){const t=this.querySelector('[data-type="new-option"]');this.focusAndScrollIntoView(t)}else if(e)this.focusAndScrollIntoView(e);else if(this.includeSearch&&!(document.activeElement instanceof HTMLInputElement)){const t=this.querySelector('[role="searchbox"]');window.setTimeout(()=>t.focus(),0)}else this.focusFirstOption()}toggleOption(e){const t=e instanceof HTMLElement?e.dataset.disabled:e.disabled;if(this.disabled||t)return;const i=e instanceof HTMLElement?e.dataset.value:e.value;this.dispatchEvent(new CustomEvent("option-toggle",{detail:i,bubbles:!1}))}selectAll(){this.dispatchEvent(new CustomEvent("select-all",{bubbles:!1}))}closeOptions(){this.dispatchEvent(new CustomEvent("close-options",{bubbles:!1}))}filterOptions(){this.searchValue?this._filteredOptions=this.options.filter(e=>{var i;return(e.fulltext||e.label+e.value+(e.prefix||"")).toLowerCase().includes(((i=this.searchValue)==null?void 0:i.toLowerCase())||"")}):this._filteredOptions=[...this.options]}isLetterOrSpace(e){return/^[\p{L} ]$/u.test(e)}handleTypeAhead(e){this.typeAheadString+=e.toLowerCase(),this.typeAheadTimeout&&clearTimeout(this.typeAheadTimeout),this.typeAheadTimeout=window.setTimeout(()=>{this.typeAheadString=""},500);const i=this.getOptionElements().find(n=>{var o;return(o=n.textContent)==null?void 0:o.trim().toLowerCase().startsWith(this.typeAheadString)});i&&this.focusAndScrollIntoView(i)}getOptionElements(){return this._filteredOptions.length?Array.from(this.querySelectorAll('[role="option"]:not([data-disabled])')||[]):[]}};l([s.n({type:String})],exports.PktListbox.prototype,"id",2);l([s.n({type:String})],exports.PktListbox.prototype,"label",2);l([s.n({type:Array})],exports.PktListbox.prototype,"options",2);l([s.n({type:Boolean,reflect:!0})],exports.PktListbox.prototype,"isOpen",2);l([s.n({type:Boolean})],exports.PktListbox.prototype,"disabled",2);l([s.n({type:Boolean})],exports.PktListbox.prototype,"includeSearch",2);l([s.n({type:Boolean})],exports.PktListbox.prototype,"isMultiSelect",2);l([s.n({type:Boolean})],exports.PktListbox.prototype,"allowUserInput",2);l([s.n({type:Boolean})],exports.PktListbox.prototype,"maxIsReached",2);l([s.n({type:String})],exports.PktListbox.prototype,"customUserInput",2);l([s.n({type:String})],exports.PktListbox.prototype,"searchPlaceholder",2);l([s.n({type:String})],exports.PktListbox.prototype,"searchValue",2);l([s.n({type:Number})],exports.PktListbox.prototype,"maxLength",2);l([s.n({type:String})],exports.PktListbox.prototype,"userMessage",2);l([p.r()],exports.PktListbox.prototype,"_filteredOptions",2);exports.PktListbox=l([s.t("pkt-listbox")],exports.PktListbox);
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { P as
|
|
2
|
-
import { r as
|
|
3
|
-
import { o as
|
|
1
|
+
import { P as b, b as r, A as p, s as f, n as a, t as m } from "./element-CV9utnHJ.js";
|
|
2
|
+
import { r as y } from "./state-l4hGZdFJ.js";
|
|
3
|
+
import { o as u } from "./if-defined-rXcLNTzN.js";
|
|
4
4
|
import { c as k } from "./repeat-DnlRNf63.js";
|
|
5
|
-
import { e as
|
|
5
|
+
import { e as d } from "./class-map-3ADKve8g.js";
|
|
6
6
|
import { u as x } from "./utils-DznhwRXm.js";
|
|
7
7
|
var O = Object.defineProperty, g = Object.getOwnPropertyDescriptor, l = (e, t, s, o) => {
|
|
8
8
|
for (var n = o > 1 ? void 0 : o ? g(t, s) : t, c = e.length - 1, h; c >= 0; c--)
|
|
9
9
|
(h = e[c]) && (n = (o ? h(t, s, n) : h(n)) || n);
|
|
10
10
|
return o && n && O(t, s, n), n;
|
|
11
11
|
};
|
|
12
|
-
let i = class extends
|
|
12
|
+
let i = class extends b {
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments), this.id = x(), this.label = null, this.options = [], this.isOpen = !1, this.disabled = !1, this.includeSearch = !1, this.isMultiSelect = !1, this.allowUserInput = !1, this.maxIsReached = !1, this.customUserInput = null, this.searchPlaceholder = null, this.searchValue = null, this.maxLength = 0, this.userMessage = null, this._selectedOptions = 0, this._filteredOptions = [];
|
|
15
15
|
}
|
|
@@ -27,13 +27,14 @@ let i = class extends d {
|
|
|
27
27
|
render() {
|
|
28
28
|
return r`
|
|
29
29
|
<div
|
|
30
|
-
class=${
|
|
30
|
+
class=${d({
|
|
31
31
|
"pkt-listbox": !0,
|
|
32
32
|
"pkt-listbox__open": this.isOpen,
|
|
33
33
|
"pkt-txt-16-light": !0
|
|
34
34
|
})}
|
|
35
35
|
role="listbox"
|
|
36
|
-
aria-
|
|
36
|
+
aria-multiselectable=${u(this.isMultiSelect ? "true" : void 0)}
|
|
37
|
+
aria-label=${u(this.label)}
|
|
37
38
|
>
|
|
38
39
|
<div class="pkt-listbox__banners">
|
|
39
40
|
${this.renderMaximumReachedBanner()} ${this.renderUserMessage()}
|
|
@@ -71,7 +72,7 @@ let i = class extends d {
|
|
|
71
72
|
}}
|
|
72
73
|
aria-selected=${e.selected ? "true" : "false"}
|
|
73
74
|
@keydown=${this.handleOptionKeydown}
|
|
74
|
-
class=${
|
|
75
|
+
class=${d({
|
|
75
76
|
"pkt-listbox__option": !0,
|
|
76
77
|
"pkt-listbox__option--selected": !!(!this.isMultiSelect && e.selected),
|
|
77
78
|
"pkt-listbox__option--checkBox": this.isMultiSelect
|
|
@@ -143,7 +144,7 @@ let i = class extends d {
|
|
|
143
144
|
type="text"
|
|
144
145
|
aria-label="Søk i listen"
|
|
145
146
|
form=""
|
|
146
|
-
placeholder=${this.searchPlaceholder ||
|
|
147
|
+
placeholder=${this.searchPlaceholder || f.forms.search.placeholder}
|
|
147
148
|
@input=${this.handleSearchInput}
|
|
148
149
|
@keydown=${this.handleSearchKeydown}
|
|
149
150
|
.value=${this.searchValue}
|
|
@@ -350,10 +351,10 @@ l([
|
|
|
350
351
|
a({ type: String })
|
|
351
352
|
], i.prototype, "userMessage", 2);
|
|
352
353
|
l([
|
|
353
|
-
|
|
354
|
+
y()
|
|
354
355
|
], i.prototype, "_filteredOptions", 2);
|
|
355
356
|
i = l([
|
|
356
|
-
|
|
357
|
+
m("pkt-listbox")
|
|
357
358
|
], i);
|
|
358
359
|
export {
|
|
359
360
|
i as P
|
package/dist/pkt-combobox.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./combobox-
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./combobox-C5YcNVSZ.cjs"),o=e.PktCombobox;Object.defineProperty(exports,"PktCombobox",{enumerable:!0,get:()=>e.PktCombobox});exports.default=o;
|
package/dist/pkt-combobox.js
CHANGED
package/dist/pkt-index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("./alert-BDXWFRcf.cjs"),t=require("./accordionitem-To95GT6b.cjs"),a=require("./backlink-CQoNgoa-.cjs"),P=require("./button-VWxZW89G.cjs"),i=require("./calendar-DjbO2g5L.cjs"),c=require("./card-5S2r9UD1.cjs"),b=require("./combobox-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("./alert-BDXWFRcf.cjs"),t=require("./accordionitem-To95GT6b.cjs"),a=require("./backlink-CQoNgoa-.cjs"),P=require("./button-VWxZW89G.cjs"),i=require("./calendar-DjbO2g5L.cjs"),c=require("./card-5S2r9UD1.cjs"),b=require("./combobox-C5YcNVSZ.cjs"),k=require("./consent-BQLkfN3d.cjs"),d=require("./checkbox-D98_NjcU.cjs"),r=require("./datepicker-SEKblnRR.cjs"),e=require("./pkt-header.cjs"),l=require("./helptext-BjW1WdOn.cjs"),s=require("./heading-B0XRE0lq.cjs"),p=require("./icon-Dj0oZZSa.cjs"),g=require("./input-wrapper-JU4D2TGu.cjs"),m=require("./link-CDuv1jxx.cjs"),f=require("./linkcard-3WUL0CpY.cjs"),y=require("./loader-C1LI8Q4z.cjs"),j=require("./messagebox-Dmot5szX.cjs"),O=require("./modal-S9MOKOaz.cjs"),q=require("./progressbar-Bxh335uT.cjs"),n=require("./radiobutton-95wp024h.cjs"),x=require("./tag-BnT5onW2.cjs"),o=require("./tabitem-BKv4eN0a.cjs"),T=require("./textarea-CuTsE1WX.cjs"),C=require("./textinput-st4Vml5J.cjs"),H=require("./select-CZ_Lx5W6.cjs");Object.defineProperty(exports,"PktAlert",{enumerable:!0,get:()=>u.PktAlert});exports.PktAccordion=t.PktAccordion;exports.PktAccordionItem=t.PktAccordionItem_default;Object.defineProperty(exports,"PktBackLink",{enumerable:!0,get:()=>a.PktBackLink});Object.defineProperty(exports,"PktButton",{enumerable:!0,get:()=>P.PktButton});Object.defineProperty(exports,"PktCalendar",{enumerable:!0,get:()=>i.PktCalendar});Object.defineProperty(exports,"PktCard",{enumerable:!0,get:()=>c.PktCard});Object.defineProperty(exports,"PktCombobox",{enumerable:!0,get:()=>b.PktCombobox});Object.defineProperty(exports,"PktConsent",{enumerable:!0,get:()=>k.PktConsent});Object.defineProperty(exports,"PktCheckbox",{enumerable:!0,get:()=>d.PktCheckbox});Object.defineProperty(exports,"PktDateTags",{enumerable:!0,get:()=>r.PktDateTags});Object.defineProperty(exports,"PktDatepicker",{enumerable:!0,get:()=>r.PktDatepicker});Object.defineProperty(exports,"PktHeader",{enumerable:!0,get:()=>e.PktHeader});Object.defineProperty(exports,"PktHeaderService",{enumerable:!0,get:()=>e.PktHeaderService});Object.defineProperty(exports,"PktHeaderUserMenu",{enumerable:!0,get:()=>e.PktHeaderUserMenu});Object.defineProperty(exports,"PktHelptext",{enumerable:!0,get:()=>l.PktHelptext});Object.defineProperty(exports,"PktHeading",{enumerable:!0,get:()=>s.PktHeading});Object.defineProperty(exports,"PktIcon",{enumerable:!0,get:()=>p.PktIcon});Object.defineProperty(exports,"PktInputWrapper",{enumerable:!0,get:()=>g.PktInputWrapper});Object.defineProperty(exports,"PktLink",{enumerable:!0,get:()=>m.PktLink});Object.defineProperty(exports,"PktLinkCard",{enumerable:!0,get:()=>f.PktLinkCard});Object.defineProperty(exports,"PktLoader",{enumerable:!0,get:()=>y.PktLoader});Object.defineProperty(exports,"PktMessagebox",{enumerable:!0,get:()=>j.PktMessagebox});Object.defineProperty(exports,"PktModal",{enumerable:!0,get:()=>O.PktModal});Object.defineProperty(exports,"PktProgressbar",{enumerable:!0,get:()=>q.PktProgressbar});Object.defineProperty(exports,"PktRadioButton",{enumerable:!0,get:()=>n.PktRadioButton});Object.defineProperty(exports,"PktRadiobutton",{enumerable:!0,get:()=>n.PktRadioButton});Object.defineProperty(exports,"PktTag",{enumerable:!0,get:()=>x.PktTag});exports.PktTabItem=o.PktTabItem_default;exports.PktTabs=o.PktTabs;Object.defineProperty(exports,"PktTextarea",{enumerable:!0,get:()=>T.PktTextarea});Object.defineProperty(exports,"PktTextinput",{enumerable:!0,get:()=>C.PktTextinput});Object.defineProperty(exports,"PktSelect",{enumerable:!0,get:()=>H.PktSelect});
|
package/dist/pkt-index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { P as s } from "./backlink-C68H4Z3b.js";
|
|
|
4
4
|
import { P as x } from "./button-CHUuxLQV.js";
|
|
5
5
|
import { P as f } from "./calendar-DTnx3DDH.js";
|
|
6
6
|
import { P as d } from "./card-CnPjrdre.js";
|
|
7
|
-
import { P as c } from "./combobox-
|
|
7
|
+
import { P as c } from "./combobox-cer7PLSE.js";
|
|
8
8
|
import { P as u } from "./consent-knPF4PS_.js";
|
|
9
9
|
import { P as T } from "./checkbox-BSz71IeT.js";
|
|
10
10
|
import { P as l, a as H } from "./datepicker-nnyTW0vf.js";
|
package/dist/pkt-listbox.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./listbox-
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./listbox-C7NEa9SU.cjs"),t=e.PktListbox;Object.defineProperty(exports,"PktListbox",{enumerable:!0,get:()=>e.PktListbox});exports.default=t;
|
package/dist/pkt-listbox.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oslokommune/punkt-elements",
|
|
3
|
-
"version": "15.4.
|
|
3
|
+
"version": "15.4.5",
|
|
4
4
|
"description": "Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo",
|
|
5
5
|
"homepage": "https://punkt.oslo.kommune.no",
|
|
6
6
|
"author": "Team Designsystem, Oslo Origo",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@babel/preset-env": "^7.28.3",
|
|
43
43
|
"@babel/preset-typescript": "^7.25.9",
|
|
44
44
|
"@oslokommune/punkt-assets": "^15.0.0",
|
|
45
|
-
"@oslokommune/punkt-css": "^15.4.
|
|
45
|
+
"@oslokommune/punkt-css": "^15.4.4",
|
|
46
46
|
"@testing-library/jest-dom": "^6.6.3",
|
|
47
47
|
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
|
48
48
|
"@typescript-eslint/parser": "^8.46.0",
|
|
@@ -79,5 +79,5 @@
|
|
|
79
79
|
"url": "https://github.com/oslokommune/punkt/issues"
|
|
80
80
|
},
|
|
81
81
|
"license": "MIT",
|
|
82
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "64154bb897bebc4a10bddd741816ca5943b1f687"
|
|
83
83
|
}
|
|
@@ -700,16 +700,6 @@ describe('PktCombobox', () => {
|
|
|
700
700
|
expect(textInput?.getAttribute('aria-autocomplete')).toBe('list')
|
|
701
701
|
})
|
|
702
702
|
|
|
703
|
-
test('sets correct ARIA attributes for multiple selection', async () => {
|
|
704
|
-
const container = await createCombobox('id="test" name="test" allowUserInput multiple')
|
|
705
|
-
|
|
706
|
-
const combobox = container.querySelector('pkt-combobox') as PktCombobox
|
|
707
|
-
await combobox.updateComplete
|
|
708
|
-
|
|
709
|
-
const textInput = combobox.querySelector('input[type="text"]')
|
|
710
|
-
expect(textInput?.getAttribute('aria-multiselectable')).toBe('true')
|
|
711
|
-
})
|
|
712
|
-
|
|
713
703
|
test('sets correct aria-activedescendant when value is selected', async () => {
|
|
714
704
|
const testOptions: IPktComboboxOption[] = [{ value: 'option1', label: 'Option 1' }]
|
|
715
705
|
|
|
@@ -383,7 +383,6 @@ export class PktCombobox extends PktInputElement implements IPktCombobox {
|
|
|
383
383
|
aria-label=${ifDefined(this.label)}
|
|
384
384
|
aria-autocomplete=${this.typeahead ? 'both' : 'list'}
|
|
385
385
|
aria-controls="${this.id}-listbox"
|
|
386
|
-
aria-multiselectable=${ifDefined(this.multiple ? 'true' : undefined)}
|
|
387
386
|
aria-activedescendant=${ifDefined(
|
|
388
387
|
this._value[0] && !!this.findValueInOptions(this._value[0])
|
|
389
388
|
? `${this.id}-listbox-${this.findIndexInOptions(this._value[0])}`
|
|
@@ -206,6 +206,119 @@ describe('PktListbox', () => {
|
|
|
206
206
|
})
|
|
207
207
|
})
|
|
208
208
|
|
|
209
|
+
describe('Multi-select functionality', () => {
|
|
210
|
+
test('sets aria-multiselectable to true when isMultiSelect is true', async () => {
|
|
211
|
+
const options = [
|
|
212
|
+
{ value: 'option1', label: 'Option 1' },
|
|
213
|
+
{ value: 'option2', label: 'Option 2' },
|
|
214
|
+
]
|
|
215
|
+
const { listbox } = await createListboxTest({
|
|
216
|
+
isMultiSelect: true,
|
|
217
|
+
options,
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
const listboxElement = listbox.querySelector('[role="listbox"]')
|
|
221
|
+
expect(listboxElement?.getAttribute('aria-multiselectable')).toBe('true')
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
test('allows multiple options to be selected', async () => {
|
|
225
|
+
const options = [
|
|
226
|
+
{ value: 'option1', label: 'Option 1', selected: true },
|
|
227
|
+
{ value: 'option2', label: 'Option 2', selected: true },
|
|
228
|
+
{ value: 'option3', label: 'Option 3', selected: false },
|
|
229
|
+
]
|
|
230
|
+
const { listbox } = await createListboxTest({
|
|
231
|
+
isMultiSelect: true,
|
|
232
|
+
options,
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
const checkboxes = listbox.querySelectorAll('input[type="checkbox"]')
|
|
236
|
+
expect(checkboxes[0]).toBeChecked()
|
|
237
|
+
expect(checkboxes[1]).toBeChecked()
|
|
238
|
+
expect(checkboxes[2]).not.toBeChecked()
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
test('dispatches select-all event when Cmd+A is pressed', async () => {
|
|
242
|
+
const options = [
|
|
243
|
+
{ value: 'option1', label: 'Option 1' },
|
|
244
|
+
{ value: 'option2', label: 'Option 2' },
|
|
245
|
+
{ value: 'option3', label: 'Option 3' },
|
|
246
|
+
]
|
|
247
|
+
const { listbox } = await createListboxTest({
|
|
248
|
+
isMultiSelect: true,
|
|
249
|
+
options,
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
let selectAllCalled = false
|
|
253
|
+
listbox.addEventListener('select-all', () => {
|
|
254
|
+
selectAllCalled = true
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
const firstOption = listbox.querySelector('.pkt-listbox__option')
|
|
258
|
+
firstOption?.dispatchEvent(
|
|
259
|
+
new KeyboardEvent('keydown', {
|
|
260
|
+
key: 'a',
|
|
261
|
+
metaKey: true,
|
|
262
|
+
bubbles: true,
|
|
263
|
+
}),
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
await listbox.updateComplete
|
|
267
|
+
expect(selectAllCalled).toBe(true)
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
test('dispatches select-all event when Ctrl+A is pressed', async () => {
|
|
271
|
+
const options = [
|
|
272
|
+
{ value: 'option1', label: 'Option 1' },
|
|
273
|
+
{ value: 'option2', label: 'Option 2' },
|
|
274
|
+
]
|
|
275
|
+
const { listbox } = await createListboxTest({
|
|
276
|
+
isMultiSelect: true,
|
|
277
|
+
options,
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
let selectAllCalled = false
|
|
281
|
+
listbox.addEventListener('select-all', () => {
|
|
282
|
+
selectAllCalled = true
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
const firstOption = listbox.querySelector('.pkt-listbox__option')
|
|
286
|
+
firstOption?.dispatchEvent(
|
|
287
|
+
new KeyboardEvent('keydown', {
|
|
288
|
+
key: 'a',
|
|
289
|
+
ctrlKey: true,
|
|
290
|
+
bubbles: true,
|
|
291
|
+
}),
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
await listbox.updateComplete
|
|
295
|
+
expect(selectAllCalled).toBe(true)
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
test('toggles individual options in multi-select mode', async () => {
|
|
299
|
+
const options = [
|
|
300
|
+
{ value: 'option1', label: 'Option 1' },
|
|
301
|
+
{ value: 'option2', label: 'Option 2' },
|
|
302
|
+
]
|
|
303
|
+
const { listbox } = await createListboxTest({
|
|
304
|
+
isMultiSelect: true,
|
|
305
|
+
options,
|
|
306
|
+
})
|
|
307
|
+
|
|
308
|
+
const toggledValues: string[] = []
|
|
309
|
+
listbox.addEventListener('option-toggle', (e: any) => {
|
|
310
|
+
toggledValues.push(e.detail)
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
const optionElements = listbox.querySelectorAll('.pkt-listbox__option')
|
|
314
|
+
fireEvent.click(optionElements[0])
|
|
315
|
+
fireEvent.click(optionElements[1])
|
|
316
|
+
|
|
317
|
+
await listbox.updateComplete
|
|
318
|
+
expect(toggledValues).toEqual(['option1', 'option2'])
|
|
319
|
+
})
|
|
320
|
+
})
|
|
321
|
+
|
|
209
322
|
describe('Accessibility', () => {
|
|
210
323
|
test('basic listbox is accessible', async () => {
|
|
211
324
|
const options = [
|
|
@@ -87,6 +87,7 @@ export class PktListbox extends PktElement implements IPktListbox {
|
|
|
87
87
|
'pkt-txt-16-light': true,
|
|
88
88
|
})}
|
|
89
89
|
role="listbox"
|
|
90
|
+
aria-multiselectable=${ifDefined(this.isMultiSelect ? 'true' : undefined)}
|
|
90
91
|
aria-label=${ifDefined(this.label)}
|
|
91
92
|
>
|
|
92
93
|
<div class="pkt-listbox__banners">
|