-
Notifications
You must be signed in to change notification settings - Fork 122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TextInput: refresh adornment API #770
Changes from 14 commits
f149830
036f642
e88a74a
a37a38a
4d417c1
e13e5fd
82d8a35
02328fa
588e90b
fb1f326
31ed83e
65a92ff
4f22c42
aa2b33f
f259c47
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import React, { useCallback } from 'react' | ||
import PropTypes from 'prop-types' | ||
import { useTheme } from '../../theme' | ||
import { warnOnce } from '../../utils' | ||
import { warn, warnOnce } from '../../utils' | ||
import { textStyle, GU, RADIUS } from '../../style' | ||
|
||
// Simple text input | ||
|
@@ -84,24 +84,80 @@ TextInput.defaultProps = { | |
type: 'text', | ||
} | ||
|
||
const Adornment = React.memo(({ adornment, position, padding }) => { | ||
const theme = useTheme() | ||
return ( | ||
<div | ||
css={` | ||
position: absolute; | ||
top: 0; | ||
bottom: 0; | ||
height: 100%; | ||
${position === 'end' ? 'right' : 'left'}: ${padding}px; | ||
Evalir marked this conversation as resolved.
Show resolved
Hide resolved
|
||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
color: ${theme.surfaceContentSecondary}; | ||
`} | ||
> | ||
{adornment} | ||
</div> | ||
) | ||
}) | ||
|
||
Adornment.propTypes = { | ||
adornment: PropTypes.node, | ||
position: PropTypes.oneOf(['start', 'end']), | ||
padding: PropTypes.number, | ||
} | ||
|
||
Adornment.defaultProps = { | ||
padding: 4, | ||
} | ||
|
||
// Text input wrapped to allow adornments | ||
const WrapperTextInput = React.forwardRef( | ||
( | ||
{ | ||
adornment, | ||
adornmentPosition, | ||
adornmentSettings: { | ||
width: adornmentWidth = 36, | ||
padding: adornmentPadding = 4, | ||
}, | ||
...props | ||
}, | ||
ref | ||
) => { | ||
const theme = useTheme() | ||
({ adornment, adornmentPosition, adornmentSettings, ...props }, ref) => { | ||
if (adornmentPosition) { | ||
warn( | ||
'TextInput: The "adornmentPosition" prop is deprecated. Please use the "adornment" prop instead.' | ||
) | ||
} | ||
if (adornmentSettings) { | ||
warn( | ||
'TextInput: The "adornmentSettings" props is deprecated. Please use the "adornment" prop instead.' | ||
) | ||
} | ||
|
||
if (!adornment) { | ||
return <TextInput ref={ref} {...props} /> | ||
} | ||
|
||
let adornmentConfig = adornment | ||
|
||
const usingDeprecatedAPI = | ||
React.isValidElement(adornment) || | ||
typeof adornment === 'string' || | ||
(typeof adornment === 'object' && adornment.constructor === Array) | ||
|
||
if (usingDeprecatedAPI) { | ||
const { adornmentPosition = 'start', adornmentSettings = {} } = props | ||
adornmentConfig = { | ||
[adornmentPosition]: adornment, | ||
[`${adornmentPosition}Padding`]: adornmentSettings.padding, | ||
[`${adornmentPosition}Width`]: adornmentSettings.width, | ||
} | ||
} | ||
|
||
const { | ||
start, | ||
startPadding, | ||
startWidth = 36, | ||
end, | ||
endPadding, | ||
endWidth = 36, | ||
} = adornmentConfig | ||
|
||
return ( | ||
<div | ||
css={` | ||
|
@@ -113,37 +169,43 @@ const WrapperTextInput = React.forwardRef( | |
<TextInput | ||
ref={ref} | ||
css={` | ||
${adornmentPosition === 'end' | ||
? 'padding-right' | ||
: 'padding-left'}: ${adornmentWidth - adornmentPadding * 2}px; | ||
${start && `padding-left: ${startWidth}`} | ||
${end && `padding-right: ${endWidth}`} | ||
`} | ||
{...props} | ||
/> | ||
<div | ||
css={` | ||
position: absolute; | ||
top: 0; | ||
bottom: 0; | ||
height: 100%; | ||
${adornmentPosition === 'end' | ||
? 'right' | ||
: 'left'}: ${adornmentPadding}px; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
color: ${theme.surfaceContentSecondary}; | ||
`} | ||
> | ||
{adornment} | ||
</div> | ||
{start && ( | ||
<Adornment | ||
adornment={start} | ||
padding={startPadding} | ||
position="start" | ||
/> | ||
)} | ||
{end && ( | ||
<Adornment adornment={end} padding={endPadding} position="end" /> | ||
)} | ||
</div> | ||
) | ||
} | ||
) | ||
|
||
WrapperTextInput.propTypes = { | ||
...TextInput.propTypes, | ||
adornment: PropTypes.node, | ||
adornment: PropTypes.oneOf([ | ||
PropTypes.shape({ | ||
start: PropTypes.node, | ||
startWidth: PropTypes.number, | ||
startPadding: PropTypes.number, | ||
end: PropTypes.node, | ||
endWidth: PropTypes.number, | ||
endPadding: PropTypes.number, | ||
}), | ||
|
||
// deprecated | ||
PropTypes.node, | ||
]), | ||
|
||
// deprecated | ||
adornmentPosition: PropTypes.oneOf(['start', 'end']), | ||
adornmentSettings: PropTypes.shape({ | ||
width: PropTypes.number, | ||
Evalir marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
@@ -154,8 +216,6 @@ WrapperTextInput.propTypes = { | |
WrapperTextInput.defaultProps = { | ||
...TextInput.defaultProps, | ||
adornment: null, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure, but should we add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sadly, React doesn't seem to have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prop types interpret To combine a value with a type, the trick is to use PropTypes.oneOfType([
PropTypes.oneOf([null]),
PropTypes.number,
]) This is what we are doing for the aragonUI’s |
||
adornmentPosition: 'start', | ||
adornmentSettings: {}, | ||
} | ||
|
||
// <input type=number> (only for compat) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we also update this component's documentation with the new changes? We can remove (or mark) the deprecated props :). |
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For these older examples, perhaps we can either remove them or update them to use the new API?