diff --git a/devbox/apps/Input.js b/devbox/apps/Input.js index a547e6491..68eb5fbcb 100644 --- a/devbox/apps/Input.js +++ b/devbox/apps/Input.js @@ -25,6 +25,25 @@ function App() {
+ + + + }} /> + }} /> { return ( - ) : ( - - - - ) - } - adornmentPosition="end" + adornment={{ + end: + (props.value || '') === EMPTY ? ( + + ) : ( + + + + ), + }} onChange={handleChange} {...props} /> diff --git a/src/components/Input/TextInput.js b/src/components/Input/TextInput.js index 6f3c3bcc9..be8c8ac1d 100644 --- a/src/components/Input/TextInput.js +++ b/src/components/Input/TextInput.js @@ -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 ( +
+ {adornment} +
+ ) +}) + +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 } + + 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 (
-
- {adornment} -
+ {start && ( + + )} + {end && ( + + )}
) } @@ -143,7 +191,22 @@ const WrapperTextInput = React.forwardRef( 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, + }), + PropTypes.oneOf([null]), + + // deprecated + PropTypes.node, + ]), + + // deprecated adornmentPosition: PropTypes.oneOf(['start', 'end']), adornmentSettings: PropTypes.shape({ width: PropTypes.number, @@ -154,8 +217,6 @@ WrapperTextInput.propTypes = { WrapperTextInput.defaultProps = { ...TextInput.defaultProps, adornment: null, - adornmentPosition: 'start', - adornmentSettings: {}, } // (only for compat) diff --git a/src/components/TextCopy/TextCopy.js b/src/components/TextCopy/TextCopy.js index e7fa6fd9e..51e05e640 100644 --- a/src/components/TextCopy/TextCopy.js +++ b/src/components/TextCopy/TextCopy.js @@ -92,25 +92,24 @@ const TextCopy = React.memo( )} - - - } - adornmentPosition="end" - adornmentSettings={{ + adornment={{ + end: ( + + + + ), // Keep the button square - width: HEIGHT - 2, - padding: 0, + endWidth: HEIGHT - 2, + endPadding: 0, }} autofocus={autofocus} onFocus={handleFocus}