Skip to content

Commit 40ca6bb

Browse files
committed
feat(ui-text-input,ui-date-input): properly support IconButtons inside TextInputs
1 parent 94f0a6f commit 40ca6bb

File tree

4 files changed

+39
-11
lines changed

4 files changed

+39
-11
lines changed

packages/ui-date-input/src/DateInput2/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
describes: DateInput2
33
---
44

5-
> _Warning_: `DateInput2` is an **experimental** upgrade to the existing [`DateInput`](/#DateInput) component, offering easier configuration, better UX, improved accessibility, and a year picker. While it addresses key limitations of `DateInput`, it's still in the experimental phase, with some missing unit tests and potential API changes.
5+
> _Info_: `DateInput2` is an upgrade to the [`DateInput`](/#DateInput) component, offering easier configuration, better UX, improved accessibility, and a year picker. Please consider updating to this for WCAG compatiblity and an overall better experience (for both devs and users).
66
77
### Minimal config
88

packages/ui-date-input/src/DateInput2/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,6 @@ const DateInput2 = forwardRef(
290290
withBackground={false}
291291
withBorder={false}
292292
screenReaderLabel={screenReaderLabels.calendarIcon}
293-
shape="circle"
294293
interaction={interaction}
295294
>
296295
{renderCalendarIcon ? (

packages/ui-text-input/src/TextInput/README.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,6 @@ TextInput accepts focusable and non-focusable content before and/or after
182182
the input text. A common use case is adding an icon or avatar to the input.
183183
Focusable content will be focused separately from the input itself.
184184

185-
> Note: For any content larger than an icon or small avatar (multiple [Tags](#Tag), for example),
186-
> use the `renderBeforeInput` property.
187-
188185
- ```javascript
189186
class ExtraContentExample extends React.Component {
190187
constructor(props) {
@@ -301,6 +298,33 @@ Focusable content will be focused separately from the input itself.
301298
render(<ExtraContentExample />)
302299
```
303300

301+
Another common usecase is to add an `IconButton` at the end of a TextInput, e.g. for revealing the content of a password field. In these cases, please use the `withBorder={false}` and `withBackground={false}` props for the IconButton.
302+
303+
```js
304+
---
305+
type: example
306+
---
307+
const InputsWithButtonsExample = () => {
308+
const [passwordValue, setPasswordValue] = useState('')
309+
const [showPassword, setShowPassword] = useState(false)
310+
return (
311+
<TextInput
312+
renderLabel="Password"
313+
type={showPassword ? 'text' : 'password'}
314+
placeholder="Find something..."
315+
value={passwordValue}
316+
onChange={(e, newValue) => setPasswordValue(newValue)}
317+
renderAfterInput={
318+
<IconButton withBorder={false} withBackground={false} onClick={() => setShowPassword(prevState => !prevState)} screenReaderLabel={showPassword ? 'Hide password' : 'Show password'}>
319+
{showPassword ? <IconOffLine/> : <IconEyeLine/>}
320+
</IconButton>
321+
}
322+
/>
323+
)
324+
}
325+
render(<InputsWithButtonsExample />)
326+
```
327+
304328
### Setting width and display
305329

306330
To make the component display inline, set the `display` property to `inline-block`. To constrain the

packages/ui-text-input/src/TextInput/styles.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,20 @@ const generateStyle = (
206206
...flexBase
207207
},
208208
afterElement: {
209-
// TODO this is added for the case when there is an IconButton inside a TextInput (like in the DateInput2 component)
210-
// and the button size makes the whole input 2px larger (because of the borders)
211-
// this is not the best solution and in the long term we should work with the design team to figure out how to handle such cases
212-
marginTop: '-1px',
213-
marginBottom: '-1px',
209+
// the next couple lines (until the `label`) is needed so the IconButton looks OK inside the TextInput
210+
// explanation: if the content inside is not a button or a popover (which could contain a button) it should have some padding on the right
211+
'& > :not(button):not([data-cid$="Popover"])': {
212+
marginRight: componentTheme.padding
213+
},
214+
marginTop: '1px',
215+
marginBottom: '1px',
216+
display: 'flex',
217+
alignItems: 'center',
218+
...sizeVariants[size!],
214219
label: 'textInput__afterElement',
215220
...viewBase,
221+
borderRadius: componentTheme.borderRadius,
216222
flexShrink: 0,
217-
paddingInlineEnd: componentTheme.padding,
218223
// we only override the padding once the width is calculated,
219224
// it needs the padding on render
220225
...(afterElementHasWidth === false && {

0 commit comments

Comments
 (0)