@oicl/openbridge-webcomponents 2.0.0-next.59 → 2.0.0-next.60

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 (42) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +5557 -4305
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +1204 -25
  4. package/dist/components/navigation-item/navigation-item.css.js +5 -0
  5. package/dist/components/navigation-item/navigation-item.css.js.map +1 -1
  6. package/dist/components/navigation-item/navigation-item.d.ts +18 -0
  7. package/dist/components/navigation-item/navigation-item.d.ts.map +1 -1
  8. package/dist/components/navigation-item/navigation-item.js +49 -1
  9. package/dist/components/navigation-item/navigation-item.js.map +1 -1
  10. package/dist/components/navigation-item-group/navigation-item-group.css.js +8 -0
  11. package/dist/components/navigation-item-group/navigation-item-group.css.js.map +1 -1
  12. package/dist/components/navigation-item-group/navigation-item-group.d.ts +22 -0
  13. package/dist/components/navigation-item-group/navigation-item-group.d.ts.map +1 -1
  14. package/dist/components/navigation-item-group/navigation-item-group.js +63 -1
  15. package/dist/components/navigation-item-group/navigation-item-group.js.map +1 -1
  16. package/dist/components/navigation-menu/navigation-menu.d.ts +29 -1
  17. package/dist/components/navigation-menu/navigation-menu.d.ts.map +1 -1
  18. package/dist/components/navigation-menu/navigation-menu.js +105 -0
  19. package/dist/components/navigation-menu/navigation-menu.js.map +1 -1
  20. package/dist/components/tree-navigation/tree-navigation.css.js +18 -0
  21. package/dist/components/tree-navigation/tree-navigation.css.js.map +1 -0
  22. package/dist/components/tree-navigation/tree-navigation.d.ts +74 -0
  23. package/dist/components/tree-navigation/tree-navigation.d.ts.map +1 -0
  24. package/dist/components/tree-navigation/tree-navigation.js +120 -0
  25. package/dist/components/tree-navigation/tree-navigation.js.map +1 -0
  26. package/dist/components/tree-navigation-group/tree-navigation-group.css.js +22 -0
  27. package/dist/components/tree-navigation-group/tree-navigation-group.css.js.map +1 -0
  28. package/dist/components/tree-navigation-group/tree-navigation-group.d.ts +94 -0
  29. package/dist/components/tree-navigation-group/tree-navigation-group.d.ts.map +1 -0
  30. package/dist/components/tree-navigation-group/tree-navigation-group.js +116 -0
  31. package/dist/components/tree-navigation-group/tree-navigation-group.js.map +1 -0
  32. package/dist/components/tree-navigation-item/tree-navigation-item.css.js +429 -0
  33. package/dist/components/tree-navigation-item/tree-navigation-item.css.js.map +1 -0
  34. package/dist/components/tree-navigation-item/tree-navigation-item.d.ts +160 -0
  35. package/dist/components/tree-navigation-item/tree-navigation-item.d.ts.map +1 -0
  36. package/dist/components/tree-navigation-item/tree-navigation-item.js +208 -0
  37. package/dist/components/tree-navigation-item/tree-navigation-item.js.map +1 -0
  38. package/dist/internal/tree-roving-navigator.d.ts +71 -0
  39. package/dist/internal/tree-roving-navigator.d.ts.map +1 -0
  40. package/dist/internal/tree-roving-navigator.js +172 -0
  41. package/dist/internal/tree-roving-navigator.js.map +1 -0
  42. package/package.json +1 -1
@@ -2,6 +2,8 @@ import { unsafeCSS, LitElement, nothing, html } from "lit";
2
2
  import { property, state } from "lit/decorators.js";
3
3
  import compentStyle from "./navigation-menu.css.js";
4
4
  import { customElement } from "../../decorator.js";
5
+ import { TreeBranchType } from "../tree-navigation-item/tree-navigation-item.js";
6
+ import { TreeRovingNavigator } from "../../internal/tree-roving-navigator.js";
5
7
  var __defProp = Object.defineProperty;
