@oslokommune/punkt-elements 19.5.1 → 19.5.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/base-elements/checkable-native-parity.test.d.ts +0 -0
  3. package/dist/base-elements/form-disabled.test.d.ts +0 -0
  4. package/dist/base-elements/input-element.d.ts +10 -1
  5. package/dist/{checkbox-DKeErDb5.js → checkbox-Bbxt-tVW.js} +8 -8
  6. package/dist/checkbox-_NnoYkue.cjs +40 -0
  7. package/dist/{combobox-C7FUvv5T.cjs → combobox-BBx87DCG.cjs} +6 -6
  8. package/dist/{combobox-BKnHg_-E.js → combobox-CjLX_Gfd.js} +14 -14
  9. package/dist/{datepicker-CeUpoQuG.cjs → datepicker-Bk-m5Zaa.cjs} +5 -5
  10. package/dist/{datepicker-COFEJpB4.js → datepicker-CFCRxFQL.js} +6 -6
  11. package/dist/{fileupload-CUPl41uN.js → fileupload-B2606SvG.js} +1 -1
  12. package/dist/{fileupload-CaZGBvZr.cjs → fileupload-COAxc3sX.cjs} +1 -1
  13. package/dist/{header-Cq6INZmI.js → header-BQdc29IO.js} +1 -1
  14. package/dist/{header-CgP3-6-b.cjs → header-BhM7FRoC.cjs} +1 -1
  15. package/dist/input-element-CSfDGslx.cjs +1 -0
  16. package/dist/{input-element-5hsxasU3.js → input-element-lLzfwdim.js} +198 -173
  17. package/dist/{input-wrapper-Cf__-4E-.cjs → input-wrapper-BBG8EXQ8.cjs} +20 -20
  18. package/dist/{input-wrapper-DACDx6Ie.js → input-wrapper-Bz9GwYrn.js} +20 -20
  19. package/dist/pkt-checkbox.cjs +1 -1
  20. package/dist/pkt-checkbox.js +1 -1
  21. package/dist/pkt-combobox.cjs +1 -1
  22. package/dist/pkt-combobox.js +1 -1
  23. package/dist/pkt-datepicker.cjs +1 -1
  24. package/dist/pkt-datepicker.js +1 -1
  25. package/dist/pkt-fileupload.cjs +1 -1
  26. package/dist/pkt-fileupload.js +1 -1
  27. package/dist/pkt-header.cjs +1 -1
  28. package/dist/pkt-header.js +1 -1
  29. package/dist/pkt-index.cjs +1 -1
  30. package/dist/pkt-index.js +11 -11
  31. package/dist/pkt-input-wrapper.cjs +1 -1
  32. package/dist/pkt-input-wrapper.js +1 -1
  33. package/dist/pkt-radiobutton.cjs +1 -1
  34. package/dist/pkt-radiobutton.js +1 -1
  35. package/dist/pkt-select.cjs +1 -1
  36. package/dist/pkt-select.js +1 -1
  37. package/dist/pkt-textarea.cjs +1 -1
  38. package/dist/pkt-textarea.js +1 -1
  39. package/dist/pkt-textinput.cjs +1 -1
  40. package/dist/pkt-textinput.js +1 -1
  41. package/dist/pkt-timepicker.cjs +1 -1
  42. package/dist/pkt-timepicker.js +1 -1
  43. package/dist/{radiobutton-oEYrBiT6.cjs → radiobutton-C3kEjvHQ.cjs} +2 -2
  44. package/dist/{radiobutton-DP791tUe.js → radiobutton-D9htviZG.js} +5 -5
  45. package/dist/{select-B97S4g1v.js → select-BizHes0n.js} +4 -4
  46. package/dist/{select-QobXCtIL.cjs → select-BuQxosyi.cjs} +3 -3
  47. package/dist/{textarea-ZMbtZNp3.cjs → textarea-BXadsEdL.cjs} +3 -3
  48. package/dist/{textarea-DgW0hRV5.js → textarea-CL1yUDVL.js} +4 -4
  49. package/dist/{textinput-s-qz2xSC.js → textinput-Csil0Zda.js} +4 -4
  50. package/dist/{textinput-DfT_1aGb.cjs → textinput-qi0f5NZH.cjs} +3 -3
  51. package/dist/{timepicker-BAa_VEnf.cjs → timepicker-CvL2-Siz.cjs} +8 -8
  52. package/dist/{timepicker-Crj4isb9.js → timepicker-DNoYMBAL.js} +9 -9
  53. package/package.json +2 -2
  54. package/src/components/checkbox/checkbox.ts +6 -9
  55. package/src/components/combobox/combobox-handlers.ts +6 -6
  56. package/src/components/combobox/combobox-value.ts +1 -1
  57. package/src/components/combobox/combobox.ts +5 -5
  58. package/src/components/datepicker/datepicker.ts +4 -4
  59. package/src/components/input-wrapper/input-wrapper.test.ts +36 -0
  60. package/src/components/input-wrapper/input-wrapper.ts +12 -5
  61. package/src/components/radiobutton/radiobutton.ts +3 -6
  62. package/src/components/select/select.ts +2 -2
  63. package/src/components/textarea/textarea.ts +2 -2
  64. package/src/components/textinput/textinput.ts +2 -2
  65. package/src/components/timepicker/timepicker.ts +7 -7
  66. package/dist/checkbox-DIyi1Cya.cjs +0 -40
  67. package/dist/input-element-Ctkz5fQk.cjs +0 -1
