-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ToggleButtons]: Add toggle buttons (#10144)
- Loading branch information
Showing
22 changed files
with
1,101 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { withStyles } from '@material-ui/core/styles'; | ||
import FormatAlignLeftIcon from '@material-ui/icons/FormatAlignLeft'; | ||
import FormatAlignCenterIcon from '@material-ui/icons/FormatAlignCenter'; | ||
import FormatAlignRightIcon from '@material-ui/icons/FormatAlignRight'; | ||
import FormatAlignJustifyIcon from '@material-ui/icons/FormatAlignJustify'; | ||
import FormatBoldIcon from '@material-ui/icons/FormatBold'; | ||
import FormatItalicIcon from '@material-ui/icons/FormatItalic'; | ||
import FormatUnderlinedIcon from '@material-ui/icons/FormatUnderlined'; | ||
import FormatColorFillIcon from '@material-ui/icons/FormatColorFill'; | ||
import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown'; | ||
import Typography from '@material-ui/core/Typography'; | ||
import Grid from '@material-ui/core/Grid'; | ||
import ToggleButton, { ToggleButtonGroup } from '@material-ui/lab/ToggleButton'; | ||
|
||
const styles = theme => ({ | ||
toggleContainer: { | ||
height: 56, | ||
padding: `${theme.spacing.unit}px ${theme.spacing.unit * 2}px`, | ||
display: 'flex', | ||
alignItems: 'center', | ||
justifyContent: 'flex-start', | ||
margin: `${theme.spacing.unit}px 0`, | ||
background: theme.palette.background.default, | ||
}, | ||
}); | ||
|
||
class ToggleButtons extends React.Component { | ||
state = { | ||
alignment: 'left', | ||
formats: ['bold'], | ||
}; | ||
|
||
handleFormat = formats => this.setState({ formats }); | ||
|
||
handleAlignment = alignment => this.setState({ alignment }); | ||
|
||
render() { | ||
const { classes } = this.props; | ||
const { alignment, formats } = this.state; | ||
|
||
return ( | ||
<Grid container spacing={16}> | ||
<Grid item xs={12} sm={6}> | ||
<div className={classes.toggleContainer}> | ||
<ToggleButtonGroup value={alignment} exclusive onChange={this.handleAlignment}> | ||
<ToggleButton value="left"> | ||
<FormatAlignLeftIcon /> | ||
</ToggleButton> | ||
<ToggleButton value="center"> | ||
<FormatAlignCenterIcon /> | ||
</ToggleButton> | ||
<ToggleButton value="right"> | ||
<FormatAlignRightIcon /> | ||
</ToggleButton> | ||
<ToggleButton value="justify" disabled> | ||
<FormatAlignJustifyIcon /> | ||
</ToggleButton> | ||
</ToggleButtonGroup> | ||
</div> | ||
<Typography type="caption" gutterBottom> | ||
Exclusive Selection | ||
</Typography> | ||
<Typography type="caption"> | ||
Text justification toggle buttons present options for left, right, center, full, and | ||
justified text with only one item available for selection at a time. Selecting one | ||
option deselects any other. | ||
</Typography> | ||
</Grid> | ||
<Grid item xs={12} sm={6}> | ||
<div className={classes.toggleContainer}> | ||
<ToggleButtonGroup value={formats} onChange={this.handleFormat}> | ||
<ToggleButton value="bold"> | ||
<FormatBoldIcon /> | ||
</ToggleButton> | ||
<ToggleButton value="italic"> | ||
<FormatItalicIcon /> | ||
</ToggleButton> | ||
<ToggleButton value="underlined"> | ||
<FormatUnderlinedIcon /> | ||
</ToggleButton> | ||
<ToggleButton disabled value="color"> | ||
<FormatColorFillIcon /> | ||
<ArrowDropDownIcon /> | ||
</ToggleButton> | ||
</ToggleButtonGroup> | ||
</div> | ||
<Typography type="caption" gutterBottom> | ||
Multiple Selection | ||
</Typography> | ||
<Typography type="caption"> | ||
Logically-grouped options, like Bold, Italic, and Underline, allow multiple options to | ||
be selected. | ||
</Typography> | ||
</Grid> | ||
</Grid> | ||
); | ||
} | ||
} | ||
|
||
ToggleButtons.propTypes = { | ||
classes: PropTypes.object.isRequired, | ||
}; | ||
|
||
export default withStyles(styles)(ToggleButtons); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
title: Toggle Button React component | ||
components: ToggleButton, ToggleButtonGroup | ||
--- | ||
|
||
# Toggle Buttons | ||
|
||
<p class="description">Toggle buttons can be used to group related options.</p> | ||
|
||
To emphasize groups of related [Toggle buttons](https://material.io/design/components/buttons.html#toggle-button), | ||
a group should share a common container. | ||
|
||
The `ToggleButtonGroup` will control the selected of its child buttons when | ||
given its own `value` prop. | ||
|
||
{{"demo": "pages/lab/toggle-button/ToggleButtons.js"}} |
20 changes: 20 additions & 0 deletions
20
packages/material-ui-lab/src/ToggleButton/ToggleButton.d.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import * as React from 'react'; | ||
import { StandardProps, PropTypes } from '..'; | ||
import { ButtonBaseProps, ButtonBaseClassKey } from '../ButtonBase'; | ||
|
||
export interface ToggleButtonProps | ||
extends StandardProps<ButtonBaseProps, ToggleButtonClassKey, 'component'> { | ||
component?: React.ReactType<ToggleButtonProps>; | ||
disabled?: boolean; | ||
disableFocusRipple?: boolean; | ||
disableRipple?: boolean; | ||
selected?: boolean; | ||
type?: string; | ||
value?: any; | ||
} | ||
|
||
export type ToggleButtonClassKey = ButtonBaseClassKey | 'label' | 'selected'; | ||
|
||
declare const ToggleButton: React.ComponentType<ToggleButtonProps>; | ||
|
||
export default ToggleButton; |
189 changes: 189 additions & 0 deletions
189
packages/material-ui-lab/src/ToggleButton/ToggleButton.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
// @inheritedComponent ButtonBase | ||
|
||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import classNames from 'classnames'; | ||
import { withStyles } from '@material-ui/core/styles'; | ||
import { fade } from '@material-ui/core/styles/colorManipulator'; | ||
import ButtonBase from '@material-ui/core/ButtonBase'; | ||
|
||
export const styles = theme => ({ | ||
root: { | ||
...theme.typography.button, | ||
height: 32, | ||
minWidth: 48, | ||
margin: 0, | ||
padding: `${theme.spacing.unit - 4}px ${theme.spacing.unit * 1.5}px`, | ||
borderRadius: 2, | ||
willChange: 'opacity', | ||
color: fade(theme.palette.action.active, 0.38), | ||
'&:hover': { | ||
textDecoration: 'none', | ||
// Reset on mouse devices | ||
backgroundColor: fade(theme.palette.text.primary, 0.12), | ||
'@media (hover: none)': { | ||
backgroundColor: 'transparent', | ||
}, | ||
'&$disabled': { | ||
backgroundColor: 'transparent', | ||
}, | ||
}, | ||
|
||
'&:not(:first-child)': { | ||
borderTopLeftRadius: 0, | ||
borderBottomLeftRadius: 0, | ||
}, | ||
|
||
'&:not(:last-child)': { | ||
borderTopRightRadius: 0, | ||
borderBottomRightRadius: 0, | ||
}, | ||
}, | ||
label: { | ||
width: '100%', | ||
display: 'inherit', | ||
alignItems: 'inherit', | ||
justifyContent: 'inherit', | ||
}, | ||
disabled: { | ||
color: fade(theme.palette.action.disabled, 0.12), | ||
}, | ||
selected: { | ||
color: theme.palette.action.active, | ||
'&:after': { | ||
content: '""', | ||
display: 'block', | ||
position: 'absolute', | ||
overflow: 'hidden', | ||
borderRadius: 'inherit', | ||
width: '100%', | ||
height: '100%', | ||
left: 0, | ||
top: 0, | ||
pointerEvents: 'none', | ||
zIndex: 0, | ||
backgroundColor: 'currentColor', | ||
opacity: 0.38, | ||
}, | ||
|
||
'& + &:before': { | ||
content: '""', | ||
display: 'block', | ||
position: 'absolute', | ||
overflow: 'hidden', | ||
width: 1, | ||
height: '100%', | ||
left: 0, | ||
top: 0, | ||
pointerEvents: 'none', | ||
zIndex: 0, | ||
backgroundColor: 'currentColor', | ||
opacity: 0.12, | ||
}, | ||
}, | ||
}); | ||
|
||
class ToggleButton extends React.Component { | ||
handleChange = event => { | ||
const { onChange, onClick, value } = this.props; | ||
|
||
if (onClick) { | ||
onClick(event); | ||
if (event.isDefaultPrevented()) { | ||
return; | ||
} | ||
} | ||
|
||
if (onChange) { | ||
onChange(value); | ||
} | ||
}; | ||
|
||
render() { | ||
const { | ||
children, | ||
className: classNameProp, | ||
classes, | ||
disableFocusRipple, | ||
disabled, | ||
selected, | ||
...other | ||
} = this.props; | ||
|
||
const className = classNames( | ||
classes.root, | ||
{ | ||
[classes.disabled]: disabled, | ||
[classes.selected]: selected, | ||
}, | ||
classNameProp, | ||
); | ||
|
||
return ( | ||
<ButtonBase | ||
className={className} | ||
disabled={disabled} | ||
focusRipple={!disableFocusRipple} | ||
onClick={this.handleChange} | ||
{...other} | ||
> | ||
<span className={classes.label}>{children}</span> | ||
</ButtonBase> | ||
); | ||
} | ||
} | ||
|
||
ToggleButton.propTypes = { | ||
/** | ||
* The content of the button. | ||
*/ | ||
children: PropTypes.node.isRequired, | ||
/** | ||
* Useful to extend the style applied to components. | ||
*/ | ||
classes: PropTypes.object.isRequired, | ||
/** | ||
* @ignore | ||
*/ | ||
className: PropTypes.string, | ||
/** | ||
* If `true`, the button will be disabled. | ||
*/ | ||
disabled: PropTypes.bool, | ||
/** | ||
* If `true`, the keyboard focus ripple will be disabled. | ||
* `disableRipple` must also be true. | ||
*/ | ||
disableFocusRipple: PropTypes.bool, | ||
/** | ||
* If `true`, the ripple effect will be disabled. | ||
*/ | ||
disableRipple: PropTypes.bool, | ||
/** | ||
* @ignore | ||
*/ | ||
onChange: PropTypes.func, | ||
/** | ||
* @ignore | ||
*/ | ||
onClick: PropTypes.func, | ||
/** | ||
* If `true`, the button will be rendered in an active state. | ||
*/ | ||
selected: PropTypes.bool, | ||
/** | ||
* The value to associate with the button when selected in a | ||
* ToggleButtonGroup. | ||
*/ | ||
value: PropTypes.any.isRequired, | ||
}; | ||
|
||
ToggleButton.defaultProps = { | ||
disabled: false, | ||
disableFocusRipple: false, | ||
disableRipple: false, | ||
}; | ||
|
||
ToggleButton.muiName = 'ToggleButton'; | ||
|
||
export default withStyles(styles, { name: 'MuiToggleButton' })(ToggleButton); |
Oops, something went wrong.