Skip to content

Commit

Permalink
Allows the actions of speed dial to be placed in any direction
Browse files Browse the repository at this point in the history
  • Loading branch information
Sean Chamberlain committed Jul 25, 2018
1 parent e45ece3 commit f4c06c0
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 7 deletions.
11 changes: 8 additions & 3 deletions packages/material-ui-lab/src/SpeedDial/SpeedDial.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import { TransitionHandlerProps } from '@material-ui/core/transitions/transition

export interface SpeedDialProps
extends StandardProps<
React.HTMLAttributes<HTMLDivElement> & Partial<TransitionHandlerProps>,
SpeedDialClassKey
> {
React.HTMLAttributes<HTMLDivElement> & Partial<TransitionHandlerProps>,
SpeedDialClassKey
> {
actionsPlacement?:
| 'top'
| 'bottom'
| 'left'
| 'right';
ariaLabel: string;
ButtonProps?: Partial<ButtonProps>;
hidden?: boolean;
Expand Down
40 changes: 36 additions & 4 deletions packages/material-ui-lab/src/SpeedDial/SpeedDial.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,26 @@ export const styles = {
root: {
zIndex: 1050,
display: 'flex',
flexDirection: 'column-reverse', // Place the Actions above the FAB.
},
/* Styles when actions are placed to the top */
actionsTop: {
flexDirection: 'column-reverse',
},
/* Styles when actions are placed to the bottom */
actionsBottom: {
flexDirection: 'column',
},
/* Styles when actions are placed to the left */
actionsLeft: {
flexDirection: 'row-reverse',
},
/* Styles when actions are placed to the right */
actionsRight: {
flexDirection: 'row',
},
/* Styles applied to the actions (`children` wrapper) element. */
actions: {
display: 'flex',
flexDirection: 'column-reverse', // Display the first action at the bottom.
marginBottom: 16,
},
/* Styles applied to the actions (`children` wrapper) element if `open={false}`. */
Expand Down Expand Up @@ -102,6 +116,7 @@ class SpeedDial extends React.Component {
onClose,
onKeyDown,
open,
actionsPlacement,
openIcon,
TransitionComponent,
transitionDuration,
Expand Down Expand Up @@ -151,8 +166,15 @@ class SpeedDial extends React.Component {
return icon;
};

const actionsPlacementClass = {
[classes.actionsTop]: actionsPlacement === 'top',
[classes.actionsBottom]: actionsPlacement === 'bottom',
[classes.actionsLeft]: actionsPlacement === 'left',
[classes.actionsRight]: actionsPlacement === 'right',
}

return (
<div className={classNames(classes.root, classNameProp)} {...other}>
<div className={classNames(classes.root, classNameProp, actionsPlacementClass)} {...other}>
<TransitionComponent
in={!hidden}
timeout={transitionDuration}
Expand All @@ -178,7 +200,7 @@ class SpeedDial extends React.Component {
</TransitionComponent>
<div
id={`${id}-actions`}
className={classNames(classes.actions, { [classes.actionsClosed]: !open })}
className={classNames(classes.actions, { [classes.actionsClosed]: !open }, actionsPlacementClass)}
ref={ref => {
this.actionsRef = ref;
}}
Expand All @@ -191,6 +213,15 @@ class SpeedDial extends React.Component {
}

SpeedDial.propTypes = {
/**
* The placement of floating actions buttons in relation to speed dial.
*/
actionsPlacement: PropTypes.oneOf([
'top',
'bottom',
'left',
'right',
]),
/**
* The aria-label of the `Button` element.
* Also used to provide the `id` for the `SpeedDial` element and its children.
Expand Down Expand Up @@ -265,6 +296,7 @@ SpeedDial.propTypes = {

SpeedDial.defaultProps = {
hidden: false,
actionsPlacement: 'top',
TransitionComponent: Zoom,
transitionDuration: {
enter: duration.enteringScreen,
Expand Down
22 changes: 22 additions & 0 deletions packages/material-ui-lab/src/SpeedDial/SpeedDial.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,26 @@ describe('<SpeedDial />', () => {
assert.strictEqual(handleKeyDown.args[0][0], event);
});
});

describe('prop: actionPlacement', () => {
const testPlacement = placement => {
const className = `actions${placement}`;
const wrapper = shallow(
<SpeedDial {...defaultProps} actionsPlacement={placement.toLowerCase()} icon={icon}>
<SpeedDialAction icon={icon} />
<SpeedDialAction icon={icon} />
</SpeedDial>,
);
const actionsWrapper = wrapper.childAt(1);
assert.strictEqual(wrapper.hasClass(classes[className]), true);
assert.strictEqual(actionsWrapper.hasClass(classes[className]), true);
};

it('should place actions in correct position', () => {
testPlacement('Left');
testPlacement('Right');
testPlacement('Top');
testPlacement('Bottom');
});
});
});
5 changes: 5 additions & 0 deletions pages/lab/api/speed-dial.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ title: SpeedDial API

| Name | Type | Default | Description |
|:-----|:-----|:--------|:------------|
| <span class="prop-name">actionsPlacement</span> | <span class="prop-type">enum:&nbsp;'top'&nbsp;&#124;<br>&nbsp;'bottom'&nbsp;&#124;<br>&nbsp;'left'&nbsp;&#124;<br>&nbsp;'right'<br> | <span class="prop-default">'top'</span> | The placement of floating actions buttons in relation to speed dial. |
| <span class="prop-name required">ariaLabel *</span> | <span class="prop-type">string |   | The aria-label of the `Button` element. Also used to provide the `id` for the `SpeedDial` element and its children. |
| <span class="prop-name">ButtonProps</span> | <span class="prop-type">object |   | Properties applied to the [`Button`](/api/button) element. |
| <span class="prop-name required">children *</span> | <span class="prop-type">node |   | SpeedDialActions to display when the SpeedDial is `open`. |
Expand All @@ -39,6 +40,10 @@ This property accepts the following keys:
| Name | Description |
|:-----|:------------|
| <span class="prop-name">root</span> | Styles applied to the root element.
| <span class="prop-name">actionsTop</span> | Styles when actions are placed to the top
| <span class="prop-name">actionsBottom</span> | Styles when actions are placed to the bottom
| <span class="prop-name">actionsLeft</span> | Styles when actions are placed to the left
| <span class="prop-name">actionsRight</span> | Styles when actions are placed to the right
| <span class="prop-name">actions</span> | Styles applied to the actions (`children` wrapper) element.
| <span class="prop-name">actionsClosed</span> | Styles applied to the actions (`children` wrapper) element if `open={false}`.

Expand Down

0 comments on commit f4c06c0

Please sign in to comment.