@record-evolution/widget-navbar 1.0.16 → 1.0.18

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,12 +1,12 @@
1
- import { LitElement as f, css as u, nothing as p, html as c } from "lit";
2
- import { property as d, state as h } from "lit/decorators.js";
3
- import { repeat as m } from "lit/directives/repeat.js";
1
+ import { LitElement as f, css as p, nothing as u, html as c } from "lit";
2
+ import { property as v, state as h } from "lit/decorators.js";
3
+ import { repeat as b } from "lit/directives/repeat.js";
4
4
  import "@material/web/icon/icon";
5
5
  import "@material/web/tabs/secondary-tab";
6
- var b = Object.defineProperty, l = (s, t, e, a) => {
6
+ var m = Object.defineProperty, l = (s, t, e, a) => {
7
7
  for (var o = void 0, r = s.length - 1, n; r >= 0; r--)
8
8
  (n = s[r]) && (o = n(t, e, o) || o);
9
- return o && b(t, e, o), o;
9
+ return o && m(t, e, o), o;
10
10
  };
11
11
  const g = (s) => {
12
12
  if (!s) return !0;
@@ -14,9 +14,9 @@ const g = (s) => {
14
14
  if (t === "transparent") return !0;
15
15
  const e = t.match(/^(?:rgba|hsla)\([^)]*[,/]\s*([\d.]+%?)\s*\)$/);
16
16
  return e ? parseFloat(e[1]) === 0 : /^#[0-9a-f]{8}$/.test(t) ? t.slice(7) === "00" : /^#[0-9a-f]{4}$/.test(t) ? t[4] === "0" : !1;
17
- }, v = class v extends f {
17
+ }, d = class d extends f {
18
18
  constructor() {
19
- super(...arguments), this.version = "1.0.16";
19
+ super(...arguments), this.version = "1.0.18";
20
20
  }
21
21
  update(t) {
22
22
  t.has("theme") && this.registerTheme(this.theme), super.update(t);
@@ -25,8 +25,8 @@ const g = (s) => {
25
25
  this.registerTheme(this.theme);
26
26
  }
27
27
  registerTheme(t) {
28
- const e = getComputedStyle(this).getPropertyValue("--re-text-color").trim(), a = getComputedStyle(this).getPropertyValue("--re-tile-background-color").trim(), o = t?.theme_object?.backgroundColor;
29
- this.themeBgColor = a || (g(o) ? void 0 : o), this.themeTitleColor = e || t?.theme_object?.title?.textStyle?.color;
28
+ const e = t?.theme_object?.backgroundColor;
29
+ this.themeBgColor = `var(--re-tile-background-color, ${(g(e) ? void 0 : e) || "transparent"})`, this.themeTitleColor = `var(--re-text-color, ${t?.theme_object?.title?.textStyle?.color || "inherit"})`;
30
30
  }
31
31
  handleNavItemClick(t) {
32
32
  const e = new CustomEvent("nav-submit", {
@@ -61,7 +61,7 @@ const g = (s) => {
61
61
  return t.startsWith("/") ? e.startsWith(a) : e.endsWith(a) || e === a;
62
62
  }
63
63
  render() {
64
- const t = this.inputData?.style?.fontSize ?? 16, e = this.inputData?.style?.fontWeight ?? 400, a = t * 1.5, o = this.inputData?.style?.color || this.themeTitleColor || "black", r = this.inputData?.style?.backgroundColor || this.themeBgColor || "white";
64
+ const t = this.inputData?.style?.fontSize ?? 16, e = this.inputData?.style?.fontWeight ?? 400, a = t * 1.5, o = this.themeTitleColor || "black", r = this.themeBgColor || "white";
65
65
  return c`
66
66
  <div
67
67
  class="wrapper"
@@ -83,7 +83,7 @@ const g = (s) => {
83
83
  ${this.inputData?.title}
84
84
  </h2>
85
85
  <div class="nav-list" role="tablist">
86
- ${m(
86
+ ${b(
87
87
  this.inputData?.navItems || [],
88
88
  (n) => n.label,
89
89
  (n) => c`
@@ -91,7 +91,7 @@ const g = (s) => {
91
91
  ?active=${this.matchesRoute(this.resolveRoute(n))}
92
92
  @click=${() => this.handleNavItemClick(this.resolveRoute(n))}
93
93
  >
94
- ${n.iconName ? c`<md-icon slot="icon">${n.iconName}</md-icon>` : p}
94
+ ${n.iconName ? c`<md-icon slot="icon">${n.iconName}</md-icon>` : u}
95
95
  ${n.label}
96
96
  </md-secondary-tab>
97
97
  `
@@ -101,7 +101,7 @@ const g = (s) => {
101
101
  `;
102
102
  }
103
103
  };
104
- v.styles = u`
104
+ d.styles = p`
105
105
  :host {
106
106
  display: block;
107
107
  font-family: sans-serif;
@@ -195,15 +195,15 @@ v.styles = u`
195
195
  font-weight: inherit;
196
196
  }
197
197
  `;
198
- let i = v;
198
+ let i = d;
199
199
  l([
200
- d({ type: Object })
200
+ v({ type: Object })
201
201
  ], i.prototype, "inputData");
202
202
  l([
203
- d({ type: Object })
203
+ v({ type: Object })
204
204
  ], i.prototype, "theme");
205
205
  l([
206
- d({ type: String })
206
+ v({ type: String })
207
207
  ], i.prototype, "route");
208
208
  l([
209
209
  h()
@@ -211,7 +211,7 @@ l([
211
211
  l([
212
212
  h()
213
213
  ], i.prototype, "themeTitleColor");
214
- window.customElements.define("widget-navbar-1.0.16", i);
214
+ window.customElements.define("widget-navbar-1.0.18", i);
215
215
  export {
216
216
  i as WidgetNavbar
217
217
  };
@@ -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 { NavigationBarConfiguration } from './definition-schema'\n\nimport '@material/web/icon/icon'\nimport '@material/web/tabs/secondary-tab'\n\ntype Theme = {\n theme_name: string\n theme_object: any\n}\n\n/**\n * ECharts themes describe a *chart canvas*, and most of them set\n * `backgroundColor` to a fully transparent colour (the light theme uses\n * `rgba(0, 0, 0, 0)`). That is a valid, truthy colour string, so using it\n * verbatim as the navbar background paints nothing at all. Treat any\n * fully transparent theme colour as \"no colour\" so the fallback kicks in.\n */\nconst isTransparent = (color?: string) => {\n if (!color) return true\n const value = color.trim().toLowerCase()\n if (value === 'transparent') return true\n const functional = value.match(/^(?:rgba|hsla)\\([^)]*[,/]\\s*([\\d.]+%?)\\s*\\)$/)\n if (functional) return parseFloat(functional[1]) === 0\n // #rrggbbaa / #rgba\n if (/^#[0-9a-f]{8}$/.test(value)) return value.slice(7) === '00'\n if (/^#[0-9a-f]{4}$/.test(value)) return value[4] === '0'\n return false\n}\nexport class WidgetNavbar extends LitElement {\n @property({ type: Object }) inputData?: NavigationBarConfiguration\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 const themeBgColor = theme?.theme_object?.backgroundColor\n this.themeBgColor = cssBgColor || (isTransparent(themeBgColor) ? undefined : themeBgColor)\n this.themeTitleColor = cssTextColor || 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 gap: 8px;\n height: 100%;\n width: 100%;\n padding: 0 16px;\n box-sizing: border-box;\n background-color: var(--nav-bg);\n color: var(--nav-fg);\n font-size: var(--nav-font-size);\n font-weight: var(--nav-font-weight);\n }\n\n /* One scrollable row. Without this the tabs wrap onto several lines and\n spill outside the coloured bar as soon as they don't fit. */\n .nav-list {\n display: flex;\n align-items: end;\n flex: 1;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n }\n\n .nav-list::-webkit-scrollbar {\n display: none;\n }\n\n /* Material's tab tokens default to the M3 palette (purple indicator,\n near-black labels), which ignores the widget's configured colours.\n Map every colour token onto the nav colours. */\n md-secondary-tab {\n flex: none;\n --md-secondary-tab-container-color: var(--nav-bg);\n --md-secondary-tab-label-text-size: var(--nav-font-size);\n --md-secondary-tab-label-text-weight: var(--nav-font-weight);\n --md-secondary-tab-icon-size: var(--nav-icon-size);\n --md-secondary-tab-label-text-color: var(--nav-fg);\n --md-secondary-tab-hover-label-text-color: var(--nav-fg);\n --md-secondary-tab-focus-label-text-color: var(--nav-fg);\n --md-secondary-tab-pressed-label-text-color: var(--nav-fg);\n --md-secondary-tab-active-label-text-color: var(--nav-fg);\n --md-secondary-tab-active-hover-label-text-color: var(--nav-fg);\n --md-secondary-tab-active-focus-label-text-color: var(--nav-fg);\n --md-secondary-tab-active-pressed-label-text-color: var(--nav-fg);\n --md-secondary-tab-icon-color: var(--nav-fg);\n --md-secondary-tab-hover-icon-color: var(--nav-fg);\n --md-secondary-tab-focus-icon-color: var(--nav-fg);\n --md-secondary-tab-pressed-icon-color: var(--nav-fg);\n --md-secondary-tab-active-icon-color: var(--nav-fg);\n --md-secondary-tab-active-hover-icon-color: var(--nav-fg);\n --md-secondary-tab-active-focus-icon-color: var(--nav-fg);\n --md-secondary-tab-active-pressed-icon-color: var(--nav-fg);\n --md-secondary-tab-active-indicator-color: var(--nav-fg);\n --md-secondary-tab-hover-state-layer-color: var(--nav-fg);\n --md-secondary-tab-pressed-state-layer-color: var(--nav-fg);\n --md-secondary-tab-active-hover-state-layer-color: var(--nav-fg);\n --md-secondary-tab-active-pressed-state-layer-color: var(--nav-fg);\n }\n\n md-icon {\n font-family: 'Material Symbols Outlined';\n font-size: var(--nav-icon-size);\n width: var(--nav-icon-size);\n height: var(--nav-icon-size);\n color: var(--nav-fg);\n }\n\n h2 {\n margin: 0;\n padding: 0px;\n flex: none;\n display: flex;\n align-items: center;\n min-height: 48px;\n font-size: 1.2em;\n /* the UA stylesheet forces bold, which would ignore the\n configured font weight */\n font-weight: inherit;\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 fontWeight = this.inputData?.style?.fontWeight ?? 400\n const iconFontSize = fontSize * 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=\"--nav-bg: ${bgColor}; --nav-fg: ${fontColor};\n --nav-font-size: ${fontSize}px; --nav-font-weight: ${fontWeight};\n --nav-icon-size: ${iconFontSize}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 <div class=\"nav-list\" role=\"tablist\">\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 @click=${() => this.handleNavItemClick(this.resolveRoute(item))}\n >\n ${item.iconName\n ? html`<md-icon slot=\"icon\">${item.iconName}</md-icon>`\n : nothing}\n ${item.label}\n </md-secondary-tab>\n `\n )}\n </div>\n </div>\n `\n }\n}\nwindow.customElements.define('widget-navbar-versionplaceholder', WidgetNavbar)\n"],"names":["isTransparent","color","value","functional","_WidgetNavbar","LitElement","changedProperties","_changedProperties","theme","cssTextColor","cssBgColor","themeBgColor","route","event","item","variable","currentSegments","routeSegments","i","itemRoute","subRoute","fontSize","fontWeight","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 { NavigationBarConfiguration } from './definition-schema'\n\nimport '@material/web/icon/icon'\nimport '@material/web/tabs/secondary-tab'\n\ntype Theme = {\n theme_name: string\n theme_object: any\n}\n\n/**\n * ECharts themes describe a *chart canvas*, and most of them set\n * `backgroundColor` to a fully transparent colour (the light theme uses\n * `rgba(0, 0, 0, 0)`). That is a valid, truthy colour string, so using it\n * verbatim as the navbar background paints nothing at all. Treat any\n * fully transparent theme colour as \"no colour\" so the fallback kicks in.\n */\nconst isTransparent = (color?: string) => {\n if (!color) return true\n const value = color.trim().toLowerCase()\n if (value === 'transparent') return true\n const functional = value.match(/^(?:rgba|hsla)\\([^)]*[,/]\\s*([\\d.]+%?)\\s*\\)$/)\n if (functional) return parseFloat(functional[1]) === 0\n // #rrggbbaa / #rgba\n if (/^#[0-9a-f]{8}$/.test(value)) return value.slice(7) === '00'\n if (/^#[0-9a-f]{4}$/.test(value)) return value[4] === '0'\n return false\n}\nexport class WidgetNavbar extends LitElement {\n @property({ type: Object }) inputData?: NavigationBarConfiguration\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 themeBgColor = theme?.theme_object?.backgroundColor\n this.themeBgColor = `var(--re-tile-background-color, ${(isTransparent(themeBgColor) ? undefined : themeBgColor) || 'transparent'})`\n this.themeTitleColor = `var(--re-text-color, ${theme?.theme_object?.title?.textStyle?.color || 'inherit'})`\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 gap: 8px;\n height: 100%;\n width: 100%;\n padding: 0 16px;\n box-sizing: border-box;\n background-color: var(--nav-bg);\n color: var(--nav-fg);\n font-size: var(--nav-font-size);\n font-weight: var(--nav-font-weight);\n }\n\n /* One scrollable row. Without this the tabs wrap onto several lines and\n spill outside the coloured bar as soon as they don't fit. */\n .nav-list {\n display: flex;\n align-items: end;\n flex: 1;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n }\n\n .nav-list::-webkit-scrollbar {\n display: none;\n }\n\n /* Material's tab tokens default to the M3 palette (purple indicator,\n near-black labels), which ignores the widget's configured colours.\n Map every colour token onto the nav colours. */\n md-secondary-tab {\n flex: none;\n --md-secondary-tab-container-color: var(--nav-bg);\n --md-secondary-tab-label-text-size: var(--nav-font-size);\n --md-secondary-tab-label-text-weight: var(--nav-font-weight);\n --md-secondary-tab-icon-size: var(--nav-icon-size);\n --md-secondary-tab-label-text-color: var(--nav-fg);\n --md-secondary-tab-hover-label-text-color: var(--nav-fg);\n --md-secondary-tab-focus-label-text-color: var(--nav-fg);\n --md-secondary-tab-pressed-label-text-color: var(--nav-fg);\n --md-secondary-tab-active-label-text-color: var(--nav-fg);\n --md-secondary-tab-active-hover-label-text-color: var(--nav-fg);\n --md-secondary-tab-active-focus-label-text-color: var(--nav-fg);\n --md-secondary-tab-active-pressed-label-text-color: var(--nav-fg);\n --md-secondary-tab-icon-color: var(--nav-fg);\n --md-secondary-tab-hover-icon-color: var(--nav-fg);\n --md-secondary-tab-focus-icon-color: var(--nav-fg);\n --md-secondary-tab-pressed-icon-color: var(--nav-fg);\n --md-secondary-tab-active-icon-color: var(--nav-fg);\n --md-secondary-tab-active-hover-icon-color: var(--nav-fg);\n --md-secondary-tab-active-focus-icon-color: var(--nav-fg);\n --md-secondary-tab-active-pressed-icon-color: var(--nav-fg);\n --md-secondary-tab-active-indicator-color: var(--nav-fg);\n --md-secondary-tab-hover-state-layer-color: var(--nav-fg);\n --md-secondary-tab-pressed-state-layer-color: var(--nav-fg);\n --md-secondary-tab-active-hover-state-layer-color: var(--nav-fg);\n --md-secondary-tab-active-pressed-state-layer-color: var(--nav-fg);\n }\n\n md-icon {\n font-family: 'Material Symbols Outlined';\n font-size: var(--nav-icon-size);\n width: var(--nav-icon-size);\n height: var(--nav-icon-size);\n color: var(--nav-fg);\n }\n\n h2 {\n margin: 0;\n padding: 0px;\n flex: none;\n display: flex;\n align-items: center;\n min-height: 48px;\n font-size: 1.2em;\n /* the UA stylesheet forces bold, which would ignore the\n configured font weight */\n font-weight: inherit;\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 fontWeight = this.inputData?.style?.fontWeight ?? 400\n const iconFontSize = fontSize * 1.5\n const fontColor = this.themeTitleColor || 'black'\n const bgColor = this.themeBgColor || 'white'\n return html`\n <div\n class=\"wrapper\"\n style=\"--nav-bg: ${bgColor}; --nav-fg: ${fontColor};\n --nav-font-size: ${fontSize}px; --nav-font-weight: ${fontWeight};\n --nav-icon-size: ${iconFontSize}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 <div class=\"nav-list\" role=\"tablist\">\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 @click=${() => this.handleNavItemClick(this.resolveRoute(item))}\n >\n ${item.iconName\n ? html`<md-icon slot=\"icon\">${item.iconName}</md-icon>`\n : nothing}\n ${item.label}\n </md-secondary-tab>\n `\n )}\n </div>\n </div>\n `\n }\n}\nwindow.customElements.define('widget-navbar-versionplaceholder', WidgetNavbar)\n"],"names":["isTransparent","color","value","functional","_WidgetNavbar","LitElement","changedProperties","_changedProperties","theme","themeBgColor","route","event","item","variable","currentSegments","routeSegments","i","itemRoute","subRoute","fontSize","fontWeight","iconFontSize","fontColor","bgColor","html","repeat","nothing","css","WidgetNavbar","__decorateClass","property","state"],"mappings":"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"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Webcomponent widget-navbar following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "widget-navbar",
6
- "version": "1.0.16",
6
+ "version": "1.0.18",
7
7
  "engines": {
8
8
  "node": ">=24.9.0",
9
9
  "npm": ">=10.0.2"
@@ -25,7 +25,11 @@
25
25
  "link": "npm run build && npm link && cd ../RESWARM/frontend && npm link @record-evolution/widget-navbar",
26
26
  "unlink": "npm unlink --global && cd ../RESWARM/frontend && npm unlink @record-evolution/widget-navbar && npm i @record-evolution/widget-navbar",
27
27
  "types": "cat src/definition-schema.json | json2ts --style.tabWidth=4 > src/definition-schema.d.ts",
28
- "release": "npm run build && npm run types && npm version patch --tag-version-prefix='' && git push && git push --tag && npm run build"
28
+ "preversion": "sh scripts/release-preflight.sh",
29
+ "postversion": "git push --follow-tags && sh scripts/release-verify.sh",
30
+ "release": "npm version patch",
31
+ "release:minor": "npm version minor",
32
+ "release:major": "npm version major"
29
33
  },
30
34
  "dependencies": {
31
35
  "@material/web": "^2.4.1",
@@ -77,7 +77,7 @@ export type NavigationItems = {
77
77
  }[];
78
78
 
79
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.
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 font size and weight; colors follow the dashboard theme or the widget's custom tile style. Ideal for multi-page dashboards requiring clear navigation structure and branding.
81
81
  */
82
82
  export interface NavigationBarConfiguration {
83
83
  title?: TitleSettings;
@@ -93,19 +93,5 @@ export interface NavigationBarConfiguration {
93
93
  export interface ItemStyle {
94
94
  fontSize?: FontSize;
95
95
  fontWeight?: FontWeight;
96
- color?: FontColor;
97
- backgroundColor?: BackgroundColor;
98
- [k: string]: unknown;
99
- }
100
- /**
101
- * Text color for navigation item labels.
102
- */
103
- export interface FontColor {
104
- [k: string]: unknown;
105
- }
106
- /**
107
- * Background color of the navigation bar.
108
- */
109
- export interface BackgroundColor {
110
96
  [k: string]: unknown;
111
97
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "title": "Navigation Bar Configuration",
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
+ "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 font size and weight; colors follow the dashboard theme or the widget's custom tile style. Ideal for multi-page dashboards requiring clear navigation structure and branding.",
4
4
  "aiSelection": {
5
5
  "dataShape": "Navigation structure only: a title with a route, plus navItems[] each carrying a label, an icon and a route. No data input.",
6
6
  "useWhen": [
@@ -72,20 +72,6 @@
72
72
  "order": 3,
73
73
  "dataDrivenDisabled": true,
74
74
  "type": "number"
75
- },
76
- "color": {
77
- "title": "Font Color",
78
- "description": "Text color for navigation item labels.",
79
- "order": 4,
80
- "type": "color",
81
- "dataDrivenDisabled": true
82
- },
83
- "backgroundColor": {
84
- "title": "Background Color",
85
- "description": "Background color of the navigation bar.",
86
- "order": 5,
87
- "type": "color",
88
- "dataDrivenDisabled": true
89
75
  }
90
76
  }
91
77
  },
@@ -52,11 +52,9 @@ export class WidgetNavbar extends LitElement {
52
52
  }
53
53
 
54
54
  registerTheme(theme?: Theme) {
55
- const cssTextColor = getComputedStyle(this).getPropertyValue('--re-text-color').trim()
56
- const cssBgColor = getComputedStyle(this).getPropertyValue('--re-tile-background-color').trim()
57
55
  const themeBgColor = theme?.theme_object?.backgroundColor
58
- this.themeBgColor = cssBgColor || (isTransparent(themeBgColor) ? undefined : themeBgColor)
59
- this.themeTitleColor = cssTextColor || theme?.theme_object?.title?.textStyle?.color
56
+ this.themeBgColor = `var(--re-tile-background-color, ${(isTransparent(themeBgColor) ? undefined : themeBgColor) || 'transparent'})`
57
+ this.themeTitleColor = `var(--re-text-color, ${theme?.theme_object?.title?.textStyle?.color || 'inherit'})`
60
58
  }
61
59
 
62
60
  handleNavItemClick(route?: string) {
@@ -213,8 +211,8 @@ export class WidgetNavbar extends LitElement {
213
211
  const fontSize = this.inputData?.style?.fontSize ?? 16
214
212
  const fontWeight = this.inputData?.style?.fontWeight ?? 400
215
213
  const iconFontSize = fontSize * 1.5
216
- const fontColor = this.inputData?.style?.color || this.themeTitleColor || 'black'
217
- const bgColor = this.inputData?.style?.backgroundColor || this.themeBgColor || 'white'
214
+ const fontColor = this.themeTitleColor || 'black'
215
+ const bgColor = this.themeBgColor || 'white'
218
216
  return html`
219
217
  <div
220
218
  class="wrapper"