Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[material-ui][SpeedDial] Fix SpeedDial tooltip placement #41997

Open
wants to merge 9 commits into
base: next
Choose a base branch
from
30 changes: 0 additions & 30 deletions docs/pages/material-ui/api/speed-dial-action.json
Expand Up @@ -41,36 +41,6 @@
"className": "MuiSpeedDialAction-fabClosed",
"description": "Styles applied to the Fab component if `open={false}`.",
"isGlobal": false
},
{
"key": "staticTooltip",
"className": "MuiSpeedDialAction-staticTooltip",
"description": "Styles applied to the root element if `tooltipOpen={true}`.",
"isGlobal": false
},
{
"key": "staticTooltipClosed",
"className": "MuiSpeedDialAction-staticTooltipClosed",
"description": "Styles applied to the root element if `tooltipOpen={true}` and `open={false}`.",
"isGlobal": false
},
{
"key": "staticTooltipLabel",
"className": "MuiSpeedDialAction-staticTooltipLabel",
"description": "Styles applied to the static tooltip label if `tooltipOpen={true}`.",
"isGlobal": false
},
{
"key": "tooltipPlacementLeft",
"className": "MuiSpeedDialAction-tooltipPlacementLeft",
"description": "Styles applied to the root element if `tooltipOpen={true}` and `tooltipPlacement=\"left\"``",
"isGlobal": false
},
{
"key": "tooltipPlacementRight",
"className": "MuiSpeedDialAction-tooltipPlacementRight",
"description": "Styles applied to the root element if `tooltipOpen={true}` and `tooltipPlacement=\"right\"``",
"isGlobal": false
}
],
"spread": true,
Expand Down
Expand Up @@ -29,27 +29,6 @@
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the Fab component",
"conditions": "<code>open={false}</code>"
},
"staticTooltip": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the root element",
"conditions": "<code>tooltipOpen={true}</code>"
},
"staticTooltipClosed": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the root element",
"conditions": "<code>tooltipOpen={true}</code> and <code>open={false}</code>"
},
"staticTooltipLabel": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the static tooltip label",
"conditions": "<code>tooltipOpen={true}</code>"
},
"tooltipPlacementLeft": {
"description": "Styles applied to the root element if <code>tooltipOpen={true}</code> and `tooltipPlacement=&quot;left&quot;``"
},
"tooltipPlacementRight": {
"description": "Styles applied to the root element if <code>tooltipOpen={true}</code> and `tooltipPlacement=&quot;right&quot;``"
}
}
}
133 changes: 29 additions & 104 deletions packages/mui-material/src/SpeedDialAction/SpeedDialAction.js
Expand Up @@ -8,22 +8,15 @@ import { emphasize } from '@mui/system/colorManipulator';
import { styled, createUseThemeProps } from '../zero-styled';
import Fab from '../Fab';
import Tooltip from '../Tooltip';
import capitalize from '../utils/capitalize';
import speedDialActionClasses, { getSpeedDialActionUtilityClass } from './speedDialActionClasses';
import { getSpeedDialActionUtilityClass } from './speedDialActionClasses';

const useThemeProps = createUseThemeProps('MuiSpeedDialAction');

const useUtilityClasses = (ownerState) => {
const { open, tooltipPlacement, classes } = ownerState;
const { open, classes } = ownerState;

const slots = {
fab: ['fab', !open && 'fabClosed'],
staticTooltip: [
'staticTooltip',
`tooltipPlacement${capitalize(tooltipPlacement)}`,
!open && 'staticTooltipClosed',
],
staticTooltipLabel: ['staticTooltipLabel'],
};

return composeClasses(slots, getSpeedDialActionUtilityClass, classes);
Expand Down Expand Up @@ -59,83 +52,16 @@ const SpeedDialActionFab = styled(Fab, {
transform: 'scale(0)',
},
},
],
}));

const SpeedDialActionStaticTooltip = styled('span', {
name: 'MuiSpeedDialAction',
slot: 'StaticTooltip',
overridesResolver: (props, styles) => {
const { ownerState } = props;

return [
styles.staticTooltip,
!ownerState.open && styles.staticTooltipClosed,
styles[`tooltipPlacement${capitalize(ownerState.tooltipPlacement)}`],
];
},
})(({ theme }) => ({
position: 'relative',
display: 'flex',
alignItems: 'center',
[`& .${speedDialActionClasses.staticTooltipLabel}`]: {
transition: theme.transitions.create(['transform', 'opacity'], {
duration: theme.transitions.duration.shorter,
}),
opacity: 1,
},
variants: [
{
props: ({ ownerState }) => !ownerState.open,
style: {
[`& .${speedDialActionClasses.staticTooltipLabel}`]: {
opacity: 0,
transform: 'scale(0.5)',
},
},
},
{
props: {
tooltipPlacement: 'left',
},
style: {
[`& .${speedDialActionClasses.staticTooltipLabel}`]: {
transformOrigin: '100% 50%',
right: '100%',
marginRight: 8,
},
},
},
{
props: {
tooltipPlacement: 'right',
},
props: ({ ownerState }) => !ownerState.open && ownerState.tooltipOpen,
style: {
[`& .${speedDialActionClasses.staticTooltipLabel}`]: {
transformOrigin: '0% 50%',
left: '100%',
marginLeft: 8,
},
opacity: 0,
transform: 'scale(1)',
},
},
],
}));