6
8
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
9
  var __decorateClass = (decorators, target, key, kind) => {
@@ -12,11 +14,21 @@ var __decorateClass = (decorators, target, key, kind) => {
12
14
  if (kind && result) __defProp(target, key, result);
13
15
  return result;
14
16
  };
17
+ const NAV_ITEM_TAG = "obc-navigation-item";
18
+ const NAV_GROUP_TAG = "obc-navigation-item-group";
19
+ function isNavGroup(el) {
20
+ return el.tagName.toLowerCase() === NAV_GROUP_TAG;
21
+ }
22
+ function isNavRow(el) {
23
+ const tag = el.tagName.toLowerCase();
24
+ return tag === NAV_ITEM_TAG || tag === NAV_GROUP_TAG;
25
+ }
15
26
  var ObcNavigationMenuVariant = /* @__PURE__ */ ((ObcNavigationMenuVariant2) => {
16
27
  ObcNavigationMenuVariant2["Full"] = "full";
17
28
  ObcNavigationMenuVariant2["IconOnly"] = "icon-only";
18
29
  ObcNavigationMenuVariant2["IconOnlyLarge"] = "icon-only-large";
19
30
  ObcNavigationMenuVariant2["Compact"] = "compact";
31
+ ObcNavigationMenuVariant2["Tree"] = "tree";
20
32
  return ObcNavigationMenuVariant2;
21
33
  })(ObcNavigationMenuVariant || {});
22
34
  var ObcNavigationMenuFlyoutVariant = /* @__PURE__ */ ((ObcNavigationMenuFlyoutVariant2) => {
@@ -32,6 +44,46 @@ let ObcNavigationMenu = class extends LitElement {
32
44
  this.smallScreen = false;
33
45
  this.slotObservers = [];
34
46
  this.hasFooter = false;
47
+ this.treeNavigator = new TreeRovingNavigator(this, {
48
+ getRows: () => this.treeRootRows(),
49
+ childRows: (row) => this.treeChildRows(row),
50
+ isGroup: (row) => isNavGroup(row),
51
+ // Read the group's own synchronous open state, not the shadow header's
52
+ // attribute (which lags a render tick behind a keyboard expand/collapse).
53
+ isExpanded: (row) => isNavGroup(row) && row.expanded,
54
+ setExpanded: (row, expanded) => {
55
+ if (!isNavGroup(row)) return;
56
+ if (expanded) row.open();
57
+ else row.close();
58
+ },
59
+ innerItem: (row) => this.treeInnerItem(row)
60
+ });
61
+ this.onTreeKeydown = (event) => {
62
+ if (this.variant !== "tree") return;
63
+ if (this.treeNavigator.handleKeydown(event)) event.preventDefault();
64
+ };
65
+ }
66
+ /** Top-level tree rows of the main slot (mirrors `assignTreeBranches`'s filter). */
67
+ treeRootRows() {
68
+ return Array.from(this.children).filter((child) => {
69
+ if (!isNavRow(child)) return false;
70
+ const slot = child.getAttribute("slot");
71
+ return slot === null || slot === "main";
72
+ });
73
+ }
74
+ /** Direct tree-row children of a row, in document order. */
75
+ treeChildRows(row) {
76
+ return Array.from(row.children).filter(isNavRow);
77
+ }
78
+ /** The inline `obc-tree-navigation-item` a tree-mode row renders in its shadow root. */
79
+ treeInnerItem(row) {
80
+ return row.shadowRoot?.querySelector(
81
+ "obc-tree-navigation-item"
82
+ ) ?? null;
83
+ }
84
+ connectedCallback() {
85
+ super.connectedCallback();
86
+ this.addEventListener("keydown", this.onTreeKeydown);
35
87
  }
36
88
  findAllElements(el, tag, {
37
89
  slot,
@@ -80,6 +132,7 @@ let ObcNavigationMenu = class extends LitElement {
80
132
  registerGroup(groups) {
81
133
  groups.forEach((group) => {
82
134
  group.addEventListener("open", () => {
135
+ if (this.variant === "tree") return;
83
136
  groups.forEach((g) => {
84
137
  if (g !== group) {
85
138
  g.close();
@@ -148,12 +201,64 @@ let ObcNavigationMenu = class extends LitElement {
148
201
  disconnectedCallback() {
149
202
  super.disconnectedCallback();
150
203
  this.cleanupSlotObservers();
204
+ this.removeEventListener("keydown", this.onTreeKeydown);
151
205
  }
152
206
  handleSlotChange() {
153
207
  this.setupItems();
154
208
  this.setupSlotObservers();
155
209
  }
210
+ assignTreeBranches(el, depth) {
211
+ for (const child of el.children) {
212
+ const tag = child.tagName.toLowerCase();
213
+ const isItem = tag === "obc-navigation-item";
214
+ const isGroup = tag === "obc-navigation-item-group";
215
+ if (!isItem && !isGroup) continue;
216
+ if (depth === 0) {
217
+ const slot = child.getAttribute("slot");
218
+ if (slot !== null && slot !== "main") continue;
219
+ }
220
+ const branches = Array.from(
221
+ { length: depth },
222
+ () => TreeBranchType.blank
223
+ );
224
+ const row = child;
225
+ row.treeMode = true;
226
+ row.treeBranches = branches;
227
+ if (isGroup) {
228
+ this.assignTreeBranches(child, depth + 1);
229
+ }
230
+ }
231
+ }
232
+ // Reset tree mode on every descendant item/group so switching away from the
233
+ // Tree variant restores the flat rendering.
234
+ clearTreeMode(el) {
235
+ for (const child of el.children) {
236
+ const tag = child.tagName.toLowerCase();
237
+ const isItem = tag === "obc-navigation-item";
238
+ const isGroup = tag === "obc-navigation-item-group";
239
+ if (!isItem && !isGroup) continue;
240
+ const row = child;
241
+ row.treeMode = false;
242
+ row.treeBranches = [];
243
+ if (isGroup) {
244
+ this.clearTreeMode(child);
245
+ }
246
+ }
247
+ }
156
248
  setupItems() {
249
+ if (this.variant === "tree") {
250
+ this.assignTreeBranches(this, 0);
251
+ ["footer", "logo"].forEach((slot) => {
252
+ this.findAllItems(this, slot).forEach((item) => {
253
+ item.treeMode = false;
254
+ item.treeBranches = [];
255
+ item.variant = "full";
256
+ });
257
+ });
258
+ queueMicrotask(() => this.treeNavigator.refresh());
259
+ return;
260
+ }
261
+ this.clearTreeMode(this);
157
262
  const hug = this.variant !== "full" || this.flyoutVariant === "compact";
158
263
  this.setHugToGroups(this, hug);
159
264
  const groups = this.findAllGroups(this);
@@ -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';\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 *\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}\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 * - **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 * - 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 * @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 */\n@customElement('obc-navigation-menu')\nexport class ObcNavigationMenu extends LitElement {\n /**\n * Controls the visual style and layout of the navigation menu.\n *\n * - `full`: Standard menu with icons and labels (default).\n * - `icon-only`: Compact, icon-only menu (use only when no flyouts/groups are present).\n * - `icon-only-large`: Icon-only menu supporting flyouts/groups.\n * - `compact`: Minimal, space-saving menu.\n */\n @property({type: String}) variant: ObcNavigationMenuVariant =\n ObcNavigationMenuVariant.Full;\n\n /**\n * Visual variant of the flyout.\n * One of `Full` (default) or `Compact`.\n */\n @property({type: String}) flyoutVariant: ObcNavigationMenuFlyoutVariant =\n ObcNavigationMenuFlyoutVariant.Full;\n\n /**\n * When `true`, adapts the layout for small screens (e.g., moves logo into the footer area and adjusts item layout).\n */\n @property({type: Boolean}) smallScreen = false;\n\n private slotObservers: MutationObserver[] = [];\n @state() private hasFooter = false;\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 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 }\n\n private handleSlotChange() {\n this.setupItems();\n this.setupSlotObservers();\n }\n\n private setupItems() {\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} ${this.smallScreen\n ? '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 ${this.smallScreen\n ? nothing\n : html`\n <div class=\"logo\">\n <slot name=\"logo\"></slot>\n </div>\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';\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 badge, terminal marker) is available via the\n * items' `hasAlertBadge`/`alertCount`/`alertType`/`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 * @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 */\n@customElement('obc-navigation-menu')\nexport class ObcNavigationMenu extends LitElement {\n /**\n * Controls the visual style and layout of the navigation menu.\n *\n * - `full`: Standard menu with icons and labels (default).\n * - `icon-only`: Compact, icon-only menu (use only when no flyouts/groups are present).\n * - `icon-only-large`: Icon-only menu supporting flyouts/groups.\n * - `compact`: Minimal, space-saving menu.\n * - `tree`: Hierarchical tree — groups expand inline and rows are indented by depth.\n */\n @property({type: String}) variant: ObcNavigationMenuVariant =\n ObcNavigationMenuVariant.Full;\n\n /**\n * Visual variant of the flyout.\n * One of `Full` (default) or `Compact`.\n */\n @property({type: String}) flyoutVariant: ObcNavigationMenuFlyoutVariant =\n ObcNavigationMenuFlyoutVariant.Full;\n\n /**\n * When `true`, adapts the layout for small screens (e.g., moves logo into the footer area and adjusts item layout).\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>(this, {\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} ${this.smallScreen\n ? '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 ${this.smallScreen\n ? nothing\n : html`\n <div class=\"logo\">\n <slot name=\"logo\"></slot>\n </div>\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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"}
@@ -0,0 +1,18 @@
1
+ import { css } from "lit";
2
+ const componentStyle = css`
3
+ * {
4
+ -webkit-tap-highlight-color: transparent;
5
+ }
6
+
7
+ :host {
8
+ display: block;
9
+ }
10
+
11
+ [role="tree"] {
12
+ display: block;
13
+ }
14
+ `;
15
+ export {
16
+ componentStyle as default
17
+ };
18
+ //# sourceMappingURL=tree-navigation.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-navigation.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;"}
@@ -0,0 +1,74 @@
1
+ import { LitElement } from 'lit';
2
+ import '../tree-navigation-group/tree-navigation-group.js';
3
+ /**
4
+ * `<obc-tree-navigation>` – The container for a tree- or file-explorer-style
5
+ * navigation list. Holds nested `<obc-tree-navigation-group>` and
6
+ * `<obc-tree-navigation-item>` rows and computes each row's indentation guide
7
+ * lines automatically from its position in the hierarchy.
8
+ *
9
+ * Consumers write the tree as plain nested markup; the container assigns every
10
+ * row's `branches` array so the guide lines (pass-through verticals, elbows, and
11
+ * the last-child corner) connect correctly — there is no need to compute depth or
12
+ * branch types by hand. It re-derives the guides whenever rows are added, removed,
13
+ * or groups expand and collapse.
14
+ *
15
+ * ## Features
16
+ * - **Automatic guide lines:** Each row receives a `branches` array derived from
17
+ * its depth and whether each ancestor still has siblings below it. Last children
18
+ * get a corner (`└`); rows with siblings below get an intersection (`├`); and
19
+ * ancestor columns become a pass-through (`│`) or blank as appropriate.
20
+ * - **Live updates:** Reacts to slotted content changes and to group expand state,
21
+ * recomputing the guides so they always match the visible structure.
22
+ * - **Composable:** Works with any nesting depth of groups and items.
23
+ *
24
+ * ## Usage Guidelines
25
+ * - Use as the root of a hierarchical navigation list. For flat navigation, use
26
+ * `obc-navigation-menu` instead.
27
+ * - Place `<obc-tree-navigation-group>` for expandable parents and
28
+ * `<obc-tree-navigation-item>` for leaves; nest groups to any depth.
29
+ * - Do not set each row's `branches` manually — the container manages them.
30
+ *
31
+ * ## Slots
32
+ *
33
+ * | Slot Name | Renders When... | Purpose |
34
+ * |-----------|-----------------|----------------------------------------------------|
35
+ * | (default) | Always | Top-level rows (`obc-tree-navigation-group`/`-item`). |
36
+ *
37
+ * @slot - Top-level tree rows (groups and items).
38
+ */
39
+ export declare class ObcTreeNavigation extends LitElement {
40
+ private mutationObserver?;
41
+ /** The focusable header item for a row: a leaf is itself; a group's is its shadow header. */
42
+ private innerItem;
43
+ private readonly navigator;
44
+ connectedCallback(): void;
45
+ private onKeydown;
46
+ disconnectedCallback(): void;
47
+ private onExpandToggle;
48
+ firstUpdated(): void;
49
+ /** Direct tree-row children of an element, in document order. */
50
+ private childRows;
51
+ /**
52
+ * Walk the row tree and assign each row's `branches`. Mirrors the guide-line
53
+ * model: a row gets one column per ancestor (pass-through `straight` if that
54
+ * ancestor still has siblings below, else `blank`) followed by its own elbow
55
+ * (`corner` if it is the last child, else `intersection`). Top-level rows draw
56
+ * no columns at all.
57
+ *
58
+ * @param rows - sibling rows at this level, in order
59
+ * @param ancestorHasNextSibling - one flag per ancestor *below the root*: true
60
+ * if that ancestor has a sibling still below it (so its column is a
61
+ * pass-through), false if its subtree has ended (a blank column)
62
+ * @param depth - nesting depth; 0 for top-level rows (which draw no columns)
63
+ */
64
+ private assignBranches;
65
+ private updateBranches;
66
+ render(): import('lit-html').TemplateResult<1>;
67
+ static styles: import('lit').CSSResult;
68
+ }
69
+ declare global {
70
+ interface HTMLElementTagNameMap {
71
+ 'obc-tree-navigation': ObcTreeNavigation;
72
+ }
73
+ }
74
+ //# sourceMappingURL=tree-navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-navigation.d.ts","sourceRoot":"","sources":["../../../src/components/tree-navigation/tree-navigation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAkB,MAAM,KAAK,CAAC;AAQhD,OAAO,mDAAmD,CAAC;AAqB3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBACa,iBAAkB,SAAQ,UAAU;IAC/C,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAE5C,6FAA6F;IAC7F,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAUc;IAE/B,iBAAiB,IAAI,IAAI;IAelC,OAAO,CAAC,SAAS,CAEf;IAEO,oBAAoB,IAAI,IAAI;IAQrC,OAAO,CAAC,cAAc,CAIpB;IAEO,YAAY,IAAI,IAAI;IAI7B,iEAAiE;IACjE,OAAO,CAAC,SAAS;IAIjB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,cAAc;IAyBtB,OAAO,CAAC,cAAc;IAMb,MAAM;IAMf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,qBAAqB,EAAE,iBAAiB,CAAC;KAC1C;CACF"}
@@ -0,0 +1,120 @@
1
+ import { unsafeCSS, LitElement, html } from "lit";
2
+ import componentStyle from "./tree-navigation.css.js";
3
+ import { customElement } from "../../decorator.js";
4
+ import { TreeBranchType } from "../tree-navigation-item/tree-navigation-item.js";
5
+ import "../tree-navigation-group/tree-navigation-group.js";
6
+ import { TreeRovingNavigator } from "../../internal/tree-roving-navigator.js";
7
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
+ var __decorateClass = (decorators, target, key, kind) => {
9
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
10
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
11
+ if (decorator = decorators[i])
12
+ result = decorator(result) || result;
13
+ return result;
14
+ };
15
+ const ITEM_TAG = "obc-tree-navigation-item";
16
+ const GROUP_TAG = "obc-tree-navigation-group";
17
+ function isGroup(el) {
18
+ return el.tagName.toLowerCase() === GROUP_TAG;
19
+ }
20
+ function isRow(el) {
21
+ const tag = el.tagName.toLowerCase();
22
+ return tag === ITEM_TAG || tag === GROUP_TAG;
23
+ }
24
+ let ObcTreeNavigation = class extends LitElement {
25
+ constructor() {
26
+ super(...arguments);
27
+ this.navigator = new TreeRovingNavigator(this, {
28
+ getRows: () => this.childRows(this),
29
+ childRows: (row) => this.childRows(row),
30
+ isGroup: (row) => isGroup(row),
31
+ isExpanded: (row) => isGroup(row) && row.hasAttribute("expanded"),
32
+ setExpanded: (row, expanded) => {
33
+ if (isGroup(row)) row.expanded = expanded;
34
+ },
35
+ innerItem: (row) => this.innerItem(row),
36
+ isDisabled: (row) => this.innerItem(row)?.hasAttribute("disabled") ?? false
37
+ });
38
+ this.onKeydown = (event) => {
39
+ if (this.navigator.handleKeydown(event)) event.preventDefault();
40
+ };
41
+ this.onExpandToggle = () => {
42
+ queueMicrotask(() => this.updateBranches());
43
+ };
44
+ }
45
+ /** The focusable header item for a row: a leaf is itself; a group's is its shadow header. */
46
+ innerItem(row) {
47
+ return isGroup(row) ? row.shadowRoot?.querySelector(ITEM_TAG) ?? null : row;
48
+ }
49
+ connectedCallback() {
50
+ super.connectedCallback();
51
+ this.mutationObserver = new MutationObserver(() => this.updateBranches());
52
+ this.mutationObserver.observe(this, {
53
+ childList: true,
54
+ subtree: true,
55
+ attributes: true,
56
+ attributeFilter: ["expanded"]
57
+ });
58
+ this.addEventListener("expand-toggle", this.onExpandToggle);
59
+ this.addEventListener("keydown", this.onKeydown);
60
+ }
61
+ disconnectedCallback() {
62
+ super.disconnectedCallback();
63
+ this.mutationObserver?.disconnect();
64
+ this.mutationObserver = void 0;
65
+ this.removeEventListener("expand-toggle", this.onExpandToggle);
66
+ this.removeEventListener("keydown", this.onKeydown);
67
+ }
68
+ firstUpdated() {
69
+ this.updateBranches();
70
+ }
71
+ /** Direct tree-row children of an element, in document order. */
72
+ childRows(el) {
73
+ return Array.from(el.children).filter(isRow);
74
+ }
75
+ /**
76
+ * Walk the row tree and assign each row's `branches`. Mirrors the guide-line
77
+ * model: a row gets one column per ancestor (pass-through `straight` if that
78
+ * ancestor still has siblings below, else `blank`) followed by its own elbow
79
+ * (`corner` if it is the last child, else `intersection`). Top-level rows draw
80
+ * no columns at all.
81
+ *
82
+ * @param rows - sibling rows at this level, in order
83
+ * @param ancestorHasNextSibling - one flag per ancestor *below the root*: true
84
+ * if that ancestor has a sibling still below it (so its column is a
85
+ * pass-through), false if its subtree has ended (a blank column)
86
+ * @param depth - nesting depth; 0 for top-level rows (which draw no columns)
87
+ */
88
+ assignBranches(rows, ancestorHasNextSibling, depth) {
89
+ rows.forEach((row, index) => {
90
+ const isLast = index === rows.length - 1;
91
+ row.branches = depth === 0 ? [] : [
92
+ ...ancestorHasNextSibling.map(
93
+ (hasNext) => hasNext ? TreeBranchType.straight : TreeBranchType.blank
94
+ ),
95
+ isLast ? TreeBranchType.corner : TreeBranchType.intersection
96
+ ];
97
+ if (isGroup(row)) {
98
+ const childAncestry = depth === 0 ? [] : [...ancestorHasNextSibling, !isLast];
99
+ this.assignBranches(this.childRows(row), childAncestry, depth + 1);
100
+ }
101
+ });
102
+ }
103
+ updateBranches() {
104
+ this.assignBranches(this.childRows(this), [], 0);
105
+ this.navigator.refresh();
106
+ }
107
+ render() {
108
+ return html`<div role="tree">
109
+ <slot @slotchange=${() => this.updateBranches()}></slot>
110
+ </div>`;
111
+ }
112
+ };
113
+ ObcTreeNavigation.styles = unsafeCSS(componentStyle);
114
+ ObcTreeNavigation = __decorateClass([
115
+ customElement("obc-tree-navigation")
116
+ ], ObcTreeNavigation);
117
+ export {
118
+ ObcTreeNavigation
119
+ };
120
+ //# sourceMappingURL=tree-navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-navigation.js","sources":["../../../src/components/tree-navigation/tree-navigation.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS} from 'lit';\nimport componentStyle from './tree-navigation.css?inline';\nimport {customElement} from '../../decorator.js';\nimport {\n ObcTreeNavigationItem,\n TreeBranchType,\n} from '../tree-navigation-item/tree-navigation-item.js';\nimport {ObcTreeNavigationGroup} from '../tree-navigation-group/tree-navigation-group.js';\nimport '../tree-navigation-group/tree-navigation-group.js';\nimport {\n TreeRovingNavigator,\n TreeRovingAdapter,\n} from '../../internal/tree-roving-navigator.js';\n\n/** A tree row is either a leaf item or an expandable group. */\ntype TreeRow = ObcTreeNavigationItem | ObcTreeNavigationGroup;\n\nconst ITEM_TAG = 'obc-tree-navigation-item';\nconst GROUP_TAG = 'obc-tree-navigation-group';\n\nfunction isGroup(el: Element): el is ObcTreeNavigationGroup {\n return el.tagName.toLowerCase() === GROUP_TAG;\n}\n\nfunction isRow(el: Element): el is TreeRow {\n const tag = el.tagName.toLowerCase();\n return tag === ITEM_TAG || tag === GROUP_TAG;\n}\n\n/**\n * `<obc-tree-navigation>` – The container for a tree- or file-explorer-style\n * navigation list. Holds nested `<obc-tree-navigation-group>` and\n * `<obc-tree-navigation-item>` rows and computes each row's indentation guide\n * lines automatically from its position in the hierarchy.\n *\n * Consumers write the tree as plain nested markup; the container assigns every\n * row's `branches` array so the guide lines (pass-through verticals, elbows, and\n * the last-child corner) connect correctly — there is no need to compute depth or\n * branch types by hand. It re-derives the guides whenever rows are added, removed,\n * or groups expand and collapse.\n *\n * ## Features\n * - **Automatic guide lines:** Each row receives a `branches` array derived from\n * its depth and whether each ancestor still has siblings below it. Last children\n * get a corner (`└`); rows with siblings below get an intersection (`├`); and\n * ancestor columns become a pass-through (`│`) or blank as appropriate.\n * - **Live updates:** Reacts to slotted content changes and to group expand state,\n * recomputing the guides so they always match the visible structure.\n * - **Composable:** Works with any nesting depth of groups and items.\n *\n * ## Usage Guidelines\n * - Use as the root of a hierarchical navigation list. For flat navigation, use\n * `obc-navigation-menu` instead.\n * - Place `<obc-tree-navigation-group>` for expandable parents and\n * `<obc-tree-navigation-item>` for leaves; nest groups to any depth.\n * - Do not set each row's `branches` manually — the container manages them.\n *\n * ## Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |-----------|-----------------|----------------------------------------------------|\n * | (default) | Always | Top-level rows (`obc-tree-navigation-group`/`-item`). |\n *\n * @slot - Top-level tree rows (groups and items).\n */\n@customElement('obc-tree-navigation')\nexport class ObcTreeNavigation extends LitElement {\n private mutationObserver?: MutationObserver;\n\n /** The focusable header item for a row: a leaf is itself; a group's is its shadow header. */\n private innerItem(row: TreeRow): ObcTreeNavigationItem | null {\n return isGroup(row)\n ? (row.shadowRoot?.querySelector<ObcTreeNavigationItem>(ITEM_TAG) ?? null)\n : row;\n }\n\n private readonly navigator = new TreeRovingNavigator<TreeRow>(this, {\n getRows: () => this.childRows(this),\n childRows: (row) => this.childRows(row),\n isGroup: (row) => isGroup(row),\n isExpanded: (row) => isGroup(row) && row.hasAttribute('expanded'),\n setExpanded: (row, expanded) => {\n if (isGroup(row)) row.expanded = expanded;\n },\n innerItem: (row) => this.innerItem(row),\n isDisabled: (row) => this.innerItem(row)?.hasAttribute('disabled') ?? false,\n } satisfies TreeRovingAdapter<TreeRow>);\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Recompute guides on any structural change: rows added/removed, or a group's\n // `expanded` attribute toggled anywhere in the subtree.\n this.mutationObserver = new MutationObserver(() => this.updateBranches());\n this.mutationObserver.observe(this, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['expanded'],\n });\n this.addEventListener('expand-toggle', this.onExpandToggle);\n this.addEventListener('keydown', this.onKeydown);\n }\n\n private onKeydown = (event: KeyboardEvent): void => {\n if (this.navigator.handleKeydown(event)) event.preventDefault();\n };\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.mutationObserver?.disconnect();\n this.mutationObserver = undefined;\n this.removeEventListener('expand-toggle', this.onExpandToggle);\n this.removeEventListener('keydown', this.onKeydown);\n }\n\n private onExpandToggle = () => {\n // Defer so the group's `expanded` attribute and slotted children reflect the\n // new state before guides are recomputed.\n queueMicrotask(() => this.updateBranches());\n };\n\n override firstUpdated(): void {\n this.updateBranches();\n }\n\n /** Direct tree-row children of an element, in document order. */\n private childRows(el: Element): TreeRow[] {\n return Array.from(el.children).filter(isRow);\n }\n\n /**\n * Walk the row tree and assign each row's `branches`. Mirrors the guide-line\n * model: a row gets one column per ancestor (pass-through `straight` if that\n * ancestor still has siblings below, else `blank`) followed by its own elbow\n * (`corner` if it is the last child, else `intersection`). Top-level rows draw\n * no columns at all.\n *\n * @param rows - sibling rows at this level, in order\n * @param ancestorHasNextSibling - one flag per ancestor *below the root*: true\n * if that ancestor has a sibling still below it (so its column is a\n * pass-through), false if its subtree has ended (a blank column)\n * @param depth - nesting depth; 0 for top-level rows (which draw no columns)\n */\n private assignBranches(\n rows: TreeRow[],\n ancestorHasNextSibling: boolean[],\n depth: number\n ): void {\n rows.forEach((row, index) => {\n const isLast = index === rows.length - 1;\n row.branches =\n depth === 0\n ? []\n : [\n ...ancestorHasNextSibling.map((hasNext) =>\n hasNext ? TreeBranchType.straight : TreeBranchType.blank\n ),\n isLast ? TreeBranchType.corner : TreeBranchType.intersection,\n ];\n\n if (isGroup(row)) {\n const childAncestry =\n depth === 0 ? [] : [...ancestorHasNextSibling, !isLast];\n this.assignBranches(this.childRows(row), childAncestry, depth + 1);\n }\n });\n }\n\n private updateBranches(): void {\n this.assignBranches(this.childRows(this), [], 0);\n // Keep the roving tabindex in lockstep with the visible structure.\n this.navigator.refresh();\n }\n\n override render() {\n return html`<div role=\"tree\">\n <slot @slotchange=${() => this.updateBranches()}></slot>\n </div>`;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-tree-navigation': ObcTreeNavigation;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { css } from "lit";
2
+ const componentStyle = css`
3
+ * {
4
+ -webkit-tap-highlight-color: transparent;
5
+ }
6
+
7
+ :host {
8
+ display: block;
9
+ }
10
+
11
+ [part="children"] {
12
+ display: block;
13
+ }
14
+
15
+ [part="children"][hidden] {
16
+ display: none;
17
+ }
18
+ `;
19
+ export {
20
+ componentStyle as default
21
+ };
22
+ //# sourceMappingURL=tree-navigation-group.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-navigation-group.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,94 @@
1
+ import { LitElement } from 'lit';
2
+ import { TreeBranchType } from '../tree-navigation-item/tree-navigation-item.js';
3
+ import '../tree-navigation-item/tree-navigation-item.js';
4
+ /**
5
+ * `<obc-tree-navigation-group>` – An expandable parent row in a tree-navigation
6
+ * structure: a header row with an expand/collapse chevron, plus a slot for the
7
+ * child rows it discloses.
8
+ *
9
+ * A group renders an `<obc-tree-navigation-item>` header (carrying its own label,
10
+ * icon, terminal type, and alert badge) followed by its slotted children. When
11
+ * placed inside `<obc-tree-navigation>`, the container computes and assigns the
12
+ * `branches` guide lines for every row automatically from each row's position —
13
+ * a group does not need its depth configured by hand.
14
+ *
15
+ * The group manages only its own open/closed state and forwards header presentation
16
+ * to its internal header item. It does not draw guide lines itself; that is the
17
+ * container's responsibility (see `<obc-tree-navigation>`).
18
+ *
19
+ * ## Features
20
+ * - **Disclosure:** A chevron in the header toggles the slotted children. The open
21
+ * state is held in `expanded` and reflected so the container and CSS can react.
22
+ * - **Header presentation:** `label`, the `icon` slot, `terminalType`, and the
23
+ * alert badge (`hasAlertBadge`, `alertCount`, `alertType`) are forwarded to the
24
+ * header row.
25
+ * - **Selection:** `checked` marks the group's header as the current item.
26
+ * - **Automatic guides:** Inside `<obc-tree-navigation>`, the header's `branches`
27
+ * are assigned by the container; nested groups continue the guide columns down.
28
+ *
29
+ * ## Usage Guidelines
30
+ * - Nest `<obc-tree-navigation-item>` (leaves) and further `<obc-tree-navigation-group>`
31
+ * elements as children to build the hierarchy.
32
+ * - Always place groups and items inside an `<obc-tree-navigation>` container so the
33
+ * guide lines are computed; using a group standalone draws a header with no guides.
34
+ * - Provide a header icon via the `icon` slot (forwarded to the header row).
35
+ *
36
+ * ## Slots
37
+ *
38
+ * | Slot Name | Renders When... | Purpose |
39
+ * |-----------|--------------------------|--------------------------------------------------------------|
40
+ * | icon | `hasIcon` is true | Leading icon for the group header row. |
41
+ * | (default) | Always | Child rows (`obc-tree-navigation-item` / `-group`). |
42
+ *
43
+ * @slot icon - Leading icon for the group header (shown when `hasIcon` is true).
44
+ * @slot - Child rows disclosed when the group is expanded.
45
+ * @fires expand-toggle {CustomEvent<boolean>} Fired when the header is activated; detail is the next `expanded` value.
46
+ */
47
+ export declare class ObcTreeNavigationGroup extends LitElement {
48
+ /** The text label displayed for the group header row. */
49
+ label: string;
50
+ /**
51
+ * Guide line to draw for each ancestor level of the header row. Normally set by
52
+ * the parent `<obc-tree-navigation>` container from the group's position; only
53
+ * set it manually when using a group outside the container.
54
+ */
55
+ branches: TreeBranchType[];
56
+ /** Whether the group is expanded, disclosing its children. Rotates the chevron. */
57
+ expanded: boolean;
58
+ /** Whether the group header is the current selection. */
59
+ checked: boolean;
60
+ /** Disables the group header, removing it from the tab order and dimming it. */
61
+ disabled: boolean;
62
+ /** Whether the group header shows a leading icon (provided via the `icon` slot). */
63
+ hasIcon: boolean;
64
+ /**
65
+ * Terminal type for the header row, controlling the alert-header marker shown in
66
+ * the terminal. One of `regular` (default), `aggregated-header`, or `group-header`.
67
+ */
68
+ terminalType: string;
69
+ /** Whether a trailing alert counter badge is shown on the header row. */
70
+ hasAlertBadge: boolean;
71
+ /** The number shown in the header's alert badge when `hasAlertBadge` is true. */
72
+ alertCount: number;
73
+ /** The severity/type of the header's alert badge. One of the `obc-badge` types (default `alarm`). */
74
+ alertType: string;
75
+ /**
76
+ * The URL to navigate to when the header is activated. If set, the header row
77
+ * renders as a link; otherwise it acts as a button.
78
+ */
79
+ href: string | undefined;
80
+ private headerItem?;
81
+ private onHeaderToggle;
82
+ /** Closes the group (and, recursively, any nested groups inside it). */
83
+ close(): void;
84
+ focus(options?: FocusOptions): void;
85
+ render(): import('lit-html').TemplateResult<1>;
86
+ static styles: import('lit').CSSResult;
87
+ }
88
+ export type ObcTreeNavigationGroupExpandToggleEvent = CustomEvent<boolean>;
89
+ declare global {
90
+ interface HTMLElementTagNameMap {
91
+ 'obc-tree-navigation-group': ObcTreeNavigationGroup;
92
+ }
93
+ }
94
+ //# sourceMappingURL=tree-navigation-group.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-navigation-group.d.ts","sourceRoot":"","sources":["../../../src/components/tree-navigation-group/tree-navigation-group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAIzD,OAAO,EAEL,cAAc,EAEf,MAAM,iDAAiD,CAAC;AACzD,OAAO,iDAAiD,CAAC;AAGzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBACa,sBAAuB,SAAQ,UAAU;IACpD,yDAAyD;IAC/B,KAAK,SAAW;IAE1C;;;;OAIG;IACsB,QAAQ,EAAE,cAAc,EAAE,CAAM;IAEzD,mFAAmF;IACzC,QAAQ,UAAS;IAE3D,yDAAyD;IACf,OAAO,UAAS;IAE1D,gFAAgF;IACtC,QAAQ,UAAS;IAE3D,oFAAoF;IACvC,OAAO,UAAQ;IAE5D;;;OAGG;IACuB,YAAY,EAAE,MAAM,CAA4B;IAE1E,yEAAyE;IAC9C,aAAa,UAAS;IAEjD,iFAAiF;IACvD,UAAU,SAAK;IAEzC,qGAAqG;IAC3E,SAAS,EAAE,MAAM,CAAmB;IAE9D;;;OAGG;IACuB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAEhB,OAAO,CAAC,UAAU,CAAC,CAAwB;IAE9E,OAAO,CAAC,cAAc;IAOtB,wEAAwE;IACxE,KAAK;IAOW,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAI1C,MAAM;IA0Bf,OAAgB,MAAM,0BAA6B;CACpD;AAED,MAAM,MAAM,uCAAuC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;AAE3E,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,2BAA2B,EAAE,sBAAsB,CAAC;KACrD;CACF"}