@@ -1,11 +1,11 @@
1
- const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),n=require("./element-with-slot-D7sTqOr3.cjs");require("./icon-Dnv6LtPC.cjs");const r=require("./if-defined-2mkIDgOm.cjs"),i=require("./ref-Emu5PNxk.cjs"),a=require("./input-element-Ctkz5fQk.cjs"),o=require("./input-wrapper-Cf__-4E-.cjs");var s=class extends a.t{constructor(...e){super(...e),this.inputRef=i.t(),this.value=``,this.type=`text`,this.size=null,this.autocomplete=null,this.iconNameRight=null,this.prefix=null,this.suffix=null,this.omitSearchIcon=!1,this.counterCurrent=0}attributeChangedCallback(e,t,n){e===`value`&&this.value!==t&&(this.counterCurrent=n?n.length:0),super.attributeChangedCallback(e,t,n)}willUpdate(e){super.willUpdate(e),e.has(`value`)&&(this.counterCurrent=this.value?.length||0),e.has(`id`)&&!this.name&&this.id&&(this.name=this.id)}updated(e){super.updated(e),this.classList.add(`pkt-textinput`),e.has(`value`)&&this.valueChanged(this.value,e.get(`value`))}render(){let a=this.type===`search`&&!this.iconNameRight&&!this.omitSearchIcon,s=this.effectiveCounter(this.counterMaxLength>0),c=t.t({"pkt-input":!0,[`pkt-input--${this.inputSize}`]:!0,"pkt-input--fullwidth":this.fullwidth,"pkt-input--counter-error":s&&this.counterMaxLength>0&&this.value.length>this.counterMaxLength}),l=this.ariaLabelledby||`${this.id}-input-label`;return e._`
1
+ const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),n=require("./element-with-slot-D7sTqOr3.cjs");require("./icon-Dnv6LtPC.cjs");const r=require("./if-defined-2mkIDgOm.cjs"),i=require("./ref-Emu5PNxk.cjs"),a=require("./input-element-CSfDGslx.cjs"),o=require("./input-wrapper-BBG8EXQ8.cjs");var s=class extends a.t{constructor(...e){super(...e),this.inputRef=i.t(),this.value=``,this.type=`text`,this.size=null,this.autocomplete=null,this.iconNameRight=null,this.prefix=null,this.suffix=null,this.omitSearchIcon=!1,this.counterCurrent=0}attributeChangedCallback(e,t,n){e===`value`&&this.value!==t&&(this.counterCurrent=n?n.length:0),super.attributeChangedCallback(e,t,n)}willUpdate(e){super.willUpdate(e),e.has(`value`)&&(this.counterCurrent=this.value?.length||0),e.has(`id`)&&!this.name&&this.id&&(this.name=this.id)}updated(e){super.updated(e),this.classList.add(`pkt-textinput`),e.has(`value`)&&this.valueChanged(this.value,e.get(`value`))}render(){let a=this.type===`search`&&!this.iconNameRight&&!this.omitSearchIcon,s=this.effectiveCounter(this.counterMaxLength>0),c=t.t({"pkt-input":!0,[`pkt-input--${this.inputSize}`]:!0,"pkt-input--fullwidth":this.fullwidth,"pkt-input--counter-error":s&&this.counterMaxLength>0&&this.value.length>this.counterMaxLength}),l=this.ariaLabelledby||`${this.id}-input-label`;return e._`
2
2
  <pkt-input-wrapper
3
3
  ${n.n(this,[`helptext`])}
4
4
  .strings=${this.strings}
5
5
  label="${this.label}"
6
6
  ?counter=${s}
7
7
  ?hasFieldset=${this.effectiveHasFieldset(!1)}
8
- ?disabled=${this.disabled}
8
+ ?disabled=${this.isDisabled}
9
9
  ?hasError=${this.hasError}
10
10
  ?inline=${this.inline}
11
11
  ?optionalTag=${this.optionalTag}
@@ -44,7 +44,7 @@ const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),
44
44
  ?readonly=${this.readonly}
45
45
  size=${this.size||e.h}
46
46
  .value=${this.value}
47
- ?disabled=${this.disabled}
47
+ ?disabled=${this.isDisabled}
48
48
  aria-invalid=${this.hasError}
49
49
  aria-errormessage=${r.t(this.hasError?`${this.id}-input-error`:void 0)}
50
50
  aria-describedby=${r.t(o.r({id:this.id+`-input`,hasHelptext:!!this.helptext||this.hasSlotContent(`helptext`),hasCounter:s,ariaDescribedby:this.ariaDescribedby}))}
@@ -1,4 +1,4 @@
1
- const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),n=require("./format-B8meU8Tm.cjs"),r=require("./element-with-slot-D7sTqOr3.cjs");require("./icon-Dnv6LtPC.cjs");const i=require("./if-defined-2mkIDgOm.cjs"),a=require("./ref-Emu5PNxk.cjs"),o=require("./input-element-Ctkz5fQk.cjs"),s=require("./input-wrapper-Cf__-4E-.cjs");var c=e=>/^\d{2}:\d{2}$/.test(e)&&parseInt(e.slice(0,2),10)<=23&&parseInt(e.slice(3),10)<=59,l=e=>{let[t,n]=e.split(`:`).map(Number);return t*60+n},u=e=>e?Math.max(1,Math.round(e/60)):1,d=(e,t)=>{let n=e?parseInt(String(e).split(`:`)[0],10):0,r=t?parseInt(String(t).split(`:`)[0],10):23;return Array.from({length:r-n+1},(e,t)=>t+n)},f=e=>{let t=u(e);return Array.from({length:Math.floor(60/t)},(e,n)=>n*t)},p=(e,t,n,r)=>{let i=e===``?n===1?0:23:parseInt(e,10),a=t===``?n===1?0:Math.floor(59/r)*r:parseInt(t,10);return a+=n*r,a>59?(a=0,i=(i+1)%24):a<0&&(a=Math.floor(59/r)*r,i=(i-1+24)%24),{hours:String(i).padStart(2,`0`),minutes:String(a).padStart(2,`0`)}},m=class extends o.t{constructor(...e){super(...e),this.hiddenInputRef=a.t(),this.hoursInputRef=a.t(),this.minutesInputRef=a.t(),this.buttonRef=a.t(),this.value=``,this.hidePicker=!1,this.stepArrows=!1,this._hours=``,this._minutes=``,this._isOpen=!1,this._hoursDigitCount=0,this._hoursFirstDigit=-1,this._minutesDigitCount=0,this._minutesFirstDigit=-1,this._hasFocus=!1,this._outsideClickHandler=e=>{this.contains(e.target)||this._closePopup()},this._handleComponentFocusIn=()=>{this._hasFocus||(this._hasFocus=!0,this.onFocus())},this._handleComponentFocusOut=e=>{this.contains(e.relatedTarget)||(this._hasFocus=!1,this.onBlur())},this._handleHoursKeydown=e=>{let t=e.target;switch(e.key){case`ArrowUp`:{e.preventDefault();let t=this._hours===``?0:parseInt(this._hours,10);this._hours=String((t+1)%24).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowDown`:{e.preventDefault();let t=this._hours===``?0:parseInt(this._hours,10);this._hours=String((t-1+24)%24).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowRight`:e.preventDefault(),this.minutesInputRef.value?.focus();break;case`Backspace`:case`Delete`:this._hoursDigitCount=0,this._hoursFirstDigit=-1;break;case`Tab`:break;case`Enter`:{e.preventDefault();let n=this.internals.form;n?n.requestSubmit():t.blur();break}default:if(/^\d$/.test(e.key)){e.preventDefault();let t=parseInt(e.key,10);if(this._hoursDigitCount===0)this._hoursFirstDigit=t,this._hours=String(t).padStart(2,`0`),this._hoursDigitCount=1,this.onInput(),t>=3&&(this._hoursFirstDigit=-1,this._hoursDigitCount=0,this._syncValueFromDisplay(),this.minutesInputRef.value?.focus());else{let e=this._hoursFirstDigit*10+t;this._hours=e<=23?String(e).padStart(2,`0`):String(t).padStart(2,`0`),this._hoursFirstDigit=-1,this._hoursDigitCount=0,this._syncValueFromDisplay(),this.onInput(),this.minutesInputRef.value?.focus()}}else e.preventDefault()}},this._handleHoursBlur=()=>{this._hours!==``&&(this._hours=String(parseInt(this._hours,10)).padStart(2,`0`)),this._hoursDigitCount=0,this._hoursFirstDigit=-1,this._syncValueFromDisplay()},this._handleMinutesKeydown=e=>{let t=e.target;switch(e.key){case`ArrowUp`:{e.preventDefault();let t=this._minutes===``?0:parseInt(this._minutes,10);this._minutes=String((t+this._minuteStep)%60).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowDown`:{e.preventDefault();let t=this._minutes===``?0:parseInt(this._minutes,10);this._minutes=String((t-this._minuteStep+60)%60).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowLeft`:e.preventDefault(),this.hoursInputRef.value?.focus();break;case`Backspace`:case`Delete`:this._minutesDigitCount=0,this._minutesFirstDigit=-1;break;case`Tab`:break;case`Enter`:{e.preventDefault();let n=this.internals.form;n?n.requestSubmit():t.blur();break}default:if(/^\d$/.test(e.key)){e.preventDefault();let t=parseInt(e.key,10);if(this._minutesDigitCount===0)this._minutesFirstDigit=t,this._minutes=String(t).padStart(2,`0`),this._minutesDigitCount=1,this.onInput(),t>=6&&(this._minutesFirstDigit=-1,this._minutesDigitCount=0,this._syncValueFromDisplay());else{let e=this._minutesFirstDigit*10+t;this._minutes=e<=59?String(e).padStart(2,`0`):String(t).padStart(2,`0`),this._minutesFirstDigit=-1,this._minutesDigitCount=0,this._syncValueFromDisplay(),this.onInput()}}else e.preventDefault()}},this._handleMinutesBlur=()=>{this._minutes!==``&&(this._minutes=String(parseInt(this._minutes,10)).padStart(2,`0`)),this._minutesDigitCount=0,this._minutesFirstDigit=-1,this._syncValueFromDisplay()},this._handlePopupKeydown=e=>{let t=document.activeElement,n=t.closest(`.pkt-timepicker-popup__col`);if(!n)return;let r=Array.from(n.querySelectorAll(`.pkt-timepicker-popup__option`)),i=r.indexOf(t),a=t.dataset.type??``;switch(e.key){case`ArrowDown`:e.preventDefault(),this._focusOptionAndSync(r[Math.min(i+1,r.length-1)],a);break;case`ArrowUp`:e.preventDefault(),this._focusOptionAndSync(r[Math.max(i-1,0)],a);break;case`Home`:e.preventDefault(),this._focusOptionAndSync(r[0],a);break;case`End`:e.preventDefault(),this._focusOptionAndSync(r[r.length-1],a);break;case`ArrowRight`:e.preventDefault(),a===`hour`&&(this._focusOptionAndSync(t,a),this.updateComplete.then(()=>{this._scrollToSelected(),this._focusSelectedOrFirst(`minute`)}));break;case`ArrowLeft`:e.preventDefault(),a===`minute`&&(this._focusOptionAndSync(t,a),this.updateComplete.then(()=>{this._scrollToSelected(),this._focusSelectedOrFirst(`hour`)}));break;case`Enter`:case` `:e.preventDefault(),t.click();break;case`Escape`:e.preventDefault(),this._closePopup(),this.buttonRef.value?.focus()}}}get inputRef(){return this.hiddenInputRef}manageValidity(e){let t=this.hoursInputRef.value;if(!t)return;let r=this.pktStrings.get(`validation`);if(this.required&&!this.value){this.internals.setValidity({valueMissing:!0},r.valueMissing,t),this._setAriaInvalid(!0);return}if(!this.value){this.internals.setValidity({}),this._setAriaInvalid(!1);return}let i=l(this.value),a=u(this.step);if(this.min&&i<l(String(this.min))){this.internals.setValidity({rangeUnderflow:!0},n.t(r.rangeUnderflowMin,{min:String(this.min)}),t),this._setAriaInvalid(!0);return}if(this.max&&i>l(String(this.max))){this.internals.setValidity({rangeOverflow:!0},n.t(r.rangeOverflowMax,{max:String(this.max)}),t),this._setAriaInvalid(!0);return}if(this.step&&i%a!==0){let e=a===60?r.timeStepMismatchHour:a===30?r.timeStepMismatchHalfHour:n.t(r.timeStepMismatch,{step:`${a}, ${a*2}, ${a*3}`});this.internals.setValidity({stepMismatch:!0},e,t),this._setAriaInvalid(!0);return}this.internals.setValidity({}),this._setAriaInvalid(!1)}_describedBy(){return s.r({id:`${this.id}-hours`,hasHelptext:!!this.helptext||this.hasSlotContent(`helptext`),ariaDescribedby:this.ariaDescribedby})}_setAriaInvalid(e){if(!this.touched&&e)return;let t=this.hoursInputRef.value,n=this.minutesInputRef.value;if(e)t?.setAttribute(`aria-invalid`,`true`),n?.setAttribute(`aria-invalid`,`true`);else{if(this.hasError)return;t?.removeAttribute(`aria-invalid`),n?.removeAttribute(`aria-invalid`)}}connectedCallback(){super.connectedCallback(),this.addEventListener(`focusin`,this._handleComponentFocusIn),this.addEventListener(`focusout`,this._handleComponentFocusOut),document.addEventListener(`click`,this._outsideClickHandler)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(`focusin`,this._handleComponentFocusIn),this.removeEventListener(`focusout`,this._handleComponentFocusOut),document.removeEventListener(`click`,this._outsideClickHandler)}willUpdate(e){super.willUpdate(e),e.has(`value`)&&this._syncDisplayFromValue()}updated(e){super.updated(e),this.classList.add(`pkt-timepicker`),this.classList.toggle(`pkt-timepicker--stepper`,this.stepArrows),this.classList.toggle(`pkt-timepicker--fullwidth`,this.fullwidth),this.classList.toggle(`pkt-timepicker--medium`,this.inputSize===`medium`),this.classList.toggle(`pkt-timepicker--small`,this.inputSize===`small`),this.classList.toggle(`pkt-timepicker--xsmall`,this.inputSize===`xsmall`),e.has(`step`)&&this.step!==null&&!this._isValidStep(this.step)&&console.warn(`pkt-timepicker: step="${this.step}" er ikke en gyldig verdi. Step må være et multiplum av 60 (hele minutter) eller nøyaktig 3600 (hel time).`)}formResetCallback(){super.formResetCallback(),this._hours=``,this._minutes=``,this._isOpen=!1}_isValidStep(e){return e===3600||e<3600&&3600%e==0&&e%60==0}_syncDisplayFromValue(){let e=c(this.value)?this.value.split(`:`):null;e?(this._hours=e[0],this._minutes=e[1]):(this._hours=``,this._minutes=``)}_syncValueFromDisplay(){if(this._hours!==``&&this._minutes!==``){let e=`${this._hours}:${this._minutes}`;e!==this.value&&(this.value=e,this.onChange(e))}else this.value!==``&&(this.value=``,this.onChange(``))}get _minuteStep(){return u(this.step)}get _hourOptions(){return d(this.min,this.max)}get _minuteOptions(){return f(this.step)}_openPopup(){this._isOpen=!0,this.updateComplete.then(()=>{this._scrollToSelected(),this._focusSelectedOrFirst(`hour`)})}_closePopup(){this._isOpen=!1,this._syncValueFromDisplay()}_togglePopup(){this._isOpen?this._closePopup():this._openPopup()}_scrollToSelected(){let e=this.querySelector(`.pkt-timepicker-popup`);e&&e.querySelectorAll(`.pkt-timepicker-popup__col`).forEach(e=>{let t=e.querySelector(`.pkt-timepicker-popup__option--selected`);t&&t.scrollIntoView({block:`center`})})}_focusSelectedOrFirst(e){let t=this.querySelector(`.pkt-timepicker-popup`);if(!t)return;let n=t.querySelectorAll(`.pkt-timepicker-popup__col`),r=e===`hour`?n[0]:n[1];if(!r)return;let i=r.querySelector(`.pkt-timepicker-popup__option--selected`),a=r.querySelector(`.pkt-timepicker-popup__option`);(i||a)?.focus()}_handleOptionClick(e,t){let n=String(e).padStart(2,`0`);t===`hour`?(this._hours=n,this.updateComplete.then(()=>this._focusSelectedOrFirst(`minute`))):(this._minutes=n,this._closePopup(),this.buttonRef.value?.focus())}_focusOptionAndSync(e,t){if(!e)return;let n=parseInt(e.dataset.value??`0`,10);t===`hour`?this._hours=String(n).padStart(2,`0`):this._minutes=String(n).padStart(2,`0`),e.focus()}_stepTime(e){let t=p(this._hours,this._minutes,e,this._minuteStep);this._hours=t.hours,this._minutes=t.minutes,this._syncValueFromDisplay()}_renderOption(n,r){let i=String(n).padStart(2,`0`),a=n===(r===`hour`?this._hours===``?NaN:parseInt(this._hours,10):this._minutes===``?NaN:parseInt(this._minutes,10));return e._`
1
+ const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),n=require("./format-B8meU8Tm.cjs"),r=require("./element-with-slot-D7sTqOr3.cjs");require("./icon-Dnv6LtPC.cjs");const i=require("./if-defined-2mkIDgOm.cjs"),a=require("./ref-Emu5PNxk.cjs"),o=require("./input-element-CSfDGslx.cjs"),s=require("./input-wrapper-BBG8EXQ8.cjs");var c=e=>/^\d{2}:\d{2}$/.test(e)&&parseInt(e.slice(0,2),10)<=23&&parseInt(e.slice(3),10)<=59,l=e=>{let[t,n]=e.split(`:`).map(Number);return t*60+n},u=e=>e?Math.max(1,Math.round(e/60)):1,d=(e,t)=>{let n=e?parseInt(String(e).split(`:`)[0],10):0,r=t?parseInt(String(t).split(`:`)[0],10):23;return Array.from({length:r-n+1},(e,t)=>t+n)},f=e=>{let t=u(e);return Array.from({length:Math.floor(60/t)},(e,n)=>n*t)},p=(e,t,n,r)=>{let i=e===``?n===1?0:23:parseInt(e,10),a=t===``?n===1?0:Math.floor(59/r)*r:parseInt(t,10);return a+=n*r,a>59?(a=0,i=(i+1)%24):a<0&&(a=Math.floor(59/r)*r,i=(i-1+24)%24),{hours:String(i).padStart(2,`0`),minutes:String(a).padStart(2,`0`)}},m=class extends o.t{constructor(...e){super(...e),this.hiddenInputRef=a.t(),this.hoursInputRef=a.t(),this.minutesInputRef=a.t(),this.buttonRef=a.t(),this.value=``,this.hidePicker=!1,this.stepArrows=!1,this._hours=``,this._minutes=``,this._isOpen=!1,this._hoursDigitCount=0,this._hoursFirstDigit=-1,this._minutesDigitCount=0,this._minutesFirstDigit=-1,this._hasFocus=!1,this._outsideClickHandler=e=>{this.contains(e.target)||this._closePopup()},this._handleComponentFocusIn=()=>{this._hasFocus||(this._hasFocus=!0,this.onFocus())},this._handleComponentFocusOut=e=>{this.contains(e.relatedTarget)||(this._hasFocus=!1,this.onBlur())},this._handleHoursKeydown=e=>{let t=e.target;switch(e.key){case`ArrowUp`:{e.preventDefault();let t=this._hours===``?0:parseInt(this._hours,10);this._hours=String((t+1)%24).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowDown`:{e.preventDefault();let t=this._hours===``?0:parseInt(this._hours,10);this._hours=String((t-1+24)%24).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowRight`:e.preventDefault(),this.minutesInputRef.value?.focus();break;case`Backspace`:case`Delete`:this._hoursDigitCount=0,this._hoursFirstDigit=-1;break;case`Tab`:break;case`Enter`:{e.preventDefault();let n=this.internals.form;n?n.requestSubmit():t.blur();break}default:if(/^\d$/.test(e.key)){e.preventDefault();let t=parseInt(e.key,10);if(this._hoursDigitCount===0)this._hoursFirstDigit=t,this._hours=String(t).padStart(2,`0`),this._hoursDigitCount=1,this.onInput(),t>=3&&(this._hoursFirstDigit=-1,this._hoursDigitCount=0,this._syncValueFromDisplay(),this.minutesInputRef.value?.focus());else{let e=this._hoursFirstDigit*10+t;this._hours=e<=23?String(e).padStart(2,`0`):String(t).padStart(2,`0`),this._hoursFirstDigit=-1,this._hoursDigitCount=0,this._syncValueFromDisplay(),this.onInput(),this.minutesInputRef.value?.focus()}}else e.preventDefault()}},this._handleHoursBlur=()=>{this._hours!==``&&(this._hours=String(parseInt(this._hours,10)).padStart(2,`0`)),this._hoursDigitCount=0,this._hoursFirstDigit=-1,this._syncValueFromDisplay()},this._handleMinutesKeydown=e=>{let t=e.target;switch(e.key){case`ArrowUp`:{e.preventDefault();let t=this._minutes===``?0:parseInt(this._minutes,10);this._minutes=String((t+this._minuteStep)%60).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowDown`:{e.preventDefault();let t=this._minutes===``?0:parseInt(this._minutes,10);this._minutes=String((t-this._minuteStep+60)%60).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowLeft`:e.preventDefault(),this.hoursInputRef.value?.focus();break;case`Backspace`:case`Delete`:this._minutesDigitCount=0,this._minutesFirstDigit=-1;break;case`Tab`:break;case`Enter`:{e.preventDefault();let n=this.internals.form;n?n.requestSubmit():t.blur();break}default:if(/^\d$/.test(e.key)){e.preventDefault();let t=parseInt(e.key,10);if(this._minutesDigitCount===0)this._minutesFirstDigit=t,this._minutes=String(t).padStart(2,`0`),this._minutesDigitCount=1,this.onInput(),t>=6&&(this._minutesFirstDigit=-1,this._minutesDigitCount=0,this._syncValueFromDisplay());else{let e=this._minutesFirstDigit*10+t;this._minutes=e<=59?String(e).padStart(2,`0`):String(t).padStart(2,`0`),this._minutesFirstDigit=-1,this._minutesDigitCount=0,this._syncValueFromDisplay(),this.onInput()}}else e.preventDefault()}},this._handleMinutesBlur=()=>{this._minutes!==``&&(this._minutes=String(parseInt(this._minutes,10)).padStart(2,`0`)),this._minutesDigitCount=0,this._minutesFirstDigit=-1,this._syncValueFromDisplay()},this._handlePopupKeydown=e=>{let t=document.activeElement,n=t.closest(`.pkt-timepicker-popup__col`);if(!n)return;let r=Array.from(n.querySelectorAll(`.pkt-timepicker-popup__option`)),i=r.indexOf(t),a=t.dataset.type??``;switch(e.key){case`ArrowDown`:e.preventDefault(),this._focusOptionAndSync(r[Math.min(i+1,r.length-1)],a);break;case`ArrowUp`:e.preventDefault(),this._focusOptionAndSync(r[Math.max(i-1,0)],a);break;case`Home`:e.preventDefault(),this._focusOptionAndSync(r[0],a);break;case`End`:e.preventDefault(),this._focusOptionAndSync(r[r.length-1],a);break;case`ArrowRight`:e.preventDefault(),a===`hour`&&(this._focusOptionAndSync(t,a),this.updateComplete.then(()=>{this._scrollToSelected(),this._focusSelectedOrFirst(`minute`)}));break;case`ArrowLeft`:e.preventDefault(),a===`minute`&&(this._focusOptionAndSync(t,a),this.updateComplete.then(()=>{this._scrollToSelected(),this._focusSelectedOrFirst(`hour`)}));break;case`Enter`:case` `:e.preventDefault(),t.click();break;case`Escape`:e.preventDefault(),this._closePopup(),this.buttonRef.value?.focus()}}}get inputRef(){return this.hiddenInputRef}manageValidity(e){let t=this.hoursInputRef.value;if(!t)return;let r=this.pktStrings.get(`validation`);if(this.required&&!this.value){this.internals.setValidity({valueMissing:!0},r.valueMissing,t),this._setAriaInvalid(!0);return}if(!this.value){this.internals.setValidity({}),this._setAriaInvalid(!1);return}let i=l(this.value),a=u(this.step);if(this.min&&i<l(String(this.min))){this.internals.setValidity({rangeUnderflow:!0},n.t(r.rangeUnderflowMin,{min:String(this.min)}),t),this._setAriaInvalid(!0);return}if(this.max&&i>l(String(this.max))){this.internals.setValidity({rangeOverflow:!0},n.t(r.rangeOverflowMax,{max:String(this.max)}),t),this._setAriaInvalid(!0);return}if(this.step&&i%a!==0){let e=a===60?r.timeStepMismatchHour:a===30?r.timeStepMismatchHalfHour:n.t(r.timeStepMismatch,{step:`${a}, ${a*2}, ${a*3}`});this.internals.setValidity({stepMismatch:!0},e,t),this._setAriaInvalid(!0);return}this.internals.setValidity({}),this._setAriaInvalid(!1)}_describedBy(){return s.r({id:`${this.id}-hours`,hasHelptext:!!this.helptext||this.hasSlotContent(`helptext`),ariaDescribedby:this.ariaDescribedby})}_setAriaInvalid(e){if(!this.touched&&e)return;let t=this.hoursInputRef.value,n=this.minutesInputRef.value;if(e)t?.setAttribute(`aria-invalid`,`true`),n?.setAttribute(`aria-invalid`,`true`);else{if(this.hasError)return;t?.removeAttribute(`aria-invalid`),n?.removeAttribute(`aria-invalid`)}}connectedCallback(){super.connectedCallback(),this.addEventListener(`focusin`,this._handleComponentFocusIn),this.addEventListener(`focusout`,this._handleComponentFocusOut),document.addEventListener(`click`,this._outsideClickHandler)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(`focusin`,this._handleComponentFocusIn),this.removeEventListener(`focusout`,this._handleComponentFocusOut),document.removeEventListener(`click`,this._outsideClickHandler)}willUpdate(e){super.willUpdate(e),e.has(`value`)&&this._syncDisplayFromValue()}updated(e){super.updated(e),this.classList.add(`pkt-timepicker`),this.classList.toggle(`pkt-timepicker--stepper`,this.stepArrows),this.classList.toggle(`pkt-timepicker--fullwidth`,this.fullwidth),this.classList.toggle(`pkt-timepicker--medium`,this.inputSize===`medium`),this.classList.toggle(`pkt-timepicker--small`,this.inputSize===`small`),this.classList.toggle(`pkt-timepicker--xsmall`,this.inputSize===`xsmall`),e.has(`step`)&&this.step!==null&&!this._isValidStep(this.step)&&console.warn(`pkt-timepicker: step="${this.step}" er ikke en gyldig verdi. Step må være et multiplum av 60 (hele minutter) eller nøyaktig 3600 (hel time).`)}formResetCallback(){super.formResetCallback(),this._hours=``,this._minutes=``,this._isOpen=!1}_isValidStep(e){return e===3600||e<3600&&3600%e==0&&e%60==0}_syncDisplayFromValue(){let e=c(this.value)?this.value.split(`:`):null;e?(this._hours=e[0],this._minutes=e[1]):(this._hours=``,this._minutes=``)}_syncValueFromDisplay(){if(this._hours!==``&&this._minutes!==``){let e=`${this._hours}:${this._minutes}`;e!==this.value&&(this.value=e,this.onChange(e))}else this.value!==``&&(this.value=``,this.onChange(``))}get _minuteStep(){return u(this.step)}get _hourOptions(){return d(this.min,this.max)}get _minuteOptions(){return f(this.step)}_openPopup(){this._isOpen=!0,this.updateComplete.then(()=>{this._scrollToSelected(),this._focusSelectedOrFirst(`hour`)})}_closePopup(){this._isOpen=!1,this._syncValueFromDisplay()}_togglePopup(){this._isOpen?this._closePopup():this._openPopup()}_scrollToSelected(){let e=this.querySelector(`.pkt-timepicker-popup`);e&&e.querySelectorAll(`.pkt-timepicker-popup__col`).forEach(e=>{let t=e.querySelector(`.pkt-timepicker-popup__option--selected`);t&&t.scrollIntoView({block:`center`})})}_focusSelectedOrFirst(e){let t=this.querySelector(`.pkt-timepicker-popup`);if(!t)return;let n=t.querySelectorAll(`.pkt-timepicker-popup__col`),r=e===`hour`?n[0]:n[1];if(!r)return;let i=r.querySelector(`.pkt-timepicker-popup__option--selected`),a=r.querySelector(`.pkt-timepicker-popup__option`);(i||a)?.focus()}_handleOptionClick(e,t){let n=String(e).padStart(2,`0`);t===`hour`?(this._hours=n,this.updateComplete.then(()=>this._focusSelectedOrFirst(`minute`))):(this._minutes=n,this._closePopup(),this.buttonRef.value?.focus())}_focusOptionAndSync(e,t){if(!e)return;let n=parseInt(e.dataset.value??`0`,10);t===`hour`?this._hours=String(n).padStart(2,`0`):this._minutes=String(n).padStart(2,`0`),e.focus()}_stepTime(e){let t=p(this._hours,this._minutes,e,this._minuteStep);this._hours=t.hours,this._minutes=t.minutes,this._syncValueFromDisplay()}_renderOption(n,r){let i=String(n).padStart(2,`0`),a=n===(r===`hour`?this._hours===``?NaN:parseInt(this._hours,10):this._minutes===``?NaN:parseInt(this._minutes,10));return e._`
2
2
  <button
3
3
  class=${t.t({"pkt-btn":!0,"pkt-btn--tertiary":!0,"pkt-btn--small":!0,"pkt-btn--label-only":!0,"pkt-timepicker-popup__option":!0,"pkt-timepicker-popup__option--selected":a})}
4
4
  type="button"
@@ -48,7 +48,7 @@ const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),
48
48
  class="pkt-input-icon pkt-btn pkt-btn--icon-only pkt-btn--tertiary pkt-btn--${this.inputSize} pkt-timepicker__button pkt-timepicker__button--prev"
49
49
  type="button"
50
50
  aria-label=${this.pktStrings.get(`timepicker`).prevTime}
51
- ?disabled=${this.disabled}
51
+ ?disabled=${this.isDisabled}
52
52
  @click=${()=>this._stepTime(-1)}
53
53
  >
54
54
  <pkt-icon name="chevron-thin-left"></pkt-icon>
@@ -79,7 +79,7 @@ const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),
79
79
  aria-valuenow=${this._hours===``?e.h:this._hours}
80
80
  aria-valuetext=${this._hours===``?e.h:`${this._hours} ${t.toLowerCase()}`}
81
81
  autocomplete="off"
82
- ?disabled=${this.disabled}
82
+ ?disabled=${this.isDisabled}
83
83
  @keydown=${this._handleHoursKeydown}
84
84
  @blur=${this._handleHoursBlur}
85
85
  @focus=${e=>{e.target.select(),e.stopImmediatePropagation()}}
@@ -107,7 +107,7 @@ const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),
107
107
  aria-valuenow=${this._minutes===``?e.h:this._minutes}
108
108
  aria-valuetext=${this._minutes===``?e.h:`${this._minutes} ${n.toLowerCase()}`}
109
109
  autocomplete="off"
110
- ?disabled=${this.disabled}
110
+ ?disabled=${this.isDisabled}
111
111
  @keydown=${this._handleMinutesKeydown}
112
112
  @blur=${this._handleMinutesBlur}
113
113
  @focus=${e=>{e.target.select(),e.stopImmediatePropagation()}}
@@ -126,7 +126,7 @@ const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),
126
126
  aria-haspopup="listbox"
127
127
  aria-expanded=${this._isOpen?`true`:`false`}
128
128
  aria-controls=${this.id+`-popup`}
129
- ?disabled=${this.disabled}
129
+ ?disabled=${this.isDisabled}
130
130
  @click=${this._togglePopup}
131
131
  >
132
132
  <pkt-icon name="clock"></pkt-icon>
@@ -140,7 +140,7 @@ const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),
140
140
  class="pkt-input-icon pkt-btn pkt-btn--icon-only pkt-btn--tertiary pkt-btn--${this.inputSize} pkt-timepicker__button pkt-timepicker__button--next"
141
141
  type="button"
142
142
  aria-label=${this.pktStrings.get(`timepicker`).nextTime}
143
- ?disabled=${this.disabled}
143
+ ?disabled=${this.isDisabled}
144
144
  @click=${()=>this._stepTime(1)}
145
145
  >
146
146
  <pkt-icon name="chevron-thin-right"></pkt-icon>
@@ -160,7 +160,7 @@ const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),
160
160
  max=${i.t(this.max??void 0)}
