Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "fix: Adding expanded styles for MenuButtons and making various other styling fixes for Button components.",
"packageName": "@fluentui/react-button",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { mergeClasses, makeStyles } from '@griffel/react';
import { iconFilledClassName, iconRegularClassName } from '@fluentui/react-icons';
import { tokens } from '@fluentui/react-theme';
import { useButtonStyles_unstable } from '../Button/useButtonStyles';
import type { SlotClassNames } from '@fluentui/react-utilities';
import { mergeClasses, makeStyles, shorthands } from '@griffel/react';
import { useButtonStyles_unstable } from '../Button/useButtonStyles';
import type { MenuButtonSlots, MenuButtonState } from './MenuButton.types';

export const menuButtonClassNames: SlotClassNames<MenuButtonSlots> = {
Expand All @@ -10,6 +11,59 @@ export const menuButtonClassNames: SlotClassNames<MenuButtonSlots> = {
menuIcon: 'fui-MenuButton__menuIcon',
};

const useRootExpandedStyles = makeStyles({
base: {
[`& .${iconFilledClassName}`]: {
display: 'inline',
},
[`& .${iconRegularClassName}`]: {
display: 'none',
},
},

// Appearance variations
outline: {
...shorthands.borderColor(tokens.colorNeutralStroke1Selected),
...shorthands.borderWidth(tokens.strokeWidthThicker),
color: tokens.colorNeutralForeground1Selected,
},
primary: {
backgroundColor: tokens.colorBrandBackgroundSelected,
},
secondary: {
backgroundColor: tokens.colorNeutralBackground1Selected,
...shorthands.borderColor(tokens.colorNeutralStroke1Selected),
color: tokens.colorNeutralForeground1Selected,
},
subtle: {
backgroundColor: tokens.colorSubtleBackgroundSelected,
color: tokens.colorNeutralForeground2Selected,
},
transparent: {
backgroundColor: tokens.colorTransparentBackgroundSelected,
color: tokens.colorNeutralForeground2BrandSelected,
},
});

const useIconExpandedStyles = makeStyles({
// Appearance variations
outline: {
color: tokens.colorNeutralForeground1Selected,
},
primary: {
/* The primary styles are exactly the same as the base styles. */
},
secondary: {
color: tokens.colorNeutralForeground1Selected,
},
subtle: {
color: tokens.colorNeutralForeground2BrandSelected,
},
transparent: {
color: tokens.colorNeutralForeground2BrandSelected,
},
});

const useMenuIconStyles = makeStyles({
base: {
lineHeight: 0,
Expand Down Expand Up @@ -42,12 +96,23 @@ const useMenuIconStyles = makeStyles({
});

export const useMenuButtonStyles_unstable = (state: MenuButtonState): MenuButtonState => {
const rootExpandedStyles = useRootExpandedStyles();
const iconExpandedStyles = useIconExpandedStyles();
const menuIconStyles = useMenuIconStyles();

state.root.className = mergeClasses(menuButtonClassNames.root, state.root.className);
state.root.className = mergeClasses(
menuButtonClassNames.root,
state.root['aria-expanded'] && rootExpandedStyles.base,
state.root['aria-expanded'] && rootExpandedStyles[state.appearance],
state.root.className,
);

if (state.icon) {
state.icon.className = mergeClasses(menuButtonClassNames.icon, state.icon.className);
state.icon.className = mergeClasses(
menuButtonClassNames.icon,
state.root['aria-expanded'] && iconExpandedStyles[state.appearance],
state.icon.className,
);
}

if (state.menuIcon) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const toggleButtonClassNames: SlotClassNames<ButtonSlots> = {
icon: 'fui-ToggleButton__icon',
};

const useCheckedStyles = makeStyles({
const useRootCheckedStyles = makeStyles({
// Base styles
base: {
backgroundColor: tokens.colorNeutralBackground1Selected,
Expand Down Expand Up @@ -74,6 +74,7 @@ const useCheckedStyles = makeStyles({
// Appearance variations
outline: {
backgroundColor: tokens.colorTransparentBackgroundSelected,
...shorthands.borderColor(tokens.colorNeutralStroke1),
...shorthands.borderWidth(tokens.strokeWidthThicker),

':hover': {
Expand Down Expand Up @@ -144,7 +145,7 @@ const useCheckedStyles = makeStyles({
},
});

const useDisabledStyles = makeStyles({
const useRootDisabledStyles = makeStyles({
// Base styles
base: {
backgroundColor: tokens.colorNeutralBackgroundDisabled,
Expand Down Expand Up @@ -214,29 +215,29 @@ const useDisabledStyles = makeStyles({

const useIconCheckedStyles = makeStyles({
// Appearance variations
subtle: {
subtleOrTransparent: {
color: tokens.colorNeutralForeground2BrandSelected,
},
});

export const useToggleButtonStyles_unstable = (state: ToggleButtonState): ToggleButtonState => {
const checkedStyles = useCheckedStyles();
const disabledStyles = useDisabledStyles();
const iconStyles = useIconCheckedStyles();
const rootCheckedStyles = useRootCheckedStyles();
const rootDisabledStyles = useRootDisabledStyles();
const iconCheckedStyles = useIconCheckedStyles();

const { appearance, checked, disabled, disabledFocusable } = state;

state.root.className = mergeClasses(
toggleButtonClassNames.root,

// Checked styles
checked && checkedStyles.base,
checked && checkedStyles.highContrast,
appearance && checked && checkedStyles[appearance],
checked && rootCheckedStyles.base,
checked && rootCheckedStyles.highContrast,
appearance && checked && rootCheckedStyles[appearance],

// Disabled styles
(disabled || disabledFocusable) && disabledStyles.base,
appearance && (disabled || disabledFocusable) && disabledStyles[appearance],
(disabled || disabledFocusable) && rootDisabledStyles.base,
appearance && (disabled || disabledFocusable) && rootDisabledStyles[appearance],

// User provided class name
state.root.className,
Expand All @@ -245,7 +246,7 @@ export const useToggleButtonStyles_unstable = (state: ToggleButtonState): Toggle
if (state.icon) {
state.icon.className = mergeClasses(
toggleButtonClassNames.icon,
appearance === 'subtle' && checked && iconStyles.subtle,
(appearance === 'subtle' || appearance === 'transparent') && iconCheckedStyles.subtleOrTransparent,
state.icon.className,
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import * as React from 'react';
import { makeStyles, Menu, MenuButton, MenuItem, MenuList, MenuPopover, MenuTrigger } from '@fluentui/react-components';
import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons';

const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);

const useStyles = makeStyles({
wrapper: {
Expand All @@ -15,7 +18,7 @@ export const Appearance = () => {
<div className={styles.wrapper}>
<Menu>
<MenuTrigger disableButtonEnhancement>
<MenuButton>Default</MenuButton>
<MenuButton icon={<CalendarMonthRegular />}>Default</MenuButton>
</MenuTrigger>

<MenuPopover>
Expand All @@ -28,7 +31,9 @@ export const Appearance = () => {

<Menu>
<MenuTrigger disableButtonEnhancement>
<MenuButton appearance="primary">Primary</MenuButton>
<MenuButton appearance="primary" icon={<CalendarMonthRegular />}>
Primary
</MenuButton>
</MenuTrigger>

<MenuPopover>
Expand All @@ -41,7 +46,9 @@ export const Appearance = () => {

<Menu>
<MenuTrigger disableButtonEnhancement>
<MenuButton appearance="outline">Outline</MenuButton>
<MenuButton appearance="outline" icon={<CalendarMonth />}>
Outline
</MenuButton>
</MenuTrigger>

<MenuPopover>
Expand All @@ -54,7 +61,9 @@ export const Appearance = () => {

<Menu>
<MenuTrigger disableButtonEnhancement>
<MenuButton appearance="subtle">Subtle</MenuButton>
<MenuButton appearance="subtle" icon={<CalendarMonth />}>
Subtle
</MenuButton>
</MenuTrigger>

<MenuPopover>
Expand All @@ -67,7 +76,9 @@ export const Appearance = () => {

<Menu>
<MenuTrigger disableButtonEnhancement>
<MenuButton appearance="transparent">Transparent</MenuButton>
<MenuButton appearance="transparent" icon={<CalendarMonth />}>
Transparent
</MenuButton>
</MenuTrigger>

<MenuPopover>
Expand Down