@oslokommune/punkt-elements 16.24.1 → 16.25.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 +17 -0
- package/dist/components/header/header-service.d.ts +1 -0
- package/dist/{header-DONTGbD9.js → header-BdxslVug.js} +11 -2
- package/dist/{header-CjBip0zj.cjs → header-gOdqWZ-o.cjs} +8 -3
- package/dist/{link-ClUNY__5.js → link-DauiNRMq.js} +8 -0
- package/dist/{link-B5ur0Rym.cjs → link-EZ0-lS3W.cjs} +1 -1
- package/dist/pkt-header.cjs +1 -1
- package/dist/pkt-header.js +1 -1
- package/dist/pkt-index.cjs +1 -1
- package/dist/pkt-index.js +2 -2
- package/dist/pkt-link.cjs +1 -1
- package/dist/pkt-link.js +1 -1
- package/package.json +2 -2
- package/src/components/header/header-service.test.ts +77 -0
- package/src/components/header/header-service.ts +24 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ og skriver commits ca etter [Conventional Commits](https://conventionalcommits.o
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
## [16.25.0](https://github.com/oslokommune/punkt/compare/16.24.1...16.25.0) (2026-06-12)
|
|
9
|
+
|
|
10
|
+
### ⚠ BREAKING CHANGES
|
|
11
|
+
Ingen
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
Ingen
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
Ingen
|
|
18
|
+
|
|
19
|
+
### Chores
|
|
20
|
+
Ingen
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
|
|
8
25
|
## [16.24.1](https://github.com/oslokommune/punkt/compare/16.24.0...16.24.1) (2026-05-29)
|
|
9
26
|
|
|
10
27
|
### ⚠ BREAKING CHANGES
|
|
@@ -54,6 +54,7 @@ export declare class PktHeaderService extends PktElementWithSlot<IPktHeader> imp
|
|
|
54
54
|
private setupScrollListener;
|
|
55
55
|
private handleScroll;
|
|
56
56
|
private handleClickOutside;
|
|
57
|
+
private handleSlotContentClick;
|
|
57
58
|
private handleFocusOut;
|
|
58
59
|
private handleEscapeKey;
|
|
59
60
|
private restoreFocus;
|
|
@@ -6,7 +6,7 @@ import { t as u } from "./if-defined-VShASPdu.js";
|
|
|
6
6
|
import "./button-CR-KWhTT.js";
|
|
7
7
|
import { n as d, t as f } from "./ref-BgoHEsEt.js";
|
|
8
8
|
import { t as p } from "./booleanish-BmcOU-43.js";
|
|
9
|
-
import "./link-
|
|
9
|
+
import "./link-DauiNRMq.js";
|
|
10
10
|
import "./textinput-CZrBM-Fj.js";
|
|
11
11
|
//#region ../../shared-types/header.ts
|
|
12
12
|
var m = (e) => typeof e.target == "string" ? {
|
|
@@ -189,6 +189,10 @@ var v = "https://punkt-cdn.oslo.kommune.no/latest/logos/", y = class extends l {
|
|
|
189
189
|
}, this.handleClickOutside = (e) => {
|
|
190
190
|
let t = e.target;
|
|
191
191
|
this.user && this.openMenu === "user" && !t.closest(".pkt-header-service__user-container") && (this.openMenu = "none"), this.openMenu === "slot" && !t.closest(".pkt-header-service__slot-container") && (this.openMenu = "none"), this.openMenu === "search" && !t.closest(".pkt-header-service__search-container") && !t.closest(".pkt-header-service__search-input") && (this.openMenu = "none");
|
|
192
|
+
}, this.handleSlotContentClick = (e) => {
|
|
193
|
+
if (!this.isTablet || this.openMenu !== "slot") return;
|
|
194
|
+
let t = e.target.closest("a[href], button, [role=\"link\"], [role=\"button\"], [role=\"menuitem\"], [role=\"menuitemradio\"], [role=\"menuitemcheckbox\"]");
|
|
195
|
+
!t || !this.slotContentRef.value?.contains(t) || t.closest("[data-pkt-header-keep-open]") || t.disabled || t.getAttribute("aria-disabled") === "true" || (this.openMenu = "none");
|
|
192
196
|
}, this.handleFocusOut = (e, t) => {
|
|
193
197
|
let n = e.relatedTarget, r;
|
|
194
198
|
switch (t) {
|
|
@@ -369,7 +373,11 @@ var v = "https://punkt-cdn.oslo.kommune.no/latest/logos/", y = class extends l {
|
|
|
369
373
|
</button>
|
|
370
374
|
</span>
|
|
371
375
|
` : i`
|
|
372
|
-
<span
|
|
376
|
+
<span
|
|
377
|
+
class="pkt-header-service__service-name"
|
|
378
|
+
translate="no"
|
|
379
|
+
@click=${this.handleServiceClick}
|
|
380
|
+
>
|
|
373
381
|
<span class="pkt-header-service__service-link">${this.serviceName}</span>
|
|
374
382
|
</span>
|
|
375
383
|
` : t;
|
|
@@ -409,6 +417,7 @@ var v = "https://punkt-cdn.oslo.kommune.no/latest/logos/", y = class extends l {
|
|
|
409
417
|
id="mobile-slot-menu"
|
|
410
418
|
role=${this.isTablet ? "menu" : t}
|
|
411
419
|
aria-label=${this.isTablet ? "Meny" : t}
|
|
420
|
+
@click=${this.handleSlotContentClick}
|
|
412
421
|
${d(this.slotContentRef)}
|
|
413
422
|
>
|
|
414
423
|
${c(this)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const e=require(`./element-CXAtr6Gu.cjs`),t=require(`./class-map-B8Ja0q7n.cjs`),n=require(`./element-with-slot-Cmxb9h4H.cjs`);require(`./icon-Dw6I0HDV.cjs`);const r=require(`./if-defined-LTjAScFG.cjs`);require(`./button-Dwv11n6R.cjs`);const i=require(`./ref-CBdWMlde.cjs`),a=require(`./booleanish-jJLlnr6-.cjs`);require(`./link-
|
|
1
|
+
const e=require(`./element-CXAtr6Gu.cjs`),t=require(`./class-map-B8Ja0q7n.cjs`),n=require(`./element-with-slot-Cmxb9h4H.cjs`);require(`./icon-Dw6I0HDV.cjs`);const r=require(`./if-defined-LTjAScFG.cjs`);require(`./button-Dwv11n6R.cjs`);const i=require(`./ref-CBdWMlde.cjs`),a=require(`./booleanish-jJLlnr6-.cjs`);require(`./link-EZ0-lS3W.cjs`),require(`./textinput-C_6kvf87.cjs`);var o=e=>typeof e.target==`string`?{title:e.title,iconName:e.iconName,href:e.target}:{title:e.title,iconName:e.iconName,onClick:e.target},s=e=>o(e),c=e=>{if(!e)return;let t=typeof e==`string`?new Date(e):e;if(!isNaN(t.getTime()))return t.toLocaleDateString(`nb-NO`,{day:`numeric`,month:`long`,year:`numeric`,hour:`2-digit`,minute:`2-digit`})},l=class extends e.t{constructor(...e){super(...e),this.canChangeRepresentation=!1,this.logoutOnClick=!1}handleChangeRepresentation(){this.dispatchEvent(new CustomEvent(`change-representation`,{bubbles:!0,composed:!0}))}handleLogout(){this.dispatchEvent(new CustomEvent(`log-out`,{bubbles:!0,composed:!0}))}handleMenuItemClick(e){`onClick`in e&&typeof e.onClick==`function`&&e.onClick()}renderLinkOrButton(n,r){let i=`href`in n,a=t.t({"pkt-user-menu__link":!0,"pkt-link-button":!i,"pkt-link":!i,"pkt-link--icon-left":!i,[r||``]:!!r});return i?e.p`
|
|
2
2
|
<pkt-link
|
|
3
3
|
icon-name=${n.iconName||e.d}
|
|
4
4
|
href=${n.href}
|
|
@@ -80,7 +80,7 @@ const e=require(`./element-CXAtr6Gu.cjs`),t=require(`./class-map-B8Ja0q7n.cjs`),
|
|
|
80
80
|
`:e.d}
|
|
81
81
|
</ul>
|
|
82
82
|
</nav>
|
|
83
|
-
`}};e.n([e.o({type:Object})],l.prototype,`user`,void 0),e.n([e.o({type:String,attribute:`formatted-last-logged-in`})],l.prototype,`formattedLastLoggedIn`,void 0),e.n([e.o({type:Object})],l.prototype,`representing`,void 0),e.n([e.o({type:Array,attribute:`user-menu`})],l.prototype,`userMenu`,void 0),e.n([e.o({type:Boolean,attribute:`can-change-representation`,converter:a.t})],l.prototype,`canChangeRepresentation`,void 0),e.n([e.o({type:Boolean,attribute:`logout-on-click`,converter:a.t})],l.prototype,`logoutOnClick`,void 0);try{e.s(`pkt-header-user-menu`)(l)}catch{console.warn(`Forsøker å definere <pkt-header-user-menu>, men den er allerede definert`)}var u=`https://punkt-cdn.oslo.kommune.no/latest/logos/`,d=class extends n.t{constructor(...e){super(...e),this.searchPlaceholder=`Søk`,this.searchValue=``,this.mobileBreakpoint=768,this.tabletBreakpoint=1280,this.openedMenu=`none`,this.logOutButtonPlacement=`none`,this.position=`fixed`,this.scrollBehavior=`hide`,this.slotMenuVariant=`icon-only`,this.slotMenuText=`Meny`,this.hideLogo=!1,this.compact=!1,this.showSearch=!1,this.canChangeRepresentation=!1,this.hasLogOut=!1,this.isMobile=!1,this.isTablet=!1,this.openMenu=`none`,this.isHidden=!1,this.componentWidth=typeof window<`u`?window.innerWidth:0,this.alignSlotRight=!1,this.alignSearchRight=!1,this.headerRef=i.t(),this.userContainerRef=i.t(),this.slotContainerRef=i.t(),this.searchContainerRef=i.t(),this.slotContentRef=i.t(),this.searchMenuRef=i.t(),this.lastScrollPosition=0,this.savedScrollY=0,this.lastFocusedElement=null,this.shouldRestoreFocus=!1,this.handleScroll=()=>{if(!this.shouldHideOnScroll)return;let e=window.pageYOffset||document.documentElement.scrollTop;e<0||Math.abs(e-this.lastScrollPosition)<60||(this.isHidden=e>this.lastScrollPosition,this.lastScrollPosition=e)},this.handleClickOutside=e=>{let t=e.target;this.user&&this.openMenu===`user`&&!t.closest(`.pkt-header-service__user-container`)&&(this.openMenu=`none`),this.openMenu===`slot`&&!t.closest(`.pkt-header-service__slot-container`)&&(this.openMenu=`none`),this.openMenu===`search`&&!t.closest(`.pkt-header-service__search-container`)&&!t.closest(`.pkt-header-service__search-input`)&&(this.openMenu=`none`)},this.handleFocusOut=(e,t)=>{let n=e.relatedTarget,r;switch(t){case`user`:r=this.userContainerRef;break;case`slot`:r=this.slotContainerRef;break;case`search`:r=this.searchContainerRef;break;default:return}let i=r.value;i&&(!n||!i.contains(n))&&(this.openMenu=`none`)},this.handleEscapeKey=e=>{e.key===`Escape`&&this.openMenu!==`none`&&(e.preventDefault(),this.shouldRestoreFocus=!0,this.openMenu=`none`)}}connectedCallback(){super.connectedCallback(),this.setupScrollListener()}disconnectedCallback(){super.disconnectedCallback(),this.resizeObserver?.disconnect(),window.removeEventListener(`scroll`,this.handleScroll),this.unlockScroll()}firstUpdated(){this.setupResizeObserver()}updated(e){if(super.updated(e),e.has(`openedMenu`)&&this.openedMenu!==this.openMenu&&(this.openMenu=this.openedMenu),(e.has(`mobileBreakpoint`)||e.has(`tabletBreakpoint`))&&(this.updateIsMobile(),this.updateIsTablet()),e.has(`openMenu`)){let t=e.get(`openMenu`);this.openMenu!==`none`&&(t===`none`||t===void 0)?(document.addEventListener(`mousedown`,this.handleClickOutside),document.addEventListener(`keydown`,this.handleEscapeKey),(this.openMenu===`slot`||this.openMenu===`search`)&&requestAnimationFrame(()=>{this.checkDropdownAlignment(this.openMenu)})):this.openMenu===`none`&&t!==`none`&&(document.removeEventListener(`mousedown`,this.handleClickOutside),document.removeEventListener(`keydown`,this.handleEscapeKey),this.restoreFocus())}(e.has(`openMenu`)||e.has(`isMobile`))&&this.updateScrollLock()}setupResizeObserver(){let e=this.headerRef.value;e&&(this.componentWidth=e.offsetWidth,this.updateIsMobile(),this.updateIsTablet(),this.resizeObserver=new ResizeObserver(e=>{for(let t of e)t.borderBoxSize&&t.borderBoxSize.length>0?this.componentWidth=t.borderBoxSize[0].inlineSize:this.componentWidth=t.contentRect.width,this.updateIsMobile(),this.updateIsTablet()}),this.resizeObserver.observe(e))}updateIsMobile(){this.isMobile=this.componentWidth<this.mobileBreakpoint}updateIsTablet(){this.isTablet=this.componentWidth<this.tabletBreakpoint}updateScrollLock(){this.position===`fixed`&&this.isMobile&&this.openMenu!==`none`?this.lockScroll():this.unlockScroll()}lockScroll(){let e=document.body,t=document.documentElement;this.savedScrollY=window.scrollY||window.pageYOffset;let n=window.innerWidth-t.clientWidth;n>0&&(e.style.paddingRight=`${n}px`),e.style.position=`fixed`,e.style.top=`-${this.savedScrollY}px`,e.style.left=`0`,e.style.right=`0`,e.style.width=`100%`,e.style.overflow=`hidden`,t.classList.add(`is-scroll-locked`)}unlockScroll(){let e=document.body,t=document.documentElement;t.classList.contains(`is-scroll-locked`)&&(e.style.removeProperty(`position`),e.style.removeProperty(`top`),e.style.removeProperty(`left`),e.style.removeProperty(`right`),e.style.removeProperty(`width`),e.style.removeProperty(`overflow`),e.style.removeProperty(`padding-right`),t.classList.remove(`is-scroll-locked`),window.scrollTo({top:this.savedScrollY}))}setupScrollListener(){window.addEventListener(`scroll`,this.handleScroll)}restoreFocus(){this.shouldRestoreFocus&&this.lastFocusedElement&&document.contains(this.lastFocusedElement)&&this.lastFocusedElement.focus(),this.lastFocusedElement=null,this.shouldRestoreFocus=!1}checkDropdownAlignment(e){let t=e===`slot`?this.slotContainerRef:this.searchContainerRef,n=e===`slot`?this.slotContentRef:this.searchMenuRef;if(!t.value||!n.value||!this.isTablet||this.isMobile)return;let r=t.value.getBoundingClientRect(),i=n.value.offsetWidth,a=r.left+i>window.innerWidth;e===`slot`?this.alignSlotRight=a:this.alignSearchRight=a}handleMenuToggle(e){this.openMenu===`none`?(this.lastFocusedElement=document.activeElement,this.openMenu=e):this.openMenu=`none`}handleLogoClick(e){this.dispatchEvent(new CustomEvent(`logo-click`,{bubbles:!0,composed:!0,detail:{originalEvent:e}}))}handleServiceClick(e){this.dispatchEvent(new CustomEvent(`service-click`,{bubbles:!0,composed:!0,detail:{originalEvent:e}}))}handleLogout(){this.dispatchEvent(new CustomEvent(`log-out`,{bubbles:!0,composed:!0}))}handleSearch(e){this.dispatchEvent(new CustomEvent(`search`,{detail:{query:e},bubbles:!0,composed:!0}))}handleSearchChange(e){this.dispatchEvent(new CustomEvent(`search-change`,{detail:{query:e},bubbles:!0,composed:!0}))}handleSearchInputChange(e){let t=e.target.value;this.handleSearchChange(t)}handleSearchKeyDown(e){e.key===`Enter`&&this.handleSearch(e.target.value)}get formattedLastLoggedIn(){return c(this.user?.lastLoggedIn)}get isFixed(){return this.position===`fixed`}get shouldHideOnScroll(){return this.scrollBehavior===`hide`}get showLogoutInHeader(){return this.hasLogOut&&(this.logOutButtonPlacement===`header`||this.logOutButtonPlacement===`both`)}get showLogoutInUserMenu(){return this.hasLogOut&&(this.logOutButtonPlacement===`userMenu`||this.logOutButtonPlacement===`both`)}renderLogo(){if(this.hideLogo)return e.d;let t=e.p`
|
|
83
|
+
`}};e.n([e.o({type:Object})],l.prototype,`user`,void 0),e.n([e.o({type:String,attribute:`formatted-last-logged-in`})],l.prototype,`formattedLastLoggedIn`,void 0),e.n([e.o({type:Object})],l.prototype,`representing`,void 0),e.n([e.o({type:Array,attribute:`user-menu`})],l.prototype,`userMenu`,void 0),e.n([e.o({type:Boolean,attribute:`can-change-representation`,converter:a.t})],l.prototype,`canChangeRepresentation`,void 0),e.n([e.o({type:Boolean,attribute:`logout-on-click`,converter:a.t})],l.prototype,`logoutOnClick`,void 0);try{e.s(`pkt-header-user-menu`)(l)}catch{console.warn(`Forsøker å definere <pkt-header-user-menu>, men den er allerede definert`)}var u=`https://punkt-cdn.oslo.kommune.no/latest/logos/`,d=class extends n.t{constructor(...e){super(...e),this.searchPlaceholder=`Søk`,this.searchValue=``,this.mobileBreakpoint=768,this.tabletBreakpoint=1280,this.openedMenu=`none`,this.logOutButtonPlacement=`none`,this.position=`fixed`,this.scrollBehavior=`hide`,this.slotMenuVariant=`icon-only`,this.slotMenuText=`Meny`,this.hideLogo=!1,this.compact=!1,this.showSearch=!1,this.canChangeRepresentation=!1,this.hasLogOut=!1,this.isMobile=!1,this.isTablet=!1,this.openMenu=`none`,this.isHidden=!1,this.componentWidth=typeof window<`u`?window.innerWidth:0,this.alignSlotRight=!1,this.alignSearchRight=!1,this.headerRef=i.t(),this.userContainerRef=i.t(),this.slotContainerRef=i.t(),this.searchContainerRef=i.t(),this.slotContentRef=i.t(),this.searchMenuRef=i.t(),this.lastScrollPosition=0,this.savedScrollY=0,this.lastFocusedElement=null,this.shouldRestoreFocus=!1,this.handleScroll=()=>{if(!this.shouldHideOnScroll)return;let e=window.pageYOffset||document.documentElement.scrollTop;e<0||Math.abs(e-this.lastScrollPosition)<60||(this.isHidden=e>this.lastScrollPosition,this.lastScrollPosition=e)},this.handleClickOutside=e=>{let t=e.target;this.user&&this.openMenu===`user`&&!t.closest(`.pkt-header-service__user-container`)&&(this.openMenu=`none`),this.openMenu===`slot`&&!t.closest(`.pkt-header-service__slot-container`)&&(this.openMenu=`none`),this.openMenu===`search`&&!t.closest(`.pkt-header-service__search-container`)&&!t.closest(`.pkt-header-service__search-input`)&&(this.openMenu=`none`)},this.handleSlotContentClick=e=>{if(!this.isTablet||this.openMenu!==`slot`)return;let t=e.target.closest(`a[href], button, [role="link"], [role="button"], [role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"]`);!t||!this.slotContentRef.value?.contains(t)||t.closest(`[data-pkt-header-keep-open]`)||t.disabled||t.getAttribute(`aria-disabled`)===`true`||(this.openMenu=`none`)},this.handleFocusOut=(e,t)=>{let n=e.relatedTarget,r;switch(t){case`user`:r=this.userContainerRef;break;case`slot`:r=this.slotContainerRef;break;case`search`:r=this.searchContainerRef;break;default:return}let i=r.value;i&&(!n||!i.contains(n))&&(this.openMenu=`none`)},this.handleEscapeKey=e=>{e.key===`Escape`&&this.openMenu!==`none`&&(e.preventDefault(),this.shouldRestoreFocus=!0,this.openMenu=`none`)}}connectedCallback(){super.connectedCallback(),this.setupScrollListener()}disconnectedCallback(){super.disconnectedCallback(),this.resizeObserver?.disconnect(),window.removeEventListener(`scroll`,this.handleScroll),this.unlockScroll()}firstUpdated(){this.setupResizeObserver()}updated(e){if(super.updated(e),e.has(`openedMenu`)&&this.openedMenu!==this.openMenu&&(this.openMenu=this.openedMenu),(e.has(`mobileBreakpoint`)||e.has(`tabletBreakpoint`))&&(this.updateIsMobile(),this.updateIsTablet()),e.has(`openMenu`)){let t=e.get(`openMenu`);this.openMenu!==`none`&&(t===`none`||t===void 0)?(document.addEventListener(`mousedown`,this.handleClickOutside),document.addEventListener(`keydown`,this.handleEscapeKey),(this.openMenu===`slot`||this.openMenu===`search`)&&requestAnimationFrame(()=>{this.checkDropdownAlignment(this.openMenu)})):this.openMenu===`none`&&t!==`none`&&(document.removeEventListener(`mousedown`,this.handleClickOutside),document.removeEventListener(`keydown`,this.handleEscapeKey),this.restoreFocus())}(e.has(`openMenu`)||e.has(`isMobile`))&&this.updateScrollLock()}setupResizeObserver(){let e=this.headerRef.value;e&&(this.componentWidth=e.offsetWidth,this.updateIsMobile(),this.updateIsTablet(),this.resizeObserver=new ResizeObserver(e=>{for(let t of e)t.borderBoxSize&&t.borderBoxSize.length>0?this.componentWidth=t.borderBoxSize[0].inlineSize:this.componentWidth=t.contentRect.width,this.updateIsMobile(),this.updateIsTablet()}),this.resizeObserver.observe(e))}updateIsMobile(){this.isMobile=this.componentWidth<this.mobileBreakpoint}updateIsTablet(){this.isTablet=this.componentWidth<this.tabletBreakpoint}updateScrollLock(){this.position===`fixed`&&this.isMobile&&this.openMenu!==`none`?this.lockScroll():this.unlockScroll()}lockScroll(){let e=document.body,t=document.documentElement;this.savedScrollY=window.scrollY||window.pageYOffset;let n=window.innerWidth-t.clientWidth;n>0&&(e.style.paddingRight=`${n}px`),e.style.position=`fixed`,e.style.top=`-${this.savedScrollY}px`,e.style.left=`0`,e.style.right=`0`,e.style.width=`100%`,e.style.overflow=`hidden`,t.classList.add(`is-scroll-locked`)}unlockScroll(){let e=document.body,t=document.documentElement;t.classList.contains(`is-scroll-locked`)&&(e.style.removeProperty(`position`),e.style.removeProperty(`top`),e.style.removeProperty(`left`),e.style.removeProperty(`right`),e.style.removeProperty(`width`),e.style.removeProperty(`overflow`),e.style.removeProperty(`padding-right`),t.classList.remove(`is-scroll-locked`),window.scrollTo({top:this.savedScrollY}))}setupScrollListener(){window.addEventListener(`scroll`,this.handleScroll)}restoreFocus(){this.shouldRestoreFocus&&this.lastFocusedElement&&document.contains(this.lastFocusedElement)&&this.lastFocusedElement.focus(),this.lastFocusedElement=null,this.shouldRestoreFocus=!1}checkDropdownAlignment(e){let t=e===`slot`?this.slotContainerRef:this.searchContainerRef,n=e===`slot`?this.slotContentRef:this.searchMenuRef;if(!t.value||!n.value||!this.isTablet||this.isMobile)return;let r=t.value.getBoundingClientRect(),i=n.value.offsetWidth,a=r.left+i>window.innerWidth;e===`slot`?this.alignSlotRight=a:this.alignSearchRight=a}handleMenuToggle(e){this.openMenu===`none`?(this.lastFocusedElement=document.activeElement,this.openMenu=e):this.openMenu=`none`}handleLogoClick(e){this.dispatchEvent(new CustomEvent(`logo-click`,{bubbles:!0,composed:!0,detail:{originalEvent:e}}))}handleServiceClick(e){this.dispatchEvent(new CustomEvent(`service-click`,{bubbles:!0,composed:!0,detail:{originalEvent:e}}))}handleLogout(){this.dispatchEvent(new CustomEvent(`log-out`,{bubbles:!0,composed:!0}))}handleSearch(e){this.dispatchEvent(new CustomEvent(`search`,{detail:{query:e},bubbles:!0,composed:!0}))}handleSearchChange(e){this.dispatchEvent(new CustomEvent(`search-change`,{detail:{query:e},bubbles:!0,composed:!0}))}handleSearchInputChange(e){let t=e.target.value;this.handleSearchChange(t)}handleSearchKeyDown(e){e.key===`Enter`&&this.handleSearch(e.target.value)}get formattedLastLoggedIn(){return c(this.user?.lastLoggedIn)}get isFixed(){return this.position===`fixed`}get shouldHideOnScroll(){return this.scrollBehavior===`hide`}get showLogoutInHeader(){return this.hasLogOut&&(this.logOutButtonPlacement===`header`||this.logOutButtonPlacement===`both`)}get showLogoutInUserMenu(){return this.hasLogOut&&(this.logOutButtonPlacement===`userMenu`||this.logOutButtonPlacement===`both`)}renderLogo(){if(this.hideLogo)return e.d;let t=e.p`
|
|
84
84
|
<pkt-icon name="oslologo" aria-hidden="true" path=${u}></pkt-icon>
|
|
85
85
|
`;return this.logoLink&&typeof this.logoLink==`string`?e.p`
|
|
86
86
|
<span class="pkt-header-service__logo">
|
|
@@ -120,7 +120,11 @@ const e=require(`./element-CXAtr6Gu.cjs`),t=require(`./class-map-B8Ja0q7n.cjs`),
|
|
|
120
120
|
</button>
|
|
121
121
|
</span>
|
|
122
122
|
`:e.p`
|
|
123
|
-
<span
|
|
123
|
+
<span
|
|
124
|
+
class="pkt-header-service__service-name"
|
|
125
|
+
translate="no"
|
|
126
|
+
@click=${this.handleServiceClick}
|
|
127
|
+
>
|
|
124
128
|
<span class="pkt-header-service__service-link">${this.serviceName}</span>
|
|
125
129
|
</span>
|
|
126
130
|
`:e.d}renderSlotContainer(){if(!this.hasSlotContent())return e.d;let r=t.t({"pkt-header-service__slot-container":!0,"is-open":this.openMenu===`slot`}),a=t.t({"pkt-header-service__slot-content":!0,"align-right":this.alignSlotRight});return e.p`
|
|
@@ -149,6 +153,7 @@ const e=require(`./element-CXAtr6Gu.cjs`),t=require(`./class-map-B8Ja0q7n.cjs`),
|
|
|
149
153
|
id="mobile-slot-menu"
|
|
150
154
|
role=${this.isTablet?`menu`:e.d}
|
|
151
155
|
aria-label=${this.isTablet?`Meny`:e.d}
|
|
156
|
+
@click=${this.handleSlotContentClick}
|
|
152
157
|
${i.n(this.slotContentRef)}
|
|
153
158
|
>
|
|
154
159
|
${n.n(this)}
|
|
@@ -39,6 +39,14 @@ var c = {
|
|
|
39
39
|
description: "Posisjonen til ikonet i forhold til lenketeksten",
|
|
40
40
|
type: ["left", "right"],
|
|
41
41
|
category: "ui"
|
|
42
|
+
},
|
|
43
|
+
renderLink: {
|
|
44
|
+
name: "Egendefinert lenkekomponent",
|
|
45
|
+
description: "React: Funksjon for å rendre en egendefinert lenkekomponent (f.eks. Next.js Link eller React Router Link). Mottar et objekt med href, className, children og props. Standard er et vanlig <a>-element.",
|
|
46
|
+
type: "function",
|
|
47
|
+
required: !1,
|
|
48
|
+
category: "tech",
|
|
49
|
+
reactOnly: !0
|
|
42
50
|
}
|
|
43
51
|
},
|
|
44
52
|
slots: { default: { description: "Innholdet i lenken" } }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const e=require(`./element-CXAtr6Gu.cjs`),t=require(`./class-map-B8Ja0q7n.cjs`),n=require(`./element-with-slot-Cmxb9h4H.cjs`);require(`./icon-Dw6I0HDV.cjs`);var r={name:`pkt-link`,react:`PktLink`,"css-class":`pkt-link`,"dark-mode":!0,isElement:!0,props:{href:{name:`URL`,description:`URL til lenken`,type:`string`,default:`#`,category:`contents`},target:{name:`Mål`,description:`Mål for lenken`,type:[`_blank`,`_self`,`_parent`,`_top`],default:`_self`,category:`tech`},iconName:{name:`Ikon`,description:`Ikon som skal vises ved siden av lenketeksten`,type:`icon`,category:`ui`},iconPosition:{name:`Ikonposisjon`,description:`Posisjonen til ikonet i forhold til lenketeksten`,type:[`left`,`right`],category:`ui`}},slots:{default:{description:`Innholdet i lenken`}}},i=class extends n.t{constructor(...e){super(...e),this.href=r.props.href.default,this.iconName=void 0,this.iconPosition=void 0,this.external=!1,this.target=r.props.target.default}render(){return e.p`<a
|
|
1
|
+
const e=require(`./element-CXAtr6Gu.cjs`),t=require(`./class-map-B8Ja0q7n.cjs`),n=require(`./element-with-slot-Cmxb9h4H.cjs`);require(`./icon-Dw6I0HDV.cjs`);var r={name:`pkt-link`,react:`PktLink`,"css-class":`pkt-link`,"dark-mode":!0,isElement:!0,props:{href:{name:`URL`,description:`URL til lenken`,type:`string`,default:`#`,category:`contents`},target:{name:`Mål`,description:`Mål for lenken`,type:[`_blank`,`_self`,`_parent`,`_top`],default:`_self`,category:`tech`},iconName:{name:`Ikon`,description:`Ikon som skal vises ved siden av lenketeksten`,type:`icon`,category:`ui`},iconPosition:{name:`Ikonposisjon`,description:`Posisjonen til ikonet i forhold til lenketeksten`,type:[`left`,`right`],category:`ui`},renderLink:{name:`Egendefinert lenkekomponent`,description:`React: Funksjon for å rendre en egendefinert lenkekomponent (f.eks. Next.js Link eller React Router Link). Mottar et objekt med href, className, children og props. Standard er et vanlig <a>-element.`,type:`function`,required:!1,category:`tech`,reactOnly:!0}},slots:{default:{description:`Innholdet i lenken`}}},i=class extends n.t{constructor(...e){super(...e),this.href=r.props.href.default,this.iconName=void 0,this.iconPosition=void 0,this.external=!1,this.target=r.props.target.default}render(){return e.p`<a
|
|
2
2
|
class=${t.t({"pkt-link":!0,"pkt-link--icon-left":!!this.iconName&&this.iconPosition===`left`||!!(this.iconName&&!this.iconPosition),"pkt-link--icon-right":!!this.iconName&&this.iconPosition===`right`,"pkt-link--external":this.external})}
|
|
3
3
|
href=${this.href}
|
|
4
4
|
.target=${this.target}
|
package/dist/pkt-header.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./header-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./header-gOdqWZ-o.cjs`);exports.PktHeader=e.t,exports.PktHeaderService=e.n,exports.PktHeaderUserMenu=e.r,exports.formatLastLoggedIn=e.i;
|
package/dist/pkt-header.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as e, n as t, r as n, t as r } from "./header-
|
|
1
|
+
import { i as e, n as t, r as n, t as r } from "./header-BdxslVug.js";
|
|
2
2
|
export { r as PktHeader, t as PktHeaderService, n as PktHeaderUserMenu, e as formatLastLoggedIn };
|
package/dist/pkt-index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./alert-D_45dWPn.cjs`),t=require(`./icon-Dw6I0HDV.cjs`),n=require(`./button-Dwv11n6R.cjs`),r=require(`./accordion-DaeWPWod.cjs`),i=require(`./backlink-C42-3OG3.cjs`),a=require(`./breadcrumbs-CkjeLh3U.cjs`),o=require(`./calendar-64LmbIdR.cjs`),s=require(`./card-C__IlsUa.cjs`),c=require(`./tag-CBFz0R9N.cjs`),l=require(`./heading-C40-NX0r.cjs`),u=require(`./combobox-x4tBGP3F.cjs`),d=require(`./header-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./alert-D_45dWPn.cjs`),t=require(`./icon-Dw6I0HDV.cjs`),n=require(`./button-Dwv11n6R.cjs`),r=require(`./accordion-DaeWPWod.cjs`),i=require(`./backlink-C42-3OG3.cjs`),a=require(`./breadcrumbs-CkjeLh3U.cjs`),o=require(`./calendar-64LmbIdR.cjs`),s=require(`./card-C__IlsUa.cjs`),c=require(`./tag-CBFz0R9N.cjs`),l=require(`./heading-C40-NX0r.cjs`),u=require(`./combobox-x4tBGP3F.cjs`),d=require(`./header-gOdqWZ-o.cjs`),f=require(`./header-menu-CnW7nzmF.cjs`),p=require(`./datepicker-Bs95HYGc.cjs`),m=require(`./fileupload-BLto9H17.cjs`),h=require(`./helptext-DNLg43eI.cjs`),g=require(`./input-wrapper-Dhkt20WW.cjs`),_=require(`./consent-DVt6sMvB.cjs`),v=require(`./checkbox-DzMc0AJX.cjs`),y=require(`./modal-CrYHKOmr.cjs`),b=require(`./progressbar-DADdvDl5.cjs`),x=require(`./link-EZ0-lS3W.cjs`),S=require(`./textinput-C_6kvf87.cjs`),C=require(`./linkcard-BIcCW-qw.cjs`),w=require(`./loader-Uap9qDsV.cjs`),T=require(`./messagebox-BqBxXK8c.cjs`),E=require(`./radiobutton-BfURufrZ.cjs`),D=require(`./tabs-DxQy8U-0.cjs`),O=require(`./textarea-M_S9WK7s.cjs`),k=require(`./select-DzZHv6Bz.cjs`),A=require(`./searchinput-BrxfRzez.cjs`),j=require(`./timepicker-WiYLAncb.cjs`);exports.PktAccordion=r.r,exports.PktAccordionItem=r.n,exports.PktAlert=e.n,exports.PktBackLink=i.n,exports.PktBreadcrumbs=a.t,exports.PktButton=n.n,exports.PktCalendar=o.n,exports.PktCard=s.n,exports.PktCheckbox=v.n,exports.PktCombobox=u.n,exports.PktConsent=_.n,exports.PktDateTags=p.a,exports.PktDatepicker=p.t,Object.defineProperty(exports,`PktFileUpload`,{enumerable:!0,get:function(){return m.n}}),exports.PktHeader=d.t,exports.PktHeaderMenu=f.n,exports.PktHeaderService=d.n,exports.PktHeaderUserMenu=d.r,exports.PktHeading=l.n,exports.PktHelptext=h.n,exports.PktIcon=t.n,exports.PktInputWrapper=g.n,exports.PktLink=x.n,exports.PktLinkCard=C.n,exports.PktLoader=w.n,exports.PktMessagebox=T.n,exports.PktModal=y.n,exports.PktProgressbar=b.n,exports.PktRadioButton=E.n,exports.PktRadiobutton=E.n,exports.PktSearchInput=A.n,exports.PktSelect=k.n,exports.PktTabItem=D.n,exports.PktTabs=D.r,exports.PktTag=c.n,exports.PktTextarea=O.n,exports.PktTextinput=S.n,exports.PktTimepicker=j.t;
|
package/dist/pkt-index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { n as c } from "./card-5PydU247.js";
|
|
|
9
9
|
import { n as l } from "./tag-CzlnHhho.js";
|
|
10
10
|
import { n as u } from "./heading-3o4Dk0Wn.js";
|
|
11
11
|
import { n as d } from "./combobox-D-DY7YcW.js";
|
|
12
|
-
import { n as f, r as p, t as m } from "./header-
|
|
12
|
+
import { n as f, r as p, t as m } from "./header-BdxslVug.js";
|
|
13
13
|
import { n as h } from "./header-menu-BU-ylGrJ.js";
|
|
14
14
|
import { a as g, t as _ } from "./datepicker-DxkcKevq.js";
|
|
15
15
|
import { n as v } from "./fileupload-bykWTtA6.js";
|
|
@@ -19,7 +19,7 @@ import { n as x } from "./consent-BFdURuBl.js";
|
|
|
19
19
|
import { n as S } from "./checkbox-CC1X7fw4.js";
|
|
20
20
|
import { n as C } from "./modal-CWgeT-RP.js";
|
|
21
21
|
import { n as w } from "./progressbar-B0P_vmGD.js";
|
|
22
|
-
import { n as T } from "./link-
|
|
22
|
+
import { n as T } from "./link-DauiNRMq.js";
|
|
23
23
|
import { n as E } from "./textinput-CZrBM-Fj.js";
|
|
24
24
|
import { n as D } from "./linkcard-DNJm5FvA.js";
|
|
25
25
|
import { n as O } from "./loader-gKdQpOOQ.js";
|
package/dist/pkt-link.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require(`./link-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require(`./link-EZ0-lS3W.cjs`);exports.PktLink=e.n,exports.default=e.t;
|
package/dist/pkt-link.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as e, t } from "./link-
|
|
1
|
+
import { n as e, t } from "./link-DauiNRMq.js";
|
|
2
2
|
export { e as PktLink, t as default };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oslokommune/punkt-elements",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.25.0",
|
|
4
4
|
"description": "Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo",
|
|
5
5
|
"homepage": "https://punkt.oslo.kommune.no",
|
|
6
6
|
"author": "Team Designsystem, Oslo Origo",
|
|
@@ -79,5 +79,5 @@
|
|
|
79
79
|
"url": "https://github.com/oslokommune/punkt/issues"
|
|
80
80
|
},
|
|
81
81
|
"license": "MIT",
|
|
82
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "d01de2b51e9c71b709202eb0d2fb3336e2932a20"
|
|
83
83
|
}
|
|
@@ -401,4 +401,81 @@ describe('pkt-header-service', () => {
|
|
|
401
401
|
}
|
|
402
402
|
})
|
|
403
403
|
})
|
|
404
|
+
|
|
405
|
+
describe('slot menu closes on intentional click', () => {
|
|
406
|
+
const isSlotOpen = (element: HTMLElement) =>
|
|
407
|
+
!!element.querySelector('.pkt-header-service__slot-container.is-open')
|
|
408
|
+
|
|
409
|
+
const clickSlotChild = async (element: HTMLElement, selector: string) => {
|
|
410
|
+
const target = element.querySelector(`.pkt-header-service__slot-content ${selector}`)
|
|
411
|
+
target?.dispatchEvent(new MouseEvent('click', { bubbles: true }))
|
|
412
|
+
await (element as CustomElementFor<'pkt-header-service'>).updateComplete
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
it('closes when clicking a link inside the menu', async () => {
|
|
416
|
+
const { element } = await createHeaderServiceTest({
|
|
417
|
+
'service-name': 'Svc',
|
|
418
|
+
'opened-menu': 'slot',
|
|
419
|
+
content: '<a href="#">Gå hit</a>',
|
|
420
|
+
})
|
|
421
|
+
expect(isSlotOpen(element)).toBe(true)
|
|
422
|
+
await clickSlotChild(element, 'a[href]')
|
|
423
|
+
expect(isSlotOpen(element)).toBe(false)
|
|
424
|
+
})
|
|
425
|
+
|
|
426
|
+
it('closes when clicking a button inside the menu', async () => {
|
|
427
|
+
const { element } = await createHeaderServiceTest({
|
|
428
|
+
'service-name': 'Svc',
|
|
429
|
+
'opened-menu': 'slot',
|
|
430
|
+
content: '<button type="button">Gjør noe</button>',
|
|
431
|
+
})
|
|
432
|
+
expect(isSlotOpen(element)).toBe(true)
|
|
433
|
+
await clickSlotChild(element, 'button')
|
|
434
|
+
expect(isSlotOpen(element)).toBe(false)
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
it('stays open when clicking a form input inside the menu', async () => {
|
|
438
|
+
const { element } = await createHeaderServiceTest({
|
|
439
|
+
'service-name': 'Svc',
|
|
440
|
+
'opened-menu': 'slot',
|
|
441
|
+
content: '<input type="text" aria-label="Filtrer" />',
|
|
442
|
+
})
|
|
443
|
+
expect(isSlotOpen(element)).toBe(true)
|
|
444
|
+
await clickSlotChild(element, 'input')
|
|
445
|
+
expect(isSlotOpen(element)).toBe(true)
|
|
446
|
+
})
|
|
447
|
+
|
|
448
|
+
it('stays open when clicking non-interactive content inside the menu', async () => {
|
|
449
|
+
const { element } = await createHeaderServiceTest({
|
|
450
|
+
'service-name': 'Svc',
|
|
451
|
+
'opened-menu': 'slot',
|
|
452
|
+
content: '<span>Bare tekst</span>',
|
|
453
|
+
})
|
|
454
|
+
expect(isSlotOpen(element)).toBe(true)
|
|
455
|
+
await clickSlotChild(element, 'span')
|
|
456
|
+
expect(isSlotOpen(element)).toBe(true)
|
|
457
|
+
})
|
|
458
|
+
|
|
459
|
+
it('stays open when clicking an element marked data-pkt-header-keep-open', async () => {
|
|
460
|
+
const { element } = await createHeaderServiceTest({
|
|
461
|
+
'service-name': 'Svc',
|
|
462
|
+
'opened-menu': 'slot',
|
|
463
|
+
content: '<button type="button" data-pkt-header-keep-open>Vis mer</button>',
|
|
464
|
+
})
|
|
465
|
+
expect(isSlotOpen(element)).toBe(true)
|
|
466
|
+
await clickSlotChild(element, 'button')
|
|
467
|
+
expect(isSlotOpen(element)).toBe(true)
|
|
468
|
+
})
|
|
469
|
+
|
|
470
|
+
it('stays open when clicking a disabled button inside the menu', async () => {
|
|
471
|
+
const { element } = await createHeaderServiceTest({
|
|
472
|
+
'service-name': 'Svc',
|
|
473
|
+
'opened-menu': 'slot',
|
|
474
|
+
content: '<button type="button" disabled>Utilgjengelig</button>',
|
|
475
|
+
})
|
|
476
|
+
expect(isSlotOpen(element)).toBe(true)
|
|
477
|
+
await clickSlotChild(element, 'button')
|
|
478
|
+
expect(isSlotOpen(element)).toBe(true)
|
|
479
|
+
})
|
|
480
|
+
})
|
|
404
481
|
})
|
|
@@ -253,6 +253,24 @@ export class PktHeaderService extends PktElementWithSlot<IPktHeader> implements
|
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
+
// Close the slot menu when the user makes an intentional click inside it.
|
|
257
|
+
private handleSlotContentClick = (event: MouseEvent) => {
|
|
258
|
+
if (!this.isTablet || this.openMenu !== 'slot') return
|
|
259
|
+
|
|
260
|
+
const interactive = (event.target as HTMLElement).closest<HTMLElement>(
|
|
261
|
+
'a[href], button, [role="link"], [role="button"], [role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"]',
|
|
262
|
+
)
|
|
263
|
+
if (!interactive || !this.slotContentRef.value?.contains(interactive)) return
|
|
264
|
+
if (interactive.closest('[data-pkt-header-keep-open]')) return
|
|
265
|
+
if (
|
|
266
|
+
(interactive as HTMLButtonElement).disabled ||
|
|
267
|
+
interactive.getAttribute('aria-disabled') === 'true'
|
|
268
|
+
)
|
|
269
|
+
return
|
|
270
|
+
|
|
271
|
+
this.openMenu = 'none'
|
|
272
|
+
}
|
|
273
|
+
|
|
256
274
|
private handleFocusOut = (event: FocusEvent, menuType: THeaderMenu) => {
|
|
257
275
|
const relatedTarget = event.relatedTarget as HTMLElement | null
|
|
258
276
|
|
|
@@ -483,7 +501,11 @@ export class PktHeaderService extends PktElementWithSlot<IPktHeader> implements
|
|
|
483
501
|
|
|
484
502
|
// No link - just render the text
|
|
485
503
|
return html`
|
|
486
|
-
<span
|
|
504
|
+
<span
|
|
505
|
+
class="pkt-header-service__service-name"
|
|
506
|
+
translate="no"
|
|
507
|
+
@click=${this.handleServiceClick}
|
|
508
|
+
>
|
|
487
509
|
<span class="pkt-header-service__service-link">${this.serviceName}</span>
|
|
488
510
|
</span>
|
|
489
511
|
`
|
|
@@ -529,6 +551,7 @@ export class PktHeaderService extends PktElementWithSlot<IPktHeader> implements
|
|
|
529
551
|
id="mobile-slot-menu"
|
|
530
552
|
role=${this.isTablet ? 'menu' : nothing}
|
|
531
553
|
aria-label=${this.isTablet ? 'Meny' : nothing}
|
|
554
|
+
@click=${this.handleSlotContentClick}
|
|
532
555
|
${ref(this.slotContentRef)}
|
|
533
556
|
>
|
|
534
557
|
${slotContent(this)}
|