@postnord/pn-marketweb-components 1.0.18 → 1.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/cjs/loader.cjs.js +1 -1
  2. package/cjs/pn-filter-checkbox.cjs.entry.js +67 -0
  3. package/cjs/pn-language-selector_9.cjs.entry.js +29 -13
  4. package/cjs/pn-mainnav-link.cjs.entry.js +1 -1
  5. package/cjs/{pn-mainnav-store-661b0b11.js → pn-mainnav-store-87a95686.js} +1 -0
  6. package/cjs/pn-market-web-components.cjs.js +1 -1
  7. package/cjs/pn-marketweb-sitefooter.cjs.entry.js +1 -1
  8. package/cjs/pn-marketweb-siteheader.cjs.entry.js +29 -8
  9. package/collection/collection-manifest.json +1 -0
  10. package/collection/components/input/pn-filter-checkbox/checkbox.stories.js +34 -0
  11. package/collection/components/input/pn-filter-checkbox/pn-filter-checkbox.css +73 -0
  12. package/collection/components/input/pn-filter-checkbox/pn-filter-checkbox.js +183 -0
  13. package/collection/components/layout-components/pn-marketweb-sitefooter/pn-marketweb-sitefooter.js +0 -1
  14. package/collection/components/layout-components/pn-marketweb-siteheader/pn-marketweb-siteheader-login.js +44 -5
  15. package/collection/components/layout-components/pn-marketweb-siteheader/pn-marketweb-siteheader-loginmanager.js +9 -5
  16. package/collection/components/layout-components/pn-marketweb-siteheader/pn-marketweb-siteheader.js +77 -8
  17. package/collection/components/layout-components/pn-marketweb-siteheader/pn-marketweb-siteheader.stories.js +18 -3
  18. package/collection/components/navigation/pn-language-selector/pn-language-selector.js +19 -2
  19. package/collection/components/navigation/pn-mainnav/pn-mainnav-level.css +3 -0
  20. package/collection/components/navigation/pn-mainnav/pn-mainnav-level.js +5 -1
  21. package/collection/components/navigation/pn-mainnav/pn-mainnav-store.js +1 -0
  22. package/collection/components/navigation/pn-mainnav/pn-mainnav.js +1 -1
  23. package/custom-elements/index.d.ts +6 -0
  24. package/custom-elements/index.js +127 -25
  25. package/esm/loader.js +1 -1
  26. package/esm/pn-filter-checkbox.entry.js +63 -0
  27. package/esm/pn-language-selector_9.entry.js +30 -14
  28. package/esm/pn-mainnav-link.entry.js +1 -1
  29. package/esm/{pn-mainnav-store-4b030e31.js → pn-mainnav-store-8e518460.js} +1 -0
  30. package/esm/pn-market-web-components.js +1 -1
  31. package/esm/pn-marketweb-sitefooter.entry.js +1 -1
  32. package/esm/pn-marketweb-siteheader.entry.js +29 -8
  33. package/esm-es5/loader.js +1 -1
  34. package/esm-es5/pn-filter-checkbox.entry.js +1 -0
  35. package/esm-es5/pn-language-selector_9.entry.js +1 -1
  36. package/esm-es5/pn-mainnav-link.entry.js +1 -1
  37. package/esm-es5/pn-mainnav-store-8e518460.js +1 -0
  38. package/esm-es5/pn-market-web-components.js +1 -1
  39. package/esm-es5/pn-marketweb-sitefooter.entry.js +1 -1
  40. package/esm-es5/pn-marketweb-siteheader.entry.js +1 -1
  41. package/package.json +2 -2
  42. package/pn-market-web-components/{p-a354ab84.system.entry.js → p-02eed66e.system.entry.js} +1 -1
  43. package/pn-market-web-components/{p-facf4ecb.system.entry.js → p-251d44f2.system.entry.js} +1 -1
  44. package/pn-market-web-components/p-25bdf3f8.system.js +1 -1
  45. package/pn-market-web-components/p-8680c074.entry.js +1 -0
  46. package/pn-market-web-components/p-86a9f853.system.js +1 -0
  47. package/pn-market-web-components/p-88ab0d91.system.entry.js +1 -0
  48. package/pn-market-web-components/p-8c072330.entry.js +1 -0
  49. package/pn-market-web-components/p-8d62c46f.system.entry.js +1 -0
  50. package/pn-market-web-components/p-8dad5ed9.js +1 -0
  51. package/pn-market-web-components/{p-e5e7e50e.entry.js → p-ae0e5fd8.entry.js} +1 -1
  52. package/pn-market-web-components/p-d7441208.entry.js +1 -0
  53. package/pn-market-web-components/p-dd22803d.system.entry.js +1 -0
  54. package/pn-market-web-components/{p-f7d60229.entry.js → p-e220ea83.entry.js} +1 -1
  55. package/pn-market-web-components/pn-market-web-components.esm.js +1 -1
  56. package/types/components/input/pn-filter-checkbox/pn-filter-checkbox.d.ts +22 -0
  57. package/types/components/layout-components/pn-marketweb-siteheader/pn-marketweb-siteheader-login.d.ts +3 -0
  58. package/types/components/layout-components/pn-marketweb-siteheader/pn-marketweb-siteheader-loginmanager.d.ts +7 -2
  59. package/types/components/layout-components/pn-marketweb-siteheader/pn-marketweb-siteheader.d.ts +8 -1
  60. package/types/components/navigation/pn-language-selector/pn-language-selector.d.ts +2 -0
  61. package/types/components/navigation/pn-mainnav/pn-mainnav-store.d.ts +2 -0
  62. package/types/components.d.ts +63 -0
  63. package/esm-es5/pn-mainnav-store-4b030e31.js +0 -1
  64. package/pn-market-web-components/p-14f9acfd.entry.js +0 -1
  65. package/pn-market-web-components/p-2da203c9.system.entry.js +0 -1
  66. package/pn-market-web-components/p-582dbd9c.entry.js +0 -1
  67. package/pn-market-web-components/p-6b735c44.system.js +0 -1
  68. package/pn-market-web-components/p-7f853b67.system.entry.js +0 -1
  69. package/pn-market-web-components/p-a74e5481.js +0 -1
