Skip to content

bug: aria-label/label cause undesired changes on ionic components #27236

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

Closed
3 tasks done
Wasenshi123 opened this issue Apr 19, 2023 · 21 comments
Closed
3 tasks done

bug: aria-label/label cause undesired changes on ionic components #27236

Wasenshi123 opened this issue Apr 19, 2023 · 21 comments
Labels

Comments

@Wasenshi123
Copy link

Wasenshi123 commented Apr 19, 2023

Prerequisites

Ionic Framework Version

v7.x

Current Behavior

When I upgraded to ionic 7, I noticed the warning in console about aria-label or label needed on various component (mainly, ion-input, ion-select, ion-textarea).

I have my own layout structure for look & responsive purpose, so I cannot just use "label" property. Thus, I tried to add aria-label instead.

But I found out that, after I added aria-label (or label property for that matter), the look and behavior of those components got changed.

namely:

  • all: line is not highlighted anymore( when the component got focus)
  • ion-input: placeholder gets shown all the time (previously, will only be shown when the component gets focus)
  • ion-select: the arrow of the select box is not at the end of component and no transition animation
  • ion-select: Header in alert interface is not shown anymore

Those structure and issues have been demonstrated here:
https://stackblitz.com/edit/3we1ad-cymjmo?file=index.html

Expected Behavior

The behavior and appearance of ion-input/ion-select/ion-textarea should not be altered after adding aria-label or label property.

Steps to Reproduce

  1. Wrap ion-input or ion-select or ion-textarea in ion-item
  2. Add aria-label or label property
  3. Behavior get altered

Code Reproduction URL

https://stackblitz.com/edit/3we1ad-cymjmo?file=index.html

Ionic Info

Ionic:

Ionic CLI : 7.0.1 (C:\Users\User\AppData\Roaming\npm\node_modules@ionic\cli)
Ionic Framework : @ionic/angular 7.0.1
@angular-devkit/build-angular : 15.2.5
@angular-devkit/schematics : 10.1.7
@angular/cli : 15.2.5
@ionic/angular-toolkit : 9.0.0

Capacitor:

Capacitor CLI : 4.7.3
@capacitor/android : 4.7.3
@capacitor/core : 4.7.3
@capacitor/ios : 4.7.3

Utility:

cordova-res : not installed globally
native-run : 1.7.2

System:

NodeJS : v16.18.0 (C:\Program Files\nodejs\node.exe)
npm : 8.19.2
OS : Windows 10

Additional Information

No response

@ionitron-bot ionitron-bot bot added the triage label Apr 19, 2023
@liamdebeasi liamdebeasi self-assigned this Apr 19, 2023
@liamdebeasi
Copy link
Contributor

liamdebeasi commented Apr 19, 2023

Thanks for the report. There are a few issues here:

  1. Inputs do not receive the blue highlight line.
    Inputs inside of ion-item no longer receive the blue highlight. This was done to match the Material Design spec. Inputs used outside of ion-item continue to receive the blue highlight.

  2. Placeholder is always show on the input
    This is happening because you did not migrate your input correctly. The warning states that you should use the label property on ion-input for visible text and remove ion-label. However, you used aria-label which should be used if you do not have visible text. When migrating to the new syntax, ion-input ignores the ion-label which is why the unexpected behavior is happening.

Here is the correct syntax:

<ion-input label="Name" label-placement="floating"></ion-input>

(I omitted the other attributes for brevity)

  1. Select is not sized correctly.

This is the same issue as 2 but with ion-select. Here is the correct syntax:

<ion-select label="Gender" label-placement="floating">...</ion-select>
  1. Header is not shown in select alert.

Making the changes in step 3 fixes the issue.

@liamdebeasi
Copy link
Contributor

Our documentation also has more examples on how to migrate: https://ionicframework.com/docs/api/input#migrating-from-legacy-input-syntax

@liamdebeasi liamdebeasi added the needs: reply the issue needs a response from the user label Apr 19, 2023
@liamdebeasi liamdebeasi removed their assignment Apr 19, 2023
@ionitron-bot ionitron-bot bot removed the triage label Apr 19, 2023
@Wasenshi123
Copy link
Author

Wasenshi123 commented Apr 19, 2023

If you expand the window you will see that I have another set of labels on the other ion-cols for wider screen.

How can I make your solution applied to this case?

