Skip to content
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

[TextField] implement suffix/prefix props #19792

Closed
eps1lon opened this issue Feb 21, 2020 · 12 comments · Fixed by #44744
Closed

[TextField] implement suffix/prefix props #19792

eps1lon opened this issue Feb 21, 2020 · 12 comments · Fixed by #44744
Labels
component: text field This is the name of the generic UI component, not the React module! new feature New feature or request

Comments

@eps1lon
Copy link
Member

eps1lon commented Feb 21, 2020

Current Behavior 😯

Screenshot from 2020-02-21 09-59-58

Expected Behavior 🤔

filled-end-alignment

Steps to Reproduce 🕹

<TextField
  label="value"
  InputProps={{
    endAdornment: <InputAdornment position="end">days</InputAdornment>
  }}
  type="text"
  variant="filled"
/>

https://codesandbox.io/s/textfield-endadornment-on-filled-misaligned-rbcyy

Steps:

  1. Goto https://codesandbox.io/s/textfield-endadornment-on-filled-misaligned-rbcyy
  2. Observe misalignment

Context 🔦

Displaying units of the input value for filled inputs

Implementation proposal

<TextField
  label="value"
  InputProps={{
    suffix: <InputSuffix>days</InputSuffix>
  }}
  type="text"
  variant="filled"
/>

following https://material.io/components/text-fields/#filled-text-field (see "prefix and suffix text")

Notes

The alignment uses the baseline of the input without a value (where the label looks like a placeholder). Once we transition to label+value the alignment is off. The Adornment should adjust for this state.

Your Environment 🌎

Tech Version
Material-UI v4.9.3
React 16.12
Browser Chrome Version 80.0.3987.116 (Official Build) (64-bit) Ubuntu 18.04
@eps1lon eps1lon added the component: text field This is the name of the generic UI component, not the React module! label Feb 21, 2020
@oliviertassinari
Copy link
Member

There is a concern to consider with the display when the field is empty and only the label is visible. I might recall a older issue on this very problem.

@eps1lon
Copy link
Member Author

eps1lon commented Feb 21, 2020

There is a concern to consider with the display when the field is empty and only the label is visible. I might recall a older issue on this very problem.

I included this already

The alignment uses the baseline of the input without a value (where the label looks like a placeholder). Once we transition to label+value the alignment is off. The Adornment should adjust for this state.

@eps1lon
Copy link
Member Author

eps1lon commented Feb 21, 2020

Ok I now remember the underlying issue. I want to abuse the end adornment for a suffix. Changing the alignment would be bad if we have something like a show/hide password toggle.

We probably want to implement prefixes/suffixes separately as described in the guidelines:

Screenshot from 2020-02-21 10-22-01

-- https://material.io/components/text-fields/#filled-text-field

@oliviertassinari
Copy link
Member

👌 Makes it hard to solve :).

@eps1lon eps1lon changed the title [TextField] endAdornment on filled misaligned [TextField] implement suffix/prefix props Feb 21, 2020
@oliviertassinari
Copy link
Member

Maybe we should force the shrink state?

@eps1lon
Copy link
Member Author

eps1lon commented Feb 21, 2020

Maybe we should force the shrink state?

I'm favoring separating adornments and affixes. They are already described in guidelines. Forcing the alignment would look weird if your adornment is button-like (see password show/hide toggle).

@eps1lon eps1lon added the new feature New feature or request label Feb 21, 2020
@Floriferous
Copy link
Contributor

Could this be the right place to consider changing the adornment API?

Right now you always have to pass the <InputAdornment /> to your inputs, as is proposed with <InputSuffix />. Could we instead simply pass the content, and use another prop to customize the component if needed?

<TextField
  startAdornment={<Icon />}
  endAdornment="€"
  StartAdornmentComponent={SomeOtherAdornmentComponent}
  EndAdornmentComponent={SomeOtherAdornmentComponent} 
/>

This would make the adornment and pre-suffixes simpler to use for almost all use cases. (On that note, it might be interesting to see some custom adornment demos in the docs, without InputAdornment, I fail to see the use-case for now)

@eps1lon
Copy link
Member Author

eps1lon commented Apr 14, 2020

<TextField
  startAdornment={<Icon />}
  endAdornment="€"
  StartAdornmentComponent={SomeOtherAdornmentComponent}
  EndAdornmentComponent={SomeOtherAdornmentComponent} 
/>

This is generally an API that I don't find useful. Where would props for SomeOtherAdornmentComponent go? Is stardAdornment the children of SomeOtherAdornmentComponent? How does this look if you pass in more props: Is it still obivous which props belong together?

This would make the adornment and pre-suffixes simpler to use for almost all use cases.

What do you mean by "simpler"? I don't see how

-<TextField startAdornment={<SomeOtherAdornmentComponent><Icon /></SomeOtherAdornmentComponent>} />
+<TextField startAdornment={<Icon />} StartAdornmentComponent {SomeOtherAdornmentComponent} />

is simpler.

@Floriferous
Copy link
Contributor

Floriferous commented Apr 14, 2020

It is simpler because StartAdornmentComponent and EndAdornmentComponent would have a defaultvalue of InputAdornment.

I agree, passing props inside of those components is a bit messy, as you have to either merge children inside of it, or add another prop to pass props into that component. Or you can turn the prop into a function, and completely invert control, as needed:

// 99% of use-cases
<TextField
  startAdornment="€"
/>

// Special use-cases
<TextField
  startAdornment="€"
  // Optional prop
  renderStartAdornment={content => <SomeOtherAdornmentComponent myChildProp={content} type="start" />}
/>

The point is, for the few times I need to use adornments, I always have to look back at the docs, to find the perfect combination of props, components and content I need to make it look normal. I wish I could simply give material-ui my content, and let it figure out as much as possible which combo of low-level components it should use. You should always be able to customize it, but the TextField component can and should take care of the general use case imho:

// Batteries included!
<TextField
  value={amount}
  onChange={setAmount}
  label="Cost"
  startAdornment="€"
/>

EDIT: Be more clear about benefits

@etothepii
Copy link

etothepii commented Jul 28, 2023

I have noticed that the position attribute on the InputAdornment allows one to achieve the stated objective.

position=start lines the adornment up with the text (below the label) and position=end lines the adornment up with the field itself. Perhaps because of the nomenclature it wasn't obvious to test this but if one uses.

<TextField
  label="value"
  InputProps={{
    endAdornment: <InputAdornment position="start">days</InputAdornment>
  }}
  type="text"
  variant="filled"
/>

They will get the desired output.

I have put this in code sand box here

image

@siriwatknp
Copy link
Member

siriwatknp commented Dec 12, 2024

This can be achieve with som custom styles. Adding a demo to demonstrate how to customize seems to be the best option so far.

Copy link

This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue.
Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: text field This is the name of the generic UI component, not the React module! new feature New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants