@moneyforward/mfui-components 4.1.2 → 4.3.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/dist/src/DropdownMenu/DropdownMenu.js +11 -45
- package/dist/src/DropdownMenu/DropdownMenuItem/DropdownMenuItem.js +2 -2
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenu.d.ts +34 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenu.js +57 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenu.types.d.ts +79 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuDivider/ApplicationMenuDivider.d.ts +7 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuDivider/ApplicationMenuDivider.js +13 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuDivider/ApplicationMenuDivider.types.d.ts +6 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuDivider/ApplicationMenuDivider.types.js +1 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuDivider/index.d.ts +2 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuDivider/index.js +1 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuGroup/ApplicationMenuGroup.d.ts +11 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuGroup/ApplicationMenuGroup.js +20 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuGroup/ApplicationMenuGroup.types.d.ts +18 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuGroup/ApplicationMenuGroup.types.js +1 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuGroup/index.d.ts +2 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuGroup/index.js +1 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuItem/ApplicationMenuItem.d.ts +14 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuItem/ApplicationMenuItem.js +21 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuItem/ApplicationMenuItem.types.d.ts +9 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuItem/ApplicationMenuItem.types.js +1 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuItem/index.d.ts +2 -0
- package/dist/src/GlobalHeader/ApplicationMenu/ApplicationMenuItem/index.js +1 -0
- package/dist/src/GlobalHeader/ApplicationMenu/index.d.ts +2 -0
- package/dist/src/GlobalHeader/ApplicationMenu/index.js +1 -0
- package/dist/src/GlobalHeader/GlobalHeader.d.ts +4 -0
- package/dist/src/GlobalHeader/GlobalHeader.js +7 -1
- package/dist/src/GlobalHeader/GlobalHeader.types.d.ts +47 -7
- package/dist/src/GlobalHeader/index.d.ts +1 -0
- package/dist/src/MultipleSelectBox/MultipleSelectBoxTrigger/MultipleSelectBoxTrigger.js +1 -1
- package/dist/src/SelectBox/SelectBox.js +1 -1
- package/dist/src/Toast/api/toast.d.ts +34 -0
- package/dist/src/Toast/api/toast.js +41 -0
- package/dist/src/shared/Menu/MenuCloseContext.d.ts +10 -0
- package/dist/src/shared/Menu/MenuCloseContext.js +7 -0
- package/dist/src/shared/Menu/MenuContainer.d.ts +10 -0
- package/dist/src/{DropdownMenu/DropdownMenuContainer/DropdownMenuContainer.js → shared/Menu/MenuContainer.js} +8 -7
- package/dist/src/{DropdownMenu/DropdownMenuContainer/DropdownMenuContainer.types.d.ts → shared/Menu/MenuContainer.types.d.ts} +6 -9
- package/dist/src/shared/Menu/MenuContainer.types.js +1 -0
- package/dist/src/shared/Menu/index.d.ts +5 -0
- package/dist/src/shared/Menu/index.js +3 -0
- package/dist/src/shared/Menu/useMenuTriggerActivation.d.ts +35 -0
- package/dist/src/shared/Menu/useMenuTriggerActivation.js +69 -0
- package/dist/styled-system/recipes/application-menu-divider-slot-recipe.d.ts +33 -0
- package/dist/styled-system/recipes/application-menu-divider-slot-recipe.js +32 -0
- package/dist/styled-system/recipes/application-menu-group-slot-recipe.d.ts +33 -0
- package/dist/styled-system/recipes/application-menu-group-slot-recipe.js +28 -0
- package/dist/styled-system/recipes/application-menu-item-slot-recipe.d.ts +33 -0
- package/dist/styled-system/recipes/application-menu-item-slot-recipe.js +28 -0
- package/dist/styled-system/recipes/application-menu-slot-recipe.d.ts +33 -0
- package/dist/styled-system/recipes/application-menu-slot-recipe.js +32 -0
- package/dist/styled-system/recipes/index.d.ts +4 -0
- package/dist/styled-system/recipes/index.js +4 -0
- package/dist/styles.css +47 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/dist/src/DropdownMenu/DropdownMenuContainer/DropdownMenuContainer.d.ts +0 -6
- package/dist/src/DropdownMenu/DropdownMenuContainer/index.d.ts +0 -2
- package/dist/src/DropdownMenu/DropdownMenuContainer/index.js +0 -1
- package/dist/src/DropdownMenu/DropdownMenuContext.d.ts +0 -10
- package/dist/src/DropdownMenu/DropdownMenuContext.js +0 -7
- /package/dist/src/{DropdownMenu/DropdownMenuContainer/DropdownMenuContainer.types.js → GlobalHeader/ApplicationMenu/ApplicationMenu.types.js} +0 -0
|
@@ -12,9 +12,42 @@ declare const showToast: (props: ToastApiProps | string, type?: ToastSlotRecipeV
|
|
|
12
12
|
* Destroy a toast message.
|
|
13
13
|
* If the key is not provided, all toasts will be destroyed.
|
|
14
14
|
*
|
|
15
|
+
* This only hides the toasts; the internal React root stays mounted. To also
|
|
16
|
+
* unmount that root and remove its container, use {@link toast.reset}.
|
|
17
|
+
*
|
|
15
18
|
* @param key - The key of the toast message to destroy.
|
|
16
19
|
*/
|
|
17
20
|
declare const destroyToast: (key?: string) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Tear down the toast renderer completely.
|
|
23
|
+
*
|
|
24
|
+
* Unmounts the internal React root, removes the container element it created,
|
|
25
|
+
* and resets every module-scoped reference, so the next toast starts from the
|
|
26
|
+
* same state as the very first one. Calling it before any toast has been shown,
|
|
27
|
+
* or twice in a row, is a safe no-op.
|
|
28
|
+
*
|
|
29
|
+
* This is intended for test teardown and application shutdown. To only hide the
|
|
30
|
+
* currently displayed toasts, use {@link toast.destroy} instead.
|
|
31
|
+
*
|
|
32
|
+
* The unmount flushes synchronously, which has two consequences: do not call it
|
|
33
|
+
* from a render or an effect cleanup, and wrap it in `act()` in tests. Calling
|
|
34
|
+
* it bare in a test logs "An update to Root inside a test was not wrapped in
|
|
35
|
+
* act(...)".
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* import { act } from '@testing-library/react';
|
|
40
|
+
* import { afterEach } from 'vitest';
|
|
41
|
+
* import { toast } from '@moneyforward/mfui-components/Toast';
|
|
42
|
+
*
|
|
43
|
+
* afterEach(() => {
|
|
44
|
+
* act(() => {
|
|
45
|
+
* toast.reset();
|
|
46
|
+
* });
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
declare const resetToast: () => void;
|
|
18
51
|
export declare const toast: {
|
|
19
52
|
show: typeof showToast;
|
|
20
53
|
success: (props: ToastApiProps | string) => void;
|
|
@@ -23,5 +56,6 @@ export declare const toast: {
|
|
|
23
56
|
progress: (props: ToastApiProps | string) => void;
|
|
24
57
|
caution: (props: ToastApiProps | string) => void;
|
|
25
58
|
destroy: typeof destroyToast;
|
|
59
|
+
reset: typeof resetToast;
|
|
26
60
|
};
|
|
27
61
|
export {};
|
|
@@ -95,11 +95,51 @@ const showToast = (props, type = 'custom') => {
|
|
|
95
95
|
* Destroy a toast message.
|
|
96
96
|
* If the key is not provided, all toasts will be destroyed.
|
|
97
97
|
*
|
|
98
|
+
* This only hides the toasts; the internal React root stays mounted. To also
|
|
99
|
+
* unmount that root and remove its container, use {@link toast.reset}.
|
|
100
|
+
*
|
|
98
101
|
* @param key - The key of the toast message to destroy.
|
|
99
102
|
*/
|
|
100
103
|
const destroyToast = (key) => {
|
|
101
104
|
removeToast(key);
|
|
102
105
|
};
|
|
106
|
+
/**
|
|
107
|
+
* Tear down the toast renderer completely.
|
|
108
|
+
*
|
|
109
|
+
* Unmounts the internal React root, removes the container element it created,
|
|
110
|
+
* and resets every module-scoped reference, so the next toast starts from the
|
|
111
|
+
* same state as the very first one. Calling it before any toast has been shown,
|
|
112
|
+
* or twice in a row, is a safe no-op.
|
|
113
|
+
*
|
|
114
|
+
* This is intended for test teardown and application shutdown. To only hide the
|
|
115
|
+
* currently displayed toasts, use {@link toast.destroy} instead.
|
|
116
|
+
*
|
|
117
|
+
* The unmount flushes synchronously, which has two consequences: do not call it
|
|
118
|
+
* from a render or an effect cleanup, and wrap it in `act()` in tests. Calling
|
|
119
|
+
* it bare in a test logs "An update to Root inside a test was not wrapped in
|
|
120
|
+
* act(...)".
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* import { act } from '@testing-library/react';
|
|
125
|
+
* import { afterEach } from 'vitest';
|
|
126
|
+
* import { toast } from '@moneyforward/mfui-components/Toast';
|
|
127
|
+
*
|
|
128
|
+
* afterEach(() => {
|
|
129
|
+
* act(() => {
|
|
130
|
+
* toast.reset();
|
|
131
|
+
* });
|
|
132
|
+
* });
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
const resetToast = () => {
|
|
136
|
+
root?.unmount();
|
|
137
|
+
rootElement?.remove();
|
|
138
|
+
root = null;
|
|
139
|
+
rootElement = null;
|
|
140
|
+
rootWrapper = undefined;
|
|
141
|
+
toastList = [];
|
|
142
|
+
};
|
|
103
143
|
export const toast = {
|
|
104
144
|
show: showToast,
|
|
105
145
|
success: (props) => {
|
|
@@ -118,4 +158,5 @@ export const toast = {
|
|
|
118
158
|
showToast(props, 'caution');
|
|
119
159
|
},
|
|
120
160
|
destroy: destroyToast,
|
|
161
|
+
reset: resetToast,
|
|
121
162
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type MenuCloseContextValue = {
|
|
2
|
+
/**
|
|
3
|
+
* The function to close the menu popover.
|
|
4
|
+
* This function is provided by the menu component (e.g. `DropdownMenu`, `ApplicationMenu`).
|
|
5
|
+
*/
|
|
6
|
+
closeMenuPopover?: () => void;
|
|
7
|
+
};
|
|
8
|
+
export declare const useMenuCloseContext: () => MenuCloseContextValue;
|
|
9
|
+
export declare const MenuCloseProvider: import("react").Provider<MenuCloseContextValue>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
const MenuCloseContext = createContext({
|
|
4
|
+
closeMenuPopover: undefined,
|
|
5
|
+
});
|
|
6
|
+
export const useMenuCloseContext = () => useContext(MenuCloseContext);
|
|
7
|
+
export const MenuCloseProvider = MenuCloseContext.Provider;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type MenuContainerProps } from './MenuContainer.types';
|
|
2
|
+
/**
|
|
3
|
+
* The shared root component for menu-button components (e.g. `DropdownMenu`, `ApplicationMenu`).
|
|
4
|
+
* Put focusable menu item components (marked with `data-mfui-menu-item` /
|
|
5
|
+
* `data-mfui-focusable="true"`) inside this component.
|
|
6
|
+
*
|
|
7
|
+
* Owns the roving focus of the menu items: Escape / Tab close the menu, ArrowDown / ArrowUp
|
|
8
|
+
* move the focus between the items.
|
|
9
|
+
*/
|
|
10
|
+
export declare const MenuContainer: import("react").ForwardRefExoticComponent<MenuContainerProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { forwardRef, useCallback, useEffect, useRef } from 'react';
|
|
4
|
-
import { cx } from '../../../styled-system/css';
|
|
5
4
|
import { mergeRefs } from '../../utilities/dom/mergeRefs';
|
|
6
|
-
import { dropdownMenuContainerSlotRecipe } from '../../../styled-system/recipes';
|
|
7
5
|
/**
|
|
8
|
-
* The root component for
|
|
9
|
-
* Put
|
|
6
|
+
* The shared root component for menu-button components (e.g. `DropdownMenu`, `ApplicationMenu`).
|
|
7
|
+
* Put focusable menu item components (marked with `data-mfui-menu-item` /
|
|
8
|
+
* `data-mfui-focusable="true"`) inside this component.
|
|
9
|
+
*
|
|
10
|
+
* Owns the roving focus of the menu items: Escape / Tab close the menu, ArrowDown / ArrowUp
|
|
11
|
+
* move the focus between the items.
|
|
10
12
|
*/
|
|
11
|
-
export const
|
|
12
|
-
const classes = dropdownMenuContainerSlotRecipe();
|
|
13
|
+
export const MenuContainer = forwardRef(({ children, className, defaultFocusItem: defaultFocus = 'first', style, onClose }, ref) => {
|
|
13
14
|
const menuContainerRef = useRef(null);
|
|
14
15
|
const getFocusableItems = useCallback(() => menuContainerRef.current?.querySelectorAll('[data-mfui-menu-item]:is([data-mfui-focusable=true])'), []);
|
|
15
16
|
useEffect(() => {
|
|
@@ -54,5 +55,5 @@ export const DropdownMenuContainer = forwardRef(({ children, className, defaultF
|
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
}, [onClose, getFocusableItems]);
|
|
57
|
-
return (_jsx("div", { ref: mergeRefs(ref, menuContainerRef), "data-mfui-menu-container": true, role: "menu", className:
|
|
58
|
+
return (_jsx("div", { ref: mergeRefs(ref, menuContainerRef), "data-mfui-menu-container": true, role: "menu", className: className, tabIndex: -1, style: style, onKeyDown: handleKeyDown, children: children }));
|
|
58
59
|
});
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
4
|
-
export type DropdownMenuDefaultFocusItem = 'first' | 'last' | 'none';
|
|
5
|
-
export type DropdownMenuContainerProps = {
|
|
1
|
+
import { type MenuDefaultFocusItem } from './useMenuTriggerActivation';
|
|
2
|
+
export type MenuContainerProps = {
|
|
6
3
|
/**
|
|
7
4
|
* The content of the component.
|
|
8
5
|
*
|
|
9
|
-
* It should be a collection of
|
|
6
|
+
* It should be a collection of menu item / divider / heading components.
|
|
10
7
|
*/
|
|
11
8
|
children: React.ReactNode;
|
|
12
9
|
/**
|
|
@@ -14,7 +11,7 @@ export type DropdownMenuContainerProps = {
|
|
|
14
11
|
*/
|
|
15
12
|
className?: string;
|
|
16
13
|
/**
|
|
17
|
-
* The default focus position of the
|
|
14
|
+
* The default focus position of the menu.
|
|
18
15
|
*
|
|
19
16
|
* It should be either 'first', 'last' or 'none'.
|
|
20
17
|
*
|
|
@@ -26,7 +23,7 @@ export type DropdownMenuContainerProps = {
|
|
|
26
23
|
*
|
|
27
24
|
* @default 'first'
|
|
28
25
|
*/
|
|
29
|
-
defaultFocusItem?:
|
|
26
|
+
defaultFocusItem?: MenuDefaultFocusItem;
|
|
30
27
|
/**
|
|
31
28
|
* The style to apply to the component.
|
|
32
29
|
* This prop is used to add custom styles to the component.
|
|
@@ -36,7 +33,7 @@ export type DropdownMenuContainerProps = {
|
|
|
36
33
|
*/
|
|
37
34
|
style?: React.CSSProperties;
|
|
38
35
|
/**
|
|
39
|
-
* The function to close the
|
|
36
|
+
* The function to close the menu.
|
|
40
37
|
*/
|
|
41
38
|
onClose: () => void;
|
|
42
39
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { MenuContainer } from './MenuContainer';
|
|
2
|
+
export type { MenuContainerProps } from './MenuContainer.types';
|
|
3
|
+
export { useMenuTriggerActivation } from './useMenuTriggerActivation';
|
|
4
|
+
export type { MenuDefaultFocusItem } from './useMenuTriggerActivation';
|
|
5
|
+
export { useMenuCloseContext, MenuCloseProvider } from './MenuCloseContext';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type FocusEvent, type KeyboardEvent, type MouseEvent } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* The default focus position of the menu.
|
|
4
|
+
*/
|
|
5
|
+
export type MenuDefaultFocusItem = 'first' | 'last' | 'none';
|
|
6
|
+
/**
|
|
7
|
+
* Shared trigger-activation machinery for menu-button components (e.g. `DropdownMenu`,
|
|
8
|
+
* `ApplicationMenu`). Tracks whether the trigger was activated by keyboard so the menu focuses
|
|
9
|
+
* its first item on Enter / Space, and moves the default focus position on ArrowUp / ArrowDown.
|
|
10
|
+
*
|
|
11
|
+
* The returned handlers wrap the corresponding handler already provided by `Popover`'s
|
|
12
|
+
* `renderTrigger`, so callers compose them at the trigger call site:
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* const { menuDefaultFocusPosition, handleTriggerKeyDown, handleTriggerBlur, handleTriggerClick } =
|
|
17
|
+
* useMenuTriggerActivation();
|
|
18
|
+
*
|
|
19
|
+
* <Popover
|
|
20
|
+
* renderTrigger={({ togglePopover, handleTriggerKeyDown: popoverKeyDown, handleTriggerBlur: popoverBlur }) => (
|
|
21
|
+
* <Button
|
|
22
|
+
* onKeyDown={(event) => handleTriggerKeyDown(event, popoverKeyDown)}
|
|
23
|
+
* onBlur={(event) => handleTriggerBlur(event, popoverBlur)}
|
|
24
|
+
* onClick={(event) => handleTriggerClick(event, togglePopover)}
|
|
25
|
+
* />
|
|
26
|
+
* )}
|
|
27
|
+
* />
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function useMenuTriggerActivation(): {
|
|
31
|
+
menuDefaultFocusPosition: MenuDefaultFocusItem;
|
|
32
|
+
handleTriggerKeyDown: (event: KeyboardEvent<HTMLElement>, next: (event: KeyboardEvent<HTMLElement>) => void) => void;
|
|
33
|
+
handleTriggerBlur: (event: FocusEvent<HTMLElement>, next: (event: FocusEvent<HTMLElement>) => void) => void;
|
|
34
|
+
handleTriggerClick: (event: MouseEvent<HTMLElement>, next: (event: MouseEvent<HTMLElement>) => void) => void;
|
|
35
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useCallback, useRef, useState } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Shared trigger-activation machinery for menu-button components (e.g. `DropdownMenu`,
|
|
5
|
+
* `ApplicationMenu`). Tracks whether the trigger was activated by keyboard so the menu focuses
|
|
6
|
+
* its first item on Enter / Space, and moves the default focus position on ArrowUp / ArrowDown.
|
|
7
|
+
*
|
|
8
|
+
* The returned handlers wrap the corresponding handler already provided by `Popover`'s
|
|
9
|
+
* `renderTrigger`, so callers compose them at the trigger call site:
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* const { menuDefaultFocusPosition, handleTriggerKeyDown, handleTriggerBlur, handleTriggerClick } =
|
|
14
|
+
* useMenuTriggerActivation();
|
|
15
|
+
*
|
|
16
|
+
* <Popover
|
|
17
|
+
* renderTrigger={({ togglePopover, handleTriggerKeyDown: popoverKeyDown, handleTriggerBlur: popoverBlur }) => (
|
|
18
|
+
* <Button
|
|
19
|
+
* onKeyDown={(event) => handleTriggerKeyDown(event, popoverKeyDown)}
|
|
20
|
+
* onBlur={(event) => handleTriggerBlur(event, popoverBlur)}
|
|
21
|
+
* onClick={(event) => handleTriggerClick(event, togglePopover)}
|
|
22
|
+
* />
|
|
23
|
+
* )}
|
|
24
|
+
* />
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function useMenuTriggerActivation() {
|
|
28
|
+
const [menuDefaultFocusPosition, setMenuDefaultFocusPosition] = useState('first');
|
|
29
|
+
// Tracks keyboard activation (Enter / Space) of the trigger. The resulting click event usually
|
|
30
|
+
// has `detail === 0`, but Safari reports keyboard-triggered clicks with `detail === 1`, so the
|
|
31
|
+
// keydown itself is recorded as the reliable signal.
|
|
32
|
+
const isTriggerActivatedByKeyboardRef = useRef(false);
|
|
33
|
+
const handleTriggerKeyDown = useCallback((event, next) => {
|
|
34
|
+
// The flag only survives from an Enter / Space keydown to its follow-up click; any other key
|
|
35
|
+
// invalidates the pending keyboard activation so the flag cannot linger when the click never
|
|
36
|
+
// fires.
|
|
37
|
+
isTriggerActivatedByKeyboardRef.current = event.key === 'Enter' || event.key === ' ';
|
|
38
|
+
switch (event.key) {
|
|
39
|
+
case 'ArrowDown':
|
|
40
|
+
event.stopPropagation();
|
|
41
|
+
event.preventDefault();
|
|
42
|
+
setMenuDefaultFocusPosition('first');
|
|
43
|
+
break;
|
|
44
|
+
case 'ArrowUp':
|
|
45
|
+
event.stopPropagation();
|
|
46
|
+
event.preventDefault();
|
|
47
|
+
setMenuDefaultFocusPosition('last');
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
next(event);
|
|
51
|
+
}, []);
|
|
52
|
+
const handleTriggerBlur = useCallback((event, next) => {
|
|
53
|
+
// Focus leaving the trigger invalidates any pending keyboard activation (e.g. a Space
|
|
54
|
+
// keydown whose follow-up click never fired), so a later mouse click cannot be
|
|
55
|
+
// misclassified as keyboard activation.
|
|
56
|
+
isTriggerActivatedByKeyboardRef.current = false;
|
|
57
|
+
next(event);
|
|
58
|
+
}, []);
|
|
59
|
+
const handleTriggerClick = useCallback((event, next) => {
|
|
60
|
+
// Opening with the keyboard (Enter / Space) focuses the first item, following the
|
|
61
|
+
// WAI-ARIA menu button pattern. Opening with the mouse focuses no item; the menu
|
|
62
|
+
// container receives focus instead so that arrow keys still work.
|
|
63
|
+
const isKeyboardActivation = isTriggerActivatedByKeyboardRef.current || event.detail === 0;
|
|
64
|
+
isTriggerActivatedByKeyboardRef.current = false;
|
|
65
|
+
setMenuDefaultFocusPosition(isKeyboardActivation ? 'first' : 'none');
|
|
66
|
+
next(event);
|
|
67
|
+
}, []);
|
|
68
|
+
return { menuDefaultFocusPosition, handleTriggerKeyDown, handleTriggerBlur, handleTriggerClick };
|
|
69
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import type { ConditionalValue } from '../types/index';
|
|
3
|
+
import type { DistributiveOmit, Pretty } from '../types/system-types';
|
|
4
|
+
|
|
5
|
+
interface ApplicationMenuDividerSlotRecipeVariant {
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type ApplicationMenuDividerSlotRecipeVariantMap = {
|
|
10
|
+
[key in keyof ApplicationMenuDividerSlotRecipeVariant]: Array<ApplicationMenuDividerSlotRecipeVariant[key]>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type ApplicationMenuDividerSlotRecipeSlot = "root" | "line"
|
|
14
|
+
|
|
15
|
+
export type ApplicationMenuDividerSlotRecipeVariantProps = {
|
|
16
|
+
[key in keyof ApplicationMenuDividerSlotRecipeVariant]?: ConditionalValue<ApplicationMenuDividerSlotRecipeVariant[key]> | undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ApplicationMenuDividerSlotRecipeRecipe {
|
|
20
|
+
__slot: ApplicationMenuDividerSlotRecipeSlot
|
|
21
|
+
__type: ApplicationMenuDividerSlotRecipeVariantProps
|
|
22
|
+
(props?: ApplicationMenuDividerSlotRecipeVariantProps): Pretty<Record<ApplicationMenuDividerSlotRecipeSlot, string>>
|
|
23
|
+
raw: (props?: ApplicationMenuDividerSlotRecipeVariantProps) => ApplicationMenuDividerSlotRecipeVariantProps
|
|
24
|
+
variantMap: ApplicationMenuDividerSlotRecipeVariantMap
|
|
25
|
+
variantKeys: Array<keyof ApplicationMenuDividerSlotRecipeVariant>
|
|
26
|
+
splitVariantProps<Props extends ApplicationMenuDividerSlotRecipeVariantProps>(props: Props): [ApplicationMenuDividerSlotRecipeVariantProps, Pretty<DistributiveOmit<Props, keyof ApplicationMenuDividerSlotRecipeVariantProps>>]
|
|
27
|
+
getVariantProps: (props?: ApplicationMenuDividerSlotRecipeVariantProps) => ApplicationMenuDividerSlotRecipeVariantProps
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Slot class created for the MFUI ApplicationMenuDivider component.
|
|
32
|
+
*/
|
|
33
|
+
export declare const applicationMenuDividerSlotRecipe: ApplicationMenuDividerSlotRecipeRecipe
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { compact, getSlotCompoundVariant, memo, splitProps } from '../helpers.js';
|
|
2
|
+
import { createRecipe } from './create-recipe.js';
|
|
3
|
+
const applicationMenuDividerSlotRecipeDefaultVariants = {};
|
|
4
|
+
const applicationMenuDividerSlotRecipeCompoundVariants = [];
|
|
5
|
+
const applicationMenuDividerSlotRecipeSlotNames = [
|
|
6
|
+
[
|
|
7
|
+
"root",
|
|
8
|
+
"ApplicationMenuDivider__root"
|
|
9
|
+
],
|
|
10
|
+
[
|
|
11
|
+
"line",
|
|
12
|
+
"ApplicationMenuDivider__line"
|
|
13
|
+
]
|
|
14
|
+
];
|
|
15
|
+
const applicationMenuDividerSlotRecipeSlotFns = /* @__PURE__ */ applicationMenuDividerSlotRecipeSlotNames.map(([slotName, slotKey]) => [slotName, createRecipe(slotKey, applicationMenuDividerSlotRecipeDefaultVariants, getSlotCompoundVariant(applicationMenuDividerSlotRecipeCompoundVariants, slotName))]);
|
|
16
|
+
const applicationMenuDividerSlotRecipeFn = memo((props = {}) => {
|
|
17
|
+
return Object.fromEntries(applicationMenuDividerSlotRecipeSlotFns.map(([slotName, slotFn]) => [slotName, slotFn.recipeFn(props)]));
|
|
18
|
+
});
|
|
19
|
+
const applicationMenuDividerSlotRecipeVariantKeys = [];
|
|
20
|
+
const getVariantProps = (variants) => ({ ...applicationMenuDividerSlotRecipeDefaultVariants, ...compact(variants) });
|
|
21
|
+
export const applicationMenuDividerSlotRecipe = /* @__PURE__ */ Object.assign(applicationMenuDividerSlotRecipeFn, {
|
|
22
|
+
__recipe__: false,
|
|
23
|
+
__name__: 'applicationMenuDividerSlotRecipe',
|
|
24
|
+
raw: (props) => props,
|
|
25
|
+
classNameMap: {},
|
|
26
|
+
variantKeys: applicationMenuDividerSlotRecipeVariantKeys,
|
|
27
|
+
variantMap: {},
|
|
28
|
+
splitVariantProps(props) {
|
|
29
|
+
return splitProps(props, applicationMenuDividerSlotRecipeVariantKeys);
|
|
30
|
+
},
|
|
31
|
+
getVariantProps
|
|
32
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import type { ConditionalValue } from '../types/index';
|
|
3
|
+
import type { DistributiveOmit, Pretty } from '../types/system-types';
|
|
4
|
+
|
|
5
|
+
interface ApplicationMenuGroupSlotRecipeVariant {
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type ApplicationMenuGroupSlotRecipeVariantMap = {
|
|
10
|
+
[key in keyof ApplicationMenuGroupSlotRecipeVariant]: Array<ApplicationMenuGroupSlotRecipeVariant[key]>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type ApplicationMenuGroupSlotRecipeSlot = "root"
|
|
14
|
+
|
|
15
|
+
export type ApplicationMenuGroupSlotRecipeVariantProps = {
|
|
16
|
+
[key in keyof ApplicationMenuGroupSlotRecipeVariant]?: ConditionalValue<ApplicationMenuGroupSlotRecipeVariant[key]> | undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ApplicationMenuGroupSlotRecipeRecipe {
|
|
20
|
+
__slot: ApplicationMenuGroupSlotRecipeSlot
|
|
21
|
+
__type: ApplicationMenuGroupSlotRecipeVariantProps
|
|
22
|
+
(props?: ApplicationMenuGroupSlotRecipeVariantProps): Pretty<Record<ApplicationMenuGroupSlotRecipeSlot, string>>
|
|
23
|
+
raw: (props?: ApplicationMenuGroupSlotRecipeVariantProps) => ApplicationMenuGroupSlotRecipeVariantProps
|
|
24
|
+
variantMap: ApplicationMenuGroupSlotRecipeVariantMap
|
|
25
|
+
variantKeys: Array<keyof ApplicationMenuGroupSlotRecipeVariant>
|
|
26
|
+
splitVariantProps<Props extends ApplicationMenuGroupSlotRecipeVariantProps>(props: Props): [ApplicationMenuGroupSlotRecipeVariantProps, Pretty<DistributiveOmit<Props, keyof ApplicationMenuGroupSlotRecipeVariantProps>>]
|
|
27
|
+
getVariantProps: (props?: ApplicationMenuGroupSlotRecipeVariantProps) => ApplicationMenuGroupSlotRecipeVariantProps
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Slot class created for the MFUI ApplicationMenuGroup component.
|
|
32
|
+
*/
|
|
33
|
+
export declare const applicationMenuGroupSlotRecipe: ApplicationMenuGroupSlotRecipeRecipe
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { compact, getSlotCompoundVariant, memo, splitProps } from '../helpers.js';
|
|
2
|
+
import { createRecipe } from './create-recipe.js';
|
|
3
|
+
const applicationMenuGroupSlotRecipeDefaultVariants = {};
|
|
4
|
+
const applicationMenuGroupSlotRecipeCompoundVariants = [];
|
|
5
|
+
const applicationMenuGroupSlotRecipeSlotNames = [
|
|
6
|
+
[
|
|
7
|
+
"root",
|
|
8
|
+
"ApplicationMenuGroup__root"
|
|
9
|
+
]
|
|
10
|
+
];
|
|
11
|
+
const applicationMenuGroupSlotRecipeSlotFns = /* @__PURE__ */ applicationMenuGroupSlotRecipeSlotNames.map(([slotName, slotKey]) => [slotName, createRecipe(slotKey, applicationMenuGroupSlotRecipeDefaultVariants, getSlotCompoundVariant(applicationMenuGroupSlotRecipeCompoundVariants, slotName))]);
|
|
12
|
+
const applicationMenuGroupSlotRecipeFn = memo((props = {}) => {
|
|
13
|
+
return Object.fromEntries(applicationMenuGroupSlotRecipeSlotFns.map(([slotName, slotFn]) => [slotName, slotFn.recipeFn(props)]));
|
|
14
|
+
});
|
|
15
|
+
const applicationMenuGroupSlotRecipeVariantKeys = [];
|
|
16
|
+
const getVariantProps = (variants) => ({ ...applicationMenuGroupSlotRecipeDefaultVariants, ...compact(variants) });
|
|
17
|
+
export const applicationMenuGroupSlotRecipe = /* @__PURE__ */ Object.assign(applicationMenuGroupSlotRecipeFn, {
|
|
18
|
+
__recipe__: false,
|
|
19
|
+
__name__: 'applicationMenuGroupSlotRecipe',
|
|
20
|
+
raw: (props) => props,
|
|
21
|
+
classNameMap: {},
|
|
22
|
+
variantKeys: applicationMenuGroupSlotRecipeVariantKeys,
|
|
23
|
+
variantMap: {},
|
|
24
|
+
splitVariantProps(props) {
|
|
25
|
+
return splitProps(props, applicationMenuGroupSlotRecipeVariantKeys);
|
|
26
|
+
},
|
|
27
|
+
getVariantProps
|
|
28
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import type { ConditionalValue } from '../types/index';
|
|
3
|
+
import type { DistributiveOmit, Pretty } from '../types/system-types';
|
|
4
|
+
|
|
5
|
+
interface ApplicationMenuItemSlotRecipeVariant {
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type ApplicationMenuItemSlotRecipeVariantMap = {
|
|
10
|
+
[key in keyof ApplicationMenuItemSlotRecipeVariant]: Array<ApplicationMenuItemSlotRecipeVariant[key]>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type ApplicationMenuItemSlotRecipeSlot = "root"
|
|
14
|
+
|
|
15
|
+
export type ApplicationMenuItemSlotRecipeVariantProps = {
|
|
16
|
+
[key in keyof ApplicationMenuItemSlotRecipeVariant]?: ConditionalValue<ApplicationMenuItemSlotRecipeVariant[key]> | undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ApplicationMenuItemSlotRecipeRecipe {
|
|
20
|
+
__slot: ApplicationMenuItemSlotRecipeSlot
|
|
21
|
+
__type: ApplicationMenuItemSlotRecipeVariantProps
|
|
22
|
+
(props?: ApplicationMenuItemSlotRecipeVariantProps): Pretty<Record<ApplicationMenuItemSlotRecipeSlot, string>>
|
|
23
|
+
raw: (props?: ApplicationMenuItemSlotRecipeVariantProps) => ApplicationMenuItemSlotRecipeVariantProps
|
|
24
|
+
variantMap: ApplicationMenuItemSlotRecipeVariantMap
|
|
25
|
+
variantKeys: Array<keyof ApplicationMenuItemSlotRecipeVariant>
|
|
26
|
+
splitVariantProps<Props extends ApplicationMenuItemSlotRecipeVariantProps>(props: Props): [ApplicationMenuItemSlotRecipeVariantProps, Pretty<DistributiveOmit<Props, keyof ApplicationMenuItemSlotRecipeVariantProps>>]
|
|
27
|
+
getVariantProps: (props?: ApplicationMenuItemSlotRecipeVariantProps) => ApplicationMenuItemSlotRecipeVariantProps
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Slot class created for the MFUI ApplicationMenuItem component.
|
|
32
|
+
*/
|
|
33
|
+
export declare const applicationMenuItemSlotRecipe: ApplicationMenuItemSlotRecipeRecipe
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { compact, getSlotCompoundVariant, memo, splitProps } from '../helpers.js';
|
|
2
|
+
import { createRecipe } from './create-recipe.js';
|
|
3
|
+
const applicationMenuItemSlotRecipeDefaultVariants = {};
|
|
4
|
+
const applicationMenuItemSlotRecipeCompoundVariants = [];
|
|
5
|
+
const applicationMenuItemSlotRecipeSlotNames = [
|
|
6
|
+
[
|
|
7
|
+
"root",
|
|
8
|
+
"ApplicationMenuItem__root"
|
|
9
|
+
]
|
|
10
|
+
];
|
|
11
|
+
const applicationMenuItemSlotRecipeSlotFns = /* @__PURE__ */ applicationMenuItemSlotRecipeSlotNames.map(([slotName, slotKey]) => [slotName, createRecipe(slotKey, applicationMenuItemSlotRecipeDefaultVariants, getSlotCompoundVariant(applicationMenuItemSlotRecipeCompoundVariants, slotName))]);
|
|
12
|
+
const applicationMenuItemSlotRecipeFn = memo((props = {}) => {
|
|
13
|
+
return Object.fromEntries(applicationMenuItemSlotRecipeSlotFns.map(([slotName, slotFn]) => [slotName, slotFn.recipeFn(props)]));
|
|
14
|
+
});
|
|
15
|
+
const applicationMenuItemSlotRecipeVariantKeys = [];
|
|
16
|
+
const getVariantProps = (variants) => ({ ...applicationMenuItemSlotRecipeDefaultVariants, ...compact(variants) });
|
|
17
|
+
export const applicationMenuItemSlotRecipe = /* @__PURE__ */ Object.assign(applicationMenuItemSlotRecipeFn, {
|
|
18
|
+
__recipe__: false,
|
|
19
|
+
__name__: 'applicationMenuItemSlotRecipe',
|
|
20
|
+
raw: (props) => props,
|
|
21
|
+
classNameMap: {},
|
|
22
|
+
variantKeys: applicationMenuItemSlotRecipeVariantKeys,
|
|
23
|
+
variantMap: {},
|
|
24
|
+
splitVariantProps(props) {
|
|
25
|
+
return splitProps(props, applicationMenuItemSlotRecipeVariantKeys);
|
|
26
|
+
},
|
|
27
|
+
getVariantProps
|
|
28
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import type { ConditionalValue } from '../types/index';
|
|
3
|
+
import type { DistributiveOmit, Pretty } from '../types/system-types';
|
|
4
|
+
|
|
5
|
+
interface ApplicationMenuSlotRecipeVariant {
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type ApplicationMenuSlotRecipeVariantMap = {
|
|
10
|
+
[key in keyof ApplicationMenuSlotRecipeVariant]: Array<ApplicationMenuSlotRecipeVariant[key]>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type ApplicationMenuSlotRecipeSlot = "popover" | "menuContainer"
|
|
14
|
+
|
|
15
|
+
export type ApplicationMenuSlotRecipeVariantProps = {
|
|
16
|
+
[key in keyof ApplicationMenuSlotRecipeVariant]?: ConditionalValue<ApplicationMenuSlotRecipeVariant[key]> | undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ApplicationMenuSlotRecipeRecipe {
|
|
20
|
+
__slot: ApplicationMenuSlotRecipeSlot
|
|
21
|
+
__type: ApplicationMenuSlotRecipeVariantProps
|
|
22
|
+
(props?: ApplicationMenuSlotRecipeVariantProps): Pretty<Record<ApplicationMenuSlotRecipeSlot, string>>
|
|
23
|
+
raw: (props?: ApplicationMenuSlotRecipeVariantProps) => ApplicationMenuSlotRecipeVariantProps
|
|
24
|
+
variantMap: ApplicationMenuSlotRecipeVariantMap
|
|
25
|
+
variantKeys: Array<keyof ApplicationMenuSlotRecipeVariant>
|
|
26
|
+
splitVariantProps<Props extends ApplicationMenuSlotRecipeVariantProps>(props: Props): [ApplicationMenuSlotRecipeVariantProps, Pretty<DistributiveOmit<Props, keyof ApplicationMenuSlotRecipeVariantProps>>]
|
|
27
|
+
getVariantProps: (props?: ApplicationMenuSlotRecipeVariantProps) => ApplicationMenuSlotRecipeVariantProps
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Slot class created for the MFUI ApplicationMenu component.
|
|
32
|
+
*/
|
|
33
|
+
export declare const applicationMenuSlotRecipe: ApplicationMenuSlotRecipeRecipe
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { compact, getSlotCompoundVariant, memo, splitProps } from '../helpers.js';
|
|
2
|
+
import { createRecipe } from './create-recipe.js';
|
|
3
|
+
const applicationMenuSlotRecipeDefaultVariants = {};
|
|
4
|
+
const applicationMenuSlotRecipeCompoundVariants = [];
|
|
5
|
+
const applicationMenuSlotRecipeSlotNames = [
|
|
6
|
+
[
|
|
7
|
+
"popover",
|
|
8
|
+
"ApplicationMenu__popover"
|
|
9
|
+
],
|
|
10
|
+
[
|
|
11
|
+
"menuContainer",
|
|
12
|
+
"ApplicationMenu__menuContainer"
|
|
13
|
+
]
|
|
14
|
+
];
|
|
15
|
+
const applicationMenuSlotRecipeSlotFns = /* @__PURE__ */ applicationMenuSlotRecipeSlotNames.map(([slotName, slotKey]) => [slotName, createRecipe(slotKey, applicationMenuSlotRecipeDefaultVariants, getSlotCompoundVariant(applicationMenuSlotRecipeCompoundVariants, slotName))]);
|
|
16
|
+
const applicationMenuSlotRecipeFn = memo((props = {}) => {
|
|
17
|
+
return Object.fromEntries(applicationMenuSlotRecipeSlotFns.map(([slotName, slotFn]) => [slotName, slotFn.recipeFn(props)]));
|
|
18
|
+
});
|
|
19
|
+
const applicationMenuSlotRecipeVariantKeys = [];
|
|
20
|
+
const getVariantProps = (variants) => ({ ...applicationMenuSlotRecipeDefaultVariants, ...compact(variants) });
|
|
21
|
+
export const applicationMenuSlotRecipe = /* @__PURE__ */ Object.assign(applicationMenuSlotRecipeFn, {
|
|
22
|
+
__recipe__: false,
|
|
23
|
+
__name__: 'applicationMenuSlotRecipe',
|
|
24
|
+
raw: (props) => props,
|
|
25
|
+
classNameMap: {},
|
|
26
|
+
variantKeys: applicationMenuSlotRecipeVariantKeys,
|
|
27
|
+
variantMap: {},
|
|
28
|
+
splitVariantProps(props) {
|
|
29
|
+
return splitProps(props, applicationMenuSlotRecipeVariantKeys);
|
|
30
|
+
},
|
|
31
|
+
getVariantProps
|
|
32
|
+
});
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
|
+
export * from './application-menu-slot-recipe';
|
|
3
|
+
export * from './application-menu-divider-slot-recipe';
|
|
4
|
+
export * from './application-menu-item-slot-recipe';
|
|
5
|
+
export * from './application-menu-group-slot-recipe';
|
|
2
6
|
export * from './breadcrumbs-slot-recipe';
|
|
3
7
|
export * from './icon-button-slot-recipe';
|
|
4
8
|
export * from './focus-indicator-slot-recipe';
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export * from './application-menu-slot-recipe.js';
|
|
2
|
+
export * from './application-menu-divider-slot-recipe.js';
|
|
3
|
+
export * from './application-menu-item-slot-recipe.js';
|
|
4
|
+
export * from './application-menu-group-slot-recipe.js';
|
|
1
5
|
export * from './breadcrumbs-slot-recipe.js';
|
|
2
6
|
export * from './icon-button-slot-recipe.js';
|
|
3
7
|
export * from './focus-indicator-slot-recipe.js';
|