Unable to apply custom formatting to ion-input

If the desired result is this:

image

I’m hitting dead-end trying to achieve this in Ionic. Obviously this is a very straight forward formatting task in vanilla css. But to force an ionic component to look the same appears to be undoable, without an extraordinary amount of effort…

Here’s where I am at so far. I realise it’s a mess as is but it serves to illustrate the approach. By now, I’ve tried so many things by now and gotten close but then pulled it down again in disgust at how ridiculously complex the code got.

The specific issues are:

  1. Can’t control the height of the ion-input element.
  2. Can’t find a satisfactory way to align / offset vertical the input text (moving the units is easy - it’s in a div I can access directly).

image

with this code:

<ion-item
  [ngClass]="classes"
  class="monkey-ion-item"
  lines="none">

  <!-- Label Text -->
  <span class="label-span"> {{ label }} </span>

  <!-- User Input -->
  <ion-input
    #ionInputEl
    [value]="inputModel"
    (ionInput)="onInput($event)"
    (ionBlur)="onBlur()"
    class="monkey-ion-input right-aligned"
  >

    <!-- Label -->
    <div slot="label" class="monkey-input-label">{{ units }}</div>

  </ion-input>

</ion-item>

And this scss:

/** Main Styles */
.monkey-ion-item {
  --padding-start: 0;
  --inner-padding-end: 0;

  // height: 42px;

  --background: transparent;

  width: 100%;
  display: flex;
  align-items: bottom;

  .label-span {
    @extend .text-medium;

    flex: 1;
    margin-right: 8px;
    white-space: nowrap;        // prevent wrapping
    overflow: hidden;           // handle overflow
    text-overflow: ellipsis;    // show ... when text is too long
  }


  .monkey-ion-input {
    @extend .text-medium;

    --background: transparent;
    max-width: 120px;
    transition: border-color 0.2s ease;

    border-bottom: 1px solid var(--dark-gray);  // Move the border to the container

    &:focus-within {  // Change border when input is focused
      border-bottom-color: var(--lines-and-text);
    }

    .monkey-input-label {
      color: var(--gray);
      transform: translateY(7px); // moves label (units) down
    }
  }
}

I made some progress using ::ng-deep and then hacking through the various elements. But it’s not an acceptable approach. I’m starting to think that I’m kind of wasting my time trying to adapt ionic components. Unless I’m missing something really obvious…

Does this get you closer? IonInput Custom Formatting with Suffix - StackBlitz

Sorry it’s Vue :upside_down_face:

I first tried with the end slot on IonInput to add the units but aligning was difficult to get exactly as you wanted.

1 Like

Hey @twestrick!

Gotta say, I’m super impressed with that. A few small changes, and it’s pretty much perfect in your stackblitz example.

When I went to implement it in my Angular component, there seem to be several important differences which are interesting…

  1. I had to change this code in order for it to apply. Appears that the structure of my ion-input is different to yours!? Or some subtle differences are affecting how the style gets applied.
.threshold-input {
  text-align: right;
  font-size: 20px;
  line-height: 24px;
  height: 22px;
}
  1. But while the font size etc worked, the height had no effect. After some intensive fiddling, I stumbled upon the fact that I could increase the height, but not decrease it. Which made me wonder whether there was a min-height applied somewhere in the guts of the component. So I tried adding min-height: 22px; and the height changed!!!

  2. This style makes no difference for me:

.threshold-input .native-wrapper {
  align-items: end;
}

Seems likely that also a result of different internal structure.

Conclusion
There appear to be some inconsistencies in the components I’m getting out of the box and what you are. I notice that you are at V8, whereas I’m still V7. Seems likely that this is relevant!

While I assume the documented CSS Custom Properties will (mostly) work, it seems that any styles that go into the component are likely to result in brittle code that will not survive a migration to a newer version of Ionic!

And the process of battling through these challenges is time consuming to the extreme!

1 Like

Oh, forgot to ask, do you know if there is a way to centre the text vertically inside the ion-input. I was able to adjust the location of the label (floating) by putting it in a div and using a transform with a fixed number of pixels. Which is so utterly horrible! But as for the text the user types in, I can’t figure out how to move it relative to it’s container?!

Glad that was helpful. Are you familiar with flexbox? If not, it’s amazing for alignment. Gone are the days of fixed pixel margins and whatever else to get elements aligned correctly. You should be able to use it for your label alignment.

I would guess there are differences between Ionic 7 & 8 as there were changes to input in v8. Here is my recommendation. Don’t be afraid to just roll your own input. You don’t always need to use Ionic components especially when you need something super custom like this. Trying to highly customize an Ionic component to fit your needs will create a maintenance headache like you said. The only downside is that you might lose the auto detection on the on-screen keyboard. But, you can easily handle it yourself - Keyboard Guide: Tools to Manage an On-Screen Mobile App Keyboard.

1 Like