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