@@ -0,0 +1,183 @@
1
+ import { Component, Prop, h, Host, Element, Listen } from "@stencil/core";
2
+ export class PnFilterCheckbox {
3
+ constructor() {
4
+ this.disabled = false;
5
+ this.checked = false;
6
+ this.indeterminate = false;
7
+ }
8
+ handlechange() {
9
+ this.indeterminate = false;
10
+ }
11
+ componentDidLoad() {
12
+ this.checkAndSetIndeterminateState();
13
+ this.bindEvents();
14
+ }
15
+ componentDidUpdate() {
16
+ this.checkAndSetIndeterminateState();
17
+ }
18
+ bindEvents() {
19
+ const labels = document.querySelectorAll('label[for="' + this.checkboxid + '"]');
20
+ labels.forEach((label) => {
21
+ label.addEventListener('click', () => {
22
+ this.hostElement.shadowRoot.querySelector('label').click();
23
+ });
24
+ });
25
+ const checkboxInput = this.hostElement.shadowRoot.querySelector('input');
26
+ checkboxInput.addEventListener('change', this.onCheckboxChange.bind(this, checkboxInput));
27
+ }
28
+ onCheckboxChange(checkboxInput) {
29
+ let outsideInput = this.hostElement.querySelector("input.hidden-" + this.checkboxid);
30
+ if (outsideInput) {
31
+ outsideInput.value = (checkboxInput.checked) ? this.value : "";
32
+ }
33
+ }
34
+ checkAndSetIndeterminateState() {
35
+ let checkbox = this.hostElement.querySelector(`#${this.checkboxid}`);
36
+ if (checkbox) {
37
+ checkbox.indeterminate = this.indeterminate;
38
+ }
39
+ }
40
+ renderInputOutsideShadowRoot() {
41
+ var _a;
42
+ let input = this.hostElement.querySelector("input.hidden-" + this.checkboxid);
43
+ if (!input) {
44
+ input = this.hostElement.ownerDocument.createElement("input");
45
+ input.type = "hidden";
46
+ input.classList.add("hidden-" + this.checkboxid);
47
+ this.hostElement.appendChild(input);
48
+ }
49
+ input.name = (_a = this.name) !== null && _a !== void 0 ? _a : this.checkboxid;
50
+ }
51
+ render() {
52
+ this.renderInputOutsideShadowRoot();
53
+ return (h(Host, { checked: this.checked, id: this.checkboxid },
54
+ h("input", { type: "checkbox", id: this.checkboxid, value: this.value, name: this.name || this.checkboxid, disabled: this.disabled, checked: this.checked }),
55
+ h("label", { htmlFor: this.checkboxid, class: "pn-checkbox" },
56
+ h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none" },
57
+ h("polyline", { class: "checkmark-path", points: "4,12 9,17 20,6", "stroke-width": "3" }),
58
+ h("polyline", { class: "indeterminate-path", points: "4,12 20,12", "stroke-width": "3" })))));
59
+ }
60
+ static get is() { return "pn-filter-checkbox"; }
61
+ static get encapsulation() { return "shadow"; }
62
+ static get originalStyleUrls() { return {
63
+ "$": ["pn-filter-checkbox.scss"]
64
+ }; }
65
+ static get styleUrls() { return {
66
+ "$": ["pn-filter-checkbox.css"]
67
+ }; }
68
+ static get properties() { return {
69
+ "value": {
70
+ "type": "any",
71
+ "mutable": false,
72
+ "complexType": {
73
+ "original": "any",
74
+ "resolved": "any",
75
+ "references": {}
76
+ },
77
+ "required": false,
78
+ "optional": false,
79
+ "docs": {
80
+ "tags": [],
81
+ "text": "This will be emitted on change and input, like a native checkbox"
82
+ },
83
+ "attribute": "value",
84
+ "reflect": true
85
+ },
86
+ "name": {
87
+ "type": "string",
88
+ "mutable": false,
89
+ "complexType": {
90
+ "original": "string",
91
+ "resolved": "string",
92
+ "references": {}
93
+ },
94
+ "required": false,
95
+ "optional": false,
96
+ "docs": {
97
+ "tags": [],
98
+ "text": "The name of the checkbox group"
99
+ },
100
+ "attribute": "name",
101
+ "reflect": false
102
+ },
103
+ "checkboxid": {
104
+ "type": "string",
105
+ "mutable": false,
106
+ "complexType": {
107
+ "original": "string",
108
+ "resolved": "string",
109
+ "references": {}
110
+ },
111
+ "required": false,
112
+ "optional": false,
113
+ "docs": {
114
+ "tags": [],
115
+ "text": "The string you put here will be what you'd make the ID of a native radio button, you can't name props \"id\" because it's reserved\nso we went with the more descriptive name \"checkboxid\", if you want to create labels for your checkbox, you will bind it to this ID"
116
+ },
117
+ "attribute": "checkboxid",
118
+ "reflect": false
119
+ },
120
+ "disabled": {
121
+ "type": "boolean",
122
+ "mutable": false,
123
+ "complexType": {
124
+ "original": "boolean",
125
+ "resolved": "boolean",
126
+ "references": {}
127
+ },
128
+ "required": false,
129
+ "optional": true,
130
+ "docs": {
131
+ "tags": [],
132
+ "text": ""
133
+ },
134
+ "attribute": "disabled",
135
+ "reflect": false,
136
+ "defaultValue": "false"
137
+ },
138
+ "checked": {
139
+ "type": "boolean",
140
+ "mutable": false,
141
+ "complexType": {
142
+ "original": "boolean",
143
+ "resolved": "boolean",
144
+ "references": {}
145
+ },
146
+ "required": false,
147
+ "optional": true,
148
+ "docs": {
149
+ "tags": [],
150
+ "text": ""
151
+ },
152
+ "attribute": "checked",
153
+ "reflect": false,
154
+ "defaultValue": "false"
155
+ },
156
+ "indeterminate": {
157
+ "type": "boolean",
158
+ "mutable": true,
159
+ "complexType": {
160
+ "original": "boolean",
161
+ "resolved": "boolean",
162
+ "references": {}
163
+ },
164
+ "required": false,
165
+ "optional": true,
166
+ "docs": {
167
+ "tags": [],
168
+ "text": ""
169
+ },
170
+ "attribute": "indeterminate",
171
+ "reflect": false,
172
+ "defaultValue": "false"
173
+ }
174
+ }; }
175
+ static get elementRef() { return "hostElement"; }
176
+ static get listeners() { return [{
177
+ "name": "change",
178
+ "method": "handlechange",
179
+ "target": undefined,
180
+ "capture": false,
181
+ "passive": false
182
+ }]; }
183
+ }
@@ -109,7 +109,6 @@ export class PnMarketwebSiteheader {
109
109
  render() {
110
110
  var _a, _b, _c, _d, _e;
111
111
  return (h(Host, { language: this.language, market: this.market, environment: this.environment },
112
- h("button", { onClick: () => { this.language = "en"; } }, "en"),
113
112
  h("pn-site-footer", { url: (_b = (_a = this.siteDefinition) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : "" },
114
113
  (this.gotData && ((_c = this.footerContent) === null || _c === void 0 ? void 0 : _c.columns)) ? this.footerContent.columns.map((column) => (h("pn-site-footer-col", null,
115
114
  h("h3", null, column.heading),
@@ -1,9 +1,10 @@
1
- import { Component, Prop, h, State, Element, Watch } from "@stencil/core";
1
+ import { Component, Prop, h, State, Element, Watch, Event } from "@stencil/core";
2
2
  import { PNLoginManager } from "./pn-marketweb-siteheader-loginmanager";
3
3
  export class PnMarketwebSiteheaderLogin {
4
4
  constructor() {
5
5
  /** Specifies which endpoint domain we should load from */
6
6
  this.endpoint = "";
7
+ this.emitEvents = true;
7
8
  // Login dialog
8
9
  this.loginDialog = null;
9
10
  this.loginManager = null;
@@ -12,11 +13,12 @@ export class PnMarketwebSiteheaderLogin {
12
13
  }
13
14
  componentWillLoad() {
14
15
  this.loginManager = new PNLoginManager({ endpoint: this.endpoint, eventTarget: this.hostElement });
16
+ this.hostElement["loginmanager"] = this.loginManager;
17
+ this.hostElement.addEventListener(this.loginManager.events.loginstatechange, this.onLoginStateChange.bind(this));
15
18
  this.init();
16
19
  }
17
20
  async init() {
18
21
  this.toggleButtonText = this.loginDialog.loginMenuLinkText;
19
- this.hostElement.addEventListener(this.loginManager.events.loginstatechange, this.onLoginStateChange.bind(this));
20
22
  this.loginManager.init();
21
23
  this.setToggleButtonText();
22
24
  }
@@ -35,8 +37,11 @@ export class PnMarketwebSiteheaderLogin {
35
37
  }
36
38
  }
37
39
  onLoginStateChange(e) {
38
- this.loggedIn = e.detail;
39
- this.setToggleButtonText();
40
+ if (this.loggedIn !== e.detail && this.emitEvents) {
41
+ this.loggedIn = e.detail;
42
+ this.loginStateChange.emit({ loggedIn: this.loggedIn, token: this.loginManager.getToken() });
43
+ this.setToggleButtonText();
44
+ }
40
45
  }
41
46
  render() {
42
47
  var _a, _b, _c;
@@ -64,7 +69,7 @@ export class PnMarketwebSiteheaderLogin {
64
69
  h("div", null,
65
70
  h("ul", null, this.loginDialog.loggedInLinks.map((link) => {
66
71
  const isLogoutLink = link.href.indexOf('logout');
67
- const href = (isLogoutLink) ? this.loginManager.getLogoutUrl(link.href.replace('logout', '')) : link.href;
72
+ const href = (isLogoutLink) ? this.loginManager.getLogoutUrl(link.href.replace('logout', '').replace('http://window.location.href/?', '').replace('https://window.location.href/?', '')) : link.href;
68
73
  return (h("li", null,
69
74
  h("a", Object.assign({ href: href }, (link.openInNewWindow && { target: '_blank' })),
70
75
  h("pn-button", { appearance: (link.primaryLinkApperance ? "dark" : "light"), onClick: () => { if (isLogoutLink) {
@@ -119,6 +124,24 @@ export class PnMarketwebSiteheaderLogin {
119
124
  "attribute": "i-1-8n",
120
125
  "reflect": false
121
126
  },
127
+ "emitEvents": {
128
+ "type": "boolean",
129
+ "mutable": false,
130
+ "complexType": {
131
+ "original": "boolean",
132
+ "resolved": "boolean",
133
+ "references": {}
134
+ },
135
+ "required": false,
136
+ "optional": false,
137
+ "docs": {
138
+ "tags": [],
139
+ "text": ""
140
+ },
141
+ "attribute": "emit-events",
142
+ "reflect": false,
143
+ "defaultValue": "true"
144
+ },
122
145
  "loginDialog": {
123
146
  "type": "unknown",
124
147
  "mutable": true,
@@ -146,6 +169,22 @@ export class PnMarketwebSiteheaderLogin {
146
169
  "loggedIn": {},
147
170
  "toggleButtonText": {}
148
171
  }; }
172
+ static get events() { return [{
173
+ "method": "loginStateChange",
174
+ "name": "loginStateChange",
175
+ "bubbles": true,
176
+ "cancelable": true,
177
+ "composed": true,
178
+ "docs": {
179
+ "tags": [],
180
+ "text": ""
181
+ },
182
+ "complexType": {
183
+ "original": "any",
184
+ "resolved": "any",
185
+ "references": {}
186
+ }
187
+ }]; }
149
188
  static get elementRef() { return "hostElement"; }
150
189
  static get watchers() { return [{
151
190
  "propName": "i18n",
@@ -110,10 +110,11 @@ class PNLoginManager {
110
110
  const params = new URLSearchParams(window.location.search);
111
111
  if (params.get("oneTimeCode")) {
112
112
  const oneTimeCode = params.get("oneTimeCode");
113
- this.getToken(oneTimeCode);
114
- const currentHref = window.location.href;
115
- const paramPrefix = (currentHref.indexOf('?oneTimeCode') !== -1) ? "?" : "&";
116
- history.replaceState({}, document.querySelector('title').innerText, currentHref.replace(`${paramPrefix}oneTimeCode=${oneTimeCode}`, ''));
113
+ this.exchangeToken(oneTimeCode).then(() => {
114
+ const currentHref = window.location.href;
115
+ const paramPrefix = (currentHref.indexOf('?oneTimeCode') !== -1) ? "?" : "&";
116
+ history.replaceState({}, document.querySelector('title').innerText, currentHref.replace(`${paramPrefix}oneTimeCode=${oneTimeCode}`, ''));
117
+ });
117
118
  }
118
119
  }
119
120
  async fetchUserInfo() {
@@ -149,7 +150,10 @@ class PNLoginManager {
149
150
  this.store.remove(this.keys.expire);
150
151
  this.store.remove(this.keys.expireDate);
151
152
  }
152
- async getToken(oneTimeCode) {
153
+ getToken() {
154
+ return this.store.get(this.keys.token);
155
+ }
156
+ async exchangeToken(oneTimeCode) {
153
157
  this.clearUserData();
154
158
  const response = await fetch(`${this.getBaseUrl()}${this.endpoints.tokenExchangeEndpoint}?oneTimeCode=${oneTimeCode}`);
155
159
  const { token } = await response.json();
@@ -22,6 +22,10 @@ export class PnMarketwebSiteheader {
22
22
  this.hideSearch = false;
23
23
  /** Hides the login if set to true*/
24
24
  this.hideLogin = false;
25
+ /** Forward session to backend */
26
+ this.sessionForward = false;
27
+ /** Event based only language switch */
28
+ this.spaMode = false;
25
29
  this.gotData = false;
26
30
  this.fetchingData = false;
27
31
  // Menu state
@@ -62,11 +66,6 @@ export class PnMarketwebSiteheader {
62
66
  this.endpoint = "";
63
67
  }
64
68
  }
65
- // TODO
66
- //* Expose market and language attributes when changed internally
67
- //* Business logic to select market and language depending on domains / html tag.
68
- //* Property to stop language change from changeing url, throw an event instead.
69
- //* Fetch new data when langauge or market is changed
70
69
  async init() {
71
70
  this.setTranslations();
72
71
  await this.fetchData();
@@ -77,6 +76,9 @@ export class PnMarketwebSiteheader {
77
76
  this.i18n = translations[this.language];
78
77
  }
79
78
  }
79
+ onLanguageSelectorChange(e) {
80
+ this.language = e.detail;
81
+ }
80
82
  onLanguageChange() {
81
83
  this.setTranslations();
82
84
  this.changeLanguage.emit(this.language);
@@ -96,9 +98,12 @@ export class PnMarketwebSiteheader {
96
98
  const fetchUrl = `${endpointBase}${this.endpointPath}?market=${this.market}&language=${this.language}`;
97
99
  const response = await fetch(fetchUrl);
98
100
  const data = await response.json();
99
- this.setStateFromData(data);
101
+ await this.setStateFromData(data);
100
102
  }
101
103
  getLanguageVersionUrl(item) {
104
+ if (this.spaMode) {
105
+ return null;
106
+ }
102
107
  const alternativeTag = document.querySelector(`link[rel="alternate"][hreflang="${item.twoLetterISOLanguageName}"]`);
103
108
  if (alternativeTag) {
104
109
  return alternativeTag.getAttribute('href');
@@ -107,7 +112,7 @@ export class PnMarketwebSiteheader {
107
112
  // Add trailing slash to domain if it's missing
108
113
  return siteUrl + ((siteUrl.lastIndexOf("/") !== siteUrl.length - 1) ? "/" : "") + item.twoLetterISOLanguageName;
109
114
  }
110
- setStateFromData(data) {
115
+ async setStateFromData(data) {
111
116
  if (typeof data !== "object") {
112
117
  console.warn('Data was not valid', data);
113
118
  }
@@ -131,10 +136,26 @@ export class PnMarketwebSiteheader {
131
136
  // Set language selector
132
137
  this.languageSelector = data.languageSelectorViewModel;
133
138
  this.loginDialog = data.loginViewModel;
139
+ await this.spaModeAdjustments();
134
140
  this.gotData = true;
135
141
  this.fetchingData = true;
136
142
  window.setTimeout(() => { this.checkMenuOverflow(); }, 100);
137
143
  }
144
+ async spaModeAdjustments() {
145
+ if (!this.spaMode) {
146
+ return;
147
+ }
148
+ return;
149
+ }
150
+ onLoginStateChange(e) {
151
+ var _a, _b;
152
+ if (((_a = e.detail) === null || _a === void 0 ? void 0 : _a.loggedIn) && ((_b = e.detail) === null || _b === void 0 ? void 0 : _b.token) && this.sessionForward) {
153
+ try {
154
+ fetch('/api/userprofile/sync?token=' + e.detail.token);
155
+ }
156
+ catch (e) { }
157
+ }
158
+ }
138
159
  promotedItemId(item) {
139
160
  return "promo-" + item.linkText.replace(/[^A-Za-z0-9.\\\/]/igm, "");
140
161
  }
@@ -204,7 +225,7 @@ export class PnMarketwebSiteheader {
204
225
  h("pn-mainnav-list", { heading: item.promotedMenuItemsHeader }, item.promotedMenuItems.map((childitem) => (h("pn-mainnav-link", { href: childitem.href, name: childitem.linkText, target: childitem.openInNewWindow ? "_blank" : "_self", linkid: this.promotedItemId(childitem) })))))));
205
226
  })),
206
227
  h("div", { slot: "footer", class: "siteheader-menu-footer" },
207
- (this.gotData && this.loginDialog && !this.hideLogin) && (h("pn-marketweb-siteheader-login", { loginDialog: this.loginDialog, endpoint: this.endpoint, i18n: this.i18n })),
228
+ (this.gotData && this.loginDialog && !this.hideLogin) && (h("pn-marketweb-siteheader-login", { emitEvents: false, loginDialog: this.loginDialog, endpoint: this.endpoint, i18n: this.i18n })),
208
229
  (this.gotData && ((_h = this.languageSelector) === null || _h === void 0 ? void 0 : _h.languages)) && !this.hideLanguageSelector &&
209
230
  h("pn-language-selector", { value: this.language }, this.languageSelector.languages.map(language => h("pn-language-selector-option", { name: language.nativeName, code: language.twoLetterISOLanguageName, selected: language.isCurrent, url: this.getLanguageVersionUrl(language) }))),
210
231
  !this.hideSiteSelector &&
@@ -367,6 +388,42 @@ export class PnMarketwebSiteheader {
367
388
  "attribute": "hide-login",
368
389
  "reflect": true,
369
390
  "defaultValue": "false"
391
+ },
392
+ "sessionForward": {
393
+ "type": "boolean",
394
+ "mutable": false,
395
+ "complexType": {
396
+ "original": "boolean",
397
+ "resolved": "boolean",
398
+ "references": {}
399
+ },
400
+ "required": false,
401
+ "optional": false,
402
+ "docs": {
403
+ "tags": [],
404
+ "text": "Forward session to backend"
405
+ },
406
+ "attribute": "session-forward",
407
+ "reflect": false,
408
+ "defaultValue": "false"
409
+ },
410
+ "spaMode": {
411
+ "type": "boolean",
412
+ "mutable": false,
413
+ "complexType": {
414
+ "original": "boolean",
415
+ "resolved": "boolean",
416
+ "references": {}
417
+ },
418
+ "required": false,
419
+ "optional": false,
420
+ "docs": {
421
+ "tags": [],
422
+ "text": "Event based only language switch"
423
+ },
424
+ "attribute": "spa-mode",
425
+ "reflect": false,
426
+ "defaultValue": "false"
370
427
  }
371
428
  }; }
372
429
  static get states() { return {
@@ -421,6 +478,18 @@ export class PnMarketwebSiteheader {
421
478
  "methodName": "onMarketChange"
422
479
  }]; }
423
480
  static get listeners() { return [{
481
+ "name": "setLanguage",
482
+ "method": "onLanguageSelectorChange",
483
+ "target": undefined,
484
+ "capture": false,
485
+ "passive": false
486
+ }, {
487
+ "name": "loginStateChange",
488
+ "method": "onLoginStateChange",
489
+ "target": undefined,
490
+ "capture": false,
491
+ "passive": false
492
+ }, {
424
493
  "name": "resize",
425
494
  "method": "handleResize",
426
495
  "target": "window",
@@ -48,7 +48,8 @@ const PrimaryTemplate = ({ ...args }) => {
48
48
  hide-site-selector="false"
49
49
  hide-language-selector="false"
50
50
  hide-search="false"
51
- hide-login="false">
51
+ hide-login="false"
52
+ session-forward="true">
52
53
  </pn-marketweb-siteheader>
53
54
  <div style="height:120vh; margin:2em; max-width:calc(100vw - 1em);background:#ccc;border:1px solid #333;">
54
55
  Content that is higher than 100% viewport height
@@ -74,11 +75,25 @@ const MinimalOptionsTemplate = ({ ...args }) => {
74
75
  `;
75
76
  };
76
77
 
77
-
78
-
79
78
  export const MinimalOptions = MinimalOptionsTemplate.bind({});
80
79
  MinimalOptionsTemplate.args = {
81
80
  market : "",
82
81
  language: '',
83
82
  endpoint: ''
84
83
  };
84
+
85
+ const SPAModeOptionsTemplate = ({ ...args }) => {
86
+ return `
87
+ <div style="background:#ddd;min-height:100vh;">
88
+ <pn-marketweb-siteheader language="sv" spa-mode="true">
89
+ </pn-marketweb-siteheader>
90
+ </div>
91
+ `;
92
+ };
93
+
94
+ export const SPAModeOptions = SPAModeOptionsTemplate.bind({});
95
+ SPAModeOptions.args = {
96
+ market : "",
97
+ language: '',
98
+ endpoint: ''
99
+ };
@@ -1,4 +1,4 @@
1
- import { Component, Prop, h, State, Host, Watch, Element } from "@stencil/core";
1
+ import { Component, Prop, h, State, Host, Watch, Element, Event } from "@stencil/core";
2
2
  import { translations } from "./translations";
3
3
  export class PnlanguageSelector {
4
4
  constructor() {
@@ -41,6 +41,7 @@ export class PnlanguageSelector {
41
41
  onSetCurrentLanguage(option) {
42
42
  this.value = option.code;
43
43
  this.selectedLanguageName = option.name;
44
+ this.setLanguage.emit(this.value);
44
45
  }
45
46
  setTranslations() {
46
47
  if (translations[this.value]) {
@@ -77,7 +78,7 @@ export class PnlanguageSelector {
77
78
  static get properties() { return {
78
79
  "value": {
79
80
  "type": "string",
80
- "mutable": false,
81
+ "mutable": true,
81
82
  "complexType": {
82
83
  "original": "string",
83
84
  "resolved": "string",
@@ -99,6 +100,22 @@ export class PnlanguageSelector {
99
100
  "options": {},
100
101
  "i18n": {}
101
102
  }; }
103
+ static get events() { return [{
104
+ "method": "setLanguage",
105
+ "name": "setLanguage",
106
+ "bubbles": true,
107
+ "cancelable": true,
108
+ "composed": true,
109
+ "docs": {
110
+ "tags": [],
111
+ "text": ""
112
+ },
113
+ "complexType": {
114
+ "original": "any",
115
+ "resolved": "any",
116
+ "references": {}
117
+ }
118
+ }]; }
102
119
  static get elementRef() { return "hostElement"; }
103
120
  static get watchers() { return [{
104
121
  "propName": "value",
@@ -102,6 +102,9 @@ pn-mainnav-level [slot=top] {
102
102
  display: none;
103
103
  }
104
104
  }
105
+ [data-menu-currentlevel="2"] pn-mainnav-level [slot=footer] {
106
+ display: none;
107
+ }
105
108
 
106
109
  .mainnav-level-header {
107
110
  grid-area: top;
@@ -56,12 +56,16 @@ export class PnMainnavLevel {
56
56
  }
57
57
  onChangeOpenLevel() {
58
58
  this.isOpen = state.openLevel === this.levelId;
59
+ state.currentLevel = this.level;
59
60
  }
60
61
  render() {
61
62
  return (h(Host, Object.assign({ role: "navigation" }, ((this.level > 1 && this.levelId) ? { 'aria-hidden': (!this.isOpen) + '' } : {}), { "data-level-listcount": this.listCount + '', "data-level-alignment": this.alignment, "data-level": this.level + '' }, (this.levelId ? { id: this.levelId } : {})),
62
63
  (this.level > 1) ? (h("div", { class: "mainnav-level-header" },
63
64
  h("label", { htmlFor: this.levelId }, state.i18n.menuGoBackButton),
64
- h("button", { class: "secondlevel-backbtn", onClick: () => state.openLevel = '', "aria-expanded": (state.openLevel === this.levelId) + '' },
65
+ h("button", { class: "secondlevel-backbtn", onClick: () => {
66
+ state.openLevel = '';
67
+ state.currentLevel = 1;
68
+ }, "aria-expanded": (state.openLevel === this.levelId) + '' },
65
69
  h("pn-icon", { symbol: "arrow-left", color: "blue700" }),
66
70
  state.i18n.menuStartButton),
67
71
  (this.parentHref && this.parentName) ? h("pn-mainnav-link", { href: this.parentHref, name: this.parentName, linkid: this.parentLinkId }) : null)) : null,
@@ -2,6 +2,7 @@ import { createStore } from "@stencil/store";
2
2
  // Read more about how stencil stores work here: https://stenciljs.com/docs/stencil-store
3
3
  const { state, onChange } = createStore({
4
4
  openLevel: '',
5
+ currentLevel: 1,
5
6
  openMenu: false,
6
7
  i18n: {
7
8
  menuHomeButton: '',
@@ -56,7 +56,7 @@ export class PnMainnav {
56
56
  h("button", { "aria-controls": this.navigationId, "aria-expanded": state.openMenu + '', onClick: this.setMenuOpenState.bind(this) },
57
57
  state.i18n.mainMenuButton,
58
58
  h("pn-icon", { symbol: state.openMenu ? "close" : "bars", color: "white" }))),
59
- h("nav", { class: "mainnav", "aria-label": this.navLabel, "data-menu-open": state.openMenu + '', id: this.navigationId },
59
+ h("nav", { class: "mainnav", "aria-label": this.navLabel, "data-menu-open": state.openMenu + '', "data-menu-currentlevel": state.currentLevel, id: this.navigationId },
60
60
  h("slot", null))));
61
61
  }
62
62
  static get is() { return "pn-mainnav"; }
@@ -8,6 +8,12 @@ export const PnChoiceButton: {
8
8
  new (): PnChoiceButton;
9
9
  };
10
10
 
11
+ interface PnFilterCheckbox extends Components.PnFilterCheckbox, HTMLElement {}
12
+ export const PnFilterCheckbox: {
13
+ prototype: PnFilterCheckbox;
14
+ new (): PnFilterCheckbox;
15
+ };
16
+
11
17
  interface PnFilterSearch extends Components.PnFilterSearch, HTMLElement {}
12
18
  export const PnFilterSearch: {
13
19
  prototype: PnFilterSearch;