161
161
  step=${i.t(this.step??void 0)}
162
162
  ?required=${this.required}
163
- ?disabled=${this.disabled}
163
+ ?disabled=${this.isDisabled}
164
164
  tabindex="-1"
165
165
  />
166
166
  </div>
@@ -169,7 +169,7 @@ const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),
169
169
  ${r.n(this,[`helptext`])}
170
170
  .strings=${this.strings}
171
171
  label="${this.label}"
172
- ?disabled=${this.disabled}
172
+ ?disabled=${this.isDisabled}
173
173
  ?fullwidth=${this.fullwidth}
174
174
  ?hasError=${this.hasError}
175
175
  ?hasFieldset=${this.effectiveHasFieldset(!1)}
@@ -5,8 +5,8 @@ import { n as c } from "./element-with-slot-DQv0cbbD.js";
5
5
  import "./icon-JigbxxF7.js";
6
6
  import { t as l } from "./if-defined-Bebu3LXY.js";
7
7
  import { n as u, t as d } from "./ref-CCSGk4MP.js";
8
- import { t as f } from "./input-element-5hsxasU3.js";
9
- import { r as p } from "./input-wrapper-DACDx6Ie.js";
8
+ import { t as f } from "./input-element-lLzfwdim.js";
9
+ import { r as p } from "./input-wrapper-Bz9GwYrn.js";
10
10
  //#region ../../shared-utils/timepicker/time-utils.ts
