@oslokommune/punkt-elements 16.10.0 → 16.12.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/tabs/tabs.d.ts +5 -0
- package/dist/docs/components/tabs.d.ts +11 -7
- package/dist/pkt-index.cjs +1 -1
- package/dist/pkt-index.js +1 -1
- package/dist/pkt-tabs.cjs +1 -1
- package/dist/pkt-tabs.js +1 -1
- package/dist/{tabs-COwm9b3n.cjs → tabs-BfurI6C3.cjs} +7 -7
- package/dist/{tabs-C0DWPmn2.js → tabs-Rc9N9HWa.js} +34 -9
- package/package.json +3 -3
- package/src/components/tabs/tabitem.ts +2 -1
- package/src/components/tabs/tabs.test.ts +30 -0
- package/src/components/tabs/tabs.ts +40 -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.11.0](https://github.com/oslokommune/punkt/compare/16.10.0...16.11.0) (2026-04-29)
|
|
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.10.0](https://github.com/oslokommune/punkt/compare/16.9.1...16.10.0) (2026-04-22)
|
|
9
26
|
|
|
10
27
|
### ⚠ BREAKING CHANGES
|
|
@@ -3,16 +3,21 @@ import { PropertyValues } from 'lit';
|
|
|
3
3
|
export interface IPktTabs {
|
|
4
4
|
arrowNav?: boolean;
|
|
5
5
|
disableArrowNav?: boolean;
|
|
6
|
+
separatorIconName?: string;
|
|
7
|
+
separatorIconPath?: string;
|
|
6
8
|
}
|
|
7
9
|
export declare class PktTabs extends PktElementWithSlot<IPktTabs> implements IPktTabs {
|
|
8
10
|
arrowNav: boolean;
|
|
9
11
|
disableArrowNav: boolean;
|
|
12
|
+
separatorIconName: string;
|
|
13
|
+
separatorIconPath: string;
|
|
10
14
|
private tabRefs;
|
|
11
15
|
private disabledMap;
|
|
12
16
|
private tabCount;
|
|
13
17
|
private get useArrowNav();
|
|
14
18
|
private context;
|
|
15
19
|
updated(changedProperties: PropertyValues): void;
|
|
20
|
+
private syncSeparators;
|
|
16
21
|
private registerTab;
|
|
17
22
|
private isTabDisabled;
|
|
18
23
|
private findEnabledIndex;
|
|
@@ -8,20 +8,24 @@ export declare class Tabs extends PktElement {
|
|
|
8
8
|
private activeTab5;
|
|
9
9
|
private activeTab6;
|
|
10
10
|
private activeTab7;
|
|
11
|
+
private activeStepperTab;
|
|
12
|
+
private stepperTitles;
|
|
13
|
+
private stepperCompleted;
|
|
14
|
+
private stepperUnlocked;
|
|
15
|
+
private stepperSeparatorIconName;
|
|
16
|
+
private stepperRenderKey;
|
|
11
17
|
private activeTabTest;
|
|
12
18
|
private tabTitles;
|
|
13
19
|
private disabledTabs;
|
|
14
20
|
private skins;
|
|
15
21
|
private tabNames;
|
|
16
22
|
private content;
|
|
17
|
-
private
|
|
18
|
-
private handleTabSelected2;
|
|
19
|
-
private handleTabSelected3;
|
|
20
|
-
private handleTabSelected4;
|
|
21
|
-
private handleTabSelected5;
|
|
22
|
-
private handleTabSelected6;
|
|
23
|
-
private handleTabSelected7;
|
|
23
|
+
private handleTabSelected;
|
|
24
24
|
private handleTabTestSelected;
|
|
25
|
+
private handleStepperTabSelected;
|
|
26
|
+
private completeActiveStepperTab;
|
|
27
|
+
private resetStepperFlow;
|
|
28
|
+
private handleSeparatorIconNameChange;
|
|
25
29
|
private updateTabTitle;
|
|
26
30
|
private toggleDisabledTab;
|
|
27
31
|
private addDynamicDisabledTab;
|
package/dist/pkt-index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./alert-BEEnTiCb.cjs`),t=require(`./icon-Dr8sfT2X.cjs`),n=require(`./button-D-TOBaJB.cjs`),r=require(`./accordion-BB1JrONI.cjs`),i=require(`./backlink-Ba03LlbB.cjs`),a=require(`./breadcrumbs-CD1zib3s.cjs`),o=require(`./calendar-E5jJLt8D.cjs`),s=require(`./card-CUFhMVim.cjs`),c=require(`./tag-DLthw5b4.cjs`),l=require(`./heading-BgSWIRii.cjs`),u=require(`./combobox-CGbFTWq_.cjs`),d=require(`./header-DWgPgGfS.cjs`),f=require(`./datepicker-DpmlsnH_.cjs`),p=require(`./helptext-D-3QfZv5.cjs`),m=require(`./input-wrapper-BRuVELpK.cjs`),h=require(`./consent-hwu7pp3S.cjs`),g=require(`./checkbox-BARDb9iV.cjs`),_=require(`./link-CyTCpI0k.cjs`),v=require(`./textinput-DFh8_9cx.cjs`),y=require(`./linkcard-BE4-FewK.cjs`),b=require(`./loader-CX2rsC01.cjs`),x=require(`./messagebox-Din9X53b.cjs`),S=require(`./modal-CBEWrAi2.cjs`),C=require(`./progressbar-CdXtmOBb.cjs`),w=require(`./radiobutton-GOnpUbCW.cjs`),T=require(`./tabs-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./alert-BEEnTiCb.cjs`),t=require(`./icon-Dr8sfT2X.cjs`),n=require(`./button-D-TOBaJB.cjs`),r=require(`./accordion-BB1JrONI.cjs`),i=require(`./backlink-Ba03LlbB.cjs`),a=require(`./breadcrumbs-CD1zib3s.cjs`),o=require(`./calendar-E5jJLt8D.cjs`),s=require(`./card-CUFhMVim.cjs`),c=require(`./tag-DLthw5b4.cjs`),l=require(`./heading-BgSWIRii.cjs`),u=require(`./combobox-CGbFTWq_.cjs`),d=require(`./header-DWgPgGfS.cjs`),f=require(`./datepicker-DpmlsnH_.cjs`),p=require(`./helptext-D-3QfZv5.cjs`),m=require(`./input-wrapper-BRuVELpK.cjs`),h=require(`./consent-hwu7pp3S.cjs`),g=require(`./checkbox-BARDb9iV.cjs`),_=require(`./link-CyTCpI0k.cjs`),v=require(`./textinput-DFh8_9cx.cjs`),y=require(`./linkcard-BE4-FewK.cjs`),b=require(`./loader-CX2rsC01.cjs`),x=require(`./messagebox-Din9X53b.cjs`),S=require(`./modal-CBEWrAi2.cjs`),C=require(`./progressbar-CdXtmOBb.cjs`),w=require(`./radiobutton-GOnpUbCW.cjs`),T=require(`./tabs-BfurI6C3.cjs`),E=require(`./textarea-D7aGOyDf.cjs`),D=require(`./select-C2i8sOk5.cjs`),O=require(`./timepicker-BIfE7KKJ.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=g.n,exports.PktCombobox=u.n,exports.PktConsent=h.n,exports.PktDateTags=f.a,exports.PktDatepicker=f.t,exports.PktHeader=d.t,exports.PktHeaderService=d.n,exports.PktHeaderUserMenu=d.r,exports.PktHeading=l.n,exports.PktHelptext=p.n,exports.PktIcon=t.n,exports.PktInputWrapper=m.n,exports.PktLink=_.n,exports.PktLinkCard=y.n,exports.PktLoader=b.n,exports.PktMessagebox=x.n,exports.PktModal=S.n,exports.PktProgressbar=C.n,exports.PktRadioButton=w.n,exports.PktRadiobutton=w.n,exports.PktSelect=D.n,exports.PktTabItem=T.n,exports.PktTabs=T.r,exports.PktTag=c.n,exports.PktTextarea=E.n,exports.PktTextinput=v.n,exports.PktTimepicker=O.t;
|
package/dist/pkt-index.js
CHANGED
|
@@ -23,7 +23,7 @@ import { n as T } from "./messagebox-Cwlg5sOr.js";
|
|
|
23
23
|
import { n as E } from "./modal-pPp8nia6.js";
|
|
24
24
|
import { n as D } from "./progressbar-Dy9AiYQz.js";
|
|
25
25
|
import { n as O } from "./radiobutton-V_KPbup_.js";
|
|
26
|
-
import { n as k, r as A } from "./tabs-
|
|
26
|
+
import { n as k, r as A } from "./tabs-Rc9N9HWa.js";
|
|
27
27
|
import { n as j } from "./textarea-DYOBhJrN.js";
|
|
28
28
|
import { n as M } from "./select-BSAFd8Wa.js";
|
|
29
29
|
import { t as N } from "./timepicker-DaSwn1FA.js";
|
package/dist/pkt-tabs.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require(`./tabs-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require(`./tabs-BfurI6C3.cjs`);exports.PktTabItem=e.n,exports.PktTabs=e.r,exports.default=e.t;
|
package/dist/pkt-tabs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as e, r as t, t as n } from "./tabs-
|
|
1
|
+
import { n as e, r as t, t as n } from "./tabs-Rc9N9HWa.js";
|
|
2
2
|
export { e as PktTabItem, t as PktTabs, n as default };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
const e=require(`./element-DjtxO-1r.cjs`),t=require(`./element-with-slot-CWoTGA1B.cjs`),n=require(`./if-defined-XKOD_t_V.cjs`),r=require(`./ref-BaJ0mBT_.cjs`);var i=class extends Event{constructor(e,t,n,r){super(`context-request`,{bubbles:!0,composed:!0}),this.context=e,this.contextTarget=t,this.callback=n,this.subscribe=r??!1}};function a(e){return e}var o=class{constructor(e,t,n,r){if(this.subscribe=!1,this.provided=!1,this.value=void 0,this.t=(e,t)=>{this.unsubscribe&&(this.unsubscribe!==t&&(this.provided=!1,this.unsubscribe()),this.subscribe||this.unsubscribe()),this.value=e,this.host.requestUpdate(),this.provided&&!this.subscribe||(this.provided=!0,this.callback&&this.callback(e,t)),this.unsubscribe=t},this.host=e,t.context!==void 0){let e=t;this.context=e.context,this.callback=e.callback,this.subscribe=e.subscribe??!1}else this.context=t,this.callback=n,this.subscribe=r??!1;this.host.addController(this)}hostConnected(){this.dispatchRequest()}hostDisconnected(){this.unsubscribe&&=(this.unsubscribe(),void 0)}dispatchRequest(){this.host.dispatchEvent(new i(this.context,this.host,this.t,this.subscribe))}},s=class{get value(){return this.o}set value(e){this.setValue(e)}setValue(e,t=!1){let n=t||!Object.is(e,this.o);this.o=e,n&&this.updateObservers()}constructor(e){this.subscriptions=new Map,this.updateObservers=()=>{for(let[e,{disposer:t}]of this.subscriptions)e(this.o,t)},e!==void 0&&(this.value=e)}addCallback(e,t,n){if(!n)return void e(this.value);this.subscriptions.has(e)||this.subscriptions.set(e,{disposer:()=>{this.subscriptions.delete(e)},consumerHost:t});let{disposer:r}=this.subscriptions.get(e);e(this.value,r)}clearCallbacks(){this.subscriptions.clear()}},c=class extends Event{constructor(e,t){super(`context-provider`,{bubbles:!0,composed:!0}),this.context=e,this.contextTarget=t}},l=class extends s{constructor(e,t,n){super(t.context===void 0?n:t.initialValue),this.onContextRequest=e=>{if(e.context!==this.context)return;let t=e.contextTarget??e.composedPath()[0];t!==this.host&&(e.stopPropagation(),this.addCallback(e.callback,t,e.subscribe))},this.onProviderRequest=e=>{if(e.context!==this.context||(e.contextTarget??e.composedPath()[0])===this.host)return;let t=new Set;for(let[e,{consumerHost:n}]of this.subscriptions)t.has(e)||(t.add(e),n.dispatchEvent(new i(this.context,n,e,!0)));e.stopPropagation()},this.host=e,t.context===void 0?this.context=t:this.context=t.context,this.attachListeners(),this.host.addController?.(this)}attachListeners(){this.host.addEventListener(`context-request`,this.onContextRequest),this.host.addEventListener(`context-provider`,this.onProviderRequest)}hostConnected(){this.host.dispatchEvent(new c(this.context,this.host))}};function u({context:e}){return(t,n)=>{let r=new WeakMap;if(typeof n==`object`)return{get(){return t.get.call(this)},set(e){return r.get(this).setValue(e),t.set.call(this,e)},init(t){return r.set(this,new l(this,{context:e,initialValue:t})),t}};{t.constructor.addInitializer((t=>{r.set(t,new l(t,{context:e}))}));let i=Object.getOwnPropertyDescriptor(t,n),a;if(i===void 0){let e=new WeakMap;a={get(){return e.get(this)},set(t){r.get(this).setValue(t),e.set(this,t)},configurable:!0,enumerable:!0}}else{let e=i.set;a={...i,set(t){r.get(this).setValue(t),e?.call(this,t)}}}Object.defineProperty(t,n,a);return}}}function d({context:e,subscribe:t}){return(n,r)=>{typeof r==`object`?r.addInitializer((function(){new o(this,{context:e,callback:e=>{n.set.call(this,e)},subscribe:t})})):n.constructor.addInitializer((n=>{new o(n,{context:e,callback:e=>{n[r]=e},subscribe:t})}))}}var f=a(Symbol(`pkt-tabs-context`)),p=class extends t.t{constructor(...e){super(...e),this.arrowNav=!0,this.disableArrowNav=!1,this.tabRefs=[],this.disabledMap={},this.tabCount=0,this.context={useArrowNav:this.useArrowNav,registerTab:this.registerTab.bind(this),handleClick:this.handleClick.bind(this),handleKeyUp:this.handleKeyUp.bind(this)}}get useArrowNav(){return this.arrowNav&&!this.disableArrowNav}updated(e){(e.has(`arrowNav`)||e.has(`disableArrowNav`))&&(this.context={...this.context,useArrowNav:this.useArrowNav})}registerTab(e,t,n=!1){this.tabRefs[t]=e,this.disabledMap[t]=n,this.tabCount=Math.max(this.tabCount,t+1)}isTabDisabled(e){return!!this.disabledMap[e]}findEnabledIndex(e,t){let n=e+t;for(;n>=0&&n<this.tabCount;){if(!this.isTabDisabled(n))return n;n+=t}return null}handleClick(e){this.isTabDisabled(e)||this.dispatchEvent(new CustomEvent(`tab-selected`,{detail:{index:e},bubbles:!0,composed:!0}))}handleKeyUp(e,t){if(this.useArrowNav){if(e.key===`ArrowLeft`){e.preventDefault();let n=this.findEnabledIndex(t,-1);n!==null&&this.tabRefs[n]?.focus()}if(e.key===`ArrowRight`){e.preventDefault();let n=this.findEnabledIndex(t,1);n!==null&&this.tabRefs[n]?.focus()}(e.key===`Enter`||e.key===` `||e.key===`Spacebar`||e.key===`ArrowDown`)&&(e.preventDefault(),this.handleClick(t))}}render(){return e.d`
|
|
2
|
-
<div class
|
|
3
|
-
<div class="pkt-tabs__list" role=${
|
|
1
|
+
const e=require(`./element-DjtxO-1r.cjs`),t=require(`./element-with-slot-CWoTGA1B.cjs`),n=require(`./if-defined-XKOD_t_V.cjs`),r=require(`./ref-BaJ0mBT_.cjs`);var i=class extends Event{constructor(e,t,n,r){super(`context-request`,{bubbles:!0,composed:!0}),this.context=e,this.contextTarget=t,this.callback=n,this.subscribe=r??!1}};function a(e){return e}var o=class{constructor(e,t,n,r){if(this.subscribe=!1,this.provided=!1,this.value=void 0,this.t=(e,t)=>{this.unsubscribe&&(this.unsubscribe!==t&&(this.provided=!1,this.unsubscribe()),this.subscribe||this.unsubscribe()),this.value=e,this.host.requestUpdate(),this.provided&&!this.subscribe||(this.provided=!0,this.callback&&this.callback(e,t)),this.unsubscribe=t},this.host=e,t.context!==void 0){let e=t;this.context=e.context,this.callback=e.callback,this.subscribe=e.subscribe??!1}else this.context=t,this.callback=n,this.subscribe=r??!1;this.host.addController(this)}hostConnected(){this.dispatchRequest()}hostDisconnected(){this.unsubscribe&&=(this.unsubscribe(),void 0)}dispatchRequest(){this.host.dispatchEvent(new i(this.context,this.host,this.t,this.subscribe))}},s=class{get value(){return this.o}set value(e){this.setValue(e)}setValue(e,t=!1){let n=t||!Object.is(e,this.o);this.o=e,n&&this.updateObservers()}constructor(e){this.subscriptions=new Map,this.updateObservers=()=>{for(let[e,{disposer:t}]of this.subscriptions)e(this.o,t)},e!==void 0&&(this.value=e)}addCallback(e,t,n){if(!n)return void e(this.value);this.subscriptions.has(e)||this.subscriptions.set(e,{disposer:()=>{this.subscriptions.delete(e)},consumerHost:t});let{disposer:r}=this.subscriptions.get(e);e(this.value,r)}clearCallbacks(){this.subscriptions.clear()}},c=class extends Event{constructor(e,t){super(`context-provider`,{bubbles:!0,composed:!0}),this.context=e,this.contextTarget=t}},l=class extends s{constructor(e,t,n){super(t.context===void 0?n:t.initialValue),this.onContextRequest=e=>{if(e.context!==this.context)return;let t=e.contextTarget??e.composedPath()[0];t!==this.host&&(e.stopPropagation(),this.addCallback(e.callback,t,e.subscribe))},this.onProviderRequest=e=>{if(e.context!==this.context||(e.contextTarget??e.composedPath()[0])===this.host)return;let t=new Set;for(let[e,{consumerHost:n}]of this.subscriptions)t.has(e)||(t.add(e),n.dispatchEvent(new i(this.context,n,e,!0)));e.stopPropagation()},this.host=e,t.context===void 0?this.context=t:this.context=t.context,this.attachListeners(),this.host.addController?.(this)}attachListeners(){this.host.addEventListener(`context-request`,this.onContextRequest),this.host.addEventListener(`context-provider`,this.onProviderRequest)}hostConnected(){this.host.dispatchEvent(new c(this.context,this.host))}};function u({context:e}){return(t,n)=>{let r=new WeakMap;if(typeof n==`object`)return{get(){return t.get.call(this)},set(e){return r.get(this).setValue(e),t.set.call(this,e)},init(t){return r.set(this,new l(this,{context:e,initialValue:t})),t}};{t.constructor.addInitializer((t=>{r.set(t,new l(t,{context:e}))}));let i=Object.getOwnPropertyDescriptor(t,n),a;if(i===void 0){let e=new WeakMap;a={get(){return e.get(this)},set(t){r.get(this).setValue(t),e.set(this,t)},configurable:!0,enumerable:!0}}else{let e=i.set;a={...i,set(t){r.get(this).setValue(t),e?.call(this,t)}}}Object.defineProperty(t,n,a);return}}}function d({context:e,subscribe:t}){return(n,r)=>{typeof r==`object`?r.addInitializer((function(){new o(this,{context:e,callback:e=>{n.set.call(this,e)},subscribe:t})})):n.constructor.addInitializer((n=>{new o(n,{context:e,callback:e=>{n[r]=e},subscribe:t})}))}}var f=a(Symbol(`pkt-tabs-context`)),p=class extends t.t{constructor(...e){super(...e),this.arrowNav=!0,this.disableArrowNav=!1,this.separatorIconName=``,this.separatorIconPath=``,this.tabRefs=[],this.disabledMap={},this.tabCount=0,this.context={useArrowNav:this.useArrowNav,registerTab:this.registerTab.bind(this),handleClick:this.handleClick.bind(this),handleKeyUp:this.handleKeyUp.bind(this)}}get useArrowNav(){return this.arrowNav&&!this.disableArrowNav}updated(e){(e.has(`arrowNav`)||e.has(`disableArrowNav`))&&(this.context={...this.context,useArrowNav:this.useArrowNav}),this.updateComplete.then(()=>this.syncSeparators())}syncSeparators(){let e=this.querySelector(`.pkt-tabs__list`);if(!e||(e.querySelectorAll(`.pkt-tabs__separator`).forEach(e=>e.remove()),!(this.separatorIconName||this.separatorIconPath)))return;let t=Array.from(e.children).filter(e=>!e.classList.contains(`pkt-tabs__separator`));for(let e=0;e<t.length-1;e++){let n=document.createElement(`span`);if(n.className=`pkt-tabs__separator`,n.setAttribute(`aria-hidden`,`true`),n.setAttribute(`role`,`presentation`),this.separatorIconPath){let e=document.createElement(`img`);e.setAttribute(`src`,this.separatorIconPath),e.setAttribute(`alt`,``),e.setAttribute(`aria-hidden`,`true`),n.appendChild(e)}else if(this.separatorIconName){let e=document.createElement(`pkt-icon`);e.setAttribute(`name`,this.separatorIconName),e.classList.add(`pkt-tabs__separator-icon`),n.appendChild(e)}t[e].after(n)}}registerTab(e,t,n=!1){this.tabRefs[t]=e,this.disabledMap[t]=n,this.tabCount=Math.max(this.tabCount,t+1)}isTabDisabled(e){return!!this.disabledMap[e]}findEnabledIndex(e,t){let n=e+t;for(;n>=0&&n<this.tabCount;){if(!this.isTabDisabled(n))return n;n+=t}return null}handleClick(e){this.isTabDisabled(e)||this.dispatchEvent(new CustomEvent(`tab-selected`,{detail:{index:e},bubbles:!0,composed:!0}))}handleKeyUp(e,t){if(this.useArrowNav){if(e.key===`ArrowLeft`){e.preventDefault();let n=this.findEnabledIndex(t,-1);n!==null&&this.tabRefs[n]?.focus()}if(e.key===`ArrowRight`){e.preventDefault();let n=this.findEnabledIndex(t,1);n!==null&&this.tabRefs[n]?.focus()}(e.key===`Enter`||e.key===` `||e.key===`Spacebar`||e.key===`ArrowDown`)&&(e.preventDefault(),this.handleClick(t))}}render(){let n=this.useArrowNav?`tablist`:`navigation`;return e.d`
|
|
2
|
+
<div class=${this.separatorIconName||this.separatorIconPath?`pkt-tabs pkt-tabs--with-separator`:`pkt-tabs`}>
|
|
3
|
+
<div class="pkt-tabs__list" role=${n}>${t.n(this)}</div>
|
|
4
4
|
</div>
|
|
5
|
-
`}};e.r([e.s({type:Boolean,reflect:!0,attribute:`arrow-nav`})],p.prototype,`arrowNav`,void 0),e.r([e.s({type:Boolean,reflect:!0,attribute:`disable-arrow-nav`})],p.prototype,`disableArrowNav`,void 0),e.r([e.o()],p.prototype,`tabRefs`,void 0),e.r([e.o()],p.prototype,`disabledMap`,void 0),e.r([e.o()],p.prototype,`tabCount`,void 0),e.r([u({context:f}),e.o()],p.prototype,`context`,void 0);try{e.c(`pkt-tabs`)(p)}catch{console.warn(`Forsøker å definere <pkt-tabs>, men den er allerede definert`)}var m=class extends t.t{constructor(){super(),this.active=!1,this.disabled=!1,this.href=``,this.icon=``,this.controls=``,this.tag=``,this.tagSkin=`blue`,this.index=0,this.elementRef=r.t()}connectedCallback(){super.connectedCallback(),this.updateComplete.then(()=>{this.elementRef.value&&this.context&&this.context.registerTab(this.elementRef.value,this.index,this.disabled)})}updated(){this.elementRef.value&&this.context&&this.context.registerTab(this.elementRef.value,this.index,this.disabled)}handleClick(e){if(this.disabled){e.preventDefault(),e.stopPropagation();return}this.context&&this.context.handleClick(this.index)}handleKeyDown(e){if(this.disabled&&(e.key===`Enter`||e.key===` `||e.key===`Spacebar`)){e.preventDefault(),e.stopPropagation();return}this.context&&this.context.handleKeyUp(e,this.index)}render(){let i=this.context?.useArrowNav??!0,a=this.active&&!this.disabled,o=[a?`active`:``,this.disabled?`pkt-tabs__item--disabled`:``].filter(Boolean).join(` `),s=i?`tab`:void 0,c=i?a:void 0,l=this.disabled?-1:a||!i?void 0:-1,u=e.d`
|
|
6
|
-
${this.icon?e.d`<pkt-icon name=${this.icon} class
|
|
5
|
+
`}};e.r([e.s({type:Boolean,reflect:!0,attribute:`arrow-nav`})],p.prototype,`arrowNav`,void 0),e.r([e.s({type:Boolean,reflect:!0,attribute:`disable-arrow-nav`})],p.prototype,`disableArrowNav`,void 0),e.r([e.s({type:String,reflect:!0,attribute:`separator-icon-name`})],p.prototype,`separatorIconName`,void 0),e.r([e.s({type:String,reflect:!0,attribute:`separator-icon-path`})],p.prototype,`separatorIconPath`,void 0),e.r([e.o()],p.prototype,`tabRefs`,void 0),e.r([e.o()],p.prototype,`disabledMap`,void 0),e.r([e.o()],p.prototype,`tabCount`,void 0),e.r([u({context:f}),e.o()],p.prototype,`context`,void 0);try{e.c(`pkt-tabs`)(p)}catch{console.warn(`Forsøker å definere <pkt-tabs>, men den er allerede definert`)}var m=class extends t.t{constructor(){super(),this.active=!1,this.disabled=!1,this.href=``,this.icon=``,this.controls=``,this.tag=``,this.tagSkin=`blue`,this.index=0,this.elementRef=r.t()}connectedCallback(){super.connectedCallback(),this.updateComplete.then(()=>{this.elementRef.value&&this.context&&this.context.registerTab(this.elementRef.value,this.index,this.disabled)})}updated(){this.elementRef.value&&this.context&&this.context.registerTab(this.elementRef.value,this.index,this.disabled)}handleClick(e){if(this.disabled){e.preventDefault(),e.stopPropagation();return}this.context&&this.context.handleClick(this.index)}handleKeyDown(e){if(this.disabled&&(e.key===`Enter`||e.key===` `||e.key===`Spacebar`)){e.preventDefault(),e.stopPropagation();return}this.context&&this.context.handleKeyUp(e,this.index)}render(){let i=this.context?.useArrowNav??!0,a=this.active&&!this.disabled,o=[a?`active`:``,this.disabled?`pkt-tabs__item--disabled`:``].filter(Boolean).join(` `),s=i?`tab`:void 0,c=i?a:void 0,l=this.disabled?-1:a||!i?void 0:-1,u=`pkt-icon--small ${this.icon===`check`?`pkt-tabs__status-icon`:``}`,d=e.d`
|
|
6
|
+
${this.icon?e.d`<pkt-icon name=${this.icon} class=${u}></pkt-icon>`:``}
|
|
7
7
|
<span>${t.n(this)}</span>
|
|
8
8
|
${this.tag?e.d`<pkt-tag skin=${this.tagSkin} size="small">${this.tag}</pkt-tag>`:``}
|
|
9
9
|
`;return this.href?e.d`
|
|
@@ -19,7 +19,7 @@ const e=require(`./element-DjtxO-1r.cjs`),t=require(`./element-with-slot-CWoTGA1
|
|
|
19
19
|
@click=${this.handleClick}
|
|
20
20
|
@keydown=${this.handleKeyDown}
|
|
21
21
|
>
|
|
22
|
-
${
|
|
22
|
+
${d}
|
|
23
23
|
</a>
|
|
24
24
|
`:e.d`
|
|
25
25
|
<button
|
|
@@ -35,6 +35,6 @@ const e=require(`./element-DjtxO-1r.cjs`),t=require(`./element-with-slot-CWoTGA1
|
|
|
35
35
|
@click=${this.handleClick}
|
|
36
36
|
@keydown=${this.handleKeyDown}
|
|
37
37
|
>
|
|
38
|
-
${
|
|
38
|
+
${d}
|
|
39
39
|
</button>
|
|
40
40
|
`}};e.r([e.s({type:Boolean,reflect:!0})],m.prototype,`active`,void 0),e.r([e.s({type:Boolean,reflect:!0})],m.prototype,`disabled`,void 0),e.r([e.s({type:String,reflect:!0})],m.prototype,`href`,void 0),e.r([e.s({type:String,reflect:!0})],m.prototype,`icon`,void 0),e.r([e.s({type:String,reflect:!0})],m.prototype,`controls`,void 0),e.r([e.s({type:String,reflect:!0})],m.prototype,`tag`,void 0),e.r([e.s({type:String,reflect:!0,attribute:`tag-skin`})],m.prototype,`tagSkin`,void 0),e.r([e.s({type:Number,reflect:!0})],m.prototype,`index`,void 0),e.r([d({context:f,subscribe:!0}),e.s({attribute:!1})],m.prototype,`context`,void 0);try{e.c(`pkt-tab-item`)(m)}catch{console.warn(`Forsøker å definere <pkt-tab-item>, men den er allerede definert`)}var h=p;Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return h}});
|
|
@@ -171,7 +171,7 @@ function _({ context: e, subscribe: t }) {
|
|
|
171
171
|
//#region src/components/tabs/tabs-context.ts
|
|
172
172
|
var v = d(Symbol("pkt-tabs-context")), y = class extends o {
|
|
173
173
|
constructor(...e) {
|
|
174
|
-
super(...e), this.arrowNav = !0, this.disableArrowNav = !1, this.tabRefs = [], this.disabledMap = {}, this.tabCount = 0, this.context = {
|
|
174
|
+
super(...e), this.arrowNav = !0, this.disableArrowNav = !1, this.separatorIconName = "", this.separatorIconPath = "", this.tabRefs = [], this.disabledMap = {}, this.tabCount = 0, this.context = {
|
|
175
175
|
useArrowNav: this.useArrowNav,
|
|
176
176
|
registerTab: this.registerTab.bind(this),
|
|
177
177
|
handleClick: this.handleClick.bind(this),
|
|
@@ -185,7 +185,23 @@ var v = d(Symbol("pkt-tabs-context")), y = class extends o {
|
|
|
185
185
|
(e.has("arrowNav") || e.has("disableArrowNav")) && (this.context = {
|
|
186
186
|
...this.context,
|
|
187
187
|
useArrowNav: this.useArrowNav
|
|
188
|
-
});
|
|
188
|
+
}), this.updateComplete.then(() => this.syncSeparators());
|
|
189
|
+
}
|
|
190
|
+
syncSeparators() {
|
|
191
|
+
let e = this.querySelector(".pkt-tabs__list");
|
|
192
|
+
if (!e || (e.querySelectorAll(".pkt-tabs__separator").forEach((e) => e.remove()), !(this.separatorIconName || this.separatorIconPath))) return;
|
|
193
|
+
let t = Array.from(e.children).filter((e) => !e.classList.contains("pkt-tabs__separator"));
|
|
194
|
+
for (let e = 0; e < t.length - 1; e++) {
|
|
195
|
+
let n = document.createElement("span");
|
|
196
|
+
if (n.className = "pkt-tabs__separator", n.setAttribute("aria-hidden", "true"), n.setAttribute("role", "presentation"), this.separatorIconPath) {
|
|
197
|
+
let e = document.createElement("img");
|
|
198
|
+
e.setAttribute("src", this.separatorIconPath), e.setAttribute("alt", ""), e.setAttribute("aria-hidden", "true"), n.appendChild(e);
|
|
199
|
+
} else if (this.separatorIconName) {
|
|
200
|
+
let e = document.createElement("pkt-icon");
|
|
201
|
+
e.setAttribute("name", this.separatorIconName), e.classList.add("pkt-tabs__separator-icon"), n.appendChild(e);
|
|
202
|
+
}
|
|
203
|
+
t[e].after(n);
|
|
204
|
+
}
|
|
189
205
|
}
|
|
190
206
|
registerTab(e, t, n = !1) {
|
|
191
207
|
this.tabRefs[t] = e, this.disabledMap[t] = n, this.tabCount = Math.max(this.tabCount, t + 1);
|
|
@@ -224,9 +240,10 @@ var v = d(Symbol("pkt-tabs-context")), y = class extends o {
|
|
|
224
240
|
}
|
|
225
241
|
}
|
|
226
242
|
render() {
|
|
243
|
+
let e = this.useArrowNav ? "tablist" : "navigation";
|
|
227
244
|
return t`
|
|
228
|
-
<div class
|
|
229
|
-
<div class="pkt-tabs__list" role=${
|
|
245
|
+
<div class=${this.separatorIconName || this.separatorIconPath ? "pkt-tabs pkt-tabs--with-separator" : "pkt-tabs"}>
|
|
246
|
+
<div class="pkt-tabs__list" role=${e}>${a(this)}</div>
|
|
230
247
|
</div>
|
|
231
248
|
`;
|
|
232
249
|
}
|
|
@@ -239,7 +256,15 @@ r([i({
|
|
|
239
256
|
type: Boolean,
|
|
240
257
|
reflect: !0,
|
|
241
258
|
attribute: "disable-arrow-nav"
|
|
242
|
-
})], y.prototype, "disableArrowNav", void 0), r([
|
|
259
|
+
})], y.prototype, "disableArrowNav", void 0), r([i({
|
|
260
|
+
type: String,
|
|
261
|
+
reflect: !0,
|
|
262
|
+
attribute: "separator-icon-name"
|
|
263
|
+
})], y.prototype, "separatorIconName", void 0), r([i({
|
|
264
|
+
type: String,
|
|
265
|
+
reflect: !0,
|
|
266
|
+
attribute: "separator-icon-path"
|
|
267
|
+
})], y.prototype, "separatorIconPath", void 0), r([n()], y.prototype, "tabRefs", void 0), r([n()], y.prototype, "disabledMap", void 0), r([n()], y.prototype, "tabCount", void 0), r([g({ context: v }), n()], y.prototype, "context", void 0);
|
|
243
268
|
try {
|
|
244
269
|
e("pkt-tabs")(y);
|
|
245
270
|
} catch {
|
|
@@ -274,8 +299,8 @@ var b = class extends o {
|
|
|
274
299
|
this.context && this.context.handleKeyUp(e, this.index);
|
|
275
300
|
}
|
|
276
301
|
render() {
|
|
277
|
-
let e = this.context?.useArrowNav ?? !0, n = this.active && !this.disabled, r = [n ? "active" : "", this.disabled ? "pkt-tabs__item--disabled" : ""].filter(Boolean).join(" "), i = e ? "tab" : void 0, o = e ? n : void 0, l = this.disabled ? -1 : n || !e ? void 0 : -1, u = t`
|
|
278
|
-
${this.icon ? t`<pkt-icon name=${this.icon} class
|
|
302
|
+
let e = this.context?.useArrowNav ?? !0, n = this.active && !this.disabled, r = [n ? "active" : "", this.disabled ? "pkt-tabs__item--disabled" : ""].filter(Boolean).join(" "), i = e ? "tab" : void 0, o = e ? n : void 0, l = this.disabled ? -1 : n || !e ? void 0 : -1, u = `pkt-icon--small ${this.icon === "check" ? "pkt-tabs__status-icon" : ""}`, d = t`
|
|
303
|
+
${this.icon ? t`<pkt-icon name=${this.icon} class=${u}></pkt-icon>` : ""}
|
|
279
304
|
<span>${a(this)}</span>
|
|
280
305
|
${this.tag ? t`<pkt-tag skin=${this.tagSkin} size="small">${this.tag}</pkt-tag>` : ""}
|
|
281
306
|
`;
|
|
@@ -292,7 +317,7 @@ var b = class extends o {
|
|
|
292
317
|
@click=${this.handleClick}
|
|
293
318
|
@keydown=${this.handleKeyDown}
|
|
294
319
|
>
|
|
295
|
-
${
|
|
320
|
+
${d}
|
|
296
321
|
</a>
|
|
297
322
|
` : t`
|
|
298
323
|
<button
|
|
@@ -308,7 +333,7 @@ var b = class extends o {
|
|
|
308
333
|
@click=${this.handleClick}
|
|
309
334
|
@keydown=${this.handleKeyDown}
|
|
310
335
|
>
|
|
311
|
-
${
|
|
336
|
+
${d}
|
|
312
337
|
</button>
|
|
313
338
|
`;
|
|
314
339
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oslokommune/punkt-elements",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.12.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",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@babel/plugin-transform-private-property-in-object": "^7.25.9",
|
|
42
42
|
"@babel/preset-env": "^7.28.3",
|
|
43
43
|
"@babel/preset-typescript": "^7.25.9",
|
|
44
|
-
"@oslokommune/punkt-assets": "^16.
|
|
44
|
+
"@oslokommune/punkt-assets": "^16.12.0",
|
|
45
45
|
"@testing-library/jest-dom": "^6.6.3",
|
|
46
46
|
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
|
47
47
|
"@typescript-eslint/parser": "^8.46.0",
|
|
@@ -78,5 +78,5 @@
|
|
|
78
78
|
"url": "https://github.com/oslokommune/punkt/issues"
|
|
79
79
|
},
|
|
80
80
|
"license": "MIT",
|
|
81
|
-
"gitHead": "
|
|
81
|
+
"gitHead": "6a61829c404cb9efe379f57046bc8704f09b1e26"
|
|
82
82
|
}
|
|
@@ -91,8 +91,9 @@ export class PktTabItem extends PktElementWithSlot<IPktTabItem> implements IPktT
|
|
|
91
91
|
const ariaSelected = useArrowNav ? isActive : undefined
|
|
92
92
|
const tabIndex = this.disabled ? -1 : isActive || !useArrowNav ? undefined : -1
|
|
93
93
|
|
|
94
|
+
const iconClasses = `pkt-icon--small ${this.icon === 'check' ? 'pkt-tabs__status-icon' : ''}`
|
|
94
95
|
const content = html`
|
|
95
|
-
${this.icon ? html`<pkt-icon name=${this.icon} class
|
|
96
|
+
${this.icon ? html`<pkt-icon name=${this.icon} class=${iconClasses}></pkt-icon>` : ''}
|
|
96
97
|
<span>${slotContent(this)}</span>
|
|
97
98
|
${this.tag ? html`<pkt-tag skin=${this.tagSkin} size="small">${this.tag}</pkt-tag>` : ''}
|
|
98
99
|
`
|
|
@@ -132,6 +132,20 @@ describe('PktTabs', () => {
|
|
|
132
132
|
|
|
133
133
|
expect(tabs.disableArrowNav).toBe(true)
|
|
134
134
|
})
|
|
135
|
+
|
|
136
|
+
test('applies separator class on tabs root when separator icon is provided', async () => {
|
|
137
|
+
const container = await createTabs('separator-icon-name="arrow-right"')
|
|
138
|
+
const tabsRoot = container.querySelector('.pkt-tabs')
|
|
139
|
+
expect(tabsRoot).toHaveClass('pkt-tabs--with-separator')
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
test('uses separator-icon-path when both separator props are provided', async () => {
|
|
143
|
+
const container = await createTabs(
|
|
144
|
+
'separator-icon-name="arrow-right" separator-icon-path="/custom.svg"',
|
|
145
|
+
)
|
|
146
|
+
const separatorImage = container.querySelector('.pkt-tabs__separator img')
|
|
147
|
+
expect(separatorImage?.getAttribute('src')).toBe('/custom.svg')
|
|
148
|
+
})
|
|
135
149
|
})
|
|
136
150
|
|
|
137
151
|
describe('Tab item props', () => {
|
|
@@ -536,6 +550,22 @@ describe('PktTabs', () => {
|
|
|
536
550
|
|
|
537
551
|
expect(tabList).toHaveAttribute('role', 'navigation')
|
|
538
552
|
})
|
|
553
|
+
|
|
554
|
+
test('keeps tab semantics when separators are enabled', async () => {
|
|
555
|
+
const container = await createTabs('separator-icon-name="arrow-right"')
|
|
556
|
+
const tabList = container.querySelector('.pkt-tabs__list')
|
|
557
|
+
const buttons = container.querySelectorAll('pkt-tab-item button')
|
|
558
|
+
|
|
559
|
+
expect(tabList).toHaveAttribute('role', 'tablist')
|
|
560
|
+
buttons.forEach((button) => {
|
|
561
|
+
expect(button).toHaveAttribute('role', 'tab')
|
|
562
|
+
})
|
|
563
|
+
})
|
|
564
|
+
|
|
565
|
+
test('renders decorative separators in DOM', async () => {
|
|
566
|
+
const container = await createTabs('separator-icon-name="arrow-right"')
|
|
567
|
+
expect(container.querySelectorAll('.pkt-tabs__separator')).toHaveLength(2)
|
|
568
|
+
})
|
|
539
569
|
})
|
|
540
570
|
|
|
541
571
|
describe('Multiple tab items', () => {
|
|
@@ -8,12 +8,16 @@ import { tabsContext, type TabsContext } from './tabs-context'
|
|
|
8
8
|
export interface IPktTabs {
|
|
9
9
|
arrowNav?: boolean
|
|
10
10
|
disableArrowNav?: boolean
|
|
11
|
+
separatorIconName?: string
|
|
12
|
+
separatorIconPath?: string
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
export class PktTabs extends PktElementWithSlot<IPktTabs> implements IPktTabs {
|
|
14
16
|
@property({ type: Boolean, reflect: true, attribute: 'arrow-nav' }) arrowNav: boolean = true
|
|
15
17
|
@property({ type: Boolean, reflect: true, attribute: 'disable-arrow-nav' })
|
|
16
18
|
disableArrowNav: boolean = false
|
|
19
|
+
@property({ type: String, reflect: true, attribute: 'separator-icon-name' }) separatorIconName: string = ''
|
|
20
|
+
@property({ type: String, reflect: true, attribute: 'separator-icon-path' }) separatorIconPath: string = ''
|
|
17
21
|
|
|
18
22
|
@state() private tabRefs: Array<HTMLAnchorElement | HTMLButtonElement | null> = []
|
|
19
23
|
@state() private disabledMap: Record<number, boolean> = {}
|
|
@@ -41,6 +45,39 @@ export class PktTabs extends PktElementWithSlot<IPktTabs> implements IPktTabs {
|
|
|
41
45
|
useArrowNav: this.useArrowNav,
|
|
42
46
|
}
|
|
43
47
|
}
|
|
48
|
+
this.updateComplete.then(() => this.syncSeparators())
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private syncSeparators() {
|
|
52
|
+
// Slotted tab items require post-render DOM sync for decorative separators.
|
|
53
|
+
const list = this.querySelector('.pkt-tabs__list')
|
|
54
|
+
if (!list) return
|
|
55
|
+
|
|
56
|
+
list.querySelectorAll('.pkt-tabs__separator').forEach((separator) => separator.remove())
|
|
57
|
+
const hasSeparator = !!(this.separatorIconName || this.separatorIconPath)
|
|
58
|
+
if (!hasSeparator) return
|
|
59
|
+
|
|
60
|
+
const items = Array.from(list.children).filter((child) => !child.classList.contains('pkt-tabs__separator'))
|
|
61
|
+
for (let i = 0; i < items.length - 1; i++) {
|
|
62
|
+
const separator = document.createElement('span')
|
|
63
|
+
separator.className = 'pkt-tabs__separator'
|
|
64
|
+
separator.setAttribute('aria-hidden', 'true')
|
|
65
|
+
separator.setAttribute('role', 'presentation')
|
|
66
|
+
|
|
67
|
+
if (this.separatorIconPath) {
|
|
68
|
+
const img = document.createElement('img')
|
|
69
|
+
img.setAttribute('src', this.separatorIconPath)
|
|
70
|
+
img.setAttribute('alt', '')
|
|
71
|
+
img.setAttribute('aria-hidden', 'true')
|
|
72
|
+
separator.appendChild(img)
|
|
73
|
+
} else if (this.separatorIconName) {
|
|
74
|
+
const icon = document.createElement('pkt-icon')
|
|
75
|
+
icon.setAttribute('name', this.separatorIconName)
|
|
76
|
+
icon.classList.add('pkt-tabs__separator-icon')
|
|
77
|
+
separator.appendChild(icon)
|
|
78
|
+
}
|
|
79
|
+
items[i].after(separator)
|
|
80
|
+
}
|
|
44
81
|
}
|
|
45
82
|
|
|
46
83
|
private registerTab(element: HTMLElement, index: number, disabled = false) {
|
|
@@ -104,9 +141,11 @@ export class PktTabs extends PktElementWithSlot<IPktTabs> implements IPktTabs {
|
|
|
104
141
|
|
|
105
142
|
render() {
|
|
106
143
|
const role = this.useArrowNav ? 'tablist' : 'navigation'
|
|
144
|
+
const hasSeparator = !!(this.separatorIconName || this.separatorIconPath)
|
|
145
|
+
const tabsClass = hasSeparator ? 'pkt-tabs pkt-tabs--with-separator' : 'pkt-tabs'
|
|
107
146
|
|
|
108
147
|
return html`
|
|
109
|
-
<div class
|
|
148
|
+
<div class=${tabsClass}>
|
|
110
149
|
<div class="pkt-tabs__list" role=${role}>${slotContent(this)}</div>
|
|
111
150
|
</div>
|
|
112
151
|
`
|