@record-evolution/widget-navbar 1.0.11 → 1.0.13
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/dist/widget-navbar.js +52 -36
- package/dist/widget-navbar.js.map +1 -1
- package/package.json +1 -1
- package/src/definition-schema.d.ts +58 -17
- package/src/definition-schema.json +56 -27
- package/src/widget-navbar.ts +30 -9
package/dist/widget-navbar.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { LitElement as
|
|
2
|
-
import { property as
|
|
3
|
-
import { repeat as
|
|
1
|
+
import { LitElement as m, css as d, nothing as f, html as l } from "lit";
|
|
2
|
+
import { property as a, state as u } from "lit/decorators.js";
|
|
3
|
+
import { repeat as g } from "lit/directives/repeat.js";
|
|
4
4
|
import "@material/web/icon/icon";
|
|
5
5
|
import "@material/web/tabs/tabs";
|
|
6
6
|
import "@material/web/tabs/primary-tab";
|
|
7
7
|
import "@material/web/tabs/secondary-tab";
|
|
8
|
-
var b = Object.defineProperty, n = (
|
|
9
|
-
for (var
|
|
10
|
-
(
|
|
11
|
-
return
|
|
8
|
+
var b = Object.defineProperty, n = (p, t, e, i) => {
|
|
9
|
+
for (var r = void 0, o = p.length - 1, c; o >= 0; o--)
|
|
10
|
+
(c = p[o]) && (r = c(t, e, r) || r);
|
|
11
|
+
return r && b(t, e, r), r;
|
|
12
12
|
};
|
|
13
|
-
const h = class h extends
|
|
13
|
+
const h = class h extends m {
|
|
14
14
|
constructor() {
|
|
15
|
-
super(...arguments), this.version = "1.0.
|
|
15
|
+
super(...arguments), this.version = "1.0.13";
|
|
16
16
|
}
|
|
17
17
|
update(t) {
|
|
18
18
|
t.has("theme") && this.registerTheme(this.theme), super.update(t);
|
|
@@ -38,8 +38,18 @@ const h = class h extends u {
|
|
|
38
38
|
trimRoute(t) {
|
|
39
39
|
return t ? "/" + t.split("/").filter(Boolean).join("/") : "";
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
resolveRoute(t) {
|
|
42
|
+
let e = String(t?.route ?? "");
|
|
43
|
+
if (t?.variables)
|
|
44
|
+
for (const i of t.variables)
|
|
45
|
+
i.label && (e = e.split(`{{${i.label}}}`).join(encodeURIComponent(String(i.value ?? ""))));
|
|
46
|
+
if (e.includes("*")) {
|
|
47
|
+
const i = (this.route || "").split("/").filter(Boolean), r = e.split("/").filter(Boolean);
|
|
48
|
+
for (let o = 0; o < r.length; o++)
|
|
49
|
+
r[o] === "*" && (r[o] = i[o] ?? "");
|
|
50
|
+
e = (e.startsWith("/") ? "/" : "") + r.filter(Boolean).join("/");
|
|
51
|
+
}
|
|
52
|
+
return e;
|
|
43
53
|
}
|
|
44
54
|
matchesRoute(t) {
|
|
45
55
|
if (t === void 0) return !1;
|
|
@@ -47,11 +57,11 @@ const h = class h extends u {
|
|
|
47
57
|
return t.startsWith("/") ? e.startsWith(i) : e.endsWith(i) || e === i;
|
|
48
58
|
}
|
|
49
59
|
render() {
|
|
50
|
-
const t = this.inputData?.style?.fontSize ?? 16, e = (this.inputData?.style?.fontSize ?? 16) * 1.5, i = this.inputData?.style?.color || this.themeTitleColor || "black",
|
|
51
|
-
return
|
|
60
|
+
const t = this.inputData?.style?.fontSize ?? 16, e = (this.inputData?.style?.fontSize ?? 16) * 1.5, i = this.inputData?.style?.color || this.themeTitleColor || "black", r = this.inputData?.style?.backgroundColor || this.themeBgColor || "white";
|
|
61
|
+
return l`
|
|
52
62
|
<div
|
|
53
63
|
class="wrapper"
|
|
54
|
-
style="background-color: ${
|
|
64
|
+
style="background-color: ${r}; color: ${i};
|
|
55
65
|
font-weight: ${this.inputData?.style?.fontWeight};
|
|
56
66
|
font-size: ${t}px;"
|
|
57
67
|
>
|
|
@@ -59,30 +69,35 @@ const h = class h extends u {
|
|
|
59
69
|
class="paging"
|
|
60
70
|
style=${this.inputData?.route ? "cursor: pointer" : ""}
|
|
61
71
|
?active=${this.inputData?.title}
|
|
62
|
-
@click=${() => this.handleNavItemClick(
|
|
72
|
+
@click=${() => this.handleNavItemClick(
|
|
73
|
+
this.resolveRoute({
|
|
74
|
+
route: this.inputData?.route,
|
|
75
|
+
variables: this.inputData?.variables
|
|
76
|
+
})
|
|
77
|
+
)}
|
|
63
78
|
>
|
|
64
79
|
${this.inputData?.title}
|
|
65
80
|
</h2>
|
|
66
81
|
<md-tab class="xnav-list">
|
|
67
|
-
${
|
|
82
|
+
${g(
|
|
68
83
|
this.inputData?.navItems || [],
|
|
69
84
|
(o) => o.label,
|
|
70
|
-
(o) =>
|
|
85
|
+
(o) => l`
|
|
71
86
|
<md-secondary-tab
|
|
72
|
-
?active=${this.matchesRoute(this.
|
|
87
|
+
?active=${this.matchesRoute(this.resolveRoute(o))}
|
|
73
88
|
style="font-size: ${t}px;
|
|
74
|
-
--md-secondary-tab-container-color: ${
|
|
89
|
+
--md-secondary-tab-container-color: ${r};
|
|
75
90
|
color: ${i};"
|
|
76
|
-
@click=${() => this.handleNavItemClick(this.
|
|
91
|
+
@click=${() => this.handleNavItemClick(this.resolveRoute(o))}
|
|
77
92
|
>
|
|
78
|
-
${o.iconName ?
|
|
93
|
+
${o.iconName ? l`
|
|
79
94
|
<md-icon
|
|
80
95
|
slot="icon"
|
|
81
96
|
style="font-size: ${e}px;width: ${e}px;color: ${i}"
|
|
82
97
|
>
|
|
83
98
|
${o.iconName}
|
|
84
99
|
</md-icon>
|
|
85
|
-
` :
|
|
100
|
+
` : f}
|
|
86
101
|
${o.label}
|
|
87
102
|
</md-secondary-tab>
|
|
88
103
|
`
|
|
@@ -92,7 +107,7 @@ const h = class h extends u {
|
|
|
92
107
|
`;
|
|
93
108
|
}
|
|
94
109
|
};
|
|
95
|
-
h.styles =
|
|
110
|
+
h.styles = d`
|
|
96
111
|
:host {
|
|
97
112
|
display: block;
|
|
98
113
|
font-family: sans-serif;
|
|
@@ -109,6 +124,7 @@ h.styles = m`
|
|
|
109
124
|
align-items: end;
|
|
110
125
|
height: 100%;
|
|
111
126
|
width: 100%;
|
|
127
|
+
padding: 0 16px;
|
|
112
128
|
box-sizing: border-box;
|
|
113
129
|
}
|
|
114
130
|
|
|
@@ -129,24 +145,24 @@ h.styles = m`
|
|
|
129
145
|
height: 48px;
|
|
130
146
|
}
|
|
131
147
|
`;
|
|
132
|
-
let
|
|
148
|
+
let s = h;
|
|
133
149
|
n([
|
|
134
|
-
|
|
135
|
-
],
|
|
150
|
+
a({ type: Object })
|
|
151
|
+
], s.prototype, "inputData");
|
|
136
152
|
n([
|
|
137
|
-
|
|
138
|
-
],
|
|
153
|
+
a({ type: Object })
|
|
154
|
+
], s.prototype, "theme");
|
|
139
155
|
n([
|
|
140
|
-
|
|
141
|
-
],
|
|
156
|
+
a({ type: String })
|
|
157
|
+
], s.prototype, "route");
|
|
142
158
|
n([
|
|
143
|
-
|
|
144
|
-
],
|
|
159
|
+
u()
|
|
160
|
+
], s.prototype, "themeBgColor");
|
|
145
161
|
n([
|
|
146
|
-
|
|
147
|
-
],
|
|
148
|
-
window.customElements.define("widget-navbar-1.0.
|
|
162
|
+
u()
|
|
163
|
+
], s.prototype, "themeTitleColor");
|
|
164
|
+
window.customElements.define("widget-navbar-1.0.13", s);
|
|
149
165
|
export {
|
|
150
|
-
|
|
166
|
+
s as WidgetNavbar
|
|
151
167
|
};
|
|
152
168
|
//# sourceMappingURL=widget-navbar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widget-navbar.js","sources":["../src/widget-navbar.ts"],"sourcesContent":["import { html, css, LitElement, PropertyValues, nothing } from 'lit'\nimport { property, state } from 'lit/decorators.js'\nimport { repeat } from 'lit/directives/repeat.js'\nimport { InputData } from './definition-schema'\n\nimport '@material/web/icon/icon'\nimport '@material/web/tabs/tabs'\nimport '@material/web/tabs/primary-tab'\nimport '@material/web/tabs/secondary-tab'\n\ntype Theme = {\n theme_name: string\n theme_object: any\n}\nexport class WidgetNavbar 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 // console.log('Navigating to:', item.route)\n const event = new CustomEvent('nav-submit', {\n detail: { path: route },\n bubbles: true,\n composed: true\n })\n this.dispatchEvent(event)\n }\n\n normalizeRoute(route?: string) {\n if (!route) return '/'\n return route\n }\n\n static styles = css`\n :host {\n display: block;\n font-family: sans-serif;\n box-sizing: border-box;\n margin: auto;\n }\n\n .paging:not([active]) {\n display: none !important;\n }\n\n .wrapper {\n display: flex;\n align-items: end;\n height: 100%;\n width: 100%;\n box-sizing: border-box;\n }\n\n md-icon {\n font-family: 'Material Symbols Outlined';\n }\n\n .selected {\n font-weight: bold;\n background-color: rgba(0, 0, 0, 0.1);\n }\n\n h2 {\n margin: 0;\n padding: 0px;\n font-size: 1.2em;\n line-height: 2.5;\n height: 48px;\n }\n `\n\n trimRoute(route?: string) {\n if (!route) return ''\n return '/' + route.split('/').filter(Boolean).join('/')\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 matchesRoute(itemRoute?: string) {\n if (itemRoute === undefined) return false\n const route = this.trimRoute(decodeURIComponent(this.route || '/'))\n const subRoute = this.trimRoute(itemRoute)\n if (itemRoute.startsWith('/')) {\n return route.startsWith(subRoute)\n } else {\n return route.endsWith(subRoute) || route === subRoute\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 return html`\n <div\n class=\"wrapper\"\n style=\"background-color: ${bgColor}; color: ${fontColor};\n font-weight: ${this.inputData?.style?.fontWeight};\n font-size: ${fontSize}px;\"\n >\n <h2\n class=\"paging\"\n style=${this.inputData?.route ? 'cursor: pointer' : ''}\n ?active=${this.inputData?.title}\n @click=${() => this.handleNavItemClick(this.addSlashes(this.inputData))}\n >\n ${this.inputData?.title}\n </h2>\n <md-tab class=\"xnav-list\">\n ${repeat(\n this.inputData?.navItems || [],\n (item) => item.label,\n (item) => html`\n <md-secondary-tab\n ?active=${this.matchesRoute(this.addSlashes(item))}\n style=\"font-size: ${fontSize}px;\n --md-secondary-tab-container-color: ${bgColor};\n color: ${fontColor};\"\n @click=${() => this.handleNavItemClick(this.addSlashes(item))}\n >\n ${item.iconName\n ? html`\n <md-icon\n slot=\"icon\"\n style=\"font-size: ${iconFontSize}px;width: ${iconFontSize}px;color: ${fontColor}\"\n >\n ${item.iconName}\n </md-icon>\n `\n : nothing}\n ${item.label}\n </md-secondary-tab>\n `\n )}\n </md-tab>\n </div>\n `\n }\n}\nwindow.customElements.define('widget-navbar-versionplaceholder', WidgetNavbar)\n"],"names":["_WidgetNavbar","LitElement","changedProperties","_changedProperties","theme","cssTextColor","cssBgColor","route","event","item","itemRoute","subRoute","fontSize","iconFontSize","fontColor","bgColor","html","repeat","nothing","css","WidgetNavbar","__decorateClass","property","state"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"widget-navbar.js","sources":["../src/widget-navbar.ts"],"sourcesContent":["import { html, css, LitElement, PropertyValues, nothing } from 'lit'\nimport { property, state } from 'lit/decorators.js'\nimport { repeat } from 'lit/directives/repeat.js'\nimport { InputData } from './definition-schema'\n\nimport '@material/web/icon/icon'\nimport '@material/web/tabs/tabs'\nimport '@material/web/tabs/primary-tab'\nimport '@material/web/tabs/secondary-tab'\n\ntype Theme = {\n theme_name: string\n theme_object: any\n}\nexport class WidgetNavbar 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 // console.log('Navigating to:', item.route)\n const event = new CustomEvent('nav-submit', {\n detail: { path: route },\n bubbles: true,\n composed: true\n })\n this.dispatchEvent(event)\n }\n\n normalizeRoute(route?: string) {\n if (!route) return '/'\n return route\n }\n\n static styles = css`\n :host {\n display: block;\n font-family: sans-serif;\n box-sizing: border-box;\n margin: auto;\n }\n\n .paging:not([active]) {\n display: none !important;\n }\n\n .wrapper {\n display: flex;\n align-items: end;\n height: 100%;\n width: 100%;\n padding: 0 16px;\n box-sizing: border-box;\n }\n\n md-icon {\n font-family: 'Material Symbols Outlined';\n }\n\n .selected {\n font-weight: bold;\n background-color: rgba(0, 0, 0, 0.1);\n }\n\n h2 {\n margin: 0;\n padding: 0px;\n font-size: 1.2em;\n line-height: 2.5;\n height: 48px;\n }\n `\n\n trimRoute(route?: string) {\n if (!route) return ''\n return '/' + route.split('/').filter(Boolean).join('/')\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 matchesRoute(itemRoute?: string) {\n if (itemRoute === undefined) return false\n const route = this.trimRoute(decodeURIComponent(this.route || '/'))\n const subRoute = this.trimRoute(itemRoute)\n if (itemRoute.startsWith('/')) {\n return route.startsWith(subRoute)\n } else {\n return route.endsWith(subRoute) || route === subRoute\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 return html`\n <div\n class=\"wrapper\"\n style=\"background-color: ${bgColor}; color: ${fontColor};\n font-weight: ${this.inputData?.style?.fontWeight};\n font-size: ${fontSize}px;\"\n >\n <h2\n class=\"paging\"\n style=${this.inputData?.route ? 'cursor: pointer' : ''}\n ?active=${this.inputData?.title}\n @click=${() =>\n this.handleNavItemClick(\n this.resolveRoute({\n route: this.inputData?.route,\n variables: this.inputData?.variables\n })\n )}\n >\n ${this.inputData?.title}\n </h2>\n <md-tab class=\"xnav-list\">\n ${repeat(\n this.inputData?.navItems || [],\n (item) => item.label,\n (item) => html`\n <md-secondary-tab\n ?active=${this.matchesRoute(this.resolveRoute(item))}\n style=\"font-size: ${fontSize}px;\n --md-secondary-tab-container-color: ${bgColor};\n color: ${fontColor};\"\n @click=${() => this.handleNavItemClick(this.resolveRoute(item))}\n >\n ${item.iconName\n ? html`\n <md-icon\n slot=\"icon\"\n style=\"font-size: ${iconFontSize}px;width: ${iconFontSize}px;color: ${fontColor}\"\n >\n ${item.iconName}\n </md-icon>\n `\n : nothing}\n ${item.label}\n </md-secondary-tab>\n `\n )}\n </md-tab>\n </div>\n `\n }\n}\nwindow.customElements.define('widget-navbar-versionplaceholder', WidgetNavbar)\n"],"names":["_WidgetNavbar","LitElement","changedProperties","_changedProperties","theme","cssTextColor","cssBgColor","route","event","item","variable","currentSegments","routeSegments","i","itemRoute","subRoute","fontSize","iconFontSize","fontColor","bgColor","html","repeat","nothing","css","WidgetNavbar","__decorateClass","property","state"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -5,56 +5,91 @@
|
|
|
5
5
|
* and run json-schema-to-typescript to regenerate this file.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* The main title/brand text displayed in the navigation bar, typically on the left side. Often used for logo text or application name.
|
|
10
|
+
*/
|
|
8
11
|
export type TitleSettings = string;
|
|
9
12
|
/**
|
|
10
|
-
*
|
|
13
|
+
* The destination path when the title is clicked. Supports two dynamic substitution mechanisms: (1) Variable placeholders using double curly braces — define variables in the 'Title Navigation 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.
|
|
11
14
|
*/
|
|
12
15
|
export type TitleNavigation = string;
|
|
13
16
|
/**
|
|
14
|
-
*
|
|
17
|
+
* The variable name used in the route string. Reference this in your route using the {{label}} syntax. Use descriptive names like 'temperature', 'status', 'deviceName'.
|
|
18
|
+
*/
|
|
19
|
+
export type Label = string;
|
|
20
|
+
/**
|
|
21
|
+
* 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.
|
|
15
22
|
*/
|
|
16
|
-
export type
|
|
23
|
+
export type Value = string;
|
|
17
24
|
/**
|
|
18
|
-
*
|
|
25
|
+
* 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.
|
|
26
|
+
*/
|
|
27
|
+
export type TitleNavigationVariables = {
|
|
28
|
+
label?: Label;
|
|
29
|
+
value?: Value;
|
|
30
|
+
[k: string]: unknown;
|
|
31
|
+
}[];
|
|
32
|
+
/**
|
|
33
|
+
* Font size in pixels for navigation item labels.
|
|
19
34
|
*/
|
|
20
|
-
export type AddTraillingSlash = boolean;
|
|
21
35
|
export type FontSize = number;
|
|
36
|
+
/**
|
|
37
|
+
* Font weight for navigation items (100=thin, 400=normal, 700=bold, 900=black).
|
|
38
|
+
*/
|
|
22
39
|
export type FontWeight = number;
|
|
23
|
-
export type Label = string;
|
|
24
40
|
/**
|
|
25
|
-
*
|
|
41
|
+
* The text displayed for this navigation item. Should be short and descriptive (e.g., 'Dashboard', 'Settings', 'Reports').
|
|
42
|
+
*/
|
|
43
|
+
export type Label1 = string;
|
|
44
|
+
/**
|
|
45
|
+
* Material icon name to display alongside the label. Find icon names at https://fonts.google.com/icons (e.g., 'home', 'settings', 'dashboard', 'analytics').
|
|
26
46
|
*/
|
|
27
47
|
export type IconName = string;
|
|
28
48
|
/**
|
|
29
|
-
*
|
|
49
|
+
* The destination path when this item is clicked. 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.
|
|
30
50
|
*/
|
|
31
51
|
export type NavigationRoute = string;
|
|
32
52
|
/**
|
|
33
|
-
*
|
|
53
|
+
* The variable name used in the route string. Reference this in your route using the {{label}} syntax. Use descriptive names like 'temperature', 'status', 'deviceName'.
|
|
34
54
|
*/
|
|
35
|
-
export type
|
|
55
|
+
export type Label2 = string;
|
|
36
56
|
/**
|
|
37
|
-
*
|
|
57
|
+
* 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.
|
|
58
|
+
*/
|
|
59
|
+
export type Value1 = string;
|
|
60
|
+
/**
|
|
61
|
+
* 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.
|
|
62
|
+
*/
|
|
63
|
+
export type NavigationVariables = {
|
|
64
|
+
label?: Label2;
|
|
65
|
+
value?: Value1;
|
|
66
|
+
[k: string]: unknown;
|
|
67
|
+
}[];
|
|
68
|
+
/**
|
|
69
|
+
* Array of clickable navigation links displayed in the navigation bar. Each item can have a label, icon, and destination route.
|
|
38
70
|
*/
|
|
39
|
-
export type AddTraillingSlash1 = boolean;
|
|
40
71
|
export type NavigationItems = {
|
|
41
|
-
label?:
|
|
72
|
+
label?: Label1;
|
|
42
73
|
iconName?: IconName;
|
|
43
74
|
route?: NavigationRoute;
|
|
44
|
-
|
|
45
|
-
trailingSlash?: AddTraillingSlash1;
|
|
75
|
+
variables?: NavigationVariables;
|
|
46
76
|
[k: string]: unknown;
|
|
47
77
|
}[];
|
|
48
78
|
|
|
79
|
+
/**
|
|
80
|
+
* A horizontal navigation bar widget for creating top-level dashboard navigation. Use this widget to provide consistent navigation across dashboard pages with a clickable title and multiple navigation items. Each item can have an icon and routes to different dashboard sections. Supports customizable styling for font size, weight, and colors. Ideal for multi-page dashboards requiring clear navigation structure and branding.
|
|
81
|
+
*/
|
|
49
82
|
export interface InputData {
|
|
50
83
|
title?: TitleSettings;
|
|
51
84
|
route?: TitleNavigation;
|
|
52
|
-
|
|
53
|
-
trailingSlash?: AddTraillingSlash;
|
|
85
|
+
variables?: TitleNavigationVariables;
|
|
54
86
|
style?: ItemStyle;
|
|
55
87
|
navItems?: NavigationItems;
|
|
56
88
|
[k: string]: unknown;
|
|
57
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Global styling options applied to all navigation items in the bar.
|
|
92
|
+
*/
|
|
58
93
|
export interface ItemStyle {
|
|
59
94
|
fontSize?: FontSize;
|
|
60
95
|
fontWeight?: FontWeight;
|
|
@@ -62,9 +97,15 @@ export interface ItemStyle {
|
|
|
62
97
|
backgroundColor?: BackgroundColor;
|
|
63
98
|
[k: string]: unknown;
|
|
64
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Text color for navigation item labels.
|
|
102
|
+
*/
|
|
65
103
|
export interface FontColor {
|
|
66
104
|
[k: string]: unknown;
|
|
67
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Background color of the navigation bar.
|
|
108
|
+
*/
|
|
68
109
|
export interface BackgroundColor {
|
|
69
110
|
[k: string]: unknown;
|
|
70
111
|
}
|
|
@@ -1,57 +1,74 @@
|
|
|
1
1
|
{
|
|
2
2
|
"title": "Input Data",
|
|
3
|
+
"description": "A horizontal navigation bar widget for creating top-level dashboard navigation. Use this widget to provide consistent navigation across dashboard pages with a clickable title and multiple navigation items. Each item can have an icon and routes to different dashboard sections. Supports customizable styling for font size, weight, and colors. Ideal for multi-page dashboards requiring clear navigation structure and branding.",
|
|
3
4
|
"type": "object",
|
|
4
5
|
"properties": {
|
|
5
6
|
"title": {
|
|
6
7
|
"title": "Title Settings",
|
|
8
|
+
"description": "The main title/brand text displayed in the navigation bar, typically on the left side. Often used for logo text or application name.",
|
|
7
9
|
"order": 1,
|
|
8
10
|
"type": "string"
|
|
9
11
|
},
|
|
10
12
|
"route": {
|
|
11
13
|
"title": "Title Navigation",
|
|
12
14
|
"order": 3,
|
|
13
|
-
"description": "
|
|
15
|
+
"description": "The destination path when the title is clicked. Supports two dynamic substitution mechanisms: (1) Variable placeholders using double curly braces — define variables in the 'Title Navigation 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.",
|
|
14
16
|
"type": "string"
|
|
15
17
|
},
|
|
16
|
-
"
|
|
17
|
-
"title": "
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"dataDrivenDisabled": true,
|
|
21
|
-
"type": "boolean"
|
|
22
|
-
},
|
|
23
|
-
"trailingSlash": {
|
|
24
|
-
"title": "Add Trailling Slash",
|
|
25
|
-
"order": 5,
|
|
26
|
-
"description": "Whether to add a trailing slash to the navigation route.",
|
|
18
|
+
"variables": {
|
|
19
|
+
"title": "Title Navigation Variables",
|
|
20
|
+
"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.",
|
|
21
|
+
"type": "array",
|
|
27
22
|
"dataDrivenDisabled": true,
|
|
28
|
-
"
|
|
23
|
+
"order": 4,
|
|
24
|
+
"items": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"properties": {
|
|
27
|
+
"label": {
|
|
28
|
+
"title": "Label",
|
|
29
|
+
"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'.",
|
|
30
|
+
"type": "string",
|
|
31
|
+
"order": 1
|
|
32
|
+
},
|
|
33
|
+
"value": {
|
|
34
|
+
"title": "Value",
|
|
35
|
+
"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.",
|
|
36
|
+
"type": "string",
|
|
37
|
+
"order": 2
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
29
41
|
},
|
|
30
42
|
"style": {
|
|
31
43
|
"title": "Item Style",
|
|
44
|
+
"description": "Global styling options applied to all navigation items in the bar.",
|
|
32
45
|
"order": 6,
|
|
33
46
|
"type": "object",
|
|
34
47
|
"properties": {
|
|
35
48
|
"fontSize": {
|
|
36
49
|
"title": "Font Size",
|
|
50
|
+
"description": "Font size in pixels for navigation item labels.",
|
|
37
51
|
"order": 1,
|
|
38
52
|
"dataDrivenDisabled": true,
|
|
39
53
|
"type": "number"
|
|
40
54
|
},
|
|
41
55
|
"fontWeight": {
|
|
42
56
|
"title": "Font Weight",
|
|
57
|
+
"description": "Font weight for navigation items (100=thin, 400=normal, 700=bold, 900=black).",
|
|
43
58
|
"order": 3,
|
|
44
59
|
"dataDrivenDisabled": true,
|
|
45
60
|
"type": "number"
|
|
46
61
|
},
|
|
47
62
|
"color": {
|
|
48
63
|
"title": "Font Color",
|
|
64
|
+
"description": "Text color for navigation item labels.",
|
|
49
65
|
"order": 4,
|
|
50
66
|
"type": "color",
|
|
51
67
|
"dataDrivenDisabled": true
|
|
52
68
|
},
|
|
53
69
|
"backgroundColor": {
|
|
54
70
|
"title": "Background Color",
|
|
71
|
+
"description": "Background color of the navigation bar.",
|
|
55
72
|
"order": 4,
|
|
56
73
|
"type": "color",
|
|
57
74
|
"dataDrivenDisabled": true
|
|
@@ -60,6 +77,7 @@
|
|
|
60
77
|
},
|
|
61
78
|
"navItems": {
|
|
62
79
|
"title": "Navigation Items",
|
|
80
|
+
"description": "Array of clickable navigation links displayed in the navigation bar. Each item can have a label, icon, and destination route.",
|
|
63
81
|
"order": 7,
|
|
64
82
|
"type": "array",
|
|
65
83
|
"items": {
|
|
@@ -67,35 +85,46 @@
|
|
|
67
85
|
"properties": {
|
|
68
86
|
"label": {
|
|
69
87
|
"title": "Label",
|
|
88
|
+
"description": "The text displayed for this navigation item. Should be short and descriptive (e.g., 'Dashboard', 'Settings', 'Reports').",
|
|
70
89
|
"order": 1,
|
|
71
90
|
"type": "string"
|
|
72
91
|
},
|
|
73
92
|
"iconName": {
|
|
74
93
|
"title": "Icon Name",
|
|
75
94
|
"order": 2,
|
|
76
|
-
"description": "
|
|
95
|
+
"description": "Material icon name to display alongside the label. Find icon names at https://fonts.google.com/icons (e.g., 'home', 'settings', 'dashboard', 'analytics').",
|
|
77
96
|
"dataDrivenDisabled": true,
|
|
78
97
|
"type": "string"
|
|
79
98
|
},
|
|
80
99
|
"route": {
|
|
81
100
|
"title": "Navigation Route",
|
|
82
101
|
"order": 3,
|
|
83
|
-
"description": "
|
|
102
|
+
"description": "The destination path when this item is clicked. 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.",
|
|
84
103
|
"type": "string"
|
|
85
104
|
},
|
|
86
|
-
"
|
|
87
|
-
"title": "
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"dataDrivenDisabled": true,
|
|
91
|
-
"type": "boolean"
|
|
92
|
-
},
|
|
93
|
-
"trailingSlash": {
|
|
94
|
-
"title": "Add Trailling Slash",
|
|
95
|
-
"order": 5,
|
|
96
|
-
"description": "Whether to add a trailing slash to the navigation route.",
|
|
105
|
+
"variables": {
|
|
106
|
+
"title": "Navigation Variables",
|
|
107
|
+
"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.",
|
|
108
|
+
"type": "array",
|
|
97
109
|
"dataDrivenDisabled": true,
|
|
98
|
-
"
|
|
110
|
+
"order": 4,
|
|
111
|
+
"items": {
|
|
112
|
+
"type": "object",
|
|
113
|
+
"properties": {
|
|
114
|
+
"label": {
|
|
115
|
+
"title": "Label",
|
|
116
|
+
"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'.",
|
|
117
|
+
"type": "string",
|
|
118
|
+
"order": 1
|
|
119
|
+
},
|
|
120
|
+
"value": {
|
|
121
|
+
"title": "Value",
|
|
122
|
+
"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.",
|
|
123
|
+
"type": "string",
|
|
124
|
+
"order": 2
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
99
128
|
}
|
|
100
129
|
}
|
|
101
130
|
}
|
package/src/widget-navbar.ts
CHANGED
|
@@ -73,6 +73,7 @@ export class WidgetNavbar extends LitElement {
|
|
|
73
73
|
align-items: end;
|
|
74
74
|
height: 100%;
|
|
75
75
|
width: 100%;
|
|
76
|
+
padding: 0 16px;
|
|
76
77
|
box-sizing: border-box;
|
|
77
78
|
}
|
|
78
79
|
|
|
@@ -99,14 +100,28 @@ export class WidgetNavbar extends LitElement {
|
|
|
99
100
|
return '/' + route.split('/').filter(Boolean).join('/')
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
resolveRoute(item?: any): string | undefined {
|
|
104
|
+
let route = String(item?.route ?? '')
|
|
105
|
+
if (item?.variables) {
|
|
106
|
+
for (const variable of item.variables) {
|
|
107
|
+
if (variable.label) {
|
|
108
|
+
route = route
|
|
109
|
+
.split(`{{${variable.label}}}`)
|
|
110
|
+
.join(encodeURIComponent(String(variable.value ?? '')))
|
|
111
|
+
}
|
|
112
|
+
}
|
|
105
113
|
}
|
|
106
|
-
if (
|
|
107
|
-
|
|
114
|
+
if (route.includes('*')) {
|
|
115
|
+
const currentSegments = (this.route || '').split('/').filter(Boolean)
|
|
116
|
+
const routeSegments = route.split('/').filter(Boolean)
|
|
117
|
+
for (let i = 0; i < routeSegments.length; i++) {
|
|
118
|
+
if (routeSegments[i] === '*') {
|
|
119
|
+
routeSegments[i] = currentSegments[i] ?? ''
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
route = (route.startsWith('/') ? '/' : '') + routeSegments.filter(Boolean).join('/')
|
|
108
123
|
}
|
|
109
|
-
return
|
|
124
|
+
return route
|
|
110
125
|
}
|
|
111
126
|
|
|
112
127
|
matchesRoute(itemRoute?: string) {
|
|
@@ -136,7 +151,13 @@ export class WidgetNavbar extends LitElement {
|
|
|
136
151
|
class="paging"
|
|
137
152
|
style=${this.inputData?.route ? 'cursor: pointer' : ''}
|
|
138
153
|
?active=${this.inputData?.title}
|
|
139
|
-
@click=${() =>
|
|
154
|
+
@click=${() =>
|
|
155
|
+
this.handleNavItemClick(
|
|
156
|
+
this.resolveRoute({
|
|
157
|
+
route: this.inputData?.route,
|
|
158
|
+
variables: this.inputData?.variables
|
|
159
|
+
})
|
|
160
|
+
)}
|
|
140
161
|
>
|
|
141
162
|
${this.inputData?.title}
|
|
142
163
|
</h2>
|
|
@@ -146,11 +167,11 @@ export class WidgetNavbar extends LitElement {
|
|
|
146
167
|
(item) => item.label,
|
|
147
168
|
(item) => html`
|
|
148
169
|
<md-secondary-tab
|
|
149
|
-
?active=${this.matchesRoute(this.
|
|
170
|
+
?active=${this.matchesRoute(this.resolveRoute(item))}
|
|
150
171
|
style="font-size: ${fontSize}px;
|
|
151
172
|
--md-secondary-tab-container-color: ${bgColor};
|
|
152
173
|
color: ${fontColor};"
|
|
153
|
-
@click=${() => this.handleNavItemClick(this.
|
|
174
|
+
@click=${() => this.handleNavItemClick(this.resolveRoute(item))}
|
|
154
175
|
>
|
|
155
176
|
${item.iconName
|
|
156
177
|
? html`
|