@oslokommune/punkt-elements 19.14.3 → 19.15.0

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 CHANGED
@@ -5,6 +5,21 @@ og skriver commits ca etter [Conventional Commits](https://conventionalcommits.o
5
5
 
6
6
  ---
7
7
 
8
+ ## [19.15.0](https://github.com/oslokommune/punkt/compare/19.14.3...19.15.0) (2026-10-16)
9
+
10
+ ### Features
11
+ * Modal får mulighet for ikon i overskriften (#3719) (#3738). Ny prop headingIconName legger et ikon foran overskriften. Ikonet
12
+ skalerer med overskriften. headingIconPath overstyrer hvor ikonet hentes
13
+ fra.
14
+
15
+ Bug funnet underveis: med flere modaler på samme side leste skjermlesere
16
+ opp overskriften fra feil modal. Hver modal får nå sine egne id-er.
17
+
18
+ closes #3719
19
+
20
+ ---
21
+
22
+
8
23
  ## [19.14.3](https://github.com/oslokommune/punkt/compare/19.14.2...19.14.3) (2026-10-16)
9
24
 
10
25
  ### Bug Fixes
@@ -6,6 +6,8 @@ type ModalSize = TPktSize | 'fit-content';
6
6
  export interface IPktModal {
7
7
  open?: boolean;
8
8
  headingText?: string;
9
+ headingIconName?: string;
10
+ headingIconPath?: string;
9
11
  removePadding?: boolean;
10
12
  hideCloseButton?: boolean;
11
13
  closeOnBackdropClick?: boolean;
@@ -18,6 +20,8 @@ export interface IPktModal {
18
20
  export declare class PktModal extends PktElementWithSlot implements IPktModal {
19
21
  open?: boolean;
20
22
  headingText?: string;
23
+ headingIconName?: string;
24
+ headingIconPath?: string;
21
25
  removePadding?: boolean;
22
26
  hideCloseButton?: boolean;
23
27
  closeOnBackdropClick?: boolean;
@@ -28,6 +32,9 @@ export declare class PktModal extends PktElementWithSlot implements IPktModal {
28
32
  transparentBackdrop?: boolean;
29
33
  dialogRef: Ref<HTMLDialogElement>;
30
34
  private _scrollLockToken;
35
+ private readonly _idSuffix;
36
+ private readonly _headingId;
37
+ private readonly _contentId;
31
38
  _isOpen: boolean;
32
39
  constructor();
33
40
  connectedCallback(): Promise<void>;
@@ -0,0 +1,9 @@
1
+ import { BaseTestConfig } from '../../tests/test-framework';
2
+ import { IPktModal } from './modal';
3
+ export interface ModalTestConfig extends IPktModal, BaseTestConfig {
4
+ }
5
+ export declare const createModalTest: (config?: ModalTestConfig) => Promise<{
6
+ container: HTMLElement;
7
+ modal: import('./modal').PktModal;
8
+ heading: Element | null;
9
+ }>;
@@ -16,6 +16,8 @@ export declare class Modal extends PktElement {
16
16
  pktModal4: HTMLDialogElement;
17
17
  pktModal5: HTMLDialogElement;
18
18
  pktModal6: HTMLDialogElement;
19
+ pktModalHeadingIcon: HTMLDialogElement;
20
+ pktModalHeadingIconLong: HTMLDialogElement;
19
21
  connectedCallback(): void;
20
22
  disconnectedCallback(): void;
21
23
  render(): import('lit-html').TemplateResult<1>;
@@ -8,7 +8,7 @@ import { t as d } from "./converters-CkjLSYpa.js";
8
8
  import { n as f } from "./utils-BwF4QSrq.js";
9
9
  import "./input-wrapper-Bb6CZxmg.js";
10
10
  import { r as p } from "./focus-trap-DG3pEuyJ.js";
11
- import "./modal-B3CQEBBB.js";
11
+ import "./modal-0D0paY70.js";
12
12
  import "./progressbar-DZHiq7B0.js";
13
13
  //#region ../../shared-utils/fileupload/size.ts
14
14
  function m(e) {
@@ -1,4 +1,4 @@
1
- const e=require("./element-C6WTyJFE.cjs"),t=require("./class-map-Bh6toDeV.cjs"),n=require("./format-B8meU8Tm.cjs");require("./alert-CuXM6TnC.cjs"),require("./icon-jPhyZD1z.cjs");const r=require("./if-defined-CiML3MTM.cjs"),i=require("./converters-BJ9Fe0kW.cjs"),a=require("./utils-63cRpWut.cjs");require("./input-wrapper-BwzajfFX.cjs");const o=require("./focus-trap-DSv4Ifqm.cjs");require("./modal-BKeSXrzi.cjs"),require("./progressbar-CnX4fFfR.cjs");function s(e){if(e==null||e===``)return;if(typeof e==`number`)return Number.isFinite(e)&&e>0?e:void 0;let t=String(e).trim(),n=Number(t);if(!Number.isNaN(n)&&n>0)return n;let r=t.match(/^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB)$/i);if(!r){console.warn(`PktFileUpload: Invalid maxFileSize format "${t}". Use format like "5MB", "500KB", "1GB", or bytes.`);return}let i=parseFloat(r[1]);switch(r[2].toUpperCase()){case`B`:return i;case`KB`:return i*1024;case`MB`:return i*1024*1024;case`GB`:return i*1024*1024*1024;default:return}}function c(e){return e<1024?`${Math.round(e)} B`:e<1048576?`${Math.round(e/1024)} KB`:e<1073741824?`${Math.round(e/1048576)} MB`:`${Math.round(e/1073741824)} GB`}function l(e){return Array.isArray(e)?e.map(e=>String(e).trim().toLowerCase()).filter(Boolean):[]}function u(e){return e?e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean):[]}function d(e,t,n){let r=e.toLowerCase().replace(/^\./,``);if(r.includes(`/`)){if(r.endsWith(`/*`)){let e=r.replace(`/*`,``);return n.startsWith(`${e}/`)}return n===r}return t===r}function f(e,t){let n=l(t);if(n.length===0)return!0;let r=e.name.split(`.`).pop()?.toLowerCase()??``,i=e.type.toLowerCase();return n.some(e=>d(e,r,i))}function p(e,t){let n=(e??``).trim();if(n)return n;let r=l(t);return r.length===0?``:r.map(e=>e.includes(`/`)||e.startsWith(`.`)?e:`.${e}`).join(`, `)}function m(e){return e.includes(`/`)?e:e.replace(/^\./,``).toUpperCase()}function h(e,t){let n=l(e);if(n.length>0)return n.map(m).join(`, `);let r=u(t);return r.length>0?r.map(m).join(`, `):``}function g(e,t,n){return((e??``).trim()||t).replace(/\{(\w+)\}/g,(e,t)=>n[t]??`{${t}}`)}function _(t,n){let r=l(n.allowedFormats);if(r.length>0&&!f(t,r)){let t=r.join(`, `),i=e.s.fileupload.invalidFormat;return g(n.formatErrorMessage,i,{formats:t})}let i=s(n.maxFileSize);if(i!==void 0&&t.size>i){let t=c(i),r=e.s.fileupload.sizeTooLarge;return g(n.sizeErrorMessage,r,{maxSize:t})}if(n.onFileValidation){let e=n.onFileValidation(t);if(e)return e}return null}function v(e){let t=e.file;if(t?.type?.startsWith(`image/`))return!0;let n=e.attributes?.targetFilename||t?.name||``;return/\.(jpe?g|png|gif|webp|heic|heif|bmp|svg)$/i.test(n)}function y(e){return typeof e==`number`?`in-progress`:e===`error`?`error`:`idle`}function b(e,t,n){let r={"in-progress":0,error:1,idle:2};return e.map(e=>{let r=t?.find(t=>t.fileId===e.fileId);return{...e,progress:r?.progress??(n===`form`?`done`:`queued`),errorMessage:r?.errorMessage,showProgress:r?.showProgress,lastProgress:r?.lastProgress}}).sort((e,t)=>r[y(e.progress)]-r[y(t.progress)])}function x(e,t){return!t||t<=0||e.length<=t+3?null:{head:e.slice(0,e.length-t),tail:e.slice(-t)}}function S(e,t,n){return n<=0?0:t===`prev`?e<=0?n-1:e-1:e>=n-1?0:e+1}function C(e,t){let n=e.length;if(n===0||!t||t.length===0)return{totalCount:n,uploadedCount:0,failedCount:0};let r=0,i=0;for(let n of e){let e=t.find(e=>e.fileId===n.fileId);e?.progress===`done`?r++:e?.progress===`error`&&i++}return{totalCount:n,uploadedCount:r,failedCount:i}}function w(t,n=e.s.fileupload.unknownFilename){return t.attributes?.targetFilename||t.file?.name||n}var T=class extends e.t{constructor(...e){super(...e),this.id=`pkt-fileupload-${a.n()}`,this.name=`files`,this.label=``,this.helptext=``,this.helptextDropdown=``,this.required=!1,this.multiple=!1,this.disabled=!1,this.fullwidth=!1,this.uploadStrategy=`form`,this.itemRenderer=`filename`,this.accept=``,this.allowedFormats=[],this.formatErrorMessage=``,this.sizeErrorMessage=``,this.transfers=[],this.addCommentsEnabled=!1,this.renameFilesEnabled=!1,this.extraOperations=[],this.enableImagePreview=!1,this.hasError=!1,this.errorMessage=``,this.optionalTag=!1,this.requiredTag=!1,this.tagText=null,this.truncateTail=4,this.files=[],this.isDragActive=!1,this.validationErrorMessage=null,this.addedAnnouncement=``,this.thumbnailUrls={},this.hasInitializedValue=!1,this.hasWarnedInvalidValueCombo=!1,this.thumbnailFileById=new Map,this.connectedForm=null,this.addedAnnouncementTimer=null,this.onNativeFileChange=e=>{let t=e.target;this.addFiles(t.files?Array.from(t.files):[]),this.uploadStrategy===`custom`&&(t.value=``)},this.openFileDialog=e=>{e.preventDefault(),e.stopPropagation(),!this.disabled&&this.querySelector(`#${this.id}-input`)?.click()},this.onDropZoneClick=e=>{this.disabled||e.target.closest(`.pkt-fileupload__drop-zone__placeholder__title__open-file-dialog`)||this.querySelector(`#${this.id}-input`)?.click()},this.onDragOver=e=>{e.preventDefault(),!this.disabled&&(this.isDragActive=!0)},this.onDragLeave=()=>{this.isDragActive=!1},this.onDrop=e=>{if(e.preventDefault(),this.isDragActive=!1,this.disabled)return;let t=e.dataTransfer?.files?Array.from(e.dataTransfer.files):[];this.addFiles(t)},this.onHostFormSubmit=e=>{!this.required||this.uploadStrategy!==`custom`||this.getCurrentFiles().length>0||(this.validationErrorMessage=this.requiredSelectionMessage,e.preventDefault())}}get requiredSelectionMessage(){return this.pktStrings.get(`fileupload`).requiredMissing}get isControlled(){return this.value!==void 0}get hasEffectiveError(){return!!this.validationErrorMessage||this.hasError||!!this.errorMessage.trim()}get effectiveErrorMessage(){return this.validationErrorMessage??this.errorMessage??``}get hasValidationError(){return!!this.validationErrorMessage}firstUpdated(e){super.firstUpdated?.(e),this.hasInitializedValue||=(this.files=this.value??this.defaultValue??[],this.syncThumbnailUrls(this.files),!0),this.value!==void 0&&this.defaultValue!==void 0&&this.warnInvalidValueCombo()}willUpdate(e){super.willUpdate(e),this.hasInitializedValue&&this.isControlled&&(e.has(`value`)||e.has(`itemRenderer`)||e.has(`enableImagePreview`))&&(this.files=this.value??[],this.syncThumbnailUrls(this.files))}updated(e){super.updated(e),(e.has(`uploadStrategy`)||e.has(`required`)||e.has(`value`)||e.has(`form`))&&this.syncFormSubmitListener(),this.uploadStrategy===`form`&&(e.has(`value`)||e.has(`files`)||e.has(`uploadStrategy`))&&this.syncNativeInputFiles()}syncNativeInputFiles(){let e=this.querySelector(`#${this.id}-input`);if(!(!e||typeof DataTransfer>`u`))try{let t=new DataTransfer;for(let e of this.getCurrentFiles())e.file&&t.items.add(e.file);e.files=t.files}catch{}}warnInvalidValueCombo(){this.hasWarnedInvalidValueCombo||=(console.warn(`PktFileUpload: Både value og defaultValue er angitt. Komponenten kan være enten kontrollert eller ukontrollert, ikke begge. value vil bli prioritert.`),!0)}disconnectedCallback(){this.teardownFormSubmitListener(),this.addedAnnouncementTimer&&=(clearTimeout(this.addedAnnouncementTimer),null),super.disconnectedCallback(),this.revokeAllThumbnailUrls()}setAddedAnnouncement(e){this.addedAnnouncement=e,this.addedAnnouncementTimer&&clearTimeout(this.addedAnnouncementTimer),this.addedAnnouncementTimer=setTimeout(()=>{this.addedAnnouncement=``,this.addedAnnouncementTimer=null},1500)}connectedCallback(){super.connectedCallback(),this.syncFormSubmitListener()}addFiles(e){if(e.length===0)return;let t=this.multiple?e:[e[0]];for(let e of t){let t=this.validateFile(e);if(t){this.validationErrorMessage=t;return}}this.validationErrorMessage=null;let r=t.map(e=>({fileId:a.n(),file:e,attributes:{targetFilename:e.name}})),i=this.pktStrings.get(`fileupload`);this.setAddedAnnouncement(r.length===1?n.t(i.srFileAdded,{filename:r[0].attributes.targetFilename}):n.t(i.srFilesAdded,{count:r.length}));let o=this.getCurrentFiles(),s=this.multiple?[...o,...r]:[r[0]];this.commitFiles(s,`add`,r.map(e=>e.fileId)),this.uploadStrategy===`custom`&&r.forEach(e=>{this.dispatchEvent(new CustomEvent(`file-upload-requested`,{detail:{fileId:e.fileId,file:e.file,attributes:e.attributes},bubbles:!0,composed:!0}))})}getCurrentFiles(){return this.isControlled?this.value??[]:this.files}cancelTransfer(e){if(this.disabled)return;let t=this.getCurrentFiles().find(t=>t.fileId===e);t&&(this.removeFileItem(e),this.dispatchEvent(new CustomEvent(`transfer-cancelled`,{detail:{fileId:t.fileId,file:t.file,attributes:t.attributes},bubbles:!0,composed:!0})))}removeFileItem(e){if(this.disabled)return;let t=this.getCurrentFiles(),n=t.filter(t=>t.fileId!==e);n.length!==t.length&&this.commitFiles(n,`remove`,[e])}updateFileItem(e,t){let n=this.getCurrentFiles().map(n=>n.fileId===e?{...n,...t}:n);this.commitFiles(n,`update`,[e])}commitFiles(e,t,n){this.isControlled||(this.files=e,this.syncThumbnailUrls(e)),this.validationErrorMessage===this.requiredSelectionMessage&&e.length>0&&(this.validationErrorMessage=null),this.dispatchEvent(new CustomEvent(`files-changed`,{detail:{files:e,reason:t,changedFileIds:n},bubbles:!0,composed:!0}))}getThumbnailUrl(e){return this.thumbnailUrls[e.fileId]}getTransferProgress(e){let t=this.transfers.find(t=>t.fileId===e);return t?t.progress:this.uploadStrategy===`form`?`done`:`queued`}getTransferForFile(e){return this.transfers.find(t=>t.fileId===e)}isImageFile(e){return v(e)}formatFileSize(e){return c(e)}getResolvedAcceptValue(){return p(this.accept,this.allowedFormats)}getSupportedFormatsText(){return h(this.allowedFormats,this.accept)}getSortedFilesAndTransfers(){return b(this.getCurrentFiles(),this.transfers,this.uploadStrategy)}validateFile(e){let t=_(e,{allowedFormats:this.allowedFormats,maxFileSize:this.maxFileSize,formatErrorMessage:this.formatErrorMessage,sizeErrorMessage:this.sizeErrorMessage,onFileValidation:this.onFileValidation});if(t)return t;let n={file:e,errorMessage:null},r=new CustomEvent(`file-validate`,{detail:n,bubbles:!0,composed:!0,cancelable:!0});return this.dispatchEvent(r),n.errorMessage?n.errorMessage:r.defaultPrevented?this.pktStrings.get(`fileupload`).genericValidationRejection:null}syncThumbnailUrls(e){if(!(typeof URL<`u`&&typeof URL.createObjectURL==`function`&&typeof URL.revokeObjectURL==`function`)){this.thumbnailUrls={},this.thumbnailFileById.clear();return}let t=new Set(e.map(e=>e.fileId)),n={};for(let[e,n]of Object.entries(this.thumbnailUrls))t.has(e)||(URL.revokeObjectURL(n),this.thumbnailFileById.delete(e));for(let t of e){let e=this.thumbnailUrls[t.fileId],r=this.thumbnailFileById.get(t.fileId);if(!t.file||!this.isImageFile(t)){e&&(URL.revokeObjectURL(e),this.thumbnailFileById.delete(t.fileId));continue}if(e&&r===t.file){n[t.fileId]=e;continue}e&&r!==t.file&&URL.revokeObjectURL(e);let i=URL.createObjectURL(t.file);this.thumbnailFileById.set(t.fileId,t.file),n[t.fileId]=i}this.thumbnailUrls=n}revokeAllThumbnailUrls(){if(typeof URL>`u`||typeof URL.revokeObjectURL!=`function`){this.thumbnailUrls={},this.thumbnailFileById.clear();return}Object.values(this.thumbnailUrls).forEach(e=>URL.revokeObjectURL(e)),this.thumbnailUrls={},this.thumbnailFileById.clear()}getSrUploadedMessage(){if(this.addedAnnouncement)return this.addedAnnouncement;let{totalCount:e,uploadedCount:t}=C(this.getCurrentFiles(),this.transfers);if(e===0||t===0)return``;let r=this.pktStrings.get(`fileupload`);return n.t(r.srFilesUploadedOfTotal,{uploaded:t,total:e,label:n.n(e,r.fileLabelOne,r.fileLabelOther)})}getSrErrorsMessage(){let{totalCount:e,failedCount:t}=C(this.getCurrentFiles(),this.transfers);if(e===0||t===0)return``;let r=this.pktStrings.get(`fileupload`);return n.t(r.srFilesFailedOfTotal,{failed:t,total:e,label:n.n(e,r.fileLabelOne,r.fileLabelOther)})}get ownerForm(){if(this.form!==void 0){if(!this.form)return null;let e=this.ownerDocument?.getElementById(this.form);return e instanceof HTMLFormElement?e:null}return this.closest(`form`)}syncFormSubmitListener(){let e=this.ownerForm;this.connectedForm!==e&&(this.teardownFormSubmitListener(),this.connectedForm=e,this.connectedForm&&this.connectedForm.addEventListener(`submit`,this.onHostFormSubmit))}teardownFormSubmitListener(){this.connectedForm&&=(this.connectedForm.removeEventListener(`submit`,this.onHostFormSubmit),null)}};e.n([e.u({type:String})],T.prototype,`id`,void 0),e.n([e.u({type:String})],T.prototype,`name`,void 0),e.n([e.u({type:String,reflect:!0})],T.prototype,`form`,void 0),e.n([e.u({type:String})],T.prototype,`label`,void 0),e.n([e.u({type:String})],T.prototype,`helptext`,void 0),e.n([e.u({type:String,attribute:`helptext-dropdown`})],T.prototype,`helptextDropdown`,void 0),e.n([e.u({type:String,attribute:`helptext-dropdown-button`})],T.prototype,`helptextDropdownButton`,void 0),e.n([e.u({type:Boolean,reflect:!0})],T.prototype,`required`,void 0),e.n([e.u({type:Boolean,reflect:!0})],T.prototype,`multiple`,void 0),e.n([e.u({type:Boolean,reflect:!0})],T.prototype,`disabled`,void 0),e.n([e.u({type:Boolean,reflect:!0,attribute:`fullwidth`})],T.prototype,`fullwidth`,void 0),e.n([e.u({type:String,reflect:!0,attribute:`upload-strategy`})],T.prototype,`uploadStrategy`,void 0),e.n([e.u({type:String,reflect:!0,attribute:`item-renderer`})],T.prototype,`itemRenderer`,void 0),e.n([e.u({type:String})],T.prototype,`accept`,void 0),e.n([e.u({converter:i.t.csvToArray,attribute:`allowed-formats`})],T.prototype,`allowedFormats`,void 0),e.n([e.u({type:String,attribute:`format-error-message`})],T.prototype,`formatErrorMessage`,void 0),e.n([e.u({attribute:`max-file-size`})],T.prototype,`maxFileSize`,void 0),e.n([e.u({type:String,attribute:`size-error-message`})],T.prototype,`sizeErrorMessage`,void 0),e.n([e.u({attribute:!1})],T.prototype,`onFileValidation`,void 0),e.n([e.u({attribute:!1})],T.prototype,`transfers`,void 0),e.n([e.u({type:Boolean,attribute:`add-comments-enabled`})],T.prototype,`addCommentsEnabled`,void 0),e.n([e.u({type:Boolean,attribute:`rename-files-enabled`})],T.prototype,`renameFilesEnabled`,void 0),e.n([e.u({attribute:!1})],T.prototype,`extraOperations`,void 0),e.n([e.u({type:Boolean,reflect:!0,attribute:`enable-image-preview`})],T.prototype,`enableImagePreview`,void 0),e.n([e.u({type:Boolean,attribute:`has-error`})],T.prototype,`hasError`,void 0),e.n([e.u({type:String,attribute:`error-message`})],T.prototype,`errorMessage`,void 0),e.n([e.u({type:Boolean,attribute:`optional-tag`})],T.prototype,`optionalTag`,void 0),e.n([e.u({type:String,attribute:`optional-text`})],T.prototype,`optionalText`,void 0),e.n([e.u({type:Boolean,attribute:`required-tag`})],T.prototype,`requiredTag`,void 0),e.n([e.u({type:String,attribute:`required-text`})],T.prototype,`requiredText`,void 0),e.n([e.u({type:String,attribute:`tag-text`})],T.prototype,`tagText`,void 0),e.n([e.u({type:Number,attribute:`truncate-tail`})],T.prototype,`truncateTail`,void 0),e.n([e.u({attribute:!1})],T.prototype,`value`,void 0),e.n([e.u({attribute:!1})],T.prototype,`defaultValue`,void 0),e.n([e.l()],T.prototype,`files`,void 0),e.n([e.l()],T.prototype,`isDragActive`,void 0),e.n([e.l()],T.prototype,`validationErrorMessage`,void 0),e.n([e.l()],T.prototype,`addedAnnouncement`,void 0),e.n([e.l()],T.prototype,`thumbnailUrls`,void 0);var E=`comments`,D=(e,t)=>{let r=new Date(e);if(Number.isNaN(r.getTime()))return e;let i=String(r.getDate()).padStart(2,`0`),a=String(r.getMonth()+1).padStart(2,`0`),o=r.getFullYear(),s=String(r.getHours()).padStart(2,`0`),c=String(r.getMinutes()).padStart(2,`0`);return n.t(t.commentTimestamp,{date:`${i}.${a}.${o}`,time:`${s}:${c}`})},O=(e,t,n)=>{e.key===`Enter`&&(e.preventDefault(),e.stopPropagation(),t()),e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),n())},k=(e,t,n)=>{e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),n()),(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&(e.preventDefault(),e.stopPropagation(),t())},A=(e,t)=>({id:`remove`,title:t.remove,ariaLabel:t.removeFile,onClick:({file:t})=>e(t.fileId)}),j=t=>({id:`rename`,title:t.rename,ariaLabel:t.renameFile,renderInlineUI:n=>{let r=n.getAttribute(`targetFilename`)||n.file.attributes?.targetFilename||n.file.file?.name||``,i=`pkt-fileupload-rename-${n.file.fileId}`,a=()=>{let e=document.getElementById(i)?.value?.trim();e&&n.setAttribute(`targetFilename`,e),n.close()};return e._`
1
+ const e=require("./element-C6WTyJFE.cjs"),t=require("./class-map-Bh6toDeV.cjs"),n=require("./format-B8meU8Tm.cjs");require("./alert-CuXM6TnC.cjs"),require("./icon-jPhyZD1z.cjs");const r=require("./if-defined-CiML3MTM.cjs"),i=require("./converters-BJ9Fe0kW.cjs"),a=require("./utils-63cRpWut.cjs");require("./input-wrapper-BwzajfFX.cjs");const o=require("./focus-trap-DSv4Ifqm.cjs");require("./modal-wEEmCcUx.cjs"),require("./progressbar-CnX4fFfR.cjs");function s(e){if(e==null||e===``)return;if(typeof e==`number`)return Number.isFinite(e)&&e>0?e:void 0;let t=String(e).trim(),n=Number(t);if(!Number.isNaN(n)&&n>0)return n;let r=t.match(/^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB)$/i);if(!r){console.warn(`PktFileUpload: Invalid maxFileSize format "${t}". Use format like "5MB", "500KB", "1GB", or bytes.`);return}let i=parseFloat(r[1]);switch(r[2].toUpperCase()){case`B`:return i;case`KB`:return i*1024;case`MB`:return i*1024*1024;case`GB`:return i*1024*1024*1024;default:return}}function c(e){return e<1024?`${Math.round(e)} B`:e<1048576?`${Math.round(e/1024)} KB`:e<1073741824?`${Math.round(e/1048576)} MB`:`${Math.round(e/1073741824)} GB`}function l(e){return Array.isArray(e)?e.map(e=>String(e).trim().toLowerCase()).filter(Boolean):[]}function u(e){return e?e.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean):[]}function d(e,t,n){let r=e.toLowerCase().replace(/^\./,``);if(r.includes(`/`)){if(r.endsWith(`/*`)){let e=r.replace(`/*`,``);return n.startsWith(`${e}/`)}return n===r}return t===r}function f(e,t){let n=l(t);if(n.length===0)return!0;let r=e.name.split(`.`).pop()?.toLowerCase()??``,i=e.type.toLowerCase();return n.some(e=>d(e,r,i))}function p(e,t){let n=(e??``).trim();if(n)return n;let r=l(t);return r.length===0?``:r.map(e=>e.includes(`/`)||e.startsWith(`.`)?e:`.${e}`).join(`, `)}function m(e){return e.includes(`/`)?e:e.replace(/^\./,``).toUpperCase()}function h(e,t){let n=l(e);if(n.length>0)return n.map(m).join(`, `);let r=u(t);return r.length>0?r.map(m).join(`, `):``}function g(e,t,n){return((e??``).trim()||t).replace(/\{(\w+)\}/g,(e,t)=>n[t]??`{${t}}`)}function _(t,n){let r=l(n.allowedFormats);if(r.length>0&&!f(t,r)){let t=r.join(`, `),i=e.s.fileupload.invalidFormat;return g(n.formatErrorMessage,i,{formats:t})}let i=s(n.maxFileSize);if(i!==void 0&&t.size>i){let t=c(i),r=e.s.fileupload.sizeTooLarge;return g(n.sizeErrorMessage,r,{maxSize:t})}if(n.onFileValidation){let e=n.onFileValidation(t);if(e)return e}return null}function v(e){let t=e.file;if(t?.type?.startsWith(`image/`))return!0;let n=e.attributes?.targetFilename||t?.name||``;return/\.(jpe?g|png|gif|webp|heic|heif|bmp|svg)$/i.test(n)}function y(e){return typeof e==`number`?`in-progress`:e===`error`?`error`:`idle`}function b(e,t,n){let r={"in-progress":0,error:1,idle:2};return e.map(e=>{let r=t?.find(t=>t.fileId===e.fileId);return{...e,progress:r?.progress??(n===`form`?`done`:`queued`),errorMessage:r?.errorMessage,showProgress:r?.showProgress,lastProgress:r?.lastProgress}}).sort((e,t)=>r[y(e.progress)]-r[y(t.progress)])}function x(e,t){return!t||t<=0||e.length<=t+3?null:{head:e.slice(0,e.length-t),tail:e.slice(-t)}}function S(e,t,n){return n<=0?0:t===`prev`?e<=0?n-1:e-1:e>=n-1?0:e+1}function C(e,t){let n=e.length;if(n===0||!t||t.length===0)return{totalCount:n,uploadedCount:0,failedCount:0};let r=0,i=0;for(let n of e){let e=t.find(e=>e.fileId===n.fileId);e?.progress===`done`?r++:e?.progress===`error`&&i++}return{totalCount:n,uploadedCount:r,failedCount:i}}function w(t,n=e.s.fileupload.unknownFilename){return t.attributes?.targetFilename||t.file?.name||n}var T=class extends e.t{constructor(...e){super(...e),this.id=`pkt-fileupload-${a.n()}`,this.name=`files`,this.label=``,this.helptext=``,this.helptextDropdown=``,this.required=!1,this.multiple=!1,this.disabled=!1,this.fullwidth=!1,this.uploadStrategy=`form`,this.itemRenderer=`filename`,this.accept=``,this.allowedFormats=[],this.formatErrorMessage=``,this.sizeErrorMessage=``,this.transfers=[],this.addCommentsEnabled=!1,this.renameFilesEnabled=!1,this.extraOperations=[],this.enableImagePreview=!1,this.hasError=!1,this.errorMessage=``,this.optionalTag=!1,this.requiredTag=!1,this.tagText=null,this.truncateTail=4,this.files=[],this.isDragActive=!1,this.validationErrorMessage=null,this.addedAnnouncement=``,this.thumbnailUrls={},this.hasInitializedValue=!1,this.hasWarnedInvalidValueCombo=!1,this.thumbnailFileById=new Map,this.connectedForm=null,this.addedAnnouncementTimer=null,this.onNativeFileChange=e=>{let t=e.target;this.addFiles(t.files?Array.from(t.files):[]),this.uploadStrategy===`custom`&&(t.value=``)},this.openFileDialog=e=>{e.preventDefault(),e.stopPropagation(),!this.disabled&&this.querySelector(`#${this.id}-input`)?.click()},this.onDropZoneClick=e=>{this.disabled||e.target.closest(`.pkt-fileupload__drop-zone__placeholder__title__open-file-dialog`)||this.querySelector(`#${this.id}-input`)?.click()},this.onDragOver=e=>{e.preventDefault(),!this.disabled&&(this.isDragActive=!0)},this.onDragLeave=()=>{this.isDragActive=!1},this.onDrop=e=>{if(e.preventDefault(),this.isDragActive=!1,this.disabled)return;let t=e.dataTransfer?.files?Array.from(e.dataTransfer.files):[];this.addFiles(t)},this.onHostFormSubmit=e=>{!this.required||this.uploadStrategy!==`custom`||this.getCurrentFiles().length>0||(this.validationErrorMessage=this.requiredSelectionMessage,e.preventDefault())}}get requiredSelectionMessage(){return this.pktStrings.get(`fileupload`).requiredMissing}get isControlled(){return this.value!==void 0}get hasEffectiveError(){return!!this.validationErrorMessage||this.hasError||!!this.errorMessage.trim()}get effectiveErrorMessage(){return this.validationErrorMessage??this.errorMessage??``}get hasValidationError(){return!!this.validationErrorMessage}firstUpdated(e){super.firstUpdated?.(e),this.hasInitializedValue||=(this.files=this.value??this.defaultValue??[],this.syncThumbnailUrls(this.files),!0),this.value!==void 0&&this.defaultValue!==void 0&&this.warnInvalidValueCombo()}willUpdate(e){super.willUpdate(e),this.hasInitializedValue&&this.isControlled&&(e.has(`value`)||e.has(`itemRenderer`)||e.has(`enableImagePreview`))&&(this.files=this.value??[],this.syncThumbnailUrls(this.files))}updated(e){super.updated(e),(e.has(`uploadStrategy`)||e.has(`required`)||e.has(`value`)||e.has(`form`))&&this.syncFormSubmitListener(),this.uploadStrategy===`form`&&(e.has(`value`)||e.has(`files`)||e.has(`uploadStrategy`))&&this.syncNativeInputFiles()}syncNativeInputFiles(){let e=this.querySelector(`#${this.id}-input`);if(!(!e||typeof DataTransfer>`u`))try{let t=new DataTransfer;for(let e of this.getCurrentFiles())e.file&&t.items.add(e.file);e.files=t.files}catch{}}warnInvalidValueCombo(){this.hasWarnedInvalidValueCombo||=(console.warn(`PktFileUpload: Både value og defaultValue er angitt. Komponenten kan være enten kontrollert eller ukontrollert, ikke begge. value vil bli prioritert.`),!0)}disconnectedCallback(){this.teardownFormSubmitListener(),this.addedAnnouncementTimer&&=(clearTimeout(this.addedAnnouncementTimer),null),super.disconnectedCallback(),this.revokeAllThumbnailUrls()}setAddedAnnouncement(e){this.addedAnnouncement=e,this.addedAnnouncementTimer&&clearTimeout(this.addedAnnouncementTimer),this.addedAnnouncementTimer=setTimeout(()=>{this.addedAnnouncement=``,this.addedAnnouncementTimer=null},1500)}connectedCallback(){super.connectedCallback(),this.syncFormSubmitListener()}addFiles(e){if(e.length===0)return;let t=this.multiple?e:[e[0]];for(let e of t){let t=this.validateFile(e);if(t){this.validationErrorMessage=t;return}}this.validationErrorMessage=null;let r=t.map(e=>({fileId:a.n(),file:e,attributes:{targetFilename:e.name}})),i=this.pktStrings.get(`fileupload`);this.setAddedAnnouncement(r.length===1?n.t(i.srFileAdded,{filename:r[0].attributes.targetFilename}):n.t(i.srFilesAdded,{count:r.length}));let o=this.getCurrentFiles(),s=this.multiple?[...o,...r]:[r[0]];this.commitFiles(s,`add`,r.map(e=>e.fileId)),this.uploadStrategy===`custom`&&r.forEach(e=>{this.dispatchEvent(new CustomEvent(`file-upload-requested`,{detail:{fileId:e.fileId,file:e.file,attributes:e.attributes},bubbles:!0,composed:!0}))})}getCurrentFiles(){return this.isControlled?this.value??[]:this.files}cancelTransfer(e){if(this.disabled)return;let t=this.getCurrentFiles().find(t=>t.fileId===e);t&&(this.removeFileItem(e),this.dispatchEvent(new CustomEvent(`transfer-cancelled`,{detail:{fileId:t.fileId,file:t.file,attributes:t.attributes},bubbles:!0,composed:!0})))}removeFileItem(e){if(this.disabled)return;let t=this.getCurrentFiles(),n=t.filter(t=>t.fileId!==e);n.length!==t.length&&this.commitFiles(n,`remove`,[e])}updateFileItem(e,t){let n=this.getCurrentFiles().map(n=>n.fileId===e?{...n,...t}:n);this.commitFiles(n,`update`,[e])}commitFiles(e,t,n){this.isControlled||(this.files=e,this.syncThumbnailUrls(e)),this.validationErrorMessage===this.requiredSelectionMessage&&e.length>0&&(this.validationErrorMessage=null),this.dispatchEvent(new CustomEvent(`files-changed`,{detail:{files:e,reason:t,changedFileIds:n},bubbles:!0,composed:!0}))}getThumbnailUrl(e){return this.thumbnailUrls[e.fileId]}getTransferProgress(e){let t=this.transfers.find(t=>t.fileId===e);return t?t.progress:this.uploadStrategy===`form`?`done`:`queued`}getTransferForFile(e){return this.transfers.find(t=>t.fileId===e)}isImageFile(e){return v(e)}formatFileSize(e){return c(e)}getResolvedAcceptValue(){return p(this.accept,this.allowedFormats)}getSupportedFormatsText(){return h(this.allowedFormats,this.accept)}getSortedFilesAndTransfers(){return b(this.getCurrentFiles(),this.transfers,this.uploadStrategy)}validateFile(e){let t=_(e,{allowedFormats:this.allowedFormats,maxFileSize:this.maxFileSize,formatErrorMessage:this.formatErrorMessage,sizeErrorMessage:this.sizeErrorMessage,onFileValidation:this.onFileValidation});if(t)return t;let n={file:e,errorMessage:null},r=new CustomEvent(`file-validate`,{detail:n,bubbles:!0,composed:!0,cancelable:!0});return this.dispatchEvent(r),n.errorMessage?n.errorMessage:r.defaultPrevented?this.pktStrings.get(`fileupload`).genericValidationRejection:null}syncThumbnailUrls(e){if(!(typeof URL<`u`&&typeof URL.createObjectURL==`function`&&typeof URL.revokeObjectURL==`function`)){this.thumbnailUrls={},this.thumbnailFileById.clear();return}let t=new Set(e.map(e=>e.fileId)),n={};for(let[e,n]of Object.entries(this.thumbnailUrls))t.has(e)||(URL.revokeObjectURL(n),this.thumbnailFileById.delete(e));for(let t of e){let e=this.thumbnailUrls[t.fileId],r=this.thumbnailFileById.get(t.fileId);if(!t.file||!this.isImageFile(t)){e&&(URL.revokeObjectURL(e),this.thumbnailFileById.delete(t.fileId));continue}if(e&&r===t.file){n[t.fileId]=e;continue}e&&r!==t.file&&URL.revokeObjectURL(e);let i=URL.createObjectURL(t.file);this.thumbnailFileById.set(t.fileId,t.file),n[t.fileId]=i}this.thumbnailUrls=n}revokeAllThumbnailUrls(){if(typeof URL>`u`||typeof URL.revokeObjectURL!=`function`){this.thumbnailUrls={},this.thumbnailFileById.clear();return}Object.values(this.thumbnailUrls).forEach(e=>URL.revokeObjectURL(e)),this.thumbnailUrls={},this.thumbnailFileById.clear()}getSrUploadedMessage(){if(this.addedAnnouncement)return this.addedAnnouncement;let{totalCount:e,uploadedCount:t}=C(this.getCurrentFiles(),this.transfers);if(e===0||t===0)return``;let r=this.pktStrings.get(`fileupload`);return n.t(r.srFilesUploadedOfTotal,{uploaded:t,total:e,label:n.n(e,r.fileLabelOne,r.fileLabelOther)})}getSrErrorsMessage(){let{totalCount:e,failedCount:t}=C(this.getCurrentFiles(),this.transfers);if(e===0||t===0)return``;let r=this.pktStrings.get(`fileupload`);return n.t(r.srFilesFailedOfTotal,{failed:t,total:e,label:n.n(e,r.fileLabelOne,r.fileLabelOther)})}get ownerForm(){if(this.form!==void 0){if(!this.form)return null;let e=this.ownerDocument?.getElementById(this.form);return e instanceof HTMLFormElement?e:null}return this.closest(`form`)}syncFormSubmitListener(){let e=this.ownerForm;this.connectedForm!==e&&(this.teardownFormSubmitListener(),this.connectedForm=e,this.connectedForm&&this.connectedForm.addEventListener(`submit`,this.onHostFormSubmit))}teardownFormSubmitListener(){this.connectedForm&&=(this.connectedForm.removeEventListener(`submit`,this.onHostFormSubmit),null)}};e.n([e.u({type:String})],T.prototype,`id`,void 0),e.n([e.u({type:String})],T.prototype,`name`,void 0),e.n([e.u({type:String,reflect:!0})],T.prototype,`form`,void 0),e.n([e.u({type:String})],T.prototype,`label`,void 0),e.n([e.u({type:String})],T.prototype,`helptext`,void 0),e.n([e.u({type:String,attribute:`helptext-dropdown`})],T.prototype,`helptextDropdown`,void 0),e.n([e.u({type:String,attribute:`helptext-dropdown-button`})],T.prototype,`helptextDropdownButton`,void 0),e.n([e.u({type:Boolean,reflect:!0})],T.prototype,`required`,void 0),e.n([e.u({type:Boolean,reflect:!0})],T.prototype,`multiple`,void 0),e.n([e.u({type:Boolean,reflect:!0})],T.prototype,`disabled`,void 0),e.n([e.u({type:Boolean,reflect:!0,attribute:`fullwidth`})],T.prototype,`fullwidth`,void 0),e.n([e.u({type:String,reflect:!0,attribute:`upload-strategy`})],T.prototype,`uploadStrategy`,void 0),e.n([e.u({type:String,reflect:!0,attribute:`item-renderer`})],T.prototype,`itemRenderer`,void 0),e.n([e.u({type:String})],T.prototype,`accept`,void 0),e.n([e.u({converter:i.t.csvToArray,attribute:`allowed-formats`})],T.prototype,`allowedFormats`,void 0),e.n([e.u({type:String,attribute:`format-error-message`})],T.prototype,`formatErrorMessage`,void 0),e.n([e.u({attribute:`max-file-size`})],T.prototype,`maxFileSize`,void 0),e.n([e.u({type:String,attribute:`size-error-message`})],T.prototype,`sizeErrorMessage`,void 0),e.n([e.u({attribute:!1})],T.prototype,`onFileValidation`,void 0),e.n([e.u({attribute:!1})],T.prototype,`transfers`,void 0),e.n([e.u({type:Boolean,attribute:`add-comments-enabled`})],T.prototype,`addCommentsEnabled`,void 0),e.n([e.u({type:Boolean,attribute:`rename-files-enabled`})],T.prototype,`renameFilesEnabled`,void 0),e.n([e.u({attribute:!1})],T.prototype,`extraOperations`,void 0),e.n([e.u({type:Boolean,reflect:!0,attribute:`enable-image-preview`})],T.prototype,`enableImagePreview`,void 0),e.n([e.u({type:Boolean,attribute:`has-error`})],T.prototype,`hasError`,void 0),e.n([e.u({type:String,attribute:`error-message`})],T.prototype,`errorMessage`,void 0),e.n([e.u({type:Boolean,attribute:`optional-tag`})],T.prototype,`optionalTag`,void 0),e.n([e.u({type:String,attribute:`optional-text`})],T.prototype,`optionalText`,void 0),e.n([e.u({type:Boolean,attribute:`required-tag`})],T.prototype,`requiredTag`,void 0),e.n([e.u({type:String,attribute:`required-text`})],T.prototype,`requiredText`,void 0),e.n([e.u({type:String,attribute:`tag-text`})],T.prototype,`tagText`,void 0),e.n([e.u({type:Number,attribute:`truncate-tail`})],T.prototype,`truncateTail`,void 0),e.n([e.u({attribute:!1})],T.prototype,`value`,void 0),e.n([e.u({attribute:!1})],T.prototype,`defaultValue`,void 0),e.n([e.l()],T.prototype,`files`,void 0),e.n([e.l()],T.prototype,`isDragActive`,void 0),e.n([e.l()],T.prototype,`validationErrorMessage`,void 0),e.n([e.l()],T.prototype,`addedAnnouncement`,void 0),e.n([e.l()],T.prototype,`thumbnailUrls`,void 0);var E=`comments`,D=(e,t)=>{let r=new Date(e);if(Number.isNaN(r.getTime()))return e;let i=String(r.getDate()).padStart(2,`0`),a=String(r.getMonth()+1).padStart(2,`0`),o=r.getFullYear(),s=String(r.getHours()).padStart(2,`0`),c=String(r.getMinutes()).padStart(2,`0`);return n.t(t.commentTimestamp,{date:`${i}.${a}.${o}`,time:`${s}:${c}`})},O=(e,t,n)=>{e.key===`Enter`&&(e.preventDefault(),e.stopPropagation(),t()),e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),n())},k=(e,t,n)=>{e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),n()),(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&(e.preventDefault(),e.stopPropagation(),t())},A=(e,t)=>({id:`remove`,title:t.remove,ariaLabel:t.removeFile,onClick:({file:t})=>e(t.fileId)}),j=t=>({id:`rename`,title:t.rename,ariaLabel:t.renameFile,renderInlineUI:n=>{let r=n.getAttribute(`targetFilename`)||n.file.attributes?.targetFilename||n.file.file?.name||``,i=`pkt-fileupload-rename-${n.file.fileId}`,a=()=>{let e=document.getElementById(i)?.value?.trim();e&&n.setAttribute(`targetFilename`,e),n.close()};return e._`
2
2
  <label for=${i} class="pkt-sr-only">${t.renameInputLabel}</label>
3
3
  <input
4
4
  id=${i}
@@ -2,9 +2,11 @@ import { _ as e, d as t, h as n, l as r, n as i, u as a } from "./element-DBugHP
2
2
  import { t as o } from "./class-map-Bf-QzUpN.js";
3
3
  import { i as s, t as c } from "./element-with-slot-CVmm0_IE.js";
4
4
  import "./icon-Bao96Zb8.js";
5
- import { n as l, t as u } from "./ref-y_5qv9vU.js";
6
- import { n as d, t as f } from "./scroll-lock-BALd8hF9.js";
7
- var p = {
5
+ import { t as l } from "./if-defined-O59_I-e-.js";
6
+ import { n as u, t as d } from "./ref-y_5qv9vU.js";
7
+ import { n as f } from "./utils-BwF4QSrq.js";
8
+ import { n as p, t as m } from "./scroll-lock-BALd8hF9.js";
9
+ var h = {
8
10
  name: "pkt-modal",
9
11
  react: "PktModal",
10
12
  "css-class": "pkt-modal",
@@ -28,6 +30,18 @@ var p = {
28
30
  type: "string",
29
31
  category: "contents"
30
32
  },
33
+ headingIconName: {
34
+ name: "Ikon i overskriften",
35
+ description: "Navn på ikonet som vises foran overskriften. Vises bare når headingText er satt.",
36
+ type: "icon",
37
+ category: "ui"
38
+ },
39
+ headingIconPath: {
40
+ name: "Ikon-sti for overskriften",
41
+ description: "Overstyr stien til ikonet i overskriften. Kan også settes globalt med window.pktIconPath.",
42
+ type: "string",
43
+ category: "tech"
44
+ },
31
45
  hideCloseButton: {
32
46
  name: "Gjem 'Lukk'-knapp",
33
47
  description: "Gjemmer lukkeknappen. Dersom denne er satt til true, vil ikke lukkeknappen vises, og dermed er det viktig at man tilbyr en annen måte som f.eks. en knapp for å lukke modalen på.",
@@ -91,11 +105,11 @@ var p = {
91
105
  }
92
106
  },
93
107
  slots: { default: { description: "Innholdet i meldingen. Her tilbyr vi støtteklasser for å style 1-3 knapper i modalen." } }
94
- }, m = class extends c {
108
+ }, g = class extends c {
95
109
  constructor() {
96
- super(), this.open = !1, this.headingText = "", this.removePadding = !1, this.hideCloseButton = p.props.hideCloseButton.default, this.closeOnBackdropClick = p.props.closeOnBackdropClick.default, this.closeButtonSkin = "blue", this.size = p.props.size.default, this.variant = "dialog", this.drawerPosition = "right", this.transparentBackdrop = !1, this.dialogRef = u(), this._scrollLockToken = f(), this._isOpen = !1, this.close = (e, t = !1) => {
110
+ super(), this.open = !1, this.headingText = "", this.removePadding = !1, this.hideCloseButton = h.props.hideCloseButton.default, this.closeOnBackdropClick = h.props.closeOnBackdropClick.default, this.closeButtonSkin = "blue", this.size = h.props.size.default, this.variant = "dialog", this.drawerPosition = "right", this.transparentBackdrop = !1, this.dialogRef = d(), this._scrollLockToken = m(), this._idSuffix = f(), this._headingId = `pkt-modal__headingText-${this._idSuffix}`, this._contentId = `pkt-modal__content-${this._idSuffix}`, this._isOpen = !1, this.close = (e, t = !1) => {
97
111
  if (!this._isOpen) return;
98
- this._isOpen = !1, this.open = !1, d(this._scrollLockToken, !1);
112
+ this._isOpen = !1, this.open = !1, p(this._scrollLockToken, !1);
99
113
  let n = document.activeElement;
100
114
  n && !this.isElementInViewport(n) && n.scrollIntoView({
101
115
  behavior: "smooth",
@@ -106,7 +120,7 @@ var p = {
106
120
  composed: !0
107
121
  })), t || this.dialogRef.value?.close(), this.requestUpdate();
108
122
  }, this.showModal = (e = null) => {
109
- this._isOpen = !0, this.open = !0, this.dialogRef.value?.showModal(), d(this._scrollLockToken, !0), this.dispatchEvent(new CustomEvent("showModal", {
123
+ this._isOpen = !0, this.open = !0, this.dialogRef.value?.showModal(), p(this._scrollLockToken, !0), this.dispatchEvent(new CustomEvent("showModal", {
110
124
  detail: { origin: e },
111
125
  bubbles: !0,
112
126
  composed: !0
@@ -117,7 +131,7 @@ var p = {
117
131
  super.connectedCallback(), document.addEventListener("keydown", this.handleKeyDown.bind(this)), document.addEventListener("click", this.handleBackdropClick.bind(this));
118
132
  }
119
133
  disconnectedCallback() {
120
- super.disconnectedCallback(), document.removeEventListener("keydown", this.handleKeyDown), document.removeEventListener("click", this.handleBackdropClick), d(this._scrollLockToken, !1);
134
+ super.disconnectedCallback(), document.removeEventListener("keydown", this.handleKeyDown), document.removeEventListener("click", this.handleBackdropClick), p(this._scrollLockToken, !1);
121
135
  }
122
136
  updated(e) {
123
137
  super.updated(e), e.has("open") && (this.open && !this._isOpen ? this.showModal() : !this.open && this._isOpen && this.close(new Event("close"), !1));
@@ -149,43 +163,48 @@ var p = {
149
163
  [`pkt-modal__drawer--${this.drawerPosition}`]: this.variant === "drawer"
150
164
  }, r = {
151
165
  "pkt-modal__headingText": !0,
152
- "pkt-txt-24": !0
153
- }, i = {
166
+ "pkt-txt-24": !0,
167
+ "pkt-modal__headingText--hasIcon": !!this.headingIconName
168
+ }, i = this.headingIconName ? e`<pkt-icon
169
+ class="pkt-modal__headingIcon"
170
+ name=${this.headingIconName}
171
+ path=${l(this.headingIconPath)}
172
+ ></pkt-icon>` : n, a = {
154
173
  "pkt-modal__content": !0,
155
174
  "pkt-txt-18-light": !0
156
- }, a = this.closeButtonSkin === "blue", c = {
175
+ }, c = this.closeButtonSkin === "blue", d = {
157
176
  "pkt-modal__closeButton": !0,
158
177
  [`pkt-modal__closeButton--${this.closeButtonSkin}`]: !0
159
178
  };
160
179
  return e`
161
180
  <dialog
162
181
  class=${o(t)}
163
- ${l(this.dialogRef)}
164
- aria-labelledby=${this.headingText ? "pkt-modal__headingText" : n}
165
- aria-describedby="pkt-modal__content"
182
+ ${u(this.dialogRef)}
183
+ aria-labelledby=${this.headingText ? this._headingId : n}
184
+ aria-describedby=${this._contentId}
166
185
  @close=${(e) => this.close(e, !0)}
167
186
  >
168
187
  <div class="pkt-modal__wrapper">
169
188
  ${this.headingText || !this.hideCloseButton ? e`<div class="pkt-modal__header">
170
189
  <div class="pkt-modal__header-background"></div>
171
- ${this.headingText ? e`<h1 id="pkt-modal__headingText" class=${o(r)}>
172
- ${this.headingText}
190
+ ${this.headingText ? e`<h1 id=${this._headingId} class=${o(r)}>
191
+ ${i}${this.headingText}
173
192
  </h1>` : e`<div class="pkt-modal__headingText"></div>`}
174
- ${this.hideCloseButton ? e`<div class="pkt-modal__noCloseButton"></div>` : e`<div class="${o(c)}">
193
+ ${this.hideCloseButton ? e`<div class="pkt-modal__noCloseButton"></div>` : e`<div class="${o(d)}">
175
194
  <pkt-button
176
195
  @click=${(e) => this.close(e)}
177
196
  aria-label=${this.pktStrings.get("generic").close}
178
197
  iconname="close"
179
198
  variant="icon-only"
180
199
  size="medium"
181
- skin=${a ? "tertiary" : "primary"}
200
+ skin=${c ? "tertiary" : "primary"}
182
201
  >
183
202
  ${this.pktStrings.get("generic").close}
184
203
  </pkt-button>
185
204
  </div>`}
186
205
  </div>` : n}
187
206
  <div class="pkt-modal__container">
188
- <div id="pkt-modal__content" class=${o(i)}>
207
+ <div id=${this._contentId} class=${o(a)}>
189
208
  ${s(this)}
190
209
  </div>
191
210
  </div>
@@ -197,14 +216,14 @@ var p = {
197
216
  i([a({
198
217
  type: Boolean,
199
218
  reflect: !0
200
- })], m.prototype, "open", void 0), i([a({ type: String })], m.prototype, "headingText", void 0), i([a({ type: Boolean })], m.prototype, "removePadding", void 0), i([a({ type: Boolean })], m.prototype, "hideCloseButton", void 0), i([a({ type: Boolean })], m.prototype, "closeOnBackdropClick", void 0), i([a({ type: String })], m.prototype, "closeButtonSkin", void 0), i([a({ type: String })], m.prototype, "size", void 0), i([a({ type: String })], m.prototype, "variant", void 0), i([a({ type: String })], m.prototype, "drawerPosition", void 0), i([a({ type: Boolean })], m.prototype, "transparentBackdrop", void 0), i([r()], m.prototype, "_isOpen", void 0);
219
+ })], g.prototype, "open", void 0), i([a({ type: String })], g.prototype, "headingText", void 0), i([a({ type: String })], g.prototype, "headingIconName", void 0), i([a({ type: String })], g.prototype, "headingIconPath", void 0), i([a({ type: Boolean })], g.prototype, "removePadding", void 0), i([a({ type: Boolean })], g.prototype, "hideCloseButton", void 0), i([a({ type: Boolean })], g.prototype, "closeOnBackdropClick", void 0), i([a({ type: String })], g.prototype, "closeButtonSkin", void 0), i([a({ type: String })], g.prototype, "size", void 0), i([a({ type: String })], g.prototype, "variant", void 0), i([a({ type: String })], g.prototype, "drawerPosition", void 0), i([a({ type: Boolean })], g.prototype, "transparentBackdrop", void 0), i([r()], g.prototype, "_isOpen", void 0);
201
220
  try {
202
- t("pkt-modal")(m);
221
+ t("pkt-modal")(g);
203
222
  } catch {
204
223
  console.warn("Forsøker å definere <pkt-modal>, men den er allerede definert");
205
224
  }
206
225
  //#endregion
207
226
  //#region src/components/modal/index.ts
208
- var h = m;
227
+ var _ = g;
209
228
  //#endregion
210
- export { m as n, h as t };
229
+ export { g as n, _ as t };
@@ -0,0 +1,39 @@
1
+ const e=require("./element-C6WTyJFE.cjs"),t=require("./class-map-Bh6toDeV.cjs"),n=require("./element-with-slot-CcJPCLgn.cjs");require("./icon-jPhyZD1z.cjs");const r=require("./if-defined-CiML3MTM.cjs"),i=require("./ref-CB7e9nMY.cjs"),a=require("./utils-63cRpWut.cjs"),o=require("./scroll-lock-B46ur0FF.cjs");var s={name:`pkt-modal`,react:`PktModal`,"css-class":`pkt-modal`,isElement:!0,isPureReact:!0,events:{"background-click":{description:`Event som trigges når bakgrunnen trykkes på`},close:{description:`Event som trigges når meldingsboksen lukkes`}},props:{open:{name:`Åpen`,description:`Deklarativ styring av modalens åpen/lukket-tilstand. Kan brukes i stedet for showModal()/close()-metodene.`,type:`boolean`,category:`tech`,default:!1},headingText:{name:`Heading text`,description:`Heading tekst på modalen`,type:`string`,category:`contents`},headingIconName:{name:`Ikon i overskriften`,description:`Navn på ikonet som vises foran overskriften. Vises bare når headingText er satt.`,type:`icon`,category:`ui`},headingIconPath:{name:`Ikon-sti for overskriften`,description:`Overstyr stien til ikonet i overskriften. Kan også settes globalt med window.pktIconPath.`,type:`string`,category:`tech`},hideCloseButton:{name:`Gjem 'Lukk'-knapp`,description:`Gjemmer lukkeknappen. Dersom denne er satt til true, vil ikke lukkeknappen vises, og dermed er det viktig at man tilbyr en annen måte som f.eks. en knapp for å lukke modalen på.`,type:`boolean`,category:`ui`,default:!1},closeOnBackdropClick:{name:`Lukk modalen når bakgrunnen trykkes på`,description:`Lukk modalen når bakgrunnen trykkes på`,type:`boolean`,category:`tech`,default:!1},closeButtonSkin:{name:`Stil på lukkeknappen`,description:`Stil på lukkeknappen`,type:[`blue`,`yellow-filled`],category:`ui`,default:`blue`},size:{name:`Størrelse`,description:`Størrelsen på modalen`,type:[`small`,`medium`,`large`,`fit-content`],category:`ui`,default:`medium`},variant:{name:`Variant`,description:`Standard dialog eller skuff`,type:[`dialog`,`drawer`],category:`ui`,default:`dialog`},drawerPosition:{name:`Skuffposisjon`,description:`Posisjonen til skuffen`,type:[`left`,`right`],category:`ui`,default:`right`},transparentBackdrop:{name:`Gjennomsiktig bakgrunn`,description:`Bakgrunnen er gjennomsiktig`,type:`boolean`,category:`ui`,default:!1},removePadding:{name:`Fjern padding`,description:`Fjerner paddingen rundt innholdet i modalen`,type:`boolean`,category:`ui`,default:!1}},slots:{default:{description:`Innholdet i meldingen. Her tilbyr vi støtteklasser for å style 1-3 knapper i modalen.`}}},c=class extends n.t{constructor(){super(),this.open=!1,this.headingText=``,this.removePadding=!1,this.hideCloseButton=s.props.hideCloseButton.default,this.closeOnBackdropClick=s.props.closeOnBackdropClick.default,this.closeButtonSkin=`blue`,this.size=s.props.size.default,this.variant=`dialog`,this.drawerPosition=`right`,this.transparentBackdrop=!1,this.dialogRef=i.t(),this._scrollLockToken=o.t(),this._idSuffix=a.n(),this._headingId=`pkt-modal__headingText-${this._idSuffix}`,this._contentId=`pkt-modal__content-${this._idSuffix}`,this._isOpen=!1,this.close=(e,t=!1)=>{if(!this._isOpen)return;this._isOpen=!1,this.open=!1,o.n(this._scrollLockToken,!1);let n=document.activeElement;n&&!this.isElementInViewport(n)&&n.scrollIntoView({behavior:`smooth`,block:`nearest`}),this.dispatchEvent(new CustomEvent(`close`,{detail:{origin:e},bubbles:!0,composed:!0})),t||this.dialogRef.value?.close(),this.requestUpdate()},this.showModal=(e=null)=>{this._isOpen=!0,this.open=!0,this.dialogRef.value?.showModal(),o.n(this._scrollLockToken,!0),this.dispatchEvent(new CustomEvent(`showModal`,{detail:{origin:e},bubbles:!0,composed:!0})),this.requestUpdate()},this._isOpen=!1}async connectedCallback(){super.connectedCallback(),document.addEventListener(`keydown`,this.handleKeyDown.bind(this)),document.addEventListener(`click`,this.handleBackdropClick.bind(this))}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(`keydown`,this.handleKeyDown),document.removeEventListener(`click`,this.handleBackdropClick),o.n(this._scrollLockToken,!1)}updated(e){super.updated(e),e.has(`open`)&&(this.open&&!this._isOpen?this.showModal():!this.open&&this._isOpen&&this.close(new Event(`close`),!1))}async firstUpdated(e){super.firstUpdated(e),this.dialogRef.value&&!window.HTMLDialogElement&&!this.dialogRef.value.showModal&&(`document`in window&&`createElement`in document&&(await Promise.resolve().then(()=>require("./dialog-polyfill.esm-B-g35ove.cjs")).then(e=>e.default)).registerDialog(this.dialogRef.value),this.dialogRef.value.addEventListener(`close`,()=>{this.close(new Event(`close`),!0)}))}handleKeyDown(e){e.key===`Escape`&&this.close(e)}handleBackdropClick(e){this.closeOnBackdropClick&&e.target===this.dialogRef?.value&&this.close(e)}isElementInViewport(e){let t=e.getBoundingClientRect();return t.top>=0&&t.left>=0&&t.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&t.right<=(window.innerWidth||document.documentElement.clientWidth)}render(){let a={"pkt-modal":!0,"pkt-modal--removePadding":this.removePadding??!1,"pkt-modal--noHeadingText":this.headingText===``||this.headingText===void 0,"pkt-modal--noShadow":this.closeButtonSkin===`yellow-filled`,"pkt-modal--transparentBackdrop":this.transparentBackdrop??!1,[`pkt-modal--${this.size}`]:this.size!==void 0,[`pkt-modal__${this.variant}`]:this.variant!==void 0,[`pkt-modal__drawer--${this.drawerPosition}`]:this.variant===`drawer`},o={"pkt-modal__headingText":!0,"pkt-txt-24":!0,"pkt-modal__headingText--hasIcon":!!this.headingIconName},s=this.headingIconName?e._`<pkt-icon
2
+ class="pkt-modal__headingIcon"
3
+ name=${this.headingIconName}
4
+ path=${r.t(this.headingIconPath)}
5
+ ></pkt-icon>`:e.h,c={"pkt-modal__content":!0,"pkt-txt-18-light":!0},l=this.closeButtonSkin===`blue`,u={"pkt-modal__closeButton":!0,[`pkt-modal__closeButton--${this.closeButtonSkin}`]:!0};return e._`
6
+ <dialog
7
+ class=${t.t(a)}
8
+ ${i.n(this.dialogRef)}
9
+ aria-labelledby=${this.headingText?this._headingId:e.h}
10
+ aria-describedby=${this._contentId}
11
+ @close=${e=>this.close(e,!0)}
12
+ >
13
+ <div class="pkt-modal__wrapper">
14
+ ${this.headingText||!this.hideCloseButton?e._`<div class="pkt-modal__header">
15
+ <div class="pkt-modal__header-background"></div>
16
+ ${this.headingText?e._`<h1 id=${this._headingId} class=${t.t(o)}>
17
+ ${s}${this.headingText}
18
+ </h1>`:e._`<div class="pkt-modal__headingText"></div>`}
19
+ ${this.hideCloseButton?e._`<div class="pkt-modal__noCloseButton"></div>`:e._`<div class="${t.t(u)}">
20
+ <pkt-button
21
+ @click=${e=>this.close(e)}
22
+ aria-label=${this.pktStrings.get(`generic`).close}
23
+ iconname="close"
24
+ variant="icon-only"
25
+ size="medium"
26
+ skin=${l?`tertiary`:`primary`}
27
+ >
28
+ ${this.pktStrings.get(`generic`).close}
29
+ </pkt-button>
30
+ </div>`}
31
+ </div>`:e.h}
32
+ <div class="pkt-modal__container">
33
+ <div id=${this._contentId} class=${t.t(c)}>
34
+ ${n.i(this)}
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </dialog>
39
+ `}};e.n([e.u({type:Boolean,reflect:!0})],c.prototype,`open`,void 0),e.n([e.u({type:String})],c.prototype,`headingText`,void 0),e.n([e.u({type:String})],c.prototype,`headingIconName`,void 0),e.n([e.u({type:String})],c.prototype,`headingIconPath`,void 0),e.n([e.u({type:Boolean})],c.prototype,`removePadding`,void 0),e.n([e.u({type:Boolean})],c.prototype,`hideCloseButton`,void 0),e.n([e.u({type:Boolean})],c.prototype,`closeOnBackdropClick`,void 0),e.n([e.u({type:String})],c.prototype,`closeButtonSkin`,void 0),e.n([e.u({type:String})],c.prototype,`size`,void 0),e.n([e.u({type:String})],c.prototype,`variant`,void 0),e.n([e.u({type:String})],c.prototype,`drawerPosition`,void 0),e.n([e.u({type:Boolean})],c.prototype,`transparentBackdrop`,void 0),e.n([e.l()],c.prototype,`_isOpen`,void 0);try{e.d(`pkt-modal`)(c)}catch{console.warn(`Forsøker å definere <pkt-modal>, men den er allerede definert`)}var l=c;Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return l}});
@@ -1 +1 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./fileupload-CyLRyoVU.cjs");Object.defineProperty(exports,"PktFileUpload",{enumerable:!0,get:function(){return e.n}}),exports.default=e.t;
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./fileupload-CnjtgTlF.cjs");Object.defineProperty(exports,"PktFileUpload",{enumerable:!0,get:function(){return e.n}}),exports.default=e.t;
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./fileupload-BmfFC748.js";
1
+ import { n as e, t } from "./fileupload-BKk03Dq-.js";
2
2
  export { e as PktFileUpload, t as default };
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./element-C6WTyJFE.cjs"),t=require("./consent-DBYZaCTp.cjs"),n=require("./alert-CuXM6TnC.cjs"),r=require("./header-BCrefip0.cjs"),i=require("./card-Diivw_vm.cjs"),a=require("./checkbox-BwI9QNSh.cjs"),o=require("./radiobutton-DwDErNo5.cjs"),s=require("./icon-jPhyZD1z.cjs"),c=require("./accordion-DukAa2ED.cjs"),l=require("./messagebox-CR59jv8N.cjs"),u=require("./calendar-C5QwPrbk.cjs"),d=require("./combobox-jsPpImVF.cjs"),f=require("./button-BFG-7bDB.cjs"),p=require("./backlink-CsFeerTH.cjs"),m=require("./breadcrumbs-D03id_ha.cjs"),h=require("./tag-BMtnaJ1A.cjs"),g=require("./input-wrapper-BwzajfFX.cjs"),_=require("./helptext-Bdv80rcs.cjs"),v=require("./checkbox-group-adbFTj8y.cjs"),y=require("./fileupload-CyLRyoVU.cjs"),b=require("./modal-BKeSXrzi.cjs"),x=require("./progressbar-CnX4fFfR.cjs"),S=require("./datepicker-CZYpIyJd.cjs"),C=require("./footer-C6ajmlq2.cjs"),w=require("./link-CRLAhYi0.cjs"),T=require("./textinput-BqBgsBZF.cjs"),E=require("./searchinput-Mdc9Ihld.cjs"),D=require("./header-menu-Cz7G7Q2R.cjs"),O=require("./heading-BluavR6A.cjs"),k=require("./linkcard-DnZgMzqL.cjs"),A=require("./loader-Zo_VSsNw.cjs"),j=require("./radio-group-MxNLGu-0.cjs"),M=require("./tabs-R1Jzzj3-.cjs"),N=require("./textarea-C-sdNBRk.cjs"),P=require("./select-Czz1y2nI.cjs"),F=require("./timepicker-C_k-K1jA.cjs");exports.PktAccordion=c.r,exports.PktAccordionItem=c.n,exports.PktAlert=n.n,exports.PktBackLink=p.n,exports.PktBreadcrumbs=m.t,exports.PktButton=f.n,exports.PktCalendar=u.n,exports.PktCard=i.n,exports.PktCheckbox=a.n,exports.PktCheckboxGroup=v.n,exports.PktCombobox=d.n,exports.PktConsent=t.n,exports.PktDateTags=S.a,exports.PktDatepicker=S.t,Object.defineProperty(exports,"PktFileUpload",{enumerable:!0,get:function(){return y.n}}),exports.PktFooter=C.n,exports.PktFooterSimple=C.t,exports.PktHeader=r.t,exports.PktHeaderGlobal=r.n,exports.PktHeaderMenu=D.n,exports.PktHeaderService=r.r,exports.PktHeaderUserMenu=r.i,exports.PktHeading=O.n,exports.PktHelptext=_.n,exports.PktIcon=s.n,exports.PktInputWrapper=g.n,exports.PktLink=w.n,exports.PktLinkCard=k.n,exports.PktLoader=A.n,exports.PktMessagebox=l.n,exports.PktModal=b.n,exports.PktProgressbar=x.n,exports.PktRadioButton=o.n,exports.PktRadiobutton=o.n,exports.PktRadioGroup=j.n,exports.PktSearchInput=E.n,exports.PktSelect=P.n,exports.PktTabItem=M.n,exports.PktTabs=M.r,exports.PktTag=h.n,exports.PktTextarea=N.n,exports.PktTextinput=T.n,exports.PktTimepicker=F.t,exports.getPktStrings=e.r,exports.pktStringsNb=e.s,exports.resetPktStrings=e.i,exports.setPktStrings=e.a,exports.subscribePktStrings=e.o;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./element-C6WTyJFE.cjs"),t=require("./consent-DBYZaCTp.cjs"),n=require("./alert-CuXM6TnC.cjs"),r=require("./header-BCrefip0.cjs"),i=require("./card-Diivw_vm.cjs"),a=require("./checkbox-BwI9QNSh.cjs"),o=require("./radiobutton-DwDErNo5.cjs"),s=require("./icon-jPhyZD1z.cjs"),c=require("./accordion-DukAa2ED.cjs"),l=require("./messagebox-CR59jv8N.cjs"),u=require("./calendar-C5QwPrbk.cjs"),d=require("./combobox-jsPpImVF.cjs"),f=require("./button-BFG-7bDB.cjs"),p=require("./backlink-CsFeerTH.cjs"),m=require("./breadcrumbs-D03id_ha.cjs"),h=require("./tag-BMtnaJ1A.cjs"),g=require("./input-wrapper-BwzajfFX.cjs"),_=require("./helptext-Bdv80rcs.cjs"),v=require("./checkbox-group-adbFTj8y.cjs"),y=require("./fileupload-CnjtgTlF.cjs"),b=require("./modal-wEEmCcUx.cjs"),x=require("./progressbar-CnX4fFfR.cjs"),S=require("./datepicker-CZYpIyJd.cjs"),C=require("./footer-C6ajmlq2.cjs"),w=require("./link-CRLAhYi0.cjs"),T=require("./textinput-BqBgsBZF.cjs"),E=require("./searchinput-Mdc9Ihld.cjs"),D=require("./header-menu-Cz7G7Q2R.cjs"),O=require("./heading-BluavR6A.cjs"),k=require("./linkcard-DnZgMzqL.cjs"),A=require("./loader-Zo_VSsNw.cjs"),j=require("./radio-group-MxNLGu-0.cjs"),M=require("./tabs-R1Jzzj3-.cjs"),N=require("./textarea-C-sdNBRk.cjs"),P=require("./select-Czz1y2nI.cjs"),F=require("./timepicker-C_k-K1jA.cjs");exports.PktAccordion=c.r,exports.PktAccordionItem=c.n,exports.PktAlert=n.n,exports.PktBackLink=p.n,exports.PktBreadcrumbs=m.t,exports.PktButton=f.n,exports.PktCalendar=u.n,exports.PktCard=i.n,exports.PktCheckbox=a.n,exports.PktCheckboxGroup=v.n,exports.PktCombobox=d.n,exports.PktConsent=t.n,exports.PktDateTags=S.a,exports.PktDatepicker=S.t,Object.defineProperty(exports,"PktFileUpload",{enumerable:!0,get:function(){return y.n}}),exports.PktFooter=C.n,exports.PktFooterSimple=C.t,exports.PktHeader=r.t,exports.PktHeaderGlobal=r.n,exports.PktHeaderMenu=D.n,exports.PktHeaderService=r.r,exports.PktHeaderUserMenu=r.i,exports.PktHeading=O.n,exports.PktHelptext=_.n,exports.PktIcon=s.n,exports.PktInputWrapper=g.n,exports.PktLink=w.n,exports.PktLinkCard=k.n,exports.PktLoader=A.n,exports.PktMessagebox=l.n,exports.PktModal=b.n,exports.PktProgressbar=x.n,exports.PktRadioButton=o.n,exports.PktRadiobutton=o.n,exports.PktRadioGroup=j.n,exports.PktSearchInput=E.n,exports.PktSelect=P.n,exports.PktTabItem=M.n,exports.PktTabs=M.r,exports.PktTag=h.n,exports.PktTextarea=N.n,exports.PktTextinput=T.n,exports.PktTimepicker=F.t,exports.getPktStrings=e.r,exports.pktStringsNb=e.s,exports.resetPktStrings=e.i,exports.setPktStrings=e.a,exports.subscribePktStrings=e.o;
package/dist/pkt-index.js CHANGED
@@ -17,8 +17,8 @@ import { n as C } from "./tag-uVXp7uP-.js";
17
17
  import { n as w } from "./input-wrapper-Bb6CZxmg.js";
18
18
  import { n as T } from "./helptext-Dujce_W9.js";
19
19
  import { n as E } from "./checkbox-group-C8mo9dkO.js";
20
- import { n as D } from "./fileupload-BmfFC748.js";
21
- import { n as O } from "./modal-B3CQEBBB.js";
20
+ import { n as D } from "./fileupload-BKk03Dq-.js";
21
+ import { n as O } from "./modal-0D0paY70.js";
22
22
  import { n as k } from "./progressbar-DZHiq7B0.js";
23
23
  import { a as A, t as j } from "./datepicker-CjUY_mLR.js";
24
24
  import { n as M, t as N } from "./footer-L2vhQTAS.js";
@@ -1 +1 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./modal-BKeSXrzi.cjs");exports.PktModal=e.n,exports.default=e.t;
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./modal-wEEmCcUx.cjs");exports.PktModal=e.n,exports.default=e.t;
package/dist/pkt-modal.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./modal-B3CQEBBB.js";
1
+ import { n as e, t } from "./modal-0D0paY70.js";
2
2
  export { e as PktModal, t as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oslokommune/punkt-elements",
3
- "version": "19.14.3",
3
+ "version": "19.15.0",
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": "c81c6cf722332d44ad8590517eb989fc8d46b33d"
87
+ "gitHead": "3d719ef8a2e368d08d6111be152f9a6c1b64da1e"
88
88
  }
@@ -0,0 +1,141 @@
1
+ import '@testing-library/jest-dom'
2
+ import { axe, toHaveNoViolations } from 'jest-axe'
3
+ import { createElementTest, BaseTestConfig } from '../../tests/test-framework'
4
+ import { CustomElementFor } from '../../tests/component-registry'
5
+ import type { IPktModal } from './modal'
6
+ import './modal'
7
+
8
+ expect.extend(toHaveNoViolations)
9
+
10
+ export interface ModalTestConfig extends IPktModal, BaseTestConfig {}
11
+
12
+ export const createModalTest = async (config: ModalTestConfig = {}) => {
13
+ const { container, element } = await createElementTest<
14
+ CustomElementFor<'pkt-modal'>,
15
+ ModalTestConfig
16
+ >('pkt-modal', config)
17
+
18
+ return {
19
+ container,
20
+ modal: element,
21
+ heading: element.querySelector('.pkt-modal__headingText'),
22
+ }
23
+ }
24
+
25
+ afterEach(() => {
26
+ document.body.innerHTML = ''
27
+ })
28
+
29
+ describe('PktModal', () => {
30
+ describe('heading icon', () => {
31
+ test('renders no icon by default', async () => {
32
+ const { heading } = await createModalTest({ headingText: 'Historikk' })
33
+ expect(heading).not.toHaveClass('pkt-modal__headingText--hasIcon')
34
+ expect(heading?.querySelector('pkt-icon')).toBeNull()
35
+ })
36
+
37
+ test('renders the icon before the heading text', async () => {
38
+ const { heading } = await createModalTest({
39
+ headingText: 'Historikk',
40
+ headingIconName: 'clock-history',
41
+ })
42
+ expect(heading).toHaveClass('pkt-modal__headingText--hasIcon')
43
+ const icon = heading?.firstElementChild
44
+ expect(icon?.tagName.toLowerCase()).toBe('pkt-icon')
45
+ expect(icon).toHaveClass('pkt-modal__headingIcon')
46
+ expect(icon).toHaveAttribute('name', 'clock-history')
47
+ expect(heading).toHaveTextContent('Historikk')
48
+ })
49
+
50
+ test('passes headingIconPath to the icon', async () => {
51
+ const customPath = 'https://custom-cdn.example.com/icons/'
52
+ const { modal } = await createModalTest({
53
+ headingText: 'Historikk',
54
+ headingIconName: 'clock-history',
55
+ headingIconPath: customPath,
56
+ })
57
+ expect(modal.headingIconPath).toBe(customPath)
58
+ const icon = modal.querySelector('.pkt-modal__headingIcon')
59
+ expect(icon).toHaveAttribute('path', customPath)
60
+ })
61
+
62
+ test('does not set the path attribute when headingIconPath is not provided', async () => {
63
+ const { modal } = await createModalTest({
64
+ headingText: 'Historikk',
65
+ headingIconName: 'clock-history',
66
+ })
67
+ const icon = modal.querySelector('.pkt-modal__headingIcon')
68
+ expect(icon).not.toHaveAttribute('path')
69
+ })
70
+
71
+ test('does not render the icon without headingText', async () => {
72
+ const { modal } = await createModalTest({ headingIconName: 'clock-history' })
73
+ expect(modal.querySelector('.pkt-modal__headingIcon')).toBeNull()
74
+ })
75
+
76
+ test('updates the icon when headingIconName changes', async () => {
77
+ const { modal } = await createModalTest({
78
+ headingText: 'Historikk',
79
+ headingIconName: 'clock-history',
80
+ })
81
+ modal.headingIconName = 'user'
82
+ await modal.updateComplete
83
+ expect(modal.querySelector('.pkt-modal__headingIcon')).toHaveAttribute('name', 'user')
84
+
85
+ modal.headingIconName = undefined
86
+ await modal.updateComplete
87
+ expect(modal.querySelector('.pkt-modal__headingIcon')).toBeNull()
88
+ expect(modal.querySelector('.pkt-modal__headingText')).not.toHaveClass(
89
+ 'pkt-modal__headingText--hasIcon',
90
+ )
91
+ })
92
+
93
+ test('renders with no wcag errors with axe', async () => {
94
+ const { container } = await createModalTest({
95
+ headingText: 'Historikk',
96
+ headingIconName: 'clock-history',
97
+ })
98
+ const results = await axe(container)
99
+ expect(results).toHaveNoViolations()
100
+ })
101
+ })
102
+
103
+ describe('ids', () => {
104
+ test('labels and describes the dialog with its own heading and content', async () => {
105
+ const { modal } = await createModalTest({ headingText: 'Historikk' })
106
+ const dialog = modal.querySelector('dialog')!
107
+ const heading = modal.querySelector('h1.pkt-modal__headingText')!
108
+ const content = modal.querySelector('.pkt-modal__content')!
109
+ expect(heading.id).toMatch(/^pkt-modal__headingText-/)
110
+ expect(content.id).toMatch(/^pkt-modal__content-/)
111
+ expect(dialog).toHaveAttribute('aria-labelledby', heading.id)
112
+ expect(dialog).toHaveAttribute('aria-describedby', content.id)
113
+ })
114
+
115
+ test('gives each modal on the page unique ids', async () => {
116
+ const { modal: first } = await createModalTest({ headingText: 'Første' })
117
+ const { modal: second } = await createModalTest({ headingText: 'Andre' })
118
+ const firstHeading = first.querySelector('h1')!
119
+ const secondHeading = second.querySelector('h1')!
120
+ expect(firstHeading.id).not.toBe(secondHeading.id)
121
+ expect(first.querySelector('dialog')).toHaveAttribute('aria-labelledby', firstHeading.id)
122
+ expect(second.querySelector('dialog')).toHaveAttribute('aria-labelledby', secondHeading.id)
123
+ expect(first.querySelector('dialog')!.getAttribute('aria-describedby')).not.toBe(
124
+ second.querySelector('dialog')!.getAttribute('aria-describedby'),
125
+ )
126
+ })
127
+
128
+ test('keeps the ids stable across re-renders', async () => {
129
+ const { modal } = await createModalTest({ headingText: 'Historikk' })
130
+ const before = modal.querySelector('h1')!.id
131
+ modal.headingText = 'Endret'
132
+ await modal.updateComplete
133
+ expect(modal.querySelector('h1')!.id).toBe(before)
134
+ })
135
+
136
+ test('omits aria-labelledby without headingText', async () => {
137
+ const { modal } = await createModalTest()
138
+ expect(modal.querySelector('dialog')).not.toHaveAttribute('aria-labelledby')
139
+ })
140
+ })
141
+ })
@@ -1,4 +1,5 @@
1
1
  import { classMap } from 'lit/directives/class-map.js'
2
+ import { ifDefined } from 'lit/directives/if-defined.js'
2
3
  import { customElement, property, state } from 'lit/decorators.js'
3
4
  import { html, nothing, PropertyValues } from 'lit'
4
5
  import { PktElementWithSlot } from '@/base-elements/element-with-slot'
@@ -11,6 +12,7 @@ import {
11
12
  setScrollLock,
12
13
  type ScrollLockToken,
13
14
  } from 'shared-utils/scroll-lock'
15
+ import { uuidish } from 'shared-utils/utils'
14
16
  import specs from 'componentSpecs/modal.json'
15
17
  import '@/components/icon'
16
18
 
@@ -19,6 +21,8 @@ type ModalSize = TPktSize | 'fit-content'
19
21
  export interface IPktModal {
20
22
  open?: boolean
21
23
  headingText?: string
24
+ headingIconName?: string
25
+ headingIconPath?: string
22
26
  removePadding?: boolean
23
27
  hideCloseButton?: boolean
24
28
  closeOnBackdropClick?: boolean
@@ -33,6 +37,8 @@ export class PktModal extends PktElementWithSlot implements IPktModal {
33
37
  // Public properties
34
38
  @property({ type: Boolean, reflect: true }) open?: boolean = false
35
39
  @property({ type: String }) headingText?: string = ''
40
+ @property({ type: String }) headingIconName?: string
41
+ @property({ type: String }) headingIconPath?: string
36
42
  @property({ type: Boolean }) removePadding?: boolean = false
37
43
  @property({ type: Boolean }) hideCloseButton?: boolean = specs.props.hideCloseButton.default
38
44
  @property({ type: Boolean })
@@ -47,6 +53,10 @@ export class PktModal extends PktElementWithSlot implements IPktModal {
47
53
 
48
54
  private _scrollLockToken: ScrollLockToken = createScrollLockToken()
49
55
 
56
+ private readonly _idSuffix = uuidish()
57
+ private readonly _headingId = `pkt-modal__headingText-${this._idSuffix}`
58
+ private readonly _contentId = `pkt-modal__content-${this._idSuffix}`
59
+
50
60
  @state() _isOpen: boolean = false
51
61
 
52
62
  constructor() {
@@ -164,8 +174,17 @@ export class PktModal extends PktElementWithSlot implements IPktModal {
164
174
  const headingClasses = {
165
175
  'pkt-modal__headingText': true,
166
176
  'pkt-txt-24': true,
177
+ 'pkt-modal__headingText--hasIcon': !!this.headingIconName,
167
178
  }
168
179
 
180
+ const headingIcon = this.headingIconName
181
+ ? html`<pkt-icon
182
+ class="pkt-modal__headingIcon"
183
+ name=${this.headingIconName}
184
+ path=${ifDefined(this.headingIconPath)}
185
+ ></pkt-icon>`
186
+ : nothing
187
+
169
188
  const contentClasses = {
170
189
  'pkt-modal__content': true,
171
190
  'pkt-txt-18-light': true,
@@ -181,8 +200,8 @@ export class PktModal extends PktElementWithSlot implements IPktModal {
181
200
  <dialog
182
201
  class=${classMap(classes)}
183
202
  ${ref(this.dialogRef)}
184
- aria-labelledby=${this.headingText ? 'pkt-modal__headingText' : nothing}
185
- aria-describedby="pkt-modal__content"
203
+ aria-labelledby=${this.headingText ? this._headingId : nothing}
204
+ aria-describedby=${this._contentId}
186
205
  @close=${(event: Event) => this.close(event, true)}
187
206
  >
188
207
  <div class="pkt-modal__wrapper">
@@ -190,8 +209,8 @@ export class PktModal extends PktElementWithSlot implements IPktModal {
190
209
  ? html`<div class="pkt-modal__header">
191
210
  <div class="pkt-modal__header-background"></div>
192
211
  ${this.headingText
193
- ? html`<h1 id="pkt-modal__headingText" class=${classMap(headingClasses)}>
194
- ${this.headingText}
212
+ ? html`<h1 id=${this._headingId} class=${classMap(headingClasses)}>
213
+ ${headingIcon}${this.headingText}
195
214
  </h1>`
196
215
  : html`<div class="pkt-modal__headingText"></div>`}
197
216
  ${!this.hideCloseButton
@@ -211,7 +230,7 @@ export class PktModal extends PktElementWithSlot implements IPktModal {
211
230
  </div>`
212
231
  : nothing}
213
232
  <div class="pkt-modal__container">
214
- <div id="pkt-modal__content" class=${classMap(contentClasses)}>
233
+ <div id=${this._contentId} class=${classMap(contentClasses)}>
215
234
  ${slotContent(this)}
216
235
  </div>
217
236
  </div>
@@ -1,35 +0,0 @@
1
- const e=require("./element-C6WTyJFE.cjs"),t=require("./class-map-Bh6toDeV.cjs"),n=require("./element-with-slot-CcJPCLgn.cjs");require("./icon-jPhyZD1z.cjs");const r=require("./ref-CB7e9nMY.cjs"),i=require("./scroll-lock-B46ur0FF.cjs");var a={name:`pkt-modal`,react:`PktModal`,"css-class":`pkt-modal`,isElement:!0,isPureReact:!0,events:{"background-click":{description:`Event som trigges når bakgrunnen trykkes på`},close:{description:`Event som trigges når meldingsboksen lukkes`}},props:{open:{name:`Åpen`,description:`Deklarativ styring av modalens åpen/lukket-tilstand. Kan brukes i stedet for showModal()/close()-metodene.`,type:`boolean`,category:`tech`,default:!1},headingText:{name:`Heading text`,description:`Heading tekst på modalen`,type:`string`,category:`contents`},hideCloseButton:{name:`Gjem 'Lukk'-knapp`,description:`Gjemmer lukkeknappen. Dersom denne er satt til true, vil ikke lukkeknappen vises, og dermed er det viktig at man tilbyr en annen måte som f.eks. en knapp for å lukke modalen på.`,type:`boolean`,category:`ui`,default:!1},closeOnBackdropClick:{name:`Lukk modalen når bakgrunnen trykkes på`,description:`Lukk modalen når bakgrunnen trykkes på`,type:`boolean`,category:`tech`,default:!1},closeButtonSkin:{name:`Stil på lukkeknappen`,description:`Stil på lukkeknappen`,type:[`blue`,`yellow-filled`],category:`ui`,default:`blue`},size:{name:`Størrelse`,description:`Størrelsen på modalen`,type:[`small`,`medium`,`large`,`fit-content`],category:`ui`,default:`medium`},variant:{name:`Variant`,description:`Standard dialog eller skuff`,type:[`dialog`,`drawer`],category:`ui`,default:`dialog`},drawerPosition:{name:`Skuffposisjon`,description:`Posisjonen til skuffen`,type:[`left`,`right`],category:`ui`,default:`right`},transparentBackdrop:{name:`Gjennomsiktig bakgrunn`,description:`Bakgrunnen er gjennomsiktig`,type:`boolean`,category:`ui`,default:!1},removePadding:{name:`Fjern padding`,description:`Fjerner paddingen rundt innholdet i modalen`,type:`boolean`,category:`ui`,default:!1}},slots:{default:{description:`Innholdet i meldingen. Her tilbyr vi støtteklasser for å style 1-3 knapper i modalen.`}}},o=class extends n.t{constructor(){super(),this.open=!1,this.headingText=``,this.removePadding=!1,this.hideCloseButton=a.props.hideCloseButton.default,this.closeOnBackdropClick=a.props.closeOnBackdropClick.default,this.closeButtonSkin=`blue`,this.size=a.props.size.default,this.variant=`dialog`,this.drawerPosition=`right`,this.transparentBackdrop=!1,this.dialogRef=r.t(),this._scrollLockToken=i.t(),this._isOpen=!1,this.close=(e,t=!1)=>{if(!this._isOpen)return;this._isOpen=!1,this.open=!1,i.n(this._scrollLockToken,!1);let n=document.activeElement;n&&!this.isElementInViewport(n)&&n.scrollIntoView({behavior:`smooth`,block:`nearest`}),this.dispatchEvent(new CustomEvent(`close`,{detail:{origin:e},bubbles:!0,composed:!0})),t||this.dialogRef.value?.close(),this.requestUpdate()},this.showModal=(e=null)=>{this._isOpen=!0,this.open=!0,this.dialogRef.value?.showModal(),i.n(this._scrollLockToken,!0),this.dispatchEvent(new CustomEvent(`showModal`,{detail:{origin:e},bubbles:!0,composed:!0})),this.requestUpdate()},this._isOpen=!1}async connectedCallback(){super.connectedCallback(),document.addEventListener(`keydown`,this.handleKeyDown.bind(this)),document.addEventListener(`click`,this.handleBackdropClick.bind(this))}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(`keydown`,this.handleKeyDown),document.removeEventListener(`click`,this.handleBackdropClick),i.n(this._scrollLockToken,!1)}updated(e){super.updated(e),e.has(`open`)&&(this.open&&!this._isOpen?this.showModal():!this.open&&this._isOpen&&this.close(new Event(`close`),!1))}async firstUpdated(e){super.firstUpdated(e),this.dialogRef.value&&!window.HTMLDialogElement&&!this.dialogRef.value.showModal&&(`document`in window&&`createElement`in document&&(await Promise.resolve().then(()=>require("./dialog-polyfill.esm-B-g35ove.cjs")).then(e=>e.default)).registerDialog(this.dialogRef.value),this.dialogRef.value.addEventListener(`close`,()=>{this.close(new Event(`close`),!0)}))}handleKeyDown(e){e.key===`Escape`&&this.close(e)}handleBackdropClick(e){this.closeOnBackdropClick&&e.target===this.dialogRef?.value&&this.close(e)}isElementInViewport(e){let t=e.getBoundingClientRect();return t.top>=0&&t.left>=0&&t.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&t.right<=(window.innerWidth||document.documentElement.clientWidth)}render(){let i={"pkt-modal":!0,"pkt-modal--removePadding":this.removePadding??!1,"pkt-modal--noHeadingText":this.headingText===``||this.headingText===void 0,"pkt-modal--noShadow":this.closeButtonSkin===`yellow-filled`,"pkt-modal--transparentBackdrop":this.transparentBackdrop??!1,[`pkt-modal--${this.size}`]:this.size!==void 0,[`pkt-modal__${this.variant}`]:this.variant!==void 0,[`pkt-modal__drawer--${this.drawerPosition}`]:this.variant===`drawer`},a={"pkt-modal__headingText":!0,"pkt-txt-24":!0},o={"pkt-modal__content":!0,"pkt-txt-18-light":!0},s=this.closeButtonSkin===`blue`,c={"pkt-modal__closeButton":!0,[`pkt-modal__closeButton--${this.closeButtonSkin}`]:!0};return e._`
2
- <dialog
3
- class=${t.t(i)}
4
- ${r.n(this.dialogRef)}
5
- aria-labelledby=${this.headingText?`pkt-modal__headingText`:e.h}
6
- aria-describedby="pkt-modal__content"
7
- @close=${e=>this.close(e,!0)}
8
- >
9
- <div class="pkt-modal__wrapper">
10
- ${this.headingText||!this.hideCloseButton?e._`<div class="pkt-modal__header">
11
- <div class="pkt-modal__header-background"></div>
12
- ${this.headingText?e._`<h1 id="pkt-modal__headingText" class=${t.t(a)}>
13
- ${this.headingText}
14
- </h1>`:e._`<div class="pkt-modal__headingText"></div>`}
15
- ${this.hideCloseButton?e._`<div class="pkt-modal__noCloseButton"></div>`:e._`<div class="${t.t(c)}">
16
- <pkt-button
17
- @click=${e=>this.close(e)}
18
- aria-label=${this.pktStrings.get(`generic`).close}
19
- iconname="close"
20
- variant="icon-only"
21
- size="medium"
22
- skin=${s?`tertiary`:`primary`}
23
- >
24
- ${this.pktStrings.get(`generic`).close}
25
- </pkt-button>
26
- </div>`}
27
- </div>`:e.h}
28
- <div class="pkt-modal__container">
29
- <div id="pkt-modal__content" class=${t.t(o)}>
30
- ${n.i(this)}
31
- </div>
32
- </div>
33
- </div>
34
- </dialog>
35
- `}};e.n([e.u({type:Boolean,reflect:!0})],o.prototype,`open`,void 0),e.n([e.u({type:String})],o.prototype,`headingText`,void 0),e.n([e.u({type:Boolean})],o.prototype,`removePadding`,void 0),e.n([e.u({type:Boolean})],o.prototype,`hideCloseButton`,void 0),e.n([e.u({type:Boolean})],o.prototype,`closeOnBackdropClick`,void 0),e.n([e.u({type:String})],o.prototype,`closeButtonSkin`,void 0),e.n([e.u({type:String})],o.prototype,`size`,void 0),e.n([e.u({type:String})],o.prototype,`variant`,void 0),e.n([e.u({type:String})],o.prototype,`drawerPosition`,void 0),e.n([e.u({type:Boolean})],o.prototype,`transparentBackdrop`,void 0),e.n([e.l()],o.prototype,`_isOpen`,void 0);try{e.d(`pkt-modal`)(o)}catch{console.warn(`Forsøker å definere <pkt-modal>, men den er allerede definert`)}var s=o;Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return s}});