@record-evolution/widget-navbutton 1.0.6 → 1.0.8

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.6";
13
+ super(...arguments), this.version = "1.0.8";
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.6")
102
- ], r);
111
+ m()
112
+ ], l.prototype, "themeTitleColor", 2);
113
+ l = s([
114
+ d("widget-navbutton-1.0.8")
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":"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"}
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.6",
6
+ "version": "1.0.8",
7
7
  "engines": {
8
8
  "node": ">=24.9.0",
9
9
  "npm": ">=10.0.2"
@@ -5,46 +5,68 @@
5
5
  * and run json-schema-to-typescript to regenerate this file.
6
6
  */
7
7
 
8
+ /**
9
+ * The text displayed on the button. Should be short and action-oriented (e.g., 'Go Back', 'View Details', 'Open Settings').
10
+ */
8
11
  export type Label = string;
9
12
  /**
10
- * Name of the icon from https://fonts.google.com/icons
13
+ * Material icon name displayed alongside the label. Find icon names at https://fonts.google.com/icons (e.g., 'arrow_back', 'open_in_new', 'settings', 'home').
11
14
  */
12
15
  export type IconName = string;
13
16
  /**
14
- * Navigation to perform on button click. Leave blank to perform automatic back navigation. Example: If you are at route /my/route/asset then 'settings/profile' routes to '/my/route/settings/profile'.
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.
15
18
  */
16
19
  export type Navigation = string;
17
20
  /**
18
- * Whether to add a leading slash to the navigation route.
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'.
19
22
  */
20
- export type AddLeadingSlash = boolean;
23
+ export type Label1 = string;
21
24
  /**
22
- * Whether to add a trailing slash to the navigation route.
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.
23
26
  */
24
- export type AddTraillingSlash = boolean;
27
+ export type Value = string;
25
28
  /**
26
- * Font size in pixels
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
+ }[];
36
+ /**
37
+ * Font size in pixels for the button label text.
27
38
  */
28
39
  export type FontSize = number;
29
40
 
41
+ /**
42
+ * A navigation button widget for in-dashboard navigation between pages or sections. Use this widget to create clickable buttons that navigate users to different dashboard views, external pages, or perform back navigation. Supports Material Design icons and customizable styling. Ideal for creating navigation flows, back buttons, call-to-action links, or any clickable element that should route users to another location.
43
+ */
30
44
  export interface InputData {
31
45
  title?: Label;
32
46
  iconName?: IconName;
33
47
  route?: Navigation;
34
- leadingSlash?: AddLeadingSlash;
35
- trailingSlash?: AddTraillingSlash;
48
+ variables?: NavigationVariables;
36
49
  style?: ButtonStyle;
37
50
  [k: string]: unknown;
38
51
  }
52
+ /**
53
+ * Visual styling options for the button appearance.
54
+ */
39
55
  export interface ButtonStyle {
40
56
  fontSize?: FontSize;
41
57
  color?: FontColor;
42
58
  backgroundColor?: BackgroundColor;
43
59
  [k: string]: unknown;
44
60
  }
61
+ /**
62
+ * Text color for the button label and icon.
63
+ */
45
64
  export interface FontColor {
46
65
  [k: string]: unknown;
47
66
  }
67
+ /**
68
+ * Background fill color of the button.
69
+ */
48
70
  export interface BackgroundColor {
49
71
  [k: string]: unknown;
50
72
  }
@@ -1,59 +1,74 @@
1
1
  {
2
2
  "title": "Input Data",
3
+ "description": "A navigation button widget for in-dashboard navigation between pages or sections. Use this widget to create clickable buttons that navigate users to different dashboard views, external pages, or perform back navigation. Supports Material Design icons and customizable styling. Ideal for creating navigation flows, back buttons, call-to-action links, or any clickable element that should route users to another location.",
3
4
  "type": "object",
4
5
  "properties": {
5
6
  "title": {
6
7
  "title": "Label",
8
+ "description": "The text displayed on the button. Should be short and action-oriented (e.g., 'Go Back', 'View Details', 'Open Settings').",
7
9
  "order": 1,
8
10
  "type": "string"
9
11
  },
10
12
  "iconName": {
11
13
  "title": "Icon Name",
12
14
  "order": 2,
13
- "description": "Name of the icon from https://fonts.google.com/icons",
15
+ "description": "Material icon name displayed alongside the label. Find icon names at https://fonts.google.com/icons (e.g., 'arrow_back', 'open_in_new', 'settings', 'home').",
14
16
  "dataDrivenDisabled": true,
15
17
  "type": "string"
16
18
  },
17
19
  "route": {
18
20
  "title": "Navigation",
19
21
  "order": 3,
20
- "description": "Navigation to perform on button click. Leave blank to perform automatic back navigation. Example: If you are at route /my/route/asset then 'settings/profile' routes to '/my/route/settings/profile'.",
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.",
21
23
  "type": "string"
22
24
  },
23
- "leadingSlash": {
24
- "title": "Add Leading Slash",
25
- "order": 4,
26
- "description": "Whether to add a leading slash to the navigation route.",
27
- "dataDrivenDisabled": true,
28
- "type": "boolean"
29
- },
30
- "trailingSlash": {
31
- "title": "Add Trailling Slash",
32
- "order": 5,
33
- "description": "Whether to add a trailing slash to the navigation route.",
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",
34
29
  "dataDrivenDisabled": true,
35
- "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
+ }
36
48
  },
37
49
  "style": {
38
50
  "title": "Button Style",
51
+ "description": "Visual styling options for the button appearance.",
39
52
  "order": 6,
40
53
  "type": "object",
41
54
  "properties": {
42
55
  "fontSize": {
43
56
  "title": "Font Size",
44
57
  "order": 1,
45
- "description": "Font size in pixels",
58
+ "description": "Font size in pixels for the button label text.",
46
59
  "dataDrivenDisabled": true,
47
60
  "type": "number"
48
61
  },
49
62
  "color": {
50
63
  "title": "Font Color",
64
+ "description": "Text color for the button label and icon.",
51
65
  "order": 4,
52
66
  "type": "color",
53
67
  "dataDrivenDisabled": true
54
68
  },
55
69
  "backgroundColor": {
56
70
  "title": "Background Color",
71
+ "description": "Background fill color of the button.",
57
72
  "order": 4,
58
73
  "type": "color",
59
74
  "dataDrivenDisabled": true
@@ -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>