@spectrum-web-components/menu 1.12.0-testing.20260223092154 → 1.12.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spectrum-web-components/menu",
3
- "version": "1.12.0-testing.20260223092154",
3
+ "version": "1.12.0",
4
4
  "description": "",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Adobe",
@@ -86,15 +86,15 @@
86
86
  "types": "./src/index.d.ts",
87
87
  "dependencies": {
88
88
  "@lit-labs/observers": "2.0.2",
89
- "@spectrum-web-components/action-button": "1.12.0-testing.20260223092154",
90
- "@spectrum-web-components/base": "1.12.0-testing.20260223092154",
91
- "@spectrum-web-components/divider": "1.12.0-testing.20260223092154",
92
- "@spectrum-web-components/icon": "1.12.0-testing.20260223092154",
93
- "@spectrum-web-components/icons-ui": "1.12.0-testing.20260223092154",
94
- "@spectrum-web-components/overlay": "1.12.0-testing.20260223092154",
95
- "@spectrum-web-components/popover": "1.12.0-testing.20260223092154",
96
- "@spectrum-web-components/reactive-controllers": "1.12.0-testing.20260223092154",
97
- "@spectrum-web-components/shared": "1.12.0-testing.20260223092154"
89
+ "@spectrum-web-components/action-button": "1.12.0",
90
+ "@spectrum-web-components/base": "1.12.0",
91
+ "@spectrum-web-components/divider": "1.12.0",
92
+ "@spectrum-web-components/icon": "1.12.0",
93
+ "@spectrum-web-components/icons-ui": "1.12.0",
94
+ "@spectrum-web-components/overlay": "1.12.0",
95
+ "@spectrum-web-components/popover": "1.12.0",
96
+ "@spectrum-web-components/reactive-controllers": "1.12.0",
97
+ "@spectrum-web-components/shared": "1.12.0"
98
98
  },
