@trimble-oss/moduswebcomponents-mcp 1.0.1 → 1.2.0

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.
@@ -0,0 +1,165 @@
1
+ {
2
+ "description": "A customizable menu item component used to display the item portion of a menu. This component supports a 'start-icon' `<slot>` that allows for custom icons to be placed at the beginning of the item.",
3
+ "properties": [
4
+ {
5
+ "name": "bordered",
6
+ "type": "boolean",
7
+ "description": "",
8
+ "default": null,
9
+ "mutable": false,
10
+ "end_line": 34
11
+ },
12
+ {
13
+ "name": "checkbox",
14
+ "type": "boolean",
15
+ "description": "If true, renders a checkbox at the start of the menu item.",
16
+ "default": null,
17
+ "mutable": false,
18
+ "end_line": 37
19
+ },
20
+ {
21
+ "name": "customClass",
22
+ "type": "string",
23
+ "description": "Custom CSS class to apply to the li element.",
24
+ "default": "''",
25
+ "mutable": false,
26
+ "end_line": 40
27
+ },
28
+ {
29
+ "name": "disabled",
30
+ "type": "boolean",
31
+ "description": "The disabled state of the menu item.",
32
+ "default": null,
33
+ "mutable": false,
34
+ "end_line": 43
35
+ },
36
+ {
37
+ "name": "label",
38
+ "type": "string",
39
+ "description": "The text rendered in the menu item.",
40
+ "default": "''",
41
+ "mutable": false,
42
+ "end_line": 46
43
+ },
44
+ {
45
+ "name": "selected",
46
+ "type": "boolean",
47
+ "description": "The selected state of the menu item.",
48
+ "default": null,
49
+ "mutable": true,
50
+ "end_line": 49
51
+ },
52
+ {
53
+ "name": "focused",
54
+ "type": "boolean",
55
+ "description": "The focused state of the menu item.",
56
+ "default": null,
57
+ "mutable": false,
58
+ "end_line": 52
59
+ },
60
+ {
61
+ "name": "size",
62
+ "type": "ModusSize",
63
+ "description": "The size of the menu item.",
64
+ "default": "'md'",
65
+ "mutable": false,
66
+ "end_line": 55
67
+ },
68
+ {
69
+ "name": "subLabel",
70
+ "type": "string",
71
+ "description": "The text rendered beneath the label.",
72
+ "default": null,
73
+ "mutable": false,
74
+ "end_line": 58
75
+ },
76
+ {
77
+ "name": "tooltipContent",
78
+ "type": "string",
79
+ "description": "The tooltip text to display when hovering over the menu item.",
80
+ "default": null,
81
+ "mutable": false,
82
+ "end_line": 61
83
+ },
84
+ {
85
+ "name": "tooltipPosition",
86
+ "type": "'auto' | 'top' | 'right' | 'bottom' | 'left'",
87
+ "description": "The position of the tooltip relative to the menu item.",
88
+ "default": "'auto'",
89
+ "mutable": false,
90
+ "end_line": 65
91
+ },
92
+ {
93
+ "name": "value",
94
+ "type": "string",
95
+ "description": "The unique identifying value of the menu item.",
96
+ "default": "''",
97
+ "mutable": false,
98
+ "end_line": 68
99
+ },
100
+ {
101
+ "name": "hasSubmenu",
102
+ "type": "boolean",
103
+ "description": "Whether this menu item has a collapsible submenu. When true, the item will show a caret and handle toggle behavior.",
104
+ "default": null,
105
+ "mutable": false,
106
+ "end_line": 71
107
+ }
108
+ ],
109
+ "events": [
110
+ {
111
+ "name": "itemSelect",
112
+ "detail": "{ value: string; selected?: boolean; }",
113
+ "description": "Event emitted when a menu item is selected.",
114
+ "end_line": 82
115
+ }
116
+ ],
117
+ "methods": [
118
+ {
119
+ "name": "collapseSubmenu",
120
+ "signature": "()",
121
+ "parameters": "",
122
+ "returnType": "P",
123
+ "description": "Public method to collapse the submenu if it's expanded",
124
+ "end_line": 131
125
+ }
126
+ ],
127
+ "slots": [
128
+ {
129
+ "name": "start-icon",
130
+ "description": "Slot for start-icon content"
131
+ },
132
+ {
133
+ "name": "default",
134
+ "description": "Slot for default content"
135
+ }
136
+ ],
137
+ "examples": {
138
+ "basic": "<modus-wc-menu>\n <modus-wc-menu-item\n ?bordered=${args.bordered}\n ?checkbox=${args.checkbox}\n custom-class=${ifDefined(args['custom-class'])}\n ?disabled=${args.disabled}\n label=${args.label}\n ?selected=${args.selected}\n size=${args.size}\n sub-label=${ifDefined(args['sub-label'])}\n tooltip-content=${ifDefined(args['tooltip-content'])}\n tooltip-position=${ifDefined(args['tooltip-position'])}\n value=${args.value}\n ></modus-wc-menu-item>\n</modus-wc-menu>",
139
+ "variations": [],
140
+ "args": {
141
+ "label": "'Menu Item'",
142
+ "size": "'md'",
143
+ "value": "'menuItem'"
144
+ },
145
+ "argTypes": {},
146
+ "usage": [],
147
+ "events": [
148
+ "itemSelect"
149
+ ]
150
+ },
151
+ "tag": "modus-wc-menu-item",
152
+ "storyExample": {
153
+ "template": "<modus-wc-menu>\n <modus-wc-menu-item\n ?bordered=${args.bordered}\n ?checkbox=${args.checkbox}\n custom-class=${ifDefined(args['custom-class'])}\n ?disabled=${args.disabled}\n label=${args.label}\n ?selected=${args.selected}\n size=${args.size}\n sub-label=${ifDefined(args['sub-label'])}\n tooltip-content=${ifDefined(args['tooltip-content'])}\n tooltip-position=${ifDefined(args['tooltip-position'])}\n value=${args.value}\n ></modus-wc-menu-item>\n</modus-wc-menu>",
154
+ "args": {
155
+ "label": "'Menu Item'",
156
+ "size": "'md'",
157
+ "value": "'menuItem'"
158
+ },
159
+ "argTypes": {},
160
+ "events": [
161
+ "itemSelect"
162
+ ],
163
+ "fullContent": "import { withActions } from '@storybook/addon-actions/decorator';\nimport { Meta, StoryObj } from '@storybook/web-components';\nimport { html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { createShadowHostClass } from '../../providers/shadow-dom/shadow-host-helper';\nimport { ModusSize } from '../types';\n\ninterface MenuItemArgs {\n bordered?: boolean;\n checkbox?: boolean;\n 'custom-class'?: string;\n disabled?: boolean;\n 'has-submenu'?: boolean;\n label: string;\n selected?: boolean;\n size?: ModusSize;\n 'sub-label'?: string;\n 'tooltip-content'?: string;\n 'tooltip-position'?: 'auto' | 'top' | 'right' | 'bottom' | 'left';\n value: string;\n}\n\nconst meta: Meta<MenuItemArgs> = {\n title: 'Components/Menu Item',\n component: 'modus-wc-menu-item',\n args: {\n label: 'Menu Item',\n size: 'md',\n value: 'menuItem',\n },\n argTypes: {\n size: {\n control: { type: 'select' },\n options: ['sm', 'md', 'lg'],\n },\n 'tooltip-position': {\n control: { type: 'select' },\n options: ['auto', 'top', 'right', 'bottom', 'left'],\n },\n },\n decorators: [withActions],\n parameters: {\n actions: {\n handles: ['itemSelect'],\n },\n },\n};\n\nexport default meta;\n\ntype Story = StoryObj<MenuItemArgs>;\n\nconst Template: Story = {\n render: (args) => {\n // prettier-ignore\n return html`\n<modus-wc-menu>\n <modus-wc-menu-item\n ?bordered=${args.bordered}\n ?checkbox=${args.checkbox}\n custom-class=${ifDefined(args['custom-class'])}\n ?disabled=${args.disabled}\n label=${args.label}\n ?selected=${args.selected}\n size=${args.size}\n sub-label=${ifDefined(args['sub-label'])}\n tooltip-content=${ifDefined(args['tooltip-content'])}\n tooltip-position=${ifDefined(args['tooltip-position'])}\n value=${args.value}\n ></modus-wc-menu-item>\n</modus-wc-menu>\n `;\n },\n};\n\nexport const Default: Story = { ...Template };\n\nexport const WithIcon: Story = {\n render: (args) => {\n // prettier-ignore\n return html`\n<modus-wc-menu>\n <modus-wc-menu-item\n ?bordered=${args.bordered}\n ?checkbox=${args.checkbox}\n custom-class=${ifDefined(args['custom-class'])}\n ?disabled=${args.disabled}\n label=${args.label}\n ?selected=${args.selected}\n size=${args.size}\n sub-label=${ifDefined(args['sub-label'])}\n tooltip-content=${ifDefined(args['tooltip-content'])}\n tooltip-position=${ifDefined(args['tooltip-position'])}\n value=${args.value}\n >\n <modus-wc-icon\n slot=\"start-icon\"\n name=\"alert\"\n size=\"sm\"\n ></modus-wc-icon>\n </modus-wc-menu-item>\n</modus-wc-menu>\n `;\n },\n};\nexport const WithCheckbox: Story = {\n args: {\n checkbox: true,\n },\n render: (args) => {\n // prettier-ignore\n return html`\n<modus-wc-menu>\n <modus-wc-menu-item\n ?bordered=${args.bordered}\n ?checkbox=${args.checkbox}\n custom-class=${ifDefined(args['custom-class'])}\n ?disabled=${args.disabled}\n label=${args.label}\n ?selected=${args.selected}\n size=${args.size}\n sub-label=${ifDefined(args['sub-label'])}\n value=${args.value}\n ></modus-wc-menu-item>\n</modus-wc-menu>\n `;\n },\n};\n\nexport const WithTooltip: Story = {\n args: {\n 'tooltip-content': 'This is a tooltip for the menu item',\n 'tooltip-position': 'top',\n },\n render: (args) => {\n // prettier-ignore\n return html`\n<modus-wc-menu>\n <modus-wc-menu-item\n ?bordered=${args.bordered}\n custom-class=${ifDefined(args['custom-class'])}\n ?disabled=${args.disabled}\n label=${args.label}\n ?selected=${args.selected}\n size=${args.size}\n sub-label=${ifDefined(args['sub-label'])}\n tooltip-content=${ifDefined((args['tooltip-content']))}\n tooltip-position=${ifDefined(args['tooltip-position'])}\n value=${args.value}\n ></modus-wc-menu-item>\n</modus-wc-menu>\n `;\n },\n};\n\nexport const ShadowDomParent: Story = {\n render: (args) => {\n // Create a unique shadow host for menu-item component\n if (!customElements.get('menu-item-shadow-host')) {\n const MenuItemShadowHost = createShadowHostClass<MenuItemArgs>({\n componentTag: 'modus-wc-menu',\n propsMapper: (v: MenuItemArgs, el: HTMLElement) => {\n const menuEl = el as unknown as {\n ariaLabel: string;\n };\n menuEl.ariaLabel = 'Shadow DOM Menu';\n\n // Get or create menu item\n let menuItem = el.querySelector('modus-wc-menu-item');\n if (!menuItem) {\n menuItem = document.createElement('modus-wc-menu-item');\n el.innerHTML = '';\n el.appendChild(menuItem);\n }\n\n // Update properties on the existing element\n const menuItemEl = menuItem as unknown as {\n ariaLabel: string;\n bordered: boolean;\n checkbox: boolean;\n customClass: string;\n disabled: boolean;\n label: string;\n selected: boolean;\n size: string;\n subLabel: string;\n tooltipContent: string;\n tooltipPosition: string;\n value: string;\n };\n\n menuItemEl.ariaLabel = 'Menu item in shadow DOM';\n menuItemEl.bordered = Boolean(v.bordered);\n menuItemEl.checkbox = Boolean(v.checkbox);\n menuItemEl.customClass = v['custom-class'] || '';\n menuItemEl.disabled = Boolean(v.disabled);\n menuItemEl.label = v.label;\n menuItemEl.selected = Boolean(v.selected);\n menuItemEl.size = v.size || 'md';\n menuItemEl.subLabel = v['sub-label'] || '';\n menuItemEl.tooltipContent = v['tooltip-content'] || '';\n menuItemEl.tooltipPosition = v['tooltip-position'] || 'auto';\n menuItemEl.value = v.value;\n },\n });\n customElements.define('menu-item-shadow-host', MenuItemShadowHost);\n }\n\n return html`<menu-item-shadow-host\n .props=${{ ...args }}\n ></menu-item-shadow-host>`;\n },\n};\n"
164
+ }
165
+ }
@@ -0,0 +1,106 @@
1
+ {
2
+ "description": "A customizable menu component used to display a list of li elements vertically or horizontally. The component supports a `<slot>` for injecting custom li elements inside the ul element.",
3
+ "properties": [
4
+ {
5
+ "name": "bordered",
6
+ "type": "boolean",
7
+ "description": "Indicates that the menu should have a border.",
8
+ "default": null,
9
+ "mutable": false,
10
+ "end_line": 34
11
+ },
12
+ {
13
+ "name": "customClass",
14
+ "type": "string",
15
+ "description": "Custom CSS class to apply to the ul element.",
16
+ "default": "''",
17
+ "mutable": false,
18
+ "end_line": 37
19
+ },
20
+ {
21
+ "name": "orientation",
22
+ "type": "Orientation",
23
+ "description": "The orientation of the menu.",
24
+ "default": "'vertical'",
25
+ "mutable": false,
26
+ "end_line": 40
27
+ },
28
+ {
29
+ "name": "selectionMode",
30
+ "type": "SelectionMode",
31
+ "description": "The selection mode of the menu.",
32
+ "default": "'single'",
33
+ "mutable": false,
34
+ "end_line": 43
35
+ },
36
+ {
37
+ "name": "size",
38
+ "type": "ModusSize",
39
+ "description": "The size of the menu.",
40
+ "default": "'md'",
41
+ "mutable": false,
42
+ "end_line": 51
43
+ },
44
+ {
45
+ "name": "isSubMenu",
46
+ "type": "boolean",
47
+ "description": "Indicates that this menu is a submenu (dropdown).",
48
+ "default": null,
49
+ "mutable": false,
50
+ "end_line": 54
51
+ }
52
+ ],
53
+ "events": [
54
+ {
55
+ "name": "menuFocusout",
56
+ "detail": "FocusEvent",
57
+ "description": "Event emitted when the menu loses focus.",
58
+ "end_line": 57
59
+ },
60
+ {
61
+ "name": "menuSelectionChange",
62
+ "detail": "{ selectedItems: HTMLElement[]; }",
63
+ "description": "Event emitted when the selection changes in multiple selection mode. Emits the array of currently selected menu item elements.",
64
+ "end_line": 62
65
+ }
66
+ ],
67
+ "methods": [],
68
+ "slots": [
69
+ {
70
+ "name": "default",
71
+ "description": "Slot for default content"
72
+ }
73
+ ],
74
+ "examples": {
75
+ "basic": "<modus-wc-menu\n aria-label=\"Menu\"\n ?bordered=${args.bordered}\n custom-class=${ifDefined(args['custom-class'])}\n orientation=${ifDefined(args.orientation)}\n selection-mode=${ifDefined(args['selection-mode'])}\n size=${ifDefined(args.size)}\n>\n <modus-wc-menu-item\n label=\"Small\"\n value=\"1\"\n size=\"sm\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item label=\"Medium\" value=\"2\"></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Large\"\n value=\"3\"\n size=\"lg\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Bordered\"\n value=\"3\"\n bordered=\"true\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"With Sub-label\"\n value=\"3\"\n sub-label=\"Sub-label\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Selected\"\n value=\"3\"\n selected=\"true\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"With Start Icon\"\n value=\"3\"\n >\n <modus-wc-icon slot=\"start-icon\" name=\"info\"></modus-wc-icon>\n </modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Disabled\"\n value=\"3\"\n disabled=\"true\"\n ></modus-wc-menu-item>\n</modus-wc-menu>",
76
+ "variations": [],
77
+ "args": {
78
+ "orientation": "'vertical'",
79
+ "selection-mode": "'single'",
80
+ "size": "'md'"
81
+ },
82
+ "argTypes": {},
83
+ "usage": [],
84
+ "events": [
85
+ "menuFocusout",
86
+ "menuSelectionChange",
87
+ "itemSelect"
88
+ ]
89
+ },
90
+ "tag": "modus-wc-menu",
91
+ "storyExample": {
92
+ "template": "<modus-wc-menu\n aria-label=\"Menu\"\n ?bordered=${args.bordered}\n custom-class=${ifDefined(args['custom-class'])}\n orientation=${ifDefined(args.orientation)}\n selection-mode=${ifDefined(args['selection-mode'])}\n size=${ifDefined(args.size)}\n>\n <modus-wc-menu-item\n label=\"Small\"\n value=\"1\"\n size=\"sm\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item label=\"Medium\" value=\"2\"></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Large\"\n value=\"3\"\n size=\"lg\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Bordered\"\n value=\"3\"\n bordered=\"true\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"With Sub-label\"\n value=\"3\"\n sub-label=\"Sub-label\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Selected\"\n value=\"3\"\n selected=\"true\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"With Start Icon\"\n value=\"3\"\n >\n <modus-wc-icon slot=\"start-icon\" name=\"info\"></modus-wc-icon>\n </modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Disabled\"\n value=\"3\"\n disabled=\"true\"\n ></modus-wc-menu-item>\n</modus-wc-menu>",
93
+ "args": {
94
+ "orientation": "'vertical'",
95
+ "selection-mode": "'single'",
96
+ "size": "'md'"
97
+ },
98
+ "argTypes": {},
99
+ "events": [
100
+ "menuFocusout",
101
+ "menuSelectionChange",
102
+ "itemSelect"
103
+ ],
104
+ "fullContent": "import { withActions } from '@storybook/addon-actions/decorator';\nimport { Meta, StoryObj } from '@storybook/web-components';\nimport { html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { ref } from 'lit/directives/ref.js';\nimport { createShadowHostClass } from '../../providers/shadow-dom/shadow-host-helper';\nimport { ModusSize, Orientation, SelectionMode } from '../types';\n\ninterface MenuArgs {\n bordered?: boolean;\n 'custom-class'?: string;\n orientation?: Orientation;\n 'selection-mode'?: SelectionMode;\n size?: ModusSize;\n}\n\nconst meta: Meta<MenuArgs> = {\n title: 'Components/Menu',\n component: 'modus-wc-menu',\n args: {\n orientation: 'vertical',\n 'selection-mode': 'single',\n size: 'md',\n },\n argTypes: {\n orientation: {\n control: { type: 'select' },\n options: ['horizontal', 'vertical'],\n },\n 'selection-mode': {\n control: { type: 'select' },\n options: ['single', 'multiple'],\n },\n size: {\n control: { type: 'select' },\n options: ['xs', 'sm', 'md', 'lg'],\n },\n },\n decorators: [withActions],\n parameters: {\n actions: {\n handles: ['menuFocusout', 'menuSelectionChange', 'itemSelect'],\n },\n },\n};\n\nexport default meta;\n\ntype Story = StoryObj<MenuArgs>;\n\nexport const Default: Story = {\n render: (args) => {\n // prettier-ignore\n return html`\n<modus-wc-menu\n aria-label=\"Menu\"\n ?bordered=${args.bordered}\n custom-class=${ifDefined(args['custom-class'])}\n orientation=${ifDefined(args.orientation)}\n selection-mode=${ifDefined(args['selection-mode'])}\n size=${ifDefined(args.size)}\n>\n <modus-wc-menu-item\n label=\"Small\"\n value=\"1\"\n size=\"sm\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item label=\"Medium\" value=\"2\"></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Large\"\n value=\"3\"\n size=\"lg\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Bordered\"\n value=\"3\"\n bordered=\"true\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"With Sub-label\"\n value=\"3\"\n sub-label=\"Sub-label\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Selected\"\n value=\"3\"\n selected=\"true\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"With Start Icon\"\n value=\"3\"\n >\n <modus-wc-icon slot=\"start-icon\" name=\"info\"></modus-wc-icon>\n </modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Disabled\"\n value=\"3\"\n disabled=\"true\"\n ></modus-wc-menu-item>\n</modus-wc-menu>\n `;\n },\n};\n\nexport const MultiSelect: Story = {\n args: {\n 'selection-mode': 'multiple',\n },\n render: (args) => {\n let outputEl: Element | undefined;\n\n const handleSelectionChange = (\n e: CustomEvent<{ selectedItems: HTMLElement[] }>\n ) => {\n if (!outputEl) return;\n const { selectedItems } = e.detail;\n outputEl.textContent =\n selectedItems.length > 0\n ? `Selected: ${selectedItems.map((i) => i.getAttribute('value')).join(', ')}`\n : 'Selected: none';\n };\n\n // prettier-ignore\n return html`\n<modus-wc-menu\n aria-label=\"Menu\"\n ?bordered=${args.bordered}\n custom-class=${ifDefined(args['custom-class'])}\n orientation=${ifDefined(args.orientation)}\n selection-mode=${ifDefined(args['selection-mode'])}\n size=${ifDefined(args.size)}\n @menuSelectionChange=${handleSelectionChange}\n>\n <modus-wc-menu-item\n label=\"Menu Item 1\"\n value=\"1\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item label=\"Menu Item 2\" value=\"2\"></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Menu Item 3\"\n value=\"3\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Menu Item 4\"\n value=\"4\"\n bordered=\"true\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Menu Item 5\"\n value=\"5\"\n sub-label=\"Menu Item 5 Sub-label\"\n ></modus-wc-menu-item>\n</modus-wc-menu>\n<p ${ref((el) => { outputEl = el; })} style=\"font-size: 0.875rem; margin-top: 0.5rem; color: var(--modus-wc-color-gray-6);\">Selected: none</p>\n `;\n },\n};\n\nexport const CustomMenu: Story = {\n render: () => {\n // prettier-ignore\n return html`\n<style>\n .custom-menu-width {\n width: 400px;\n }\n .custom-flex-row {\n display: flex;\n align-items: center;\n }\n .custom-nested-row {\n padding-inline-start: 3rem;\n }\n .custom-justify-end {\n margin-left: auto;\n }\n .green-square {\n height: 18px;\n width: 18px;\n background-color: green;\n }\n .red-square {\n height: 18px;\n width: 18px;\n background-color: red;\n }\n</style>\n<modus-wc-menu\n aria-label=\"Custom menu\"\n custom-class=\"custom-menu-width\"\n>\n <li>\n <div class=\"custom-flex-row\">\n <modus-wc-icon decorative=\"true\" name=\"expand_more\"></modus-wc-icon>\n <modus-wc-button aria-label=\"Visible button\" size=\"sm\" shape=\"circle\" variant=\"borderless\">\n <modus-wc-icon aria-label=\"Visible icon\" name=\"visibility_on\"></modus-wc-icon>\n </modus-wc-button>\n <div>Parent</div>\n <div class=\"custom-justify-end\">\n <modus-wc-button aria-label=\"Actions button\" size=\"sm\" shape=\"circle\" variant=\"borderless\">\n <modus-wc-icon aria-label=\"Actions icon\" name=\"more_vertical\"></modus-wc-icon>\n </modus-wc-button>\n </div>\n </div>\n </li>\n <li>\n <div class=\"custom-flex-row custom-nested-row\">\n <modus-wc-button aria-label=\"Visible button\" size=\"sm\" shape=\"circle\" variant=\"borderless\">\n <modus-wc-icon aria-label=\"Visible icon\" name=\"visibility_on\"></modus-wc-icon>\n </modus-wc-button>\n <div class=\"green-square\"></div>\n <div>Child</div>\n <div class=\"custom-justify-end\">\n <modus-wc-button aria-label=\"Actions button\" size=\"sm\" shape=\"circle\" variant=\"borderless\">\n <modus-wc-icon aria-label=\"Actions icon\" name=\"more_vertical\"></modus-wc-icon>\n </modus-wc-button>\n </div>\n </div>\n </li>\n <li>\n <div class=\"custom-flex-row custom-nested-row\">\n <modus-wc-button aria-label=\"Visible button\" size=\"sm\" shape=\"circle\" variant=\"borderless\">\n <modus-wc-icon aria-label=\"Invisible icon\" name=\"visibility_off\"></modus-wc-icon>\n </modus-wc-button>\n <div class=\"red-square\"></div>\n <div>Child</div>\n <div class=\"custom-justify-end\">\n <modus-wc-button aria-label=\"Actions button\" size=\"sm\" shape=\"circle\" variant=\"borderless\">\n <modus-wc-icon aria-label=\"Actions icon\" name=\"more_vertical\"></modus-wc-icon>\n </modus-wc-button>\n </div>\n </div>\n </li>\n <li>\n <div class=\"custom-flex-row\">\n <modus-wc-icon decorative=\"true\" name=\"chevron_right\"></modus-wc-icon>\n <modus-wc-button aria-label=\"Visible button\" size=\"sm\" shape=\"circle\" variant=\"borderless\">\n <modus-wc-icon aria-label=\"Visible icon\" name=\"visibility_on\"></modus-wc-icon>\n </modus-wc-button>\n <div>Parent</div>\n <div class=\"custom-justify-end\">\n <modus-wc-button aria-label=\"Actions button\" size=\"sm\" shape=\"circle\" variant=\"borderless\">\n <modus-wc-icon aria-label=\"Actions icon\" name=\"more_vertical\"></modus-wc-icon>\n </modus-wc-button>\n </div>\n </div>\n </li>\n</modus-wc-menu>\n `;\n },\n};\n\nexport const CollapsibleMenu: Story = {\n render: () => {\n return html`\n <style>\n .menu-width {\n width: 400px;\n }\n </style>\n <modus-wc-menu custom-class=\"menu-width\">\n <modus-wc-menu-item\n label=\"Charts\"\n .hasSubmenu=${true}\n id=\"charts-menu\"\n value=\"charts\"\n >\n <modus-wc-icon\n slot=\"start-icon\"\n decorative=\"true\"\n name=\"bar_graph\"\n ></modus-wc-icon>\n <modus-wc-menu .isSubMenu=${true} id=\"charts-submenu\">\n <modus-wc-menu-item label=\"Bar Chart\" value=\"bar-chart\">\n </modus-wc-menu-item>\n <modus-wc-menu-item label=\"Line Chart\" value=\"line-chart\">\n </modus-wc-menu-item>\n </modus-wc-menu>\n </modus-wc-menu-item>\n\n <modus-wc-menu-item label=\"Calendar\" value=\"calendar\">\n <modus-wc-icon\n slot=\"start-icon\"\n decorative=\"true\"\n name=\"calendar\"\n ></modus-wc-icon>\n </modus-wc-menu-item>\n\n <modus-wc-menu-item\n label=\"Reports\"\n .hasSubmenu=${true}\n id=\"reports-menu\"\n value=\"reports\"\n >\n <modus-wc-icon\n slot=\"start-icon\"\n decorative=\"true\"\n name=\"master_data\"\n ></modus-wc-icon>\n <modus-wc-menu .isSubMenu=${true} id=\"reports-submenu\">\n <modus-wc-menu-item label=\"Monthly Report\" value=\"monthly-report\">\n </modus-wc-menu-item>\n <modus-wc-menu-item label=\"Annual Report\" value=\"annual-report\">\n </modus-wc-menu-item>\n </modus-wc-menu>\n </modus-wc-menu-item>\n </modus-wc-menu>\n\n <script>\n // Adding this block to show how to set submenu properties via JS\n // document.addEventListener('DOMContentLoaded', () => {\n // const chartsMenu = document.querySelector('#charts-menu');\n // const reportsMenu = document.querySelector('#reports-menu');\n // const chartsSubMenu = document.querySelector('#charts-submenu');\n // const reportsSubMenu = document.querySelector('#reports-submenu');\n\n // // Set hasSubmenu property for menu items with submenus\n // [chartsMenu, reportsMenu].forEach((menuItem) => {\n // if (menuItem) {\n // menuItem.hasSubmenu = true;\n // }\n // });\n\n // // Set isSubMenu for all submenu elements\n // [chartsSubMenu, reportsSubMenu].forEach((submenu) => {\n // if (submenu) {\n // submenu.isSubMenu = true;\n // }\n // });\n // });\n </script>\n `;\n },\n};\n\nexport const ShadowDomParent: Story = {\n render: (args) => {\n // Create a unique shadow host for menu component\n if (!customElements.get('menu-shadow-host')) {\n const MenuShadowHost = createShadowHostClass<MenuArgs>({\n componentTag: 'modus-wc-menu',\n propsMapper: (v: MenuArgs, el: HTMLElement) => {\n const menuEl = el as unknown as {\n ariaLabel: string;\n bordered: boolean;\n customClass: string;\n orientation: string;\n size: string;\n };\n menuEl.ariaLabel = 'Shadow DOM Menu';\n menuEl.bordered = Boolean(v.bordered);\n menuEl.customClass = v['custom-class'] || '';\n menuEl.orientation = v.orientation || 'vertical';\n menuEl.size = v.size || 'md';\n\n // Only set innerHTML once on initial creation\n if (!el.querySelector('modus-wc-menu-item')) {\n el.innerHTML = `\n <modus-wc-menu-item\n label=\"Small\"\n value=\"1\"\n size=\"sm\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item label=\"Medium\" value=\"2\"></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Large\"\n value=\"3\"\n size=\"lg\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Bordered\"\n value=\"3\"\n bordered=\"true\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"With Sub-label\"\n value=\"3\"\n sub-label=\"Sub-label\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Selected\"\n value=\"3\"\n selected=\"true\"\n ></modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"With Start Icon\"\n value=\"3\"\n >\n <modus-wc-icon slot=\"start-icon\" name=\"info\"></modus-wc-icon>\n </modus-wc-menu-item>\n <modus-wc-menu-item\n label=\"Disabled\"\n value=\"3\"\n disabled=\"true\"\n ></modus-wc-menu-item>\n `;\n }\n },\n });\n customElements.define('menu-shadow-host', MenuShadowHost);\n }\n\n return html`<menu-shadow-host .props=${{ ...args }}></menu-shadow-host>`;\n },\n};\n"
105
+ }
106
+ }
@@ -0,0 +1,290 @@
1
+ {
2
+ "description": "A customizable navbar component used for top level navigation of all Trimble applications.",
3
+ "properties": [
4
+ {
5
+ "name": "logoName",
6
+ "type": "LogoName",
7
+ "description": "The name of the logo to display. Supports any valid 'logo-name' from the 'modus-wc-logo' component. Defaults to 'trimble'.",
8
+ "default": "'trimble'",
9
+ "mutable": false,
10
+ "end_line": 94
11
+ },
12
+ {
13
+ "name": "appsMenuOpen",
14
+ "type": "boolean",
15
+ "description": "The open state of the apps menu.",
16
+ "default": "false",
17
+ "mutable": true,
18
+ "end_line": 97
19
+ },
20
+ {
21
+ "name": "condensed",
22
+ "type": "boolean",
23
+ "description": "Applies condensed layout and styling.",
24
+ "default": "false",
25
+ "mutable": false,
26
+ "end_line": 100
27
+ },
28
+ {
29
+ "name": "condensedMenuOpen",
30
+ "type": "boolean",
31
+ "description": "The open state of the condensed menu.",
32
+ "default": "false",
33
+ "mutable": true,
34
+ "end_line": 103
35
+ },
36
+ {
37
+ "name": "customClass",
38
+ "type": "string",
39
+ "description": "Custom CSS class to apply to the host element.",
40
+ "default": "''",
41
+ "mutable": false,
42
+ "end_line": 106
43
+ },
44
+ {
45
+ "name": "mainMenuOpen",
46
+ "type": "boolean",
47
+ "description": "The open state of the main menu.",
48
+ "default": "false",
49
+ "mutable": true,
50
+ "end_line": 109
51
+ },
52
+ {
53
+ "name": "notificationsMenuOpen",
54
+ "type": "boolean",
55
+ "description": "The open state of the notifications menu.",
56
+ "default": "false",
57
+ "mutable": true,
58
+ "end_line": 112
59
+ },
60
+ {
61
+ "name": "searchDebounceMs",
62
+ "type": "number",
63
+ "description": "Debounce time in milliseconds for search input changes. Default is 300ms.",
64
+ "default": "300",
65
+ "mutable": false,
66
+ "end_line": 115
67
+ },
68
+ {
69
+ "name": "searchInputOpen",
70
+ "type": "boolean",
71
+ "description": "The open state of the search input.",
72
+ "default": "false",
73
+ "mutable": true,
74
+ "end_line": 118
75
+ },
76
+ {
77
+ "name": "textOverrides",
78
+ "type": "INavbarTextOverrides",
79
+ "description": "Text replacements for the navbar.",
80
+ "default": null,
81
+ "mutable": false,
82
+ "end_line": 121
83
+ },
84
+ {
85
+ "name": "userCard",
86
+ "type": "INavbarUserCard",
87
+ "description": "User information used to render the user card.",
88
+ "default": null,
89
+ "mutable": false,
90
+ "end_line": 124
91
+ },
92
+ {
93
+ "name": "userMenuOpen",
94
+ "type": "boolean",
95
+ "description": "The open state of the user menu.",
96
+ "default": "false",
97
+ "mutable": true,
98
+ "end_line": 127
99
+ },
100
+ {
101
+ "name": "visibility",
102
+ "type": "INavbarVisibility",
103
+ "description": "The visibility of individual navbar buttons. Default is user profile visible, others hidden.",
104
+ "default": "{ ai: false, apps: false, help: false, logo: true, mainMenu: false, notifications: false, search: false, searchInput: false, user: true, }",
105
+ "mutable": false,
106
+ "end_line": 140
107
+ }
108
+ ],
109
+ "events": [
110
+ {
111
+ "name": "aiClick",
112
+ "detail": "MouseEvent | KeyboardEvent",
113
+ "description": "Event emitted when the AI button is clicked or activated via keyboard.",
114
+ "end_line": 143
115
+ },
116
+ {
117
+ "name": "appsClick",
118
+ "detail": "MouseEvent | KeyboardEvent",
119
+ "description": "Event emitted when the apps button is clicked or activated via keyboard.",
120
+ "end_line": 146
121
+ },
122
+ {
123
+ "name": "appsMenuOpenChange",
124
+ "detail": "boolean",
125
+ "description": "Event emitted when the apps menu open state changes.",
126
+ "end_line": 149
127
+ },
128
+ {
129
+ "name": "condensedMenuOpenChange",
130
+ "detail": "boolean",
131
+ "description": "Event emitted when the condensed menu open state changes.",
132
+ "end_line": 152
133
+ },
134
+ {
135
+ "name": "helpClick",
136
+ "detail": "MouseEvent | KeyboardEvent",
137
+ "description": "Event emitted when the help button is clicked or activated via keyboard.",
138
+ "end_line": 155
139
+ },
140
+ {
141
+ "name": "mainMenuOpenChange",
142
+ "detail": "boolean",
143
+ "description": "Event emitted when the main menu open state changes.",
144
+ "end_line": 158
145
+ },
146
+ {
147
+ "name": "myTrimbleClick",
148
+ "detail": "MouseEvent | KeyboardEvent",
149
+ "description": "Event emitted when the user profile Access MyTrimble button is clicked or activated via keyboard.",
150
+ "end_line": 161
151
+ },
152
+ {
153
+ "name": "notificationsClick",
154
+ "detail": "MouseEvent | KeyboardEvent",
155
+ "description": "Event emitted when the notifications button is clicked or activated via keyboard.",
156
+ "end_line": 164
157
+ },
158
+ {
159
+ "name": "notificationsMenuOpenChange",
160
+ "detail": "boolean",
161
+ "description": "Event emitted when the notifications menu open state changes.",
162
+ "end_line": 167
163
+ },
164
+ {
165
+ "name": "searchChange",
166
+ "detail": "{ value: string }",
167
+ "description": "Event emitted when the search input value is changed.",
168
+ "end_line": 170
169
+ },
170
+ {
171
+ "name": "searchClick",
172
+ "detail": "MouseEvent | KeyboardEvent",
173
+ "description": "Event emitted when the search button is clicked or activated via keyboard.",
174
+ "end_line": 173
175
+ },
176
+ {
177
+ "name": "searchInputOpenChange",
178
+ "detail": "boolean",
179
+ "description": "Event emitted when the search input open state changes.",
180
+ "end_line": 176
181
+ },
182
+ {
183
+ "name": "signOutClick",
184
+ "detail": "MouseEvent | KeyboardEvent",
185
+ "description": "Event emitted when the user profile sign out button is clicked or activated via keyboard.",
186
+ "end_line": 179
187
+ },
188
+ {
189
+ "name": "trimbleLogoClick",
190
+ "detail": "MouseEvent | KeyboardEvent",
191
+ "description": "Event emitted when the logo button is clicked or activated via keyboard,regardless of the `logoName` prop value.",
192
+ "end_line": 183
193
+ },
194
+ {
195
+ "name": "userMenuOpenChange",
196
+ "detail": "boolean",
197
+ "description": "Event emitted when the user menu open state changes.",
198
+ "end_line": 186
199
+ }
200
+ ],
201
+ "methods": [],
202
+ "slots": [
203
+ {
204
+ "name": "main-menu",
205
+ "description": "Slot for main-menu content"
206
+ },
207
+ {
208
+ "name": "start",
209
+ "description": "Slot for start content"
210
+ },
211
+ {
212
+ "name": "center",
213
+ "description": "Slot for center content"
214
+ },
215
+ {
216
+ "name": "end",
217
+ "description": "Slot for end content"
218
+ },
219
+ {
220
+ "name": "notifications",
221
+ "description": "Slot for notifications content"
222
+ },
223
+ {
224
+ "name": "apps",
225
+ "description": "Slot for apps content"
226
+ }
227
+ ],
228
+ "examples": {
229
+ "basic": "<style>\n div[id^='story--components-navbar--default'] {\n border: 1px dashed black;\n height: 360px;\n overflow: hidden;\n }\n [slot=main-menu] {\n background-color: #0063a3;\n color: white;\n height: 400px;\n }\n</style>\n<modus-wc-navbar\n ?apps-menu-open=${args['apps-menu-open']}\n ?condensed=${args.condensed}\n ?condensed-menu-open=${args['condensed-menu-open']}\n custom-class=${ifDefined(args['custom-class'])}\n ?main-menu-open=${args['main-menu-open']}\n ?notifications-menu-open=${args['notifications-menu-open']}\n search-debounce-ms=${ifDefined(args['search-debounce-ms'])}\n ?search-input-open=${args['search-input-open']}\n .textOverrides=${ifDefined(args['text-overrides'])}\n .userCard=${args['user-card']}\n ?user-menu-open=${args['user-menu-open']}\n .visibility=${args.visibility}\n logo-name=${args['logo-name']}\n>\n <div slot=\"main-menu\">Main menu contents</div>\n <div slot=\"notifications\">Notification contents</div>\n <div slot=\"apps\">App drawer contents</div>\n</modus-wc-navbar>\n<script>\n// Added this block to demonstrate how to handle navbar visibility settings using JavaScript.\n// const visibility = {\n// ai: true,\n// apps: true,\n// help: true,\n// logo: true,\n// mainMenu: true,\n// notifications: true,\n// search: true,\n// searchInput: true,\n// user: true,\n// };\n// const userCard = {\n// avatarAlt: 'Sonic',\n// avatarSrc: 'https://i1.sndcdn.com/artworks-000405996468-wmh3uv-t500x500.jpg',\n// email: 'sonic@trimble.com',\n// name: 'Sonic the Hedgehog',\n// };\n// const navbar = document.querySelector('modus-wc-navbar');\n// navbar.visibility = visibility;\n// navbar.userCard = userCard;\n</script>",
230
+ "variations": [],
231
+ "args": {
232
+ "condensed": "false",
233
+ "search-debounce-ms": "300",
234
+ "text-overrides": "textOverrides",
235
+ "user-card": "userCard",
236
+ "logo-name": "'trimble'"
237
+ },
238
+ "argTypes": {},
239
+ "usage": [],
240
+ "events": [
241
+ "aiClick",
242
+ "appsClick",
243
+ "appsMenuOpenChange",
244
+ "condensedMenuOpenChange",
245
+ "helpClick",
246
+ "mainMenuOpenChange",
247
+ "myTrimbleClick",
248
+ "notificationsMenuOpenChange",
249
+ "notificationsClick",
250
+ "searchChange",
251
+ "searchClick",
252
+ "searchInputOpenChange",
253
+ "signOutClick",
254
+ "trimbleLogoClick",
255
+ "userMenuOpenChange",
256
+ ""
257
+ ]
258
+ },
259
+ "tag": "modus-wc-navbar",
260
+ "storyExample": {
261
+ "template": "<style>\n div[id^='story--components-navbar--default'] {\n border: 1px dashed black;\n height: 360px;\n overflow: hidden;\n }\n [slot=main-menu] {\n background-color: #0063a3;\n color: white;\n height: 400px;\n }\n</style>\n<modus-wc-navbar\n ?apps-menu-open=${args['apps-menu-open']}\n ?condensed=${args.condensed}\n ?condensed-menu-open=${args['condensed-menu-open']}\n custom-class=${ifDefined(args['custom-class'])}\n ?main-menu-open=${args['main-menu-open']}\n ?notifications-menu-open=${args['notifications-menu-open']}\n search-debounce-ms=${ifDefined(args['search-debounce-ms'])}\n ?search-input-open=${args['search-input-open']}\n .textOverrides=${ifDefined(args['text-overrides'])}\n .userCard=${args['user-card']}\n ?user-menu-open=${args['user-menu-open']}\n .visibility=${args.visibility}\n logo-name=${args['logo-name']}\n>\n <div slot=\"main-menu\">Main menu contents</div>\n <div slot=\"notifications\">Notification contents</div>\n <div slot=\"apps\">App drawer contents</div>\n</modus-wc-navbar>\n<script>\n// Added this block to demonstrate how to handle navbar visibility settings using JavaScript.\n// const visibility = {\n// ai: true,\n// apps: true,\n// help: true,\n// logo: true,\n// mainMenu: true,\n// notifications: true,\n// search: true,\n// searchInput: true,\n// user: true,\n// };\n// const userCard = {\n// avatarAlt: 'Sonic',\n// avatarSrc: 'https://i1.sndcdn.com/artworks-000405996468-wmh3uv-t500x500.jpg',\n// email: 'sonic@trimble.com',\n// name: 'Sonic the Hedgehog',\n// };\n// const navbar = document.querySelector('modus-wc-navbar');\n// navbar.visibility = visibility;\n// navbar.userCard = userCard;\n</script>",
262
+ "args": {
263
+ "condensed": "false",
264
+ "search-debounce-ms": "300",
265
+ "text-overrides": "textOverrides",
266
+ "user-card": "userCard",
267
+ "logo-name": "'trimble'"
268
+ },
269
+ "argTypes": {},
270
+ "events": [
271
+ "aiClick",
272
+ "appsClick",
273
+ "appsMenuOpenChange",
274
+ "condensedMenuOpenChange",
275
+ "helpClick",
276
+ "mainMenuOpenChange",
277
+ "myTrimbleClick",
278
+ "notificationsMenuOpenChange",
279
+ "notificationsClick",
280
+ "searchChange",
281
+ "searchClick",
282
+ "searchInputOpenChange",
283
+ "signOutClick",
284
+ "trimbleLogoClick",
285
+ "userMenuOpenChange",
286
+ ""
287
+ ],
288
+ "fullContent": "import { withActions } from '@storybook/addon-actions/decorator';\nimport { Meta, StoryObj } from '@storybook/web-components';\nimport { html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport {\n INavbarTextOverrides,\n INavbarUserCard,\n INavbarVisibility,\n} from './modus-wc-navbar';\nimport { getAvailableLogos, LogoName } from '../modus-wc-logo/logo-constants';\n\nconst textOverrides: INavbarTextOverrides = {\n apps: 'Apps',\n help: 'Help',\n notifications: 'Notifications',\n search: 'Search',\n};\n\nconst userCard: INavbarUserCard = {\n avatarAlt: 'Sonic',\n avatarSrc: 'https://i1.sndcdn.com/artworks-000405996468-wmh3uv-t500x500.jpg',\n email: 'sonic@trimble.com',\n name: 'Sonic the Hedgehog',\n};\n\nconst visibility: INavbarVisibility = {\n ai: true,\n apps: true,\n help: true,\n logo: true,\n mainMenu: true,\n notifications: true,\n search: true,\n searchInput: true,\n user: true,\n};\n\ninterface NavbarArgs {\n 'apps-menu-open'?: boolean;\n condensed?: boolean;\n 'condensed-menu-open'?: boolean;\n 'custom-class'?: string;\n 'main-menu-open'?: boolean;\n 'notifications-menu-open'?: boolean;\n 'search-debounce-ms'?: number;\n 'search-input-open'?: boolean;\n 'text-overrides'?: INavbarTextOverrides;\n 'user-card': INavbarUserCard;\n 'user-menu-open'?: boolean;\n visibility?: INavbarVisibility;\n 'logo-name': LogoName;\n}\n\nconst meta: Meta<NavbarArgs> = {\n title: 'Components/Navbar',\n component: 'modus-wc-navbar',\n args: {\n condensed: false,\n 'search-debounce-ms': 300,\n 'text-overrides': textOverrides,\n 'user-card': userCard,\n visibility,\n 'logo-name': 'trimble',\n },\n argTypes: {\n 'text-overrides': {\n description: 'Text replacements for navbar menu items',\n table: {\n type: {\n detail: `\n Interface: INavbarTextOverrides\n Properties:\n - apps (string, optional): Replaces the text for \"Apps\" in the condensed menu\n - help (string, optional): Replaces the text for \"Help\" in the condensed menu\n - notifications (string, optional): Replaces the text for \"Notifications\" in the condensed menu\n - search (string, optional): Replaces the text for \"Search\" in the condensed menu\n `,\n },\n },\n control: {\n type: 'object',\n },\n },\n 'logo-name': {\n description: 'The name of the logo to display. Defaults to \"trimble\".',\n table: {\n type: { summary: 'LogoName' },\n defaultValue: { summary: 'trimble' },\n },\n control: { type: 'select' },\n options: getAvailableLogos(),\n },\n 'user-card': {\n table: {\n type: {\n detail: `\n Interface: IUserCard\n Properties:\n - avatarAlt (string, optional): The alt value to set on the avatar\n - avatarSrc (string, optional): The avatar image source value\n - email (string): The email address of the user\n - myTrimbleButton (string, optional): Text override for the Access MyTrimble button, allows for translation\n - name (string): The name of the user\n - signOutButton (string, optional): Text override for the Sign out button, allows for translation\n `,\n },\n },\n },\n visibility: {\n description: 'Controls visibility of individual navbar buttons',\n table: {\n type: {\n detail: `\n Interface: INavbarVisibility\n Properties:\n - ai (boolean, optional): Controls visibility of the AI button\n - apps (boolean, optional): Controls visibility of the apps button\n - help (boolean, optional): Controls visibility of the help button\n - logo (boolean, optional): Controls visibility of the logo button; omit for visible\n - mainMenu (boolean, optional): Controls visibility of the main menu button\n - notifications (boolean, optional): Controls visibility of the notifications button\n - search (boolean, optional): Controls visibility of the search button\n - searchInput (boolean, optional): Controls visibility of the search input\n - user (boolean, optional): Controls visibility of the user button\n `,\n },\n },\n },\n },\n decorators: [withActions],\n parameters: {\n actions: {\n handles: [\n 'aiClick',\n 'appsClick',\n 'appsMenuOpenChange',\n 'condensedMenuOpenChange',\n 'helpClick',\n 'mainMenuOpenChange',\n 'myTrimbleClick',\n 'notificationsMenuOpenChange',\n 'notificationsClick',\n 'searchChange',\n 'searchClick',\n 'searchInputOpenChange',\n 'signOutClick',\n 'trimbleLogoClick',\n 'userMenuOpenChange',\n ],\n },\n layout: 'padded',\n },\n};\n\nexport default meta;\n\ntype Story = StoryObj<NavbarArgs>;\n\nconst Template: Story = {\n render: (args) => {\n // prettier-ignore\n return html`\n<style>\n div[id^='story--components-navbar--default'] {\n border: 1px dashed black;\n height: 360px;\n overflow: hidden;\n }\n [slot=main-menu] {\n background-color: #0063a3;\n color: white;\n height: 400px;\n }\n</style>\n<modus-wc-navbar\n ?apps-menu-open=${args['apps-menu-open']}\n ?condensed=${args.condensed}\n ?condensed-menu-open=${args['condensed-menu-open']}\n custom-class=${ifDefined(args['custom-class'])}\n ?main-menu-open=${args['main-menu-open']}\n ?notifications-menu-open=${args['notifications-menu-open']}\n search-debounce-ms=${ifDefined(args['search-debounce-ms'])}\n ?search-input-open=${args['search-input-open']}\n .textOverrides=${ifDefined(args['text-overrides'])}\n .userCard=${args['user-card']}\n ?user-menu-open=${args['user-menu-open']}\n .visibility=${args.visibility}\n logo-name=${args['logo-name']}\n>\n <div slot=\"main-menu\">Main menu contents</div>\n <div slot=\"notifications\">Notification contents</div>\n <div slot=\"apps\">App drawer contents</div>\n</modus-wc-navbar>\n<script>\n// Added this block to demonstrate how to handle navbar visibility settings using JavaScript.\n// const visibility = {\n// ai: true,\n// apps: true,\n// help: true,\n// logo: true,\n// mainMenu: true,\n// notifications: true,\n// search: true,\n// searchInput: true,\n// user: true,\n// };\n// const userCard = {\n// avatarAlt: 'Sonic',\n// avatarSrc: 'https://i1.sndcdn.com/artworks-000405996468-wmh3uv-t500x500.jpg',\n// email: 'sonic@trimble.com',\n// name: 'Sonic the Hedgehog',\n// };\n// const navbar = document.querySelector('modus-wc-navbar');\n// navbar.visibility = visibility;\n// navbar.userCard = userCard;\n</script>\n\n `;\n },\n};\n\nexport const Default: Story = { ...Template };\n\nexport const CustomMenuAndSlots: Story = {\n render: (args) => {\n function toggleCustomUserMenu(e) {\n const customIcon = e.currentTarget;\n const menu = customIcon.parentElement?.querySelector('#custom-user-menu');\n menu?.classList.toggle('hidden');\n }\n return html`\n <div id=\"custom-menu-and-slots\">\n <style>\n #custom-menu-and-slots .modus-wc-navbar {\n align-items: center;\n display: flex;\n gap: 0.2rem;\n padding: 0 1rem;\n width: 100%;\n }\n .modus-wc-card-body {\n padding: 1rem;\n }\n #custom-menu-and-slots .modus-wc-navbar-center,\n #custom-menu-and-slots .modus-wc-navbar-end,\n #custom-menu-and-slots .modus-wc-navbar-start {\n align-items: center;\n display: flex;\n flex: 1;\n }\n #custom-menu-and-slots .modus-wc-navbar-center {\n background: #d9d9d969;\n justify-content: center;\n }\n #custom-menu-and-slots .modus-wc-navbar-end {\n background: #d9d9d969;\n justify-content: flex-end;\n }\n #custom-menu-and-slots .modus-wc-navbar-start {\n background: #d9d9d969;\n justify-content: flex-start;\n }\n #custom-user-menu {\n position: absolute;\n right: 10px;\n top: 50px;\n z-index: 1000;\n }\n #custom-user-menu.hidden {\n display: none;\n }\n .custom-user-email {\n font-size: 0.8rem;\n }\n .custom-user-icon {\n cursor: pointer;\n margin-inline-start: 8px;\n margin-inline-end: 8px;\n position: relative;\n top: 3px;\n }\n .custom-user-menu-header {\n border-bottom: 1px solid #e0e0e0;\n margin-bottom: 8px;\n padding: 8px 16px;\n }\n .custom-user-menu-title {\n font-weight: bold;\n }\n div[id^='story--components-navbar--custom-menu-and-slots'] {\n border: 1px dashed black;\n height: 365px;\n }\n .menu-item {\n align-items: center;\n cursor: pointer;\n display: flex;\n padding: 8px;\n }\n .slot-bg {\n align-items: center;\n display: flex;\n font-weight: 600;\n height: 40px;\n justify-content: center;\n opacity: 0.4;\n }\n </style>\n <modus-wc-navbar\n ?apps-menu-open=${args['apps-menu-open']}\n ?condensed=${args.condensed}\n ?condensed-menu-open=${args['condensed-menu-open']}\n custom-class=${ifDefined(args['custom-class'])}\n ?main-menu-open=${args['main-menu-open']}\n ?notifications-menu-open=${args['notifications-menu-open']}\n search-debounce-ms=${ifDefined(args['search-debounce-ms'])}\n ?search-input-open=${args['search-input-open']}\n .textOverrides=${ifDefined(args['text-overrides'])}\n .userCard=${args['user-card']}\n ?user-menu-open=${args['user-menu-open']}\n .visibility=${{\n ai: false,\n apps: false,\n help: false,\n mainMenu: false,\n notifications: false,\n search: false,\n searchInput: false,\n user: false,\n }}\n >\n <div slot=\"main-menu\">Main menu contents</div>\n <div slot=\"notifications\">Notification contents</div>\n <div slot=\"apps\">App drawer contents</div>\n\n <!-- Slots demonstration -->\n <div slot=\"start\">\n <div class=\"slot-bg\">Left slot</div>\n </div>\n <div slot=\"center\">\n <div class=\"slot-bg\">Center slot</div>\n </div>\n <div slot=\"end\">\n <div class=\"slot-bg\">Right slot</div>\n <div class=\"custom-user-icon\" @click=${toggleCustomUserMenu}>\n <modus-wc-avatar\n alt=\"Sonic the Hedgehog\"\n img-src=\"https://i1.sndcdn.com/artworks-000405996468-wmh3uv-t500x500.jpg\"\n size=\"xs\"\n shape=\"circle\"\n ></modus-wc-avatar>\n </div>\n\n <!-- Custom user menu -->\n <modus-wc-card id=\"custom-user-menu\" bordered=\"true\">\n <div class=\"custom-user-menu-header\">\n <div class=\"custom-user-menu-title\">Custom Menu</div>\n <div class=\"custom-user-email\">custom.user@example.com</div>\n </div>\n <div class=\"menu-item\">\n <span class=\"menu-item-icon\"\n ><modus-wc-icon\n name=\"settings_solid\"\n size=\"16px\"\n ></modus-wc-icon\n ></span>\n <span class=\"custom-user-icon\">Account Settings</span>\n </div>\n <div class=\"menu-item\">\n <span class=\"menu-item-icon\"\n ><modus-wc-icon\n name=\"person_solid\"\n size=\"16px\"\n ></modus-wc-icon\n ></span>\n <span class=\"custom-user-icon\">Profile</span>\n </div>\n <div class=\"menu-item\">\n <span class=\"menu-item-icon\"\n ><modus-wc-icon name=\"sign_out\" size=\"16px\"></modus-wc-icon\n ></span>\n <span class=\"custom-user-icon\">Logout</span>\n </div>\n </modus-wc-card>\n </div>\n </modus-wc-navbar>\n </div>\n <script>\n // Added this block to demonstrate how to toggle a custom user menu and manage navbar visibility settings using JavaScript.\n // const toggleCustomUserMenu = (e) => {\n // const customIcon = e.currentTarget;\n // const menu = customIcon.parentElement?.querySelector('#custom-user-menu');\n // menu?.classList.toggle('hidden');\n // };\n // const navbar = document.querySelector('modus-wc-navbar');\n // const userIcon = document.querySelector('.custom-user-icon');\n // if (userIcon) {\n // userIcon.addEventListener('click', toggleCustomUserMenu);\n // }\n // if (navbar) {\n // navbar.visibility = {\n // ai: false,\n // apps: false,\n // help: false,\n // logo: true,\n // mainMenu: false,\n // notifications: false,\n // search: false,\n // searchInput: false,\n // user: false\n // };\n // }\n </script>\n `;\n },\n};\nexport const CustomLogoSizes: Story = {\n render: (args) => html`\n <style>\n .logo-small .modus-wc-logo {\n width: 90px;\n }\n\n .logo-large .modus-wc-logo {\n width: 140px;\n }\n\n .wrapper {\n display: flex;\n flex-direction: column;\n gap: 40px;\n font-family: sans-serif;\n }\n\n .navbar-frame {\n border: 1px dashed black;\n height: 360px;\n width: 100%;\n overflow: hidden;\n box-sizing: border-box;\n }\n .navbar-frame-outer {\n border: 1px dashed black;\n }\n\n [slot='main-menu'] {\n background-color: #0063a3;\n color: white;\n height: 400px;\n }\n </style>\n\n <div class=\"wrapper\">\n <div>\n <div class=\"navbar-frame-outer\">\n <div class=\"navbar-frame\">\n <modus-wc-navbar\n search-debounce-ms=\"300\"\n logo-name=\"trimble\"\n custom-class=\"logo-small\"\n .userCard=${args['user-card']}\n >\n <div slot=\"main-menu\">Main menu contents</div>\n <div slot=\"notifications\">Notification contents</div>\n <div slot=\"apps\">App drawer contents</div>\n </modus-wc-navbar>\n </div>\n </div>\n </div>\n\n <div>\n <div class=\"navbar-frame-outer\">\n <div class=\"navbar-frame\">\n <modus-wc-navbar\n search-debounce-ms=\"300\"\n logo-name=\"trimble\"\n custom-class=\"logo-large\"\n .userCard=${args['user-card']}\n >\n <div slot=\"main-menu\">Main menu contents</div>\n <div slot=\"notifications\">Notification contents</div>\n <div slot=\"apps\">App drawer contents</div>\n </modus-wc-navbar>\n </div>\n </div>\n </div>\n </div>\n `,\n};\n"
289
+ }
290
+ }