@rcarls/rc-menubar 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @rcarls/rc-menubar
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [7382c71]
8
+ - Updated dependencies [6683eb9]
9
+ - Updated dependencies [ee7ba6c]
10
+ - Updated dependencies [30eb232]
11
+ - Updated dependencies [30eb232]
12
+ - Updated dependencies [57370e4]
13
+ - @rcarls/rc-menu@0.6.0
14
+ - @rcarls/rc-menu-button@0.6.0
15
+ - @rcarls/rc-common@0.6.0
16
+
3
17
  ## 0.5.0
4
18
 
5
19
  ### Patch Changes
package/README.md CHANGED
@@ -17,8 +17,8 @@ npm install @rcarls/rc-menubar
17
17
  ## Import
18
18
 
19
19
  ```js
20
- import '@rcarls/rc-menubar/define'; // side-effect: registers <rc-menubar>
21
- import { RCMenubar } from '@rcarls/rc-menubar'; // named class export
20
+ import '@rcarls/rc-menubar/define'; // side-effect: registers <rc-menubar>
21
+ import { RCMenubar } from '@rcarls/rc-menubar'; // named class export
22
22
  ```
23
23
 
24
24
  `rc-menubar` depends on `rc-menu-button` and `rc-menu`. Ensure all three are installed.
@@ -67,49 +67,49 @@ Place `rc-menu-button` elements as direct children. The menubar manages focus an
67
67
 
68
68
  ### Properties / attributes
69
69
 
70
- | Property | Attribute | Type | Default | Description |
71
- |---|---|---|---|---|
72
- | `label` | `label` | `string` | `'Menu'` | `aria-label` for the menubar. Required — no visible label is rendered by the component. |
70
+ | Property | Attribute | Type | Default | Description |
71
+ | ------------- | ------------- | ---------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------- |
72
+ | `label` | `label` | `string` | `'Menu'` | `aria-label` for the menubar. Required — no visible label is rendered by the component. |
73
73
  | `orientation` | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout direction and keyboard navigation axis. Propagated to child `rc-menu-button` elements for arrow-key open direction. |
74
74
 
75
75
  ### CSS custom properties
76
76
 
77
- | Property | Default | Description |
78
- |---|---|---|
79
- | `--rc-menubar-gap` | `var(--rc-control-gap)` | Gap between menu buttons |
80
- | `--rc-menubar-padding-inline` | `var(--rc-control-padding-inline)` | Inline padding on the menubar container |
81
- | `--rc-menubar-padding-block` | `var(--rc-control-padding-block)` | Block padding on the menubar container |
82
- | `--rc-menubar-border` | `var(--rc-border)` | Menubar container border |
83
- | `--rc-menubar-radius` | `var(--rc-control-radius)` | Menubar container border radius |
84
- | `--rc-menubar-background` | `Canvas` | Menubar container background |
85
- | `--rc-menubar-color` | `CanvasText` | Menubar container text color |
86
- | `--rc-menubar-item-block-size` | `2.25em` | Minimum block size for child menu-button triggers |
87
- | `--rc-menubar-item-padding-block` | `0.25em` | Child trigger block-axis padding |
88
- | `--rc-menubar-item-padding-inline` | `0.75em` | Child trigger inline-axis padding |
89
- | `--rc-menubar-item-gap` | `var(--rc-item-gap)` | Gap between flex children inside child triggers |
90
- | `--rc-menubar-item-border` | `1px solid transparent` | Child trigger border |
91
- | `--rc-menubar-item-radius` | `var(--rc-control-radius)` | Child trigger border radius |
92
- | `--rc-menubar-item-background` | `transparent` | Child trigger background |
93
- | `--rc-menubar-item-color` | `inherit` | Child trigger text color |
94
- | `--rc-menubar-item-transition` | — | Child trigger state transition |
95
- | `--rc-menubar-item-hover-background` | `color-mix(in srgb, Highlight 8%, transparent)` | Child trigger hover background |
96
- | `--rc-menubar-item-hover-color` | `inherit` | Child trigger hover text color |
97
- | `--rc-menubar-item-hover-border-color` | `transparent` | Child trigger hover border color |
98
- | `--rc-menubar-item-open-background` | `color-mix(in srgb, Highlight 12%, transparent)` | Child trigger background while its menu is open |
99
- | `--rc-menubar-item-open-color` | `inherit` | Child trigger text color while its menu is open |
100
- | `--rc-menubar-item-open-border-color` | `transparent` | Child trigger border color while its menu is open |
77
+ | Property | Default | Description |
78
+ | -------------------------------------- | ------------------------------------------------ | ------------------------------------------------- |
79
+ | `--rc-menubar-gap` | `var(--rc-control-gap)` | Gap between menu buttons |
80
+ | `--rc-menubar-padding-inline` | `var(--rc-control-padding-inline)` | Inline padding on the menubar container |
81
+ | `--rc-menubar-padding-block` | `var(--rc-control-padding-block)` | Block padding on the menubar container |
82
+ | `--rc-menubar-border` | `var(--rc-border)` | Menubar container border |
83
+ | `--rc-menubar-radius` | `var(--rc-control-radius)` | Menubar container border radius |
84
+ | `--rc-menubar-background` | `Canvas` | Menubar container background |
85
+ | `--rc-menubar-color` | `CanvasText` | Menubar container text color |
86
+ | `--rc-menubar-item-block-size` | `2.25em` | Minimum block size for child menu-button triggers |
87
+ | `--rc-menubar-item-padding-block` | `0.25em` | Child trigger block-axis padding |
88
+ | `--rc-menubar-item-padding-inline` | `0.75em` | Child trigger inline-axis padding |
89
+ | `--rc-menubar-item-gap` | `var(--rc-item-gap)` | Gap between flex children inside child triggers |
90
+ | `--rc-menubar-item-border` | `1px solid transparent` | Child trigger border |
91
+ | `--rc-menubar-item-radius` | `var(--rc-control-radius)` | Child trigger border radius |
92
+ | `--rc-menubar-item-background` | `transparent` | Child trigger background |
93
+ | `--rc-menubar-item-color` | `inherit` | Child trigger text color |
94
+ | `--rc-menubar-item-transition` | — | Child trigger state transition |
95
+ | `--rc-menubar-item-hover-background` | `color-mix(in srgb, Highlight 8%, transparent)` | Child trigger hover background |
96
+ | `--rc-menubar-item-hover-color` | `inherit` | Child trigger hover text color |
97
+ | `--rc-menubar-item-hover-border-color` | `transparent` | Child trigger hover border color |
98
+ | `--rc-menubar-item-open-background` | `color-mix(in srgb, Highlight 12%, transparent)` | Child trigger background while its menu is open |
99
+ | `--rc-menubar-item-open-color` | `inherit` | Child trigger text color while its menu is open |
100
+ | `--rc-menubar-item-open-border-color` | `transparent` | Child trigger border color while its menu is open |
101
101
 
102
102
  ### CSS parts
103
103
 
104
- | Part | Element | Description |
105
- |---|---|---|
104
+ | Part | Element | Description |
105
+ | ------ | ----------- | ---------------------------- |
106
106
  | `root` | Inner `div` | The visual menubar container |
107
107
 
108
108
  ### Slots
109
109
 
110
- | Slot | Description |
111
- |---|---|
112
- | *(default)* | `rc-menu-button` elements. Non-menu-button elements are rendered but excluded from keyboard navigation. |
110
+ | Slot | Description |
111
+ | ----------- | ------------------------------------------------------------------------------------------------------- |
112
+ | _(default)_ | `rc-menu-button` elements. Non-menu-button elements are rendered but excluded from keyboard navigation. |
113
113
 
114
114
  ### Events
115
115
 
@@ -142,14 +142,14 @@ $previousItem: HTMLElement | undefined
142
142
 
143
143
  Horizontal orientation (default):
144
144
 
145
- | Key | Action |
146
- |---|---|
147
- | `ArrowRight` | Focus next trigger (wraps); if a menu is open, closes current and opens next |
148
- | `ArrowLeft` | Focus previous trigger (wraps); if a menu is open, closes current and opens previous |
149
- | `Home` | Focus first trigger |
150
- | `End` | Focus last trigger |
151
- | `Escape` | Close the active menu; focus remains on trigger |
152
- | `Tab` | Leaves the menubar (standard tab order) |
145
+ | Key | Action |
146
+ | ------------ | ------------------------------------------------------------------------------------ |
147
+ | `ArrowRight` | Focus next trigger (wraps); if a menu is open, closes current and opens next |
148
+ | `ArrowLeft` | Focus previous trigger (wraps); if a menu is open, closes current and opens previous |
149
+ | `Home` | Focus first trigger |
150
+ | `End` | Focus last trigger |
151
+ | `Escape` | Close the active menu; focus remains on trigger |
152
+ | `Tab` | Leaves the menubar (standard tab order) |
153
153
 
154
154
  For vertical orientation, `ArrowDown`/`ArrowUp` replace `ArrowRight`/`ArrowLeft`. The `rc-menu-button` children automatically inherit the menubar's orientation to determine their own open-axis arrow keys.
155
155
 
@@ -157,13 +157,13 @@ For vertical orientation, `ArrowDown`/`ArrowUp` replace `ArrowRight`/`ArrowLeft`
157
157
 
158
158
  ## ARIA
159
159
 
160
- | Attribute | Where | Value |
161
- |---|---|---|
162
- | `role="menubar"` | Host element | — |
163
- | `aria-orientation` | Host element | `"horizontal"` or `"vertical"` |
164
- | `aria-label` | Host element | Value of `label` property |
165
- | `tabindex="0"` | Active trigger | One trigger tabbable at a time (roving tabindex) |
166
- | `tabindex="-1"` | All other triggers | Removed from tab order |
160
+ | Attribute | Where | Value |
161
+ | ------------------ | ------------------ | ------------------------------------------------ |
162
+ | `role="menubar"` | Host element | — |
163
+ | `aria-orientation` | Host element | `"horizontal"` or `"vertical"` |
164
+ | `aria-label` | Host element | Value of `label` property |
165
+ | `tabindex="0"` | Active trigger | One trigger tabbable at a time (roving tabindex) |
166
+ | `tabindex="-1"` | All other triggers | Removed from tab order |
167
167
 
168
168
  ---
169
169
 
@@ -35,7 +35,7 @@
35
35
  "name": "*",
36
36
  "declaration": {
37
37
  "name": "*",
38
- "module": "src/rc-menubar"
38
+ "module": "src/rc-menubar.js"
39
39
  }
40
40
  }
41
41
  ]
@@ -42,17 +42,26 @@ const p = g`
42
42
  --rc-menu-button-trigger-padding-inline: var(--rc-menubar-item-padding-inline, 0.75em);
43
43
  --rc-menu-button-trigger-gap: var(--rc-menubar-item-gap, var(--rc-item-gap, 0.5em));
44
44
  --rc-menu-button-trigger-border: var(--rc-menubar-item-border, 1px solid transparent);
45
- --rc-menu-button-trigger-radius: var(--rc-menubar-item-radius, var(--rc-control-radius, 0.125em));
45
+ --rc-menu-button-trigger-radius: var(
46
+ --rc-menubar-item-radius,
47
+ var(--rc-control-radius, 0.125em)
48
+ );
46
49
  --rc-menu-button-trigger-background: var(--rc-menubar-item-background, transparent);
47
50
  --rc-menu-button-trigger-color: var(--rc-menubar-item-color, inherit);
48
51
  --rc-menu-button-trigger-transition: var(--rc-menubar-item-transition);
49
- --rc-menu-button-trigger-hover-border-color: var(--rc-menubar-item-hover-border-color, transparent);
52
+ --rc-menu-button-trigger-hover-border-color: var(
53
+ --rc-menubar-item-hover-border-color,
54
+ transparent
55
+ );
50
56
  --rc-menu-button-trigger-hover-background: var(
51
57
  --rc-menubar-item-hover-background,
52
58
  color-mix(in srgb, Highlight 8%, transparent)
53
59
  );
54
60
  --rc-menu-button-trigger-hover-color: var(--rc-menubar-item-hover-color, inherit);
55
- --rc-menu-button-trigger-open-border-color: var(--rc-menubar-item-open-border-color, transparent);
61
+ --rc-menu-button-trigger-open-border-color: var(
62
+ --rc-menubar-item-open-border-color,
63
+ transparent
64
+ );
56
65
  --rc-menu-button-trigger-open-background: var(
57
66
  --rc-menubar-item-open-background,
58
67
  color-mix(in srgb, Highlight 12%, transparent)
@@ -71,7 +80,10 @@ const p = g`
71
80
  color-mix(in srgb, Highlight 12%, transparent)
72
81
  );
73
82
  --rc-menu-button-trigger-hover-color: var(--rc-menubar-item-open-color, inherit);
74
- --rc-menu-button-trigger-hover-border-color: var(--rc-menubar-item-open-border-color, transparent);
83
+ --rc-menu-button-trigger-hover-border-color: var(
84
+ --rc-menubar-item-open-border-color,
85
+ transparent
86
+ );
75
87
  }
76
88
 
77
89
  :host([orientation='vertical']) ::slotted(rc-menu-button) {
@@ -269,4 +281,4 @@ u([
269
281
  export {
270
282
  s as R
271
283
  };
272
- //# sourceMappingURL=rc-menubar-VPb8lXg9.js.map
284
+ //# sourceMappingURL=rc-menubar-DCZFgZvn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-menubar-DCZFgZvn.js","sources":["../src/rc-menubar.styles.ts","../src/rc-menubar.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const menubarStyles = css`\n :host {\n display: inline-block;\n }\n\n #root {\n display: flex;\n flex-direction: row;\n align-items: stretch;\n gap: var(--rc-menubar-gap, var(--rc-control-gap, 0.25em));\n padding-inline: var(--rc-menubar-padding-inline, var(--rc-control-padding-inline, 0.25em));\n padding-block: var(--rc-menubar-padding-block, var(--rc-control-padding-block, 0.25em));\n border: var(--rc-menubar-border, var(--rc-border, 1px solid ButtonBorder));\n border-radius: var(--rc-menubar-radius, var(--rc-control-radius, 0));\n background: var(--rc-menubar-background, var(--rc-surface, Canvas));\n color: var(--rc-menubar-color, var(--rc-field-text, CanvasText));\n font-family: var(--rc-font-family, inherit);\n font-size: var(--rc-font-size, inherit);\n line-height: var(--rc-line-height, normal);\n }\n\n :host([orientation='vertical']) #root {\n flex-direction: column;\n align-items: stretch;\n }\n\n #slot-wrap {\n display: flex;\n flex-direction: inherit;\n align-items: stretch;\n gap: inherit;\n min-inline-size: 0;\n }\n\n ::slotted(rc-menu-button) {\n flex: 0 0 auto;\n --rc-menu-button-trigger-block-size: var(--rc-menubar-item-block-size, 2.25em);\n --rc-menu-button-trigger-padding-block: var(--rc-menubar-item-padding-block, 0.25em);\n --rc-menu-button-trigger-padding-inline: var(--rc-menubar-item-padding-inline, 0.75em);\n --rc-menu-button-trigger-gap: var(--rc-menubar-item-gap, var(--rc-item-gap, 0.5em));\n --rc-menu-button-trigger-border: var(--rc-menubar-item-border, 1px solid transparent);\n --rc-menu-button-trigger-radius: var(\n --rc-menubar-item-radius,\n var(--rc-control-radius, 0.125em)\n );\n --rc-menu-button-trigger-background: var(--rc-menubar-item-background, transparent);\n --rc-menu-button-trigger-color: var(--rc-menubar-item-color, inherit);\n --rc-menu-button-trigger-transition: var(--rc-menubar-item-transition);\n --rc-menu-button-trigger-hover-border-color: var(\n --rc-menubar-item-hover-border-color,\n transparent\n );\n --rc-menu-button-trigger-hover-background: var(\n --rc-menubar-item-hover-background,\n color-mix(in srgb, Highlight 8%, transparent)\n );\n --rc-menu-button-trigger-hover-color: var(--rc-menubar-item-hover-color, inherit);\n --rc-menu-button-trigger-open-border-color: var(\n --rc-menubar-item-open-border-color,\n transparent\n );\n --rc-menu-button-trigger-open-background: var(\n --rc-menubar-item-open-background,\n color-mix(in srgb, Highlight 12%, transparent)\n );\n --rc-menu-button-trigger-open-color: var(--rc-menubar-item-open-color, inherit);\n }\n\n ::slotted(rc-menu-button[open]) {\n --rc-menu-button-trigger-background: var(\n --rc-menubar-item-open-background,\n color-mix(in srgb, Highlight 12%, transparent)\n );\n --rc-menu-button-trigger-color: var(--rc-menubar-item-open-color, inherit);\n --rc-menu-button-trigger-hover-background: var(\n --rc-menubar-item-open-background,\n color-mix(in srgb, Highlight 12%, transparent)\n );\n --rc-menu-button-trigger-hover-color: var(--rc-menubar-item-open-color, inherit);\n --rc-menu-button-trigger-hover-border-color: var(\n --rc-menubar-item-open-border-color,\n transparent\n );\n }\n\n :host([orientation='vertical']) ::slotted(rc-menu-button) {\n inline-size: 100%;\n }\n`;\n\nexport default menubarStyles;\n","import { LitElement, html } from 'lit';\nimport { property, state } from 'lit/decorators.js';\n\nimport { type KeyboardNavigationAction } from '@rcarls/rc-common';\nimport type { RCMenuButton, RCMenuButtonToggleEvent } from '@rcarls/rc-menu-button';\n\nimport menubarStyles from './rc-menubar.styles.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-menubar': RCMenubar;\n }\n}\n\nconst IE_KEY_ALIASES: Record<string, string> = {\n Up: 'ArrowUp',\n Down: 'ArrowDown',\n Left: 'ArrowLeft',\n Right: 'ArrowRight',\n};\n\n/**\n * Menubar coordinator for rc-menu-button children with roving tabindex and submenu\n * handoff, following the WAI-ARIA Menubar pattern.\n *\n * Uses roving tabindex rather than aria-activedescendant so trigger buttons\n * receive real focus — required for submenu handoff and screen reader announcements.\n *\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-menubar rc-menubar docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/menubar/ WAI-ARIA Menubar pattern}\n *\n * @slot default - Takes rc-menu-button elements to display in the menubar\n *\n * @csspart root - The root container element\n *\n * @attr label - Accessible label for the `role=\"menubar\"` element.\n * @attr orientation - Layout direction and keyboard navigation axis, propagated to\n * child `rc-menu-button` elements.\n *\n * @cssprop [--rc-menubar-gap=var(--rc-control-gap)] - Gap between menu buttons\n * @cssprop [--rc-menubar-padding-inline=var(--rc-control-padding-inline)] - Inline-axis padding\n * @cssprop [--rc-menubar-padding-block=var(--rc-control-padding-block)] - Block-axis padding\n * @cssprop [--rc-menubar-border=var(--rc-border)] - Root container border\n * @cssprop [--rc-menubar-radius=var(--rc-control-radius)] - Root container border radius\n * @cssprop [--rc-menubar-background=Canvas] - Root container background\n * @cssprop [--rc-menubar-color=CanvasText] - Root container text color\n * @cssprop [--rc-menubar-item-block-size=2.25em] - Minimum block size for child menu-button triggers\n * @cssprop [--rc-menubar-item-padding-block=0.25em] - Child trigger block-axis padding\n * @cssprop [--rc-menubar-item-padding-inline=0.75em] - Child trigger inline-axis padding\n * @cssprop [--rc-menubar-item-gap=var(--rc-item-gap)] - Gap between flex children inside child triggers\n * @cssprop [--rc-menubar-item-border=1px solid transparent] - Child trigger border\n * @cssprop [--rc-menubar-item-radius=var(--rc-control-radius)] - Child trigger border radius\n * @cssprop [--rc-menubar-item-background=transparent] - Child trigger background\n * @cssprop [--rc-menubar-item-color=inherit] - Child trigger text color\n * @cssprop [--rc-menubar-item-transition] - CSS transition applied to child triggers\n * @cssprop [--rc-menubar-item-hover-background=color-mix(in srgb, Highlight 8%, transparent)] - Child trigger hover background\n * @cssprop [--rc-menubar-item-hover-color=inherit] - Child trigger hover text color\n * @cssprop [--rc-menubar-item-hover-border-color=transparent] - Child trigger hover border color\n * @cssprop [--rc-menubar-item-open-background=color-mix(in srgb, Highlight 12%, transparent)] - Child trigger background when its menu is open\n * @cssprop [--rc-menubar-item-open-color=inherit] - Child trigger text color when its menu is open\n * @cssprop [--rc-menubar-item-open-border-color=transparent] - Child trigger border color when its menu is open\n */\nexport class RCMenubar extends LitElement {\n static styles = [menubarStyles];\n\n /** Accessible label for the `role=\"menubar\"` element. */\n @property({ type: String })\n label = 'Menu';\n\n /** Orientation of the menubar, controls which arrow keys move between items. */\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /** Weak reference to the currently open child `rc-menu-button`. */\n @state()\n protected _$activeMenuButton: WeakRef<RCMenuButton> | undefined;\n\n /** The last trigger element to have received focus, used for roving-tabindex bookkeeping. */\n @state()\n protected _$lastFocused: HTMLElement | undefined;\n\n /** Weak references to all slotted `rc-menu-button` children, in DOM order. */\n protected _$menuButtons: WeakRef<RCMenuButton>[] = [];\n\n /** Bound keydown handler, held for `removeEventListener` pairing. */\n protected _boundHandleKeydown = this._handleKeydown.bind(this);\n\n /** Bound click handler, held for `removeEventListener` pairing. */\n protected _boundHandleClick = this._handleClick.bind(this);\n\n /** Syncs host ARIA attributes and registers keyboard and click handlers. */\n override connectedCallback() {\n super.connectedCallback();\n\n this._syncHostAria();\n\n this.addEventListener('keydown', this._boundHandleKeydown);\n this.addEventListener('click', this._boundHandleClick);\n }\n\n /** Removes keyboard and click handlers. */\n override disconnectedCallback() {\n super.disconnectedCallback();\n\n this.removeEventListener('keydown', this._boundHandleKeydown);\n this.removeEventListener('click', this._boundHandleClick);\n }\n\n /** Syncs host ARIA and child orientation when `label` or `orientation` change. */\n protected override updated(changedProperties: Map<PropertyKey, unknown>) {\n super.updated(changedProperties);\n\n if (changedProperties.has('label') || changedProperties.has('orientation')) {\n this._syncHostAria();\n this._syncMenuButtonOrientation();\n }\n }\n\n /** Writes `role`, `aria-label`, and `aria-orientation` to the host element. */\n protected _syncHostAria(): void {\n this.setAttribute('role', 'menubar');\n this.setAttribute('aria-label', this.label);\n this.setAttribute('aria-orientation', this.orientation);\n }\n\n /** Propagates the current `orientation` value to all slotted `rc-menu-button` children. */\n protected _syncMenuButtonOrientation(): void {\n this.$menuButtons.forEach(($menuButton) => {\n $menuButton.orientation = this.orientation;\n });\n }\n\n /** Returns the `[slot=\"trigger\"]` element inside a child `rc-menu-button`. */\n protected _$getTrigger($menuButton: RCMenuButton): HTMLElement | null {\n return $menuButton.querySelector('[slot=\"trigger\"]');\n }\n\n /** All slotted trigger elements in DOM order. */\n get $items(): HTMLElement[] {\n return this._$menuButtons\n .map((ref) => ref.deref())\n .filter(($el): $el is RCMenuButton => $el != null)\n .map(($mb) => this._$getTrigger($mb))\n .filter(($el): $el is HTMLElement => $el != null);\n }\n\n /** All slotted `rc-menu-button` children in DOM order. */\n get $menuButtons(): RCMenuButton[] {\n return this._$menuButtons\n .map((ref) => ref.deref())\n .filter(($el): $el is RCMenuButton => $el != null);\n }\n\n /** First trigger element in the menubar. */\n get $firstItem(): HTMLElement | undefined {\n return this.$items.at(0);\n }\n\n /** Last trigger element in the menubar. */\n get $lastItem(): HTMLElement | undefined {\n return this.$items.at(-1);\n }\n\n /** Trigger after `_$lastFocused`, wrapping around to the first. */\n get $nextItem(): HTMLElement | undefined {\n const index = this._$lastFocused ? this.$items.indexOf(this._$lastFocused) : 0;\n\n return this.$items.at((index + 1) % this.$items.length);\n }\n\n /** Trigger before `_$lastFocused`, wrapping around to the last. */\n get $previousItem(): HTMLElement | undefined {\n const index = this._$lastFocused ? this.$items.indexOf(this._$lastFocused) : 0;\n\n return this.$items.at((index - 1) % this.$items.length);\n }\n\n /** Returns the `rc-menu-button` whose slotted trigger matches `$trigger`. */\n protected _$getMenuButtonForTrigger($trigger: HTMLElement): RCMenuButton | undefined {\n return this.$menuButtons.find(($mb) => this._$getTrigger($mb) === $trigger);\n }\n\n /**\n * Moves focus to a trigger element.\n *\n * @param $item - trigger to focus; no-ops when `null` or `undefined`\n */\n focusItem($item?: HTMLElement | null) {\n if ($item != null) {\n $item.focus();\n }\n }\n\n /** Closes the currently open child menu without returning focus to its trigger. */\n closeActiveMenu() {\n const $activeMenuButton = this._$activeMenuButton?.deref();\n\n if ($activeMenuButton) {\n $activeMenuButton.closeMenu(false);\n\n this._$activeMenuButton = undefined;\n }\n }\n\n /** Updates roving-tabindex state when a trigger element receives focus. */\n protected _handleItemFocus(e: FocusEvent) {\n const $target = e.target as HTMLElement;\n\n if ($target.slot !== 'trigger') {\n return;\n }\n\n this._$lastFocused = $target;\n\n this.$items.forEach(($item) => $item.setAttribute('tabindex', '-1'));\n\n $target.setAttribute('tabindex', '0');\n }\n\n /** Refreshes the cached `rc-menu-button` list when slotted children change. */\n protected _handleSlotChange(e: Event) {\n const $slot = e.currentTarget as HTMLSlotElement;\n const $elements = $slot.assignedElements();\n\n const prevButtons = this._$menuButtons;\n\n // Cache element references synchronously. Defer all DOM mutations.\n // slotchange fires synchronously inside a framework reactive update pass\n // on second+ mount (shadow DOM already exists), so the handler must be\n // instantaneous to avoid interacting with the reactive system.\n this._$menuButtons = $elements\n .filter(($el): $el is RCMenuButton => $el.tagName === 'RC-MENU-BUTTON')\n .map(($el) => new WeakRef($el));\n\n queueMicrotask(() => {\n if (!this.isConnected) {\n return;\n }\n\n prevButtons.forEach((ref) => {\n const $menuButton = ref.deref();\n\n if (!$menuButton) {\n return;\n }\n\n $menuButton.removeAttribute('role');\n\n const $trigger = this._$getTrigger($menuButton);\n\n $trigger?.removeAttribute('tabindex');\n $trigger?.removeAttribute('role');\n });\n\n this.$menuButtons.forEach(($menuButton) => {\n $menuButton.removeAttribute('role');\n $menuButton.orientation = this.orientation;\n\n const $trigger = this._$getTrigger($menuButton);\n\n $trigger?.setAttribute('role', 'menuitem');\n });\n\n const $items = this.$items;\n\n $items.forEach(($trigger, index) => {\n $trigger.setAttribute('tabindex', index === 0 ? '0' : '-1');\n });\n\n if ($items.length > 0 && !this._$lastFocused) {\n this._$lastFocused = $items[0];\n }\n });\n }\n\n /** Tracks which child `rc-menu-button` is currently open. */\n protected _handleMenuButtonToggle(e: CustomEvent<RCMenuButtonToggleEvent>) {\n const $menuButton = e.target as RCMenuButton;\n\n if (e.detail.open) {\n this._$activeMenuButton = new WeakRef($menuButton);\n } else {\n if (this._$activeMenuButton?.deref() === $menuButton) {\n this._$activeMenuButton = undefined;\n }\n }\n }\n\n /**\n * Routes keyboard navigation actions to item focus and menu open/close changes.\n *\n * When a menu is open, moving to an adjacent item closes the current menu and\n * opens the one attached to the newly focused trigger.\n *\n * @param action - the navigation action produced by the keydown handler\n */\n protected _handleNavigate(action: KeyboardNavigationAction) {\n const $activeMenu = this._$activeMenuButton?.deref();\n const wasMenuOpen = $activeMenu?.open ?? false;\n\n switch (action) {\n case 'next':\n if (wasMenuOpen) {\n this.closeActiveMenu();\n }\n\n this.focusItem(this.$nextItem);\n\n if (wasMenuOpen) {\n this._openCurrentMenu();\n }\n\n break;\n\n case 'prev':\n if (wasMenuOpen) {\n this.closeActiveMenu();\n }\n\n this.focusItem(this.$previousItem);\n\n if (wasMenuOpen) {\n this._openCurrentMenu();\n }\n\n break;\n\n case 'start':\n if (wasMenuOpen) {\n this.closeActiveMenu();\n }\n\n this.focusItem(this.$firstItem);\n\n if (wasMenuOpen) {\n this._openCurrentMenu();\n }\n\n break;\n\n case 'end':\n if (wasMenuOpen) {\n this.closeActiveMenu();\n }\n\n this.focusItem(this.$lastItem);\n\n if (wasMenuOpen) {\n this._openCurrentMenu();\n }\n\n break;\n\n case 'escape':\n this.closeActiveMenu();\n\n break;\n }\n }\n\n /** Opens the menu attached to the last-focused trigger. */\n protected _openCurrentMenu() {\n if (this._$lastFocused) {\n const $menuButton = this._$getMenuButtonForTrigger(this._$lastFocused);\n\n if ($menuButton) {\n $menuButton.openMenu();\n }\n }\n }\n\n /** Translates keyboard events to navigation actions and activates keyboard interaction mode. */\n protected _handleKeydown(e: KeyboardEvent): void {\n const key = IE_KEY_ALIASES[e.key] ?? e.key;\n const navNext = this.orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown';\n const navPrev = this.orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp';\n\n let action: KeyboardNavigationAction | undefined;\n\n if (key === navNext) {\n action = 'next';\n } else if (key === navPrev) {\n action = 'prev';\n } else if (key === 'Home') {\n action = 'start';\n } else if (key === 'End') {\n action = 'end';\n } else if (key === 'Escape') {\n action = 'escape';\n } else if (key === 'Tab') {\n this.setAttribute('data-interaction-mode', 'keyboard');\n }\n\n if (!action) {\n return;\n }\n\n this._handleNavigate(action);\n this.setAttribute('data-interaction-mode', 'keyboard');\n\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** Clears keyboard interaction mode on pointer click. */\n protected _handleClick(): void {\n this.removeAttribute('data-interaction-mode');\n }\n\n protected override render() {\n return html`\n <div id=\"root\" part=\"root\">\n <div\n id=\"slot-wrap\"\n @focusin=${this._handleItemFocus}\n @rc-menu-button-toggle=${this._handleMenuButtonToggle}\n >\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n </div>\n `;\n }\n}\n\nexport default RCMenubar;\n"],"names":["menubarStyles","css","IE_KEY_ALIASES","_RCMenubar","LitElement","changedProperties","$menuButton","ref","$el","$mb","index","$trigger","$item","$activeMenuButton","e","$target","$elements","prevButtons","$items","action","wasMenuOpen","key","navNext","navPrev","html","RCMenubar","__decorateClass","property","state"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import "@rcarls/rc-menu-button/define";
2
- import { R as e } from "./rc-menubar-VPb8lXg9.js";
2
+ import { R as e } from "./rc-menubar-DCZFgZvn.js";
3
3
  customElements.get("rc-menubar") || customElements.define("rc-menubar", e);
4
4
  export {
5
5
  e as RCMenubar
@@ -1,4 +1,4 @@
1
- import { R as e } from "./rc-menubar-VPb8lXg9.js";
1
+ import { R as e } from "./rc-menubar-DCZFgZvn.js";
2
2
  export {
3
3
  e as RCMenubar
4
4
  };
@@ -1 +1 @@
1
- export * from './rc-menubar';
1
+ export * from './rc-menubar.js';
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.5.0",
6
+ "version": "0.6.0",
7
7
  "description": "Menubar coordinator for rc-menu-button children with roving tabindex and submenu handoff.",
8
8
  "repository": {
9
9
  "type": "git",
@@ -45,13 +45,13 @@
45
45
  "test:browser:firefox": "vitest --run --project=firefox"
46
46
  },
47
47
  "dependencies": {
48
- "@rcarls/rc-common": "0.5.0",
49
- "@rcarls/rc-menu": "0.5.0",
50
- "@rcarls/rc-menu-button": "0.5.0",
51
- "@types/node": "^25.6.0"
48
+ "@rcarls/rc-common": "0.6.0",
49
+ "@rcarls/rc-menu": "0.6.0",
50
+ "@rcarls/rc-menu-button": "0.6.0"
52
51
  },
53
52
  "devDependencies": {
54
53
  "@custom-elements-manifest/analyzer": "0.11.0",
54
+ "@types/node": "^25.6.0",
55
55
  "@vitest/browser-playwright": "4.1.5",
56
56
  "lit": "^3.0.0",
57
57
  "playwright": "^1.56.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"rc-menubar-VPb8lXg9.js","sources":["../src/rc-menubar.styles.ts","../src/rc-menubar.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const menubarStyles = css`\n :host {\n display: inline-block;\n }\n\n #root {\n display: flex;\n flex-direction: row;\n align-items: stretch;\n gap: var(--rc-menubar-gap, var(--rc-control-gap, 0.25em));\n padding-inline: var(--rc-menubar-padding-inline, var(--rc-control-padding-inline, 0.25em));\n padding-block: var(--rc-menubar-padding-block, var(--rc-control-padding-block, 0.25em));\n border: var(--rc-menubar-border, var(--rc-border, 1px solid ButtonBorder));\n border-radius: var(--rc-menubar-radius, var(--rc-control-radius, 0));\n background: var(--rc-menubar-background, var(--rc-surface, Canvas));\n color: var(--rc-menubar-color, var(--rc-field-text, CanvasText));\n font-family: var(--rc-font-family, inherit);\n font-size: var(--rc-font-size, inherit);\n line-height: var(--rc-line-height, normal);\n }\n\n :host([orientation='vertical']) #root {\n flex-direction: column;\n align-items: stretch;\n }\n\n #slot-wrap {\n display: flex;\n flex-direction: inherit;\n align-items: stretch;\n gap: inherit;\n min-inline-size: 0;\n }\n\n ::slotted(rc-menu-button) {\n flex: 0 0 auto;\n --rc-menu-button-trigger-block-size: var(--rc-menubar-item-block-size, 2.25em);\n --rc-menu-button-trigger-padding-block: var(--rc-menubar-item-padding-block, 0.25em);\n --rc-menu-button-trigger-padding-inline: var(--rc-menubar-item-padding-inline, 0.75em);\n --rc-menu-button-trigger-gap: var(--rc-menubar-item-gap, var(--rc-item-gap, 0.5em));\n --rc-menu-button-trigger-border: var(--rc-menubar-item-border, 1px solid transparent);\n --rc-menu-button-trigger-radius: var(--rc-menubar-item-radius, var(--rc-control-radius, 0.125em));\n --rc-menu-button-trigger-background: var(--rc-menubar-item-background, transparent);\n --rc-menu-button-trigger-color: var(--rc-menubar-item-color, inherit);\n --rc-menu-button-trigger-transition: var(--rc-menubar-item-transition);\n --rc-menu-button-trigger-hover-border-color: var(--rc-menubar-item-hover-border-color, transparent);\n --rc-menu-button-trigger-hover-background: var(\n --rc-menubar-item-hover-background,\n color-mix(in srgb, Highlight 8%, transparent)\n );\n --rc-menu-button-trigger-hover-color: var(--rc-menubar-item-hover-color, inherit);\n --rc-menu-button-trigger-open-border-color: var(--rc-menubar-item-open-border-color, transparent);\n --rc-menu-button-trigger-open-background: var(\n --rc-menubar-item-open-background,\n color-mix(in srgb, Highlight 12%, transparent)\n );\n --rc-menu-button-trigger-open-color: var(--rc-menubar-item-open-color, inherit);\n }\n\n ::slotted(rc-menu-button[open]) {\n --rc-menu-button-trigger-background: var(\n --rc-menubar-item-open-background,\n color-mix(in srgb, Highlight 12%, transparent)\n );\n --rc-menu-button-trigger-color: var(--rc-menubar-item-open-color, inherit);\n --rc-menu-button-trigger-hover-background: var(\n --rc-menubar-item-open-background,\n color-mix(in srgb, Highlight 12%, transparent)\n );\n --rc-menu-button-trigger-hover-color: var(--rc-menubar-item-open-color, inherit);\n --rc-menu-button-trigger-hover-border-color: var(--rc-menubar-item-open-border-color, transparent);\n }\n\n :host([orientation='vertical']) ::slotted(rc-menu-button) {\n inline-size: 100%;\n }\n`;\n\nexport default menubarStyles;\n","import { LitElement, html } from 'lit';\nimport { property, state } from 'lit/decorators.js';\n\nimport { type KeyboardNavigationAction } from '@rcarls/rc-common';\n\nimport type { RCMenuButton, RCMenuButtonToggleEvent } from '@rcarls/rc-menu-button';\n\nimport menubarStyles from './rc-menubar.styles';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-menubar': RCMenubar;\n }\n}\n\nconst IE_KEY_ALIASES: Record<string, string> = {\n Up: 'ArrowUp',\n Down: 'ArrowDown',\n Left: 'ArrowLeft',\n Right: 'ArrowRight',\n};\n\n/**\n * Menubar coordinator for rc-menu-button children with roving tabindex and submenu\n * handoff, following the WAI-ARIA Menubar pattern.\n *\n * Uses roving tabindex rather than aria-activedescendant so trigger buttons\n * receive real focus — required for submenu handoff and screen reader announcements.\n *\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-menubar rc-menubar docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/menubar/ WAI-ARIA Menubar pattern}\n *\n * @slot default - Takes rc-menu-button elements to display in the menubar\n *\n * @csspart root - The root container element\n *\n * @attr label - Accessible label for the `role=\"menubar\"` element.\n * @attr orientation - Layout direction and keyboard navigation axis, propagated to\n * child `rc-menu-button` elements.\n *\n * @cssprop [--rc-menubar-gap=var(--rc-control-gap)] - Gap between menu buttons\n * @cssprop [--rc-menubar-padding-inline=var(--rc-control-padding-inline)] - Inline-axis padding\n * @cssprop [--rc-menubar-padding-block=var(--rc-control-padding-block)] - Block-axis padding\n * @cssprop [--rc-menubar-border=var(--rc-border)] - Root container border\n * @cssprop [--rc-menubar-radius=var(--rc-control-radius)] - Root container border radius\n * @cssprop [--rc-menubar-background=Canvas] - Root container background\n * @cssprop [--rc-menubar-color=CanvasText] - Root container text color\n * @cssprop [--rc-menubar-item-block-size=2.25em] - Minimum block size for child menu-button triggers\n * @cssprop [--rc-menubar-item-padding-block=0.25em] - Child trigger block-axis padding\n * @cssprop [--rc-menubar-item-padding-inline=0.75em] - Child trigger inline-axis padding\n * @cssprop [--rc-menubar-item-gap=var(--rc-item-gap)] - Gap between flex children inside child triggers\n * @cssprop [--rc-menubar-item-border=1px solid transparent] - Child trigger border\n * @cssprop [--rc-menubar-item-radius=var(--rc-control-radius)] - Child trigger border radius\n * @cssprop [--rc-menubar-item-background=transparent] - Child trigger background\n * @cssprop [--rc-menubar-item-color=inherit] - Child trigger text color\n * @cssprop [--rc-menubar-item-transition] - CSS transition applied to child triggers\n * @cssprop [--rc-menubar-item-hover-background=color-mix(in srgb, Highlight 8%, transparent)] - Child trigger hover background\n * @cssprop [--rc-menubar-item-hover-color=inherit] - Child trigger hover text color\n * @cssprop [--rc-menubar-item-hover-border-color=transparent] - Child trigger hover border color\n * @cssprop [--rc-menubar-item-open-background=color-mix(in srgb, Highlight 12%, transparent)] - Child trigger background when its menu is open\n * @cssprop [--rc-menubar-item-open-color=inherit] - Child trigger text color when its menu is open\n * @cssprop [--rc-menubar-item-open-border-color=transparent] - Child trigger border color when its menu is open\n */\nexport class RCMenubar extends LitElement {\n static styles = [menubarStyles];\n\n /** Accessible label for the `role=\"menubar\"` element. */\n @property({ type: String })\n label = 'Menu';\n\n /** Orientation of the menubar, controls which arrow keys move between items. */\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /** Weak reference to the currently open child `rc-menu-button`. */\n @state()\n protected _$activeMenuButton: WeakRef<RCMenuButton> | undefined;\n\n /** The last trigger element to have received focus, used for roving-tabindex bookkeeping. */\n @state()\n protected _$lastFocused: HTMLElement | undefined;\n\n /** Weak references to all slotted `rc-menu-button` children, in DOM order. */\n protected _$menuButtons: WeakRef<RCMenuButton>[] = [];\n\n /** Bound keydown handler, held for `removeEventListener` pairing. */\n protected _boundHandleKeydown = this._handleKeydown.bind(this);\n\n /** Bound click handler, held for `removeEventListener` pairing. */\n protected _boundHandleClick = this._handleClick.bind(this);\n\n /** Syncs host ARIA attributes and registers keyboard and click handlers. */\n override connectedCallback() {\n super.connectedCallback();\n\n this._syncHostAria();\n\n this.addEventListener('keydown', this._boundHandleKeydown);\n this.addEventListener('click', this._boundHandleClick);\n }\n\n /** Removes keyboard and click handlers. */\n override disconnectedCallback() {\n super.disconnectedCallback();\n\n this.removeEventListener('keydown', this._boundHandleKeydown);\n this.removeEventListener('click', this._boundHandleClick);\n }\n\n /** Syncs host ARIA and child orientation when `label` or `orientation` change. */\n protected override updated(changedProperties: Map<PropertyKey, unknown>) {\n super.updated(changedProperties);\n\n if (changedProperties.has('label') || changedProperties.has('orientation')) {\n this._syncHostAria();\n this._syncMenuButtonOrientation();\n }\n }\n\n /** Writes `role`, `aria-label`, and `aria-orientation` to the host element. */\n protected _syncHostAria(): void {\n this.setAttribute('role', 'menubar');\n this.setAttribute('aria-label', this.label);\n this.setAttribute('aria-orientation', this.orientation);\n }\n\n /** Propagates the current `orientation` value to all slotted `rc-menu-button` children. */\n protected _syncMenuButtonOrientation(): void {\n this.$menuButtons.forEach(($menuButton) => {\n $menuButton.orientation = this.orientation;\n });\n }\n\n /** Returns the `[slot=\"trigger\"]` element inside a child `rc-menu-button`. */\n protected _$getTrigger($menuButton: RCMenuButton): HTMLElement | null {\n return $menuButton.querySelector('[slot=\"trigger\"]');\n }\n\n /** All slotted trigger elements in DOM order. */\n get $items(): HTMLElement[] {\n return this._$menuButtons\n .map((ref) => ref.deref())\n .filter(($el): $el is RCMenuButton => $el != null)\n .map(($mb) => this._$getTrigger($mb))\n .filter(($el): $el is HTMLElement => $el != null);\n }\n\n /** All slotted `rc-menu-button` children in DOM order. */\n get $menuButtons(): RCMenuButton[] {\n return this._$menuButtons\n .map((ref) => ref.deref())\n .filter(($el): $el is RCMenuButton => $el != null);\n }\n\n /** First trigger element in the menubar. */\n get $firstItem(): HTMLElement | undefined {\n return this.$items.at(0);\n }\n\n /** Last trigger element in the menubar. */\n get $lastItem(): HTMLElement | undefined {\n return this.$items.at(-1);\n }\n\n /** Trigger after `_$lastFocused`, wrapping around to the first. */\n get $nextItem(): HTMLElement | undefined {\n const index = this._$lastFocused ? this.$items.indexOf(this._$lastFocused) : 0;\n\n return this.$items.at((index + 1) % this.$items.length);\n }\n\n /** Trigger before `_$lastFocused`, wrapping around to the last. */\n get $previousItem(): HTMLElement | undefined {\n const index = this._$lastFocused ? this.$items.indexOf(this._$lastFocused) : 0;\n\n return this.$items.at((index - 1) % this.$items.length);\n }\n\n /** Returns the `rc-menu-button` whose slotted trigger matches `$trigger`. */\n protected _$getMenuButtonForTrigger($trigger: HTMLElement): RCMenuButton | undefined {\n return this.$menuButtons.find(($mb) => this._$getTrigger($mb) === $trigger);\n }\n\n /**\n * Moves focus to a trigger element.\n *\n * @param $item - trigger to focus; no-ops when `null` or `undefined`\n */\n focusItem($item?: HTMLElement | null) {\n if ($item != null) {\n $item.focus();\n }\n }\n\n /** Closes the currently open child menu without returning focus to its trigger. */\n closeActiveMenu() {\n const $activeMenuButton = this._$activeMenuButton?.deref();\n\n if ($activeMenuButton) {\n $activeMenuButton.closeMenu(false);\n\n this._$activeMenuButton = undefined;\n }\n }\n\n /** Updates roving-tabindex state when a trigger element receives focus. */\n protected _handleItemFocus(e: FocusEvent) {\n const $target = e.target as HTMLElement;\n\n if ($target.slot !== 'trigger') return;\n\n this._$lastFocused = $target;\n\n this.$items.forEach(($item) => $item.setAttribute('tabindex', '-1'));\n\n $target.setAttribute('tabindex', '0');\n }\n\n /** Refreshes the cached `rc-menu-button` list when slotted children change. */\n protected _handleSlotChange(e: Event) {\n const $slot = e.currentTarget as HTMLSlotElement;\n const $elements = $slot.assignedElements();\n\n const prevButtons = this._$menuButtons;\n\n // Cache element references synchronously. Defer all DOM mutations.\n // slotchange fires synchronously inside a framework reactive update pass\n // on second+ mount (shadow DOM already exists), so the handler must be\n // instantaneous to avoid interacting with the reactive system.\n this._$menuButtons = $elements\n .filter(($el): $el is RCMenuButton => $el.tagName === 'RC-MENU-BUTTON')\n .map(($el) => new WeakRef($el));\n\n queueMicrotask(() => {\n if (!this.isConnected) {\n return;\n }\n\n prevButtons.forEach((ref) => {\n const $menuButton = ref.deref();\n if (!$menuButton) {\n return;\n }\n\n $menuButton.removeAttribute('role');\n\n const $trigger = this._$getTrigger($menuButton);\n\n $trigger?.removeAttribute('tabindex');\n $trigger?.removeAttribute('role');\n });\n\n this.$menuButtons.forEach(($menuButton) => {\n $menuButton.removeAttribute('role');\n $menuButton.orientation = this.orientation;\n\n const $trigger = this._$getTrigger($menuButton);\n\n $trigger?.setAttribute('role', 'menuitem');\n });\n\n const $items = this.$items;\n\n $items.forEach(($trigger, index) => {\n $trigger.setAttribute('tabindex', index === 0 ? '0' : '-1');\n });\n\n if ($items.length > 0 && !this._$lastFocused) {\n this._$lastFocused = $items[0];\n }\n });\n }\n\n /** Tracks which child `rc-menu-button` is currently open. */\n protected _handleMenuButtonToggle(e: CustomEvent<RCMenuButtonToggleEvent>) {\n const $menuButton = e.target as RCMenuButton;\n\n if (e.detail.open) {\n this._$activeMenuButton = new WeakRef($menuButton);\n } else {\n if (this._$activeMenuButton?.deref() === $menuButton) {\n this._$activeMenuButton = undefined;\n }\n }\n }\n\n /**\n * Routes keyboard navigation actions to item focus and menu open/close changes.\n *\n * When a menu is open, moving to an adjacent item closes the current menu and\n * opens the one attached to the newly focused trigger.\n *\n * @param action - the navigation action produced by the keydown handler\n */\n protected _handleNavigate(action: KeyboardNavigationAction) {\n const $activeMenu = this._$activeMenuButton?.deref();\n const wasMenuOpen = $activeMenu?.open ?? false;\n\n switch (action) {\n case 'next':\n if (wasMenuOpen) {\n this.closeActiveMenu();\n }\n\n this.focusItem(this.$nextItem);\n\n if (wasMenuOpen) {\n this._openCurrentMenu();\n }\n\n break;\n\n case 'prev':\n if (wasMenuOpen) {\n this.closeActiveMenu();\n }\n\n this.focusItem(this.$previousItem);\n\n if (wasMenuOpen) {\n this._openCurrentMenu();\n }\n\n break;\n\n case 'start':\n if (wasMenuOpen) {\n this.closeActiveMenu();\n }\n\n this.focusItem(this.$firstItem);\n\n if (wasMenuOpen) {\n this._openCurrentMenu();\n }\n\n break;\n\n case 'end':\n if (wasMenuOpen) {\n this.closeActiveMenu();\n }\n\n this.focusItem(this.$lastItem);\n\n if (wasMenuOpen) {\n this._openCurrentMenu();\n }\n\n break;\n\n case 'escape':\n this.closeActiveMenu();\n\n break;\n }\n }\n\n /** Opens the menu attached to the last-focused trigger. */\n protected _openCurrentMenu() {\n if (this._$lastFocused) {\n const $menuButton = this._$getMenuButtonForTrigger(this._$lastFocused);\n\n if ($menuButton) {\n $menuButton.openMenu();\n }\n }\n }\n\n /** Translates keyboard events to navigation actions and activates keyboard interaction mode. */\n protected _handleKeydown(e: KeyboardEvent): void {\n const key = IE_KEY_ALIASES[e.key] ?? e.key;\n const navNext = this.orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown';\n const navPrev = this.orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp';\n\n let action: KeyboardNavigationAction | undefined;\n\n if (key === navNext) {\n action = 'next';\n } else if (key === navPrev) {\n action = 'prev';\n } else if (key === 'Home') {\n action = 'start';\n } else if (key === 'End') {\n action = 'end';\n } else if (key === 'Escape') {\n action = 'escape';\n } else if (key === 'Tab') {\n this.setAttribute('data-interaction-mode', 'keyboard');\n }\n\n if (!action) {\n return;\n }\n\n this._handleNavigate(action);\n this.setAttribute('data-interaction-mode', 'keyboard');\n\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** Clears keyboard interaction mode on pointer click. */\n protected _handleClick(): void {\n this.removeAttribute('data-interaction-mode');\n }\n\n protected override render() {\n return html`\n <div id=\"root\" part=\"root\">\n <div\n id=\"slot-wrap\"\n @focusin=${this._handleItemFocus}\n @rc-menu-button-toggle=${this._handleMenuButtonToggle}\n >\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n </div>\n `;\n }\n}\n\nexport default RCMenubar;\n"],"names":["menubarStyles","css","IE_KEY_ALIASES","_RCMenubar","LitElement","changedProperties","$menuButton","ref","$el","$mb","index","$trigger","$item","$activeMenuButton","e","$target","$elements","prevButtons","$items","action","wasMenuOpen","key","navNext","navPrev","html","RCMenubar","__decorateClass","property","state"],"mappings":"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"}