@record-evolution/widget-sidenav 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/README.md CHANGED
@@ -1,35 +1,145 @@
1
- # \<widget-sidenav>
1
+ # widget-sidenav
2
2
 
3
- This webcomponent follows the [open-wc](https://github.com/open-wc/open-wc) recommendation.
3
+ IronFlock widget: A Lit 3.x web component that renders a vertical side navigation menu with Material Design icons. Supports route-based highlighting and emits navigation events for integration with SPA routers.
4
+
5
+ ![screenshot](thumbnail.png)
4
6
 
5
7
  ## Installation
6
8
 
7
9
  ```bash
8
- npm i widget-sidenav
10
+ npm i @record-evolution/widget-sidenav
9
11
  ```
10
12
 
13
+ **Peer Dependencies:** This widget requires `@material/web` to be available at runtime via import map or bundled separately.
14
+
11
15
  ## Usage
12
16
 
13
17
  ```html
14
18
  <script type="module">
15
- import 'widget-sidenav/widget-sidenav.js'
19
+ import '@record-evolution/widget-sidenav'
16
20
  </script>
17
21
 
18
- <widget-sidenav></widget-sidenav>
22
+ <widget-sidenav-1.0.12></widget-sidenav-1.0.12>
23
+ ```
24
+
25
+ > **Note:** The element tag includes the version number (e.g., `widget-sidenav-1.0.12`). This is replaced at build time via `@rollup/plugin-replace`.
26
+
27
+ ## Configuration
28
+
29
+ The widget accepts an `inputData` property with the following structure:
30
+
31
+ ```typescript
32
+ interface InputData {
33
+ title?: string
34
+ route?: string // Navigation route for title click
35
+ leadingSlash?: boolean // Add leading slash to routes
36
+ trailingSlash?: boolean // Add trailing slash to routes
37
+ style?: {
38
+ fontSize?: number
39
+ fontWeight?: number
40
+ color?: string // Font color
41
+ backgroundColor?: string
42
+ }
43
+ navItems?: Array<{
44
+ label?: string
45
+ iconName?: string // Material icon name (e.g., "home", "settings")
46
+ route?: string // Navigation route on click
47
+ leadingSlash?: boolean
48
+ trailingSlash?: boolean
49
+ }>
50
+ }
51
+ ```
52
+
53
+ ## Example Configuration
54
+
55
+ ```javascript
56
+ element.inputData = {
57
+ title: 'Dashboard',
58
+ route: '/',
59
+ style: {
60
+ fontSize: 16,
61
+ fontWeight: 500
62
+ },
63
+ navItems: [
64
+ { label: 'Home', iconName: 'home', route: '/' },
65
+ { label: 'Analytics', iconName: 'analytics', route: '/analytics' },
66
+ { label: 'Settings', iconName: 'settings', route: '/settings' }
67
+ ]
68
+ }
69
+ ```
70
+
71
+ ## Navigation Events
72
+
73
+ When a navigation item is clicked, the widget dispatches a `nav-submit` custom event:
74
+
75
+ ```javascript
76
+ element.addEventListener('nav-submit', (e) => {
77
+ console.log(e.detail)
78
+ // { path: "/settings" }
79
+ })
19
80
  ```
20
81
 
21
- ## Expected data format
82
+ ## Route Matching
22
83
 
23
- ## Tooling configs
84
+ The widget highlights the active navigation item based on the current route:
24
85
 
25
- For most of the tools, the configuration is in the `package.json` to reduce the amount of files in your project.
86
+ ```javascript
87
+ element.route = '/settings/profile' // Highlights "Settings" nav item
88
+ ```
89
+
90
+ - Routes starting with `/` are matched from the beginning (absolute)
91
+ - Other routes are matched from the end (relative)
92
+
93
+ ## Material Icons
94
+
95
+ Icons are rendered using `@material/web` icon component. Use icon names from [Google Material Symbols](https://fonts.google.com/icons):
96
+
97
+ ```javascript
98
+ {
99
+ iconName: 'home'
100
+ } // Home icon
101
+ {
102
+ iconName: 'settings'
103
+ } // Settings gear icon
104
+ {
105
+ iconName: 'person'
106
+ } // User profile icon
107
+ ```
108
+
109
+ ## Theming
26
110
 
27
- If you customize the configuration a lot, you can consider moving them to individual files.
111
+ The widget supports theming via CSS custom properties or the `theme` property:
28
112
 
29
- ## Local Demo with `web-dev-server`
113
+ **CSS Custom Properties:**
114
+
115
+ ```css
116
+ widget-sidenav-1.0.12 {
117
+ --re-text-color: #333;
118
+ --re-tile-background-color: #fff;
119
+ }
120
+ ```
121
+
122
+ **Theme Object:**
123
+
124
+ ```javascript
125
+ element.theme = {
126
+ theme_name: 'dark',
127
+ theme_object: {
128
+ backgroundColor: '#1a1a1a',
129
+ title: { textStyle: { color: '#fff' } }
130
+ }
131
+ }
132
+ ```
133
+
134
+ ## Development
30
135
 
31
136
  ```bash
32
- npm start
137
+ npm run start # Dev server at localhost:8000/demo/
138
+ npm run build # Production build to dist/
139
+ npm run types # Regenerate TypeScript types from schema
140
+ npm run release # Build, bump version, push to git with tag
33
141
  ```
34
142
 
35
- To run a local development server that serves the basic demo located in `demo/index.html`
143
+ ## License
144
+
145
+ MIT
@@ -9,7 +9,7 @@ var f = Object.defineProperty, y = Object.getOwnPropertyDescriptor, a = (t, e, o
9
9
  };
10
10
  let s = class extends u {
11
11
  constructor() {
12
- super(...arguments), this.version = "1.0.11";
12
+ super(...arguments), this.version = "1.0.13";
13
13
  }
14
14
  update(t) {
15
15
  t.has("theme") && this.registerTheme(this.theme), super.update(t);
@@ -69,10 +69,10 @@ let s = class extends u {
69
69
  @click=${() => this.handleNavItemClick(this.addSlashes(i))}
70
70
  >
71
71
  ${i.iconName ? p`
72
- <mdif2-icon
72
+ <md-icon
73
73
  style="font-size: ${e}px;width: ${e}px;"
74
74
  >${i.iconName}
75
- </mdif2-icon>
75
+ </md-icon>
76
76
  ` : ""}
77
77
  ${i.label}
78
78
  </div>
@@ -122,7 +122,7 @@ s.styles = d`
122
122
  border-radius: 4px;
123
123
  }
124
124
 
125
- mdif2-icon {
125
+ md-icon {
126
126
  font-family: 'Material Symbols Outlined';
127
127
  }
128
128
 
@@ -152,7 +152,7 @@ a([
152
152
  c()
153
153
  ], s.prototype, "themeTitleColor", 2);
154
154
  s = a([
155
- g("widget-sidenav-1.0.11")
155
+ g("widget-sidenav-1.0.13")
156
156
  ], s);
157
157
  export {
158
158
  s as WidgetSidenav
@@ -1 +1 @@
1
- {"version":3,"file":"widget-sidenav.js","sources":["../src/widget-sidenav.ts"],"sourcesContent":["import { html, css, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { repeat } from 'lit/directives/repeat.js'\nimport { InputData } from './definition-schema'\n\nimport '@material/web/icon/icon.js'\n\ntype Theme = {\n theme_name: string\n theme_object: any\n}\n@customElement('widget-sidenav-versionplaceholder')\nexport class WidgetSidenav 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: String(route) },\n bubbles: true,\n composed: true\n })\n this.dispatchEvent(event)\n }\n\n trimRoute(route?: string) {\n route = String(route)\n if (!route) return ''\n return '/' + route.split('/').filter(Boolean).join('/')\n }\n\n addSlashes(item?: any): string | undefined {\n item.route = String(item.route)\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 itemRoute = String(itemRoute)\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 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 flex-direction: column;\n height: 100%;\n width: 100%;\n padding: 12px;\n box-sizing: border-box;\n }\n\n .nav-list {\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin-top: 12px;\n overflow-y: auto;\n flex-grow: 1;\n }\n\n .nav-item {\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px;\n border-radius: 4px;\n }\n\n mdif2-icon {\n font-family: 'Material Symbols Outlined';\n }\n\n .selected {\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 }\n `\n\n render() {\n const fontSize = this.inputData?.style?.fontSize ?? 16\n const iconFontSize = (this.inputData?.style?.fontSize ?? 16) * 1.5\n const gap = fontSize * 0.4\n return html`\n <div\n class=\"wrapper\"\n style=\"background-color: ${this.inputData?.style?.backgroundColor ||\n this.themeBgColor}; color: ${this.inputData?.style?.color || this.themeTitleColor};\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 <div class=\"nav-list\">\n ${repeat(\n this.inputData?.navItems || [],\n (item) => item.label,\n (item) => html`\n <div\n class=\"nav-item ${this.matchesRoute(this.addSlashes(item)) ? 'selected' : ''}\"\n style=\"gap: ${gap}px;\"\n @click=${() => this.handleNavItemClick(this.addSlashes(item))}\n >\n ${item.iconName\n ? html`\n <mdif2-icon\n style=\"font-size: ${iconFontSize}px;width: ${iconFontSize}px;\"\n >${item.iconName}\n </mdif2-icon>\n `\n : ''}\n ${item.label}\n </div>\n `\n )}\n </div>\n </div>\n `\n }\n}\n"],"names":["WidgetSidenav","LitElement","changedProperties","_changedProperties","theme","cssTextColor","cssBgColor","route","event","item","itemRoute","subRoute","fontSize","iconFontSize","gap","html","repeat","css","__decorateClass","property","state","customElement"],"mappings":"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"}
1
+ {"version":3,"file":"widget-sidenav.js","sources":["../src/widget-sidenav.ts"],"sourcesContent":["import { html, css, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { repeat } from 'lit/directives/repeat.js'\nimport { InputData } from './definition-schema'\n\nimport '@material/web/icon/icon.js'\n\ntype Theme = {\n theme_name: string\n theme_object: any\n}\n@customElement('widget-sidenav-versionplaceholder')\nexport class WidgetSidenav 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: String(route) },\n bubbles: true,\n composed: true\n })\n this.dispatchEvent(event)\n }\n\n trimRoute(route?: string) {\n route = String(route)\n if (!route) return ''\n return '/' + route.split('/').filter(Boolean).join('/')\n }\n\n addSlashes(item?: any): string | undefined {\n item.route = String(item.route)\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 itemRoute = String(itemRoute)\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 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 flex-direction: column;\n height: 100%;\n width: 100%;\n padding: 12px;\n box-sizing: border-box;\n }\n\n .nav-list {\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin-top: 12px;\n overflow-y: auto;\n flex-grow: 1;\n }\n\n .nav-item {\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px;\n border-radius: 4px;\n }\n\n md-icon {\n font-family: 'Material Symbols Outlined';\n }\n\n .selected {\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 }\n `\n\n render() {\n const fontSize = this.inputData?.style?.fontSize ?? 16\n const iconFontSize = (this.inputData?.style?.fontSize ?? 16) * 1.5\n const gap = fontSize * 0.4\n return html`\n <div\n class=\"wrapper\"\n style=\"background-color: ${this.inputData?.style?.backgroundColor ||\n this.themeBgColor}; color: ${this.inputData?.style?.color || this.themeTitleColor};\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 <div class=\"nav-list\">\n ${repeat(\n this.inputData?.navItems || [],\n (item) => item.label,\n (item) => html`\n <div\n class=\"nav-item ${this.matchesRoute(this.addSlashes(item)) ? 'selected' : ''}\"\n style=\"gap: ${gap}px;\"\n @click=${() => this.handleNavItemClick(this.addSlashes(item))}\n >\n ${item.iconName\n ? html`\n <md-icon\n style=\"font-size: ${iconFontSize}px;width: ${iconFontSize}px;\"\n >${item.iconName}\n </md-icon>\n `\n : ''}\n ${item.label}\n </div>\n `\n )}\n </div>\n </div>\n `\n }\n}\n"],"names":["WidgetSidenav","LitElement","changedProperties","_changedProperties","theme","cssTextColor","cssBgColor","route","event","item","itemRoute","subRoute","fontSize","iconFontSize","gap","html","repeat","css","__decorateClass","property","state","customElement"],"mappings":"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"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Webcomponent widget-sidenav following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "widget-sidenav",
6
- "version": "1.0.11",
6
+ "version": "1.0.13",
7
7
  "engines": {
8
8
  "node": ">=24.9.0",
9
9
  "npm": ">=10.0.2"
@@ -5,38 +5,53 @@
5
5
  * and run json-schema-to-typescript to regenerate this file.
6
6
  */
7
7
 
8
+ /**
9
+ * The header text displayed at the top of the side navigation, typically used for branding or section identification.
10
+ */
8
11
  export type TitleSettings = string;
9
12
  /**
10
- * Navigation to perform on title click. Example: If you are at route /my/route/asset then 'settings/profile' routes to '/my/route/settings/profile'.
13
+ * The destination path when the title/header is clicked. Use for navigating to a home or main page. Use relative paths or enable leadingSlash for absolute routing.
11
14
  */
12
15
  export type TitleNavigation = string;
13
16
  /**
14
- * Whether to add a leading slash to the navigation route.
17
+ * When enabled, prepends '/' to the title's navigation route making it absolute from the root. When disabled, routes are relative to the current location.
15
18
  */
16
19
  export type AddLeadingSlash = boolean;
17
20
  /**
18
- * Whether to add a trailing slash to the navigation route.
21
+ * When enabled, appends '/' to the end of the title's navigation route. Required by some routing configurations.
19
22
  */
20
23
  export type AddTraillingSlash = boolean;
24
+ /**
25
+ * Font size in pixels for navigation item labels.
26
+ */
21
27
  export type FontSize = number;
28
+ /**
29
+ * Font weight for navigation items (100=thin, 400=normal, 700=bold, 900=black).
30
+ */
22
31
  export type FontWeight = number;
32
+ /**
33
+ * The text displayed for this navigation item. Should clearly describe the destination section.
34
+ */
23
35
  export type Label = string;
24
36
  /**
25
- * Name of the icon from https://fonts.google.com/icons
37
+ * Material icon name displayed alongside the label. Find icon names at https://fonts.google.com/icons (e.g., 'dashboard', 'settings', 'analytics', 'people').
26
38
  */
27
39
  export type IconName = string;
28
40
  /**
29
- * Navigation to perform on click. Example: If you are at route /my/route/asset then 'settings/profile' routes to '/my/route/settings/profile'.
41
+ * The destination path when this item is clicked. Use relative paths that append to the current URL, or enable leadingSlash for absolute routing.
30
42
  */
31
43
  export type NavigationRoute = string;
32
44
  /**
33
- * Whether to add a leading slash to the navigation route.
45
+ * When enabled, prepends '/' to this item's route making it absolute from the root.
34
46
  */
35
47
  export type AddLeadingSlash1 = boolean;
36
48
  /**
37
- * Whether to add a trailing slash to the navigation route.
49
+ * When enabled, appends '/' to the end of this item's route.
38
50
  */
39
51
  export type AddTraillingSlash1 = boolean;
52
+ /**
53
+ * Array of navigation links displayed vertically in the sidebar. Each item can have a label, icon, and destination route.
54
+ */
40
55
  export type NavigationItems = {
41
56
  label?: Label;
42
57
  iconName?: IconName;
@@ -46,6 +61,9 @@ export type NavigationItems = {
46
61
  [k: string]: unknown;
47
62
  }[];
48
63
 
64
+ /**
65
+ * A vertical side navigation widget for creating sidebar menus in dashboards. Use this widget to provide hierarchical or list-based navigation along the side of the dashboard. Features a clickable title/header and multiple navigation items with icons. Supports customizable styling for fonts and colors to match your dashboard theme. Ideal for applications with multiple sections, settings pages, or when you need persistent navigation that doesn't take up header space.
66
+ */
49
67
  export interface InputData {
50
68
  title?: TitleSettings;
51
69
  route?: TitleNavigation;
@@ -55,6 +73,9 @@ export interface InputData {
55
73
  navItems?: NavigationItems;
56
74
  [k: string]: unknown;
57
75
  }
76
+ /**
77
+ * Global styling options applied to all navigation items in the sidebar.
78
+ */
58
79
  export interface ItemStyle {
59
80
  fontSize?: FontSize;
60
81
  fontWeight?: FontWeight;
@@ -62,9 +83,15 @@ export interface ItemStyle {
62
83
  backgroundColor?: BackgroundColor;
63
84
  [k: string]: unknown;
64
85
  }
86
+ /**
87
+ * Text color for navigation item labels and icons.
88
+ */
65
89
  export interface FontColor {
66
90
  [k: string]: unknown;
67
91
  }
92
+ /**
93
+ * Background color of the side navigation panel.
94
+ */
68
95
  export interface BackgroundColor {
69
96
  [k: string]: unknown;
70
97
  }
@@ -1,57 +1,64 @@
1
1
  {
2
2
  "title": "Input Data",
3
+ "description": "A vertical side navigation widget for creating sidebar menus in dashboards. Use this widget to provide hierarchical or list-based navigation along the side of the dashboard. Features a clickable title/header and multiple navigation items with icons. Supports customizable styling for fonts and colors to match your dashboard theme. Ideal for applications with multiple sections, settings pages, or when you need persistent navigation that doesn't take up header space.",
3
4
  "type": "object",
4
5
  "properties": {
5
6
  "title": {
6
7
  "title": "Title Settings",
8
+ "description": "The header text displayed at the top of the side navigation, typically used for branding or section identification.",
7
9
  "order": 1,
8
10
  "type": "string"
9
11
  },
10
12
  "route": {
11
13
  "title": "Title Navigation",
12
14
  "order": 3,
13
- "description": "Navigation to perform on title click. Example: If you are at route /my/route/asset then 'settings/profile' routes to '/my/route/settings/profile'.",
15
+ "description": "The destination path when the title/header is clicked. Use for navigating to a home or main page. Use relative paths or enable leadingSlash for absolute routing.",
14
16
  "type": "string"
15
17
  },
16
18
  "leadingSlash": {
17
19
  "title": "Add Leading Slash",
18
20
  "order": 4,
19
- "description": "Whether to add a leading slash to the navigation route.",
21
+ "description": "When enabled, prepends '/' to the title's navigation route making it absolute from the root. When disabled, routes are relative to the current location.",
20
22
  "dataDrivenDisabled": true,
21
23
  "type": "boolean"
22
24
  },
23
25
  "trailingSlash": {
24
26
  "title": "Add Trailling Slash",
25
27
  "order": 5,
26
- "description": "Whether to add a trailing slash to the navigation route.",
28
+ "description": "When enabled, appends '/' to the end of the title's navigation route. Required by some routing configurations.",
27
29
  "dataDrivenDisabled": true,
28
30
  "type": "boolean"
29
31
  },
30
32
  "style": {
31
33
  "title": "Item Style",
34
+ "description": "Global styling options applied to all navigation items in the sidebar.",
32
35
  "order": 6,
33
36
  "type": "object",
34
37
  "properties": {
35
38
  "fontSize": {
36
39
  "title": "Font Size",
40
+ "description": "Font size in pixels for navigation item labels.",
37
41
  "order": 1,
38
42
  "dataDrivenDisabled": true,
39
43
  "type": "number"
40
44
  },
41
45
  "fontWeight": {
42
46
  "title": "Font Weight",
47
+ "description": "Font weight for navigation items (100=thin, 400=normal, 700=bold, 900=black).",
43
48
  "order": 3,
44
49
  "dataDrivenDisabled": true,
45
50
  "type": "number"
46
51
  },
47
52
  "color": {
48
53
  "title": "Font Color",
54
+ "description": "Text color for navigation item labels and icons.",
49
55
  "order": 4,
50
56
  "type": "color",
51
57
  "dataDrivenDisabled": true
52
58
  },
53
59
  "backgroundColor": {
54
60
  "title": "Background Color",
61
+ "description": "Background color of the side navigation panel.",
55
62
  "order": 4,
56
63
  "type": "color",
57
64
  "dataDrivenDisabled": true
@@ -60,6 +67,7 @@
60
67
  },
61
68
  "navItems": {
62
69
  "title": "Navigation Items",
70
+ "description": "Array of navigation links displayed vertically in the sidebar. Each item can have a label, icon, and destination route.",
63
71
  "order": 7,
64
72
  "type": "array",
65
73
  "items": {
@@ -67,33 +75,34 @@
67
75
  "properties": {
68
76
  "label": {
69
77
  "title": "Label",
78
+ "description": "The text displayed for this navigation item. Should clearly describe the destination section.",
70
79
  "order": 1,
71
80
  "type": "string"
72
81
  },
73
82
  "iconName": {
74
83
  "title": "Icon Name",
75
84
  "order": 2,
76
- "description": "Name of the icon from https://fonts.google.com/icons",
85
+ "description": "Material icon name displayed alongside the label. Find icon names at https://fonts.google.com/icons (e.g., 'dashboard', 'settings', 'analytics', 'people').",
77
86
  "dataDrivenDisabled": true,
78
87
  "type": "string"
79
88
  },
80
89
  "route": {
81
90
  "title": "Navigation Route",
82
91
  "order": 3,
83
- "description": "Navigation to perform on click. Example: If you are at route /my/route/asset then 'settings/profile' routes to '/my/route/settings/profile'.",
92
+ "description": "The destination path when this item is clicked. Use relative paths that append to the current URL, or enable leadingSlash for absolute routing.",
84
93
  "type": "string"
85
94
  },
86
95
  "leadingSlash": {
87
96
  "title": "Add Leading Slash",
88
97
  "order": 4,
89
- "description": "Whether to add a leading slash to the navigation route.",
98
+ "description": "When enabled, prepends '/' to this item's route making it absolute from the root.",
90
99
  "dataDrivenDisabled": true,
91
100
  "type": "boolean"
92
101
  },
93
102
  "trailingSlash": {
94
103
  "title": "Add Trailling Slash",
95
104
  "order": 5,
96
- "description": "Whether to add a trailing slash to the navigation route.",
105
+ "description": "When enabled, appends '/' to the end of this item's route.",
97
106
  "dataDrivenDisabled": true,
98
107
  "type": "boolean"
99
108
  }
@@ -117,7 +117,7 @@ export class WidgetSidenav extends LitElement {
117
117
  border-radius: 4px;
118
118
  }
119
119
 
120
- mdif2-icon {
120
+ md-icon {
121
121
  font-family: 'Material Symbols Outlined';
122
122
  }
123
123
 
@@ -164,10 +164,10 @@ export class WidgetSidenav extends LitElement {
164
164
  >
165
165
  ${item.iconName
166
166
  ? html`
167
- <mdif2-icon
167
+ <md-icon
168
168
  style="font-size: ${iconFontSize}px;width: ${iconFontSize}px;"
169
169
  >${item.iconName}
170
- </mdif2-icon>
170
+ </md-icon>
171
171
  `
172
172
  : ''}
173
173
  ${item.label}