const SpeedDialActionStaticTooltipLabel = styled('span', {
name: 'MuiSpeedDialAction',
slot: 'StaticTooltipLabel',
overridesResolver: (props, styles) => styles.staticTooltipLabel,
})(({ theme }) => ({
position: 'absolute',
...theme.typography.body1,
backgroundColor: (theme.vars || theme).palette.background.paper,
borderRadius: (theme.vars || theme).shape.borderRadius,
boxShadow: (theme.vars || theme).shadows[1],
color: (theme.vars || theme).palette.text.secondary,
padding: '4px 16px',
wordBreak: 'keep-all',
}));

const SpeedDialAction = React.forwardRef(function SpeedDialAction(inProps, ref) {
const props = useThemeProps({ props: inProps, name: 'MuiSpeedDialAction' });
const {
Expand Down Expand Up @@ -184,34 +110,32 @@ const SpeedDialAction = React.forwardRef(function SpeedDialAction(inProps, ref)
</SpeedDialActionFab>
);

if (tooltipOpenProp) {
return (
<SpeedDialActionStaticTooltip
id={id}
ref={ref}
className={classes.staticTooltip}
ownerState={ownerState}
{...other}
>
<SpeedDialActionStaticTooltipLabel
style={transitionStyle}
id={`${id}-label`}
className={classes.staticTooltipLabel}
ownerState={ownerState}
>
{tooltipTitle}
</SpeedDialActionStaticTooltipLabel>
{React.cloneElement(fab, {
'aria-labelledby': `${id}-label`,
})}
</SpeedDialActionStaticTooltip>
);
}

if (!open && tooltipOpen) {
setTooltipOpen(false);
}

function round(value) {
return Math.round(value * 1e5) / 1e5;
}

const tooltipStyle = tooltipOpenProp
? {
sx: (theme) => {
return {
...theme.typography.body1,
...classes.staticTooltipLabel,
backgroundColor: (theme.vars || theme).palette.background.paper,
boxShadow: (theme.vars || theme).shadows[1],
color: (theme.vars || theme).palette.text.secondary,
padding: '4px 16px',
wordBreak: 'keep-all',
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
letterSpacing: `${round(0.15 / 16)}em`,
};
},
}
: null;

return (
<Tooltip
id={id}
Expand All @@ -220,8 +144,9 @@ const SpeedDialAction = React.forwardRef(function SpeedDialAction(inProps, ref)
placement={tooltipPlacement}
onClose={handleTooltipClose}
onOpen={handleTooltipOpen}
open={open && tooltipOpen}
open={open && (tooltipOpen || tooltipOpenProp)}
classes={TooltipClasses}
slotProps={{ tooltip: tooltipStyle }}
{...other}
>
{fab}
Expand Down
Expand Up @@ -6,16 +6,6 @@ export interface SpeedDialActionClasses {
fab: string;
/** Styles applied to the Fab component if `open={false}`. */
fabClosed: string;
/** Styles applied to the root element if `tooltipOpen={true}`. */
staticTooltip: string;
/** Styles applied to the root element if `tooltipOpen={true}` and `open={false}`. */
staticTooltipClosed: string;
/** Styles applied to the static tooltip label if `tooltipOpen={true}`. */
staticTooltipLabel: string;
/** Styles applied to the root element if `tooltipOpen={true}` and `tooltipPlacement="left"`` */
tooltipPlacementLeft: string;
/** Styles applied to the root element if `tooltipOpen={true}` and `tooltipPlacement="right"`` */
tooltipPlacementRight: string;
}

export type SpeedDialActionClassKey = keyof SpeedDialActionClasses;
Expand All @@ -26,15 +16,7 @@ export function getSpeedDialActionUtilityClass(slot: string): string {

const speedDialActionClasses: SpeedDialActionClasses = generateUtilityClasses(
'MuiSpeedDialAction',
[
'fab',
'fabClosed',
'staticTooltip',
'staticTooltipClosed',
'staticTooltipLabel',
'tooltipPlacementLeft',
'tooltipPlacementRight',
],
['fab', 'fabClosed'],
);

export default speedDialActionClasses;