11
11
  var m = (e) => /^\d{2}:\d{2}$/.test(e) && parseInt(e.slice(0, 2), 10) <= 23 && parseInt(e.slice(3), 10) <= 59, h = (e) => {
12
12
  let [t, n] = e.split(":").map(Number);
@@ -343,7 +343,7 @@ var m = (e) => /^\d{2}:\d{2}$/.test(e) && parseInt(e.slice(0, 2), 10) <= 23 && p
343
343
  class="pkt-input-icon pkt-btn pkt-btn--icon-only pkt-btn--tertiary pkt-btn--${this.inputSize} pkt-timepicker__button pkt-timepicker__button--prev"
344
344
  type="button"
345
345
  aria-label=${this.pktStrings.get("timepicker").prevTime}
346
- ?disabled=${this.disabled}
346
+ ?disabled=${this.isDisabled}
347
347
  @click=${() => this._stepTime(-1)}
348
348
  >
349
349
  <pkt-icon name="chevron-thin-left"></pkt-icon>
@@ -374,7 +374,7 @@ var m = (e) => /^\d{2}:\d{2}$/.test(e) && parseInt(e.slice(0, 2), 10) <= 23 && p
374
374
  aria-valuenow=${this._hours === "" ? n : this._hours}
375
375
  aria-valuetext=${this._hours === "" ? n : `${this._hours} ${t.toLowerCase()}`}
376
376
  autocomplete="off"
377
- ?disabled=${this.disabled}
377
+ ?disabled=${this.isDisabled}
378
378
  @keydown=${this._handleHoursKeydown}
379
379
  @blur=${this._handleHoursBlur}
380
380
  @focus=${(e) => {
@@ -404,7 +404,7 @@ var m = (e) => /^\d{2}:\d{2}$/.test(e) && parseInt(e.slice(0, 2), 10) <= 23 && p
404
404
  aria-valuenow=${this._minutes === "" ? n : this._minutes}
405
405
  aria-valuetext=${this._minutes === "" ? n : `${this._minutes} ${r.toLowerCase()}`}
406
406
  autocomplete="off"
407
- ?disabled=${this.disabled}
407
+ ?disabled=${this.isDisabled}
408
408
  @keydown=${this._handleMinutesKeydown}
409
409
  @blur=${this._handleMinutesBlur}
410
410
  @focus=${(e) => {
@@ -425,7 +425,7 @@ var m = (e) => /^\d{2}:\d{2}$/.test(e) && parseInt(e.slice(0, 2), 10) <= 23 && p
425
425
  aria-haspopup="listbox"
426
426
  aria-expanded=${this._isOpen ? "true" : "false"}
427
427
  aria-controls=${this.id + "-popup"}
428
- ?disabled=${this.disabled}
428
+ ?disabled=${this.isDisabled}
429
429
  @click=${this._togglePopup}
430
430
  >
431
431
  <pkt-icon name="clock"></pkt-icon>
@@ -439,7 +439,7 @@ var m = (e) => /^\d{2}:\d{2}$/.test(e) && parseInt(e.slice(0, 2), 10) <= 23 && p
439
439
  class="pkt-input-icon pkt-btn pkt-btn--icon-only pkt-btn--tertiary pkt-btn--${this.inputSize} pkt-timepicker__button pkt-timepicker__button--next"
440
440
  type="button"
441
441
  aria-label=${this.pktStrings.get("timepicker").nextTime}
442
- ?disabled=${this.disabled}
442
+ ?disabled=${this.isDisabled}
443
443
  @click=${() => this._stepTime(1)}
444
444
  >
445
445
  <pkt-icon name="chevron-thin-right"></pkt-icon>
@@ -459,7 +459,7 @@ var m = (e) => /^\d{2}:\d{2}$/.test(e) && parseInt(e.slice(0, 2), 10) <= 23 && p
459
459
  max=${l(this.max ?? void 0)}
460
460
  step=${l(this.step ?? void 0)}
461
461
  ?required=${this.required}
462
- ?disabled=${this.disabled}
462
+ ?disabled=${this.isDisabled}
463
463
  tabindex="-1"
464
464
  />
465
465
  </div>
@@ -471,7 +471,7 @@ var m = (e) => /^\d{2}:\d{2}$/.test(e) && parseInt(e.slice(0, 2), 10) <= 23 && p
471
471
  ${c(this, ["helptext"])}
472
472
  .strings=${this.strings}
473
473
  label="${this.label}"
474
- ?disabled=${this.disabled}
474
+ ?disabled=${this.isDisabled}
475
475
  ?fullwidth=${this.fullwidth}
476
476
  ?hasError=${this.hasError}
477
477
  ?hasFieldset=${this.effectiveHasFieldset(!1)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oslokommune/punkt-elements",
3
- "version": "19.5.1",
3
+ "version": "19.5.2",
4
4
  "description": "Komponentbiblioteket til Punkt, designsystem for Oslo kommune",
5
5
  "homepage": "https://punkt.oslo.kommune.no",
6
6
  "author": "Team Designsystem, Oslo kommune",
@@ -84,5 +84,5 @@
84
84
  "engines": {
85
85
  "node": "^22.19.0 || ^24.0.0 || ^26.0.0"
86
86
  },
87
- "gitHead": "ec50e19e909a893c46c4cea3a3b0de38e23d8666"
87
+ "gitHead": "519d9c748c2bef3bdb12d5979e115c05a2509f44"
88
88
  }
@@ -50,9 +50,6 @@ export class PktCheckbox extends PktInputElement<Props> {
50
50
  }
51
51
 
52
52
  attributeChangedCallback(name: string, _old: string | null, value: string | null): void {
53
- if (name === 'defaultChecked' && !this.checked) {
54
- this.checked = this.defaultChecked
55
- }
56
53
  if (name === 'checked') {
57
54
  this.checked = this.checked === '' || this.checked === 'true' || this.checked === true
58
55
  if (this.inputRef.value) this.inputRef.value.checked = this.checked as boolean
@@ -96,7 +93,7 @@ export class PktCheckbox extends PktInputElement<Props> {
96
93
  const inputTileClasses = classMap({
97
94
  'pkt-input-check__input': true,
98
95
  'pkt-input-check__input--tile': this.hasTile,
99
- 'pkt-input-check__input--tile-disabled': this.disabled && this.hasTile,
96
+ 'pkt-input-check__input--tile-disabled': this.isDisabled && this.hasTile,
100
97
  })
101
98
 
102
99
  const inputCheckBoxClasses = classMap({
@@ -106,7 +103,7 @@ export class PktCheckbox extends PktInputElement<Props> {
106
103
 
107
104
  const labelClasses = classMap({
108
105
  'pkt-input-check__input-label': true,
109
- 'pkt-input-check__input-label--disabled': this.disabled,
106
+ 'pkt-input-check__input-label--disabled': this.isDisabled,
110
107
  'pkt-input-check__input-label--left': this.labelPosition === 'left',
111
108
  'pkt-input-check__input-label--right': this.labelPosition === 'right',
112
109
  'pkt-sr-only': this.hideLabel,
@@ -166,7 +163,7 @@ export class PktCheckbox extends PktInputElement<Props> {
166
163
  id=${this.id + '-internal'}
167
164
  class=${inputCheckBoxClasses}
168
165
  type="checkbox"
169
- ?disabled=${this.disabled}
166
+ ?disabled=${this.isDisabled}
170
167
  name=${this.name + '-internal'}
171
168
  ${ref(this.inputRef)}
172
169
  @change=${this.handleChange}
@@ -192,7 +189,7 @@ export class PktCheckbox extends PktInputElement<Props> {
192
189
 
193
190
  private handleClick(e: Event) {
194
191
  // Prevent click on disabled checkbox
195
- if (this.disabled) {
192
+ if (this.isDisabled) {
196
193
  e.preventDefault()
197
194
  e.stopImmediatePropagation()
198
195
  return false
@@ -201,7 +198,7 @@ export class PktCheckbox extends PktInputElement<Props> {
201
198
 
202
199
  private handleChange(e: Event) {
203
200
  // Don't process change if disabled
204
- if (this.disabled) {
201
+ if (this.isDisabled) {
205
202
  e.preventDefault()
206
203
  e.stopImmediatePropagation()
207
204
  return false
@@ -212,7 +209,7 @@ export class PktCheckbox extends PktInputElement<Props> {
212
209
 
213
210
  private toggleChecked(e: Event) {
214
211
  // Don't toggle if disabled
215
- if (this.disabled) {
212
+ if (this.isDisabled) {
216
213
  e.preventDefault()
217
214
  e.stopImmediatePropagation()
218
215
  return
@@ -17,7 +17,7 @@ export class ComboboxHandlers extends ComboboxValue {
17
17
  e.stopPropagation()
18
18
  e.stopImmediatePropagation()
19
19
 
20
- if (this.disabled) return
20
+ if (this.isDisabled) return
21
21
 
22
22
  this.touched = true
23
23
  const input = e.target as HTMLInputElement
@@ -49,7 +49,7 @@ export class ComboboxHandlers extends ComboboxValue {
49
49
  }
50
50
 
51
51
  protected handleFocus(): void {
52
- if (this.disabled) return
52
+ if (this.isDisabled) return
53
53
 
54
54
  this._skipInputTab = false
55
55
 
@@ -88,7 +88,7 @@ export class ComboboxHandlers extends ComboboxValue {
88
88
  }
89
89
 
90
90
  protected handleFocusOut(e: FocusEvent): void {
91
- if (this.disabled || !this._isOptionsOpen) return
91
+ if (this.isDisabled || !this._isOptionsOpen) return
92
92
 
93
93
  const related = e.relatedTarget as Element | null
94
94
  const isFocusInsideCombobox =
@@ -176,7 +176,7 @@ export class ComboboxHandlers extends ComboboxValue {
176
176
  }
177
177
 
178
178
  protected handleInputClick(e: MouseEvent): void {
179
- if (this.disabled) {
179
+ if (this.isDisabled) {
180
180
  e.preventDefault()
181
181
  e.stopImmediatePropagation()
182
182
  return
@@ -196,7 +196,7 @@ export class ComboboxHandlers extends ComboboxValue {
196
196
  }
197
197
 
198
198
  protected handlePlaceholderClick(e: MouseEvent): void {
199
- if (this.disabled) return
199
+ if (this.isDisabled) return
200
200
  e.stopPropagation()
201
201
  if (this._hasTextInput && this.inputRef.value) {
202
202
  this.inputRef.value.focus()
@@ -209,7 +209,7 @@ export class ComboboxHandlers extends ComboboxValue {
209
209
  }
210
210
 
211
211
  protected handleSelectOnlyKeydown(e: KeyboardEvent): void {
212
- if (this.disabled) return
212
+ if (this.isDisabled) return
213
213
 
214
214
  switch (e.key) {
215
215
  case 'Enter':
@@ -15,7 +15,7 @@ import type { TComboboxMessageKey } from 'shared-utils/combobox'
15
15
  */
16
16
  export class ComboboxValue extends ComboboxBase {
17
17
  public toggleValue(value: string | null): void {
18
- if (this.disabled) return
18
+ if (this.isDisabled) return
19
19
 
20
20
  this.touched = true
21
21
  this._userInfoMessage = ''
@@ -351,7 +351,7 @@ export class PktCombobox extends ComboboxHandlers implements IPktCombobox {
351
351
  .counterMaxLength=${this.maxlength ?? 0}
352
352
  ?hasError=${this.hasError}
353
353
  ?inline=${this.inline}
354
- ?disabled=${this.disabled}
354
+ ?disabled=${this.isDisabled}
355
355
  .errorMessage=${this.errorMessage}
356
356
  ?optionalTag=${this.optionalTag}
357
357
  .optionalText=${this.optionalText}
@@ -372,7 +372,7 @@ export class PktCombobox extends ComboboxHandlers implements IPktCombobox {
372
372
  'pkt-combobox__input--fullwidth': this.fullwidth,
373
373
  'pkt-combobox__input--open': this._isOptionsOpen,
374
374
  'pkt-combobox__input--error': this.hasError,
375
- 'pkt-combobox__input--disabled': this.disabled,
375
+ 'pkt-combobox__input--disabled': this.isDisabled,
376
376
  })}
377
377
  id=${ifDefined(!this._hasTextInput ? `${this.id}-combobox` : undefined)}
378
378
  role=${ifDefined(!this._hasTextInput ? 'combobox' : undefined)}
@@ -394,7 +394,7 @@ export class PktCombobox extends ComboboxHandlers implements IPktCombobox {
394
394
  : undefined,
395
395
  )}
396
396
  aria-description=${ifDefined(this._selectionDescription || undefined)}
397
- tabindex=${!this._hasTextInput ? (this.disabled ? '-1' : '0') : '-1'}
397
+ tabindex=${!this._hasTextInput ? (this.isDisabled ? '-1' : '0') : '-1'}
398
398
  @click=${this.handleInputClick}
399
399
  @keydown=${!this._hasTextInput ? this.handleSelectOnlyKeydown : nothing}
400
400
  @blur=${this.restoreInputTab}
@@ -429,7 +429,7 @@ export class PktCombobox extends ComboboxHandlers implements IPktCombobox {
429
429
  .isOpen=${this._isOptionsOpen}
430
430
  .searchPlaceholder=${this.searchPlaceholder}
431
431
  .label="Liste: ${this.label || ''}"
432
- ?disabled=${this.disabled}
432
+ ?disabled=${this.isDisabled}
433
433
  ?include-search=${this.includeSearch}
434
434
  ?is-multi-select=${this.multiple}
435
435
  ?allow-user-input=${this.allowUserInput && !this._maxIsReached}
@@ -551,7 +551,7 @@ export class PktCombobox extends ComboboxHandlers implements IPktCombobox {
551
551
  >
552
552
  <pkt-tag
553
553
  skin=${tagSkinColor || 'blue-dark'}
554
- ?closeTag=${!this.disabled}
554
+ ?closeTag=${!this.isDisabled}
555
555
  .buttonTabindex=${isOutside ? undefined : -1}
556
556
  @close=${() => this.handleTagRemove(value)}
557
557
  @keydown=${
@@ -301,7 +301,7 @@ export class PktDatepicker extends PktInputElement<Props> {
301
301
  .max=${this.max}
302
302
  .placeholder=${this.placeholder}
303
303
  .readonly=${this.readonly}
304
- .disabled=${this.disabled}
304
+ .disabled=${this.isDisabled}
305
305
  .inputClasses=${this.inputClasses}
306
306
  .inputSize=${this.inputSize}
307
307
  .internals=${this.internals}
@@ -339,7 +339,7 @@ export class PktDatepicker extends PktInputElement<Props> {
339
339
  .max=${this.max}
340
340
  .placeholder=${this.placeholder}
341
341
  .readonly=${this.readonly}
342
- .disabled=${this.disabled}
342
+ .disabled=${this.isDisabled}
343
343
  .showRangeLabels=${this.showRangeLabels}
344
344
  .inputClasses=${this.inputClasses}
345
345
  .inputSize=${this.inputSize}
@@ -427,7 +427,7 @@ export class PktDatepicker extends PktInputElement<Props> {
427
427
  .max=${this.max}
428
428
  .placeholder=${this.placeholder}
429
429
  .readonly=${this.readonly}
430
- .disabled=${this.disabled}
430
+ .disabled=${this.isDisabled}
431
431
  .maxlength=${this.maxlength}
432
432
  .inputClasses=${this.inputClasses}
433
433
  .inputSize=${this.inputSize}
@@ -512,7 +512,7 @@ export class PktDatepicker extends PktInputElement<Props> {
512
512
  ?counter=${this.multiple && !!this.maxlength}
513
513
  .counterCurrent=${this.value ? this._value.length : 0}
514
514
  .counterMaxLength=${this.maxlength}
515
- ?disabled=${this.disabled}
515
+ ?disabled=${this.isDisabled}
516
516
  ?hasError=${this.hasError}
517
517
  ?hasFieldset=${this.effectiveHasFieldset(false)}
518
518
  ?inline=${this.inline}
@@ -389,6 +389,25 @@ describe('PktInputWrapper', () => {
389
389
  document.body.innerHTML = ''
390
390
  })
391
391
 
392
+ test('links the error message to the fieldset', async () => {
393
+ const fieldset = await mountFieldset('hasError errorMessage="Velg ett alternativ"')
394
+
395
+ expect(describedByIds(fieldset)).toContain('g-error')
396
+ expect(document.getElementById('g-error')).toBeInTheDocument()
397
+ })
398
+
399
+ test('links both helptext and error message to the fieldset', async () => {
400
+ const fieldset = await mountFieldset('helptext="Velg ett" hasError errorMessage="Mangler"')
401
+
402
+ expect(describedByIds(fieldset)).toEqual(['g-helptext', 'g-error'])
403
+ })
404
+
405
+ test('does not link an error message when hasError is off', async () => {
406
+ const fieldset = await mountFieldset('errorMessage="Mangler"')
407
+
408
+ expect(fieldset.hasAttribute('aria-describedby')).toBe(false)
409
+ })
410
+
392
411
  test('links slotted helptext to the fieldset', async () => {
393
412
  const fieldset = await mountFieldset('', '<div class="pkt-contents" slot="helptext">Velg ett</div>')
394
413
 
@@ -420,6 +439,23 @@ describe('PktInputWrapper', () => {
420
439
  expect(describedByIds(fieldset)).toEqual(['g-helptext'])
421
440
  expect(document.getElementById('g-helptext')?.textContent).toContain('Velg ett')
422
441
  })
442
+
443
+ test('only references ids that are rendered', async () => {
444
+ const fieldset = await mountFieldset('helptext="Velg ett" hasError errorMessage="Mangler"')
445
+
446
+ describedByIds(fieldset).forEach((id) => {
447
+ expect(document.getElementById(id)).toBeInTheDocument()
448
+ })
449
+ })
450
+
451
+ test('names the fieldset with a hidden legend when useWrapper is off', async () => {
452
+ const fieldset = await mountFieldset('useWrapper="false"')
453
+
454
+ const legend = fieldset.querySelector(':scope > legend')
455
+ expect(legend).toHaveClass('pkt-sr-only')
456
+ expect(legend?.textContent?.trim()).toBe('Gruppe')
457
+ expect(fieldset.querySelector('label')).toBeNull()
458
+ })
423
459
  })
424
460
 
425
461
  describe('Wrapper functionality', () => {
@@ -100,11 +100,16 @@ export class PktInputWrapper extends PktElementWithSlot<Props> {
100
100
  const tagClasses = 'pkt-tag pkt-tag--small pkt-tag--thin-text'
101
101
 
102
102
  const hasHelptext = !!this.helptext || this.hasSlotContent('helptext')
103
- const describedBy = this.ariaDescribedby
104
- ? this.ariaDescribedby
105
- : hasHelptext
106
- ? `${this.forId}-helptext`
107
- : nothing
103
+ const describedByIds = new Set(
104
+ [
105
+ this.ariaDescribedby || (hasHelptext ? `${this.forId}-helptext` : ''),
106
+ this.hasError && this.errorMessage ? `${this.forId}-error` : '',
107
+ ]
108
+ .join(' ')
109
+ .split(' ')
110
+ .filter(Boolean),
111
+ )
112
+ const describedBy = describedByIds.size ? [...describedByIds].join(' ') : nothing
108
113
 
109
114
  const formStrings = this.pktStrings.get('forms')
110
115
 
@@ -145,6 +150,8 @@ export class PktInputWrapper extends PktElementWithSlot<Props> {
145
150
  >${this.label}${tagElement()}</label
146
151
  >`
147
152
  }
153
+ } else if (this.hasFieldset) {
154
+ return html`<legend class="pkt-sr-only" id="${this.forId}-label">${this.label}</legend>`
148
155
  } else {
149
156
  return html`<label for="${this.forId}" class="pkt-sr-only" id="${this.forId}-label">
150
157
  ${this.label}
@@ -42,9 +42,6 @@ export class PktRadioButton extends PktInputElement<Props> {
42
42
  }
43
43
 
44
44
  attributeChangedCallback(name: string, _old: string | null, value: string | null): void {
45
- if (name === 'defaultChecked') {
46
- this._checked = this.defaultChecked
47
- }
48
45
  if (name === 'checked') {
49
46
  this._checked = this.checked === '' || this.checked === 'true' || this.checked === true
50
47
  }
@@ -55,7 +52,7 @@ export class PktRadioButton extends PktInputElement<Props> {
55
52
  const inputTileClasses = classMap({
56
53
  'pkt-input-check__input': true,
57
54
  'pkt-input-check__input--tile': this.hasTile,
58
- 'pkt-input-check__input--tile-disabled': this.disabled && this.hasTile,
55
+ 'pkt-input-check__input--tile-disabled': this.isDisabled && this.hasTile,
59
56
  })
60
57
 
61
58
  const inputCheckBoxClasses = classMap({
@@ -65,7 +62,7 @@ export class PktRadioButton extends PktInputElement<Props> {
65
62
 
66
63
  const labelClasses = classMap({
67
64
  'pkt-input-check__input-label': true,
68
- 'pkt-input-check__input-label--disabled': this.disabled,
65
+ 'pkt-input-check__input-label--disabled': this.isDisabled,
69
66
  'pkt-sr-only': this.hideLabel,
70
67
  })
71
68
 
@@ -122,7 +119,7 @@ export class PktRadioButton extends PktInputElement<Props> {
122
119
  id=${this.id + '-internal'}
123
120
  class=${inputCheckBoxClasses}
124
121
  type="radio"
125
- ?disabled=${this.disabled}
122
+ ?disabled=${this.isDisabled}
126
123
  form=""
127
124
  name=${this.name + '-internal'}
128
125
  ${ref(this.inputRef)}
@@ -185,7 +185,7 @@ export class PktSelect extends PktOptionsInputElement<{}, TSelectOption> impleme
185
185
  ${forwardSlots(this, ['helptext'])}
186
186
  .strings=${this.strings}
187
187
  .size=${this.inputSize}
188
- ?disabled=${this.disabled}
188
+ ?disabled=${this.isDisabled}
189
189
  ?hasError=${this.hasError}
190
190
  ?hasFieldset=${this.effectiveHasFieldset(false)}
191
191
  ?inline=${this.inline}
@@ -216,7 +216,7 @@ export class PktSelect extends PktOptionsInputElement<{}, TSelectOption> impleme
216
216
  }),
217
217
  )}
218
218
  aria-labelledby=${ifDefined(this.ariaLabelledby)}
219
- ?disabled=${this.disabled}
219
+ ?disabled=${this.isDisabled}
220
220
  id=${this.id + '-input'}
221
221
  name=${(this.name || this.id) + '-input'}
222
222
  @change=${(e: Event) => {
@@ -66,7 +66,7 @@ export class PktTextarea extends PktInputElement<Props> {
66
66
  label=${this.label}
67
67
  ?counter=${showCounter}
68
68
  ?hasFieldset=${this.effectiveHasFieldset(false)}
69
- ?disabled=${this.disabled}
69
+ ?disabled=${this.isDisabled}
70
70
  ?hasError=${this.hasError}
71
71
  ?inline=${this.inline}
72
72
  ?optionalTag=${this.optionalTag}
@@ -110,7 +110,7 @@ export class PktTextarea extends PktInputElement<Props> {
110
110
  )}
111
111
  rows=${ifDefined(this.rows ?? undefined)}
112
112
  cols=${ifDefined(this.cols ?? undefined)}
113
- ?disabled=${this.disabled}
113
+ ?disabled=${this.isDisabled}
114
114
  @input=${(e: InputEvent) => {
115
115
  this.value = (e.target as HTMLInputElement).value
116
116
  this.onInput()
@@ -82,7 +82,7 @@ export class PktTextinput extends PktInputElement<Props> {
82
82
  label="${this.label}"
83
83
  ?counter=${showCounter}
84
84
  ?hasFieldset=${this.effectiveHasFieldset(false)}
85
- ?disabled=${this.disabled}
85
+ ?disabled=${this.isDisabled}
86
86
  ?hasError=${this.hasError}
87
87
  ?inline=${this.inline}
88
88
  ?optionalTag=${this.optionalTag}
@@ -121,7 +121,7 @@ export class PktTextinput extends PktInputElement<Props> {
121
121
  ?readonly=${this.readonly}
122
122
  size=${this.size || nothing}
123
123
  .value=${this.value}
124
- ?disabled=${this.disabled}
124
+ ?disabled=${this.isDisabled}
125
125
  aria-invalid=${this.hasError}
126
126
  aria-errormessage=${ifDefined(this.hasError ? `${this.id}-input-error` : undefined)}
127
127
  aria-describedby=${ifDefined(