mtrl 0.3.3 → 0.3.6
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 +1 -1
- package/src/components/menu/api.ts +143 -268
- package/src/components/menu/config.ts +84 -40
- package/src/components/menu/features/anchor.ts +159 -0
- package/src/components/menu/features/controller.ts +970 -0
- package/src/components/menu/features/index.ts +4 -0
- package/src/components/menu/index.ts +31 -63
- package/src/components/menu/menu.ts +107 -97
- package/src/components/menu/types.ts +263 -447
- package/src/components/segmented-button/config.ts +59 -20
- package/src/components/segmented-button/index.ts +1 -1
- package/src/components/segmented-button/segment.ts +51 -97
- package/src/components/segmented-button/segmented-button.ts +114 -2
- package/src/components/segmented-button/types.ts +52 -0
- package/src/core/compose/features/icon.ts +15 -13
- package/src/core/dom/classes.ts +81 -9
- package/src/core/dom/create.ts +30 -19
- package/src/core/layout/README.md +531 -166
- package/src/core/layout/array.ts +3 -4
- package/src/core/layout/config.ts +193 -0
- package/src/core/layout/create.ts +1 -2
- package/src/core/layout/index.ts +12 -2
- package/src/core/layout/object.ts +2 -3
- package/src/core/layout/processor.ts +60 -12
- package/src/core/layout/result.ts +1 -2
- package/src/core/layout/types.ts +105 -50
- package/src/core/layout/utils.ts +69 -61
- package/src/index.ts +2 -1
- package/src/styles/components/_button.scss +6 -0
- package/src/styles/components/_chip.scss +4 -5
- package/src/styles/components/_menu.scss +20 -8
- package/src/styles/components/_segmented-button.scss +173 -63
- package/src/styles/main.scss +23 -23
- package/src/styles/utilities/_layout.scss +665 -0
- package/src/components/menu/features/items-manager.ts +0 -457
- package/src/components/menu/features/keyboard-navigation.ts +0 -133
- package/src/components/menu/features/positioning.ts +0 -127
- package/src/components/menu/features/visibility.ts +0 -230
- package/src/components/menu/menu-item.ts +0 -86
- package/src/components/menu/utils.ts +0 -67
- /package/src/{core/build → styles/utilities}/_ripple.scss +0 -0
|
@@ -1,562 +1,378 @@
|
|
|
1
1
|
// src/components/menu/types.ts
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Menu
|
|
5
|
-
*
|
|
6
|
-
* Determines how the menu is horizontally aligned relative to its anchor element.
|
|
7
|
-
*
|
|
8
|
-
* @category Components
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* // Position menu with right alignment
|
|
12
|
-
* menu.position(buttonElement, { align: 'right' });
|
|
13
|
-
* ```
|
|
14
|
-
*/
|
|
15
|
-
export type MenuAlign = 'left' | 'right' | 'center';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Menu vertical alignment options
|
|
19
|
-
*
|
|
20
|
-
* Determines how the menu is vertically positioned relative to its anchor element.
|
|
21
|
-
*
|
|
22
|
-
* @category Components
|
|
23
|
-
* @example
|
|
24
|
-
* ```typescript
|
|
25
|
-
* // Position menu above the anchor element
|
|
26
|
-
* menu.position(buttonElement, { vAlign: 'top' });
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
export type MenuVerticalAlign = 'top' | 'bottom' | 'middle';
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Menu item types
|
|
33
|
-
*
|
|
34
|
-
* Defines the different types of items that can be added to a menu.
|
|
35
|
-
* - 'item': Standard selectable menu item (default)
|
|
36
|
-
* - 'divider': Horizontal line separating groups of menu items
|
|
4
|
+
* Menu placement options
|
|
5
|
+
* Controls where the menu will appear relative to its anchor element
|
|
37
6
|
*
|
|
38
7
|
* @category Components
|
|
39
|
-
* @example
|
|
40
|
-
* ```typescript
|
|
41
|
-
* // Adding a divider between menu items
|
|
42
|
-
* menu.addItem({ type: 'divider' });
|
|
43
|
-
* ```
|
|
44
8
|
*/
|
|
45
|
-
export
|
|
9
|
+
export const MENU_PLACEMENT = {
|
|
10
|
+
/** Places menu below the anchor, aligned to left edge */
|
|
11
|
+
BOTTOM_START: 'bottom-start',
|
|
12
|
+
/** Places menu below the anchor, centered */
|
|
13
|
+
BOTTOM: 'bottom',
|
|
14
|
+
/** Places menu below the anchor, aligned to right edge */
|
|
15
|
+
BOTTOM_END: 'bottom-end',
|
|
16
|
+
/** Places menu above the anchor, aligned to left edge */
|
|
17
|
+
TOP_START: 'top-start',
|
|
18
|
+
/** Places menu above the anchor, centered */
|
|
19
|
+
TOP: 'top',
|
|
20
|
+
/** Places menu above the anchor, aligned to right edge */
|
|
21
|
+
TOP_END: 'top-end',
|
|
22
|
+
/** Places menu to the right of the anchor, aligned to top edge */
|
|
23
|
+
RIGHT_START: 'right-start',
|
|
24
|
+
/** Places menu to the right of the anchor, centered */
|
|
25
|
+
RIGHT: 'right',
|
|
26
|
+
/** Places menu to the right of the anchor, aligned to bottom edge */
|
|
27
|
+
RIGHT_END: 'right-end',
|
|
28
|
+
/** Places menu to the left of the anchor, aligned to top edge */
|
|
29
|
+
LEFT_START: 'left-start',
|
|
30
|
+
/** Places menu to the left of the anchor, centered */
|
|
31
|
+
LEFT: 'left',
|
|
32
|
+
/** Places menu to the left of the anchor, aligned to bottom edge */
|
|
33
|
+
LEFT_END: 'left-end'
|
|
34
|
+
} as const;
|
|
46
35
|
|
|
47
36
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* Events that can be subscribed to for the Menu component.
|
|
51
|
-
* - 'select': Fired when a menu item is selected
|
|
52
|
-
* - 'open': Fired when the menu is shown
|
|
53
|
-
* - 'close': Fired when the menu is hidden
|
|
54
|
-
* - 'submenuOpen': Fired when a submenu is opened
|
|
55
|
-
* - 'submenuClose': Fired when a submenu is closed
|
|
37
|
+
* Alignment options for the menu
|
|
56
38
|
*
|
|
57
39
|
* @category Components
|
|
58
|
-
* @example
|
|
59
|
-
* ```typescript
|
|
60
|
-
* // Listen for menu open events
|
|
61
|
-
* menu.on('open', () => {
|
|
62
|
-
* console.log('Menu opened');
|
|
63
|
-
* });
|
|
64
|
-
*
|
|
65
|
-
* // Listen for item selection
|
|
66
|
-
* menu.on('select', (event) => {
|
|
67
|
-
* console.log(`Selected item: ${event.name}`);
|
|
68
|
-
* });
|
|
69
|
-
* ```
|
|
70
40
|
*/
|
|
71
|
-
export type
|
|
41
|
+
export type MenuPlacement = typeof MENU_PLACEMENT[keyof typeof MENU_PLACEMENT];
|
|
72
42
|
|
|
73
43
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* Configuration object for individual menu items.
|
|
44
|
+
* Configuration interface for a menu item
|
|
77
45
|
*
|
|
78
46
|
* @category Components
|
|
79
|
-
* @example
|
|
80
|
-
* ```typescript
|
|
81
|
-
* // Basic menu item
|
|
82
|
-
* const basicItem: MenuItemConfig = {
|
|
83
|
-
* name: 'edit',
|
|
84
|
-
* text: 'Edit Document'
|
|
85
|
-
* };
|
|
86
|
-
*
|
|
87
|
-
* // Disabled menu item
|
|
88
|
-
* const disabledItem: MenuItemConfig = {
|
|
89
|
-
* name: 'print',
|
|
90
|
-
* text: 'Print',
|
|
91
|
-
* disabled: true
|
|
92
|
-
* };
|
|
93
|
-
*
|
|
94
|
-
* // Menu item with a submenu
|
|
95
|
-
* const itemWithSubmenu: MenuItemConfig = {
|
|
96
|
-
* name: 'share',
|
|
97
|
-
* text: 'Share',
|
|
98
|
-
* items: [
|
|
99
|
-
* { name: 'email', text: 'Email' },
|
|
100
|
-
* { name: 'link', text: 'Copy Link' }
|
|
101
|
-
* ]
|
|
102
|
-
* };
|
|
103
|
-
*
|
|
104
|
-
* // Divider item
|
|
105
|
-
* const divider: MenuItemConfig = { type: 'divider' };
|
|
106
|
-
* ```
|
|
107
47
|
*/
|
|
108
|
-
export interface
|
|
48
|
+
export interface MenuItem {
|
|
109
49
|
/**
|
|
110
|
-
* Unique
|
|
111
|
-
*
|
|
50
|
+
* Unique ID for the menu item
|
|
51
|
+
* Required for accessibility and event handling
|
|
112
52
|
*/
|
|
113
|
-
|
|
53
|
+
id: string;
|
|
114
54
|
|
|
115
|
-
/**
|
|
116
|
-
*
|
|
117
|
-
* This is the visible label shown in the menu
|
|
55
|
+
/**
|
|
56
|
+
* Display text for the menu item
|
|
118
57
|
*/
|
|
119
58
|
text: string;
|
|
120
59
|
|
|
121
|
-
/**
|
|
122
|
-
*
|
|
123
|
-
*
|
|
60
|
+
/**
|
|
61
|
+
* Optional icon to display before the text
|
|
62
|
+
* Accepts HTML string (typically SVG)
|
|
124
63
|
*/
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Whether the item is disabled
|
|
129
|
-
* Disabled items can't be selected and appear visually muted
|
|
130
|
-
*/
|
|
131
|
-
disabled?: boolean;
|
|
64
|
+
icon?: string;
|
|
132
65
|
|
|
133
|
-
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
66
|
+
/**
|
|
67
|
+
* Optional keyboard shortcut hint to display
|
|
68
|
+
* Shown at the end of the menu item
|
|
136
69
|
*/
|
|
137
|
-
|
|
70
|
+
shortcut?: string;
|
|
138
71
|
|
|
139
|
-
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*/
|
|
143
|
-
items?: MenuItemConfig[];
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Menu position configuration
|
|
148
|
-
*
|
|
149
|
-
* Configures how a menu is positioned relative to an anchor element.
|
|
150
|
-
* This allows for precise control over menu placement in the UI.
|
|
151
|
-
*
|
|
152
|
-
* @category Components
|
|
153
|
-
* @example
|
|
154
|
-
* ```typescript
|
|
155
|
-
* // Position menu at the bottom-right of the anchor with additional offset
|
|
156
|
-
* menu.position(buttonElement, {
|
|
157
|
-
* align: 'right',
|
|
158
|
-
* vAlign: 'bottom',
|
|
159
|
-
* offsetX: 5,
|
|
160
|
-
* offsetY: 10
|
|
161
|
-
* });
|
|
162
|
-
*
|
|
163
|
-
* // Center align menu below the anchor
|
|
164
|
-
* menu.position(buttonElement, {
|
|
165
|
-
* align: 'center',
|
|
166
|
-
* vAlign: 'bottom'
|
|
167
|
-
* });
|
|
168
|
-
* ```
|
|
169
|
-
*/
|
|
170
|
-
export interface MenuPositionConfig {
|
|
171
|
-
/**
|
|
172
|
-
* Horizontal alignment
|
|
173
|
-
* Controls how the menu aligns horizontally with the anchor element
|
|
174
|
-
* @default 'left'
|
|
72
|
+
/**
|
|
73
|
+
* Whether the menu item is disabled
|
|
74
|
+
* Disabled items cannot be clicked but remain visible
|
|
175
75
|
*/
|
|
176
|
-
|
|
76
|
+
disabled?: boolean;
|
|
177
77
|
|
|
178
|
-
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* @default 'bottom'
|
|
78
|
+
/**
|
|
79
|
+
* Whether this item has a submenu
|
|
80
|
+
* If true, the item will show an indicator and can open a nested menu
|
|
182
81
|
*/
|
|
183
|
-
|
|
82
|
+
hasSubmenu?: boolean;
|
|
184
83
|
|
|
185
|
-
/**
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
* Positive values move the menu to the right
|
|
189
|
-
* @default 0
|
|
84
|
+
/**
|
|
85
|
+
* Optional array of submenu items
|
|
86
|
+
* Only used when hasSubmenu is true
|
|
190
87
|
*/
|
|
191
|
-
|
|
88
|
+
submenu?: MenuItem[];
|
|
192
89
|
|
|
193
|
-
/**
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
* Positive values move the menu downward
|
|
197
|
-
* @default 0
|
|
90
|
+
/**
|
|
91
|
+
* Additional data to associate with the menu item
|
|
92
|
+
* This can be used for custom behavior in click handlers
|
|
198
93
|
*/
|
|
199
|
-
|
|
94
|
+
data?: any;
|
|
200
95
|
}
|
|
201
96
|
|
|
202
97
|
/**
|
|
203
|
-
* Menu
|
|
204
|
-
*
|
|
205
|
-
* Contains the calculated position values for a menu.
|
|
206
|
-
* Used internally by the positioning system.
|
|
98
|
+
* Menu item type for dividers
|
|
207
99
|
*
|
|
208
100
|
* @category Components
|
|
209
|
-
* @internal
|
|
210
101
|
*/
|
|
211
|
-
export interface
|
|
212
|
-
/**
|
|
213
|
-
*
|
|
214
|
-
* Absolute position from the left edge of the viewport
|
|
102
|
+
export interface MenuDivider {
|
|
103
|
+
/**
|
|
104
|
+
* Type must be 'divider' to differentiate from regular menu items
|
|
215
105
|
*/
|
|
216
|
-
|
|
106
|
+
type: 'divider';
|
|
217
107
|
|
|
218
|
-
/**
|
|
219
|
-
*
|
|
220
|
-
* Absolute position from the top edge of the viewport
|
|
108
|
+
/**
|
|
109
|
+
* Optional ID for the divider (for accessibility)
|
|
221
110
|
*/
|
|
222
|
-
|
|
111
|
+
id?: string;
|
|
223
112
|
}
|
|
224
113
|
|
|
225
114
|
/**
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
* Used internally to track menu item DOM elements and their configurations.
|
|
229
|
-
* This helps with item management and event handling.
|
|
115
|
+
* Combined type for menu content items (regular items or dividers)
|
|
230
116
|
*
|
|
231
117
|
* @category Components
|
|
232
|
-
* @internal
|
|
233
118
|
*/
|
|
234
|
-
export
|
|
235
|
-
/**
|
|
236
|
-
* DOM element for the item
|
|
237
|
-
* Reference to the rendered menu item element
|
|
238
|
-
*/
|
|
239
|
-
element: HTMLElement;
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Item configuration
|
|
243
|
-
* The configuration that was used to create this item
|
|
244
|
-
*/
|
|
245
|
-
config: MenuItemConfig;
|
|
246
|
-
}
|
|
119
|
+
export type MenuContent = MenuItem | MenuDivider;
|
|
247
120
|
|
|
248
121
|
/**
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
* Contains information about a selected menu item.
|
|
252
|
-
* This is passed to event handlers when an item is selected.
|
|
122
|
+
* Configuration interface for the Menu component
|
|
253
123
|
*
|
|
254
124
|
* @category Components
|
|
255
|
-
* @example
|
|
256
|
-
* ```typescript
|
|
257
|
-
* menu.on('select', (event: MenuSelectEvent) => {
|
|
258
|
-
* console.log(`Selected: ${event.name}`);
|
|
259
|
-
* console.log(`Text: ${event.text}`);
|
|
260
|
-
*
|
|
261
|
-
* // For submenu items, path contains the hierarchy
|
|
262
|
-
* if (event.path) {
|
|
263
|
-
* console.log(`From submenu path: ${event.path.join(' > ')}`);
|
|
264
|
-
* }
|
|
265
|
-
* });
|
|
266
|
-
* ```
|
|
267
125
|
*/
|
|
268
|
-
export interface
|
|
269
|
-
/**
|
|
270
|
-
*
|
|
271
|
-
*
|
|
126
|
+
export interface MenuConfig {
|
|
127
|
+
/**
|
|
128
|
+
* Element to which the menu will be anchored
|
|
129
|
+
* Can be an HTML element or a CSS selector string
|
|
272
130
|
*/
|
|
273
|
-
|
|
131
|
+
anchor: HTMLElement | string;
|
|
274
132
|
|
|
275
|
-
/**
|
|
276
|
-
*
|
|
277
|
-
* The visible text that was displayed in the menu
|
|
133
|
+
/**
|
|
134
|
+
* Array of menu items and dividers to display
|
|
278
135
|
*/
|
|
279
|
-
|
|
136
|
+
items: MenuContent[];
|
|
280
137
|
|
|
281
|
-
/**
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
* from top level to the selected item
|
|
138
|
+
/**
|
|
139
|
+
* Placement of the menu relative to the anchor
|
|
140
|
+
* @default 'bottom-start'
|
|
285
141
|
*/
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
*
|
|
292
|
-
* Provides options for creating and configuring a Menu component.
|
|
293
|
-
*
|
|
294
|
-
* @category Components
|
|
295
|
-
* @example
|
|
296
|
-
* ```typescript
|
|
297
|
-
* // Create a basic menu with initial items
|
|
298
|
-
* const menu = createMenu({
|
|
299
|
-
* items: [
|
|
300
|
-
* { name: 'copy', text: 'Copy' },
|
|
301
|
-
* { name: 'paste', text: 'Paste' },
|
|
302
|
-
* { type: 'divider' },
|
|
303
|
-
* { name: 'delete', text: 'Delete' }
|
|
304
|
-
* ],
|
|
305
|
-
* stayOpenOnSelect: false,
|
|
306
|
-
* class: 'custom-menu'
|
|
307
|
-
* });
|
|
308
|
-
*
|
|
309
|
-
* // Create a submenu
|
|
310
|
-
* const submenu = createMenu({
|
|
311
|
-
* items: [
|
|
312
|
-
* { name: 'option1', text: 'Option 1' },
|
|
313
|
-
* { name: 'option2', text: 'Option 2' }
|
|
314
|
-
* ],
|
|
315
|
-
* parentItem: parentElement
|
|
316
|
-
* });
|
|
317
|
-
* ```
|
|
318
|
-
*/
|
|
319
|
-
export interface MenuConfig {
|
|
320
|
-
/**
|
|
321
|
-
* Initial menu items
|
|
322
|
-
* Array of item configurations to populate the menu with
|
|
142
|
+
placement?: MenuPlacement;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Whether the menu should close when an item is clicked
|
|
146
|
+
* @default true
|
|
323
147
|
*/
|
|
324
|
-
|
|
148
|
+
closeOnSelect?: boolean;
|
|
325
149
|
|
|
326
|
-
/**
|
|
327
|
-
*
|
|
328
|
-
*
|
|
150
|
+
/**
|
|
151
|
+
* Whether the menu should close when the user clicks outside
|
|
152
|
+
* @default true
|
|
329
153
|
*/
|
|
330
|
-
|
|
154
|
+
closeOnClickOutside?: boolean;
|
|
331
155
|
|
|
332
|
-
/**
|
|
333
|
-
* Whether
|
|
334
|
-
*
|
|
335
|
-
* @default false
|
|
156
|
+
/**
|
|
157
|
+
* Whether the menu should close when the escape key is pressed
|
|
158
|
+
* @default true
|
|
336
159
|
*/
|
|
337
|
-
|
|
160
|
+
closeOnEscape?: boolean;
|
|
338
161
|
|
|
339
|
-
/**
|
|
340
|
-
*
|
|
341
|
-
*
|
|
162
|
+
/**
|
|
163
|
+
* Whether submenus should open on hover
|
|
164
|
+
* @default true
|
|
342
165
|
*/
|
|
343
|
-
|
|
166
|
+
openSubmenuOnHover?: boolean;
|
|
344
167
|
|
|
345
|
-
/**
|
|
346
|
-
*
|
|
347
|
-
*
|
|
168
|
+
/**
|
|
169
|
+
* Optional width for the menu (in CSS units)
|
|
170
|
+
* If not provided, menu will size to its content
|
|
348
171
|
*/
|
|
349
|
-
|
|
172
|
+
width?: string;
|
|
350
173
|
|
|
351
|
-
/**
|
|
352
|
-
*
|
|
353
|
-
*
|
|
174
|
+
/**
|
|
175
|
+
* Optional maximum height for the menu (in CSS units)
|
|
176
|
+
* If content exceeds this height, the menu will scroll
|
|
177
|
+
*/
|
|
178
|
+
maxHeight?: string;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Optional offset from the anchor (in pixels)
|
|
182
|
+
* @default 8
|
|
183
|
+
*/
|
|
184
|
+
offset?: number;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Whether the menu should automatically flip placement to stay in viewport
|
|
188
|
+
* @default true
|
|
189
|
+
*/
|
|
190
|
+
autoFlip?: boolean;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Whether the menu is initially visible
|
|
194
|
+
* @default false
|
|
195
|
+
*/
|
|
196
|
+
visible?: boolean;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Additional CSS classes to add to the menu
|
|
200
|
+
*/
|
|
201
|
+
class?: string;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Component prefix for CSS class names
|
|
354
205
|
* @default 'mtrl'
|
|
355
206
|
*/
|
|
356
207
|
prefix?: string;
|
|
357
208
|
|
|
358
|
-
/**
|
|
359
|
-
* Component name
|
|
360
|
-
* Name identifier used in CSS classes and debugging
|
|
209
|
+
/**
|
|
210
|
+
* Component name used in CSS class generation
|
|
361
211
|
* @default 'menu'
|
|
362
212
|
*/
|
|
363
213
|
componentName?: string;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Event handlers for the menu
|
|
217
|
+
*/
|
|
218
|
+
on?: {
|
|
219
|
+
/**
|
|
220
|
+
* Called when the menu is opened
|
|
221
|
+
*/
|
|
222
|
+
open?: (event: MenuEvent) => void;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Called when the menu is closed
|
|
226
|
+
*/
|
|
227
|
+
close?: (event: MenuEvent) => void;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Called when a menu item is selected
|
|
231
|
+
*/
|
|
232
|
+
select?: (event: MenuSelectEvent) => void;
|
|
233
|
+
};
|
|
364
234
|
}
|
|
365
235
|
|
|
366
236
|
/**
|
|
367
|
-
* Menu
|
|
368
|
-
*
|
|
369
|
-
* Represents a Material Design 3 menu component that provides a temporary
|
|
370
|
-
* surface containing choices that users can interact with.
|
|
371
|
-
*
|
|
372
|
-
* The menu supports positioning, item management, keyboard navigation,
|
|
373
|
-
* and event handling for user interactions.
|
|
374
|
-
*
|
|
375
|
-
* This interface is implemented by the object returned from the {@link ../menu!default | createMenu} function.
|
|
237
|
+
* Menu event interface
|
|
376
238
|
*
|
|
377
239
|
* @category Components
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
*
|
|
240
|
+
*/
|
|
241
|
+
export interface MenuEvent {
|
|
242
|
+
/** The menu component that triggered the event */
|
|
243
|
+
menu: MenuComponent;
|
|
244
|
+
|
|
245
|
+
/** Original DOM event if available */
|
|
246
|
+
originalEvent?: Event;
|
|
247
|
+
|
|
248
|
+
/** Function to prevent default behavior */
|
|
249
|
+
preventDefault: () => void;
|
|
250
|
+
|
|
251
|
+
/** Whether default behavior was prevented */
|
|
252
|
+
defaultPrevented: boolean;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Menu selection event interface
|
|
395
257
|
*
|
|
396
|
-
*
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
258
|
+
* @category Components
|
|
259
|
+
*/
|
|
260
|
+
export interface MenuSelectEvent extends MenuEvent {
|
|
261
|
+
/** The selected menu item */
|
|
262
|
+
item: MenuItem;
|
|
263
|
+
|
|
264
|
+
/** ID of the selected menu item */
|
|
265
|
+
itemId: string;
|
|
266
|
+
|
|
267
|
+
/** Data associated with the menu item (if any) */
|
|
268
|
+
itemData?: any;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Menu component interface
|
|
404
273
|
*
|
|
405
|
-
* @
|
|
274
|
+
* @category Components
|
|
406
275
|
*/
|
|
407
276
|
export interface MenuComponent {
|
|
408
|
-
/**
|
|
409
|
-
* The root element of the menu
|
|
410
|
-
* Access to the underlying DOM element for direct manipulation if needed
|
|
411
|
-
*/
|
|
277
|
+
/** The menu's root DOM element */
|
|
412
278
|
element: HTMLElement;
|
|
413
279
|
|
|
414
|
-
/**
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
* @returns The menu component for
|
|
280
|
+
/**
|
|
281
|
+
* Opens the menu
|
|
282
|
+
* @param event - Optional event that triggered the open
|
|
283
|
+
* @returns The menu component for chaining
|
|
418
284
|
*/
|
|
419
|
-
|
|
285
|
+
open: (event?: Event) => MenuComponent;
|
|
420
286
|
|
|
421
|
-
/**
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
* @returns The menu component for
|
|
287
|
+
/**
|
|
288
|
+
* Closes the menu
|
|
289
|
+
* @param event - Optional event that triggered the close
|
|
290
|
+
* @returns The menu component for chaining
|
|
425
291
|
*/
|
|
426
|
-
|
|
292
|
+
close: (event?: Event) => MenuComponent;
|
|
427
293
|
|
|
428
|
-
/**
|
|
429
|
-
*
|
|
430
|
-
* @
|
|
294
|
+
/**
|
|
295
|
+
* Toggles the menu's open state
|
|
296
|
+
* @param event - Optional event that triggered the toggle
|
|
297
|
+
* @returns The menu component for chaining
|
|
431
298
|
*/
|
|
432
|
-
|
|
299
|
+
toggle: (event?: Event) => MenuComponent;
|
|
433
300
|
|
|
434
|
-
/**
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
* @param target - The element to position the menu against
|
|
438
|
-
* @param options - Configuration for how to align the menu
|
|
439
|
-
* @returns The menu component for method chaining
|
|
301
|
+
/**
|
|
302
|
+
* Checks if the menu is currently open
|
|
303
|
+
* @returns True if the menu is open
|
|
440
304
|
*/
|
|
441
|
-
|
|
305
|
+
isOpen: () => boolean;
|
|
442
306
|
|
|
443
|
-
/**
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
* @
|
|
447
|
-
* @returns The menu component for method chaining
|
|
307
|
+
/**
|
|
308
|
+
* Updates the menu items
|
|
309
|
+
* @param items - New array of menu items and dividers
|
|
310
|
+
* @returns The menu component for chaining
|
|
448
311
|
*/
|
|
449
|
-
|
|
312
|
+
setItems: (items: MenuContent[]) => MenuComponent;
|
|
450
313
|
|
|
451
|
-
/**
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
* @param name - Name identifier of the item to remove
|
|
455
|
-
* @returns The menu component for method chaining
|
|
314
|
+
/**
|
|
315
|
+
* Gets the current menu items
|
|
316
|
+
* @returns Array of current menu items and dividers
|
|
456
317
|
*/
|
|
457
|
-
|
|
318
|
+
getItems: () => MenuContent[];
|
|
458
319
|
|
|
459
|
-
/**
|
|
460
|
-
*
|
|
461
|
-
* @
|
|
320
|
+
/**
|
|
321
|
+
* Updates the menu's anchor element
|
|
322
|
+
* @param anchor - New anchor element or selector
|
|
323
|
+
* @returns The menu component for chaining
|
|
462
324
|
*/
|
|
463
|
-
|
|
325
|
+
setAnchor: (anchor: HTMLElement | string) => MenuComponent;
|
|
464
326
|
|
|
465
|
-
/**
|
|
466
|
-
*
|
|
467
|
-
*
|
|
468
|
-
* @param event - The event name to listen for
|
|
469
|
-
* @param handler - Callback function to execute when the event occurs
|
|
470
|
-
* @returns The menu component for method chaining
|
|
327
|
+
/**
|
|
328
|
+
* Gets the current anchor element
|
|
329
|
+
* @returns Current anchor element
|
|
471
330
|
*/
|
|
472
|
-
|
|
331
|
+
getAnchor: () => HTMLElement;
|
|
473
332
|
|
|
474
|
-
/**
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
* @
|
|
478
|
-
* @param handler - The handler function to remove
|
|
479
|
-
* @returns The menu component for method chaining
|
|
333
|
+
/**
|
|
334
|
+
* Updates the menu's placement
|
|
335
|
+
* @param placement - New placement value
|
|
336
|
+
* @returns The menu component for chaining
|
|
480
337
|
*/
|
|
481
|
-
|
|
338
|
+
setPlacement: (placement: MenuPlacement) => MenuComponent;
|
|
482
339
|
|
|
483
|
-
/**
|
|
484
|
-
*
|
|
485
|
-
*
|
|
486
|
-
* @returns The menu component for method chaining
|
|
340
|
+
/**
|
|
341
|
+
* Gets the current menu placement
|
|
342
|
+
* @returns Current placement
|
|
487
343
|
*/
|
|
488
|
-
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
/**
|
|
492
|
-
* Base component interface
|
|
493
|
-
*
|
|
494
|
-
* Internal interface representing the base structure for menu components
|
|
495
|
-
* before the public API is applied.
|
|
496
|
-
*
|
|
497
|
-
* @internal
|
|
498
|
-
* @category Components
|
|
499
|
-
*/
|
|
500
|
-
export interface BaseComponent {
|
|
501
|
-
/** The root DOM element */
|
|
502
|
-
element: HTMLElement;
|
|
503
|
-
|
|
504
|
-
/** Method to emit events */
|
|
505
|
-
emit?: (event: string, data: any) => void;
|
|
344
|
+
getPlacement: () => MenuPlacement;
|
|
506
345
|
|
|
507
|
-
/**
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
show?: () => any;
|
|
515
|
-
|
|
516
|
-
/** Method to hide the component */
|
|
517
|
-
hide?: () => any;
|
|
518
|
-
|
|
519
|
-
/** Method to check visibility */
|
|
520
|
-
isVisible?: () => boolean;
|
|
521
|
-
|
|
522
|
-
/** Method to position relative to target */
|
|
523
|
-
position?: (target: HTMLElement, options?: MenuPositionConfig) => any;
|
|
524
|
-
|
|
525
|
-
/** Method to add an item */
|
|
526
|
-
addItem?: (config: MenuItemConfig) => any;
|
|
527
|
-
|
|
528
|
-
/** Method to remove an item */
|
|
529
|
-
removeItem?: (name: string) => any;
|
|
530
|
-
|
|
531
|
-
/** Method to get all items */
|
|
532
|
-
getItems?: () => Map<string, MenuItemData>;
|
|
533
|
-
|
|
534
|
-
/** Method to close submenus */
|
|
535
|
-
closeSubmenus?: () => any;
|
|
536
|
-
|
|
537
|
-
/** Method to refresh hover handlers */
|
|
538
|
-
refreshHoverHandlers?: () => any;
|
|
346
|
+
/**
|
|
347
|
+
* Adds an event listener to the menu
|
|
348
|
+
* @param event - Event name ('open', 'close', 'select')
|
|
349
|
+
* @param handler - Event handler function
|
|
350
|
+
* @returns The menu component for chaining
|
|
351
|
+
*/
|
|
352
|
+
on: <T extends keyof MenuEvents>(event: T, handler: MenuEvents[T]) => MenuComponent;
|
|
539
353
|
|
|
540
|
-
/**
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
354
|
+
/**
|
|
355
|
+
* Removes an event listener from the menu
|
|
356
|
+
* @param event - Event name
|
|
357
|
+
* @param handler - Event handler function
|
|
358
|
+
* @returns The menu component for chaining
|
|
359
|
+
*/
|
|
360
|
+
off: <T extends keyof MenuEvents>(event: T, handler: MenuEvents[T]) => MenuComponent;
|
|
544
361
|
|
|
545
|
-
/**
|
|
546
|
-
|
|
362
|
+
/**
|
|
363
|
+
* Destroys the menu component and cleans up resources
|
|
364
|
+
*/
|
|
365
|
+
destroy: () => void;
|
|
547
366
|
}
|
|
548
367
|
|
|
549
368
|
/**
|
|
550
|
-
*
|
|
369
|
+
* Menu events interface for type-checking
|
|
551
370
|
*
|
|
552
|
-
* Internal interface used when applying the API to a component.
|
|
553
|
-
*
|
|
554
|
-
* @internal
|
|
555
371
|
* @category Components
|
|
372
|
+
* @internal
|
|
556
373
|
*/
|
|
557
|
-
export interface
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
};
|
|
374
|
+
export interface MenuEvents {
|
|
375
|
+
'open': (event: MenuEvent) => void;
|
|
376
|
+
'close': (event: MenuEvent) => void;
|
|
377
|
+
'select': (event: MenuSelectEvent) => void;
|
|
562
378
|
}
|