@fluentui-react-native/menu 1.4.14 → 1.4.16
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/CHANGELOG.json +91 -1
- package/CHANGELOG.md +28 -2
- package/lib/MenuItem/MenuItem.d.ts.map +1 -1
- package/lib/MenuItem/MenuItem.js +9 -2
- package/lib/MenuItem/MenuItem.js.map +1 -1
- package/lib/MenuItem/MenuItem.styling.d.ts.map +1 -1
- package/lib/MenuItem/MenuItem.styling.js +13 -0
- package/lib/MenuItem/MenuItem.styling.js.map +1 -1
- package/lib/MenuItem/MenuItem.types.d.ts +9 -1
- package/lib/MenuItem/MenuItem.types.d.ts.map +1 -1
- package/lib/MenuItem/MenuItem.types.js.map +1 -1
- package/lib/MenuItem/MenuItemTokens.d.ts.map +1 -1
- package/lib/MenuItem/MenuItemTokens.js +5 -0
- package/lib/MenuItem/MenuItemTokens.js.map +1 -1
- package/lib/MenuItem/MenuItemTokens.macos.d.ts.map +1 -1
- package/lib/MenuItem/MenuItemTokens.macos.js +5 -0
- package/lib/MenuItem/MenuItemTokens.macos.js.map +1 -1
- package/lib/MenuItem/MenuItemTokens.win32.d.ts.map +1 -1
- package/lib/MenuItem/MenuItemTokens.win32.js +6 -0
- package/lib/MenuItem/MenuItemTokens.win32.js.map +1 -1
- package/lib/MenuItem/useMenuItem.d.ts.map +1 -1
- package/lib/MenuItem/useMenuItem.js +2 -2
- package/lib/MenuItem/useMenuItem.js.map +1 -1
- package/lib/MenuItemCheckbox/MenuItemCheckbox.d.ts.map +1 -1
- package/lib/MenuItemCheckbox/MenuItemCheckbox.js +9 -2
- package/lib/MenuItemCheckbox/MenuItemCheckbox.js.map +1 -1
- package/lib/MenuItemCheckbox/MenuItemCheckbox.styling.d.ts.map +1 -1
- package/lib/MenuItemCheckbox/MenuItemCheckbox.styling.js +13 -0
- package/lib/MenuItemCheckbox/MenuItemCheckbox.styling.js.map +1 -1
- package/lib/MenuItemCheckbox/MenuItemCheckbox.types.d.ts +9 -1
- package/lib/MenuItemCheckbox/MenuItemCheckbox.types.d.ts.map +1 -1
- package/lib/MenuItemCheckbox/MenuItemCheckbox.types.js.map +1 -1
- package/lib/MenuItemCheckbox/MenuItemCheckboxTokens.d.ts.map +1 -1
- package/lib/MenuItemCheckbox/MenuItemCheckboxTokens.js +5 -0
- package/lib/MenuItemCheckbox/MenuItemCheckboxTokens.js.map +1 -1
- package/lib/MenuItemCheckbox/MenuItemCheckboxTokens.macos.d.ts.map +1 -1
- package/lib/MenuItemCheckbox/MenuItemCheckboxTokens.macos.js +5 -0
- package/lib/MenuItemCheckbox/MenuItemCheckboxTokens.macos.js.map +1 -1
- package/lib/MenuItemCheckbox/MenuItemCheckboxTokens.win32.d.ts.map +1 -1
- package/lib/MenuItemCheckbox/MenuItemCheckboxTokens.win32.js +6 -0
- package/lib/MenuItemCheckbox/MenuItemCheckboxTokens.win32.js.map +1 -1
- package/lib/MenuItemCheckbox/useMenuItemCheckbox.d.ts.map +1 -1
- package/lib/MenuItemCheckbox/useMenuItemCheckbox.js +2 -2
- package/lib/MenuItemCheckbox/useMenuItemCheckbox.js.map +1 -1
- package/lib/MenuList/MenuList.types.d.ts +4 -0
- package/lib/MenuList/MenuList.types.d.ts.map +1 -1
- package/lib/MenuList/useMenuListContextValue.js +1 -1
- package/lib/MenuList/useMenuListContextValue.js.map +1 -1
- package/lib/context/menuContext.d.ts.map +1 -1
- package/lib/context/menuContext.js +1 -0
- package/lib/context/menuContext.js.map +1 -1
- package/lib/context/menuListContext.d.ts +1 -0
- package/lib/context/menuListContext.d.ts.map +1 -1
- package/lib/context/menuListContext.js +1 -0
- package/lib/context/menuListContext.js.map +1 -1
- package/lib-commonjs/MenuItem/MenuItem.d.ts.map +1 -1
- package/lib-commonjs/MenuItem/MenuItem.js +8 -1
- package/lib-commonjs/MenuItem/MenuItem.js.map +1 -1
- package/lib-commonjs/MenuItem/MenuItem.styling.d.ts.map +1 -1
- package/lib-commonjs/MenuItem/MenuItem.styling.js +13 -0
- package/lib-commonjs/MenuItem/MenuItem.styling.js.map +1 -1
- package/lib-commonjs/MenuItem/MenuItem.types.d.ts +9 -1
- package/lib-commonjs/MenuItem/MenuItem.types.d.ts.map +1 -1
- package/lib-commonjs/MenuItem/MenuItem.types.js.map +1 -1
- package/lib-commonjs/MenuItem/MenuItemTokens.d.ts.map +1 -1
- package/lib-commonjs/MenuItem/MenuItemTokens.js +5 -0
- package/lib-commonjs/MenuItem/MenuItemTokens.js.map +1 -1
- package/lib-commonjs/MenuItem/MenuItemTokens.macos.d.ts.map +1 -1
- package/lib-commonjs/MenuItem/MenuItemTokens.macos.js +5 -0
- package/lib-commonjs/MenuItem/MenuItemTokens.macos.js.map +1 -1
- package/lib-commonjs/MenuItem/MenuItemTokens.win32.d.ts.map +1 -1
- package/lib-commonjs/MenuItem/MenuItemTokens.win32.js +6 -0
- package/lib-commonjs/MenuItem/MenuItemTokens.win32.js.map +1 -1
- package/lib-commonjs/MenuItem/useMenuItem.d.ts.map +1 -1
- package/lib-commonjs/MenuItem/useMenuItem.js +2 -2
- package/lib-commonjs/MenuItem/useMenuItem.js.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckbox.d.ts.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckbox.js +8 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckbox.js.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckbox.styling.d.ts.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckbox.styling.js +13 -0
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckbox.styling.js.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckbox.types.d.ts +9 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckbox.types.d.ts.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckbox.types.js.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckboxTokens.d.ts.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckboxTokens.js +5 -0
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckboxTokens.js.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckboxTokens.macos.d.ts.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckboxTokens.macos.js +5 -0
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckboxTokens.macos.js.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckboxTokens.win32.d.ts.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckboxTokens.win32.js +6 -0
- package/lib-commonjs/MenuItemCheckbox/MenuItemCheckboxTokens.win32.js.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/useMenuItemCheckbox.d.ts.map +1 -1
- package/lib-commonjs/MenuItemCheckbox/useMenuItemCheckbox.js +2 -2
- package/lib-commonjs/MenuItemCheckbox/useMenuItemCheckbox.js.map +1 -1
- package/lib-commonjs/MenuList/MenuList.types.d.ts +4 -0
- package/lib-commonjs/MenuList/MenuList.types.d.ts.map +1 -1
- package/lib-commonjs/MenuList/useMenuListContextValue.js +1 -1
- package/lib-commonjs/MenuList/useMenuListContextValue.js.map +1 -1
- package/lib-commonjs/context/menuContext.d.ts.map +1 -1
- package/lib-commonjs/context/menuContext.js +1 -0
- package/lib-commonjs/context/menuContext.js.map +1 -1
- package/lib-commonjs/context/menuListContext.d.ts +1 -0
- package/lib-commonjs/context/menuListContext.d.ts.map +1 -1
- package/lib-commonjs/context/menuListContext.js +1 -0
- package/lib-commonjs/context/menuListContext.js.map +1 -1
- package/package.json +10 -9
- package/src/MenuItem/MenuItem.styling.ts +22 -0
- package/src/MenuItem/MenuItem.tsx +12 -2
- package/src/MenuItem/MenuItem.types.ts +14 -1
- package/src/MenuItem/MenuItemTokens.macos.ts +5 -0
- package/src/MenuItem/MenuItemTokens.ts +5 -0
- package/src/MenuItem/MenuItemTokens.win32.ts +6 -0
- package/src/MenuItem/useMenuItem.ts +2 -1
- package/src/MenuItemCheckbox/MenuItemCheckbox.styling.ts +22 -0
- package/src/MenuItemCheckbox/MenuItemCheckbox.tsx +12 -2
- package/src/MenuItemCheckbox/MenuItemCheckbox.types.ts +10 -2
- package/src/MenuItemCheckbox/MenuItemCheckboxTokens.macos.ts +5 -0
- package/src/MenuItemCheckbox/MenuItemCheckboxTokens.ts +5 -0
- package/src/MenuItemCheckbox/MenuItemCheckboxTokens.win32.ts +6 -0
- package/src/MenuItemCheckbox/useMenuItemCheckbox.ts +2 -1
- package/src/MenuList/MenuList.types.ts +5 -0
- package/src/MenuList/useMenuListContextValue.ts +1 -1
- package/src/context/menuContext.ts +1 -0
- package/src/context/menuListContext.ts +2 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/** @jsx withSlots */
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { I18nManager, Pressable, View } from 'react-native';
|
|
3
|
+
import { I18nManager, Image, Pressable, View } from 'react-native';
|
|
4
4
|
|
|
5
5
|
import type { UseSlots } from '@fluentui-react-native/framework';
|
|
6
6
|
import { compose, memoize, mergeProps, withSlots } from '@fluentui-react-native/framework';
|
|
7
|
+
import { IconV1 as Icon } from '@fluentui-react-native/icon';
|
|
7
8
|
import { TextV1 as Text } from '@fluentui-react-native/text';
|
|
8
9
|
import { SvgXml } from 'react-native-svg';
|
|
9
10
|
|
|
@@ -19,6 +20,9 @@ export const MenuItem = compose<MenuItemType>({
|
|
|
19
20
|
root: Pressable,
|
|
20
21
|
checkmark: View,
|
|
21
22
|
content: Text,
|
|
23
|
+
iconPlaceholder: View,
|
|
24
|
+
imgIcon: Image,
|
|
25
|
+
fontOrSvgIcon: Icon,
|
|
22
26
|
submenuIndicator: SvgXml,
|
|
23
27
|
},
|
|
24
28
|
useRender: (userProps: MenuItemProps, useSlots: UseSlots<MenuItemType>) => {
|
|
@@ -26,7 +30,7 @@ export const MenuItem = compose<MenuItemType>({
|
|
|
26
30
|
const Slots = useSlots(userProps, (layer): boolean => menuItem.state[layer] || userProps[layer]);
|
|
27
31
|
|
|
28
32
|
return (final: MenuItemProps, children: React.ReactNode) => {
|
|
29
|
-
const { accessibilityLabel, tooltip, ...mergedProps } = mergeProps(menuItem.props, final);
|
|
33
|
+
const { accessibilityLabel, icon, tooltip, ...mergedProps } = mergeProps(menuItem.props, final);
|
|
30
34
|
const chevronXml = I18nManager.isRTL
|
|
31
35
|
? `
|
|
32
36
|
<svg>
|
|
@@ -44,6 +48,12 @@ export const MenuItem = compose<MenuItemType>({
|
|
|
44
48
|
return (
|
|
45
49
|
<Slots.root {...mergedProps} accessibilityLabel={label}>
|
|
46
50
|
{menuItem.state.hasCheckmarks && <Slots.checkmark />}
|
|
51
|
+
{(icon || menuItem.state.hasIcons) && (
|
|
52
|
+
<Slots.iconPlaceholder>
|
|
53
|
+
{icon && icon.source && <Slots.imgIcon {...icon} />}
|
|
54
|
+
{icon && (icon.svgSource || icon.fontSource) && <Slots.fontOrSvgIcon {...icon} />}
|
|
55
|
+
</Slots.iconPlaceholder>
|
|
56
|
+
)}
|
|
47
57
|
{children && <Slots.content tooltip={tooltipResult}>{children}</Slots.content>}
|
|
48
58
|
{menuItem.state.hasSubmenu && <Slots.submenuIndicator xml={chevronXml} />}
|
|
49
59
|
</Slots.root>
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type * as React from 'react';
|
|
2
|
-
import type { ColorValue } from 'react-native';
|
|
2
|
+
import type { ColorValue, ImageProps } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import type { IViewProps } from '@fluentui-react-native/adapters';
|
|
5
|
+
import type { IconPropsV1 as IconProps } from '@fluentui-react-native/icon';
|
|
5
6
|
import type { IFocusable, InteractionEvent, PressablePropsExtended, PressableState } from '@fluentui-react-native/interactive-hooks';
|
|
6
7
|
import type { TextProps } from '@fluentui-react-native/text';
|
|
7
8
|
import type { FontTokens, IBorderTokens, IColorTokens, LayoutTokens } from '@fluentui-react-native/tokens';
|
|
@@ -20,6 +21,9 @@ export interface MenuItemTokens extends LayoutTokens, FontTokens, IBorderTokens,
|
|
|
20
21
|
*/
|
|
21
22
|
gap?: number;
|
|
22
23
|
|
|
24
|
+
iconColor?: ColorValue;
|
|
25
|
+
iconSize?: number;
|
|
26
|
+
|
|
23
27
|
/**
|
|
24
28
|
* Color of the indicator that shows that an item has a submenu
|
|
25
29
|
*/
|
|
@@ -50,6 +54,11 @@ export interface MenuItemProps extends Omit<PressablePropsExtended, 'onPress'> {
|
|
|
50
54
|
*/
|
|
51
55
|
componentRef?: React.RefObject<IFocusable>;
|
|
52
56
|
|
|
57
|
+
/*
|
|
58
|
+
* Source URL or name of the icon to show on the Button.
|
|
59
|
+
*/
|
|
60
|
+
icon?: IconProps | ImageProps;
|
|
61
|
+
|
|
53
62
|
/**
|
|
54
63
|
* A callback to call on button click event
|
|
55
64
|
*/
|
|
@@ -63,6 +72,7 @@ export interface MenuItemProps extends Omit<PressablePropsExtended, 'onPress'> {
|
|
|
63
72
|
|
|
64
73
|
export interface MenuItemState extends PressableState {
|
|
65
74
|
hasCheckmarks?: boolean;
|
|
75
|
+
hasIcons?: boolean;
|
|
66
76
|
|
|
67
77
|
/**
|
|
68
78
|
* If the menu item is a trigger for a submenu
|
|
@@ -84,6 +94,9 @@ export interface MenuItemSlotProps {
|
|
|
84
94
|
root: React.PropsWithRef<PressablePropsExtended>;
|
|
85
95
|
content?: TextProps;
|
|
86
96
|
checkmark?: React.PropsWithRef<IViewProps>;
|
|
97
|
+
iconPlaceholder?: React.PropsWithRef<IViewProps>;
|
|
98
|
+
imgIcon?: ImageProps;
|
|
99
|
+
fontOrSvgIcon?: IconProps;
|
|
87
100
|
submenuIndicator?: XmlProps;
|
|
88
101
|
}
|
|
89
102
|
|
|
@@ -13,6 +13,8 @@ export const defaultMenuItemTokens: TokenSettings<MenuItemTokens, Theme> = (t: T
|
|
|
13
13
|
fontSize: 13, // aligning with NSMenu font size
|
|
14
14
|
fontWeight: globalTokens.font.weight.regular as FontWeightValue,
|
|
15
15
|
gap: globalTokens.size40,
|
|
16
|
+
iconColor: t.colors.neutralForeground1,
|
|
17
|
+
iconSize: 16,
|
|
16
18
|
paddingHorizontal: 5, // hardcoded for now to match NSMenu
|
|
17
19
|
paddingVertical: 3, // hardcoded for now to match NSMenu
|
|
18
20
|
submenuIndicatorColor: t.colors.neutralForeground1,
|
|
@@ -21,13 +23,16 @@ export const defaultMenuItemTokens: TokenSettings<MenuItemTokens, Theme> = (t: T
|
|
|
21
23
|
focused: {
|
|
22
24
|
backgroundColor: t.colors.menuItemBackgroundHovered,
|
|
23
25
|
color: t.colors.menuItemTextHovered,
|
|
26
|
+
iconColor: t.colors.menuItemTextHovered,
|
|
24
27
|
},
|
|
25
28
|
pressed: {
|
|
26
29
|
backgroundColor: t.colors.menuItemBackgroundPressed,
|
|
27
30
|
color: t.colors.menuItemTextHovered,
|
|
31
|
+
iconColor: t.colors.menuItemTextHovered,
|
|
28
32
|
},
|
|
29
33
|
disabled: {
|
|
30
34
|
backgroundColor: t.colors.menuBackground,
|
|
31
35
|
color: t.colors.disabledText,
|
|
36
|
+
iconColor: t.colors.disabledText,
|
|
32
37
|
},
|
|
33
38
|
});
|
|
@@ -13,6 +13,8 @@ export const defaultMenuItemTokens: TokenSettings<MenuItemTokens, Theme> = (t: T
|
|
|
13
13
|
fontSize: globalTokens.font.size300,
|
|
14
14
|
fontWeight: globalTokens.font.weight.regular as FontWeightValue,
|
|
15
15
|
gap: globalTokens.size40,
|
|
16
|
+
iconColor: t.colors.neutralForeground2,
|
|
17
|
+
iconSize: 16,
|
|
16
18
|
minHeight: 32,
|
|
17
19
|
minWidth: 128,
|
|
18
20
|
maxWidth: 300,
|
|
@@ -23,16 +25,19 @@ export const defaultMenuItemTokens: TokenSettings<MenuItemTokens, Theme> = (t: T
|
|
|
23
25
|
hovered: {
|
|
24
26
|
backgroundColor: t.colors.neutralBackground1Hover,
|
|
25
27
|
color: t.colors.neutralForeground2Hover,
|
|
28
|
+
iconColor: t.colors.neutralForeground2Hover,
|
|
26
29
|
submenuIndicatorColor: t.colors.neutralForeground2Hover,
|
|
27
30
|
},
|
|
28
31
|
pressed: {
|
|
29
32
|
backgroundColor: t.colors.neutralBackground1Pressed,
|
|
30
33
|
color: t.colors.neutralForeground2Pressed,
|
|
34
|
+
iconColor: t.colors.neutralForeground2Pressed,
|
|
31
35
|
submenuIndicatorColor: t.colors.neutralForeground2Pressed,
|
|
32
36
|
},
|
|
33
37
|
disabled: {
|
|
34
38
|
backgroundColor: t.colors.neutralBackground1,
|
|
35
39
|
color: t.colors.neutralForegroundDisabled,
|
|
40
|
+
iconColor: t.colors.neutralForegroundDisabled,
|
|
36
41
|
submenuIndicatorColor: t.colors.neutralForegroundDisabled,
|
|
37
42
|
},
|
|
38
43
|
});
|
|
@@ -13,6 +13,8 @@ export const defaultMenuItemTokens: TokenSettings<MenuItemTokens, Theme> = (t: T
|
|
|
13
13
|
fontSize: globalTokens.font.size200,
|
|
14
14
|
fontWeight: globalTokens.font.weight.regular as FontWeightValue,
|
|
15
15
|
gap: globalTokens.size40,
|
|
16
|
+
iconColor: t.colors.neutralForeground1,
|
|
17
|
+
iconSize: 16,
|
|
16
18
|
minHeight: 24,
|
|
17
19
|
minWidth: 128,
|
|
18
20
|
maxWidth: 300,
|
|
@@ -24,21 +26,25 @@ export const defaultMenuItemTokens: TokenSettings<MenuItemTokens, Theme> = (t: T
|
|
|
24
26
|
hovered: {
|
|
25
27
|
backgroundColor: t.colors.neutralBackground1Hover,
|
|
26
28
|
color: t.colors.neutralForeground1Hover,
|
|
29
|
+
iconColor: t.colors.neutralForeground1Hover,
|
|
27
30
|
submenuIndicatorColor: t.colors.neutralForeground1Hover,
|
|
28
31
|
},
|
|
29
32
|
pressed: {
|
|
30
33
|
backgroundColor: t.colors.neutralBackground1Pressed,
|
|
31
34
|
color: t.colors.neutralForeground1Pressed,
|
|
35
|
+
iconColor: t.colors.neutralForeground1Pressed,
|
|
32
36
|
submenuIndicatorColor: t.colors.neutralForeground1Pressed,
|
|
33
37
|
},
|
|
34
38
|
disabled: {
|
|
35
39
|
backgroundColor: t.colors.neutralBackground1,
|
|
36
40
|
color: t.colors.neutralForegroundDisabled,
|
|
41
|
+
iconColor: t.colors.neutralForegroundDisabled,
|
|
37
42
|
submenuIndicatorColor: t.colors.neutralForegroundDisabled,
|
|
38
43
|
},
|
|
39
44
|
focused: {
|
|
40
45
|
backgroundColor: t.colors.neutralBackground1Hover,
|
|
41
46
|
color: t.colors.neutralForeground1Hover,
|
|
47
|
+
iconColor: t.colors.neutralForeground1Hover,
|
|
42
48
|
submenuIndicatorColor: t.colors.neutralForeground1Hover,
|
|
43
49
|
},
|
|
44
50
|
});
|
|
@@ -19,7 +19,7 @@ export const useMenuItem = (props: MenuItemProps): MenuItemInfo => {
|
|
|
19
19
|
const defaultComponentRef = React.useRef(null);
|
|
20
20
|
const { onClick, accessibilityState, componentRef = defaultComponentRef, disabled, persistOnClick, ...rest } = props;
|
|
21
21
|
const { isSubmenu, persistOnItemClick, setOpen } = useMenuContext();
|
|
22
|
-
const { hasCheckmarks, hasTooltips, onArrowClose } = useMenuListContext();
|
|
22
|
+
const { hasCheckmarks, hasIcons, hasTooltips, onArrowClose } = useMenuListContext();
|
|
23
23
|
const isTrigger = useMenuTriggerContext();
|
|
24
24
|
const shouldPersist = persistOnClick ?? persistOnItemClick;
|
|
25
25
|
|
|
@@ -84,6 +84,7 @@ export const useMenuItem = (props: MenuItemProps): MenuItemInfo => {
|
|
|
84
84
|
state: {
|
|
85
85
|
...pressable.state,
|
|
86
86
|
hasSubmenu,
|
|
87
|
+
hasIcons,
|
|
87
88
|
hasCheckmarks,
|
|
88
89
|
hasTooltips,
|
|
89
90
|
},
|
|
@@ -46,5 +46,27 @@ export const stylingSettings: UseStylingOptions<MenuItemCheckboxProps, MenuItemC
|
|
|
46
46
|
}),
|
|
47
47
|
['color', ...fontStyles.keys],
|
|
48
48
|
),
|
|
49
|
+
iconPlaceholder: buildProps(
|
|
50
|
+
(tokens: MenuItemCheckboxTokens) => ({
|
|
51
|
+
style: {
|
|
52
|
+
minHeight: tokens.iconSize,
|
|
53
|
+
minWidth: tokens.iconSize,
|
|
54
|
+
alignItems: 'center',
|
|
55
|
+
justifyContent: 'center',
|
|
56
|
+
marginEnd: tokens.gap,
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
['checkmarkSize', 'gap'],
|
|
60
|
+
),
|
|
61
|
+
imgIcon: buildProps(
|
|
62
|
+
(tokens: MenuItemCheckboxTokens) => ({
|
|
63
|
+
style: { tintColor: tokens.iconColor, height: tokens.iconSize, width: tokens.iconSize },
|
|
64
|
+
}),
|
|
65
|
+
['gap', 'iconColor', 'iconSize'],
|
|
66
|
+
),
|
|
67
|
+
fontOrSvgIcon: buildProps(
|
|
68
|
+
(tokens: MenuItemCheckboxTokens) => ({ color: tokens.iconColor, size: tokens.iconSize }),
|
|
69
|
+
['gap', 'iconColor', 'iconSize'],
|
|
70
|
+
),
|
|
49
71
|
},
|
|
50
72
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/** @jsx withSlots */
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { Pressable } from 'react-native';
|
|
3
|
+
import { Image, Pressable, View } from 'react-native';
|
|
4
4
|
|
|
5
5
|
import type { Slots, UseSlots } from '@fluentui-react-native/framework';
|
|
6
6
|
import { compose, mergeProps, withSlots } from '@fluentui-react-native/framework';
|
|
7
|
+
import { IconV1 as Icon } from '@fluentui-react-native/icon';
|
|
7
8
|
import { TextV1 as Text } from '@fluentui-react-native/text';
|
|
8
9
|
import { SvgXml } from 'react-native-svg';
|
|
9
10
|
|
|
@@ -25,6 +26,9 @@ export const MenuItemCheckbox = compose<MenuItemCheckboxType>({
|
|
|
25
26
|
root: Pressable,
|
|
26
27
|
checkmark: SvgXml,
|
|
27
28
|
content: Text,
|
|
29
|
+
iconPlaceholder: View,
|
|
30
|
+
imgIcon: Image,
|
|
31
|
+
fontOrSvgIcon: Icon,
|
|
28
32
|
},
|
|
29
33
|
useRender: (userProps: MenuItemCheckboxProps, useSlots: UseSlots<MenuItemCheckboxType>) => {
|
|
30
34
|
const menuItem = useMenuItemCheckbox(userProps);
|
|
@@ -39,7 +43,7 @@ export const menuItemFinalRender = (
|
|
|
39
43
|
Slots: Slots<MenuItemCheckboxSlotProps>,
|
|
40
44
|
): React.FunctionComponent<MenuItemCheckboxProps> => {
|
|
41
45
|
return (final: MenuItemCheckboxProps, children: React.ReactNode) => {
|
|
42
|
-
const { accessibilityLabel, tooltip, ...mergedProps } = mergeProps(menuItem.props, final);
|
|
46
|
+
const { accessibilityLabel, icon, tooltip, ...mergedProps } = mergeProps(menuItem.props, final);
|
|
43
47
|
const checkmarkXml = `
|
|
44
48
|
<svg>
|
|
45
49
|
<path fill='currentColor' d='M9.85355 3.14645C10.0488 3.34171 10.0488 3.65829 9.85355 3.85355L5.35355 8.35355C5.15829 8.54882 4.84171 8.54882 4.64645 8.35355L2.64645 6.35355C2.45118 6.15829 2.45118 5.84171 2.64645 5.64645C2.84171 5.45118 3.15829 5.45118 3.35355 5.64645L5 7.29289L9.14645 3.14645C9.34171 2.95118 9.65829 2.95118 9.85355 3.14645Z' />
|
|
@@ -51,6 +55,12 @@ export const menuItemFinalRender = (
|
|
|
51
55
|
return (
|
|
52
56
|
<Slots.root {...mergedProps} accessibilityLabel={label}>
|
|
53
57
|
<Slots.checkmark xml={checkmarkXml} />
|
|
58
|
+
{(icon || menuItem.state.hasIcons) && (
|
|
59
|
+
<Slots.iconPlaceholder>
|
|
60
|
+
{icon && icon.source && <Slots.imgIcon {...icon} />}
|
|
61
|
+
{icon && (icon.svgSource || icon.fontSource) && <Slots.fontOrSvgIcon {...icon} />}
|
|
62
|
+
</Slots.iconPlaceholder>
|
|
63
|
+
)}
|
|
54
64
|
{children && <Slots.content tooltip={tooltipResult}>{children}</Slots.content>}
|
|
55
65
|
</Slots.root>
|
|
56
66
|
);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type * as React from 'react';
|
|
2
|
-
import type { ColorValue } from 'react-native';
|
|
2
|
+
import type { ColorValue, ImageProps } from 'react-native';
|
|
3
3
|
|
|
4
|
+
import type { IViewProps } from '@fluentui-react-native/adapters';
|
|
5
|
+
import type { IconPropsV1 as IconProps } from '@fluentui-react-native/icon';
|
|
4
6
|
import type { PressablePropsExtended, PressableState } from '@fluentui-react-native/interactive-hooks';
|
|
5
7
|
import type { TextProps } from '@fluentui-react-native/text';
|
|
6
8
|
import type { XmlProps } from 'react-native-svg';
|
|
@@ -26,6 +28,9 @@ export interface MenuItemCheckboxTokens
|
|
|
26
28
|
*/
|
|
27
29
|
checkmarkVisibility?: number;
|
|
28
30
|
|
|
31
|
+
iconColor?: ColorValue;
|
|
32
|
+
iconSize?: number;
|
|
33
|
+
|
|
29
34
|
/**
|
|
30
35
|
* States of the item control
|
|
31
36
|
*/
|
|
@@ -44,13 +49,16 @@ export interface MenuItemCheckboxProps extends MenuItemProps {
|
|
|
44
49
|
}
|
|
45
50
|
export interface MenuItemCheckboxInfo {
|
|
46
51
|
props: MenuItemCheckboxProps & React.ComponentPropsWithRef<any>;
|
|
47
|
-
state: PressableState & { hasTooltips: boolean };
|
|
52
|
+
state: PressableState & { hasIcons: boolean; hasTooltips: boolean };
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
export interface MenuItemCheckboxSlotProps {
|
|
51
56
|
root: React.PropsWithRef<PressablePropsExtended>;
|
|
52
57
|
checkmark?: XmlProps;
|
|
53
58
|
content?: TextProps;
|
|
59
|
+
iconPlaceholder?: React.PropsWithRef<IViewProps>;
|
|
60
|
+
imgIcon?: ImageProps;
|
|
61
|
+
fontOrSvgIcon?: IconProps;
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
export interface MenuItemCheckboxType {
|
|
@@ -15,11 +15,14 @@ export const defaultMenuItemCheckboxTokens: TokenSettings<MenuItemCheckboxTokens
|
|
|
15
15
|
fontSize: globalTokens.font.size300,
|
|
16
16
|
fontWeight: globalTokens.font.weight.regular as FontWeightValue,
|
|
17
17
|
gap: globalTokens.size40,
|
|
18
|
+
iconColor: t.colors.neutralForeground2,
|
|
19
|
+
iconSize: 16,
|
|
18
20
|
paddingHorizontal: 5,
|
|
19
21
|
paddingVertical: 3,
|
|
20
22
|
focused: {
|
|
21
23
|
backgroundColor: t.colors.brandBackground,
|
|
22
24
|
color: t.colors.brandedContent,
|
|
25
|
+
iconColor: t.colors.brandedContent,
|
|
23
26
|
checked: {
|
|
24
27
|
checkmarkColor: t.colors.neutralForeground2Hover,
|
|
25
28
|
checkmarkVisibility: 1,
|
|
@@ -28,6 +31,7 @@ export const defaultMenuItemCheckboxTokens: TokenSettings<MenuItemCheckboxTokens
|
|
|
28
31
|
pressed: {
|
|
29
32
|
backgroundColor: t.colors.brandBackgroundPressed,
|
|
30
33
|
color: t.colors.brandedPressedContent,
|
|
34
|
+
iconColor: t.colors.brandedPressedContent,
|
|
31
35
|
checked: {
|
|
32
36
|
checkmarkColor: t.colors.brandedPressedContent,
|
|
33
37
|
checkmarkVisibility: 1,
|
|
@@ -36,6 +40,7 @@ export const defaultMenuItemCheckboxTokens: TokenSettings<MenuItemCheckboxTokens
|
|
|
36
40
|
disabled: {
|
|
37
41
|
backgroundColor: t.colors.transparentBackground,
|
|
38
42
|
color: t.colors.brandForeground1Disabled,
|
|
43
|
+
iconColor: t.colors.brandForeground1Disabled,
|
|
39
44
|
checked: {
|
|
40
45
|
checkmarkColor: t.colors.brandForeground1Disabled,
|
|
41
46
|
checkmarkVisibility: 1,
|
|
@@ -15,6 +15,8 @@ export const defaultMenuItemCheckboxTokens: TokenSettings<MenuItemCheckboxTokens
|
|
|
15
15
|
fontSize: globalTokens.font.size300,
|
|
16
16
|
fontWeight: globalTokens.font.weight.regular as FontWeightValue,
|
|
17
17
|
gap: globalTokens.size40,
|
|
18
|
+
iconColor: t.colors.neutralForeground2,
|
|
19
|
+
iconSize: 16,
|
|
18
20
|
minHeight: 32,
|
|
19
21
|
minWidth: 160,
|
|
20
22
|
maxWidth: 300,
|
|
@@ -22,6 +24,7 @@ export const defaultMenuItemCheckboxTokens: TokenSettings<MenuItemCheckboxTokens
|
|
|
22
24
|
hovered: {
|
|
23
25
|
backgroundColor: t.colors.neutralBackground1Hover,
|
|
24
26
|
color: t.colors.neutralForeground2Hover,
|
|
27
|
+
iconColor: t.colors.neutralForeground2Hover,
|
|
25
28
|
checked: {
|
|
26
29
|
checkmarkColor: t.colors.neutralForeground2Hover,
|
|
27
30
|
checkmarkVisibility: 1,
|
|
@@ -30,6 +33,7 @@ export const defaultMenuItemCheckboxTokens: TokenSettings<MenuItemCheckboxTokens
|
|
|
30
33
|
pressed: {
|
|
31
34
|
backgroundColor: t.colors.neutralBackground1Pressed,
|
|
32
35
|
color: t.colors.neutralForeground2Pressed,
|
|
36
|
+
iconColor: t.colors.neutralForeground2Pressed,
|
|
33
37
|
checked: {
|
|
34
38
|
checkmarkColor: t.colors.neutralForeground2Pressed,
|
|
35
39
|
checkmarkVisibility: 1,
|
|
@@ -38,6 +42,7 @@ export const defaultMenuItemCheckboxTokens: TokenSettings<MenuItemCheckboxTokens
|
|
|
38
42
|
disabled: {
|
|
39
43
|
backgroundColor: t.colors.neutralBackground1,
|
|
40
44
|
color: t.colors.neutralForegroundDisabled,
|
|
45
|
+
iconColor: t.colors.neutralForegroundDisabled,
|
|
41
46
|
checked: {
|
|
42
47
|
checkmarkColor: t.colors.neutralForegroundDisabled,
|
|
43
48
|
checkmarkVisibility: 1,
|
|
@@ -15,6 +15,8 @@ export const defaultMenuItemCheckboxTokens: TokenSettings<MenuItemCheckboxTokens
|
|
|
15
15
|
fontSize: globalTokens.font.size200,
|
|
16
16
|
fontWeight: globalTokens.font.weight.regular as FontWeightValue,
|
|
17
17
|
gap: globalTokens.size40,
|
|
18
|
+
iconColor: t.colors.neutralForeground1,
|
|
19
|
+
iconSize: 16,
|
|
18
20
|
minHeight: 24,
|
|
19
21
|
minWidth: 160,
|
|
20
22
|
maxWidth: 300,
|
|
@@ -23,6 +25,7 @@ export const defaultMenuItemCheckboxTokens: TokenSettings<MenuItemCheckboxTokens
|
|
|
23
25
|
hovered: {
|
|
24
26
|
backgroundColor: t.colors.neutralBackground1Hover,
|
|
25
27
|
color: t.colors.neutralForeground1Hover,
|
|
28
|
+
iconColor: t.colors.neutralForeground1Hover,
|
|
26
29
|
checked: {
|
|
27
30
|
checkmarkColor: t.colors.neutralForeground1Hover,
|
|
28
31
|
checkmarkVisibility: 1,
|
|
@@ -31,6 +34,7 @@ export const defaultMenuItemCheckboxTokens: TokenSettings<MenuItemCheckboxTokens
|
|
|
31
34
|
pressed: {
|
|
32
35
|
backgroundColor: t.colors.neutralBackground1Pressed,
|
|
33
36
|
color: t.colors.neutralForeground1Pressed,
|
|
37
|
+
iconColor: t.colors.neutralForeground1Pressed,
|
|
34
38
|
checked: {
|
|
35
39
|
checkmarkColor: t.colors.neutralForeground1Pressed,
|
|
36
40
|
checkmarkVisibility: 1,
|
|
@@ -39,6 +43,7 @@ export const defaultMenuItemCheckboxTokens: TokenSettings<MenuItemCheckboxTokens
|
|
|
39
43
|
disabled: {
|
|
40
44
|
backgroundColor: t.colors.neutralBackground1,
|
|
41
45
|
color: t.colors.neutralForegroundDisabled,
|
|
46
|
+
iconColor: t.colors.neutralForegroundDisabled,
|
|
42
47
|
checked: {
|
|
43
48
|
checkmarkColor: t.colors.neutralForegroundDisabled,
|
|
44
49
|
checkmarkVisibility: 1,
|
|
@@ -47,6 +52,7 @@ export const defaultMenuItemCheckboxTokens: TokenSettings<MenuItemCheckboxTokens
|
|
|
47
52
|
focused: {
|
|
48
53
|
backgroundColor: t.colors.neutralBackground1Hover,
|
|
49
54
|
color: t.colors.neutralForeground1Hover,
|
|
55
|
+
iconColor: t.colors.neutralForeground1Hover,
|
|
50
56
|
checked: {
|
|
51
57
|
checkmarkColor: t.colors.neutralForeground1Hover,
|
|
52
58
|
checkmarkVisibility: 1,
|
|
@@ -65,7 +65,7 @@ export const useMenuCheckboxInteraction = (
|
|
|
65
65
|
|
|
66
66
|
const isSubmenu = useMenuContext().isSubmenu;
|
|
67
67
|
|
|
68
|
-
const { checked, hasTooltips, onArrowClose } = useMenuListContext();
|
|
68
|
+
const { checked, hasIcons, hasTooltips, onArrowClose } = useMenuListContext();
|
|
69
69
|
const isChecked = checked?.[name];
|
|
70
70
|
|
|
71
71
|
// Ensure focus is placed on checkbox after click
|
|
@@ -116,6 +116,7 @@ export const useMenuCheckboxInteraction = (
|
|
|
116
116
|
...pressable.state,
|
|
117
117
|
checked: isChecked,
|
|
118
118
|
disabled,
|
|
119
|
+
hasIcons,
|
|
119
120
|
hasTooltips,
|
|
120
121
|
};
|
|
121
122
|
|
|
@@ -32,6 +32,11 @@ export interface MenuListProps extends Omit<IViewProps, 'onPress'> {
|
|
|
32
32
|
*/
|
|
33
33
|
hasCheckmarks?: boolean;
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* States that menu items can contain icons and reserves space for item alignment
|
|
37
|
+
*/
|
|
38
|
+
hasIcons?: boolean;
|
|
39
|
+
|
|
35
40
|
/**
|
|
36
41
|
* States that menu items all have tooltips with its text by default.
|
|
37
42
|
*
|
|
@@ -2,5 +2,5 @@ import type { MenuListState } from './MenuList.types';
|
|
|
2
2
|
import type { MenuListContextValue } from '../context/menuListContext';
|
|
3
3
|
|
|
4
4
|
export const useMenuListContextValue = (state: MenuListState): MenuListContextValue => {
|
|
5
|
-
return { hasCheckmarks: state.props.hasCheckmarks, hasTooltips: state.props.hasTooltips, ...state };
|
|
5
|
+
return { hasCheckmarks: state.props.hasCheckmarks, hasIcons: state.props.hasIcons, hasTooltips: state.props.hasTooltips, ...state };
|
|
6
6
|
};
|
|
@@ -7,6 +7,7 @@ import type { MenuListState } from '../MenuList/MenuList.types';
|
|
|
7
7
|
*/
|
|
8
8
|
export type MenuListContextValue = Omit<MenuListState, 'props'> & {
|
|
9
9
|
hasCheckmarks: boolean;
|
|
10
|
+
hasIcons: boolean;
|
|
10
11
|
hasTooltips: boolean;
|
|
11
12
|
};
|
|
12
13
|
|
|
@@ -14,6 +15,7 @@ export const MenuListContext = React.createContext<MenuListContextValue>({
|
|
|
14
15
|
isCheckedControlled: false,
|
|
15
16
|
checked: {},
|
|
16
17
|
hasCheckmarks: false,
|
|
18
|
+
hasIcons: false,
|
|
17
19
|
hasTooltips: false,
|
|
18
20
|
onCheckedChange: () => false,
|
|
19
21
|
onArrowClose: () => false,
|