-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f94a2c2
commit a27cc45
Showing
19 changed files
with
525 additions
and
306 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
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,19 @@ | ||
import * as React from 'react'; | ||
import { StandardProps } from '..'; | ||
import { InputProps } from '../Input'; | ||
import { MenuProps } from '../Menu'; | ||
import { NativeSelectInputProps } from './NativeSelectInput'; | ||
|
||
export interface NativeSelectProps | ||
extends StandardProps<InputProps, NativeSelectClassKey, 'value' | 'onChange'>, | ||
Pick<NativeSelectInputProps, 'onChange'> { | ||
IconComponent?: React.ReactType; | ||
input?: React.ReactNode; | ||
value?: string | number; | ||
} | ||
|
||
export type NativeSelectClassKey = 'root' | 'select' | 'selectMenu' | 'disabled' | 'icon'; | ||
|
||
declare const NativeSelect: React.ComponentType<NativeSelectProps>; | ||
|
||
export default NativeSelect; |
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,129 @@ | ||
// @inheritedComponent Input | ||
|
||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import NativeSelectInput from './NativeSelectInput'; | ||
import withStyles from '../styles/withStyles'; | ||
import ArrowDropDownIcon from '../internal/svg-icons/ArrowDropDown'; | ||
import Input from '../Input'; | ||
|
||
export const styles = theme => ({ | ||
root: { | ||
position: 'relative', | ||
width: '100%', | ||
}, | ||
select: { | ||
'-moz-appearance': 'none', // Reset | ||
'-webkit-appearance': 'none', // Reset | ||
// When interacting quickly, the text can end up selected. | ||
// Native select can't be selected either. | ||
userSelect: 'none', | ||
paddingRight: theme.spacing.unit * 4, | ||
width: `calc(100% - ${theme.spacing.unit * 4}px)`, | ||
minWidth: theme.spacing.unit * 2, // So it doesn't collapse. | ||
cursor: 'pointer', | ||
'&:focus': { | ||
// Show that it's not an text input | ||
background: | ||
theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.05)' : 'rgba(255, 255, 255, 0.05)', | ||
borderRadius: 0, // Reset Chrome style | ||
}, | ||
// Remove Firefox focus border | ||
'&:-moz-focusring': { | ||
color: 'transparent', | ||
textShadow: '0 0 0 #000', | ||
}, | ||
// Remove IE11 arrow | ||
'&::-ms-expand': { | ||
display: 'none', | ||
}, | ||
'&$disabled': { | ||
cursor: 'default', | ||
}, | ||
}, | ||
selectMenu: { | ||
width: 'auto', // Fix Safari textOverflow | ||
textOverflow: 'ellipsis', | ||
whiteSpace: 'nowrap', | ||
overflow: 'hidden', | ||
minHeight: '1.1875em', // Reset (19px), match the native input line-height | ||
}, | ||
disabled: {}, | ||
icon: { | ||
// We use a position absolute over a flexbox in order to forward the pointer events | ||
// to the input. | ||
position: 'absolute', | ||
right: 0, | ||
top: 'calc(50% - 12px)', // Center vertically | ||
color: theme.palette.action.active, | ||
'pointer-events': 'none', // Don't block pointer events on the select under the icon. | ||
}, | ||
}); | ||
|
||
/** | ||
* An alternative to `<Select native />` with a much smaller dependency graph. | ||
*/ | ||
function NativeSelect(props) { | ||
const { children, classes, IconComponent, input, inputProps, ...other } = props; | ||
|
||
return React.cloneElement(input, { | ||
// Most of the logic is implemented in `NativeSelectInput`. | ||
// The `Select` component is a simple API wrapper to expose something better to play with. | ||
inputComponent: NativeSelectInput, | ||
inputProps: { | ||
children, | ||
classes, | ||
IconComponent, | ||
type: undefined, // We render a select. We can ignore the type provided by the `Input`. | ||
...inputProps, | ||
...(input ? input.props.inputProps : {}), | ||
}, | ||
...other, | ||
}); | ||
} | ||
|
||
NativeSelect.propTypes = { | ||
/** | ||
* The option elements to populate the select with. | ||
* Can be some `<option>` elements. | ||
*/ | ||
children: PropTypes.node, | ||
/** | ||
* Override or extend the styles applied to the component. | ||
* See [CSS API](#css-api) below for more details. | ||
*/ | ||
classes: PropTypes.object.isRequired, | ||
/** | ||
* The icon that displays the arrow. | ||
*/ | ||
IconComponent: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), | ||
/** | ||
* An `Input` element; does not have to be a material-ui specific `Input`. | ||
*/ | ||
input: PropTypes.element, | ||
/** | ||
* Properties applied to the `input` element. | ||
* The properties are applied on the `select` element. | ||
*/ | ||
inputProps: PropTypes.object, | ||
/** | ||
* Callback function fired when a menu item is selected. | ||
* | ||
* @param {object} event The event source of the callback. | ||
* You can pull out the new value by accessing `event.target.value`. | ||
*/ | ||
onChange: PropTypes.func, | ||
/** | ||
* The input value. | ||
*/ | ||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), | ||
}; | ||
|
||
NativeSelect.defaultProps = { | ||
IconComponent: ArrowDropDownIcon, | ||
input: <Input />, | ||
}; | ||
|
||
NativeSelect.muiName = 'NativeSelect'; | ||
|
||
export default withStyles(styles, { name: 'MuiNativeSelect' })(NativeSelect); |
16 changes: 16 additions & 0 deletions
16
packages/material-ui/src/NativeSelect/NativeSelectInput.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,16 @@ | ||
import * as React from 'react'; | ||
|
||
export interface NativeSelectInputProps { | ||
disabled?: boolean; | ||
IconComponent?: React.ReactType; | ||
inputRef?: ( | ||
ref: HTMLSelectElement | { node: HTMLInputElement; value: NativeSelectInputProps['value'] }, | ||
) => void; | ||
name?: string; | ||
onChange?: (event: React.ChangeEvent<HTMLSelectElement>, child: React.ReactNode) => void; | ||
value?: string | number; | ||
} | ||
|
||
declare const NativeSelectInput: React.ComponentType<NativeSelectInputProps>; | ||
|
||
export default NativeSelectInput; |
90 changes: 90 additions & 0 deletions
90
packages/material-ui/src/NativeSelect/NativeSelectInput.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,90 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import classNames from 'classnames'; | ||
|
||
/** | ||
* @ignore - internal component. | ||
*/ | ||
function NativeSelectInput(props) { | ||
const { | ||
children, | ||
classes, | ||
className, | ||
disabled, | ||
IconComponent, | ||
inputRef, | ||
name, | ||
onChange, | ||
value, | ||
...other | ||
} = props; | ||
|
||
return ( | ||
<div className={classes.root}> | ||
<select | ||
className={classNames( | ||
classes.select, | ||
{ | ||
[classes.disabled]: disabled, | ||
}, | ||
className, | ||
)} | ||
name={name} | ||
disabled={disabled} | ||
onChange={onChange} | ||
value={value} | ||
ref={inputRef} | ||
{...other} | ||
> | ||
{children} | ||
</select> | ||
<IconComponent className={classes.icon} /> | ||
</div> | ||
); | ||
} | ||
|
||
NativeSelectInput.propTypes = { | ||
/** | ||
* The option elements to populate the select with. | ||
* Can be some `<option>` elements. | ||
*/ | ||
children: PropTypes.node, | ||
/** | ||
* Override or extend the styles applied to the component. | ||
* See [CSS API](#css-api) below for more details. | ||
*/ | ||
classes: PropTypes.object.isRequired, | ||
/** | ||
* The CSS class name of the select element. | ||
*/ | ||
className: PropTypes.string, | ||
/** | ||
* If `true`, the select will be disabled. | ||
*/ | ||
disabled: PropTypes.bool, | ||
/** | ||
* The icon that displays the arrow. | ||
*/ | ||
IconComponent: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), | ||
/** | ||
* Use that property to pass a ref callback to the native select element. | ||
*/ | ||
inputRef: PropTypes.func, | ||
/** | ||
* Name attribute of the `select` or hidden `input` element. | ||
*/ | ||
name: PropTypes.string, | ||
/** | ||
* Callback function fired when a menu item is selected. | ||
* | ||
* @param {object} event The event source of the callback. | ||
* You can pull out the new value by accessing `event.target.value`. | ||
*/ | ||
onChange: PropTypes.func, | ||
/** | ||
* The input value. | ||
*/ | ||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), | ||
}; | ||
|
||
export default NativeSelectInput; |
Oops, something went wrong.