@oicl/openbridge-webcomponents 2.0.0-next.168 → 2.0.0-next.169

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.
Files changed (67) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +3352 -2948
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +465 -3
  4. package/dist/components/alert-list-details-experimental/alert-list-details-experimental.d.ts.map +1 -1
  5. package/dist/components/alert-list-details-experimental/alert-list-details-experimental.js +18 -1
  6. package/dist/components/alert-list-details-experimental/alert-list-details-experimental.js.map +1 -1
  7. package/dist/components/alert-menu/alert-menu.css.js +21 -1
  8. package/dist/components/alert-menu/alert-menu.css.js.map +1 -1
  9. package/dist/components/alert-menu/alert-menu.d.ts +14 -0
  10. package/dist/components/alert-menu/alert-menu.d.ts.map +1 -1
  11. package/dist/components/alert-menu/alert-menu.js +10 -0
  12. package/dist/components/alert-menu/alert-menu.js.map +1 -1
  13. package/dist/components/app-menu/app-menu.css.js +23 -1
  14. package/dist/components/app-menu/app-menu.css.js.map +1 -1
  15. package/dist/components/app-menu/app-menu.d.ts +14 -0
  16. package/dist/components/app-menu/app-menu.d.ts.map +1 -1
  17. package/dist/components/app-menu/app-menu.js +17 -1
  18. package/dist/components/app-menu/app-menu.js.map +1 -1
  19. package/dist/components/brilliance-menu/brilliance-menu.css.js +21 -1
  20. package/dist/components/brilliance-menu/brilliance-menu.css.js.map +1 -1
  21. package/dist/components/brilliance-menu/brilliance-menu.d.ts +14 -0
  22. package/dist/components/brilliance-menu/brilliance-menu.d.ts.map +1 -1
  23. package/dist/components/brilliance-menu/brilliance-menu.js +10 -0
  24. package/dist/components/brilliance-menu/brilliance-menu.js.map +1 -1
  25. package/dist/components/command-menu/command-menu.css.js +21 -1
  26. package/dist/components/command-menu/command-menu.css.js.map +1 -1
  27. package/dist/components/command-menu/command-menu.d.ts +14 -0
  28. package/dist/components/command-menu/command-menu.d.ts.map +1 -1
  29. package/dist/components/command-menu/command-menu.js +10 -0
  30. package/dist/components/command-menu/command-menu.js.map +1 -1
  31. package/dist/components/context-menu-input/context-menu-input.css.js +58 -3
  32. package/dist/components/context-menu-input/context-menu-input.css.js.map +1 -1
  33. package/dist/components/context-menu-input/context-menu-input.d.ts +14 -1
  34. package/dist/components/context-menu-input/context-menu-input.d.ts.map +1 -1
  35. package/dist/components/context-menu-input/context-menu-input.js +11 -0
  36. package/dist/components/context-menu-input/context-menu-input.js.map +1 -1
  37. package/dist/components/navigation-menu/navigation-menu.css.js +21 -1
  38. package/dist/components/navigation-menu/navigation-menu.css.js.map +1 -1
  39. package/dist/components/navigation-menu/navigation-menu.d.ts +14 -0
  40. package/dist/components/navigation-menu/navigation-menu.d.ts.map +1 -1
  41. package/dist/components/navigation-menu/navigation-menu.js +10 -0
  42. package/dist/components/navigation-menu/navigation-menu.js.map +1 -1
  43. package/dist/components/system-menu/system-menu.css.js +81 -61
  44. package/dist/components/system-menu/system-menu.css.js.map +1 -1
  45. package/dist/components/system-menu/system-menu.d.ts +14 -0
  46. package/dist/components/system-menu/system-menu.d.ts.map +1 -1
  47. package/dist/components/system-menu/system-menu.js +10 -0
  48. package/dist/components/system-menu/system-menu.js.map +1 -1
  49. package/dist/components/top-bar/top-bar.d.ts +11 -4
  50. package/dist/components/top-bar/top-bar.d.ts.map +1 -1
  51. package/dist/components/top-bar/top-bar.js +18 -10
  52. package/dist/components/top-bar/top-bar.js.map +1 -1
  53. package/dist/components/user-button/user-button.d.ts +1 -0
  54. package/dist/components/user-button/user-button.d.ts.map +1 -1
  55. package/dist/components/user-button/user-button.js +11 -1
  56. package/dist/components/user-button/user-button.js.map +1 -1
  57. package/dist/components/user-menu/user-menu.css.js +21 -1
  58. package/dist/components/user-menu/user-menu.css.js.map +1 -1
  59. package/dist/components/user-menu/user-menu.d.ts +14 -0
  60. package/dist/components/user-menu/user-menu.d.ts.map +1 -1
  61. package/dist/components/user-menu/user-menu.js +10 -0
  62. package/dist/components/user-menu/user-menu.js.map +1 -1
  63. package/dist/internal/popover-controller.d.ts +128 -0
  64. package/dist/internal/popover-controller.d.ts.map +1 -0
  65. package/dist/internal/popover-controller.js +121 -0
  66. package/dist/internal/popover-controller.js.map +1 -0
  67. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  import { LitElement, TemplateResult } from 'lit';
2
+ import { PopoverController } from '../../internal/popover-controller.js';
2
3
  import '../../icons/icon-arrow-flyout-google.js';
3
4
  import '../../icons/icon-close-google.js';
4
5
  import '../checkbox-item/checkbox-item.js';
