Skip to content

Commit

Permalink
Creates a FilledInput component.
Browse files Browse the repository at this point in the history
  • Loading branch information
loriensleafs committed Mar 24, 2019
1 parent 4ef836f commit 82345be
Showing 1 changed file with 129 additions and 124 deletions.
253 changes: 129 additions & 124 deletions src/FilledInput/FilledInput.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,41 @@
import React from 'react';
import PropTypes from 'prop-types';
import React, { forwardRef } from 'react';
import InputBase from '../InputBase';
import { getSpacing } from '../system';
import combine from '../utils/combine';
import { getSpacing, useStyles } from '../system';
import { componentPropType, stylesPropType } from '../utils/propTypes';
import { stylesPropType } from '../utils/propTypes';

const getStartAdornmentStyles = ({ startAdornment }) =>
startAdornment && {
root: getSpacing({ pr: 14 }),
input: getSpacing({ pr: 0 }),
};

const getEndAdornmentStyles = ({ endAdornment }) =>
endAdornment && {
root: getSpacing({ pl: 14 }),
input: getSpacing({ pl: 0 }),
};
const getBaseStyles = ({ theme: { getTransition, palette, shape } }) => ({
root: {
position: 'relative',
backgroundColor:
palette.type === 'light'
? 'rgba(0, 0, 0, 0.09)'
: 'rgba(255, 255, 255, 0.09)',
borderTopLeftRadius: shape.borderRadius.round,
borderTopRightRadius: shape.borderRadius.round,
transition: getTransition('background-color', {
duration: 'shorter',
easing: 'out',
}),
':hover': {
backgroundColor:
palette.type === 'light'
? 'rgba(0, 0, 0, 0.13)'
: 'rgba(255, 255, 255, 0.13)',
// Reset on touch devices so as not to add specificity.
'@media (hover: none)': {
backgroundColor:
palette.type === 'light'
? 'rgba(0, 0, 0, 0.09)'
: 'rgba(255, 255, 255, 0.09)',
},
},
},
input: {
padding: '27px 12px 10px',
},
});

const getDisabledStyles = ({ disabled, theme: { palette } }) =>
disabled && {
Expand All @@ -24,10 +44,23 @@ const getDisabledStyles = ({ disabled, theme: { palette } }) =>
palette.type === 'light'
? 'rgba(0, 0, 0, 0.12)'
: 'rgba(255, 255, 255, 0.09)',
':before': {
borderBottomStyle: 'dotted',
},
':hover:before': {
borderBottom: `1px dotted ${palette.text.disabled}`,
},
},
};

const getErrorStyles = ({ error, theme: { palette } }) =>
const getEndAdornmentStyles = ({ endAdornment }) =>
endAdornment && {
root: getSpacing({ pl: 14 }),
input: getSpacing({ pl: 0 }),
};

const getErrorStyles = ({ disabled, error, theme: { palette } }) =>
!disabled &&
error && {
root: {
':after': {
Expand All @@ -37,6 +70,34 @@ const getErrorStyles = ({ error, theme: { palette } }) =>
},
};

const getFocusedStyles = ({ disabled, focused, theme: { palette } }) =>
!disabled &&
focused && {
root: {
backgroundColor:
palette.type === 'light'
? 'rgba(0, 0, 0, 0.09)'
: 'rgba(255, 255, 255, 0.09)',
':before': {
borderBottom: `1px solid ${
palette.type === 'light'
? 'rgba(0,0,0,0.42)'
: 'rgba(255,255,255, 0.7)'
}`,
},
':after': {
transform: 'scaleX(1)',
},
':hover:before': {
borderBottom: `1px solid ${
palette.type === 'light'
? 'rgba(0,0,0,0.42)'
: 'rgba(255,255,255, 0.7)'
}`,
},
},
};

const getMarginStyles = ({ margin }) =>
margin === 'dense' && {
input: getSpacing({ pt: 3.5, pb: 1.5 }),
Expand All @@ -54,112 +115,68 @@ const getMultilineStyles = ({ multilined }) =>
},
};

