@record-evolution/widget-navbutton 1.0.7 → 1.0.9

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.
@@ -1,16 +1,16 @@
1
- import { css as c, LitElement as d, html as m } from "lit";
2
- import { property as h, state as p, customElement as u } from "lit/decorators.js";
1
+ import { css as c, LitElement as h, html as u } from "lit";
2
+ import { property as p, state as m, customElement as d } from "lit/decorators.js";
3
3
  import "@material/web/icon/icon.js";
4
4
  import "@material/web/button/filled-button.js";
5
5
  import "@material/web/ripple/ripple.js";
6
- var f = Object.defineProperty, b = Object.getOwnPropertyDescriptor, s = (t, e, o, l) => {
7
- for (var i = l > 1 ? void 0 : l ? b(e, o) : e, n = t.length - 1, a; n >= 0; n--)
8
- (a = t[n]) && (i = (l ? a(e, o, i) : a(i)) || i);
9
- return l && i && f(e, o, i), i;
6
+ var f = Object.defineProperty, b = Object.getOwnPropertyDescriptor, s = (t, e, o, r) => {
7
+ for (var i = r > 1 ? void 0 : r ? b(e, o) : e, n = t.length - 1, a; n >= 0; n--)
8
+ (a = t[n]) && (i = (r ? a(e, o, i) : a(i)) || i);
9
+ return r && i && f(e, o, i), i;
10
10
  };
11
- let r = class extends d {
11
+ let l = class extends h {
12
12
  constructor() {
13
- super(...arguments), this.version = "1.0.7";
13
+ super(...arguments), this.version = "1.0.9";
14
14
  }
15
15
  update(t) {
16
16
  t.has("theme") && this.registerTheme(this.theme), super.update(t);
@@ -22,31 +22,44 @@ let r = class extends d {
22
22
  const e = getComputedStyle(this).getPropertyValue("--re-text-color").trim(), o = getComputedStyle(this).getPropertyValue("--re-tile-background-color").trim();
23
23
  this.themeBgColor = o || this.theme?.theme_object?.backgroundColor, this.themeTitleColor = e || this.theme?.theme_object?.title?.textStyle?.color;
24
24
  }
25
- handleNavItemClick(t) {
26
- let e;
27
- this.inputData?.route === "" ? (e = "/" + this.route?.split("/").filter(Boolean).slice(0, -1).join("/") + "/" || "/", e = e === "//" ? "/" : e) : e = this.inputData?.route || "/", console.log("Navigating to:", t, this.route, { goto: e });
28
- const o = new CustomEvent("nav-submit", {
29
- detail: { path: e },
25
+ handleNavItemClick() {
26
+ let t;
27
+ this.inputData?.route === "" ? (t = "/" + this.route?.split("/").filter(Boolean).slice(0, -1).join("/") + "/" || "/", t = t === "//" ? "/" : t) : t = this.resolveRoute({
28
+ route: this.inputData?.route,
29
+ variables: this.inputData?.variables
30
+ }) || "/";
31
+ const e = new CustomEvent("nav-submit", {
32
+ detail: { path: t },
30
33
  bubbles: !0,
31
34
  composed: !0
32
35
  });
33
- this.dispatchEvent(o);
36
+ this.dispatchEvent(e);
34
37
  }
35
- addSlashes(t) {
36
- return !t.route?.endsWith("/") && t.trailingSlash && (t.route += "/"), !t.route?.startsWith("/") && t.leadingSlash && (t.route = "/" + t.route), t.route;
38
+ resolveRoute(t) {
39
+ let e = String(t?.route ?? "");
40
+ if (t?.variables)
41
+ for (const o of t.variables)
42
+ o.label && (e = e.split(`{{${o.label}}}`).join(encodeURIComponent(String(o.value ?? ""))));
43
+ if (e.includes("*")) {
44
+ const o = (this.route || "").split("/").filter(Boolean), r = e.split("/").filter(Boolean);
45
+ for (let i = 0; i < r.length; i++)
46
+ r[i] === "*" && (r[i] = o[i] ?? "");
47
+ e = (e.startsWith("/") ? "/" : "") + r.filter(Boolean).join("/");
48
+ }
49
+ return e;
37
50
  }
38
51
  render() {
39
- const t = this.inputData?.style?.fontSize ?? 16, e = (this.inputData?.style?.fontSize ?? 16) * 1.5, o = this.inputData?.style?.color || this.themeTitleColor || "black", l = this.inputData?.style?.backgroundColor || this.themeBgColor || "white";
40
- return m`
52
+ const t = this.inputData?.style?.fontSize ?? 16, e = (this.inputData?.style?.fontSize ?? 16) * 1.5, o = this.inputData?.style?.color || this.themeTitleColor || "black", r = this.inputData?.style?.backgroundColor || this.themeBgColor || "white";
53
+ return u`
41
54
  <md-filled-button
42
55
  style="font-size: ${t}px;
43
56
  --md-filled-button-label-text-color: ${o};
44
57
  --md-filled-button-hover-label-text-color: ${o};
45
58
  --md-filled-button-pressed-label-text-color: ${o};
46
59
  --md-filled-button-focus-label-text-color: ${o};
47
- --md-filled-button-container-color: ${l};
60
+ --md-filled-button-container-color: ${r};
48
61
  "
49
- @click=${() => this.handleNavItemClick(this.addSlashes(this.inputData))}
62
+ @click=${() => this.handleNavItemClick()}
50
63
  >
51
64
  ${this.inputData?.title}
52
65
  <md-ripple></md-ripple>
@@ -57,7 +70,7 @@ let r = class extends d {
57
70
  `;
58
71
  }
59
72
  };
60
- r.styles = c`
73
+ l.styles = c`
61
74
  :host {
62
75
  display: flex;
63
76
  align-items: center;
@@ -83,24 +96,24 @@ r.styles = c`
83
96
  }
84
97
  `;
85
98
  s([
86
- h({ type: Object })
87
- ], r.prototype, "inputData", 2);
99
+ p({ type: Object })
100
+ ], l.prototype, "inputData", 2);
88
101
  s([
89
- h({ type: Object })
90
- ], r.prototype, "theme", 2);
102
+ p({ type: Object })
103
+ ], l.prototype, "theme", 2);
91
104
  s([
92
- h({ type: String })
93
- ], r.prototype, "route", 2);
105
+ p({ type: String })
106
+ ], l.prototype, "route", 2);
94
107
  s([
95
- p()
96
- ], r.prototype, "themeBgColor", 2);
108
+ m()
109
+ ], l.prototype, "themeBgColor", 2);
97
110
  s([
98
- p()
99
- ], r.prototype, "themeTitleColor", 2);
100
- r = s([
101
- u("widget-navbutton-1.0.7")
102
- ], r);
111
+ m()
112
+ ], l.prototype, "themeTitleColor", 2);
113
+ l = s([
114
+ d("widget-navbutton-1.0.9")
115
+ ], l);
103
116
  export {
104
- r as WidgetNavbutton
117
+ l as WidgetNavbutton
105
118
  };
106
119
  //# sourceMappingURL=widget-navbutton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"widget-navbutton.js","sources":["../src/widget-navbutton.ts"],"sourcesContent":["import { html, css, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { InputData } from './definition-schema'\n\nimport '@material/web/icon/icon.js'\nimport '@material/web/button/filled-button.js'\nimport '@material/web/ripple/ripple.js'\n\ntype Theme = {\n theme_name: string\n theme_object: any\n}\n\n@customElement('widget-navbutton-versionplaceholder')\nexport class WidgetNavbutton extends LitElement {\n @property({ type: Object }) inputData?: InputData\n @property({ type: Object }) theme?: Theme\n @property({ type: String }) route?: string\n\n @state() private themeBgColor?: string\n @state() private themeTitleColor?: string\n\n version: string = 'versionplaceholder'\n\n update(changedProperties: Map<string, any>) {\n if (changedProperties.has('theme')) {\n this.registerTheme(this.theme)\n }\n\n super.update(changedProperties)\n }\n\n protected firstUpdated(_changedProperties: PropertyValues): void {\n this.registerTheme(this.theme)\n }\n\n registerTheme(theme?: Theme) {\n const cssTextColor = getComputedStyle(this).getPropertyValue('--re-text-color').trim()\n const cssBgColor = getComputedStyle(this).getPropertyValue('--re-tile-background-color').trim()\n this.themeBgColor = cssBgColor || this.theme?.theme_object?.backgroundColor\n this.themeTitleColor = cssTextColor || this.theme?.theme_object?.title?.textStyle?.color\n }\n\n handleNavItemClick(route?: string) {\n let goto: string\n if (this.inputData?.route === '') {\n goto = '/' + this.route?.split('/').filter(Boolean).slice(0, -1).join('/') + '/' || '/'\n goto = goto === '//' ? '/' : goto\n } else {\n goto = this.inputData?.route || '/'\n }\n console.log('Navigating to:', route, this.route, { goto })\n const event = new CustomEvent('nav-submit', {\n detail: { path: goto },\n bubbles: true,\n composed: true\n })\n this.dispatchEvent(event)\n }\n\n addSlashes(item?: any): string | undefined {\n if (!item.route?.endsWith('/') && item.trailingSlash) {\n item.route += '/'\n }\n if (!item.route?.startsWith('/') && item.leadingSlash) {\n item.route = '/' + item.route\n }\n return item.route\n }\n\n static styles = css`\n :host {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n font-family: sans-serif;\n box-sizing: border-box;\n margin: auto;\n padding: 2cqh 2cqw;\n }\n\n md-icon {\n font-family: 'Material Symbols Outlined';\n }\n md-filled-button {\n flex: 1;\n --md-filled-button-container-shape: 4px;\n --md-filled-button-container-shadow-color: none;\n --md-sys-color-primary: #006a6a;\n --md-ripple-hover-color: var(--md-sys-color-primary);\n --md-ripple-pressed-color: var(--md-sys-color-primary);\n }\n `\n\n render() {\n const fontSize = this.inputData?.style?.fontSize ?? 16\n const iconFontSize = (this.inputData?.style?.fontSize ?? 16) * 1.5\n const fontColor = this.inputData?.style?.color || this.themeTitleColor || 'black'\n const bgColor = this.inputData?.style?.backgroundColor || this.themeBgColor || 'white'\n const gap = fontSize * 0.4\n return html`\n <md-filled-button\n style=\"font-size: ${fontSize}px; \n --md-filled-button-label-text-color: ${fontColor}; \n --md-filled-button-hover-label-text-color: ${fontColor};\n --md-filled-button-pressed-label-text-color: ${fontColor};\n --md-filled-button-focus-label-text-color: ${fontColor};\n --md-filled-button-container-color: ${bgColor};\n \"\n @click=${() => this.handleNavItemClick(this.addSlashes(this.inputData))}\n >\n ${this.inputData?.title}\n <md-ripple></md-ripple>\n <md-icon slot=\"icon\" style=\"font-size: ${iconFontSize}px; color: ${fontColor}\"\n >${this.inputData?.iconName}</md-icon\n >\n </md-filled-button>\n `\n }\n}\n"],"names":["WidgetNavbutton","LitElement","changedProperties","_changedProperties","theme","cssTextColor","cssBgColor","route","goto","event","item","fontSize","iconFontSize","fontColor","bgColor","html","css","__decorateClass","property","state","customElement"],"mappings":";;;;;;;;;;AAcO,IAAMA,IAAN,cAA8BC,EAAW;AAAA,EAAzC,cAAA;AAAA,UAAA,GAAA,SAAA,GAQH,KAAA,UAAkB;AAAA,EAAA;AAAA,EAElB,OAAOC,GAAqC;AACxC,IAAIA,EAAkB,IAAI,OAAO,KAC7B,KAAK,cAAc,KAAK,KAAK,GAGjC,MAAM,OAAOA,CAAiB;AAAA,EAClC;AAAA,EAEU,aAAaC,GAA0C;AAC7D,SAAK,cAAc,KAAK,KAAK;AAAA,EACjC;AAAA,EAEA,cAAcC,GAAe;AACzB,UAAMC,IAAe,iBAAiB,IAAI,EAAE,iBAAiB,iBAAiB,EAAE,KAAA,GAC1EC,IAAa,iBAAiB,IAAI,EAAE,iBAAiB,4BAA4B,EAAE,KAAA;AACzF,SAAK,eAAeA,KAAc,KAAK,OAAO,cAAc,iBAC5D,KAAK,kBAAkBD,KAAgB,KAAK,OAAO,cAAc,OAAO,WAAW;AAAA,EACvF;AAAA,EAEA,mBAAmBE,GAAgB;AAC/B,QAAIC;AACJ,IAAI,KAAK,WAAW,UAAU,MAC1BA,IAAO,MAAM,KAAK,OAAO,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,IAAI,OAAO,KACpFA,IAAOA,MAAS,OAAO,MAAMA,KAE7BA,IAAO,KAAK,WAAW,SAAS,KAEpC,QAAQ,IAAI,kBAAkBD,GAAO,KAAK,OAAO,EAAE,MAAAC,GAAM;AACzD,UAAMC,IAAQ,IAAI,YAAY,cAAc;AAAA,MACxC,QAAQ,EAAE,MAAMD,EAAA;AAAA,MAChB,SAAS;AAAA,MACT,UAAU;AAAA,IAAA,CACb;AACD,SAAK,cAAcC,CAAK;AAAA,EAC5B;AAAA,EAEA,WAAWC,GAAgC;AACvC,WAAI,CAACA,EAAK,OAAO,SAAS,GAAG,KAAKA,EAAK,kBACnCA,EAAK,SAAS,MAEd,CAACA,EAAK,OAAO,WAAW,GAAG,KAAKA,EAAK,iBACrCA,EAAK,QAAQ,MAAMA,EAAK,QAErBA,EAAK;AAAA,EAChB;AAAA,EA4BA,SAAS;AACL,UAAMC,IAAW,KAAK,WAAW,OAAO,YAAY,IAC9CC,KAAgB,KAAK,WAAW,OAAO,YAAY,MAAM,KACzDC,IAAY,KAAK,WAAW,OAAO,SAAS,KAAK,mBAAmB,SACpEC,IAAU,KAAK,WAAW,OAAO,mBAAmB,KAAK,gBAAgB;AAE/E,WAAOC;AAAA;AAAA,oCAEqBJ,CAAQ;AAAA,uDACWE,CAAS;AAAA,6DACHA,CAAS;AAAA,+DACPA,CAAS;AAAA,6DACXA,CAAS;AAAA,sDAChBC,CAAO;AAAA;AAAA,yBAEpC,MAAM,KAAK,mBAAmB,KAAK,WAAW,KAAK,SAAS,CAAC,CAAC;AAAA;AAAA,kBAErE,KAAK,WAAW,KAAK;AAAA;AAAA,yDAEkBF,CAAY,cAAcC,CAAS;AAAA,uBACrE,KAAK,WAAW,QAAQ;AAAA;AAAA;AAAA;AAAA,EAI3C;AACJ;AA3Gab,EAwDF,SAASgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAvDYC,EAAA;AAAA,EAA3BC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GADjBlB,EACmB,WAAA,aAAA,CAAA;AACAiB,EAAA;AAAA,EAA3BC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAFjBlB,EAEmB,WAAA,SAAA,CAAA;AACAiB,EAAA;AAAA,EAA3BC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAHjBlB,EAGmB,WAAA,SAAA,CAAA;AAEXiB,EAAA;AAAA,EAAhBE,EAAA;AAAM,GALEnB,EAKQ,WAAA,gBAAA,CAAA;AACAiB,EAAA;AAAA,EAAhBE,EAAA;AAAM,GANEnB,EAMQ,WAAA,mBAAA,CAAA;AANRA,IAANiB,EAAA;AAAA,EADNG,EAAc,wBAAqC;AAAA,GACvCpB,CAAA;"}
1
+ {"version":3,"file":"widget-navbutton.js","sources":["../src/widget-navbutton.ts"],"sourcesContent":["import { html, css, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { InputData } from './definition-schema'\n\nimport '@material/web/icon/icon.js'\nimport '@material/web/button/filled-button.js'\nimport '@material/web/ripple/ripple.js'\n\ntype Theme = {\n theme_name: string\n theme_object: any\n}\n\n@customElement('widget-navbutton-versionplaceholder')\nexport class WidgetNavbutton extends LitElement {\n @property({ type: Object }) inputData?: InputData\n @property({ type: Object }) theme?: Theme\n @property({ type: String }) route?: string\n\n @state() private themeBgColor?: string\n @state() private themeTitleColor?: string\n\n version: string = 'versionplaceholder'\n\n update(changedProperties: Map<string, any>) {\n if (changedProperties.has('theme')) {\n this.registerTheme(this.theme)\n }\n\n super.update(changedProperties)\n }\n\n protected firstUpdated(_changedProperties: PropertyValues): void {\n this.registerTheme(this.theme)\n }\n\n registerTheme(theme?: Theme) {\n const cssTextColor = getComputedStyle(this).getPropertyValue('--re-text-color').trim()\n const cssBgColor = getComputedStyle(this).getPropertyValue('--re-tile-background-color').trim()\n this.themeBgColor = cssBgColor || this.theme?.theme_object?.backgroundColor\n this.themeTitleColor = cssTextColor || this.theme?.theme_object?.title?.textStyle?.color\n }\n\n handleNavItemClick() {\n let goto: string\n if (this.inputData?.route === '') {\n goto = '/' + this.route?.split('/').filter(Boolean).slice(0, -1).join('/') + '/' || '/'\n goto = goto === '//' ? '/' : goto\n } else {\n goto =\n this.resolveRoute({\n route: this.inputData?.route,\n variables: this.inputData?.variables\n }) || '/'\n }\n const event = new CustomEvent('nav-submit', {\n detail: { path: goto },\n bubbles: true,\n composed: true\n })\n this.dispatchEvent(event)\n }\n\n resolveRoute(item?: any): string | undefined {\n let route = String(item?.route ?? '')\n if (item?.variables) {\n for (const variable of item.variables) {\n if (variable.label) {\n route = route\n .split(`{{${variable.label}}}`)\n .join(encodeURIComponent(String(variable.value ?? '')))\n }\n }\n }\n if (route.includes('*')) {\n const currentSegments = (this.route || '').split('/').filter(Boolean)\n const routeSegments = route.split('/').filter(Boolean)\n for (let i = 0; i < routeSegments.length; i++) {\n if (routeSegments[i] === '*') {\n routeSegments[i] = currentSegments[i] ?? ''\n }\n }\n route = (route.startsWith('/') ? '/' : '') + routeSegments.filter(Boolean).join('/')\n }\n return route\n }\n\n static styles = css`\n :host {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n font-family: sans-serif;\n box-sizing: border-box;\n margin: auto;\n padding: 2cqh 2cqw;\n }\n\n md-icon {\n font-family: 'Material Symbols Outlined';\n }\n md-filled-button {\n flex: 1;\n --md-filled-button-container-shape: 4px;\n --md-filled-button-container-shadow-color: none;\n --md-sys-color-primary: #006a6a;\n --md-ripple-hover-color: var(--md-sys-color-primary);\n --md-ripple-pressed-color: var(--md-sys-color-primary);\n }\n `\n\n render() {\n const fontSize = this.inputData?.style?.fontSize ?? 16\n const iconFontSize = (this.inputData?.style?.fontSize ?? 16) * 1.5\n const fontColor = this.inputData?.style?.color || this.themeTitleColor || 'black'\n const bgColor = this.inputData?.style?.backgroundColor || this.themeBgColor || 'white'\n const gap = fontSize * 0.4\n return html`\n <md-filled-button\n style=\"font-size: ${fontSize}px; \n --md-filled-button-label-text-color: ${fontColor}; \n --md-filled-button-hover-label-text-color: ${fontColor};\n --md-filled-button-pressed-label-text-color: ${fontColor};\n --md-filled-button-focus-label-text-color: ${fontColor};\n --md-filled-button-container-color: ${bgColor};\n \"\n @click=${() => this.handleNavItemClick()}\n >\n ${this.inputData?.title}\n <md-ripple></md-ripple>\n <md-icon slot=\"icon\" style=\"font-size: ${iconFontSize}px; color: ${fontColor}\"\n >${this.inputData?.iconName}</md-icon\n >\n </md-filled-button>\n `\n }\n}\n"],"names":["WidgetNavbutton","LitElement","changedProperties","_changedProperties","theme","cssTextColor","cssBgColor","goto","event","item","route","variable","currentSegments","routeSegments","fontSize","iconFontSize","fontColor","bgColor","html","css","__decorateClass","property","state","customElement"],"mappings":"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"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Webcomponent widget-navbutton following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "widget-navbutton",
6
- "version": "1.0.7",
6
+ "version": "1.0.9",
7
7
  "engines": {
8
8
  "node": ">=24.9.0",
9
9
  "npm": ">=10.0.2"
@@ -14,11 +14,12 @@
14
14
  "files": [
15
15
  "dist",
16
16
  "src",
17
- "thumbnail.png"
17
+ "thumbnail.png",
18
+ "thumbnail.webp"
18
19
  ],
19
20
  "scripts": {
20
21
  "analyze": "cem analyze --litelement",
21
- "start": "vite",
22
+ "start": "vite build --watch & vite",
22
23
  "build": "vite build",
23
24
  "watch": "vite build --watch",
24
25
  "link": "npm run build && npm link && cd ../RESWARM/frontend && npm link @record-evolution/widget-navbutton",
@@ -14,17 +14,25 @@ export type Label = string;
14
14
  */
15
15
  export type IconName = string;
16
16
  /**
17
- * The destination path when the button is clicked. Leave blank to perform automatic browser back navigation. Use relative paths (e.g., 'details', '../overview') or enable leadingSlash for absolute paths from root.
17
+ * The destination path when the button is clicked. Leave blank to perform automatic browser back navigation. Supports two dynamic substitution mechanisms: (1) Variable placeholders using double curly braces — define variables in the 'Variables' array below and reference them as {{variableName}} in the route string (e.g., '/device/{{deviceId}}/details' where a variable with label 'deviceId' provides the value). (2) Wildcard segments using a single asterisk '*' as a full path segment — each '*' is replaced at runtime by the segment at the same position from the current browser route (e.g., '/* /settings' navigates to the settings page while preserving the first segment of the current URL). The '*' must be the entire segment to be substituted; partial wildcards like 'test*' are treated as literal text. Routes starting with '/' are absolute; routes without a leading slash are relative to the current location.
18
18
  */
19
19
  export type Navigation = string;
20
20
  /**
21
- * When enabled, prepends '/' to the navigation route making it absolute from the root. When disabled, routes are relative to the current URL location.
21
+ * The variable name used in the route string. Reference this in your route using the {{label}} syntax. Use descriptive names like 'temperature', 'status', 'deviceName'.
22
22
  */
23
- export type AddLeadingSlash = boolean;
23
+ export type Label1 = string;
24
24
  /**
25
- * When enabled, appends '/' to the end of the navigation route. Required by some routing configurations for proper page matching.
25
+ * The replacement text that will appear in place of {{label}} in the rendered output. Can be a static value or bound to a data column for dynamic updates.
26
26
  */
27
- export type AddTraillingSlash = boolean;
27
+ export type Value = string;
28
+ /**
29
+ * Array of variable definitions for dynamic route segment substitution. Each variable has a label (used in the route string as {{label}}) and a value (the replacement text). Values can be static or bound to data columns for real-time updates.
30
+ */
31
+ export type NavigationVariables = {
32
+ label?: Label1;
33
+ value?: Value;
34
+ [k: string]: unknown;
35
+ }[];
28
36
  /**
29
37
  * Font size in pixels for the button label text.
30
38
  */
@@ -37,8 +45,7 @@ export interface InputData {
37
45
  title?: Label;
38
46
  iconName?: IconName;
39
47
  route?: Navigation;
40
- leadingSlash?: AddLeadingSlash;
41
- trailingSlash?: AddTraillingSlash;
48
+ variables?: NavigationVariables;
42
49
  style?: ButtonStyle;
43
50
  [k: string]: unknown;
44
51
  }
@@ -19,22 +19,32 @@
19
19
  "route": {
20
20
  "title": "Navigation",
21
21
  "order": 3,
22
- "description": "The destination path when the button is clicked. Leave blank to perform automatic browser back navigation. Use relative paths (e.g., 'details', '../overview') or enable leadingSlash for absolute paths from root.",
22
+ "description": "The destination path when the button is clicked. Leave blank to perform automatic browser back navigation. Supports two dynamic substitution mechanisms: (1) Variable placeholders using double curly braces — define variables in the 'Variables' array below and reference them as {{variableName}} in the route string (e.g., '/device/{{deviceId}}/details' where a variable with label 'deviceId' provides the value). (2) Wildcard segments using a single asterisk '*' as a full path segment — each '*' is replaced at runtime by the segment at the same position from the current browser route (e.g., '/*/settings' navigates to the settings page while preserving the first segment of the current URL). The '*' must be the entire segment to be substituted; partial wildcards like 'test*' are treated as literal text. Routes starting with '/' are absolute; routes without a leading slash are relative to the current location.",
23
23
  "type": "string"
24
24
  },
25
- "leadingSlash": {
26
- "title": "Add Leading Slash",
27
- "order": 4,
28
- "description": "When enabled, prepends '/' to the navigation route making it absolute from the root. When disabled, routes are relative to the current URL location.",
29
- "dataDrivenDisabled": true,
30
- "type": "boolean"
31
- },
32
- "trailingSlash": {
33
- "title": "Add Trailling Slash",
34
- "order": 5,
35
- "description": "When enabled, appends '/' to the end of the navigation route. Required by some routing configurations for proper page matching.",
25
+ "variables": {
26
+ "title": "Navigation Variables",
27
+ "description": "Array of variable definitions for dynamic route segment substitution. Each variable has a label (used in the route string as {{label}}) and a value (the replacement text). Values can be static or bound to data columns for real-time updates.",
28
+ "type": "array",
36
29
  "dataDrivenDisabled": true,
37
- "type": "boolean"
30
+ "order": 4,
31
+ "items": {
32
+ "type": "object",
33
+ "properties": {
34
+ "label": {
35
+ "title": "Label",
36
+ "description": "The variable name used in the route string. Reference this in your route using the {{label}} syntax. Use descriptive names like 'temperature', 'status', 'deviceName'.",
37
+ "type": "string",
38
+ "order": 1
39
+ },
40
+ "value": {
41
+ "title": "Value",
42
+ "description": "The replacement text that will appear in place of {{label}} in the rendered output. Can be a static value or bound to a data column for dynamic updates.",
43
+ "type": "string",
44
+ "order": 2
45
+ }
46
+ }
47
+ }
38
48
  },
39
49
  "style": {
40
50
  "title": "Button Style",
@@ -41,15 +41,18 @@ export class WidgetNavbutton extends LitElement {
41
41
  this.themeTitleColor = cssTextColor || this.theme?.theme_object?.title?.textStyle?.color
42
42
  }
43
43
 
44
- handleNavItemClick(route?: string) {
44
+ handleNavItemClick() {
45
45
  let goto: string
46
46
  if (this.inputData?.route === '') {
47
47
  goto = '/' + this.route?.split('/').filter(Boolean).slice(0, -1).join('/') + '/' || '/'
48
48
  goto = goto === '//' ? '/' : goto
49
49
  } else {
50
- goto = this.inputData?.route || '/'
50
+ goto =
51
+ this.resolveRoute({
52
+ route: this.inputData?.route,
53
+ variables: this.inputData?.variables
54
+ }) || '/'
51
55
  }
52
- console.log('Navigating to:', route, this.route, { goto })
53
56
  const event = new CustomEvent('nav-submit', {
54
57
  detail: { path: goto },
55
58
  bubbles: true,
@@ -58,14 +61,28 @@ export class WidgetNavbutton extends LitElement {
58
61
  this.dispatchEvent(event)
59
62
  }
60
63
 
61
- addSlashes(item?: any): string | undefined {
62
- if (!item.route?.endsWith('/') && item.trailingSlash) {
63
- item.route += '/'
64
+ resolveRoute(item?: any): string | undefined {
65
+ let route = String(item?.route ?? '')
66
+ if (item?.variables) {
67
+ for (const variable of item.variables) {
68
+ if (variable.label) {
69
+ route = route
70
+ .split(`{{${variable.label}}}`)
71
+ .join(encodeURIComponent(String(variable.value ?? '')))
72
+ }
73
+ }
64
74
  }
65
- if (!item.route?.startsWith('/') && item.leadingSlash) {
66
- item.route = '/' + item.route
75
+ if (route.includes('*')) {
76
+ const currentSegments = (this.route || '').split('/').filter(Boolean)
77
+ const routeSegments = route.split('/').filter(Boolean)
78
+ for (let i = 0; i < routeSegments.length; i++) {
79
+ if (routeSegments[i] === '*') {
80
+ routeSegments[i] = currentSegments[i] ?? ''
81
+ }
82
+ }
83
+ route = (route.startsWith('/') ? '/' : '') + routeSegments.filter(Boolean).join('/')
67
84
  }
68
- return item.route
85
+ return route
69
86
  }
70
87
 
71
88
  static styles = css`
@@ -109,7 +126,7 @@ export class WidgetNavbutton extends LitElement {
109
126
  --md-filled-button-focus-label-text-color: ${fontColor};
110
127
  --md-filled-button-container-color: ${bgColor};
111
128
  "
112
- @click=${() => this.handleNavItemClick(this.addSlashes(this.inputData))}
129
+ @click=${() => this.handleNavItemClick()}
113
130
  >
114
131
  ${this.inputData?.title}
115
132
  <md-ripple></md-ripple>
package/thumbnail.webp ADDED
Binary file