@@ -220,13 +221,25 @@ export declare enum ContextMenuType {
220
221
  * @property options - Menu options, each with a unique `value` and a `label`, and optionally an
221
222
  * `icon` template for the leading icon, a `level` giving the nesting depth
222
223
  * for nested checkboxes, and `children` for a flyout or nested menu.
224
+ * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.
225
+ * @property open - Whether the menu is showing.
226
+ * @availableWhen open softDismiss==true
223
227
  * @slot - Optionally used for custom icons in options (e.g., `<obi-placeholder slot="icon"></obi-placeholder>`)
224
228
  * @fires {ObcContextMenuInputChangeEvent} change - Fired when the selection changes.
225
229
  * @fires {ObcContextMenuInputItemClickEvent} item-click - Fired when a menu item is clicked.
226
- * @fires {CustomEvent<void>} close - Fired when the close button is clicked.
230
+ * @fires {CustomEvent<void>} close - Fired when the close button is clicked, on `Escape`, and, with `softDismiss` on, when the menu closed on its own from a click outside or another menu opening.
227
231
  * @beta
228
232
  */
229
233
  export declare class ObcContextMenuInput extends LitElement {
234
+ /** Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself. */
235
+ softDismiss: boolean;
236
+ /**
237
+ * Whether the menu is showing.
238
+ *
239
+ * Available when `softDismiss==true`.
240
+ */
241
+ open: boolean;
242
+ protected readonly softDismissController: PopoverController;
230
243
  /** Menu variant: `regular` (default) is a single-select navigation menu, `checkboxes` and `nested-checkboxes` are flat and hierarchical multi-select, `flyout` has expandable cascading groups, and `multi` and `multi-with-subtitles` lay the menu out in columns, the latter with group subtitles. */
231
244
  type: ContextMenuType;
232
245
  /** Menu options, each with a unique `value` and a `label`, and optionally an `icon` template for the leading icon, a `level` giving the nesting depth for nested checkboxes, and `children` for a flyout or nested menu. */
@@ -1 +1 @@
1
- {"version":3,"file":"context-menu-input.d.ts","sourceRoot":"","sources":["../../../src/components/context-menu-input/context-menu-input.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context-menu-input.d.ts","sourceRoot":"","sources":["../../../src/components/context-menu-input/context-menu-input.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ import { classMap } from "lit/directives/class-map.js";
13
13
  import "../icon-button/icon-button.js";
14
14
  import "../navigation-item-group/navigation-item-group.js";
15
15
  import { stopPropagation } from "../../internal/events.js";
16
+ import { PopoverController } from "../../internal/popover-controller.js";
16
17
  var __defProp = Object.defineProperty;
17
18
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
18
19
  var __decorateClass = (decorators, target, key, kind) => {
@@ -35,6 +36,9 @@ var ContextMenuType = /* @__PURE__ */ ((ContextMenuType2) => {
35
36
  let ObcContextMenuInput = class extends LitElement {
36
37
  constructor() {
37
38
  super(...arguments);
39
+ this.softDismiss = false;
40
+ this.open = false;
41
+ this.softDismissController = new PopoverController(this);
38
42
  this.type = "regular";
39
43
  this.options = [];
40
44
  this.selectedValues = [];
@@ -121,6 +125,7 @@ let ObcContextMenuInput = class extends LitElement {
121
125
  this.focusLastItem();
122
126
  break;
123
127
  case "Escape":
128
+ if (this.softDismiss) break;
124
129
  event.preventDefault();
125
130
  this.dispatchEvent(new CustomEvent("close"));
126
131
  break;
@@ -546,6 +551,12 @@ let ObcContextMenuInput = class extends LitElement {
546
551
  }
547
552
  };
548
553
  ObcContextMenuInput.styles = unsafeCSS(compentStyle);
554
+ __decorateClass([
555
+ property({ type: Boolean })
556
+ ], ObcContextMenuInput.prototype, "softDismiss", 2);
557
+ __decorateClass([
558
+ property({ type: Boolean })
559
+ ], ObcContextMenuInput.prototype, "open", 2);
549
560
  __decorateClass([
550
561
  property({ type: String })
551
562
  ], ObcContextMenuInput.prototype, "type", 2);
@@ -1 +1 @@
1
- {"version":3,"file":"context-menu-input.js","sources":["../../../src/components/context-menu-input/context-menu-input.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing, TemplateResult} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './context-menu-input.css?inline';\nimport '../../icons/icon-arrow-flyout-google.js';\nimport '../../icons/icon-close-google.js';\nimport '../checkbox-item/checkbox-item.js';\nimport '../navigation-item/navigation-item.js';\nimport {NavigationItemRole} from '../navigation-item/navigation-item.js';\nimport {ObcNavigationMenuVariant} from '../navigation-menu/navigation-menu.js';\nimport {customElement} from '../../decorator.js';\nimport {RovingNavigator} from '../../internal/roving-navigator.js';\nimport {clamp} from '../../svghelpers/math.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport '../icon-button/icon-button.js';\nimport '../navigation-item-group/navigation-item-group.js';\nimport {ObcNavigationItemGroup} from '../navigation-item-group/navigation-item-group.js';\nimport {stopPropagation} from '../../internal/events.js';\n\n/**\n * Event fired when the selection changes in `<obc-context-menu-input>`.\n *\n * @event\n */\nexport type ObcContextMenuInputChangeEvent = CustomEvent<{\n selectedValues: string[];\n selectedOptions: Array<ContextMenuOption>;\n}>;\n\n/**\n * Event fired when a menu item is clicked in `<obc-context-menu-input>`.\n *\n * @event\n */\nexport type ObcContextMenuInputItemClickEvent = CustomEvent<{\n value: string;\n option: ContextMenuOption;\n}>;\n\n/**\n * Represents a single option in the context menu.\n */\nexport interface ContextMenuOption {\n /** Unique value for the option. */\n value: string;\n /** Display label for the option. */\n label: string;\n /** Optional nesting level (for hierarchical/nested options). */\n level?: number;\n /** Optional icon (TemplateResult, e.g., `<obi-placeholder slot=\"icon\"></obi-placeholder>`). */\n icon?: TemplateResult;\n /** Optional array of child options (for flyout/nested menus). */\n children?: ContextMenuOption[];\n}\n\n/**\n * Represents a group of columns for multi-with-subtitles variant.\n */\nexport interface ColumnGroup {\n /** Title for the group (displayed as subtitle/header). */\n title: string;\n /** Number of columns in this group. */\n columns: number;\n /** Array of options for this group. */\n options: ContextMenuOption[];\n}\n\n/**\n * Enum of available context menu variants for `<obc-context-menu-input>`.\n * - `Regular`: Single-select navigation menu.\n * - `Checkboxes`: Multi-select with checkboxes.\n * - `NestedCheckboxes`: Multi-select with nested/hierarchical checkboxes.\n * - `Flyout`: Menu with expandable/cascading groups.\n * - `Multi`: Multi-column menu.\n * - `MultiWithSubtitles`: Multi-column menu with group subtitles.\n */\n/** A menu row: `obc-navigation-item` or `obc-checkbox-item`, both with the roving hook. */\ntype MenuItemElement = HTMLElement & {focusable: boolean};\n\nexport enum ContextMenuType {\n Regular = 'regular',\n Checkboxes = 'checkboxes',\n NestedCheckboxes = 'nested-checkboxes',\n Flyout = 'flyout',\n Multi = 'multi',\n MultiWithSubtitles = 'multi-with-subtitles',\n}\n\n/**\n * `<obc-context-menu-input>` – A flexible context menu component for presenting selectable lists, actions, or multi-column menus with support for single or multiple selection, checkboxes, flyout groups, and icons.\n *\n * This component provides a highly configurable menu surface for displaying options, actions, or grouped selections. It supports several variants including regular single-select menus, checkbox lists, nested checkboxes, flyout (cascading) groups, and multi-column layouts with or without group subtitles. Options can include icons and hierarchical nesting.\n *\n * Appears as a popover or dropdown menu, allowing users to select one or more items from a list, optionally organized into columns or groups. Suitable for use as a context menu, dropdown, action menu, or feature selector.\n *\n * ## Features\n *\n * - **Variants:**\n * - **Regular:** Single-select menu with navigation items (optionally with icons).\n * - **Checkboxes:** List of options with checkboxes for multi-selection.\n * - **NestedCheckboxes:** Checkbox list supporting hierarchical/nested options (with indentation).\n * - **Flyout:** Menu with expandable/cascading groups; supports both single and multi-select, and group/child icons.\n * - **Multi:** Multi-column menu for large option sets; supports single or multi-select per column.\n * - **MultiWithSubtitles:** Multi-column menu with group subtitles/headers; each group can have its own set of options and columns.\n *\n * - **Selection Modes:**\n * - Single-select, multi-select, or per-group/column single-select (configurable via `multiSelect` and `selectPerGroup`).\n * - Persistent selection (selected items remain highlighted after interaction).\n *\n * - **Icons:**\n * - Options can display leading icons (e.g., `<obi-placeholder></obi-placeholder>`).\n * - Group headers in flyout and multi-column modes can also include icons.\n *\n * - **Title Bar:**\n * - Optional title bar with customizable text and a close button.\n *\n * - **Column Grouping:**\n * - Multi-column layouts can be grouped with subtitles and custom column counts per group.\n *\n * - **Nested Options:**\n * - Nested checkboxes and flyout groups support hierarchical option structures.\n *\n * - **Accessibility:**\n * - Uses ARIA roles for menu and menuitem.\n *\n * ## Usage Guidelines\n *\n * Use `<obc-context-menu-input>` when you need to present a list of actions or options in a popover, dropdown, or context menu format, especially when:\n * - Options may require icons, grouping, or hierarchical structure.\n * - You need to support both single and multiple selection, including per-group or per-column selection.\n * - The menu may contain a large number of options, requiring multi-column or grouped layouts.\n * - You want to provide a familiar menu or action sheet experience with optional checkboxes or flyout groups.\n *\n * Common use cases include: context menus, dropdown selectors, feature pickers, action menus, filter menus, or any scenario where users need to choose from a structured list of options.\n *\n * **Do not use** for persistent navigation (use a sidebar or navigation menu instead), or for simple single-action buttons.\n *\n * **TODO(designer):** Confirm if there are recommended limits for the number of columns/groups, or best practices for deeply nested options.\n *\n * ## Features and Variants\n *\n * - **Regular:**\n * - Single-select, navigation-style menu with optional icons.\n * - **Checkboxes:**\n * - Multi-select list with checkboxes. Each option can be toggled independently.\n * - **NestedCheckboxes:**\n * - Multi-select with hierarchical/nested options. Indentation reflects nesting level.\n * - **Flyout:**\n * - Groups of options expand into submenus (flyouts). Supports both single and multi-select. Group and child options can have icons.\n * - **Multi:**\n * - Options are distributed across multiple columns. Can be single or multi-select. Optionally restrict to one selection per column.\n * - **MultiWithSubtitles:**\n * - Like Multi, but columns are grouped under subtitles/headers. Each group can have its own column count and options.\n *\n * ## Properties\n *\n * - `type` (`ContextMenuType`): Sets the menu variant. Defaults to `'regular'`.\n * - `options` (`ContextMenuOption[]`): Array of menu options. Each option can have `value`, `label`, optional `icon`, `level` (for nesting), and `children` (for flyout/nested).\n * - `selectedValues` (string[]): Array of currently selected option values.\n * - `hasTitleBar` (boolean): If true, displays a title bar with close button.\n * - `title` (string): Text for the title bar (shown if `hasTitleBar` is true).\n * - `columnGroups` (ColumnGroup[]): Used for `multi-with-subtitles` variant to define groupings and columns.\n * - `itemsPerColumn` (number): Number of options per column in multi-column layouts.\n * - `multiSelect` (boolean): If true, allows multiple selections. Defaults based on variant.\n * - `selectPerGroup` (boolean): If true, restricts selection to one per group/column (used in flyout and multi-column).\n * - `persistSelection` (boolean): If true, keeps selected items highlighted after interaction.\n *\n * ## Keyboard\n * [APG Menu](https://www.w3.org/WAI/ARIA/apg/patterns/menu/): the menu is one\n * tab stop, entered on the selected item or the first one; `Up` and `Down`\n * move between items and stop at the ends, `Home` and `End` jump to them,\n * `Enter` and `Space` select through the item, and `Escape` fires `close`, which\n * is also why the title bar's close button stays out of the tab sequence.\n * Single-select items are `menuitemradio` with `aria-checked` on their\n * control, not on the host; checkbox menus\n * keep their checkboxes and move between them the same way.\n *\n * Left out: wrapping at the ends, and type-ahead. The checkbox variants put\n * `role=\"checkbox\"` items in the menu where the pattern asks for\n * `menuitemcheckbox`. A flyout's header is a plain button without\n * `aria-haspopup` or `aria-expanded`, its children sit in a `group` rather\n * than a nested `menu`, and `Right` and `Left` do not open and close it.\n *\n * ## Events\n *\n * - `change` – Fired when the selection changes.\n * Detail includes the selected values array and the selected option objects.\n * - `item-click` – Fired when a menu item is clicked (even if not changing selection).\n * Detail includes the clicked value and its option object.\n * - `close` – Fired when the close button in the title bar is clicked.\n *\n * ## Best Practices and Constraints\n *\n * - Use icons to help users quickly identify options, especially in long or complex menus.\n * - For multi-column layouts, keep the number of columns manageable to avoid overwhelming users.\n * - Use the `multi-with-subtitles` variant for grouped feature selection or when options need to be categorized.\n * - For nested checkboxes, avoid excessive nesting for clarity.\n * - In flyout menus, use group icons to visually distinguish categories.\n * - Only use the close button if the menu is presented as a modal or overlay that requires explicit dismissal.\n * - For accessibility, ensure all options have clear labels.\n *\n * ## Example\n *\n * ```html\n * <obc-context-menu-input\n * type=\"flyout\"\n * .options=${[\n * {\n * value: 'file',\n * label: 'File',\n * icon: html`<obi-placeholder slot=\"icon\"></obi-placeholder>`,\n * children: [\n * { value: 'new', label: 'New' },\n * { value: 'open', label: 'Open' },\n * { value: 'save', label: 'Save' }\n * ]\n * },\n * { value: 'edit', label: 'Edit' }\n * ]}\n * .selectedValues=${['save']}\n * hasTitleBar\n * title=\"Menu\"\n * ></obc-context-menu-input>\n * ```\n *\n * In this example, a flyout menu is shown with a title bar, group icons, and a selected child option.\n *\n * @property title - Title text displayed in the title bar (if `hasTitleBar` is true).\n * @availableWhen title hasTitleBar==true\n * @property selectedValues - Array of currently selected option values.\n * For multi-select variants, can contain multiple values. For single-select, contains at most one value.\n * @property hasTitleBar - Whether to show a title bar with close button at the top of the menu.\n * If true, displays the `title` property and a close icon button.\n * @property columnGroups - Array of column groups for the `multi-with-subtitles` layout.\n * Each group defines a `title`, `columns` (number of columns in the group), and `options` (array of options for that group).\n * @availableWhen columnGroups type==MultiWithSubtitles\n * @property itemsPerColumn - Number of items per column in multi-column layouts.\n * Used in `multi` and `multi-with-subtitles` variants to control column splitting.\n * @availableWhen itemsPerColumn type in [Multi, MultiWithSubtitles]\n * @property multiSelect - Whether multiple selections are allowed.\n * If not set, defaults to true for checkbox/multi variants, false for regular/flyout.\n * @property selectPerGroup - If true, restricts selection to one option per group or column (used in flyout and multi-column).\n * When enabled, only one option can be selected in each group or column.\n * @property type - Menu variant: `regular` (default) is a single-select navigation menu,\n * `checkboxes` and `nested-checkboxes` are flat and hierarchical\n * multi-select, `flyout` has expandable cascading groups, and `multi` and\n * `multi-with-subtitles` lay the menu out in columns, the latter with group\n * subtitles.\n * @property options - Menu options, each with a unique `value` and a `label`, and optionally an\n * `icon` template for the leading icon, a `level` giving the nesting depth\n * for nested checkboxes, and `children` for a flyout or nested menu.\n * @slot - Optionally used for custom icons in options (e.g., `<obi-placeholder slot=\"icon\"></obi-placeholder>`)\n * @fires {ObcContextMenuInputChangeEvent} change - Fired when the selection changes.\n * @fires {ObcContextMenuInputItemClickEvent} item-click - Fired when a menu item is clicked.\n * @fires {CustomEvent<void>} close - Fired when the close button is clicked.\n * @beta\n */\n@customElement('obc-context-menu-input')\nexport class ObcContextMenuInput extends LitElement {\n @property({type: String})\n type: ContextMenuType = ContextMenuType.Regular;\n\n @property({type: Array}) options: ContextMenuOption[] = [];\n\n @property({type: Array}) selectedValues: string[] = [];\n\n @property({type: Boolean}) hasTitleBar = false;\n\n @property({type: String}) override title = '';\n\n @property({type: Array}) columnGroups: ColumnGroup[] = [];\n\n @property({type: Number}) itemsPerColumn = 5;\n\n @property({type: Boolean}) multiSelect?: boolean;\n\n @property({type: Boolean, reflect: true}) selectPerGroup?: boolean;\n\n private readonly navigator = new RovingNavigator<MenuItemElement>(\n {\n items: () => this.getMenuItems(),\n preferred: () => this.selectedMenuItem(),\n setFocusable: (item, focusable) => {\n item.focusable = focusable;\n },\n },\n {orientation: 'vertical', wrap: false}\n );\n\n override updated() {\n this.navigator.refresh();\n }\n\n private getMenuItems(): MenuItemElement[] {\n return Array.from(\n this.renderRoot.querySelectorAll<MenuItemElement>(\n '[data-menu-item=\"true\"]'\n )\n ).filter((item) => item.getClientRects().length > 0);\n }\n\n private selectedMenuItem(): MenuItemElement | undefined {\n const items = this.getMenuItems();\n return this.selectedValues\n .map((value) =>\n items.find((item) => item.getAttribute('data-menu-value') === value)\n )\n .find((item): item is MenuItemElement => item !== undefined);\n }\n\n private focusMenuItem(index: number) {\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n const item = items[clamp(index, 0, items.length - 1)];\n this.navigator.setActive(item, true);\n item.scrollIntoView({block: 'nearest'});\n }\n\n public focusFirstItem() {\n this.focusMenuItem(0);\n }\n\n public focusLastItem() {\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n this.focusMenuItem(items.length - 1);\n }\n\n public focusSelectedItem() {\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n const selectedItem = this.selectedMenuItem();\n if (selectedItem !== undefined) {\n this.navigator.setActive(selectedItem, true);\n selectedItem.scrollIntoView({block: 'nearest'});\n return;\n }\n\n this.focusFirstItem();\n }\n\n private handleKeydown(event: KeyboardEvent) {\n if (this.navigator.handleKeydown(event)) {\n event.preventDefault();\n this.navigator.activeItem?.scrollIntoView({block: 'nearest'});\n return;\n }\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n // Focus is on the menu itself, not on an item: the arrows enter the list.\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.focusFirstItem();\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.focusLastItem();\n break;\n case 'Home':\n event.preventDefault();\n this.focusFirstItem();\n break;\n case 'End':\n event.preventDefault();\n this.focusLastItem();\n break;\n case 'Escape':\n event.preventDefault();\n this.dispatchEvent(new CustomEvent('close'));\n break;\n default:\n break;\n }\n }\n\n private get isMultiSelect(): boolean {\n if (this.multiSelect !== undefined) return this.multiSelect;\n return [\n ContextMenuType.Checkboxes,\n ContextMenuType.NestedCheckboxes,\n ContextMenuType.Multi,\n ContextMenuType.MultiWithSubtitles,\n ].includes(this.type);\n }\n\n private get isPerGroupSingleSelect(): boolean {\n if (this.isMultiSelect) return false;\n if (this.selectPerGroup !== undefined) return this.selectPerGroup;\n return this.type === ContextMenuType.Flyout;\n }\n\n /**\n * Returns a unique group-key for each option:\n * - In multi-with-subtitles: group title + subcolumn index (each subcolumn is a group)\n * - In multi: column index (each column is a group)\n */\n private getGroupForValue(value: string): string | undefined {\n if (\n this.type === ContextMenuType.MultiWithSubtitles &&\n this.columnGroups.length\n ) {\n for (const group of this.columnGroups) {\n const totalCols = Math.max(\n group.columns,\n Math.ceil(group.options.length / this.itemsPerColumn)\n );\n const distributed = this.chunkArray(\n group.options,\n this.itemsPerColumn,\n totalCols\n );\n for (let subColIdx = 0; subColIdx < distributed.length; ++subColIdx) {\n if (distributed[subColIdx].some((opt) => opt.value === value)) {\n return `${group.title}___${subColIdx}`;\n }\n }\n }\n return undefined;\n }\n if (this.type === ContextMenuType.Multi && this.itemsPerColumn > 0) {\n const columns = this.chunkArray(this.options, this.itemsPerColumn);\n for (let colIdx = 0; colIdx < columns.length; ++colIdx) {\n if (columns[colIdx].some((opt) => opt.value === value)) {\n return `column-${colIdx}`;\n }\n }\n return undefined;\n }\n if (this.type === ContextMenuType.Flyout && this.options.length) {\n for (const group of this.options) {\n if (group.children?.some((child) => child.value === value)) {\n return group.value;\n }\n if (group.value === value) return group.value;\n }\n return undefined;\n }\n return undefined;\n }\n\n private handleCheckboxChange(option: ContextMenuOption, e: Event) {\n const {status} = (e as CustomEvent<{status: 'checked' | 'unchecked'}>)\n .detail;\n let next: string[];\n\n // Enable \"one per group/column\" for multi-column layouts as well\n if (\n this.selectPerGroup &&\n (this.type === ContextMenuType.Multi ||\n this.type === ContextMenuType.MultiWithSubtitles)\n ) {\n const groupKey = this.getGroupForValue(option.value);\n next = [\n ...this.selectedValues.filter(\n (val) => this.getGroupForValue(val) !== groupKey\n ),\n ...(status === 'checked' ? [option.value] : []),\n ];\n } else {\n next =\n status === 'checked'\n ? [...this.selectedValues, option.value]\n : this.selectedValues.filter((v) => v !== option.value);\n }\n\n if (!arraysEqual(this.selectedValues, next)) this.updateSelection(next);\n }\n\n private handleMenuItemClick(option: ContextMenuOption, event: Event) {\n event.preventDefault();\n\n // Always fire item-click event, even for groups\n this.dispatchEvent(\n new CustomEvent<ObcContextMenuInputItemClickEvent['detail']>(\n 'item-click',\n {\n detail: {value: option.value, option},\n }\n )\n );\n\n // Don't process selection for navigation groups in flyout menus or multi\n if (option.children?.length) return;\n\n let newSelectedValues: string[];\n\n if (this.isPerGroupSingleSelect) {\n // Get the group key for this value (column or group)\n const groupKey = this.getGroupForValue\n ? this.getGroupForValue(option.value)\n : undefined;\n\n // Find currently selected in this group\n const selectedInGroup = this.selectedValues.find(\n (val) => this.getGroupForValue(val) === groupKey\n );\n\n // If the clicked option is already selected in this group, unselect it\n if (selectedInGroup === option.value) {\n newSelectedValues = this.selectedValues.filter(\n (val) => val !== option.value\n );\n } else {\n // Otherwise, replace any existing selection in the group with this one\n newSelectedValues = [\n ...this.selectedValues.filter(\n (val) => this.getGroupForValue(val) !== groupKey\n ),\n option.value,\n ];\n }\n } else {\n // REGULAR (single select, non-grouped): toggle if already selected\n if (this.selectedValues.includes(option.value)) {\n newSelectedValues = [];\n } else {\n newSelectedValues = [option.value];\n }\n }\n\n if (!arraysEqual(this.selectedValues, newSelectedValues))\n this.updateSelection(newSelectedValues);\n }\n\n private updateSelection(vals: string[]) {\n this.selectedValues = vals;\n const selectedOptions: ContextMenuOption[] = [];\n const collect = (arr: ContextMenuOption[]) =>\n arr.forEach((o) => {\n if (vals.includes(o.value)) selectedOptions.push(o);\n if (o.children) collect(o.children);\n });\n collect(this.options);\n this.dispatchEvent(\n new CustomEvent<ObcContextMenuInputChangeEvent['detail']>('change', {\n detail: {selectedValues: vals, selectedOptions},\n })\n );\n }\n\n private handleCloseClick(e: Event) {\n e.preventDefault();\n this.dispatchEvent(new CustomEvent('close'));\n }\n\n private isOptionSelected(v: string) {\n return this.selectedValues.includes(v);\n }\n\n private renderTitleBar() {\n if (!this.hasTitleBar) return nothing;\n return html`\n <div class=\"title-container\">\n <div class=\"title-content\">\n <div class=\"title-text\">${this.title}</div>\n </div>\n <obc-icon-button\n variant=\"flat\"\n @click=${this.handleCloseClick}\n aria-label=\"Close menu\"\n .focusable=${false}\n >\n <obi-close-google></obi-close-google>\n </obc-icon-button>\n </div>\n `;\n }\n\n private renderRegularItems() {\n return this.options.map((o) => this.renderNavItem(o));\n }\n\n private renderCheckboxItems() {\n return this.options.map((o) => {\n const isSelected = this.isOptionSelected(o.value);\n const isNested =\n this.type === ContextMenuType.NestedCheckboxes &&\n o.level &&\n o.level > 1;\n const indent = isNested ? (o.level! - 1) * 16 : 0;\n return html`<div\n class=\"menu-item checkbox-item-wrapper\"\n style=${indent ? `padding-left:${indent}px` : ''}\n >\n <obc-checkbox-item\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .status=${isSelected ? 'checked' : 'unchecked'}\n @expand-toggle=${stopPropagation}\n @change=${(e: Event) => this.handleCheckboxChange(o, e)}\n ></obc-checkbox-item>\n </div>`;\n });\n }\n\n private renderNavItem(o: ContextMenuOption) {\n const isSelected = this.isOptionSelected(o.value);\n const indent = o.level ? (o.level - 1) * 16 : 0;\n return html`<div\n class=\"menu-item navigation-item-wrapper\"\n style=${indent ? `padding-left:${indent}px` : ''}\n >\n <obc-navigation-item\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .checked=${isSelected}\n .variant=${ObcNavigationMenuVariant.Full}\n @click=${(e: Event) => this.handleMenuItemClick(o, e)}\n .itemRole=${NavigationItemRole.MenuItemRadio}\n ?hasIcon=${!!o.icon}\n >\n ${o.icon ? html`<div slot=\"icon\">${o.icon}</div>` : nothing}\n </obc-navigation-item>\n </div>`;\n }\n\n // Renders checkboxes for children if multi, otherwise navigation items\n private renderFlyoutChildren(children: ContextMenuOption[]) {\n if (this.isMultiSelect) {\n return children.map((c) => {\n const isSelected = this.isOptionSelected(c.value);\n return html`<div class=\"menu-item checkbox-item-wrapper\">\n <obc-checkbox-item\n data-menu-item=\"true\"\n data-menu-value=${c.value}\n .label=${c.label}\n .status=${isSelected ? 'checked' : 'unchecked'}\n @expand-toggle=${stopPropagation}\n @change=${(e: Event) => this.handleCheckboxChange(c, e)}\n ></obc-checkbox-item>\n </div>`;\n });\n }\n return children.map((c) => {\n const isSelected = this.isOptionSelected(c.value);\n return html`<obc-navigation-item\n data-menu-item=\"true\"\n data-menu-value=${c.value}\n .label=${c.label}\n .checked=${isSelected}\n .variant=${ObcNavigationMenuVariant.Full}\n @click=${(e: Event) => this.handleMenuItemClick(c, e)}\n .itemRole=${NavigationItemRole.MenuItemRadio}\n ?hasIcon=${!!c.icon}\n >\n ${c.icon ? html`<div slot=\"icon\">${c.icon}</div>` : nothing}\n </obc-navigation-item>`;\n });\n }\n\n /**\n * Rows a group shows or hides join or leave the roving set only once the\n * group has rendered; until then a newly shown row is its own tab stop.\n */\n private async refreshAfterDisclosure(group: ObcNavigationItemGroup) {\n await group.updateComplete;\n await this.updateComplete;\n this.navigator.refresh();\n }\n\n private handleFlyoutGroupClick(option: ContextMenuOption, event: Event) {\n event.preventDefault();\n this.refreshAfterDisclosure(event.currentTarget as ObcNavigationItemGroup);\n this.dispatchEvent(\n new CustomEvent<ObcContextMenuInputItemClickEvent['detail']>(\n 'item-click',\n {\n detail: {value: option.value, option},\n }\n )\n );\n // Don't fire a change event for navigation groups\n }\n\n private renderFlyoutItems() {\n return this.options.map((o) => {\n const isSelected = this.isOptionSelected(o.value);\n if (o.children?.length) {\n return html`<obc-navigation-item-group\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .checked=${isSelected}\n .variant=${ObcNavigationMenuVariant.Full}\n .hug=${true}\n .hasIcon=${!!o.icon}\n @click=${(e: Event) => this.handleFlyoutGroupClick(o, e)}\n @open=${(e: Event) => {\n this.shadowRoot\n ?.querySelectorAll('obc-navigation-item-group')\n .forEach((g) => {\n const group = g as ObcNavigationItemGroup;\n if (group.label !== o.label) group.close();\n });\n this.refreshAfterDisclosure(\n e.currentTarget as ObcNavigationItemGroup\n );\n }}\n >\n ${o.icon ? html`<div slot=\"icon\">${o.icon}</div>` : nothing}\n ${this.renderFlyoutChildren(o.children)}\n </obc-navigation-item-group>`;\n }\n return this.renderNavItem(o);\n });\n }\n\n // --------- MULTI COLUMN ---------\n\n private renderMultiColumnItems() {\n const renderColumn = (columnOptions: ContextMenuOption[]) => {\n if (!columnOptions.length) return nothing;\n\n // True multi-select: checkboxes\n if (this.isMultiSelect && !this.selectPerGroup) {\n return columnOptions.map((o) => {\n const isSelected = this.isOptionSelected(o.value);\n return html`<div class=\"menu-item checkbox-item-wrapper\">\n <obc-checkbox-item\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .status=${isSelected ? 'checked' : 'unchecked'}\n @expand-toggle=${stopPropagation}\n @change=${(e: Event) => this.handleCheckboxChange(o, e)}\n ></obc-checkbox-item>\n </div>`;\n });\n }\n // fallback: nav item\n return columnOptions.map((opt) => this.renderNavItem(opt));\n };\n\n if (this.type === ContextMenuType.MultiWithSubtitles) {\n if (!this.columnGroups.length) {\n // Fallback – evenly spread across columns\n const cols = this.chunkArray(this.options, this.itemsPerColumn);\n return html`<div class=\"multi-content\">\n <div class=\"multi-columns\">\n <div class=\"columns-container\">\n ${cols.map(\n (col, idx) =>\n html`<div\n class=\"column-with-header ${idx ? 'column-divider' : ''}\"\n >\n <div class=\"column-header\">\n <div class=\"subtitle-container\">\n <div class=\"subtitle-text\">Group ${idx + 1}</div>\n </div>\n </div>\n <div class=\"column-content\">${renderColumn(col)}</div>\n </div>`\n )}\n </div>\n </div>\n </div>`;\n }\n\n interface ColumnInfo {\n options: ContextMenuOption[];\n groupTitle: string;\n isFirstInGroup: boolean;\n isFirstGroup: boolean;\n colIdx: number;\n }\n\n const allCols: ColumnInfo[] = [];\n this.columnGroups.forEach((g, gIdx) => {\n const calculatedCols = Math.ceil(\n g.options.length / this.itemsPerColumn\n );\n const actualCols = Math.max(g.columns, calculatedCols);\n const distributed = this.chunkArray(\n g.options,\n this.itemsPerColumn,\n actualCols\n );\n distributed.forEach((opts, idx) => {\n allCols.push({\n options: opts,\n groupTitle: g.title,\n isFirstInGroup: idx === 0,\n isFirstGroup: gIdx === 0,\n colIdx: idx,\n });\n });\n });\n\n return html`<div class=\"multi-content\">\n <div class=\"multi-columns\">\n <div class=\"columns-container\">\n ${allCols.map(\n (c) =>\n html`<div\n class=\"column-with-header ${\n !c.isFirstGroup && c.isFirstInGroup ? 'column-divider' : ''\n }\"\n >\n ${\n c.isFirstInGroup\n ? html`<div class=\"column-header\">\n <div class=\"subtitle-container\">\n <div class=\"subtitle-text\">${c.groupTitle}</div>\n </div>\n </div>`\n : html`<div class=\"column-header-spacer\"></div>`\n }\n <div class=\"column-content\">${renderColumn(c.options)}</div>\n </div>`\n )}\n </div>\n </div>\n </div>`;\n }\n\n // Simple multi (no subtitles)\n const columns = this.chunkArray(this.options, this.itemsPerColumn);\n return html`<div class=\"multi-content\">\n <div class=\"multi-columns\">\n ${columns.map(\n (col, idx) =>\n html`<div class=\"column ${idx ? 'column-divider' : ''}\">\n ${renderColumn(col)}\n </div>`\n )}\n </div>\n </div>`;\n }\n\n private chunkArray<T>(arr: T[], size: number, forcedColumns?: number): T[][] {\n if (forcedColumns) {\n const out: T[][] = Array.from({length: forcedColumns}, () => []);\n arr.forEach((item, idx) => out[Math.floor(idx / size)].push(item));\n return out;\n }\n const result: T[][] = [];\n for (let i = 0; i < arr.length; i += size)\n result.push(arr.slice(i + 0, i + size));\n return result;\n }\n\n private renderMenuContent() {\n switch (this.type) {\n case ContextMenuType.Checkboxes:\n case ContextMenuType.NestedCheckboxes:\n return this.renderCheckboxItems();\n case ContextMenuType.Flyout:\n return this.renderFlyoutItems();\n case ContextMenuType.Multi:\n case ContextMenuType.MultiWithSubtitles:\n return this.renderMultiColumnItems();\n default:\n return this.renderRegularItems();\n }\n }\n\n override render() {\n return html`<div\n class=${classMap({\n 'context-menu': true,\n [`type-${this.type}`]: true,\n 'has-title': this.hasTitleBar,\n })}\n tabindex=\"-1\"\n role=\"menu\"\n aria-label=${this.hasTitleBar ? this.title : 'Context menu'}\n @keydown=${this.handleKeydown}\n @focusin=${(event: Event) => this.navigator.handleFocusin(event)}\n >\n ${this.renderTitleBar()}\n <div class=\"menu-content\">${this.renderMenuContent()}</div>\n </div>`;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\nfunction arraysEqual(a: string[], b: string[]) {\n if (a.length !== b.length) return false;\n const setA = new Set(a);\n return b.every((v) => setA.has(v));\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-context-menu-input': ObcContextMenuInput;\n }\n}\n"],"names":["ContextMenuType"],"mappings":"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"}
1
+ {"version":3,"file":"context-menu-input.js","sources":["../../../src/components/context-menu-input/context-menu-input.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing, TemplateResult} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './context-menu-input.css?inline';\nimport '../../icons/icon-arrow-flyout-google.js';\nimport '../../icons/icon-close-google.js';\nimport '../checkbox-item/checkbox-item.js';\nimport '../navigation-item/navigation-item.js';\nimport {NavigationItemRole} from '../navigation-item/navigation-item.js';\nimport {ObcNavigationMenuVariant} from '../navigation-menu/navigation-menu.js';\nimport {customElement} from '../../decorator.js';\nimport {RovingNavigator} from '../../internal/roving-navigator.js';\nimport {clamp} from '../../svghelpers/math.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport '../icon-button/icon-button.js';\nimport '../navigation-item-group/navigation-item-group.js';\nimport {ObcNavigationItemGroup} from '../navigation-item-group/navigation-item-group.js';\nimport {stopPropagation} from '../../internal/events.js';\nimport {PopoverController} from '../../internal/popover-controller.js';\n\n/**\n * Event fired when the selection changes in `<obc-context-menu-input>`.\n *\n * @event\n */\nexport type ObcContextMenuInputChangeEvent = CustomEvent<{\n selectedValues: string[];\n selectedOptions: Array<ContextMenuOption>;\n}>;\n\n/**\n * Event fired when a menu item is clicked in `<obc-context-menu-input>`.\n *\n * @event\n */\nexport type ObcContextMenuInputItemClickEvent = CustomEvent<{\n value: string;\n option: ContextMenuOption;\n}>;\n\n/**\n * Represents a single option in the context menu.\n */\nexport interface ContextMenuOption {\n /** Unique value for the option. */\n value: string;\n /** Display label for the option. */\n label: string;\n /** Optional nesting level (for hierarchical/nested options). */\n level?: number;\n /** Optional icon (TemplateResult, e.g., `<obi-placeholder slot=\"icon\"></obi-placeholder>`). */\n icon?: TemplateResult;\n /** Optional array of child options (for flyout/nested menus). */\n children?: ContextMenuOption[];\n}\n\n/**\n * Represents a group of columns for multi-with-subtitles variant.\n */\nexport interface ColumnGroup {\n /** Title for the group (displayed as subtitle/header). */\n title: string;\n /** Number of columns in this group. */\n columns: number;\n /** Array of options for this group. */\n options: ContextMenuOption[];\n}\n\n/**\n * Enum of available context menu variants for `<obc-context-menu-input>`.\n * - `Regular`: Single-select navigation menu.\n * - `Checkboxes`: Multi-select with checkboxes.\n * - `NestedCheckboxes`: Multi-select with nested/hierarchical checkboxes.\n * - `Flyout`: Menu with expandable/cascading groups.\n * - `Multi`: Multi-column menu.\n * - `MultiWithSubtitles`: Multi-column menu with group subtitles.\n */\n/** A menu row: `obc-navigation-item` or `obc-checkbox-item`, both with the roving hook. */\ntype MenuItemElement = HTMLElement & {focusable: boolean};\n\nexport enum ContextMenuType {\n Regular = 'regular',\n Checkboxes = 'checkboxes',\n NestedCheckboxes = 'nested-checkboxes',\n Flyout = 'flyout',\n Multi = 'multi',\n MultiWithSubtitles = 'multi-with-subtitles',\n}\n\n/**\n * `<obc-context-menu-input>` – A flexible context menu component for presenting selectable lists, actions, or multi-column menus with support for single or multiple selection, checkboxes, flyout groups, and icons.\n *\n * This component provides a highly configurable menu surface for displaying options, actions, or grouped selections. It supports several variants including regular single-select menus, checkbox lists, nested checkboxes, flyout (cascading) groups, and multi-column layouts with or without group subtitles. Options can include icons and hierarchical nesting.\n *\n * Appears as a popover or dropdown menu, allowing users to select one or more items from a list, optionally organized into columns or groups. Suitable for use as a context menu, dropdown, action menu, or feature selector.\n *\n * ## Features\n *\n * - **Variants:**\n * - **Regular:** Single-select menu with navigation items (optionally with icons).\n * - **Checkboxes:** List of options with checkboxes for multi-selection.\n * - **NestedCheckboxes:** Checkbox list supporting hierarchical/nested options (with indentation).\n * - **Flyout:** Menu with expandable/cascading groups; supports both single and multi-select, and group/child icons.\n * - **Multi:** Multi-column menu for large option sets; supports single or multi-select per column.\n * - **MultiWithSubtitles:** Multi-column menu with group subtitles/headers; each group can have its own set of options and columns.\n *\n * - **Selection Modes:**\n * - Single-select, multi-select, or per-group/column single-select (configurable via `multiSelect` and `selectPerGroup`).\n * - Persistent selection (selected items remain highlighted after interaction).\n *\n * - **Icons:**\n * - Options can display leading icons (e.g., `<obi-placeholder></obi-placeholder>`).\n * - Group headers in flyout and multi-column modes can also include icons.\n *\n * - **Title Bar:**\n * - Optional title bar with customizable text and a close button.\n *\n * - **Column Grouping:**\n * - Multi-column layouts can be grouped with subtitles and custom column counts per group.\n *\n * - **Nested Options:**\n * - Nested checkboxes and flyout groups support hierarchical option structures.\n *\n * - **Accessibility:**\n * - Uses ARIA roles for menu and menuitem.\n *\n * ## Usage Guidelines\n *\n * Use `<obc-context-menu-input>` when you need to present a list of actions or options in a popover, dropdown, or context menu format, especially when:\n * - Options may require icons, grouping, or hierarchical structure.\n * - You need to support both single and multiple selection, including per-group or per-column selection.\n * - The menu may contain a large number of options, requiring multi-column or grouped layouts.\n * - You want to provide a familiar menu or action sheet experience with optional checkboxes or flyout groups.\n *\n * Common use cases include: context menus, dropdown selectors, feature pickers, action menus, filter menus, or any scenario where users need to choose from a structured list of options.\n *\n * **Do not use** for persistent navigation (use a sidebar or navigation menu instead), or for simple single-action buttons.\n *\n * **TODO(designer):** Confirm if there are recommended limits for the number of columns/groups, or best practices for deeply nested options.\n *\n * ## Features and Variants\n *\n * - **Regular:**\n * - Single-select, navigation-style menu with optional icons.\n * - **Checkboxes:**\n * - Multi-select list with checkboxes. Each option can be toggled independently.\n * - **NestedCheckboxes:**\n * - Multi-select with hierarchical/nested options. Indentation reflects nesting level.\n * - **Flyout:**\n * - Groups of options expand into submenus (flyouts). Supports both single and multi-select. Group and child options can have icons.\n * - **Multi:**\n * - Options are distributed across multiple columns. Can be single or multi-select. Optionally restrict to one selection per column.\n * - **MultiWithSubtitles:**\n * - Like Multi, but columns are grouped under subtitles/headers. Each group can have its own column count and options.\n *\n * ## Properties\n *\n * - `type` (`ContextMenuType`): Sets the menu variant. Defaults to `'regular'`.\n * - `options` (`ContextMenuOption[]`): Array of menu options. Each option can have `value`, `label`, optional `icon`, `level` (for nesting), and `children` (for flyout/nested).\n * - `selectedValues` (string[]): Array of currently selected option values.\n * - `hasTitleBar` (boolean): If true, displays a title bar with close button.\n * - `title` (string): Text for the title bar (shown if `hasTitleBar` is true).\n * - `columnGroups` (ColumnGroup[]): Used for `multi-with-subtitles` variant to define groupings and columns.\n * - `itemsPerColumn` (number): Number of options per column in multi-column layouts.\n * - `multiSelect` (boolean): If true, allows multiple selections. Defaults based on variant.\n * - `selectPerGroup` (boolean): If true, restricts selection to one per group/column (used in flyout and multi-column).\n * - `persistSelection` (boolean): If true, keeps selected items highlighted after interaction.\n *\n * ## Keyboard\n * [APG Menu](https://www.w3.org/WAI/ARIA/apg/patterns/menu/): the menu is one\n * tab stop, entered on the selected item or the first one; `Up` and `Down`\n * move between items and stop at the ends, `Home` and `End` jump to them,\n * `Enter` and `Space` select through the item, and `Escape` fires `close`, which\n * is also why the title bar's close button stays out of the tab sequence.\n * Single-select items are `menuitemradio` with `aria-checked` on their\n * control, not on the host; checkbox menus\n * keep their checkboxes and move between them the same way.\n *\n * Left out: wrapping at the ends, and type-ahead. The checkbox variants put\n * `role=\"checkbox\"` items in the menu where the pattern asks for\n * `menuitemcheckbox`. A flyout's header is a plain button without\n * `aria-haspopup` or `aria-expanded`, its children sit in a `group` rather\n * than a nested `menu`, and `Right` and `Left` do not open and close it.\n *\n * ## Events\n *\n * - `change` – Fired when the selection changes.\n * Detail includes the selected values array and the selected option objects.\n * - `item-click` – Fired when a menu item is clicked (even if not changing selection).\n * Detail includes the clicked value and its option object.\n * - `close` – Fired when the close button in the title bar is clicked.\n *\n * ## Best Practices and Constraints\n *\n * - Use icons to help users quickly identify options, especially in long or complex menus.\n * - For multi-column layouts, keep the number of columns manageable to avoid overwhelming users.\n * - Use the `multi-with-subtitles` variant for grouped feature selection or when options need to be categorized.\n * - For nested checkboxes, avoid excessive nesting for clarity.\n * - In flyout menus, use group icons to visually distinguish categories.\n * - Only use the close button if the menu is presented as a modal or overlay that requires explicit dismissal.\n * - For accessibility, ensure all options have clear labels.\n *\n * ## Example\n *\n * ```html\n * <obc-context-menu-input\n * type=\"flyout\"\n * .options=${[\n * {\n * value: 'file',\n * label: 'File',\n * icon: html`<obi-placeholder slot=\"icon\"></obi-placeholder>`,\n * children: [\n * { value: 'new', label: 'New' },\n * { value: 'open', label: 'Open' },\n * { value: 'save', label: 'Save' }\n * ]\n * },\n * { value: 'edit', label: 'Edit' }\n * ]}\n * .selectedValues=${['save']}\n * hasTitleBar\n * title=\"Menu\"\n * ></obc-context-menu-input>\n * ```\n *\n * In this example, a flyout menu is shown with a title bar, group icons, and a selected child option.\n *\n * @property title - Title text displayed in the title bar (if `hasTitleBar` is true).\n * @availableWhen title hasTitleBar==true\n * @property selectedValues - Array of currently selected option values.\n * For multi-select variants, can contain multiple values. For single-select, contains at most one value.\n * @property hasTitleBar - Whether to show a title bar with close button at the top of the menu.\n * If true, displays the `title` property and a close icon button.\n * @property columnGroups - Array of column groups for the `multi-with-subtitles` layout.\n * Each group defines a `title`, `columns` (number of columns in the group), and `options` (array of options for that group).\n * @availableWhen columnGroups type==MultiWithSubtitles\n * @property itemsPerColumn - Number of items per column in multi-column layouts.\n * Used in `multi` and `multi-with-subtitles` variants to control column splitting.\n * @availableWhen itemsPerColumn type in [Multi, MultiWithSubtitles]\n * @property multiSelect - Whether multiple selections are allowed.\n * If not set, defaults to true for checkbox/multi variants, false for regular/flyout.\n * @property selectPerGroup - If true, restricts selection to one option per group or column (used in flyout and multi-column).\n * When enabled, only one option can be selected in each group or column.\n * @property type - Menu variant: `regular` (default) is a single-select navigation menu,\n * `checkboxes` and `nested-checkboxes` are flat and hierarchical\n * multi-select, `flyout` has expandable cascading groups, and `multi` and\n * `multi-with-subtitles` lay the menu out in columns, the latter with group\n * subtitles.\n * @property options - Menu options, each with a unique `value` and a `label`, and optionally an\n * `icon` template for the leading icon, a `level` giving the nesting depth\n * for nested checkboxes, and `children` for a flyout or nested menu.\n * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.\n * @property open - Whether the menu is showing.\n * @availableWhen open softDismiss==true\n * @slot - Optionally used for custom icons in options (e.g., `<obi-placeholder slot=\"icon\"></obi-placeholder>`)\n * @fires {ObcContextMenuInputChangeEvent} change - Fired when the selection changes.\n * @fires {ObcContextMenuInputItemClickEvent} item-click - Fired when a menu item is clicked.\n * @fires {CustomEvent<void>} close - Fired when the close button is clicked, on `Escape`, and, with `softDismiss` on, when the menu closed on its own from a click outside or another menu opening.\n * @beta\n */\n@customElement('obc-context-menu-input')\nexport class ObcContextMenuInput extends LitElement {\n @property({type: Boolean}) softDismiss = false;\n\n @property({type: Boolean}) open = false;\n\n protected readonly softDismissController = new PopoverController(this);\n\n @property({type: String})\n type: ContextMenuType = ContextMenuType.Regular;\n\n @property({type: Array}) options: ContextMenuOption[] = [];\n\n @property({type: Array}) selectedValues: string[] = [];\n\n @property({type: Boolean}) hasTitleBar = false;\n\n @property({type: String}) override title = '';\n\n @property({type: Array}) columnGroups: ColumnGroup[] = [];\n\n @property({type: Number}) itemsPerColumn = 5;\n\n @property({type: Boolean}) multiSelect?: boolean;\n\n @property({type: Boolean, reflect: true}) selectPerGroup?: boolean;\n\n private readonly navigator = new RovingNavigator<MenuItemElement>(\n {\n items: () => this.getMenuItems(),\n preferred: () => this.selectedMenuItem(),\n setFocusable: (item, focusable) => {\n item.focusable = focusable;\n },\n },\n {orientation: 'vertical', wrap: false}\n );\n\n override updated() {\n this.navigator.refresh();\n }\n\n private getMenuItems(): MenuItemElement[] {\n return Array.from(\n this.renderRoot.querySelectorAll<MenuItemElement>(\n '[data-menu-item=\"true\"]'\n )\n ).filter((item) => item.getClientRects().length > 0);\n }\n\n private selectedMenuItem(): MenuItemElement | undefined {\n const items = this.getMenuItems();\n return this.selectedValues\n .map((value) =>\n items.find((item) => item.getAttribute('data-menu-value') === value)\n )\n .find((item): item is MenuItemElement => item !== undefined);\n }\n\n private focusMenuItem(index: number) {\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n const item = items[clamp(index, 0, items.length - 1)];\n this.navigator.setActive(item, true);\n item.scrollIntoView({block: 'nearest'});\n }\n\n public focusFirstItem() {\n this.focusMenuItem(0);\n }\n\n public focusLastItem() {\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n this.focusMenuItem(items.length - 1);\n }\n\n public focusSelectedItem() {\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n const selectedItem = this.selectedMenuItem();\n if (selectedItem !== undefined) {\n this.navigator.setActive(selectedItem, true);\n selectedItem.scrollIntoView({block: 'nearest'});\n return;\n }\n\n this.focusFirstItem();\n }\n\n private handleKeydown(event: KeyboardEvent) {\n if (this.navigator.handleKeydown(event)) {\n event.preventDefault();\n this.navigator.activeItem?.scrollIntoView({block: 'nearest'});\n return;\n }\n const items = this.getMenuItems();\n if (items.length === 0) return;\n\n // Focus is on the menu itself, not on an item: the arrows enter the list.\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.focusFirstItem();\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.focusLastItem();\n break;\n case 'Home':\n event.preventDefault();\n this.focusFirstItem();\n break;\n case 'End':\n event.preventDefault();\n this.focusLastItem();\n break;\n case 'Escape':\n // With softDismiss on, the browser closes the menu on Escape by\n // itself. Blocking the default here would stop that and leave the\n // menu open.\n if (this.softDismiss) break;\n event.preventDefault();\n this.dispatchEvent(new CustomEvent('close'));\n break;\n default:\n break;\n }\n }\n\n private get isMultiSelect(): boolean {\n if (this.multiSelect !== undefined) return this.multiSelect;\n return [\n ContextMenuType.Checkboxes,\n ContextMenuType.NestedCheckboxes,\n ContextMenuType.Multi,\n ContextMenuType.MultiWithSubtitles,\n ].includes(this.type);\n }\n\n private get isPerGroupSingleSelect(): boolean {\n if (this.isMultiSelect) return false;\n if (this.selectPerGroup !== undefined) return this.selectPerGroup;\n return this.type === ContextMenuType.Flyout;\n }\n\n /**\n * Returns a unique group-key for each option:\n * - In multi-with-subtitles: group title + subcolumn index (each subcolumn is a group)\n * - In multi: column index (each column is a group)\n */\n private getGroupForValue(value: string): string | undefined {\n if (\n this.type === ContextMenuType.MultiWithSubtitles &&\n this.columnGroups.length\n ) {\n for (const group of this.columnGroups) {\n const totalCols = Math.max(\n group.columns,\n Math.ceil(group.options.length / this.itemsPerColumn)\n );\n const distributed = this.chunkArray(\n group.options,\n this.itemsPerColumn,\n totalCols\n );\n for (let subColIdx = 0; subColIdx < distributed.length; ++subColIdx) {\n if (distributed[subColIdx].some((opt) => opt.value === value)) {\n return `${group.title}___${subColIdx}`;\n }\n }\n }\n return undefined;\n }\n if (this.type === ContextMenuType.Multi && this.itemsPerColumn > 0) {\n const columns = this.chunkArray(this.options, this.itemsPerColumn);\n for (let colIdx = 0; colIdx < columns.length; ++colIdx) {\n if (columns[colIdx].some((opt) => opt.value === value)) {\n return `column-${colIdx}`;\n }\n }\n return undefined;\n }\n if (this.type === ContextMenuType.Flyout && this.options.length) {\n for (const group of this.options) {\n if (group.children?.some((child) => child.value === value)) {\n return group.value;\n }\n if (group.value === value) return group.value;\n }\n return undefined;\n }\n return undefined;\n }\n\n private handleCheckboxChange(option: ContextMenuOption, e: Event) {\n const {status} = (e as CustomEvent<{status: 'checked' | 'unchecked'}>)\n .detail;\n let next: string[];\n\n // Enable \"one per group/column\" for multi-column layouts as well\n if (\n this.selectPerGroup &&\n (this.type === ContextMenuType.Multi ||\n this.type === ContextMenuType.MultiWithSubtitles)\n ) {\n const groupKey = this.getGroupForValue(option.value);\n next = [\n ...this.selectedValues.filter(\n (val) => this.getGroupForValue(val) !== groupKey\n ),\n ...(status === 'checked' ? [option.value] : []),\n ];\n } else {\n next =\n status === 'checked'\n ? [...this.selectedValues, option.value]\n : this.selectedValues.filter((v) => v !== option.value);\n }\n\n if (!arraysEqual(this.selectedValues, next)) this.updateSelection(next);\n }\n\n private handleMenuItemClick(option: ContextMenuOption, event: Event) {\n event.preventDefault();\n\n // Always fire item-click event, even for groups\n this.dispatchEvent(\n new CustomEvent<ObcContextMenuInputItemClickEvent['detail']>(\n 'item-click',\n {\n detail: {value: option.value, option},\n }\n )\n );\n\n // Don't process selection for navigation groups in flyout menus or multi\n if (option.children?.length) return;\n\n let newSelectedValues: string[];\n\n if (this.isPerGroupSingleSelect) {\n // Get the group key for this value (column or group)\n const groupKey = this.getGroupForValue\n ? this.getGroupForValue(option.value)\n : undefined;\n\n // Find currently selected in this group\n const selectedInGroup = this.selectedValues.find(\n (val) => this.getGroupForValue(val) === groupKey\n );\n\n // If the clicked option is already selected in this group, unselect it\n if (selectedInGroup === option.value) {\n newSelectedValues = this.selectedValues.filter(\n (val) => val !== option.value\n );\n } else {\n // Otherwise, replace any existing selection in the group with this one\n newSelectedValues = [\n ...this.selectedValues.filter(\n (val) => this.getGroupForValue(val) !== groupKey\n ),\n option.value,\n ];\n }\n } else {\n // REGULAR (single select, non-grouped): toggle if already selected\n if (this.selectedValues.includes(option.value)) {\n newSelectedValues = [];\n } else {\n newSelectedValues = [option.value];\n }\n }\n\n if (!arraysEqual(this.selectedValues, newSelectedValues))\n this.updateSelection(newSelectedValues);\n }\n\n private updateSelection(vals: string[]) {\n this.selectedValues = vals;\n const selectedOptions: ContextMenuOption[] = [];\n const collect = (arr: ContextMenuOption[]) =>\n arr.forEach((o) => {\n if (vals.includes(o.value)) selectedOptions.push(o);\n if (o.children) collect(o.children);\n });\n collect(this.options);\n this.dispatchEvent(\n new CustomEvent<ObcContextMenuInputChangeEvent['detail']>('change', {\n detail: {selectedValues: vals, selectedOptions},\n })\n );\n }\n\n private handleCloseClick(e: Event) {\n e.preventDefault();\n this.dispatchEvent(new CustomEvent('close'));\n }\n\n private isOptionSelected(v: string) {\n return this.selectedValues.includes(v);\n }\n\n private renderTitleBar() {\n if (!this.hasTitleBar) return nothing;\n return html`\n <div class=\"title-container\">\n <div class=\"title-content\">\n <div class=\"title-text\">${this.title}</div>\n </div>\n <obc-icon-button\n variant=\"flat\"\n @click=${this.handleCloseClick}\n aria-label=\"Close menu\"\n .focusable=${false}\n >\n <obi-close-google></obi-close-google>\n </obc-icon-button>\n </div>\n `;\n }\n\n private renderRegularItems() {\n return this.options.map((o) => this.renderNavItem(o));\n }\n\n private renderCheckboxItems() {\n return this.options.map((o) => {\n const isSelected = this.isOptionSelected(o.value);\n const isNested =\n this.type === ContextMenuType.NestedCheckboxes &&\n o.level &&\n o.level > 1;\n const indent = isNested ? (o.level! - 1) * 16 : 0;\n return html`<div\n class=\"menu-item checkbox-item-wrapper\"\n style=${indent ? `padding-left:${indent}px` : ''}\n >\n <obc-checkbox-item\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .status=${isSelected ? 'checked' : 'unchecked'}\n @expand-toggle=${stopPropagation}\n @change=${(e: Event) => this.handleCheckboxChange(o, e)}\n ></obc-checkbox-item>\n </div>`;\n });\n }\n\n private renderNavItem(o: ContextMenuOption) {\n const isSelected = this.isOptionSelected(o.value);\n const indent = o.level ? (o.level - 1) * 16 : 0;\n return html`<div\n class=\"menu-item navigation-item-wrapper\"\n style=${indent ? `padding-left:${indent}px` : ''}\n >\n <obc-navigation-item\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .checked=${isSelected}\n .variant=${ObcNavigationMenuVariant.Full}\n @click=${(e: Event) => this.handleMenuItemClick(o, e)}\n .itemRole=${NavigationItemRole.MenuItemRadio}\n ?hasIcon=${!!o.icon}\n >\n ${o.icon ? html`<div slot=\"icon\">${o.icon}</div>` : nothing}\n </obc-navigation-item>\n </div>`;\n }\n\n // Renders checkboxes for children if multi, otherwise navigation items\n private renderFlyoutChildren(children: ContextMenuOption[]) {\n if (this.isMultiSelect) {\n return children.map((c) => {\n const isSelected = this.isOptionSelected(c.value);\n return html`<div class=\"menu-item checkbox-item-wrapper\">\n <obc-checkbox-item\n data-menu-item=\"true\"\n data-menu-value=${c.value}\n .label=${c.label}\n .status=${isSelected ? 'checked' : 'unchecked'}\n @expand-toggle=${stopPropagation}\n @change=${(e: Event) => this.handleCheckboxChange(c, e)}\n ></obc-checkbox-item>\n </div>`;\n });\n }\n return children.map((c) => {\n const isSelected = this.isOptionSelected(c.value);\n return html`<obc-navigation-item\n data-menu-item=\"true\"\n data-menu-value=${c.value}\n .label=${c.label}\n .checked=${isSelected}\n .variant=${ObcNavigationMenuVariant.Full}\n @click=${(e: Event) => this.handleMenuItemClick(c, e)}\n .itemRole=${NavigationItemRole.MenuItemRadio}\n ?hasIcon=${!!c.icon}\n >\n ${c.icon ? html`<div slot=\"icon\">${c.icon}</div>` : nothing}\n </obc-navigation-item>`;\n });\n }\n\n /**\n * Rows a group shows or hides join or leave the roving set only once the\n * group has rendered; until then a newly shown row is its own tab stop.\n */\n private async refreshAfterDisclosure(group: ObcNavigationItemGroup) {\n await group.updateComplete;\n await this.updateComplete;\n this.navigator.refresh();\n }\n\n private handleFlyoutGroupClick(option: ContextMenuOption, event: Event) {\n event.preventDefault();\n this.refreshAfterDisclosure(event.currentTarget as ObcNavigationItemGroup);\n this.dispatchEvent(\n new CustomEvent<ObcContextMenuInputItemClickEvent['detail']>(\n 'item-click',\n {\n detail: {value: option.value, option},\n }\n )\n );\n // Don't fire a change event for navigation groups\n }\n\n private renderFlyoutItems() {\n return this.options.map((o) => {\n const isSelected = this.isOptionSelected(o.value);\n if (o.children?.length) {\n return html`<obc-navigation-item-group\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .checked=${isSelected}\n .variant=${ObcNavigationMenuVariant.Full}\n .hug=${true}\n .hasIcon=${!!o.icon}\n @click=${(e: Event) => this.handleFlyoutGroupClick(o, e)}\n @open=${(e: Event) => {\n this.shadowRoot\n ?.querySelectorAll('obc-navigation-item-group')\n .forEach((g) => {\n const group = g as ObcNavigationItemGroup;\n if (group.label !== o.label) group.close();\n });\n this.refreshAfterDisclosure(\n e.currentTarget as ObcNavigationItemGroup\n );\n }}\n >\n ${o.icon ? html`<div slot=\"icon\">${o.icon}</div>` : nothing}\n ${this.renderFlyoutChildren(o.children)}\n </obc-navigation-item-group>`;\n }\n return this.renderNavItem(o);\n });\n }\n\n // --------- MULTI COLUMN ---------\n\n private renderMultiColumnItems() {\n const renderColumn = (columnOptions: ContextMenuOption[]) => {\n if (!columnOptions.length) return nothing;\n\n // True multi-select: checkboxes\n if (this.isMultiSelect && !this.selectPerGroup) {\n return columnOptions.map((o) => {\n const isSelected = this.isOptionSelected(o.value);\n return html`<div class=\"menu-item checkbox-item-wrapper\">\n <obc-checkbox-item\n data-menu-item=\"true\"\n data-menu-value=${o.value}\n .label=${o.label}\n .status=${isSelected ? 'checked' : 'unchecked'}\n @expand-toggle=${stopPropagation}\n @change=${(e: Event) => this.handleCheckboxChange(o, e)}\n ></obc-checkbox-item>\n </div>`;\n });\n }\n // fallback: nav item\n return columnOptions.map((opt) => this.renderNavItem(opt));\n };\n\n if (this.type === ContextMenuType.MultiWithSubtitles) {\n if (!this.columnGroups.length) {\n // Fallback – evenly spread across columns\n const cols = this.chunkArray(this.options, this.itemsPerColumn);\n return html`<div class=\"multi-content\">\n <div class=\"multi-columns\">\n <div class=\"columns-container\">\n ${cols.map(\n (col, idx) =>\n html`<div\n class=\"column-with-header ${idx ? 'column-divider' : ''}\"\n >\n <div class=\"column-header\">\n <div class=\"subtitle-container\">\n <div class=\"subtitle-text\">Group ${idx + 1}</div>\n </div>\n </div>\n <div class=\"column-content\">${renderColumn(col)}</div>\n </div>`\n )}\n </div>\n </div>\n </div>`;\n }\n\n interface ColumnInfo {\n options: ContextMenuOption[];\n groupTitle: string;\n isFirstInGroup: boolean;\n isFirstGroup: boolean;\n colIdx: number;\n }\n\n const allCols: ColumnInfo[] = [];\n this.columnGroups.forEach((g, gIdx) => {\n const calculatedCols = Math.ceil(\n g.options.length / this.itemsPerColumn\n );\n const actualCols = Math.max(g.columns, calculatedCols);\n const distributed = this.chunkArray(\n g.options,\n this.itemsPerColumn,\n actualCols\n );\n distributed.forEach((opts, idx) => {\n allCols.push({\n options: opts,\n groupTitle: g.title,\n isFirstInGroup: idx === 0,\n isFirstGroup: gIdx === 0,\n colIdx: idx,\n });\n });\n });\n\n return html`<div class=\"multi-content\">\n <div class=\"multi-columns\">\n <div class=\"columns-container\">\n ${allCols.map(\n (c) =>\n html`<div\n class=\"column-with-header ${\n !c.isFirstGroup && c.isFirstInGroup ? 'column-divider' : ''\n }\"\n >\n ${\n c.isFirstInGroup\n ? html`<div class=\"column-header\">\n <div class=\"subtitle-container\">\n <div class=\"subtitle-text\">${c.groupTitle}</div>\n </div>\n </div>`\n : html`<div class=\"column-header-spacer\"></div>`\n }\n <div class=\"column-content\">${renderColumn(c.options)}</div>\n </div>`\n )}\n </div>\n </div>\n </div>`;\n }\n\n // Simple multi (no subtitles)\n const columns = this.chunkArray(this.options, this.itemsPerColumn);\n return html`<div class=\"multi-content\">\n <div class=\"multi-columns\">\n ${columns.map(\n (col, idx) =>\n html`<div class=\"column ${idx ? 'column-divider' : ''}\">\n ${renderColumn(col)}\n </div>`\n )}\n </div>\n </div>`;\n }\n\n private chunkArray<T>(arr: T[], size: number, forcedColumns?: number): T[][] {\n if (forcedColumns) {\n const out: T[][] = Array.from({length: forcedColumns}, () => []);\n arr.forEach((item, idx) => out[Math.floor(idx / size)].push(item));\n return out;\n }\n const result: T[][] = [];\n for (let i = 0; i < arr.length; i += size)\n result.push(arr.slice(i + 0, i + size));\n return result;\n }\n\n private renderMenuContent() {\n switch (this.type) {\n case ContextMenuType.Checkboxes:\n case ContextMenuType.NestedCheckboxes:\n return this.renderCheckboxItems();\n case ContextMenuType.Flyout:\n return this.renderFlyoutItems();\n case ContextMenuType.Multi:\n case ContextMenuType.MultiWithSubtitles:\n return this.renderMultiColumnItems();\n default:\n return this.renderRegularItems();\n }\n }\n\n override render() {\n return html`<div\n class=${classMap({\n 'context-menu': true,\n [`type-${this.type}`]: true,\n 'has-title': this.hasTitleBar,\n })}\n tabindex=\"-1\"\n role=\"menu\"\n aria-label=${this.hasTitleBar ? this.title : 'Context menu'}\n @keydown=${this.handleKeydown}\n @focusin=${(event: Event) => this.navigator.handleFocusin(event)}\n >\n ${this.renderTitleBar()}\n <div class=\"menu-content\">${this.renderMenuContent()}</div>\n </div>`;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\nfunction arraysEqual(a: string[], b: string[]) {\n if (a.length !== b.length) return false;\n const setA = new Set(a);\n return b.every((v) => setA.has(v));\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-context-menu-input': ObcContextMenuInput;\n }\n}\n"],"names":["ContextMenuType"],"mappings":"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"}
@@ -1,8 +1,28 @@
1
1
  import { css } from "lit";
2
2
  const compentStyle = css`* {
3
- -webkit-tap-highlight-color: transparent;
3
+ -webkit-tap-highlight-color: transparent;
4
4
  }
5
5
 
6
+ :host([popover]) {
7
+ /* The browser pins a popover to all four edges and lets the automatic
8
+ margins centre it. Unpinning drops it back where it would normally sit,
9
+ for the consumer to position from. */
10
+ inset: auto;
11
+ margin: 0;
12
+
13
+ padding: 0;
14
+ border: none;
15
+ background: none;
16
+ color: inherit;
17
+
18
+ /* The menus scroll their own content. */
19
+ overflow: visible;
20
+
21
+ /* The browser shrink-wraps a popover to its contents. */
22
+ width: auto;
23
+ height: auto;
24
+ }
25
+
6
26
  .wrapper {
7
27
  display: flex;
8
28
  flex-direction: column;
@@ -1 +1 @@
1
- {"version":3,"file":"navigation-menu.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"navigation-menu.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,6 +1,7 @@
1
1
  import { LitElement, PropertyValues } from 'lit';
2
2
  import { ObcNavigationItemGroup } from '../navigation-item-group/navigation-item-group.js';
3
3
  import { ObcNavigationItem } from '../navigation-item/navigation-item.js';
4
+ import { PopoverController } from '../../internal/popover-controller.js';
4
5
  /**
5
6
  * `ObcNavigationMenuVariant` – Enumerates the available visual and behavioral variants for `<obc-navigation-menu>`.
6
7
  *
@@ -130,12 +131,25 @@ export declare enum ObcNavigationMenuFlyoutVariant {
130
131
  * `icon-only-large` is the icon-only menu that does, `compact` is the
131
132
  * space-saving menu, and `tree` expands groups inline and indents rows by
132
133
  * depth.
134
+ * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.
135
+ * @property open - Whether the menu is showing.
136
+ * @availableWhen open softDismiss==true
133
137
  * @slot main - Slot for primary navigation items and groups.
134
138
  * @slot footer - Slot for secondary navigation items (e.g., settings, help).
135
139
  * @slot logo - Slot for branding/logo area.
140
+ * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.
136
141
  * @stable
137
142
  */
138
143
  export declare class ObcNavigationMenu extends LitElement {
144
+ /** Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself. */
145
+ softDismiss: boolean;
146
+ /**
147
+ * Whether the menu is showing.
148
+ *
149
+ * Available when `softDismiss==true`.
150
+ */
151
+ open: boolean;
152
+ protected readonly softDismissController: PopoverController;
139
153
  /** Visual style and layout: `full` (default) shows icons and labels, `icon-only` is the compact icon-only menu and takes no flyouts or groups, `icon-only-large` is the icon-only menu that does, `compact` is the space-saving menu, and `tree` expands groups inline and indents rows by depth. */
140
154
  variant: ObcNavigationMenuVariant;
141
155
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"navigation-menu.d.ts","sourceRoot":"","sources":["../../../src/components/navigation-menu/navigation-menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAA2B,MAAM,KAAK,CAAC;AAGzE,OAAO,EAAC,sBAAsB,EAAC,MAAM,mDAAmD,CAAC;AACzF,OAAO,EAAC,iBAAiB,EAAC,MAAM,uCAAuC,CAAC;AA0BxE;;;;;;;;;;GAUG;AACH,oBAAY,wBAAwB;IAClC,IAAI,SAAS;IACb,QAAQ,cAAc,CAAE,yEAAyE;IACjG,aAAa,oBAAoB,CAAE,iEAAiE;IACpG,OAAO,YAAY;IACnB,IAAI,SAAS;CACd;AAED;;;;;;;GAOG;AACH,oBAAY,8BAA8B;IACxC,IAAI,SAAS;IACb,OAAO,YAAY;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuGG;AACH,qBACa,iBAAkB,SAAQ,UAAU;IACrB,OAAO,EAAE,wBAAwB,CAC3B;IAEN,aAAa,EAAE,8BAA8B,CACjC;IAEX,WAAW,UAAS;IAE/C,OAAO,CAAC,aAAa,CAA0B;IACtC,OAAO,CAAC,SAAS,CAAS;IAEnC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAaa;IAE3C,oFAAoF;IACpF,OAAO,CAAC,YAAY;IAQpB,4DAA4D;IAC5D,OAAO,CAAC,aAAa;IAIrB,wFAAwF;IACxF,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,aAAa,CAGnB;IAEO,iBAAiB,IAAI,IAAI;IAKlC,eAAe,CAAC,CAAC,SAAS,OAAO,EAC/B,EAAE,EAAE,OAAO,EACX,GAAG,EAAE,MAAM,EACX,EACE,IAAI,EACJ,OAAO,GACR,GAAE;QACD,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC;KACb,GACL,CAAC,EAAE;IAoBN,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,sBAAsB,EAAE;IAQpD,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,iBAAiB,EAAE;IAO/C,YAAY,CACV,EAAE,EAAE,OAAO,EACX,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAChC,iBAAiB,EAAE;IAMtB,cAAc;IAOd,aAAa,CAAC,MAAM,EAAE,sBAAsB,EAAE;IAe9C,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,kBAAkB;cA+BP,YAAY,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;cAMtD,OAAO,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;IAWpE,OAAO,CAAC,uBAAuB;IAiBtB,oBAAoB,IAAI,IAAI;IAMrC,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,kBAAkB;IA2B1B,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,UAAU;IA0DlB,OAAO,CAAC,cAAc;IAQb,MAAM;IAiCf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,qBAAqB,EAAE,iBAAiB,CAAC;KAC1C;CACF"}
1
+ {"version":3,"file":"navigation-menu.d.ts","sourceRoot":"","sources":["../../../src/components/navigation-menu/navigation-menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAA2B,MAAM,KAAK,CAAC;AAGzE,OAAO,EAAC,sBAAsB,EAAC,MAAM,mDAAmD,CAAC;AACzF,OAAO,EAAC,iBAAiB,EAAC,MAAM,uCAAuC,CAAC;AAUxE,OAAO,EAAC,iBAAiB,EAAC,MAAM,sCAAsC,CAAC;AAiBvE;;;;;;;;;;GAUG;AACH,oBAAY,wBAAwB;IAClC,IAAI,SAAS;IACb,QAAQ,cAAc,CAAE,yEAAyE;IACjG,aAAa,oBAAoB,CAAE,iEAAiE;IACpG,OAAO,YAAY;IACnB,IAAI,SAAS;CACd;AAED;;;;;;;GAOG;AACH,oBAAY,8BAA8B;IACxC,IAAI,SAAS;IACb,OAAO,YAAY;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2GG;AACH,qBACa,iBAAkB,SAAQ,UAAU;IACpB,WAAW,UAAS;IAEpB,IAAI,UAAS;IAExC,SAAS,CAAC,QAAQ,CAAC,qBAAqB,oBAA+B;IAE7C,OAAO,EAAE,wBAAwB,CAC3B;IAEN,aAAa,EAAE,8BAA8B,CACjC;IAEX,WAAW,UAAS;IAE/C,OAAO,CAAC,aAAa,CAA0B;IACtC,OAAO,CAAC,SAAS,CAAS;IAEnC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAaa;IAE3C,oFAAoF;IACpF,OAAO,CAAC,YAAY;IAQpB,4DAA4D;IAC5D,OAAO,CAAC,aAAa;IAIrB,wFAAwF;IACxF,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,aAAa,CAGnB;IAEO,iBAAiB,IAAI,IAAI;IAKlC,eAAe,CAAC,CAAC,SAAS,OAAO,EAC/B,EAAE,EAAE,OAAO,EACX,GAAG,EAAE,MAAM,EACX,EACE,IAAI,EACJ,OAAO,GACR,GAAE;QACD,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC;KACb,GACL,CAAC,EAAE;IAoBN,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,sBAAsB,EAAE;IAQpD,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,iBAAiB,EAAE;IAO/C,YAAY,CACV,EAAE,EAAE,OAAO,EACX,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAChC,iBAAiB,EAAE;IAMtB,cAAc;IAOd,aAAa,CAAC,MAAM,EAAE,sBAAsB,EAAE;IAe9C,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,kBAAkB;cA+BP,YAAY,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;cAMtD,OAAO,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;IAWpE,OAAO,CAAC,uBAAuB;IAiBtB,oBAAoB,IAAI,IAAI;IAMrC,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,kBAAkB;IA2B1B,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,UAAU;IA0DlB,OAAO,CAAC,cAAc;IAQb,MAAM;IAiCf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,qBAAqB,EAAE,iBAAiB,CAAC;KAC1C;CACF"}
@@ -4,6 +4,7 @@ import compentStyle from "./navigation-menu.css.js";
4
4
  import { customElement } from "../../decorator.js";
5
5
  import { TreeBranchType } from "../tree-navigation-item/tree-navigation-item.js";
6
6
  import { TreeRovingNavigator } from "../../internal/tree-roving-navigator.js";
7
+ import { PopoverController } from "../../internal/popover-controller.js";
7
8
  var __defProp = Object.defineProperty;
8
9
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
10
  var __decorateClass = (decorators, target, key, kind) => {
@@ -39,6 +40,9 @@ var ObcNavigationMenuFlyoutVariant = /* @__PURE__ */ ((ObcNavigationMenuFlyoutVa
39
40
  let ObcNavigationMenu = class extends LitElement {
40
41
  constructor() {
41
42
  super(...arguments);
43
+ this.softDismiss = false;
44
+ this.open = false;
45
+ this.softDismissController = new PopoverController(this);
42
46
  this.variant = "full";
43
47
  this.flyoutVariant = "full";
44
48
  this.smallScreen = false;
@@ -317,6 +321,12 @@ let ObcNavigationMenu = class extends LitElement {
317
321
  }
318
322
  };
319
323
  ObcNavigationMenu.styles = unsafeCSS(compentStyle);
324
+ __decorateClass([
325
+ property({ type: Boolean })
326
+ ], ObcNavigationMenu.prototype, "softDismiss", 2);
327
+ __decorateClass([
328
+ property({ type: Boolean })
329
+ ], ObcNavigationMenu.prototype, "open", 2);
320
330
  __decorateClass([
321
331
  property({ type: String })
322
332
  ], ObcNavigationMenu.prototype, "variant", 2);
@@ -1 +1 @@
1
- {"version":3,"file":"navigation-menu.js","sources":["../../../src/components/navigation-menu/navigation-menu.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, nothing, unsafeCSS} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport compentStyle from './navigation-menu.css?inline';\nimport {ObcNavigationItemGroup} from '../navigation-item-group/navigation-item-group.js';\nimport {ObcNavigationItem} from '../navigation-item/navigation-item.js';\nimport {customElement} from '../../decorator.js';\nimport {\n ObcTreeNavigationItem,\n TreeBranchType,\n} from '../tree-navigation-item/tree-navigation-item.js';\nimport {\n TreeRovingNavigator,\n TreeRovingAdapter,\n} from '../../internal/tree-roving-navigator.js';\n\n/** A nav-menu tree row is either a navigation item or a navigation item group. */\ntype NavTreeRow = ObcNavigationItem | ObcNavigationItemGroup;\n\nconst NAV_ITEM_TAG = 'obc-navigation-item';\nconst NAV_GROUP_TAG = 'obc-navigation-item-group';\n\nfunction isNavGroup(el: Element): el is ObcNavigationItemGroup {\n return el.tagName.toLowerCase() === NAV_GROUP_TAG;\n}\n\nfunction isNavRow(el: Element): el is NavTreeRow {\n const tag = el.tagName.toLowerCase();\n return tag === NAV_ITEM_TAG || tag === NAV_GROUP_TAG;\n}\n\n/**\n * `ObcNavigationMenuVariant` – Enumerates the available visual and behavioral variants for `<obc-navigation-menu>`.\n *\n * - `Full`: Standard navigation menu with both icons and labels.\n * - `IconOnly`: Compact menu showing only icons (should only be used when no flyouts/submenus are present).\n * - `IconOnlyLarge`: Icon-only menu variant designed for use when flyouts/submenus are present.\n * - `Compact`: Space-saving menu with reduced padding and layout.\n * - `Tree`: Hierarchical tree — groups expand inline and rows are indented by depth.\n *\n * Use these variants to adapt the navigation menu to different layouts or device sizes.\n */\nexport enum ObcNavigationMenuVariant {\n Full = 'full',\n IconOnly = 'icon-only', // Should only be used when no flyouts are present in the navigation menu\n IconOnlyLarge = 'icon-only-large', // Should be used when flyouts are present in the navigation menu\n Compact = 'compact',\n Tree = 'tree',\n}\n\n/**\n * `ObcNavigationMenuFlyoutVariant` – Enumerates the available visual and behavioral variants for the flyout.\n *\n * - `Full`: Standard navigation flyout that takes the full height.\n * - `Compact`: Space-saving menu with reduced padding and layout.\n *\n * Use these variants to adapt the flyout menu to different layouts or device sizes.\n */\nexport enum ObcNavigationMenuFlyoutVariant {\n Full = 'full',\n Compact = 'compact',\n}\n\n/**\n * `<obc-navigation-menu>` – A flexible, slot-based navigation menu component for organizing primary and secondary navigation items.\n *\n * This component provides a vertical navigation structure supporting groups, flyouts, and footer sections. It adapts to various layouts and device sizes via its `variant` and `smallScreen` properties. Items and groups are provided via slots, allowing for icons, labels, and nested navigation hierarchies.\n *\n * Appears as a sidebar or persistent navigation panel, supporting both icon-only and full-label modes. Designed for use as the main navigation in applications, dashboards, or any interface requiring structured navigation.\n *\n * ## Features\n *\n * - **Variants:**\n * - **Full:** Displays both icons and labels for all navigation items (default).\n * - **IconOnly:** Shows only icons for a compact appearance. *Should only be used when no navigation items have sub-items or flyouts.*\n * - **IconOnlyLarge:** Icon-only mode that supports flyouts/submenus. Use when navigation contains groups or nested items.\n * - **Compact:** Reduces padding and overall width for a space-saving layout.\n * - **Tree:** Renders the same `obc-navigation-item` / `obc-navigation-item-group`\n * markup as a hierarchical tree. Groups expand inline (instead of as flyouts),\n * rows are indented by depth, multiple branches can stay open at once, and the\n * tree-row presentation (alert badges, terminal marker) is available via the\n * items' `alerts`/`terminalType` properties.\n * - **Responsive Layout:**\n * - `smallScreen` property adapts the footer and logo layout for smaller viewports.\n * - **Slot-based Content:**\n * - `main` slot for primary navigation items and groups.\n * - `footer` slot for secondary actions or links.\n * - `logo` slot for branding or logo placement (position adapts based on variant and screen size).\n * - **Nested Navigation:**\n * - Supports nested groups and flyouts via `<obc-navigation-item-group>`.\n * - **Automatic Variant Propagation:**\n * - Child items and groups automatically receive the correct variant for consistent appearance.\n * - **Dynamic Content Handling:**\n * - Reacts to dynamic addition/removal of items and groups, updating layout and variants as needed.\n * - **Interaction:**\n * - Clicking a navigation item closes all open groups/flyouts for streamlined navigation.\n *\n * ## Usage Guidelines\n *\n * Use `<obc-navigation-menu>` as the main navigation container in your application layout. Place navigation items and groups in the `main` slot for primary navigation, and use the `footer` slot for secondary actions (such as settings or help). The `logo` slot is intended for branding and is positioned according to the selected variant and screen size.\n *\n * - Use the `Full` variant for standard navigation with both icons and labels.\n * - Use `IconOnly` only when there are no nested groups or flyouts; otherwise, use `IconOnlyLarge` for icon-only navigation with flyout support.\n * - The `Compact` variant is suitable for layouts with limited space or when a minimal navigation appearance is desired.\n * - Use the `Tree` variant for hierarchical navigation (file trees, nested\n * sections). The existing item/group markup is reused unchanged — only the\n * `variant` changes. Footer and logo slots remain flat. Mark a group with\n * `defaultOpen` to have it start expanded.\n * - Set `smallScreen` to `true` to optimize the layout for smaller devices or responsive breakpoints.\n *\n * **TODO(designer):** Provide additional guidance on when to use each variant and recommended slot content for best usability.\n *\n * ## Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |-----------|----------------|---------|\n * | main | Always | Primary navigation items and groups. |\n * | footer | Always | Secondary navigation items (e.g., settings, help). |\n * | logo | Always | Branding/logo area (position varies by variant and screen size). |\n *\n * Place `<obc-navigation-item>`, `<obc-navigation-item-group>`, or other suitable elements in these slots. For icons, use `<obi-placeholder>`, `<obi-applications>`, or other OpenBridge icon components in the `icon` slot of each navigation item.\n *\n * ## Properties\n *\n * - `variant` (`ObcNavigationMenuVariant`): Controls the visual style and layout of the menu. Default is `Full`.\n * - `smallScreen` (`boolean`): When `true`, adapts the layout for small screens (e.g., moves logo into the footer area).\n *\n * ## Best Practices and Constraints\n *\n * - Only use the `IconOnly` variant when there are no navigation items with sub-items or flyouts. Use `IconOnlyLarge` if your navigation includes groups or nested items.\n * - Place only navigation-related components in the `main` and `footer` slots for clarity and accessibility.\n * - For best accessibility, ensure each navigation item has a clear label and, if using icons, a suitable `aria-label` or accessible name.\n * - Avoid placing interactive elements other than navigation items/groups in the `main` or `footer` slots.\n *\n * ## Example\n *\n * ```html\n * <obc-navigation-menu variant=\"full\">\n * <obc-navigation-item-group slot=\"main\" label=\"Apps\">\n * <obi-applications slot=\"icon\"></obi-applications>\n * <obc-navigation-item label=\"Sub item 1\" hasIcon href=\"#\">\n * <obi-placeholder slot=\"icon\"></obi-placeholder>\n * </obc-navigation-item>\n * </obc-navigation-item-group>\n * <obc-navigation-item slot=\"footer\" label=\"Settings\" hasIcon href=\"#\">\n * <obi-settings-iec slot=\"icon\"></obi-settings-iec>\n * </obc-navigation-item>\n * <obc-vendor-button imageSrc=\"/companylogo-day.png\" alt=\"logo\" slot=\"logo\"></obc-vendor-button>\n * </obc-navigation-menu>\n * ```\n *\n * In this example, the menu displays a group with sub-items in the main navigation, several footer actions, and a logo.\n *\n * @property flyoutVariant - Visual variant of the flyout.\n * One of `Full` (default) or `Compact`.\n * @availableWhen flyoutVariant variant==Full\n * @property smallScreen - When `true`, adapts the layout for small screens (e.g., moves logo into the footer area and adjusts item layout).\n * @property variant - Visual style and layout: `full` (default) shows icons and labels,\n * `icon-only` is the compact icon-only menu and takes no flyouts or groups,\n * `icon-only-large` is the icon-only menu that does, `compact` is the\n * space-saving menu, and `tree` expands groups inline and indents rows by\n * depth.\n * @slot main - Slot for primary navigation items and groups.\n * @slot footer - Slot for secondary navigation items (e.g., settings, help).\n * @slot logo - Slot for branding/logo area.\n * @stable\n */\n@customElement('obc-navigation-menu')\nexport class ObcNavigationMenu extends LitElement {\n @property({type: String}) variant: ObcNavigationMenuVariant =\n ObcNavigationMenuVariant.Full;\n\n @property({type: String}) flyoutVariant: ObcNavigationMenuFlyoutVariant =\n ObcNavigationMenuFlyoutVariant.Full;\n\n @property({type: Boolean}) smallScreen = false;\n\n private slotObservers: MutationObserver[] = [];\n @state() private hasFooter = false;\n\n /**\n * Roving-tabindex + arrow-key navigation for the Tree variant, sharing the\n * navigator that drives `obc-tree-navigation`. Engaged only while\n * `variant === Tree` (see `onTreeKeydown`).\n */\n private readonly treeNavigator = new TreeRovingNavigator<NavTreeRow>({\n getRows: () => this.treeRootRows(),\n childRows: (row) => this.treeChildRows(row),\n isGroup: (row) => isNavGroup(row),\n // Read the group's own synchronous open state, not the shadow header's\n // attribute (which lags a render tick behind a keyboard expand/collapse).\n isExpanded: (row) => isNavGroup(row) && row.expanded,\n setExpanded: (row, expanded) => {\n if (!isNavGroup(row)) return;\n if (expanded) row.open();\n else row.close();\n },\n innerItem: (row) => this.treeInnerItem(row),\n } satisfies TreeRovingAdapter<NavTreeRow>);\n\n /** Top-level tree rows of the main slot (mirrors `assignTreeBranches`'s filter). */\n private treeRootRows(): NavTreeRow[] {\n return Array.from(this.children).filter((child): child is NavTreeRow => {\n if (!isNavRow(child)) return false;\n const slot = child.getAttribute('slot');\n return slot === null || slot === 'main';\n });\n }\n\n /** Direct tree-row children of a row, in document order. */\n private treeChildRows(row: NavTreeRow): NavTreeRow[] {\n return Array.from(row.children).filter(isNavRow);\n }\n\n /** The inline `obc-tree-navigation-item` a tree-mode row renders in its shadow root. */\n private treeInnerItem(row: NavTreeRow): ObcTreeNavigationItem | null {\n return (\n row.shadowRoot?.querySelector<ObcTreeNavigationItem>(\n 'obc-tree-navigation-item'\n ) ?? null\n );\n }\n\n private onTreeKeydown = (event: KeyboardEvent): void => {\n if (this.variant !== ObcNavigationMenuVariant.Tree) return;\n if (this.treeNavigator.handleKeydown(event)) event.preventDefault();\n };\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('keydown', this.onTreeKeydown);\n }\n\n findAllElements<T extends Element>(\n el: Element,\n tag: string,\n {\n slot,\n stopTag,\n }: {\n slot?: 'main' | 'footer' | 'logo';\n stopTag?: string;\n } = {}\n ): T[] {\n const elements: T[] = [];\n for (const child of el.children) {\n if (child.tagName.toLowerCase() === tag) {\n if (slot && child.getAttribute('slot') !== slot) {\n continue;\n }\n elements.push(child as T);\n } else if (stopTag && child.tagName.toLowerCase() === stopTag) {\n continue;\n } else {\n if (slot && child.getAttribute('slot') !== slot) {\n continue;\n }\n elements.push(...this.findAllElements<T>(child, tag, {stopTag}));\n }\n }\n return elements;\n }\n\n findAllGroups(el: Element): ObcNavigationItemGroup[] {\n // Find all groups that are not in a group\n return this.findAllElements<ObcNavigationItemGroup>(\n el,\n 'obc-navigation-item-group'\n );\n }\n\n findRootItems(el: Element): ObcNavigationItem[] {\n // Find all items that are not in a group or in an item\n return this.findAllElements<ObcNavigationItem>(el, 'obc-navigation-item', {\n stopTag: 'obc-navigation-item-group',\n });\n }\n\n findAllItems(\n el: Element,\n slot?: 'main' | 'footer' | 'logo'\n ): ObcNavigationItem[] {\n return this.findAllElements<ObcNavigationItem>(el, 'obc-navigation-item', {\n slot,\n });\n }\n\n closeAllGroups() {\n const groups = this.findAllGroups(this);\n groups.forEach((group) => {\n group.close();\n });\n }\n\n registerGroup(groups: ObcNavigationItemGroup[]) {\n groups.forEach((group) => {\n group.addEventListener('open', () => {\n if (this.variant === ObcNavigationMenuVariant.Tree) return;\n groups.forEach((g) => {\n if (g !== group) {\n g.close();\n }\n });\n });\n const subGroups = this.findAllGroups(group);\n this.registerGroup(subGroups);\n });\n }\n\n private cleanupSlotObservers() {\n this.slotObservers.forEach((observer) => observer.disconnect());\n this.slotObservers = [];\n }\n\n private setupSlotObservers() {\n this.cleanupSlotObservers();\n\n const mainSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"main\"]'\n ) as HTMLSlotElement;\n const footerSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"footer\"]'\n ) as HTMLSlotElement;\n\n this.hasFooter = footerSlot?.assignedElements().length > 0;\n\n [mainSlot, footerSlot].forEach((slot) => {\n if (slot) {\n const slottedElements = slot.assignedElements();\n slottedElements.forEach((element) => {\n const observer = new MutationObserver(() => {\n this.setupItems();\n });\n\n observer.observe(element, {\n childList: true,\n subtree: true,\n });\n\n this.slotObservers.push(observer);\n });\n }\n });\n }\n\n protected override firstUpdated(_changedProperties: PropertyValues): void {\n super.firstUpdated(_changedProperties);\n const groups = this.findAllGroups(this);\n this.registerGroup(groups);\n }\n\n protected override updated(_changedProperties: PropertyValues): void {\n super.updated(_changedProperties);\n if (\n _changedProperties.has('variant') ||\n _changedProperties.has('flyoutVariant')\n ) {\n this.setupItems();\n }\n }\n\n // Recursively set variant for children of groups\n private setVariantToFlyoutItems(el: Element) {\n // Find all descendant items inside this element (not direct children of the nav menu)\n const items = this.findAllElements<ObcNavigationItem>(\n el,\n 'obc-navigation-item'\n );\n items.forEach((item) => {\n item.variant = ObcNavigationMenuVariant.Full;\n });\n\n const groups = this.findAllGroups(el);\n groups.forEach((group) => {\n group.variant = ObcNavigationMenuVariant.Full;\n this.setVariantToFlyoutItems(group);\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.cleanupSlotObservers();\n this.removeEventListener('keydown', this.onTreeKeydown);\n }\n\n private handleSlotChange() {\n this.setupItems();\n this.setupSlotObservers();\n }\n\n private assignTreeBranches(el: Element, depth: number): void {\n for (const child of el.children) {\n const tag = child.tagName.toLowerCase();\n const isItem = tag === 'obc-navigation-item';\n const isGroup = tag === 'obc-navigation-item-group';\n if (!isItem && !isGroup) continue;\n // Top-level rows are slotted; only treeify the main slot. Nested rows have\n // no slot attribute and always belong to their group's tree.\n if (depth === 0) {\n const slot = child.getAttribute('slot');\n if (slot !== null && slot !== 'main') continue;\n }\n const branches: TreeBranchType[] = Array.from(\n {length: depth},\n () => TreeBranchType.blank\n );\n const row = child as ObcNavigationItem | ObcNavigationItemGroup;\n row.treeMode = true;\n row.treeBranches = branches;\n if (isGroup) {\n this.assignTreeBranches(child, depth + 1);\n }\n }\n }\n\n // Reset tree mode on every descendant item/group so switching away from the\n // Tree variant restores the flat rendering.\n private clearTreeMode(el: Element): void {\n for (const child of el.children) {\n const tag = child.tagName.toLowerCase();\n const isItem = tag === 'obc-navigation-item';\n const isGroup = tag === 'obc-navigation-item-group';\n if (!isItem && !isGroup) continue;\n const row = child as ObcNavigationItem | ObcNavigationItemGroup;\n row.treeMode = false;\n row.treeBranches = [];\n if (isGroup) {\n this.clearTreeMode(child);\n }\n }\n }\n\n private setupItems() {\n if (this.variant === ObcNavigationMenuVariant.Tree) {\n this.assignTreeBranches(this, 0);\n // Footer and logo are not part of the tree — keep them as flat full-variant\n // items (and clear any tree mode left over from the main slot's walk).\n (['footer', 'logo'] as const).forEach((slot) => {\n this.findAllItems(this, slot).forEach((item) => {\n item.treeMode = false;\n item.treeBranches = [];\n item.variant = ObcNavigationMenuVariant.Full;\n });\n });\n // Defer so the rows' inline tree-item headers exist before the roving\n // tabindex is assigned to them.\n queueMicrotask(() => this.treeNavigator.refresh());\n return;\n }\n\n this.clearTreeMode(this);\n\n const hug =\n this.variant !== ObcNavigationMenuVariant.Full ||\n this.flyoutVariant === ObcNavigationMenuFlyoutVariant.Compact;\n this.setHugToGroups(this, hug);\n\n // Set variant to all groups (top-level)\n const groups = this.findAllGroups(this);\n groups.forEach((group) => {\n group.variant = this.variant;\n // But for flyout children, force variant to full\n this.setVariantToFlyoutItems(group);\n });\n\n // Set variant to all root items (not in group)\n this.findRootItems(this).forEach((item) => {\n item.variant = this.variant;\n });\n\n // Footer and logo logic (same as before)\n const footerVariant =\n this.smallScreen && this.variant === ObcNavigationMenuVariant.Full\n ? ObcNavigationMenuVariant.Compact\n : this.variant;\n this.findAllItems(this, 'footer').forEach((item) => {\n item.variant = footerVariant;\n });\n this.findAllItems(this, 'logo').forEach((item) => {\n item.variant = footerVariant;\n });\n\n // Close all groups on item click (unchanged)\n this.findAllItems(this).forEach((item) => {\n item.addEventListener('click', () => {\n this.closeAllGroups();\n });\n });\n }\n\n private setHugToGroups(el: Element, hug: boolean) {\n const groups = this.findAllGroups(el);\n groups.forEach((group) => {\n group.hug = hug;\n this.setHugToGroups(group, hug);\n });\n }\n\n override render() {\n return html`\n <div\n class=\"wrapper ${this.variant} ${\n this.smallScreen ? 'small-screen' : ''\n }\"\n >\n <nav class=\"main\">\n <ol>\n <slot name=\"main\" @slotchange=${this.handleSlotChange}></slot>\n </ol>\n </nav>\n <div class=\"footer ${this.hasFooter ? 'has-footer' : ''}\">\n <nav>\n <ol>\n <slot name=\"footer\" @slotchange=${this.handleSlotChange}></slot>\n ${this.smallScreen ? html` <slot name=\"logo\"></slot> ` : nothing}\n </ol>\n </nav>\n ${\n this.smallScreen\n ? nothing\n : html`\n <div class=\"logo\">\n <slot name=\"logo\"></slot>\n </div>\n `\n }\n </div>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-navigation-menu': ObcNavigationMenu;\n }\n}\n"],"names":["ObcNavigationMenuVariant","ObcNavigationMenuFlyoutVariant"],"mappings":"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"}
1
+ {"version":3,"file":"navigation-menu.js","sources":["../../../src/components/navigation-menu/navigation-menu.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, nothing, unsafeCSS} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport compentStyle from './navigation-menu.css?inline';\nimport {ObcNavigationItemGroup} from '../navigation-item-group/navigation-item-group.js';\nimport {ObcNavigationItem} from '../navigation-item/navigation-item.js';\nimport {customElement} from '../../decorator.js';\nimport {\n ObcTreeNavigationItem,\n TreeBranchType,\n} from '../tree-navigation-item/tree-navigation-item.js';\nimport {\n TreeRovingNavigator,\n TreeRovingAdapter,\n} from '../../internal/tree-roving-navigator.js';\nimport {PopoverController} from '../../internal/popover-controller.js';\n\n/** A nav-menu tree row is either a navigation item or a navigation item group. */\ntype NavTreeRow = ObcNavigationItem | ObcNavigationItemGroup;\n\nconst NAV_ITEM_TAG = 'obc-navigation-item';\nconst NAV_GROUP_TAG = 'obc-navigation-item-group';\n\nfunction isNavGroup(el: Element): el is ObcNavigationItemGroup {\n return el.tagName.toLowerCase() === NAV_GROUP_TAG;\n}\n\nfunction isNavRow(el: Element): el is NavTreeRow {\n const tag = el.tagName.toLowerCase();\n return tag === NAV_ITEM_TAG || tag === NAV_GROUP_TAG;\n}\n\n/**\n * `ObcNavigationMenuVariant` – Enumerates the available visual and behavioral variants for `<obc-navigation-menu>`.\n *\n * - `Full`: Standard navigation menu with both icons and labels.\n * - `IconOnly`: Compact menu showing only icons (should only be used when no flyouts/submenus are present).\n * - `IconOnlyLarge`: Icon-only menu variant designed for use when flyouts/submenus are present.\n * - `Compact`: Space-saving menu with reduced padding and layout.\n * - `Tree`: Hierarchical tree — groups expand inline and rows are indented by depth.\n *\n * Use these variants to adapt the navigation menu to different layouts or device sizes.\n */\nexport enum ObcNavigationMenuVariant {\n Full = 'full',\n IconOnly = 'icon-only', // Should only be used when no flyouts are present in the navigation menu\n IconOnlyLarge = 'icon-only-large', // Should be used when flyouts are present in the navigation menu\n Compact = 'compact',\n Tree = 'tree',\n}\n\n/**\n * `ObcNavigationMenuFlyoutVariant` – Enumerates the available visual and behavioral variants for the flyout.\n *\n * - `Full`: Standard navigation flyout that takes the full height.\n * - `Compact`: Space-saving menu with reduced padding and layout.\n *\n * Use these variants to adapt the flyout menu to different layouts or device sizes.\n */\nexport enum ObcNavigationMenuFlyoutVariant {\n Full = 'full',\n Compact = 'compact',\n}\n\n/**\n * `<obc-navigation-menu>` – A flexible, slot-based navigation menu component for organizing primary and secondary navigation items.\n *\n * This component provides a vertical navigation structure supporting groups, flyouts, and footer sections. It adapts to various layouts and device sizes via its `variant` and `smallScreen` properties. Items and groups are provided via slots, allowing for icons, labels, and nested navigation hierarchies.\n *\n * Appears as a sidebar or persistent navigation panel, supporting both icon-only and full-label modes. Designed for use as the main navigation in applications, dashboards, or any interface requiring structured navigation.\n *\n * ## Features\n *\n * - **Variants:**\n * - **Full:** Displays both icons and labels for all navigation items (default).\n * - **IconOnly:** Shows only icons for a compact appearance. *Should only be used when no navigation items have sub-items or flyouts.*\n * - **IconOnlyLarge:** Icon-only mode that supports flyouts/submenus. Use when navigation contains groups or nested items.\n * - **Compact:** Reduces padding and overall width for a space-saving layout.\n * - **Tree:** Renders the same `obc-navigation-item` / `obc-navigation-item-group`\n * markup as a hierarchical tree. Groups expand inline (instead of as flyouts),\n * rows are indented by depth, multiple branches can stay open at once, and the\n * tree-row presentation (alert badges, terminal marker) is available via the\n * items' `alerts`/`terminalType` properties.\n * - **Responsive Layout:**\n * - `smallScreen` property adapts the footer and logo layout for smaller viewports.\n * - **Slot-based Content:**\n * - `main` slot for primary navigation items and groups.\n * - `footer` slot for secondary actions or links.\n * - `logo` slot for branding or logo placement (position adapts based on variant and screen size).\n * - **Nested Navigation:**\n * - Supports nested groups and flyouts via `<obc-navigation-item-group>`.\n * - **Automatic Variant Propagation:**\n * - Child items and groups automatically receive the correct variant for consistent appearance.\n * - **Dynamic Content Handling:**\n * - Reacts to dynamic addition/removal of items and groups, updating layout and variants as needed.\n * - **Interaction:**\n * - Clicking a navigation item closes all open groups/flyouts for streamlined navigation.\n *\n * ## Usage Guidelines\n *\n * Use `<obc-navigation-menu>` as the main navigation container in your application layout. Place navigation items and groups in the `main` slot for primary navigation, and use the `footer` slot for secondary actions (such as settings or help). The `logo` slot is intended for branding and is positioned according to the selected variant and screen size.\n *\n * - Use the `Full` variant for standard navigation with both icons and labels.\n * - Use `IconOnly` only when there are no nested groups or flyouts; otherwise, use `IconOnlyLarge` for icon-only navigation with flyout support.\n * - The `Compact` variant is suitable for layouts with limited space or when a minimal navigation appearance is desired.\n * - Use the `Tree` variant for hierarchical navigation (file trees, nested\n * sections). The existing item/group markup is reused unchanged — only the\n * `variant` changes. Footer and logo slots remain flat. Mark a group with\n * `defaultOpen` to have it start expanded.\n * - Set `smallScreen` to `true` to optimize the layout for smaller devices or responsive breakpoints.\n *\n * **TODO(designer):** Provide additional guidance on when to use each variant and recommended slot content for best usability.\n *\n * ## Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |-----------|----------------|---------|\n * | main | Always | Primary navigation items and groups. |\n * | footer | Always | Secondary navigation items (e.g., settings, help). |\n * | logo | Always | Branding/logo area (position varies by variant and screen size). |\n *\n * Place `<obc-navigation-item>`, `<obc-navigation-item-group>`, or other suitable elements in these slots. For icons, use `<obi-placeholder>`, `<obi-applications>`, or other OpenBridge icon components in the `icon` slot of each navigation item.\n *\n * ## Properties\n *\n * - `variant` (`ObcNavigationMenuVariant`): Controls the visual style and layout of the menu. Default is `Full`.\n * - `smallScreen` (`boolean`): When `true`, adapts the layout for small screens (e.g., moves logo into the footer area).\n *\n * ## Best Practices and Constraints\n *\n * - Only use the `IconOnly` variant when there are no navigation items with sub-items or flyouts. Use `IconOnlyLarge` if your navigation includes groups or nested items.\n * - Place only navigation-related components in the `main` and `footer` slots for clarity and accessibility.\n * - For best accessibility, ensure each navigation item has a clear label and, if using icons, a suitable `aria-label` or accessible name.\n * - Avoid placing interactive elements other than navigation items/groups in the `main` or `footer` slots.\n *\n * ## Example\n *\n * ```html\n * <obc-navigation-menu variant=\"full\">\n * <obc-navigation-item-group slot=\"main\" label=\"Apps\">\n * <obi-applications slot=\"icon\"></obi-applications>\n * <obc-navigation-item label=\"Sub item 1\" hasIcon href=\"#\">\n * <obi-placeholder slot=\"icon\"></obi-placeholder>\n * </obc-navigation-item>\n * </obc-navigation-item-group>\n * <obc-navigation-item slot=\"footer\" label=\"Settings\" hasIcon href=\"#\">\n * <obi-settings-iec slot=\"icon\"></obi-settings-iec>\n * </obc-navigation-item>\n * <obc-vendor-button imageSrc=\"/companylogo-day.png\" alt=\"logo\" slot=\"logo\"></obc-vendor-button>\n * </obc-navigation-menu>\n * ```\n *\n * In this example, the menu displays a group with sub-items in the main navigation, several footer actions, and a logo.\n *\n * @property flyoutVariant - Visual variant of the flyout.\n * One of `Full` (default) or `Compact`.\n * @availableWhen flyoutVariant variant==Full\n * @property smallScreen - When `true`, adapts the layout for small screens (e.g., moves logo into the footer area and adjusts item layout).\n * @property variant - Visual style and layout: `full` (default) shows icons and labels,\n * `icon-only` is the compact icon-only menu and takes no flyouts or groups,\n * `icon-only-large` is the icon-only menu that does, `compact` is the\n * space-saving menu, and `tree` expands groups inline and indents rows by\n * depth.\n * @property softDismiss - Let the browser close this menu on its own: on a click outside it, on `Escape`, or when another menu opens. Leave it off to keep showing and hiding the menu yourself.\n * @property open - Whether the menu is showing.\n * @availableWhen open softDismiss==true\n * @slot main - Slot for primary navigation items and groups.\n * @slot footer - Slot for secondary navigation items (e.g., settings, help).\n * @slot logo - Slot for branding/logo area.\n * @fires {CustomEvent<void>} close - Fired when the menu closed on its own, from a click outside, `Escape`, or another menu opening. `open` is already `false` by the time it arrives.\n * @stable\n */\n@customElement('obc-navigation-menu')\nexport class ObcNavigationMenu extends LitElement {\n @property({type: Boolean}) softDismiss = false;\n\n @property({type: Boolean}) open = false;\n\n protected readonly softDismissController = new PopoverController(this);\n\n @property({type: String}) variant: ObcNavigationMenuVariant =\n ObcNavigationMenuVariant.Full;\n\n @property({type: String}) flyoutVariant: ObcNavigationMenuFlyoutVariant =\n ObcNavigationMenuFlyoutVariant.Full;\n\n @property({type: Boolean}) smallScreen = false;\n\n private slotObservers: MutationObserver[] = [];\n @state() private hasFooter = false;\n\n /**\n * Roving-tabindex + arrow-key navigation for the Tree variant, sharing the\n * navigator that drives `obc-tree-navigation`. Engaged only while\n * `variant === Tree` (see `onTreeKeydown`).\n */\n private readonly treeNavigator = new TreeRovingNavigator<NavTreeRow>({\n getRows: () => this.treeRootRows(),\n childRows: (row) => this.treeChildRows(row),\n isGroup: (row) => isNavGroup(row),\n // Read the group's own synchronous open state, not the shadow header's\n // attribute (which lags a render tick behind a keyboard expand/collapse).\n isExpanded: (row) => isNavGroup(row) && row.expanded,\n setExpanded: (row, expanded) => {\n if (!isNavGroup(row)) return;\n if (expanded) row.open();\n else row.close();\n },\n innerItem: (row) => this.treeInnerItem(row),\n } satisfies TreeRovingAdapter<NavTreeRow>);\n\n /** Top-level tree rows of the main slot (mirrors `assignTreeBranches`'s filter). */\n private treeRootRows(): NavTreeRow[] {\n return Array.from(this.children).filter((child): child is NavTreeRow => {\n if (!isNavRow(child)) return false;\n const slot = child.getAttribute('slot');\n return slot === null || slot === 'main';\n });\n }\n\n /** Direct tree-row children of a row, in document order. */\n private treeChildRows(row: NavTreeRow): NavTreeRow[] {\n return Array.from(row.children).filter(isNavRow);\n }\n\n /** The inline `obc-tree-navigation-item` a tree-mode row renders in its shadow root. */\n private treeInnerItem(row: NavTreeRow): ObcTreeNavigationItem | null {\n return (\n row.shadowRoot?.querySelector<ObcTreeNavigationItem>(\n 'obc-tree-navigation-item'\n ) ?? null\n );\n }\n\n private onTreeKeydown = (event: KeyboardEvent): void => {\n if (this.variant !== ObcNavigationMenuVariant.Tree) return;\n if (this.treeNavigator.handleKeydown(event)) event.preventDefault();\n };\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('keydown', this.onTreeKeydown);\n }\n\n findAllElements<T extends Element>(\n el: Element,\n tag: string,\n {\n slot,\n stopTag,\n }: {\n slot?: 'main' | 'footer' | 'logo';\n stopTag?: string;\n } = {}\n ): T[] {\n const elements: T[] = [];\n for (const child of el.children) {\n if (child.tagName.toLowerCase() === tag) {\n if (slot && child.getAttribute('slot') !== slot) {\n continue;\n }\n elements.push(child as T);\n } else if (stopTag && child.tagName.toLowerCase() === stopTag) {\n continue;\n } else {\n if (slot && child.getAttribute('slot') !== slot) {\n continue;\n }\n elements.push(...this.findAllElements<T>(child, tag, {stopTag}));\n }\n }\n return elements;\n }\n\n findAllGroups(el: Element): ObcNavigationItemGroup[] {\n // Find all groups that are not in a group\n return this.findAllElements<ObcNavigationItemGroup>(\n el,\n 'obc-navigation-item-group'\n );\n }\n\n findRootItems(el: Element): ObcNavigationItem[] {\n // Find all items that are not in a group or in an item\n return this.findAllElements<ObcNavigationItem>(el, 'obc-navigation-item', {\n stopTag: 'obc-navigation-item-group',\n });\n }\n\n findAllItems(\n el: Element,\n slot?: 'main' | 'footer' | 'logo'\n ): ObcNavigationItem[] {\n return this.findAllElements<ObcNavigationItem>(el, 'obc-navigation-item', {\n slot,\n });\n }\n\n closeAllGroups() {\n const groups = this.findAllGroups(this);\n groups.forEach((group) => {\n group.close();\n });\n }\n\n registerGroup(groups: ObcNavigationItemGroup[]) {\n groups.forEach((group) => {\n group.addEventListener('open', () => {\n if (this.variant === ObcNavigationMenuVariant.Tree) return;\n groups.forEach((g) => {\n if (g !== group) {\n g.close();\n }\n });\n });\n const subGroups = this.findAllGroups(group);\n this.registerGroup(subGroups);\n });\n }\n\n private cleanupSlotObservers() {\n this.slotObservers.forEach((observer) => observer.disconnect());\n this.slotObservers = [];\n }\n\n private setupSlotObservers() {\n this.cleanupSlotObservers();\n\n const mainSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"main\"]'\n ) as HTMLSlotElement;\n const footerSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"footer\"]'\n ) as HTMLSlotElement;\n\n this.hasFooter = footerSlot?.assignedElements().length > 0;\n\n [mainSlot, footerSlot].forEach((slot) => {\n if (slot) {\n const slottedElements = slot.assignedElements();\n slottedElements.forEach((element) => {\n const observer = new MutationObserver(() => {\n this.setupItems();\n });\n\n observer.observe(element, {\n childList: true,\n subtree: true,\n });\n\n this.slotObservers.push(observer);\n });\n }\n });\n }\n\n protected override firstUpdated(_changedProperties: PropertyValues): void {\n super.firstUpdated(_changedProperties);\n const groups = this.findAllGroups(this);\n this.registerGroup(groups);\n }\n\n protected override updated(_changedProperties: PropertyValues): void {\n super.updated(_changedProperties);\n if (\n _changedProperties.has('variant') ||\n _changedProperties.has('flyoutVariant')\n ) {\n this.setupItems();\n }\n }\n\n // Recursively set variant for children of groups\n private setVariantToFlyoutItems(el: Element) {\n // Find all descendant items inside this element (not direct children of the nav menu)\n const items = this.findAllElements<ObcNavigationItem>(\n el,\n 'obc-navigation-item'\n );\n items.forEach((item) => {\n item.variant = ObcNavigationMenuVariant.Full;\n });\n\n const groups = this.findAllGroups(el);\n groups.forEach((group) => {\n group.variant = ObcNavigationMenuVariant.Full;\n this.setVariantToFlyoutItems(group);\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.cleanupSlotObservers();\n this.removeEventListener('keydown', this.onTreeKeydown);\n }\n\n private handleSlotChange() {\n this.setupItems();\n this.setupSlotObservers();\n }\n\n private assignTreeBranches(el: Element, depth: number): void {\n for (const child of el.children) {\n const tag = child.tagName.toLowerCase();\n const isItem = tag === 'obc-navigation-item';\n const isGroup = tag === 'obc-navigation-item-group';\n if (!isItem && !isGroup) continue;\n // Top-level rows are slotted; only treeify the main slot. Nested rows have\n // no slot attribute and always belong to their group's tree.\n if (depth === 0) {\n const slot = child.getAttribute('slot');\n if (slot !== null && slot !== 'main') continue;\n }\n const branches: TreeBranchType[] = Array.from(\n {length: depth},\n () => TreeBranchType.blank\n );\n const row = child as ObcNavigationItem | ObcNavigationItemGroup;\n row.treeMode = true;\n row.treeBranches = branches;\n if (isGroup) {\n this.assignTreeBranches(child, depth + 1);\n }\n }\n }\n\n // Reset tree mode on every descendant item/group so switching away from the\n // Tree variant restores the flat rendering.\n private clearTreeMode(el: Element): void {\n for (const child of el.children) {\n const tag = child.tagName.toLowerCase();\n const isItem = tag === 'obc-navigation-item';\n const isGroup = tag === 'obc-navigation-item-group';\n if (!isItem && !isGroup) continue;\n const row = child as ObcNavigationItem | ObcNavigationItemGroup;\n row.treeMode = false;\n row.treeBranches = [];\n if (isGroup) {\n this.clearTreeMode(child);\n }\n }\n }\n\n private setupItems() {\n if (this.variant === ObcNavigationMenuVariant.Tree) {\n this.assignTreeBranches(this, 0);\n // Footer and logo are not part of the tree — keep them as flat full-variant\n // items (and clear any tree mode left over from the main slot's walk).\n (['footer', 'logo'] as const).forEach((slot) => {\n this.findAllItems(this, slot).forEach((item) => {\n item.treeMode = false;\n item.treeBranches = [];\n item.variant = ObcNavigationMenuVariant.Full;\n });\n });\n // Defer so the rows' inline tree-item headers exist before the roving\n // tabindex is assigned to them.\n queueMicrotask(() => this.treeNavigator.refresh());\n return;\n }\n\n this.clearTreeMode(this);\n\n const hug =\n this.variant !== ObcNavigationMenuVariant.Full ||\n this.flyoutVariant === ObcNavigationMenuFlyoutVariant.Compact;\n this.setHugToGroups(this, hug);\n\n // Set variant to all groups (top-level)\n const groups = this.findAllGroups(this);\n groups.forEach((group) => {\n group.variant = this.variant;\n // But for flyout children, force variant to full\n this.setVariantToFlyoutItems(group);\n });\n\n // Set variant to all root items (not in group)\n this.findRootItems(this).forEach((item) => {\n item.variant = this.variant;\n });\n\n // Footer and logo logic (same as before)\n const footerVariant =\n this.smallScreen && this.variant === ObcNavigationMenuVariant.Full\n ? ObcNavigationMenuVariant.Compact\n : this.variant;\n this.findAllItems(this, 'footer').forEach((item) => {\n item.variant = footerVariant;\n });\n this.findAllItems(this, 'logo').forEach((item) => {\n item.variant = footerVariant;\n });\n\n // Close all groups on item click (unchanged)\n this.findAllItems(this).forEach((item) => {\n item.addEventListener('click', () => {\n this.closeAllGroups();\n });\n });\n }\n\n private setHugToGroups(el: Element, hug: boolean) {\n const groups = this.findAllGroups(el);\n groups.forEach((group) => {\n group.hug = hug;\n this.setHugToGroups(group, hug);\n });\n }\n\n override render() {\n return html`\n <div\n class=\"wrapper ${this.variant} ${\n this.smallScreen ? 'small-screen' : ''\n }\"\n >\n <nav class=\"main\">\n <ol>\n <slot name=\"main\" @slotchange=${this.handleSlotChange}></slot>\n </ol>\n </nav>\n <div class=\"footer ${this.hasFooter ? 'has-footer' : ''}\">\n <nav>\n <ol>\n <slot name=\"footer\" @slotchange=${this.handleSlotChange}></slot>\n ${this.smallScreen ? html` <slot name=\"logo\"></slot> ` : nothing}\n </ol>\n </nav>\n ${\n this.smallScreen\n ? nothing\n : html`\n <div class=\"logo\">\n <slot name=\"logo\"></slot>\n </div>\n `\n }\n </div>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-navigation-menu': ObcNavigationMenu;\n }\n}\n"],"names":["ObcNavigationMenuVariant","ObcNavigationMenuFlyoutVariant"],"mappings":"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"}