Skip to content

Commit d561bce

Browse files
seanchambombrookes
authored andcommitted
[SpeedDialAction] Allow a tooltip placement prop (#12244)
* Allow a tooltip placement prop on SpeedDialAction * Allows the actions of speed dial to be placed in any direction
1 parent b10615b commit d561bce

File tree

7 files changed

+72
-5
lines changed

7 files changed

+72
-5
lines changed

packages/material-ui-lab/src/SpeedDial/SpeedDial.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export interface SpeedDialProps
1111
> {
1212
ariaLabel: string;
1313
ButtonProps?: Partial<ButtonProps>;
14+
direction?: 'up' | 'down' | 'left' | 'right';
1415
hidden?: boolean;
1516
icon: React.ReactNode;
1617
onClose?: React.ReactEventHandler<{}>;

packages/material-ui-lab/src/SpeedDial/SpeedDial.js

+35-4
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,31 @@ export const styles = {
1515
root: {
1616
zIndex: 1050,
1717
display: 'flex',
18-
flexDirection: 'column-reverse', // Place the Actions above the FAB.
1918
pointerEvents: 'none',
2019
},
2120
/* Styles applied to the Button component. */
2221
fab: {
2322
pointerEvents: 'auto',
2423
},
24+
/* Styles applied to the root and action container elements when direction="up" */
25+
directionUp: {
26+
flexDirection: 'column-reverse',
27+
},
28+
/* Styles applied to the root and action container elements when direction="down" */
29+
directionDown: {
30+
flexDirection: 'column',
31+
},
32+
/* Styles applied to the root and action container elements when direction="left" */
33+
directionLeft: {
34+
flexDirection: 'row-reverse',
35+
},
36+
/* Styles applied to the root and action container elements when direction="right" */
37+
directionRight: {
38+
flexDirection: 'row',
39+
},
2540
/* Styles applied to the actions (`children` wrapper) element. */
2641
actions: {
2742
display: 'flex',
28-
flexDirection: 'column-reverse', // Display the first action at the bottom.
2943
paddingBottom: 16,
3044
pointerEvents: 'auto',
3145
},
@@ -109,6 +123,7 @@ class SpeedDial extends React.Component {
109123
onClose,
110124
onKeyDown,
111125
open,
126+
direction,
112127
openIcon,
113128
TransitionComponent,
114129
transitionDuration,
@@ -158,8 +173,15 @@ class SpeedDial extends React.Component {
158173
return icon;
159174
};
160175

176+
const actionsPlacementClass = {
177+
[classes.directionUp]: direction === 'up',
178+
[classes.directionDown]: direction === 'down',
179+
[classes.directionLeft]: direction === 'left',
180+
[classes.directionRight]: direction === 'right',
181+
};
182+
161183
return (
162-
<div className={classNames(classes.root, classNameProp)} {...other}>
184+
<div className={classNames(classes.root, actionsPlacementClass, classNameProp)} {...other}>
163185
<TransitionComponent
164186
in={!hidden}
165187
timeout={transitionDuration}
@@ -186,7 +208,11 @@ class SpeedDial extends React.Component {
186208
</TransitionComponent>
187209
<div
188210
id={`${id}-actions`}
189-
className={classNames(classes.actions, { [classes.actionsClosed]: !open })}
211+
className={classNames(
212+
classes.actions,
213+
{ [classes.actionsClosed]: !open },
214+
actionsPlacementClass,
215+
)}
190216
ref={ref => {
191217
this.actionsRef = ref;
192218
}}
@@ -221,6 +247,10 @@ SpeedDial.propTypes = {
221247
* @ignore
222248
*/
223249
className: PropTypes.string,
250+
/**
251+
* The direction the actions open relative to the floating action button.
252+
*/
253+
direction: PropTypes.oneOf(['up', 'down', 'left', 'right']),
224254
/**
225255
* If `true`, the SpeedDial will be hidden.
226256
*/
@@ -273,6 +303,7 @@ SpeedDial.propTypes = {
273303

274304
SpeedDial.defaultProps = {
275305
hidden: false,
306+
direction: 'top',
276307
TransitionComponent: Zoom,
277308
transitionDuration: {
278309
enter: duration.enteringScreen,

packages/material-ui-lab/src/SpeedDial/SpeedDial.test.js

+22
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,26 @@ describe('<SpeedDial />', () => {
129129
assert.strictEqual(handleKeyDown.args[0][0], event);
130130
});
131131
});
132+
133+
describe('prop: direction', () => {
134+
const testDirection = direction => {
135+
const className = `direction${direction}`;
136+
const wrapper = shallow(
137+
<SpeedDial {...defaultProps} direction={direction.toLowerCase()} icon={icon}>
138+
<SpeedDialAction icon={icon} />
139+
<SpeedDialAction icon={icon} />
140+
</SpeedDial>,
141+
);
142+
const actionsWrapper = wrapper.childAt(1);
143+
assert.strictEqual(wrapper.hasClass(classes[className]), true);
144+
assert.strictEqual(actionsWrapper.hasClass(classes[className]), true);
145+
};
146+
147+
it('should place actions in correct position', () => {
148+
testDirection('Up');
149+
testDirection('Down');
150+
testDirection('Left');
151+
testDirection('Right');
152+
});
153+
});
132154
});

packages/material-ui-lab/src/SpeedDialAction/SpeedDialAction.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface SpeedDialActionProps
88
ButtonProps?: Partial<ButtonProps>;
99
delay?: number;
1010
icon: React.ReactNode;
11+
tooltipPlacement?: string;
1112
tooltipTitle?: React.ReactNode;
1213
}
1314

packages/material-ui-lab/src/SpeedDialAction/SpeedDialAction.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class SpeedDialAction extends React.Component {
5555
onClick,
5656
open,
5757
tooltipTitle,
58+
tooltipPlacement,
5859
...other
5960
} = this.props;
6061

@@ -63,7 +64,7 @@ class SpeedDialAction extends React.Component {
6364
id={id}
6465
className={classNames(classes.root, classNameProp)}
6566
title={tooltipTitle}
66-
placement="left"
67+
placement={tooltipPlacement}
6768
onClose={this.handleTooltipClose}
6869
onOpen={this.handleTooltipOpen}
6970
open={open && this.state.tooltipOpen}
@@ -124,6 +125,10 @@ SpeedDialAction.propTypes = {
124125
* @ignore
125126
*/
126127
open: PropTypes.bool,
128+
/**
129+
* Placement of the tooltip.
130+
*/
131+
tooltipPlacement: PropTypes.string,
127132
/**
128133
* Label to display in the tooltip.
129134
*/
@@ -133,6 +138,7 @@ SpeedDialAction.propTypes = {
133138
SpeedDialAction.defaultProps = {
134139
delay: 0,
135140
open: false,
141+
tooltipPlacement: 'left',
136142
};
137143

138144
export default withStyles(styles, { name: 'MuiSpeedDialAction' })(SpeedDialAction);

pages/lab/api/speed-dial-action.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ title: SpeedDialAction API
1919
| <span class="prop-name">classes</span> | <span class="prop-type">object |   | Useful to extend the style applied to components. |
2020
| <span class="prop-name">delay</span> | <span class="prop-type">number | <span class="prop-default">0</span> | Adds a transition delay, to allow a series of SpeedDialActions to be animated. |
2121
| <span class="prop-name required">icon *</span> | <span class="prop-type">node |   | The Icon to display in the SpeedDial Floating Action Button. |
22+
| <span class="prop-name">tooltipPlacement</span> | <span class="prop-type">string | <span class="prop-default">'left'</span> | Placement of the tooltip. |
2223
| <span class="prop-name">tooltipTitle</span> | <span class="prop-type">node |   | Label to display in the tooltip. |
2324

2425
Any other properties supplied will be spread to the root element (native element).

pages/lab/api/speed-dial.md

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ title: SpeedDial API
1919
| <span class="prop-name">ButtonProps</span> | <span class="prop-type">object |   | Properties applied to the [`Button`](/api/button) element. |
2020
| <span class="prop-name required">children *</span> | <span class="prop-type">node |   | SpeedDialActions to display when the SpeedDial is `open`. |
2121
| <span class="prop-name">classes</span> | <span class="prop-type">object |   | Override or extend the styles applied to the component. See [CSS API](#css-api) below for more details. |
22+
| <span class="prop-name">direction</span> | <span class="prop-type">enum:&nbsp;'up'&nbsp;&#124;<br>&nbsp;'down'&nbsp;&#124;<br>&nbsp;'left'&nbsp;&#124;<br>&nbsp;'right'<br> | <span class="prop-default">'top'</span> | The direction the actions open relative to the floating action button. |
2223
| <span class="prop-name">hidden</span> | <span class="prop-type">bool | <span class="prop-default">false</span> | If `true`, the SpeedDial will be hidden. |
2324
| <span class="prop-name required">icon *</span> | <span class="prop-type">element |   | The icon to display in the SpeedDial Floating Action Button. The `SpeedDialIcon` component provides a default Icon with animation. |
2425
| <span class="prop-name">onClose</span> | <span class="prop-type">func |   | Callback fired when the component requests to be closed.<br><br>**Signature:**<br>`function(event: object, key: string) => void`<br>*event:* The event source of the callback<br>*key:* The key pressed |
@@ -40,6 +41,10 @@ This property accepts the following keys:
4041
|:-----|:------------|
4142
| <span class="prop-name">root</span> | Styles applied to the root element.
4243
| <span class="prop-name">fab</span> | Styles applied to the Button component.
44+
| <span class="prop-name">directionUp</span> | Styles applied to the root and action container elements when direction="up"
45+
| <span class="prop-name">directionDown</span> | Styles applied to the root and action container elements when direction="down"
46+
| <span class="prop-name">directionLeft</span> | Styles applied to the root and action container elements when direction="left"
47+
| <span class="prop-name">directionRight</span> | Styles applied to the root and action container elements when direction="right"
4348
| <span class="prop-name">actions</span> | Styles applied to the actions (`children` wrapper) element.
4449
| <span class="prop-name">actionsClosed</span> | Styles applied to the actions (`children` wrapper) element if `open={false}`.
4550

0 commit comments

Comments
 (0)