99
99
  "keywords": [
100
100
  "design-system",
package/src/Menu.d.ts CHANGED
@@ -11,6 +11,8 @@
11
11
  */
12
12
  import { CSSResultArray, PropertyValues, SpectrumElement, TemplateResult } from '@spectrum-web-components/base';
13
13
  import { RovingTabindexController } from '@spectrum-web-components/reactive-controllers/src/RovingTabindex.js';
14
+ import '@spectrum-web-components/icons-ui/icons/sp-icon-arrow500.js';
15
+ import '../sp-menu-divider.js';
14
16
  import type { MenuItemKeydownEvent } from './MenuItem.js';
15
17
  import { MenuItem } from './MenuItem.js';
16
18
  export interface MenuChildItem {
@@ -20,10 +22,7 @@ export interface MenuChildItem {
20
22
  focusable: boolean;
21
23
  focusRoot: Menu;
22
24
  }
23
- declare const Menu_base: typeof SpectrumElement & {
24
- new (...args: any[]): import("@spectrum-web-components/base").SizedElementInterface;
25
- prototype: import("@spectrum-web-components/base").SizedElementInterface;
26
- } & import("@spectrum-web-components/core/mixins/sized-mixin.js").SizedElementConstructor;
25
+ declare const Menu_base: typeof SpectrumElement & import("@spectrum-web-components/base").Constructor<import("@spectrum-web-components/base").SizedElementInterface> & import("@spectrum-web-components/base").SizedElementConstructor;
27
26
  /**
28
27
  * Spectrum Menu Component
29
28
  *
@@ -49,6 +48,8 @@ export declare class Menu extends Menu_base {
49
48
  slotAssignment?: SlotAssignmentMode;
50
49
  };
51
50
  private get isSubmenu();
51
+ private asMenu;
52
+ private get _mobileViewRoot();
52
53
  protected rovingTabindexController?: RovingTabindexController<MenuItem>;
53
54
  /**
54
55
  * iPad scroll detection properties
@@ -113,6 +114,148 @@ export declare class Menu extends Menu_base {
113
114
  */
114
115
  get isScrolling(): boolean;
115
116
  set isScrolling(value: boolean);
117
+ /**
118
+ * Returns the MenuItem whose submenu is currently displayed at the
119
+ * top of the mobile drill-down stack, or `undefined` when no submenu
120
+ * is open.
121
+ */
122
+ get currentMobileSubmenu(): MenuItem | undefined;
123
+ /**
124
+ * Opens a mobile submenu by projecting its content into this menu's
125
+ * light DOM, pushing it onto the submenu stack, triggering the
126
+ * slide-in animation, and focusing the back button.
127
+ *
128
+ * @param item - The MenuItem whose submenu should be opened.
129
+ */
130
+ openMobileSubmenu(item: MenuItem): void;
131
+ /**
132
+ * Closes the topmost mobile submenu by restoring it to its original
133
+ * parent MenuItem, popping it from the stack, and either re-focusing
134
+ * the previous submenu's back button or returning focus to the
135
+ * triggering MenuItem when no deeper level remains.
136
+ */
137
+ closeMobileSubmenu(): void;
138
+ /**
139
+ * Focuses the mobile back button inside the given item's projected
140
+ * submenu. Explicitly resets `tabIndex` and `focused` on every other
141
+ * child of the submenu so only the back row is in the tab order
142
+ * after the drill-down opens. We avoid delegating to the projected
143
+ * submenu's `RovingTabindexController` here because the back button
144
+ * is appended dynamically via `render()` and may not yet be in the
145
+ * controller's element cache when this runs, which would cause
146
+ * focus to fall back to the first nested item instead.
147
+ *
148
+ * @param item - The MenuItem whose projected submenu should receive focus.
149
+ */
150
+ private _focusProjectedSubmenu;
151
+ /**
152
+ * Focuses the mobile back button of the currently visible projected
153
+ * submenu. Used when the user presses ArrowUp from the first nested
154
+ * item so focus moves to the back row instead of wrapping. Manages
155
+ * `tabIndex`/`focused` explicitly to keep the back row as the only
156
+ * tabbable element in the projected submenu.
157
+ */
158
+ private _focusMobileBackRow;
159
+ /**
160
+ * Focuses the first focusable item inside the currently visible
161
+ * projected submenu, skipping the back row. Used when the user
162
+ * presses ArrowDown from the back row. Manages `tabIndex`/`focused`
163
+ * explicitly so only the focused item is in the tab order.
164
+ */
165
+ private _focusFirstItemInCurrentNestedSubmenu;
166
+ /**
167
+ * Capture-phase keydown handler that overrides the default
168
+ * `RovingTabindexController` wrap behavior at the mobile drill-down
169
+ * boundary:
170
+ * - ArrowUp on the first nested item moves focus to the back row.
171
+ * - ArrowDown on the back row moves focus to the first nested item.
172
+ *
173
+ * Runs in the capture phase so it preempts the projected submenu's
174
+ * controller, which handles arrow keys in the bubble phase.
175
+ */
176
+ private handleMobileDrilldownKeydownCapture;
177
+ /**
178
+ * Triggers a CSS slide animation on the mobile submenu wrapper.
179
+ * Waits for the current Lit update cycle, then sets the
180
+ * `mobile-transition` attribute so the keyframe animation plays.
181
+ *
182
+ * @param direction - `'forward'` slides content in from the right,
183
+ * `'back'` slides content in from the left.
184
+ */
185
+ private _triggerMobileTransition;
186
+ /**
187
+ * Cleans up the `mobile-transition` attribute once the CSS slide
188
+ * animation finishes, preventing the animation from replaying on
189
+ * subsequent layout changes. Bound declaratively via `@animationend`
190
+ * on the wrapper, so it only fires for that element.
191
+ */
192
+ private _handleAnimationEnd;
193
+ /**
194
+ * Restores every projected submenu back to its original parent and
195
+ * clears the submenu stack. Called during `disconnectedCallback` or
196
+ * when the menu overlay closes to ensure a clean state.
197
+ */
198
+ resetMobileSubmenus(): void;
199
+ /**
200
+ * Moves the submenu element from its MenuItem parent into this Menu's
201
+ * light DOM with a `mobile-submenu` slot, so it projects through the
202
+ * named slot in the shadow DOM. Any previously visible projected submenu
203
+ * is moved to a non-rendered slot to avoid both showing at once.
204
+ */
205
+ private _projectMobileSubmenu;
206
+ /**
207
+ * Restores the submenu element back to its original MenuItem parent
208
+ * and resets the slot attribute.
209
+ */
210
+ private _restoreMobileSubmenu;
211
+ /**
212
+ * Handles click on the mobile back button. Stops the event from
213
+ * reaching parent menus and closes the current mobile submenu.
214
+ */
215
+ private handleMobileBackClick;
216
+ /**
217
+ * Maps each projected submenu element to its Lit render container so
218
+ * that back button elements can be individually cleaned up when a
219
+ * submenu is restored, without affecting other levels in the stack.
220
+ */
221
+ private _mobileBackContainers;
222
+ /**
223
+ * Declaratively renders the mobile back button and divider into the
224
+ * projected submenu element using Lit's `render()`, so the back button
225
+ * lives inside the same `<sp-menu>` and participates in its
226
+ * `RovingTabindexController` for keyboard navigation. Re-renders
227
+ * whenever `dir` or `mobileBackLabel` change so the icon orientation
228
+ * and label stay in sync.
229
+ */
230
+ private _renderMobileBackElements;
231
+ /**
232
+ * Re-render any open mobile back containers so changes to
233
+ * `mobileBackLabel` (and other reactive values consumed by the
234
+ * back-button template) propagate without needing to close
235
+ * and re-open the drill-down.
236
+ */
237
+ private _refreshMobileBackElements;
238
+ /**
239
+ * Removes the mobile back button render container from the given
240
+ * projected submenu element.
241
+ */
242
+ private _removeMobileBackElements;
243
+ /**
244
+ * Re-adds saved child items to the submenu's `childItemSet` and
245
+ * invalidates cached references after DOM re-parenting, so the
246
+ * `RovingTabindexController` picks up the correct set of focusable
247
+ * children.
248
+ *
249
+ * @param submenu - The submenu whose child state needs restoring.
250
+ * @param savedChildItems - The set of MenuItem children captured
251
+ * before the DOM move.
252
+ */
253
+ private _restoreSubmenuChildState;
254
+ /**
255
+ * Maps each projected submenu element to its original parent so the
256
+ * element can be moved back when the submenu is closed.
257
+ */
258
+ private _mobileSubmenuOriginalParents;
116
259
  /**
117
260
  * label of the menu
118
261
  */
@@ -121,6 +264,17 @@ export declare class Menu extends Menu_base {
121
264
  * whether menu should be ignored by roving tabindex controller
122
265
  */
123
266
  ignore: boolean;
267
+ /**
268
+ * Enables mobile submenu navigation where tapping a submenu item replaces
269
+ * the current menu content with the submenu's children (drill-down) instead
270
+ * of opening a flyout overlay.
271
+ */
272
+ mobileView: boolean;
273
+ /**
274
+ * Label for the mobile back button, used for localization.
275
+ */
276
+ mobileBackLabel: string;
277
+ private _mobileSubmenuStack;
124
278
  /**
125
279
  * how the menu allows selection of its items:
126
280
  * - `undefined` (default): no selection is allowed