@y14e/menu 1.4.5 → 1.4.7
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/README.md +6 -4
- package/dist/index.cjs +30 -14
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +25 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,14 +10,16 @@ npm i @y14e/menu
|
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
12
|
// npm
|
|
13
|
-
import Menu from '@y14e/menu@1.4.
|
|
13
|
+
import Menu from '@y14e/menu@1.4.7';
|
|
14
|
+
// with middleware
|
|
15
|
+
import Menu, { flip, offset, shift } from '@y14e/menu@1.4.7';
|
|
14
16
|
|
|
15
17
|
// CDNs
|
|
16
|
-
import Menu from 'https://esm.sh/@y14e/menu@1.4.
|
|
18
|
+
import Menu from 'https://esm.sh/@y14e/menu@1.4.7';
|
|
17
19
|
// or
|
|
18
|
-
import Menu from 'https://cdn.jsdelivr.net/npm/@y14e/menu@1.4.
|
|
20
|
+
import Menu from 'https://cdn.jsdelivr.net/npm/@y14e/menu@1.4.7/+esm';
|
|
19
21
|
// or
|
|
20
|
-
import Menu from 'https://esm.unpkg.com/@y14e/menu@1.4.
|
|
22
|
+
import Menu from 'https://esm.unpkg.com/@y14e/menu@1.4.7';
|
|
21
23
|
```
|
|
22
24
|
|
|
23
25
|
## Usage
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
3
5
|
// node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
|
|
4
6
|
var min = Math.min;
|
|
5
7
|
var max = Math.max;
|
|
@@ -2621,8 +2623,9 @@ var Menu = class _Menu {
|
|
|
2621
2623
|
}
|
|
2622
2624
|
};
|
|
2623
2625
|
#settings;
|
|
2624
|
-
#
|
|
2626
|
+
#externalTrigger;
|
|
2625
2627
|
#isPortal;
|
|
2628
|
+
#isSubmenu;
|
|
2626
2629
|
#triggerElement;
|
|
2627
2630
|
#listElement;
|
|
2628
2631
|
#itemElements;
|
|
@@ -2651,9 +2654,14 @@ var Menu = class _Menu {
|
|
|
2651
2654
|
this.#defaults = this.#mergeOptions(this.#defaults, _Menu.defaults);
|
|
2652
2655
|
this.#settings = this.#mergeOptions(this.#defaults, options);
|
|
2653
2656
|
matchMedia("(prefers-reduced-motion: reduce)").matches && Object.assign(this.#settings.animation, { duration: 0 });
|
|
2654
|
-
const {
|
|
2655
|
-
|
|
2657
|
+
const {
|
|
2658
|
+
externalTrigger = null,
|
|
2659
|
+
isPortal = false,
|
|
2660
|
+
isSubmenu = false
|
|
2661
|
+
} = _internal;
|
|
2662
|
+
this.#externalTrigger = externalTrigger;
|
|
2656
2663
|
this.#isPortal = isPortal;
|
|
2664
|
+
this.#isSubmenu = isSubmenu;
|
|
2657
2665
|
const { selector } = this.#settings;
|
|
2658
2666
|
this.#triggerElement = this.#rootElement.querySelector(
|
|
2659
2667
|
selector[this.#isSubmenu ? "item" : "trigger"]
|
|
@@ -2741,6 +2749,7 @@ var Menu = class _Menu {
|
|
|
2741
2749
|
}
|
|
2742
2750
|
this.#animation?.cancel();
|
|
2743
2751
|
this.#animation = null;
|
|
2752
|
+
this.#externalTrigger = null;
|
|
2744
2753
|
const elements = this.#itemElements;
|
|
2745
2754
|
if (this.#triggerElement) {
|
|
2746
2755
|
elements.push(this.#triggerElement);
|
|
@@ -2831,8 +2840,8 @@ var Menu = class _Menu {
|
|
|
2831
2840
|
if (parent?.querySelector(this.#settings.selector.list)) {
|
|
2832
2841
|
this.#submenus.push(
|
|
2833
2842
|
new _Menu(parent, this.#settings, {
|
|
2834
|
-
|
|
2835
|
-
|
|
2843
|
+
isPortal: !!this.#triggerElement,
|
|
2844
|
+
isSubmenu: true
|
|
2836
2845
|
})
|
|
2837
2846
|
);
|
|
2838
2847
|
} else if (item2.hasAttribute("disabled") || item2.tabIndex < 0) {
|
|
@@ -2916,7 +2925,7 @@ var Menu = class _Menu {
|
|
|
2916
2925
|
}
|
|
2917
2926
|
if (shiftKey && key === "Tab") {
|
|
2918
2927
|
this.close();
|
|
2919
|
-
requestAnimationFrame(() => this.#
|
|
2928
|
+
requestAnimationFrame(() => this.#focusTrigger());
|
|
2920
2929
|
return;
|
|
2921
2930
|
}
|
|
2922
2931
|
if (![
|
|
@@ -2990,7 +2999,7 @@ var Menu = class _Menu {
|
|
|
2990
2999
|
if (!this.#listElement) {
|
|
2991
3000
|
return;
|
|
2992
3001
|
}
|
|
2993
|
-
if (!this.#
|
|
3002
|
+
if (!this.#isPortal || !this.#isSubmenu && this.#triggerElement) {
|
|
2994
3003
|
const style2 = this.#listElement.style;
|
|
2995
3004
|
style2.setProperty("position", "fixed");
|
|
2996
3005
|
this.#cleanupPortal = createPortal(this.#listElement);
|
|
@@ -3006,11 +3015,7 @@ var Menu = class _Menu {
|
|
|
3006
3015
|
this.#itemElements.filter(isFocusable3).at(isFocusLastItem ? -1 : 0)?.focus();
|
|
3007
3016
|
} else {
|
|
3008
3017
|
this.#clearSubmenuTimer();
|
|
3009
|
-
|
|
3010
|
-
if (!(active instanceof HTMLElement)) {
|
|
3011
|
-
return;
|
|
3012
|
-
}
|
|
3013
|
-
this.#triggerElement && this.#containsRoot(active) && this.#triggerElement.focus();
|
|
3018
|
+
this.#focusTrigger();
|
|
3014
3019
|
}
|
|
3015
3020
|
if (!this.#triggerElement) {
|
|
3016
3021
|
return;
|
|
@@ -3075,6 +3080,14 @@ var Menu = class _Menu {
|
|
|
3075
3080
|
#containsRoot(element) {
|
|
3076
3081
|
return this.#rootElement.contains(element) || this.#listElement?.contains(element);
|
|
3077
3082
|
}
|
|
3083
|
+
#focusTrigger() {
|
|
3084
|
+
const active = getActiveElement4();
|
|
3085
|
+
if (!(active instanceof HTMLElement)) {
|
|
3086
|
+
return;
|
|
3087
|
+
}
|
|
3088
|
+
const trigger = this.#externalTrigger ?? this.#triggerElement;
|
|
3089
|
+
this.#containsRoot(active) && trigger && trigger.tabIndex >= 0 && trigger.focus();
|
|
3090
|
+
}
|
|
3078
3091
|
#includesRoot(event) {
|
|
3079
3092
|
const path = event.composedPath();
|
|
3080
3093
|
if (!this.#listElement) {
|
|
@@ -3229,7 +3242,7 @@ function isFocusable3(element) {
|
|
|
3229
3242
|
* WAI-ARIA compliant menu (menu button) pattern implementation in TypeScript.
|
|
3230
3243
|
* Supports checkbox item, radio item, and infinitely nested menus.
|
|
3231
3244
|
*
|
|
3232
|
-
* @version 1.4.
|
|
3245
|
+
* @version 1.4.7
|
|
3233
3246
|
* @author Yusuke Kamiyamane
|
|
3234
3247
|
* @license MIT
|
|
3235
3248
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -3338,4 +3351,7 @@ function isFocusable3(element) {
|
|
|
3338
3351
|
*)
|
|
3339
3352
|
*/
|
|
3340
3353
|
|
|
3341
|
-
|
|
3354
|
+
exports.default = Menu;
|
|
3355
|
+
exports.flip = flip2;
|
|
3356
|
+
exports.offset = offset2;
|
|
3357
|
+
exports.shift = shift2;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Middleware, Placement } from '@floating-ui/dom';
|
|
2
|
+
export { flip, offset, shift } from '@floating-ui/dom';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Menu
|
|
5
6
|
* WAI-ARIA compliant menu (menu button) pattern implementation in TypeScript.
|
|
6
7
|
* Supports checkbox item, radio item, and infinitely nested menus.
|
|
7
8
|
*
|
|
8
|
-
* @version 1.4.
|
|
9
|
+
* @version 1.4.7
|
|
9
10
|
* @author Yusuke Kamiyamane
|
|
10
11
|
* @license MIT
|
|
11
12
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -37,8 +38,9 @@ interface MenuPopoverOptions {
|
|
|
37
38
|
readonly placement?: Placement | string;
|
|
38
39
|
}
|
|
39
40
|
interface InternalOptions {
|
|
40
|
-
readonly
|
|
41
|
+
readonly externalTrigger?: HTMLElement;
|
|
41
42
|
readonly isPortal?: boolean;
|
|
43
|
+
readonly isSubmenu?: boolean;
|
|
42
44
|
}
|
|
43
45
|
declare class Menu {
|
|
44
46
|
#private;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Middleware, Placement } from '@floating-ui/dom';
|
|
2
|
+
export { flip, offset, shift } from '@floating-ui/dom';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Menu
|
|
5
6
|
* WAI-ARIA compliant menu (menu button) pattern implementation in TypeScript.
|
|
6
7
|
* Supports checkbox item, radio item, and infinitely nested menus.
|
|
7
8
|
*
|
|
8
|
-
* @version 1.4.
|
|
9
|
+
* @version 1.4.7
|
|
9
10
|
* @author Yusuke Kamiyamane
|
|
10
11
|
* @license MIT
|
|
11
12
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -37,8 +38,9 @@ interface MenuPopoverOptions {
|
|
|
37
38
|
readonly placement?: Placement | string;
|
|
38
39
|
}
|
|
39
40
|
interface InternalOptions {
|
|
40
|
-
readonly
|
|
41
|
+
readonly externalTrigger?: HTMLElement;
|
|
41
42
|
readonly isPortal?: boolean;
|
|
43
|
+
readonly isSubmenu?: boolean;
|
|
42
44
|
}
|
|
43
45
|
declare class Menu {
|
|
44
46
|
#private;
|
package/dist/index.js
CHANGED
|
@@ -2619,8 +2619,9 @@ var Menu = class _Menu {
|
|
|
2619
2619
|
}
|
|
2620
2620
|
};
|
|
2621
2621
|
#settings;
|
|
2622
|
-
#
|
|
2622
|
+
#externalTrigger;
|
|
2623
2623
|
#isPortal;
|
|
2624
|
+
#isSubmenu;
|
|
2624
2625
|
#triggerElement;
|
|
2625
2626
|
#listElement;
|
|
2626
2627
|
#itemElements;
|
|
@@ -2649,9 +2650,14 @@ var Menu = class _Menu {
|
|
|
2649
2650
|
this.#defaults = this.#mergeOptions(this.#defaults, _Menu.defaults);
|
|
2650
2651
|
this.#settings = this.#mergeOptions(this.#defaults, options);
|
|
2651
2652
|
matchMedia("(prefers-reduced-motion: reduce)").matches && Object.assign(this.#settings.animation, { duration: 0 });
|
|
2652
|
-
const {
|
|
2653
|
-
|
|
2653
|
+
const {
|
|
2654
|
+
externalTrigger = null,
|
|
2655
|
+
isPortal = false,
|
|
2656
|
+
isSubmenu = false
|
|
2657
|
+
} = _internal;
|
|
2658
|
+
this.#externalTrigger = externalTrigger;
|
|
2654
2659
|
this.#isPortal = isPortal;
|
|
2660
|
+
this.#isSubmenu = isSubmenu;
|
|
2655
2661
|
const { selector } = this.#settings;
|
|
2656
2662
|
this.#triggerElement = this.#rootElement.querySelector(
|
|
2657
2663
|
selector[this.#isSubmenu ? "item" : "trigger"]
|
|
@@ -2739,6 +2745,7 @@ var Menu = class _Menu {
|
|
|
2739
2745
|
}
|
|
2740
2746
|
this.#animation?.cancel();
|
|
2741
2747
|
this.#animation = null;
|
|
2748
|
+
this.#externalTrigger = null;
|
|
2742
2749
|
const elements = this.#itemElements;
|
|
2743
2750
|
if (this.#triggerElement) {
|
|
2744
2751
|
elements.push(this.#triggerElement);
|
|
@@ -2829,8 +2836,8 @@ var Menu = class _Menu {
|
|
|
2829
2836
|
if (parent?.querySelector(this.#settings.selector.list)) {
|
|
2830
2837
|
this.#submenus.push(
|
|
2831
2838
|
new _Menu(parent, this.#settings, {
|
|
2832
|
-
|
|
2833
|
-
|
|
2839
|
+
isPortal: !!this.#triggerElement,
|
|
2840
|
+
isSubmenu: true
|
|
2834
2841
|
})
|
|
2835
2842
|
);
|
|
2836
2843
|
} else if (item2.hasAttribute("disabled") || item2.tabIndex < 0) {
|
|
@@ -2914,7 +2921,7 @@ var Menu = class _Menu {
|
|
|
2914
2921
|
}
|
|
2915
2922
|
if (shiftKey && key === "Tab") {
|
|
2916
2923
|
this.close();
|
|
2917
|
-
requestAnimationFrame(() => this.#
|
|
2924
|
+
requestAnimationFrame(() => this.#focusTrigger());
|
|
2918
2925
|
return;
|
|
2919
2926
|
}
|
|
2920
2927
|
if (![
|
|
@@ -2988,7 +2995,7 @@ var Menu = class _Menu {
|
|
|
2988
2995
|
if (!this.#listElement) {
|
|
2989
2996
|
return;
|
|
2990
2997
|
}
|
|
2991
|
-
if (!this.#
|
|
2998
|
+
if (!this.#isPortal || !this.#isSubmenu && this.#triggerElement) {
|
|
2992
2999
|
const style2 = this.#listElement.style;
|
|
2993
3000
|
style2.setProperty("position", "fixed");
|
|
2994
3001
|
this.#cleanupPortal = createPortal(this.#listElement);
|
|
@@ -3004,11 +3011,7 @@ var Menu = class _Menu {
|
|
|
3004
3011
|
this.#itemElements.filter(isFocusable3).at(isFocusLastItem ? -1 : 0)?.focus();
|
|
3005
3012
|
} else {
|
|
3006
3013
|
this.#clearSubmenuTimer();
|
|
3007
|
-
|
|
3008
|
-
if (!(active instanceof HTMLElement)) {
|
|
3009
|
-
return;
|
|
3010
|
-
}
|
|
3011
|
-
this.#triggerElement && this.#containsRoot(active) && this.#triggerElement.focus();
|
|
3014
|
+
this.#focusTrigger();
|
|
3012
3015
|
}
|
|
3013
3016
|
if (!this.#triggerElement) {
|
|
3014
3017
|
return;
|
|
@@ -3073,6 +3076,14 @@ var Menu = class _Menu {
|
|
|
3073
3076
|
#containsRoot(element) {
|
|
3074
3077
|
return this.#rootElement.contains(element) || this.#listElement?.contains(element);
|
|
3075
3078
|
}
|
|
3079
|
+
#focusTrigger() {
|
|
3080
|
+
const active = getActiveElement4();
|
|
3081
|
+
if (!(active instanceof HTMLElement)) {
|
|
3082
|
+
return;
|
|
3083
|
+
}
|
|
3084
|
+
const trigger = this.#externalTrigger ?? this.#triggerElement;
|
|
3085
|
+
this.#containsRoot(active) && trigger && trigger.tabIndex >= 0 && trigger.focus();
|
|
3086
|
+
}
|
|
3076
3087
|
#includesRoot(event) {
|
|
3077
3088
|
const path = event.composedPath();
|
|
3078
3089
|
if (!this.#listElement) {
|
|
@@ -3227,7 +3238,7 @@ function isFocusable3(element) {
|
|
|
3227
3238
|
* WAI-ARIA compliant menu (menu button) pattern implementation in TypeScript.
|
|
3228
3239
|
* Supports checkbox item, radio item, and infinitely nested menus.
|
|
3229
3240
|
*
|
|
3230
|
-
* @version 1.4.
|
|
3241
|
+
* @version 1.4.7
|
|
3231
3242
|
* @author Yusuke Kamiyamane
|
|
3232
3243
|
* @license MIT
|
|
3233
3244
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -3336,4 +3347,4 @@ function isFocusable3(element) {
|
|
|
3336
3347
|
*)
|
|
3337
3348
|
*/
|
|
3338
3349
|
|
|
3339
|
-
export { Menu as default };
|
|
3350
|
+
export { Menu as default, flip2 as flip, offset2 as offset, shift2 as shift };
|