(And also, note that the labels have red '*' to indicate for user that it's required, how can I apply that to 'label' property?)

@ionitron-bot ionitron-bot bot added triage and removed needs: reply the issue needs a response from the user labels Apr 19, 2023
@Wasenshi123
Copy link
Author

Here I tried your solution: https://stackblitz.com/edit/3we1ad-ox58un?file=index.html

You can see that it still does not solve my problem entirely.

When size of window is more than sm, the labels will be doubled.

And the red '*' cannot be shown on those built-in label from 'label' property.

@liamdebeasi
Copy link
Contributor

If you expand the window you will see that I have another set of labels on the other ion-cols for wider screen.

This isn't something you should be doing. The reason is that screen readers (like VoiceOver and TalkBack) are unable to associate the label with the form control which makes for a confusing experience for people who are using assistive technology.

It looks like what you are trying to do is make sure the labels/inputs are all lined up consistently. In that case, I recommend using label-placement="fixed" which gives labels a fixed width.

(And also, note that the labels have red '*' to indicate for user that it's required, how can I apply that to 'label' property

Inputs don't have support for custom HTML at the moment, but you can do something like this:

ion-input.custom-input .label-text::after {
  content: "*";
  color: red;
}

@liamdebeasi liamdebeasi added the needs: reply the issue needs a response from the user label Apr 19, 2023
@ionitron-bot ionitron-bot bot removed the triage label Apr 19, 2023
@Wasenshi123
Copy link
Author

It looks like what you are trying to do is make sure the labels/inputs are all lined up consistently. In that case, I recommend using label-placement="fixed" which gives labels a fixed width.

Yes, partly, but not just that. I also want to make it floating when the screen is smaller to make it more user friendly and responsive.

Inputs don't have support for custom HTML at the moment, but you can do something like this:

how to apply this to ion-select too?

I tried it here, but you can see the ion-select is not receiving that: https://stackblitz.com/edit/3we1ad-kzmne4?file=index.html

@ionitron-bot ionitron-bot bot added triage and removed needs: reply the issue needs a response from the user labels Apr 19, 2023
@liamdebeasi
Copy link
Contributor

Yes, partly, but not just that. I also want to make it floating when the screen is smaller to make it more user friendly and responsive.

You can update the label-placement property when the screen resizes. The property is reactive, so the component should update.

how to apply this to ion-select too?

You can't apply this to ion-select since it uses the Shadow DOM. However, we have a feature request open to support custom HTML labels with select: #26838

@liamdebeasi liamdebeasi added the needs: reply the issue needs a response from the user label Apr 19, 2023
@ionitron-bot ionitron-bot bot removed the triage label Apr 19, 2023
@Wasenshi123
Copy link
Author

Yes, partly, but not just that. I also want to make it floating when the screen is smaller to make it more user friendly and responsive.

You can update the label-placement property when the screen resizes. The property is reactive, so the component should update.

how to apply this to ion-select too?

You can't apply this to ion-select since it uses the Shadow DOM. However, we have a feature request open to support custom HTML labels with select: #26838

Okay, that feature request seems to be what I need. Does ion-input has this feature request as well?

And a quote from that thread:

Fundamentally I think the root issue I'm having is that the ion-item interaction with form components is feeling far too "magical".

That problem is why we are doing this form control migration. Form controls have several "magical" behaviors when used inside of ion-item that caused a myriad of issues in the past.

We plan on adding support for a label slot to ion-select in an upcoming minor release.

Are you implying that we shouldn't use ion-item wrapping each form control anymore?

@ionitron-bot ionitron-bot bot added triage and removed needs: reply the issue needs a response from the user labels Apr 19, 2023
@liamdebeasi
Copy link
Contributor

Okay, that feature request seems to be what I need. Does ion-input has this feature request as well?

It does not. ion-input and ion-textarea do not support Shadow DOM, so they can't support custom HTML at the moment. We do plan on migrating to Shadow DOM in the future though.

Are you implying that we shouldn't use ion-item wrapping each form control anymore?

No. The change we made in Ionic 7 was to remove the requirement that developers must use ion-item in order to get functional form components. You can absolutely continue to use ion-item with form controls. However, ion-item should only be used in list views. Form controls should be usable outside of list views, so forcing developers to use ion-item was overly restrictive.

@Wasenshi123
Copy link
Author

Wasenshi123 commented Apr 19, 2023

Okay, that feature request seems to be what I need. Does ion-input has this feature request as well?

It does not. ion-input and ion-textarea do not support Shadow DOM, so they can't support custom HTML at the moment. We do plan on migrating to Shadow DOM in the future though.

Are you implying that we shouldn't use ion-item wrapping each form control anymore?

No. The change we made in Ionic 7 was to remove the requirement that developers must use ion-item in order to get functional form components. You can absolutely continue to use ion-item with form controls. However, ion-item should only be used in list views. Form controls should be usable outside of list views, so forcing developers to use ion-item was overly restrictive.

Oh, okay. I think that's fair enough. I would rather not use ion-item if it's not necessary.

But I do like to keep the 'grey line' (when idle, no focus) on each form control like the original I have shown. (it resemble the underline for user to fill in like in paper form)

And the ripple effect is what I find interesting for those form control under ion-item which I would like to keep also. (as you can see, I customized the css for those)

Do you have any suggestion to achieve that without ion-item wrapping each form control ?

@liamdebeasi
Copy link
Contributor

For the gray line you could add a border-bottom:

ion-input {
  border-bottom: 1px solid #aaa;
}

It might be interesting to have this "underline" behavior as a built-in feature for ion-input and ion-textarea. You could also try creating a feature request, and I'd be happy to discuss this with the team.

For the ripple effect, you can use ion-ripple-effect to add the ripple effect outside of ion-item:

<div class="ion-activatable wrapper">
  <ion-toggle>toggle</ion-toggle>
  <ion-ripple-effect></ion-ripple-effect>
</div>

Here are some examples: https://codepen.io/liamdebeasi/pen/rNqMQev

@liamdebeasi liamdebeasi added the needs: reply the issue needs a response from the user label Apr 19, 2023
@ionitron-bot ionitron-bot bot removed the triage label Apr 19, 2023
@lincolnthree
Copy link

@Wasenshi123 Does this address part of your issue? #26838 (comment) (see code in comment)

@ionitron-bot ionitron-bot bot added triage and removed needs: reply the issue needs a response from the user labels Apr 20, 2023
@Wasenshi123
Copy link
Author

Wasenshi123 commented Apr 20, 2023

@Wasenshi123 Does this address part of your issue? #26838 (comment) (see code in comment)

Thank you, I will have to try that. But I think the solution/workaround is too much of an extra code involved. So for the time being, I would rather wait for ionic update and your feature request and some other to come in. Only then I will start implement this whole new syntax.

Until then, I will keep using old structure and code for now. That's my current solution.

@liamdebeasi
Copy link
Contributor

liamdebeasi commented Apr 21, 2023

Thanks for the additional info. Sounds like there are a few requests:

1. An easy way of adding a bottom border on ion-input
This is tracked in #27239

2. A way to add the ripple effect to components when not used in ion-item
Our recommended solution is to use ion-ripple-effect directly. I provided a code sample in #27239.

3. A way to pass custom HTML to input and textarea
This is tracked in #27061.

I am going to close this in favor of #27239 and #27061, but let me know if you have questions.

@Wasenshi123
Copy link
Author

Wasenshi123 commented Apr 25, 2023

@liamdebeasi I have a few questions:

first, regarding how to apply this custom css inside a component for ionic-angular project

ion-input. custom-input .label-text::after {
  content: "*";
  color: red;
}

I try to set custom css for any child components of ion-input but seems like it doesn't work at all. (including .native-input, .label-text-wrapper, to name some)

second, do you know why Material says that there shouldn't be highlight for input used in item/list?

Inputs inside of ion-item no longer receive the blue highlight. This was done to match the Material Design spec. Inputs used outside of ion-item continue to receive the blue highlight.

And is it possible for me to have highlight for input inside ion-item? and should I? (I still have some form controls that need to be inside list/ion-item because it's a list apparently.)

@liamdebeasi
Copy link
Contributor

liamdebeasi commented Apr 25, 2023

I try to set custom css for any child components of ion-input but seems like it doesn't work at all. (including .native-input, .label-text-wrapper, to name some)

Your selector is incorrect. It should be ion-input.custom-input .label-text::after (note I removed the space between . and custom-input). If that still does not work, then I would check with browser dev tools to see if the styles are being overridden.

second, do you know why Material says that there shouldn't be highlight for input used in item/list?

The Material Design specification doesn't provide guidance as to why, but if you compare with stock Android apps you should see that inputs in a list do not receive the highlight (Such as the "Create Event" modal in Google Calendar)

And is it possible for me to have highlight for input inside ion-item? and should I? (I still have some form controls that need to be inside list/ion-item because it's a list apparently.)

ion-input does not use the Shadow DOM so you could probably add the styles yourself, though you should not do this if you want to align with the Material Design specification.

@Wasenshi123
Copy link
Author

Wasenshi123 commented Apr 25, 2023

https://github.com/Wasenshi123/Ionic7

Well, I have updated my code in this repo to showcase what I mean regarding custom css for ion-input.

The code is in home component. As you can see, it's like the css never existed.

@liamdebeasi
Copy link
Contributor

Your component has Angular's style encapsulation enabled, so your CSS is compiled to:

.required[_ngcontent-nhh-c86]   .label-text[_ngcontent-nhh-c86]::after {
  content: "*";
  color: red;
}

The .label-text element is inside ion-input and never receives that __ngcontent scoping so the CSS never matches. You can either disable style scoping or move this specific block of CSS to a global stylesheet such as global.scss

@Wasenshi123
Copy link
Author

I see, thank you. I guess I will move it to global.scss then..

When should I disable style scoping for a component? what is the best practice about this?

@liamdebeasi
Copy link
Contributor

Style scoping/view encapsulation is an Angular feature, so I recommend looking at their docs: https://angular.io/guide/view-encapsulation

@ionitron-bot
Copy link

ionitron-bot bot commented May 25, 2023

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators May 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants