@rcarls/rc-menu 0.5.0 → 0.7.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,118 @@
1
1
  # @rcarls/rc-menu
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 687a9be: Add shared popup surface tokens: `--rc-popup-background`, `--rc-popup-color`,
8
+ `--rc-popup-border`, `--rc-popup-radius`, `--rc-popup-shadow`, and
9
+ `--rc-popup-padding-block`. Menus, adaptive-menu popups, and select and
10
+ combobox listboxes read them before their own fallbacks. Themes set them at the
11
+ theme root, so popups rendered inside other shadow roots keep the theme's
12
+ surface. Select and combobox add `--rc-*-listbox-background` and
13
+ `--rc-*-listbox-color`.
14
+
15
+ Breaking: popup surfaces no longer fall back to `--rc-control-radius`. Set
16
+ `--rc-popup-radius` (or the per-component radius token) to change popup
17
+ corners. The Material, Substrate, and Win31 themes no longer set per-component
18
+ popup surface tokens such as `--rc-menu-radius` or
19
+ `--rc-adaptive-menu-popup-background`; override the `--rc-popup-*` tokens
20
+ instead. Material select and combobox listboxes now use the menu container
21
+ color, Material forced-colors popups gain a border, and Substrate listboxes use
22
+ the menu shadow and padding. Material retains its two-layer adaptive-menu popup
23
+ shadow through a component token while other popups continue using the shared
24
+ shadow.
25
+
26
+ - 6d126fd: Add shared item type tokens: `--rc-item-font-family`, `--rc-item-font-size`,
27
+ `--rc-item-font-weight`, `--rc-item-line-height`, `--rc-item-letter-spacing`,
28
+ and `--rc-item-icon-size`. Menu, listbox, and adaptive-menu items read them.
29
+ Adaptive menu adds `--rc-adaptive-menu-trigger-hover-background`,
30
+ `--rc-adaptive-menu-trigger-shadow`, and
31
+ `--rc-adaptive-menu-trigger-active-shadow`, and styles overflowed `rc-button`
32
+ and `rc-menu-button` rows from its item tokens. Themes declare their menu,
33
+ adaptive-menu, and item tokens on the theme root, so menus inside other shadow
34
+ roots match menus in the document. Substrate's adaptive-menu trigger now shows
35
+ its hover background.
36
+
37
+ Breaking: theme menu and adaptive-menu tokens are inherited from the theme root
38
+ instead of set on each element, so a value set on an ancestor now reaches
39
+ nested menus. Material sets menu, listbox, and adaptive-menu item type through
40
+ `--rc-item-*` instead of per-component rules; override those tokens to change
41
+ item type. Themes no longer style the adaptive-menu trigger through
42
+ `::part(overflow-trigger)` hover and pressed rules; use the new trigger tokens.
43
+
44
+ ### Patch Changes
45
+
46
+ - 5c006de: Ship component CSS minified. Package builds now run the CSS in Lit `css` styles
47
+ and light-DOM structural styles through Lightning CSS, removing comments and
48
+ whitespace while keeping source maps that resolve to each template. Rendered
49
+ styles are unchanged.
50
+
51
+ `@rcarls/rc-common` adds `cssText`, an identity tag that marks a plain CSS
52
+ string for minification. `rc-chip`, `rc-disclosure`, and `rc-accordion` now
53
+ depend on `@rcarls/rc-common` for it.
54
+
55
+ - Updated dependencies [e3dfa59]
56
+ - Updated dependencies [50d5610]
57
+ - Updated dependencies [9ee769c]
58
+ - Updated dependencies [1179f24]
59
+ - Updated dependencies [595fe37]
60
+ - Updated dependencies [38cd00c]
61
+ - Updated dependencies [5c006de]
62
+ - Updated dependencies [a6553ff]
63
+ - Updated dependencies [2205478]
64
+ - Updated dependencies [4341311]
65
+ - Updated dependencies [899bb5e]
66
+ - Updated dependencies [25fcfe0]
67
+ - Updated dependencies [51f6403]
68
+ - Updated dependencies [9caca6b]
69
+ - Updated dependencies [b764a3c]
70
+ - Updated dependencies [54d9ead]
71
+ - Updated dependencies [b9175e9]
72
+ - Updated dependencies [c8b762b]
73
+ - Updated dependencies [55e1e7f]
74
+ - Updated dependencies [f1ca82d]
75
+ - Updated dependencies [b87f27b]
76
+ - Updated dependencies [32ebead]
77
+ - Updated dependencies [bfefedd]
78
+ - Updated dependencies [c130173]
79
+ - Updated dependencies [11680b6]
80
+ - Updated dependencies [223d36c]
81
+ - Updated dependencies [7b91a44]
82
+ - Updated dependencies [aa04ead]
83
+ - Updated dependencies [ac65b5b]
84
+ - Updated dependencies [afcfef8]
85
+ - Updated dependencies [11ef1ad]
86
+ - @rcarls/rc-common@0.7.0
87
+
88
+ ## 0.6.0
89
+
90
+ ### Patch Changes
91
+
92
+ - 7382c71: Add a priority-aware action toolbar that moves original controls into an
93
+ overflow menu. Which actions are promoted is a purely declarative computation
94
+ from `max-shown` and each action's `data-priority`/authored `slot`, with no
95
+ runtime measurement of the toolbar's or its children's rendered size: a
96
+ consumer whose promoted count needs to react to available space owns that
97
+ decision and writes the resulting `max-shown` value down. Include controlled
98
+ and uncontrolled open state, keyboard navigation, light dismissal, and a
99
+ non-Popover fallback.
100
+
101
+ Fix `--rc-adaptive-menu-touch-target-overlap-inline-start`/`-end`: the host's
102
+ own `max-inline-size: 100%` self-referenced a shrink-to-fit ancestor's
103
+ already-margin-reduced auto size (an app bar's own trailing group, for
104
+ example), quietly clamping the host back down and canceling the overlap out
105
+ from under it. The cap now grows by the overlap amount so it only ever bounds
106
+ the host's real content.
107
+
108
+ - 30eb232: Add icon-only activation-area sizing and Material icon-button variants. Align menu
109
+ selection and submenu affordances, and keep anchored popups within the viewport
110
+ across native and fallback positioning.
111
+ - Updated dependencies [6683eb9]
112
+ - Updated dependencies [ee7ba6c]
113
+ - Updated dependencies [30eb232]
114
+ - @rcarls/rc-common@0.6.0
115
+
3
116
  ## 0.5.0
4
117
 
5
118
  ### Patch Changes
@@ -35,7 +35,7 @@
35
35
  "name": "*",
36
36
  "declaration": {
37
37
  "name": "*",
38
- "module": "src/rc-menu"
38
+ "module": "src/rc-menu.js"
39
39
  }
40
40
  }
41
41
  ]
@@ -57,32 +57,42 @@
57
57
  {
58
58
  "description": "Block (top/bottom) padding inside the panel.",
59
59
  "name": "--rc-menu-padding-block",
60
- "default": "0.25em"
60
+ "default": "var(--rc-popup-padding-block)"
61
61
  },
62
62
  {
63
- "description": "Background color; falls back through --rc-surface.",
63
+ "description": "Background color.",
64
64
  "name": "--rc-menu-background",
65
- "default": "Canvas"
65
+ "default": "var(--rc-popup-background)"
66
66
  },
67
67
  {
68
- "description": "Border; falls back through --rc-border.",
68
+ "description": "Border.",
69
69
  "name": "--rc-menu-border",
70
- "default": "1px solid ButtonBorder"
70
+ "default": "var(--rc-popup-border)"
71
71
  },
72
72
  {
73
73
  "description": "Menu panel border radius.",
74
74
  "name": "--rc-menu-radius",
75
- "default": "var(--rc-control-radius)"
75
+ "default": "var(--rc-popup-radius)"
76
76
  },
77
77
  {
78
- "description": "Box shadow; falls back through --rc-shadow.",
78
+ "description": "Box shadow.",
79
79
  "name": "--rc-menu-shadow",
80
- "default": "0 2px 8px color-mix(in srgb, CanvasText 15%, transparent)"
80
+ "default": "var(--rc-popup-shadow)"
81
81
  },
82
82
  {
83
- "description": "Text color; falls back through --rc-field-text.",
83
+ "description": "Text color.",
84
84
  "name": "--rc-menu-color",
85
- "default": "CanvasText"
85
+ "default": "var(--rc-popup-color)"
86
+ },
87
+ {
88
+ "description": "Viewport-aware maximum inline size.",
89
+ "name": "--rc-menu-max-inline-size",
90
+ "default": "calc(100dvi - 0.5rem)"
91
+ },
92
+ {
93
+ "description": "Viewport-aware maximum block size; taller menus scroll.",
94
+ "name": "--rc-menu-max-block-size",
95
+ "default": "calc(100dvb - 0.5rem)"
86
96
  },
87
97
  {
88
98
  "description": "Minimum block size for menu item rows.",
@@ -129,7 +139,7 @@
129
139
  "default": "inherit"
130
140
  },
131
141
  {
132
- "description": "Width of the leading indicator column for checkbox/radio items.",
142
+ "description": "Width of the trailing indicator column for checkbox/radio items.",
133
143
  "name": "--rc-menu-check-size",
134
144
  "default": "1.25em"
135
145
  },
@@ -139,12 +149,12 @@
139
149
  "default": "inherit"
140
150
  },
141
151
  {
142
- "description": "Font size of `[data-menu-shortcut]` labels.",
152
+ "description": "Font size of `[data-rc-menu-shortcut]` labels.",
143
153
  "name": "--rc-menu-shortcut-size",
144
154
  "default": "0.8em"
145
155
  },
146
156
  {
147
- "description": "Text color of `[data-menu-shortcut]` labels.",
157
+ "description": "Text color of `[data-rc-menu-shortcut]` labels.",
148
158
  "name": "--rc-menu-shortcut-color",
149
159
  "default": "GrayText"
150
160
  },
@@ -182,11 +192,41 @@
182
192
  "description": "Text color of `[data-group-label]` section headings.",
183
193
  "name": "--rc-menu-group-label-color",
184
194
  "default": "GrayText"
195
+ },
196
+ {
197
+ "description": "Item font family; shared with listbox and adaptive-menu items.",
198
+ "name": "--rc-item-font-family",
199
+ "default": "var(--rc-font-family)"
200
+ },
201
+ {
202
+ "description": "Item font size; shared with listbox and adaptive-menu items.",
203
+ "name": "--rc-item-font-size",
204
+ "default": "var(--rc-font-size)"
205
+ },
206
+ {
207
+ "description": "Item font weight; shared with listbox and adaptive-menu items.",
208
+ "name": "--rc-item-font-weight",
209
+ "default": "inherit"
210
+ },
211
+ {
212
+ "description": "Item line height; shared with listbox and adaptive-menu items.",
213
+ "name": "--rc-item-line-height",
214
+ "default": "var(--rc-line-height)"
215
+ },
216
+ {
217
+ "description": "Item letter spacing; shared with listbox and adaptive-menu items.",
218
+ "name": "--rc-item-letter-spacing",
219
+ "default": "inherit"
220
+ },
221
+ {
222
+ "description": "Size of icons marked with `data-rc-icon`, `data-rc-menu-leading`, or `data-rc-menu-icon`.",
223
+ "name": "--rc-item-icon-size",
224
+ "default": "inherit"
185
225
  }
186
226
  ],
187
227
  "slots": [
188
228
  {
189
- "description": "Menu items, groups, and separators. Supported content model: - Focusable elements (`<button>`, `<a>`, `[tabindex]`) become navigable `role=\"menuitem\"` entries. - `role=\"menuitemcheckbox\"` / `role=\"menuitemradio\"` elements get a leading indicator column via `::before`; `aria-checked` is initialized when missing and updated on activation. - `role=\"group\"` divs group related items; label them with `aria-label` or `aria-labelledby`. Optionally add a visible `[data-group-label]` element as first child of the group for section headings. - `role=\"separator\"` / `<hr>` produce horizontal dividers between sections. - Within any item, `[data-menu-shortcut]` elements are pushed to the inline-end edge for keyboard hints. - Nested menu triggers supply their own trailing indicator through `rc-menu-button`'s `indicator` slot.",
229
+ "description": "Menu items, groups, and separators. Supported content model: - Focusable elements (`<button>`, `<a>`, `[tabindex]`) become navigable `role=\"menuitem\"` entries. - `role=\"menuitemcheckbox\"` / `role=\"menuitemradio\"` elements get a trailing indicator column via `::after` (coexists with a leading icon the item supplies itself); `aria-checked` is initialized when missing and updated on activation. - `role=\"group\"` divs group related items; label them with `aria-label` or `aria-labelledby`. Optionally add a visible `[data-group-label]` element as first child of the group for section headings. - `role=\"separator\"` / `<hr>` produce horizontal dividers between sections. - Within any item, use `[data-rc-menu-leading]`, `[data-rc-menu-label]`, and `[data-rc-menu-trailing]` to identify content columns. `[data-rc-menu-shortcut]` (and the legacy `[data-menu-shortcut]`) is pushed to the inline-end edge. - Nested menu triggers supply their own trailing indicator through `rc-menu-button`'s `indicator` slot.",
190
230
  "name": "default"
191
231
  }
192
232
  ],
@@ -288,7 +328,7 @@
288
328
  "type": {
289
329
  "text": "Element | null"
290
330
  },
291
- "description": "The element to make active. No-op when null or undefined."
331
+ "description": "the element to make active. No-op when null or undefined"
292
332
  }
293
333
  ],
294
334
  "description": "Move the virtual cursor to a specific item."
@@ -307,7 +347,7 @@
307
347
  "type": {
308
348
  "text": "number"
309
349
  },
310
- "description": "Zero-based index into the navigable items array."
350
+ "description": "zero-based index into the navigable items array"
311
351
  }
312
352
  ],
313
353
  "description": "Move the virtual cursor to the item at `index`."
@@ -1,4 +1,4 @@
1
- import { R as e } from "./rc-menu-DJ8upIAd.js";
1
+ import { R as e } from "./rc-menu-zM-Q3-uP.js";
2
2
  customElements.get("rc-menu") || customElements.define("rc-menu", e);
3
3
  export {
4
4
  e as RCMenu
@@ -1,146 +1,13 @@
1
1
  import { css as u, LitElement as m, html as d } from "lit";
2
2
  import { property as h } from "lit/decorators.js";
3
- import { ActiveDescendantController as v, isFocusable as s } from "@rcarls/rc-common";
4
- const b = u`
5
- :host {
6
- display: flex;
7
- flex-direction: column;
8
- min-width: var(--rc-menu-min-width, 10em);
9
- padding-block: var(--rc-menu-padding-block, var(--rc-control-padding-block, 0.25em));
10
- background: var(--rc-menu-background, var(--rc-surface, Canvas));
11
- border: var(--rc-menu-border, var(--rc-border, 1px solid ButtonBorder));
12
- border-radius: var(--rc-menu-radius, var(--rc-control-radius, 0));
13
- box-shadow: var(
14
- --rc-menu-shadow,
15
- var(--rc-shadow, 0 2px 8px color-mix(in srgb, CanvasText 15%, transparent))
16
- );
17
- color: var(--rc-menu-color, var(--rc-field-text, CanvasText));
18
- font-family: var(--rc-font-family, inherit);
19
- font-size: var(--rc-font-size, inherit);
20
- line-height: var(--rc-line-height, normal);
21
- overflow: hidden;
22
- }
23
-
24
- :host(:focus-visible) {
25
- outline: var(--rc-focus-ring, auto);
26
- outline-offset: var(--rc-focus-ring-offset, 0);
27
- }
28
- `;
29
- var p = Object.defineProperty, g = (o, e, t, r) => {
30
- for (var n = void 0, i = o.length - 1, c; i >= 0; i--)
31
- (c = o[i]) && (n = c(e, t, n) || n);
32
- return n && p(e, t, n), n;
3
+ import { ActiveDescendantController as v, isFocusable as s, cssText as b } from "@rcarls/rc-common";
4
+ const p = u`:host{box-sizing:border-box;min-width:var(--rc-menu-min-width,10em);padding-block:var(--rc-menu-padding-block,var(--rc-popup-padding-block,var(--rc-control-padding-block,.25em)));background:var(--rc-menu-background,var(--rc-popup-background,var(--rc-surface,Canvas)));border:var(--rc-menu-border,var(--rc-popup-border,var(--rc-border,1px solid ButtonBorder)));border-radius:var(--rc-menu-radius,var(--rc-popup-radius,var(--rc-radius-sm,0)));box-shadow:var(--rc-menu-shadow,var(--rc-popup-shadow,var(--rc-shadow,0 2px 8px color-mix(in srgb, CanvasText 15%, transparent))));color:var(--rc-menu-color,var(--rc-popup-color,var(--rc-field-text,CanvasText)));font-family:var(--rc-item-font-family,var(--rc-font-family,inherit));font-size:var(--rc-item-font-size,var(--rc-font-size,inherit));font-weight:var(--rc-item-font-weight,inherit);line-height:var(--rc-item-line-height,var(--rc-line-height,normal));letter-spacing:var(--rc-item-letter-spacing,inherit);max-inline-size:var(--rc-menu-max-inline-size,calc(100dvi - .5rem));max-block-size:var(--rc-menu-max-block-size,calc(100dvb - .5rem));overscroll-behavior:contain;scrollbar-gutter:stable;flex-direction:column;display:flex;overflow:auto}:host(:focus-visible){outline:var(--rc-focus-ring,auto);outline-offset:var(--rc-focus-ring-offset,0)}`;
5
+ var g = Object.defineProperty, f = (c, e, t, r) => {
6
+ for (var n = void 0, i = c.length - 1, o; i >= 0; i--)
7
+ (o = c[i]) && (n = o(e, t, n) || n);
8
+ return n && g(e, t, n), n;
33
9
  };
34
- const f = ["menuitem", "menuitemcheckbox", "menuitemradio"], k = `
35
- @layer rc-base {
36
- /* Item base layout */
37
- rc-menu [role='menuitem'],
38
- rc-menu [role='menuitemcheckbox'],
39
- rc-menu [role='menuitemradio'],
40
- rc-menu button:disabled {
41
- display: flex;
42
- align-items: center;
43
- gap: var(--rc-menu-item-gap, var(--rc-item-gap, 0.5em));
44
- min-block-size: var(--rc-menu-item-min-block-size, 0px);
45
- width: 100%;
46
- text-align: start;
47
- padding: var(--rc-menu-item-padding-block, var(--rc-item-padding-block, 0.3em))
48
- var(--rc-menu-item-padding-inline, var(--rc-item-padding-inline, 0.75em));
49
- appearance: none;
50
- box-sizing: border-box;
51
- border: none;
52
- background: transparent;
53
- text-decoration: none;
54
- color: inherit;
55
- font: inherit;
56
- cursor: default;
57
- user-select: none;
58
- outline: none;
59
- transition: var(--rc-menu-item-transition);
60
- }
61
-
62
- /* Pointer hover */
63
- rc-menu [role='menuitem']:hover,
64
- rc-menu [role='menuitemcheckbox']:hover,
65
- rc-menu [role='menuitemradio']:hover {
66
- background: var(--rc-menu-hover-bg, color-mix(in srgb, Highlight 8%, transparent));
67
- color: var(--rc-menu-hover-color, inherit);
68
- }
69
-
70
- /* Virtual cursor (set by ActiveDescendantController) */
71
- rc-menu [role='menuitem'][data-active],
72
- rc-menu [role='menuitemcheckbox'][data-active],
73
- rc-menu [role='menuitemradio'][data-active] {
74
- background: var(--rc-menu-active-bg, color-mix(in srgb, Highlight 8%, transparent));
75
- color: var(--rc-menu-active-color, inherit);
76
- }
77
-
78
- /* Check/radio indicator — ::before acts as a fixed-width leading column.
79
- Content is empty (unchecked) or a Unicode symbol (checked/mixed).
80
- Semantic state is conveyed by aria-checked; the visual symbol is decorative. */
81
- rc-menu [role='menuitemcheckbox']::before,
82
- rc-menu [role='menuitemradio']::before {
83
- content: '';
84
- flex: 0 0 var(--rc-menu-check-size, 1.25em);
85
- text-align: center;
86
- line-height: 1;
87
- color: var(--rc-menu-check-color, inherit);
88
- }
89
-
90
- rc-menu [role='menuitemcheckbox'][aria-checked='true']::before {
91
- content: '✓';
92
- }
93
-
94
- rc-menu [role='menuitemcheckbox'][aria-checked='mixed']::before {
95
- content: '−';
96
- }
97
-
98
- rc-menu [role='menuitemradio'][aria-checked='true']::before {
99
- content: '•';
100
- }
101
-
102
- /* Trailing label — keyboard shortcut or hint, pushed to the inline-end of the item */
103
- rc-menu [data-menu-shortcut] {
104
- margin-inline-start: auto;
105
- font-size: var(--rc-menu-shortcut-size, 0.8em);
106
- color: var(--rc-menu-shortcut-color, GrayText);
107
- white-space: nowrap;
108
- }
109
-
110
- /* Separators */
111
- rc-menu [role='separator'],
112
- rc-menu hr {
113
- border: none;
114
- border-block-start: var(--rc-menu-separator-border, var(--rc-border, 1px solid ButtonBorder));
115
- margin-block: var(--rc-menu-separator-margin-block, var(--rc-control-gap, 0.25em));
116
- margin-inline: var(--rc-menu-separator-margin-inline, 0px);
117
- }
118
-
119
- /* Group containers */
120
- rc-menu [role='group'] {
121
- display: flex;
122
- flex-direction: column;
123
- align-items: stretch;
124
- }
125
-
126
- /* Optional section label (non-interactive heading above a group of items) */
127
- rc-menu [data-group-label] {
128
- padding-block: var(--rc-menu-group-label-padding-block, 0.1em);
129
- padding-inline: var(--rc-menu-item-padding-inline, 0.75em);
130
- color: var(--rc-menu-group-label-color, GrayText);
131
- user-select: none;
132
- pointer-events: none;
133
- }
134
-
135
- /* Disabled items */
136
- rc-menu button:disabled,
137
- rc-menu [aria-disabled='true'] {
138
- color: var(--rc-menu-disabled-color, var(--rc-text-disabled, GrayText));
139
- opacity: var(--rc-menu-disabled-opacity, var(--rc-disabled-opacity, 0.55));
140
- pointer-events: none;
141
- }
142
- }
143
- `;
10
+ const k = ["menuitem", "menuitemcheckbox", "menuitemradio"], x = b`@layer rc-base{rc-menu [role=menuitem],rc-menu [role=menuitemcheckbox],rc-menu [role=menuitemradio],rc-menu button:disabled{align-items:center;gap:var(--rc-menu-item-gap,var(--rc-item-gap,.5em));min-block-size:var(--rc-menu-item-min-block-size,0px);text-align:start;width:100%;padding:var(--rc-menu-item-padding-block,var(--rc-item-padding-block,.3em)) var(--rc-menu-item-padding-inline,var(--rc-item-padding-inline,.75em));appearance:none;box-sizing:border-box;color:inherit;font:inherit;cursor:default;user-select:none;transition:var(--rc-menu-item-transition);background:0 0;border:none;outline:none;flex-shrink:0;text-decoration:none;display:flex}rc-menu [role=menuitem]:hover,rc-menu [role=menuitemcheckbox]:hover,rc-menu [role=menuitemradio]:hover{background:var(--rc-menu-hover-bg,color-mix(in srgb, Highlight 8%, transparent));color:var(--rc-menu-hover-color,inherit)}rc-menu [role=menuitem][data-active],rc-menu [role=menuitemcheckbox][data-active],rc-menu [role=menuitemradio][data-active]{background:var(--rc-menu-active-bg,color-mix(in srgb, Highlight 8%, transparent));color:var(--rc-menu-active-color,inherit)}rc-menu [role=menuitemcheckbox]:after,rc-menu [role=menuitemradio]:after{content:"";flex:0 0 var(--rc-menu-check-size,1.25em);text-align:center;color:var(--rc-menu-check-color,inherit);margin-inline-start:auto;line-height:1}rc-menu [role=menuitemcheckbox]:has(:is([data-rc-menu-shortcut],[data-menu-shortcut])):after,rc-menu [role=menuitemradio]:has(:is([data-rc-menu-shortcut],[data-menu-shortcut])):after{margin-inline-start:0}rc-menu [role=menuitemcheckbox][aria-checked=true]:after{content:"✓"}rc-menu [role=menuitemcheckbox][aria-checked=mixed]:after{content:"−"}rc-menu [role=menuitemradio][aria-checked=true]:after{content:"•"}rc-menu [data-rc-menu-leading],rc-menu [data-rc-menu-trailing]{flex:none;justify-content:center;align-items:center;display:inline-flex}rc-menu :is([role=menuitem],[role=menuitemcheckbox],[role=menuitemradio]) :is([data-rc-icon],[data-rc-menu-leading],[data-rc-menu-icon]){font-size:var(--rc-item-icon-size,inherit);line-height:var(--rc-item-icon-size,inherit);flex:none}rc-menu [data-rc-menu-label]{flex:auto;min-inline-size:0}rc-menu [data-rc-menu-trailing],rc-menu [data-rc-menu-shortcut],rc-menu [data-menu-shortcut]{margin-inline-start:auto}rc-menu [data-rc-menu-shortcut],rc-menu [data-menu-shortcut]{font-size:var(--rc-menu-shortcut-size,.8em);color:var(--rc-menu-shortcut-color,GrayText);white-space:nowrap}rc-menu [role=separator],rc-menu hr{border:none;border-block-start:var(--rc-menu-separator-border,var(--rc-border,1px solid ButtonBorder));margin-block:var(--rc-menu-separator-margin-block,var(--rc-control-gap,.25em));margin-inline:var(--rc-menu-separator-margin-inline,0px)}rc-menu [role=group]{flex-direction:column;align-items:stretch;display:flex}rc-menu [data-group-label]{padding-block:var(--rc-menu-group-label-padding-block,.1em);padding-inline:var(--rc-menu-item-padding-inline,.75em);color:var(--rc-menu-group-label-color,GrayText);user-select:none;pointer-events:none}rc-menu button:disabled,rc-menu [aria-disabled=true]{color:var(--rc-menu-disabled-color,var(--rc-text-disabled,GrayText));opacity:var(--rc-menu-disabled-opacity,var(--rc-disabled-opacity,.55));pointer-events:none}}`;
144
11
  var a;
145
12
  const l = (a = class extends m {
146
13
  constructor() {
@@ -212,7 +79,7 @@ const l = (a = class extends m {
212
79
  return;
213
80
  a._$styledRoots.add(e);
214
81
  const t = document.createElement("style");
215
- t.setAttribute("data-rc-light-dom-base", "rc-menu"), t.textContent = k, e instanceof Document ? e.head.appendChild(t) : e.appendChild(t);
82
+ t.setAttribute("data-rc-light-dom-base", "rc-menu"), t.textContent = x, e instanceof Document ? e.head.appendChild(t) : e.appendChild(t);
216
83
  }
217
84
  connectedCallback() {
218
85
  super.connectedCallback(), this.hasAttribute("role") || this.setAttribute("role", "menu"), this.setAttribute("tabindex", "0"), this._syncAriaLabel(), this.addEventListener("keydown", this._onKeydown), this.addEventListener("blur", this._onBlur), this.addEventListener("click", this._onClick), a._ensureBaseStyles(this.getRootNode());
@@ -241,7 +108,7 @@ const l = (a = class extends m {
241
108
  /**
242
109
  * Move the virtual cursor to a specific item.
243
110
  *
244
- * @param $item - The element to make active. No-op when null or undefined.
111
+ * @param $item - the element to make active. No-op when null or undefined
245
112
  */
246
113
  focusItem(e) {
247
114
  e && (this.focus(), this._activeDescendantCtrl.navigateToItem(e));
@@ -249,7 +116,7 @@ const l = (a = class extends m {
249
116
  /**
250
117
  * Move the virtual cursor to the item at `index`.
251
118
  *
252
- * @param index - Zero-based index into the navigable items array.
119
+ * @param index - zero-based index into the navigable items array
253
120
  */
254
121
  focusItemAt(e) {
255
122
  this.focus(), this._activeDescendantCtrl.navigateTo(e);
@@ -288,7 +155,7 @@ const l = (a = class extends m {
288
155
  _initMenuItems() {
289
156
  this._$menuItems.forEach((e) => {
290
157
  const t = e.getAttribute("role");
291
- (!t || !f.includes(t)) && e.setAttribute("role", "menuitem"), e.setAttribute("tabindex", "-1"), (e.getAttribute("role") === "menuitemcheckbox" || e.getAttribute("role") === "menuitemradio") && !e.hasAttribute("aria-checked") && e.setAttribute("aria-checked", "false");
158
+ (!t || !k.includes(t)) && e.setAttribute("role", "menuitem"), e.setAttribute("tabindex", "-1"), (e.getAttribute("role") === "menuitemcheckbox" || e.getAttribute("role") === "menuitemradio") && !e.hasAttribute("aria-checked") && e.setAttribute("aria-checked", "false");
292
159
  });
293
160
  }
294
161
  _applyCheckedState(e) {
@@ -304,12 +171,12 @@ const l = (a = class extends m {
304
171
  return "true";
305
172
  }
306
173
  }
307
- }, a.styles = [b], a._$styledRoots = /* @__PURE__ */ new Set(), a);
308
- g([
174
+ }, a.styles = [p], a._$styledRoots = /* @__PURE__ */ new Set(), a);
175
+ f([
309
176
  h({ type: String })
310
177
  ], l.prototype, "label");
311
- let C = l;
178
+ let A = l;
312
179
  export {
313
- C as R
180
+ A as R
314
181
  };
315
- //# sourceMappingURL=rc-menu-DJ8upIAd.js.map
182
+ //# sourceMappingURL=rc-menu-zM-Q3-uP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-menu-zM-Q3-uP.js","sources":["../src/rc-menu.styles.ts","../src/rc-menu.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const menuStyles = css`\n :host {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n min-width: var(--rc-menu-min-width, 10em);\n padding-block: var(\n --rc-menu-padding-block,\n var(--rc-popup-padding-block, var(--rc-control-padding-block, 0.25em))\n );\n background: var(--rc-menu-background, var(--rc-popup-background, var(--rc-surface, Canvas)));\n border: var(--rc-menu-border, var(--rc-popup-border, var(--rc-border, 1px solid ButtonBorder)));\n border-radius: var(--rc-menu-radius, var(--rc-popup-radius, var(--rc-radius-sm, 0)));\n box-shadow: var(\n --rc-menu-shadow,\n var(\n --rc-popup-shadow,\n var(--rc-shadow, 0 2px 8px color-mix(in srgb, CanvasText 15%, transparent))\n )\n );\n color: var(--rc-menu-color, var(--rc-popup-color, var(--rc-field-text, CanvasText)));\n font-family: var(--rc-item-font-family, var(--rc-font-family, inherit));\n font-size: var(--rc-item-font-size, var(--rc-font-size, inherit));\n font-weight: var(--rc-item-font-weight, inherit);\n line-height: var(--rc-item-line-height, var(--rc-line-height, normal));\n letter-spacing: var(--rc-item-letter-spacing, inherit);\n max-inline-size: var(--rc-menu-max-inline-size, calc(100dvi - 0.5rem));\n max-block-size: var(--rc-menu-max-block-size, calc(100dvb - 0.5rem));\n overflow: auto;\n overscroll-behavior: contain;\n scrollbar-gutter: stable;\n }\n\n :host(:focus-visible) {\n outline: var(--rc-focus-ring, auto);\n outline-offset: var(--rc-focus-ring-offset, 0);\n }\n`;\n\nexport default menuStyles;\n","import { LitElement, html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { ActiveDescendantController, cssText, isFocusable } from '@rcarls/rc-common';\n\nimport menuStyles from './rc-menu.styles.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-menu': RCMenu;\n }\n}\n\n/** Detail payload for the `rc-menu-activate` event. */\nexport interface RCMenuActivateEvent {\n /** The activated menu item element. */\n item: HTMLElement;\n\n /** The item's `data-value` or `value` attribute, or an empty string. */\n value: string;\n\n /** Trimmed text content of the activated item. */\n text: string;\n\n /** Current `aria-checked` state for checkbox/radio menu items. */\n checked?: 'true' | 'false' | 'mixed';\n}\n\n/** WAI-ARIA roles that are valid direct children of `role=\"menu\"`. */\nconst MENU_ITEM_ROLES = ['menuitem', 'menuitemcheckbox', 'menuitemradio'] as const;\n\n/** Structural CSS for light-DOM menu items, injected into the containing document or shadow root. */\nconst LIGHT_DOM_CSS = cssText`\n@layer rc-base {\n /* Item base layout */\n rc-menu [role='menuitem'],\n rc-menu [role='menuitemcheckbox'],\n rc-menu [role='menuitemradio'],\n rc-menu button:disabled {\n display: flex;\n flex-shrink: 0;\n align-items: center;\n gap: var(--rc-menu-item-gap, var(--rc-item-gap, 0.5em));\n min-block-size: var(--rc-menu-item-min-block-size, 0px);\n width: 100%;\n text-align: start;\n padding: var(--rc-menu-item-padding-block, var(--rc-item-padding-block, 0.3em))\n var(--rc-menu-item-padding-inline, var(--rc-item-padding-inline, 0.75em));\n appearance: none;\n box-sizing: border-box;\n border: none;\n background: transparent;\n text-decoration: none;\n color: inherit;\n font: inherit;\n cursor: default;\n user-select: none;\n outline: none;\n transition: var(--rc-menu-item-transition);\n }\n\n /* Pointer hover */\n rc-menu [role='menuitem']:hover,\n rc-menu [role='menuitemcheckbox']:hover,\n rc-menu [role='menuitemradio']:hover {\n background: var(--rc-menu-hover-bg, color-mix(in srgb, Highlight 8%, transparent));\n color: var(--rc-menu-hover-color, inherit);\n }\n\n /* Virtual cursor (set by ActiveDescendantController) */\n rc-menu [role='menuitem'][data-active],\n rc-menu [role='menuitemcheckbox'][data-active],\n rc-menu [role='menuitemradio'][data-active] {\n background: var(--rc-menu-active-bg, color-mix(in srgb, Highlight 8%, transparent));\n color: var(--rc-menu-active-color, inherit);\n }\n\n /* Check/radio indicator — ::after acts as a fixed-width trailing column,\n pushed to the item's inline-end regardless of label length (same\n positioning as the [data-rc-menu-shortcut] slot below). Trailing rather\n than leading so it coexists with a leading icon a consumer supplies for\n the item itself (a radio/checkbox item's own icon and its checked state\n are different things; leading is already spoken for). Content is empty\n (unchecked) or a Unicode symbol (checked/mixed). Semantic state is\n conveyed by aria-checked; the visual symbol is decorative. */\n rc-menu [role='menuitemcheckbox']::after,\n rc-menu [role='menuitemradio']::after {\n content: '';\n flex: 0 0 var(--rc-menu-check-size, 1.25em);\n margin-inline-start: auto;\n text-align: center;\n line-height: 1;\n color: var(--rc-menu-check-color, inherit);\n }\n\n /* A shortcut owns the auto margin when both trailing affordances exist,\n keeping the shortcut and selection indicator in one end-aligned group. */\n rc-menu [role='menuitemcheckbox']:has(:is([data-rc-menu-shortcut], [data-menu-shortcut]))::after,\n rc-menu [role='menuitemradio']:has(:is([data-rc-menu-shortcut], [data-menu-shortcut]))::after {\n margin-inline-start: 0;\n }\n\n rc-menu [role='menuitemcheckbox'][aria-checked='true']::after {\n content: '✓';\n }\n\n rc-menu [role='menuitemcheckbox'][aria-checked='mixed']::after {\n content: '−';\n }\n\n rc-menu [role='menuitemradio'][aria-checked='true']::after {\n content: '•';\n }\n\n rc-menu [data-rc-menu-leading],\n rc-menu [data-rc-menu-trailing] {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n rc-menu :is([role='menuitem'], [role='menuitemcheckbox'], [role='menuitemradio'])\n :is([data-rc-icon], [data-rc-menu-leading], [data-rc-menu-icon]) {\n flex: none;\n font-size: var(--rc-item-icon-size, inherit);\n line-height: var(--rc-item-icon-size, inherit);\n }\n\n rc-menu [data-rc-menu-label] {\n flex: 1 1 auto;\n min-inline-size: 0;\n }\n\n /* Trailing label — keyboard shortcut or hint, pushed to the inline-end of the item */\n rc-menu [data-rc-menu-trailing],\n rc-menu [data-rc-menu-shortcut],\n rc-menu [data-menu-shortcut] {\n margin-inline-start: auto;\n }\n\n rc-menu [data-rc-menu-shortcut],\n rc-menu [data-menu-shortcut] {\n font-size: var(--rc-menu-shortcut-size, 0.8em);\n color: var(--rc-menu-shortcut-color, GrayText);\n white-space: nowrap;\n }\n\n /* Separators */\n rc-menu [role='separator'],\n rc-menu hr {\n border: none;\n border-block-start: var(--rc-menu-separator-border, var(--rc-border, 1px solid ButtonBorder));\n margin-block: var(--rc-menu-separator-margin-block, var(--rc-control-gap, 0.25em));\n margin-inline: var(--rc-menu-separator-margin-inline, 0px);\n }\n\n /* Group containers */\n rc-menu [role='group'] {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n }\n\n /* Optional section label (non-interactive heading above a group of items) */\n rc-menu [data-group-label] {\n padding-block: var(--rc-menu-group-label-padding-block, 0.1em);\n padding-inline: var(--rc-menu-item-padding-inline, 0.75em);\n color: var(--rc-menu-group-label-color, GrayText);\n user-select: none;\n pointer-events: none;\n }\n\n /* Disabled items */\n rc-menu button:disabled,\n rc-menu [aria-disabled='true'] {\n color: var(--rc-menu-disabled-color, var(--rc-text-disabled, GrayText));\n opacity: var(--rc-menu-disabled-opacity, var(--rc-disabled-opacity, 0.55));\n pointer-events: none;\n }\n}\n`;\n\n/**\n * Menu popup for command surfaces with keyboard navigation and typed activation events,\n * following the WAI-ARIA Menu pattern.\n *\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-menu rc-menu docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/menu/ WAI-ARIA Menu pattern}\n *\n * @slot default - Menu items, groups, and separators. Supported content model:\n * - Focusable elements (`<button>`, `<a>`, `[tabindex]`) become navigable `role=\"menuitem\"` entries.\n * - `role=\"menuitemcheckbox\"` / `role=\"menuitemradio\"` elements get a trailing indicator column via `::after`\n * (coexists with a leading icon the item supplies itself); `aria-checked` is initialized when missing and\n * updated on activation.\n * - `role=\"group\"` divs group related items; label them with `aria-label` or `aria-labelledby`. Optionally\n * add a visible `[data-group-label]` element as first child of the group for section headings.\n * - `role=\"separator\"` / `<hr>` produce horizontal dividers between sections.\n * - Within any item, use `[data-rc-menu-leading]`, `[data-rc-menu-label]`, and\n * `[data-rc-menu-trailing]` to identify content columns. `[data-rc-menu-shortcut]`\n * (and the legacy `[data-menu-shortcut]`) is pushed to the inline-end edge.\n * - Nested menu triggers supply their own trailing indicator through `rc-menu-button`'s `indicator` slot.\n *\n * @fires rc-menu-activate - Fired when a menu item is activated via keyboard (Enter/Space) or pointer click.\n * @fires rc-menu-close - Fired when Escape is pressed.\n *\n * @attr label - Accessible label for the menu; synced to `aria-label` on the host.\n *\n * @cssprop [--rc-menu-min-width=10em] - Minimum width of the menu panel.\n * @cssprop [--rc-menu-padding-block=var(--rc-popup-padding-block)] - Block (top/bottom) padding inside the panel.\n * @cssprop [--rc-menu-background=var(--rc-popup-background)] - Background color.\n * @cssprop [--rc-menu-border=var(--rc-popup-border)] - Border.\n * @cssprop [--rc-menu-radius=var(--rc-popup-radius)] - Menu panel border radius.\n * @cssprop [--rc-menu-shadow=var(--rc-popup-shadow)] - Box shadow.\n * @cssprop [--rc-menu-color=var(--rc-popup-color)] - Text color.\n * @cssprop [--rc-menu-max-inline-size=calc(100dvi - 0.5rem)] - Viewport-aware maximum inline size.\n * @cssprop [--rc-menu-max-block-size=calc(100dvb - 0.5rem)] - Viewport-aware maximum block size; taller menus scroll.\n * @cssprop [--rc-menu-item-min-block-size=0] - Minimum block size for menu item rows.\n * @cssprop [--rc-menu-item-padding-block=var(--rc-item-padding-block)] - Menu item block-axis padding.\n * @cssprop [--rc-menu-item-padding-inline=var(--rc-item-padding-inline)] - Menu item inline-axis padding.\n * @cssprop [--rc-menu-item-gap=var(--rc-item-gap)] - Gap between flex children inside each item.\n * @cssprop [--rc-menu-item-transition] - CSS transition applied to each item row.\n * @cssprop [--rc-menu-hover-bg=color-mix(in srgb, Highlight 8%, transparent)] - Pointer-hover background.\n * @cssprop [--rc-menu-hover-color=inherit] - Pointer-hover text color.\n * @cssprop [--rc-menu-active-bg=color-mix(in srgb, Highlight 8%, transparent)] - Virtual-cursor active background.\n * @cssprop [--rc-menu-active-color=inherit] - Virtual-cursor active text color.\n * @cssprop [--rc-menu-check-size=1.25em] - Width of the trailing indicator column for checkbox/radio items.\n * @cssprop [--rc-menu-check-color=inherit] - Color of the check/radio symbol.\n * @cssprop [--rc-menu-shortcut-size=0.8em] - Font size of `[data-rc-menu-shortcut]` labels.\n * @cssprop [--rc-menu-shortcut-color=GrayText] - Text color of `[data-rc-menu-shortcut]` labels.\n * @cssprop [--rc-menu-disabled-color=GrayText] - Disabled menu item text color.\n * @cssprop [--rc-menu-disabled-opacity=var(--rc-disabled-opacity)] - Disabled menu item opacity.\n * @cssprop [--rc-menu-separator-border=1px solid ButtonBorder] - Separator border.\n * @cssprop [--rc-menu-separator-margin-block=var(--rc-control-gap)] - Separator block-axis margin.\n * @cssprop [--rc-menu-separator-margin-inline=0px] - Separator inline margin; set to match item padding for inset separators.\n * @cssprop [--rc-menu-group-label-padding-block=0.1em] - Block padding on `[data-group-label]` section headings.\n * @cssprop [--rc-menu-group-label-color=GrayText] - Text color of `[data-group-label]` section headings.\n * @cssprop [--rc-item-font-family=var(--rc-font-family)] - Item font family; shared with listbox and adaptive-menu items.\n * @cssprop [--rc-item-font-size=var(--rc-font-size)] - Item font size; shared with listbox and adaptive-menu items.\n * @cssprop [--rc-item-font-weight=inherit] - Item font weight; shared with listbox and adaptive-menu items.\n * @cssprop [--rc-item-line-height=var(--rc-line-height)] - Item line height; shared with listbox and adaptive-menu items.\n * @cssprop [--rc-item-letter-spacing=inherit] - Item letter spacing; shared with listbox and adaptive-menu items.\n * @cssprop [--rc-item-icon-size=inherit] - Size of icons marked with `data-rc-icon`, `data-rc-menu-leading`, or `data-rc-menu-icon`.\n */\nexport class RCMenu extends LitElement {\n static styles = [menuStyles];\n\n private static readonly _$styledRoots = new Set<Document | ShadowRoot>();\n\n private static _ensureBaseStyles($root: Document | ShadowRoot): void {\n if (RCMenu._$styledRoots.has($root)) {\n return;\n }\n\n RCMenu._$styledRoots.add($root);\n\n const $style = document.createElement('style');\n\n $style.setAttribute('data-rc-light-dom-base', 'rc-menu');\n $style.textContent = LIGHT_DOM_CSS;\n\n if ($root instanceof Document) {\n $root.head.appendChild($style);\n } else {\n $root.appendChild($style);\n }\n }\n\n /**\n * Accessible label for this menu. Synced to `aria-label` on the host.\n *\n * Prefer `aria-labelledby` for a visible label associated via ID.\n */\n @property({ type: String })\n label = '';\n\n protected _$menuItems: Element[] = [];\n\n protected readonly _activeDescendantCtrl = new ActiveDescendantController(this, {\n host: () => this,\n items: () => this._$menuItems,\n });\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'menu');\n }\n\n this.setAttribute('tabindex', '0');\n this._syncAriaLabel();\n\n this.addEventListener('keydown', this._onKeydown);\n this.addEventListener('blur', this._onBlur);\n this.addEventListener('click', this._onClick);\n\n RCMenu._ensureBaseStyles(this.getRootNode() as Document | ShadowRoot);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n\n this.removeEventListener('keydown', this._onKeydown);\n this.removeEventListener('blur', this._onBlur);\n this.removeEventListener('click', this._onClick);\n }\n\n protected override updated(changed: Map<PropertyKey, unknown>): void {\n if (changed.has('label')) {\n this._syncAriaLabel();\n }\n }\n\n protected override render() {\n return html`<slot @slotchange=${this._onSlotChange}></slot>`;\n }\n\n /** All navigable menu item elements in document order. */\n get items(): readonly Element[] {\n return this._$menuItems;\n }\n\n /** Move the virtual cursor and DOM focus to the first navigable item. */\n focusFirst(): void {\n this.focus();\n this._activeDescendantCtrl.navigateToFirst();\n }\n\n /** Move the virtual cursor and DOM focus to the last navigable item. */\n focusLast(): void {\n this.focus();\n this._activeDescendantCtrl.navigateToLast();\n }\n\n /**\n * Move the virtual cursor to a specific item.\n *\n * @param $item - the element to make active. No-op when null or undefined\n */\n focusItem($item?: Element | null): void {\n if (!$item) {\n return;\n }\n\n this.focus();\n this._activeDescendantCtrl.navigateToItem($item);\n }\n\n /**\n * Move the virtual cursor to the item at `index`.\n *\n * @param index - zero-based index into the navigable items array\n */\n focusItemAt(index: number): void {\n this.focus();\n this._activeDescendantCtrl.navigateTo(index);\n }\n\n protected _syncAriaLabel(): void {\n if (this.label) {\n this.setAttribute('aria-label', this.label);\n } else {\n this.removeAttribute('aria-label');\n }\n }\n\n protected _onSlotChange(e: Event): void {\n const $slot = e.currentTarget as HTMLSlotElement;\n\n this._$menuItems = this._collectMenuItems($slot);\n this._initMenuItems();\n }\n\n /**\n * Collects navigable menu items from the slot, supporting `role=\"group\"`\n * containers and skipping `role=\"separator\"` elements.\n *\n * Direct focusable children are included as-is. Elements with\n * `role=\"group\"` are traversed one level deep so their focusable children\n * participate in arrow-key navigation. Separators and non-focusable\n * container elements are excluded.\n */\n protected _collectMenuItems($slot: HTMLSlotElement): Element[] {\n const $items: Element[] = [];\n\n for (const $el of $slot.assignedElements()) {\n const role = $el.getAttribute('role');\n\n if (role === 'separator') {\n continue;\n }\n\n if (role === 'group') {\n for (const $child of $el.children) {\n if (isFocusable($child)) {\n $items.push($child);\n }\n }\n\n continue;\n }\n\n if (isFocusable($el)) {\n $items.push($el);\n }\n }\n\n return $items;\n }\n\n protected _initMenuItems(): void {\n this._$menuItems.forEach(($el) => {\n const existingRole = $el.getAttribute('role');\n\n // Preserve explicit roles; only assign the default when none is present.\n if (\n !existingRole ||\n !MENU_ITEM_ROLES.includes(existingRole as (typeof MENU_ITEM_ROLES)[number])\n ) {\n $el.setAttribute('role', 'menuitem');\n }\n\n $el.setAttribute('tabindex', '-1');\n\n if (\n ($el.getAttribute('role') === 'menuitemcheckbox' ||\n $el.getAttribute('role') === 'menuitemradio') &&\n !$el.hasAttribute('aria-checked')\n ) {\n $el.setAttribute('aria-checked', 'false');\n }\n });\n }\n\n protected _applyCheckedState($item: HTMLElement): 'true' | 'false' | 'mixed' | undefined {\n const role = $item.getAttribute('role');\n\n if (role === 'menuitemcheckbox') {\n const checked = $item.getAttribute('aria-checked') === 'true' ? 'false' : 'true';\n\n $item.setAttribute('aria-checked', checked);\n\n return checked;\n }\n\n if (role === 'menuitemradio') {\n const $group = $item.closest('[role=\"group\"]');\n const $scope = $group && this.contains($group) ? $group : this;\n\n for (const $radio of $scope.querySelectorAll<HTMLElement>('[role=\"menuitemradio\"]')) {\n if ($radio.closest('rc-menu') === this) {\n $radio.setAttribute('aria-checked', $radio === $item ? 'true' : 'false');\n }\n }\n\n return 'true';\n }\n\n return undefined;\n }\n\n protected _onKeydown = (e: KeyboardEvent): void => {\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n e.stopPropagation();\n\n if (this._activeDescendantCtrl.activeItem) {\n this._activeDescendantCtrl.navigate(1);\n } else {\n this._activeDescendantCtrl.navigateToFirst();\n }\n\n break;\n }\n\n case 'ArrowUp': {\n e.preventDefault();\n e.stopPropagation();\n\n if (this._activeDescendantCtrl.activeItem) {\n this._activeDescendantCtrl.navigate(-1);\n } else {\n this._activeDescendantCtrl.navigateToLast();\n }\n\n break;\n }\n\n case 'Home': {\n e.preventDefault();\n e.stopPropagation();\n\n this._activeDescendantCtrl.navigateToFirst();\n\n break;\n }\n\n case 'End': {\n e.preventDefault();\n e.stopPropagation();\n\n this._activeDescendantCtrl.navigateToLast();\n\n break;\n }\n\n case 'Enter':\n // Falls through so both activation keys share the same handler.\n\n case ' ': {\n e.preventDefault();\n e.stopPropagation();\n\n const $active = this._activeDescendantCtrl.activeItem;\n\n if ($active) {\n // _onClick dispatches rc-menu-activate when the synthetic click bubbles up.\n ($active as HTMLElement).click();\n }\n\n break;\n }\n\n case 'Escape': {\n e.preventDefault();\n e.stopPropagation();\n\n this.dispatchEvent(\n new CustomEvent('rc-menu-close', {\n bubbles: true,\n composed: true,\n detail: { reason: 'escape' },\n }),\n );\n\n break;\n }\n }\n };\n\n protected _onBlur = (): void => {\n this._activeDescendantCtrl.clear();\n };\n\n protected _onClick = (e: MouseEvent): void => {\n const $target = e.target as Element;\n const $item = $target.closest<HTMLElement>(\n '[role=\"menuitem\"],[role=\"menuitemcheckbox\"],[role=\"menuitemradio\"]',\n );\n\n if (!$item || !this.contains($item)) {\n return;\n }\n\n if ($item.matches(':disabled, [aria-disabled=\"true\"]')) {\n return;\n }\n\n const checked = this._applyCheckedState($item);\n\n this.dispatchEvent(\n new CustomEvent<RCMenuActivateEvent>('rc-menu-activate', {\n bubbles: true,\n composed: true,\n detail: {\n item: $item,\n value: $item.dataset.value ?? $item.getAttribute('value') ?? '',\n text: $item.textContent?.trim() ?? '',\n checked,\n },\n }),\n );\n };\n}\n\nexport default RCMenu;\n"],"names":["menuStyles","css","MENU_ITEM_ROLES","LIGHT_DOM_CSS","cssText","_RCMenu","_a","LitElement","ActiveDescendantController","$active","$item","checked","$root","$style","changed","html","index","$slot","$items","$el","role","$child","isFocusable","existingRole","$group","$scope","$radio","__decorateClass","property","RCMenu"],"mappings":"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"}
package/dist/rc-menu.js CHANGED
@@ -1,4 +1,4 @@
1
- import { R as r } from "./rc-menu-DJ8upIAd.js";
1
+ import { R as r } from "./rc-menu-zM-Q3-uP.js";
2
2
  export {
3
3
  r as RCMenu
4
4
  };
@@ -1 +1 @@
1
- export * from './rc-menu';
1
+ export * from './rc-menu.js';
@@ -26,12 +26,15 @@ export interface RCMenuActivateEvent {
26
26
  *
27
27
  * @slot default - Menu items, groups, and separators. Supported content model:
28
28
  * - Focusable elements (`<button>`, `<a>`, `[tabindex]`) become navigable `role="menuitem"` entries.
29
- * - `role="menuitemcheckbox"` / `role="menuitemradio"` elements get a leading indicator column via `::before`;
30
- * `aria-checked` is initialized when missing and updated on activation.
29
+ * - `role="menuitemcheckbox"` / `role="menuitemradio"` elements get a trailing indicator column via `::after`
30
+ * (coexists with a leading icon the item supplies itself); `aria-checked` is initialized when missing and
31
+ * updated on activation.
31
32
  * - `role="group"` divs group related items; label them with `aria-label` or `aria-labelledby`. Optionally
32
33
  * add a visible `[data-group-label]` element as first child of the group for section headings.
33
34
  * - `role="separator"` / `<hr>` produce horizontal dividers between sections.
34
- * - Within any item, `[data-menu-shortcut]` elements are pushed to the inline-end edge for keyboard hints.
35
+ * - Within any item, use `[data-rc-menu-leading]`, `[data-rc-menu-label]`, and
36
+ * `[data-rc-menu-trailing]` to identify content columns. `[data-rc-menu-shortcut]`
37
+ * (and the legacy `[data-menu-shortcut]`) is pushed to the inline-end edge.
35
38
  * - Nested menu triggers supply their own trailing indicator through `rc-menu-button`'s `indicator` slot.
36
39
  *
37
40
  * @fires rc-menu-activate - Fired when a menu item is activated via keyboard (Enter/Space) or pointer click.
@@ -40,12 +43,14 @@ export interface RCMenuActivateEvent {
40
43
  * @attr label - Accessible label for the menu; synced to `aria-label` on the host.
41
44
  *
42
45
  * @cssprop [--rc-menu-min-width=10em] - Minimum width of the menu panel.
43
- * @cssprop [--rc-menu-padding-block=0.25em] - Block (top/bottom) padding inside the panel.
44
- * @cssprop [--rc-menu-background=Canvas] - Background color; falls back through --rc-surface.
45
- * @cssprop [--rc-menu-border=1px solid ButtonBorder] - Border; falls back through --rc-border.
46
- * @cssprop [--rc-menu-radius=var(--rc-control-radius)] - Menu panel border radius.
47
- * @cssprop [--rc-menu-shadow=0 2px 8px color-mix(in srgb, CanvasText 15%, transparent)] - Box shadow; falls back through --rc-shadow.
48
- * @cssprop [--rc-menu-color=CanvasText] - Text color; falls back through --rc-field-text.
46
+ * @cssprop [--rc-menu-padding-block=var(--rc-popup-padding-block)] - Block (top/bottom) padding inside the panel.
47
+ * @cssprop [--rc-menu-background=var(--rc-popup-background)] - Background color.
48
+ * @cssprop [--rc-menu-border=var(--rc-popup-border)] - Border.
49
+ * @cssprop [--rc-menu-radius=var(--rc-popup-radius)] - Menu panel border radius.
50
+ * @cssprop [--rc-menu-shadow=var(--rc-popup-shadow)] - Box shadow.
51
+ * @cssprop [--rc-menu-color=var(--rc-popup-color)] - Text color.
52
+ * @cssprop [--rc-menu-max-inline-size=calc(100dvi - 0.5rem)] - Viewport-aware maximum inline size.
53
+ * @cssprop [--rc-menu-max-block-size=calc(100dvb - 0.5rem)] - Viewport-aware maximum block size; taller menus scroll.
49
54
  * @cssprop [--rc-menu-item-min-block-size=0] - Minimum block size for menu item rows.
50
55
  * @cssprop [--rc-menu-item-padding-block=var(--rc-item-padding-block)] - Menu item block-axis padding.
51
56
  * @cssprop [--rc-menu-item-padding-inline=var(--rc-item-padding-inline)] - Menu item inline-axis padding.
@@ -55,10 +60,10 @@ export interface RCMenuActivateEvent {
55
60
  * @cssprop [--rc-menu-hover-color=inherit] - Pointer-hover text color.
56
61
  * @cssprop [--rc-menu-active-bg=color-mix(in srgb, Highlight 8%, transparent)] - Virtual-cursor active background.
57
62
  * @cssprop [--rc-menu-active-color=inherit] - Virtual-cursor active text color.
58
- * @cssprop [--rc-menu-check-size=1.25em] - Width of the leading indicator column for checkbox/radio items.
63
+ * @cssprop [--rc-menu-check-size=1.25em] - Width of the trailing indicator column for checkbox/radio items.
59
64
  * @cssprop [--rc-menu-check-color=inherit] - Color of the check/radio symbol.
60
- * @cssprop [--rc-menu-shortcut-size=0.8em] - Font size of `[data-menu-shortcut]` labels.
61
- * @cssprop [--rc-menu-shortcut-color=GrayText] - Text color of `[data-menu-shortcut]` labels.
65
+ * @cssprop [--rc-menu-shortcut-size=0.8em] - Font size of `[data-rc-menu-shortcut]` labels.
66
+ * @cssprop [--rc-menu-shortcut-color=GrayText] - Text color of `[data-rc-menu-shortcut]` labels.
62
67
  * @cssprop [--rc-menu-disabled-color=GrayText] - Disabled menu item text color.
63
68
  * @cssprop [--rc-menu-disabled-opacity=var(--rc-disabled-opacity)] - Disabled menu item opacity.
64
69
  * @cssprop [--rc-menu-separator-border=1px solid ButtonBorder] - Separator border.
@@ -66,6 +71,12 @@ export interface RCMenuActivateEvent {
66
71
  * @cssprop [--rc-menu-separator-margin-inline=0px] - Separator inline margin; set to match item padding for inset separators.
67
72
  * @cssprop [--rc-menu-group-label-padding-block=0.1em] - Block padding on `[data-group-label]` section headings.
68
73
  * @cssprop [--rc-menu-group-label-color=GrayText] - Text color of `[data-group-label]` section headings.
74
+ * @cssprop [--rc-item-font-family=var(--rc-font-family)] - Item font family; shared with listbox and adaptive-menu items.
75
+ * @cssprop [--rc-item-font-size=var(--rc-font-size)] - Item font size; shared with listbox and adaptive-menu items.
76
+ * @cssprop [--rc-item-font-weight=inherit] - Item font weight; shared with listbox and adaptive-menu items.
77
+ * @cssprop [--rc-item-line-height=var(--rc-line-height)] - Item line height; shared with listbox and adaptive-menu items.
78
+ * @cssprop [--rc-item-letter-spacing=inherit] - Item letter spacing; shared with listbox and adaptive-menu items.
79
+ * @cssprop [--rc-item-icon-size=inherit] - Size of icons marked with `data-rc-icon`, `data-rc-menu-leading`, or `data-rc-menu-icon`.
69
80
  */
70
81
  export declare class RCMenu extends LitElement {
71
82
  static styles: import('lit').CSSResult[];
@@ -82,7 +93,7 @@ export declare class RCMenu extends LitElement {
82
93
  connectedCallback(): void;
83
94
  disconnectedCallback(): void;
84
95
  protected updated(changed: Map<PropertyKey, unknown>): void;
85
- protected render(): import('lit').TemplateResult<1>;
96
+ protected render(): import('lit-html').TemplateResult<1>;
86
97
  /** All navigable menu item elements in document order. */
87
98
  get items(): readonly Element[];
88
99
  /** Move the virtual cursor and DOM focus to the first navigable item. */
@@ -92,13 +103,13 @@ export declare class RCMenu extends LitElement {
92
103
  /**
93
104
  * Move the virtual cursor to a specific item.
94
105
  *
95
- * @param $item - The element to make active. No-op when null or undefined.
106
+ * @param $item - the element to make active. No-op when null or undefined
96
107
  */
97
108
  focusItem($item?: Element | null): void;
98
109
  /**
99
110
  * Move the virtual cursor to the item at `index`.
100
111
  *
101
- * @param index - Zero-based index into the navigable items array.
112
+ * @param index - zero-based index into the navigable items array
102
113
  */
103
114
  focusItemAt(index: number): void;
104
115
  protected _syncAriaLabel(): void;
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.7.0",
7
7
  "description": "Menu popup for command surfaces with keyboard navigation and typed activation events.",
8
8
  "repository": {
9
9
  "type": "git",
@@ -45,7 +45,7 @@
45
45
  "test:browser:firefox": "vitest --run --project=firefox"
46
46
  },
47
47
  "dependencies": {
48
- "@rcarls/rc-common": "0.5.0"
48
+ "@rcarls/rc-common": "0.7.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@custom-elements-manifest/analyzer": "0.11.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"rc-menu-DJ8upIAd.js","sources":["../src/rc-menu.styles.ts","../src/rc-menu.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const menuStyles = css`\n :host {\n display: flex;\n flex-direction: column;\n min-width: var(--rc-menu-min-width, 10em);\n padding-block: var(--rc-menu-padding-block, var(--rc-control-padding-block, 0.25em));\n background: var(--rc-menu-background, var(--rc-surface, Canvas));\n border: var(--rc-menu-border, var(--rc-border, 1px solid ButtonBorder));\n border-radius: var(--rc-menu-radius, var(--rc-control-radius, 0));\n box-shadow: var(\n --rc-menu-shadow,\n var(--rc-shadow, 0 2px 8px color-mix(in srgb, CanvasText 15%, transparent))\n );\n color: var(--rc-menu-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 overflow: hidden;\n }\n\n :host(:focus-visible) {\n outline: var(--rc-focus-ring, auto);\n outline-offset: var(--rc-focus-ring-offset, 0);\n }\n`;\n\nexport default menuStyles;\n","import { LitElement, html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { ActiveDescendantController, isFocusable } from '@rcarls/rc-common';\n\nimport menuStyles from './rc-menu.styles';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-menu': RCMenu;\n }\n}\n\n/** Detail payload for the `rc-menu-activate` event. */\nexport interface RCMenuActivateEvent {\n /** The activated menu item element. */\n item: HTMLElement;\n\n /** The item's `data-value` or `value` attribute, or an empty string. */\n value: string;\n\n /** Trimmed text content of the activated item. */\n text: string;\n\n /** Current `aria-checked` state for checkbox/radio menu items. */\n checked?: 'true' | 'false' | 'mixed';\n}\n\n/** WAI-ARIA roles that are valid direct children of `role=\"menu\"`. */\nconst MENU_ITEM_ROLES = ['menuitem', 'menuitemcheckbox', 'menuitemradio'] as const;\n\n/** Structural CSS for light-DOM menu items, injected into the containing document or shadow root. */\nconst LIGHT_DOM_CSS = `\n@layer rc-base {\n /* Item base layout */\n rc-menu [role='menuitem'],\n rc-menu [role='menuitemcheckbox'],\n rc-menu [role='menuitemradio'],\n rc-menu button:disabled {\n display: flex;\n align-items: center;\n gap: var(--rc-menu-item-gap, var(--rc-item-gap, 0.5em));\n min-block-size: var(--rc-menu-item-min-block-size, 0px);\n width: 100%;\n text-align: start;\n padding: var(--rc-menu-item-padding-block, var(--rc-item-padding-block, 0.3em))\n var(--rc-menu-item-padding-inline, var(--rc-item-padding-inline, 0.75em));\n appearance: none;\n box-sizing: border-box;\n border: none;\n background: transparent;\n text-decoration: none;\n color: inherit;\n font: inherit;\n cursor: default;\n user-select: none;\n outline: none;\n transition: var(--rc-menu-item-transition);\n }\n\n /* Pointer hover */\n rc-menu [role='menuitem']:hover,\n rc-menu [role='menuitemcheckbox']:hover,\n rc-menu [role='menuitemradio']:hover {\n background: var(--rc-menu-hover-bg, color-mix(in srgb, Highlight 8%, transparent));\n color: var(--rc-menu-hover-color, inherit);\n }\n\n /* Virtual cursor (set by ActiveDescendantController) */\n rc-menu [role='menuitem'][data-active],\n rc-menu [role='menuitemcheckbox'][data-active],\n rc-menu [role='menuitemradio'][data-active] {\n background: var(--rc-menu-active-bg, color-mix(in srgb, Highlight 8%, transparent));\n color: var(--rc-menu-active-color, inherit);\n }\n\n /* Check/radio indicator — ::before acts as a fixed-width leading column.\n Content is empty (unchecked) or a Unicode symbol (checked/mixed).\n Semantic state is conveyed by aria-checked; the visual symbol is decorative. */\n rc-menu [role='menuitemcheckbox']::before,\n rc-menu [role='menuitemradio']::before {\n content: '';\n flex: 0 0 var(--rc-menu-check-size, 1.25em);\n text-align: center;\n line-height: 1;\n color: var(--rc-menu-check-color, inherit);\n }\n\n rc-menu [role='menuitemcheckbox'][aria-checked='true']::before {\n content: '✓';\n }\n\n rc-menu [role='menuitemcheckbox'][aria-checked='mixed']::before {\n content: '−';\n }\n\n rc-menu [role='menuitemradio'][aria-checked='true']::before {\n content: '•';\n }\n\n /* Trailing label — keyboard shortcut or hint, pushed to the inline-end of the item */\n rc-menu [data-menu-shortcut] {\n margin-inline-start: auto;\n font-size: var(--rc-menu-shortcut-size, 0.8em);\n color: var(--rc-menu-shortcut-color, GrayText);\n white-space: nowrap;\n }\n\n /* Separators */\n rc-menu [role='separator'],\n rc-menu hr {\n border: none;\n border-block-start: var(--rc-menu-separator-border, var(--rc-border, 1px solid ButtonBorder));\n margin-block: var(--rc-menu-separator-margin-block, var(--rc-control-gap, 0.25em));\n margin-inline: var(--rc-menu-separator-margin-inline, 0px);\n }\n\n /* Group containers */\n rc-menu [role='group'] {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n }\n\n /* Optional section label (non-interactive heading above a group of items) */\n rc-menu [data-group-label] {\n padding-block: var(--rc-menu-group-label-padding-block, 0.1em);\n padding-inline: var(--rc-menu-item-padding-inline, 0.75em);\n color: var(--rc-menu-group-label-color, GrayText);\n user-select: none;\n pointer-events: none;\n }\n\n /* Disabled items */\n rc-menu button:disabled,\n rc-menu [aria-disabled='true'] {\n color: var(--rc-menu-disabled-color, var(--rc-text-disabled, GrayText));\n opacity: var(--rc-menu-disabled-opacity, var(--rc-disabled-opacity, 0.55));\n pointer-events: none;\n }\n}\n`;\n\n/**\n * Menu popup for command surfaces with keyboard navigation and typed activation events,\n * following the WAI-ARIA Menu pattern.\n *\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-menu rc-menu docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/menu/ WAI-ARIA Menu pattern}\n *\n * @slot default - Menu items, groups, and separators. Supported content model:\n * - Focusable elements (`<button>`, `<a>`, `[tabindex]`) become navigable `role=\"menuitem\"` entries.\n * - `role=\"menuitemcheckbox\"` / `role=\"menuitemradio\"` elements get a leading indicator column via `::before`;\n * `aria-checked` is initialized when missing and updated on activation.\n * - `role=\"group\"` divs group related items; label them with `aria-label` or `aria-labelledby`. Optionally\n * add a visible `[data-group-label]` element as first child of the group for section headings.\n * - `role=\"separator\"` / `<hr>` produce horizontal dividers between sections.\n * - Within any item, `[data-menu-shortcut]` elements are pushed to the inline-end edge for keyboard hints.\n * - Nested menu triggers supply their own trailing indicator through `rc-menu-button`'s `indicator` slot.\n *\n * @fires rc-menu-activate - Fired when a menu item is activated via keyboard (Enter/Space) or pointer click.\n * @fires rc-menu-close - Fired when Escape is pressed.\n *\n * @attr label - Accessible label for the menu; synced to `aria-label` on the host.\n *\n * @cssprop [--rc-menu-min-width=10em] - Minimum width of the menu panel.\n * @cssprop [--rc-menu-padding-block=0.25em] - Block (top/bottom) padding inside the panel.\n * @cssprop [--rc-menu-background=Canvas] - Background color; falls back through --rc-surface.\n * @cssprop [--rc-menu-border=1px solid ButtonBorder] - Border; falls back through --rc-border.\n * @cssprop [--rc-menu-radius=var(--rc-control-radius)] - Menu panel border radius.\n * @cssprop [--rc-menu-shadow=0 2px 8px color-mix(in srgb, CanvasText 15%, transparent)] - Box shadow; falls back through --rc-shadow.\n * @cssprop [--rc-menu-color=CanvasText] - Text color; falls back through --rc-field-text.\n * @cssprop [--rc-menu-item-min-block-size=0] - Minimum block size for menu item rows.\n * @cssprop [--rc-menu-item-padding-block=var(--rc-item-padding-block)] - Menu item block-axis padding.\n * @cssprop [--rc-menu-item-padding-inline=var(--rc-item-padding-inline)] - Menu item inline-axis padding.\n * @cssprop [--rc-menu-item-gap=var(--rc-item-gap)] - Gap between flex children inside each item.\n * @cssprop [--rc-menu-item-transition] - CSS transition applied to each item row.\n * @cssprop [--rc-menu-hover-bg=color-mix(in srgb, Highlight 8%, transparent)] - Pointer-hover background.\n * @cssprop [--rc-menu-hover-color=inherit] - Pointer-hover text color.\n * @cssprop [--rc-menu-active-bg=color-mix(in srgb, Highlight 8%, transparent)] - Virtual-cursor active background.\n * @cssprop [--rc-menu-active-color=inherit] - Virtual-cursor active text color.\n * @cssprop [--rc-menu-check-size=1.25em] - Width of the leading indicator column for checkbox/radio items.\n * @cssprop [--rc-menu-check-color=inherit] - Color of the check/radio symbol.\n * @cssprop [--rc-menu-shortcut-size=0.8em] - Font size of `[data-menu-shortcut]` labels.\n * @cssprop [--rc-menu-shortcut-color=GrayText] - Text color of `[data-menu-shortcut]` labels.\n * @cssprop [--rc-menu-disabled-color=GrayText] - Disabled menu item text color.\n * @cssprop [--rc-menu-disabled-opacity=var(--rc-disabled-opacity)] - Disabled menu item opacity.\n * @cssprop [--rc-menu-separator-border=1px solid ButtonBorder] - Separator border.\n * @cssprop [--rc-menu-separator-margin-block=var(--rc-control-gap)] - Separator block-axis margin.\n * @cssprop [--rc-menu-separator-margin-inline=0px] - Separator inline margin; set to match item padding for inset separators.\n * @cssprop [--rc-menu-group-label-padding-block=0.1em] - Block padding on `[data-group-label]` section headings.\n * @cssprop [--rc-menu-group-label-color=GrayText] - Text color of `[data-group-label]` section headings.\n */\nexport class RCMenu extends LitElement {\n static styles = [menuStyles];\n\n private static readonly _$styledRoots = new Set<Document | ShadowRoot>();\n\n private static _ensureBaseStyles($root: Document | ShadowRoot): void {\n if (RCMenu._$styledRoots.has($root)) {\n return;\n }\n\n RCMenu._$styledRoots.add($root);\n\n const $style = document.createElement('style');\n\n $style.setAttribute('data-rc-light-dom-base', 'rc-menu');\n $style.textContent = LIGHT_DOM_CSS;\n\n if ($root instanceof Document) {\n $root.head.appendChild($style);\n } else {\n $root.appendChild($style);\n }\n }\n\n /**\n * Accessible label for this menu. Synced to `aria-label` on the host.\n *\n * Prefer `aria-labelledby` for a visible label associated via ID.\n */\n @property({ type: String })\n label = '';\n\n protected _$menuItems: Element[] = [];\n\n protected readonly _activeDescendantCtrl = new ActiveDescendantController(this, {\n host: () => this,\n items: () => this._$menuItems,\n });\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'menu');\n }\n\n this.setAttribute('tabindex', '0');\n this._syncAriaLabel();\n\n this.addEventListener('keydown', this._onKeydown);\n this.addEventListener('blur', this._onBlur);\n this.addEventListener('click', this._onClick);\n\n RCMenu._ensureBaseStyles(this.getRootNode() as Document | ShadowRoot);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n\n this.removeEventListener('keydown', this._onKeydown);\n this.removeEventListener('blur', this._onBlur);\n this.removeEventListener('click', this._onClick);\n }\n\n protected override updated(changed: Map<PropertyKey, unknown>): void {\n if (changed.has('label')) {\n this._syncAriaLabel();\n }\n }\n\n protected override render() {\n return html`<slot @slotchange=${this._onSlotChange}></slot>`;\n }\n\n /** All navigable menu item elements in document order. */\n get items(): readonly Element[] {\n return this._$menuItems;\n }\n\n /** Move the virtual cursor and DOM focus to the first navigable item. */\n focusFirst(): void {\n this.focus();\n this._activeDescendantCtrl.navigateToFirst();\n }\n\n /** Move the virtual cursor and DOM focus to the last navigable item. */\n focusLast(): void {\n this.focus();\n this._activeDescendantCtrl.navigateToLast();\n }\n\n /**\n * Move the virtual cursor to a specific item.\n *\n * @param $item - The element to make active. No-op when null or undefined.\n */\n focusItem($item?: Element | null): void {\n if (!$item) {\n return;\n }\n\n this.focus();\n this._activeDescendantCtrl.navigateToItem($item);\n }\n\n /**\n * Move the virtual cursor to the item at `index`.\n *\n * @param index - Zero-based index into the navigable items array.\n */\n focusItemAt(index: number): void {\n this.focus();\n this._activeDescendantCtrl.navigateTo(index);\n }\n\n protected _syncAriaLabel(): void {\n if (this.label) {\n this.setAttribute('aria-label', this.label);\n } else {\n this.removeAttribute('aria-label');\n }\n }\n\n protected _onSlotChange(e: Event): void {\n const $slot = e.currentTarget as HTMLSlotElement;\n\n this._$menuItems = this._collectMenuItems($slot);\n this._initMenuItems();\n }\n\n /**\n * Collects navigable menu items from the slot, supporting `role=\"group\"`\n * containers and skipping `role=\"separator\"` elements.\n *\n * Direct focusable children are included as-is. Elements with\n * `role=\"group\"` are traversed one level deep so their focusable children\n * participate in arrow-key navigation. Separators and non-focusable\n * container elements are excluded.\n */\n protected _collectMenuItems($slot: HTMLSlotElement): Element[] {\n const $items: Element[] = [];\n\n for (const $el of $slot.assignedElements()) {\n const role = $el.getAttribute('role');\n\n if (role === 'separator') {\n continue;\n }\n\n if (role === 'group') {\n for (const $child of $el.children) {\n if (isFocusable($child)) {\n $items.push($child);\n }\n }\n\n continue;\n }\n\n if (isFocusable($el)) {\n $items.push($el);\n }\n }\n\n return $items;\n }\n\n protected _initMenuItems(): void {\n this._$menuItems.forEach(($el) => {\n const existingRole = $el.getAttribute('role');\n\n // Preserve explicit roles; only assign the default when none is present.\n if (\n !existingRole ||\n !MENU_ITEM_ROLES.includes(existingRole as (typeof MENU_ITEM_ROLES)[number])\n ) {\n $el.setAttribute('role', 'menuitem');\n }\n\n $el.setAttribute('tabindex', '-1');\n\n if (\n ($el.getAttribute('role') === 'menuitemcheckbox' ||\n $el.getAttribute('role') === 'menuitemradio') &&\n !$el.hasAttribute('aria-checked')\n ) {\n $el.setAttribute('aria-checked', 'false');\n }\n });\n }\n\n protected _applyCheckedState($item: HTMLElement): 'true' | 'false' | 'mixed' | undefined {\n const role = $item.getAttribute('role');\n\n if (role === 'menuitemcheckbox') {\n const checked = $item.getAttribute('aria-checked') === 'true' ? 'false' : 'true';\n\n $item.setAttribute('aria-checked', checked);\n\n return checked;\n }\n\n if (role === 'menuitemradio') {\n const $group = $item.closest('[role=\"group\"]');\n const $scope = $group && this.contains($group) ? $group : this;\n\n for (const $radio of $scope.querySelectorAll<HTMLElement>('[role=\"menuitemradio\"]')) {\n if ($radio.closest('rc-menu') === this) {\n $radio.setAttribute('aria-checked', $radio === $item ? 'true' : 'false');\n }\n }\n\n return 'true';\n }\n\n return undefined;\n }\n\n protected _onKeydown = (e: KeyboardEvent): void => {\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n e.stopPropagation();\n\n if (this._activeDescendantCtrl.activeItem) {\n this._activeDescendantCtrl.navigate(1);\n } else {\n this._activeDescendantCtrl.navigateToFirst();\n }\n\n break;\n }\n\n case 'ArrowUp': {\n e.preventDefault();\n e.stopPropagation();\n\n if (this._activeDescendantCtrl.activeItem) {\n this._activeDescendantCtrl.navigate(-1);\n } else {\n this._activeDescendantCtrl.navigateToLast();\n }\n\n break;\n }\n\n case 'Home': {\n e.preventDefault();\n e.stopPropagation();\n\n this._activeDescendantCtrl.navigateToFirst();\n\n break;\n }\n\n case 'End': {\n e.preventDefault();\n e.stopPropagation();\n\n this._activeDescendantCtrl.navigateToLast();\n\n break;\n }\n\n case 'Enter':\n // Falls through so both activation keys share the same handler.\n\n case ' ': {\n e.preventDefault();\n e.stopPropagation();\n\n const $active = this._activeDescendantCtrl.activeItem;\n\n if ($active) {\n // _onClick dispatches rc-menu-activate when the synthetic click bubbles up.\n ($active as HTMLElement).click();\n }\n\n break;\n }\n\n case 'Escape': {\n e.preventDefault();\n e.stopPropagation();\n\n this.dispatchEvent(\n new CustomEvent('rc-menu-close', {\n bubbles: true,\n composed: true,\n detail: { reason: 'escape' },\n }),\n );\n\n break;\n }\n }\n };\n\n protected _onBlur = (): void => {\n this._activeDescendantCtrl.clear();\n };\n\n protected _onClick = (e: MouseEvent): void => {\n const $target = e.target as Element;\n const $item = $target.closest<HTMLElement>(\n '[role=\"menuitem\"],[role=\"menuitemcheckbox\"],[role=\"menuitemradio\"]',\n );\n\n if (!$item || !this.contains($item)) {\n return;\n }\n\n if ($item.matches(':disabled, [aria-disabled=\"true\"]')) {\n return;\n }\n\n const checked = this._applyCheckedState($item);\n\n this.dispatchEvent(\n new CustomEvent<RCMenuActivateEvent>('rc-menu-activate', {\n bubbles: true,\n composed: true,\n detail: {\n item: $item,\n value: $item.dataset.value ?? $item.getAttribute('value') ?? '',\n text: $item.textContent?.trim() ?? '',\n checked,\n },\n }),\n );\n };\n}\n\nexport default RCMenu;\n"],"names":["menuStyles","css","MENU_ITEM_ROLES","LIGHT_DOM_CSS","_RCMenu","_a","LitElement","ActiveDescendantController","$active","$item","checked","$root","$style","changed","html","index","$slot","$items","$el","role","$child","isFocusable","existingRole","$group","$scope","$radio","__decorateClass","property","RCMenu"],"mappings":"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"}
File without changes