const getUnderlinedStyles = ({
disabled,
const getUnderlineStyles = ({
disableUnderline,
error,
focused,
theme: { getTransition, palette },
}) => {
const isLight = palette.type === 'light';
const bottomLineColor = isLight
? 'rgba(0,0,0,0.42)'
: 'rgba(255,255,255, 0.7)';
let next = {};

if (!disableUnderline) {
next = {
root: {
':before': {
content: '"\\00a0"',
position: 'absolute',
right: '0px',
bottom: '0px',
left: '0px',
borderBottom: `1px solid ${bottomLineColor}`,
transition: getTransition('border-bottom-color', {
duration: 'shorter',
}),
pointerEvents: 'none',
},
':after': {
content: '""',
position: 'absolute',
right: '0px',
bottom: '0px',
left: '0px',
borderBottom: `2px solid ${palette.primary[palette.type]}`,
transform: 'scaleX(0)',
transition: getTransition('transform', {
duration: 'shorter',
easing: 'out',
}),
pointerEvents: 'none',
},
':disabled:before': {
borderBottom: `1px dotted ${bottomLineColor}`,
},
}) =>
!disableUnderline && {
root: {
':before': {
content: '"\\00a0"',
position: 'absolute',
right: '0px',
bottom: '0px',
left: '0px',
borderBottom: `1px solid ${
palette.type === 'light'
? 'rgba(0,0,0,0.42)'
: 'rgba(255,255,255, 0.7)'
}`,
transition: getTransition('border-bottom-color', {
duration: 'shorter',
easing: 'out',
}),
pointerEvents: 'none',
},
};

if (!error && !disabled && !focused) {
next.root[':hover'] = {
':after': {
content: '""',
position: 'absolute',
right: '0px',
left: '0px',
bottom: '0px',
borderBottom: `2px solid ${palette.primary[palette.type]}`,
transform: 'scaleX(0)',
transition: getTransition('transform', {
duration: 'shorter',
easing: 'out',
}),
pointerEvents: 'none',
},
':hover:before': {
borderBottom: `1px solid ${palette.text.primary}`,
};
}
}

return next;
};

const getBaseStyles = ({ theme: { getTransition, palette, shape } }) => ({
root: {
position: 'relative',
backgroundColor:
palette.type === 'light'
? 'rgba(0, 0, 0, 0.09)'
: 'rgba(255, 255, 255, 0.09)',
borderTopLeftRadius: shape.borderRadius.round,
borderTopRightRadius: shape.borderRadius.round,
transition: getTransition('background-color', {
duration: 'shorter',
easing: 'out',
}),
':hover': {
backgroundColor:
palette.type === 'light'
? 'rgba(0, 0, 0, 0.13)'
: 'rgba(255, 255, 255, 0.13)',
// Reset on touch devices so as not to add specificity.
'@media (hover: none)': {
backgroundColor:
palette.type === 'light'
? 'rgba(0, 0, 0, 0.09)'
: 'rgba(255, 255, 255, 0.09)',
},
},
':focused': {
backgroundColor:
palette.type === 'light'
? 'rgba(0, 0, 0, 0.09)'
: 'rgba(255, 255, 255, 0.12)',
},
},
input: {
padding: '27px 12px 10px',
},
});
};

const getStyles = combine(
const getStartAdornmentStyles = ({ startAdornment }) =>
startAdornment && {
root: getSpacing({ pr: 14 }),
input: getSpacing({ pr: 0 }),
};

const getFilledInputStyles = combine(
getBaseStyles,
getEndAdornmentStyles,
getMarginStyles,
getMultilineStyles,
getStartAdornmentStyles,
getEndAdornmentStyles,
getErrorStyles,
getUnderlineStyles,
getDisabledStyles,
getUnderlinedStyles,
getErrorStyles,
getFocusedStyles,
);

const getStyles = props => getFilledInputStyles(props);
getStyles.propTypes = {
// If `true`, the input will not have an underline.
disableUnderline: PropTypes.bool,
Expand All @@ -177,20 +194,9 @@ getStyles.propTypes = {
startAdornment: PropTypes.node,
};

function FilledInput(props) {
const [{ styles }, passThru] = useStyles(props, getStyles, {
whitelist: [
'endAdornment',
'error',
'disabled',
'margin',
'multiline',
'startAdornment',
],
});

return <InputBase styles={styles} {...passThru} />;
}
const FilledInput = forwardRef((props, ref) => (
<InputBase ref={ref} styles={getStyles} {...props} />
));

FilledInput.displayName = 'FilledInput';

Expand Down Expand Up @@ -275,12 +281,11 @@ FilledInput.propTypes = {
),
]),
...getStyles.propTypes,
...componentPropType,
...stylesPropType,
};

InputBase.defaultProps = {
as: 'input',
inputComponent: 'input',
fullWidth: false,
multiline: false,
type: 'text',
Expand Down

0 comments on commit 82345be

Please sign in to comment.