-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
feat(text-input): add password visibility toggle for text fields #1060
feat(text-input): add password visibility toggle for text fields #1060
Conversation
83a1a0d
to
cb3fae9
Compare
78cca1a
to
b179020
Compare
@IBM/carbon-designers @IBM/carbon-developers |
9d2fe7a
to
2fa48ab
Compare
Hi @emyarod A toggle should indicate the state rather than the action it will take. Similar to our toggle switches. When the password is hidden there is a slash though the eye. When the password is visible there should not be a slash. |
Thanks for the clarification @designertyler! I have updated my PR to reflect this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for bringing up an idea and great to see almost 💯 JS code @emyarod!
_toggle({ element, button }) { | ||
/* eslint-disable max-len */ | ||
const iconVisibilityOff = | ||
'<svg width="16" height="11" viewBox="0 0 16 11"><path d="M8 7.5c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 1c-1.7 0-3-1.3-3-3s1.3-3 3-3 3 1.3 3 3-1.3 3-3 3z"></path><path d="M8 10c2.8 0 5.1-1.5 6.9-4.6C13.1 2.5 10.8 1 8 1 5.2 1 3 2.4 1.2 5.4 2.9 8.6 5.2 10 8 10zM8 0c3.3 0 6 1.8 8.1 5.4C14 9.2 11.3 11 8 11S2 9.2 0 5.5C2 1.9 4.6 0 8 0z"></path></svg>'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we toggle hidden
attribute for those icons instead of changing HTML here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asudoh I've added another class method setIconVisibility
to handle changing the display
attribute rather than changing the markup. Let me know what you think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good try @emyarod! .style.x
causes usage of inline style (something we avoid) though - So we need to seek for an alternate approach like hidden
attribute.
* The component options. | ||
* | ||
* If `options` is specified in the constructor, | ||
* {@linkcode NumberInput.create .create()}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's search NumberInput
refs in this file and replace them with TextInput
.
</div> | ||
|
||
<div class="bx--form-item"> | ||
<div data-text-input class="bx--form-item"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: Do we want to prevent TextInput
JS class from being instantiated for non-password text inputs? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the [data-text-input]
on div.bx--form-item
in order to differentiate text inputs from other components that are also wrapped with div.bx--form-item
. Some of those components like Checkbox
and ComboBox
also have identifying classes on that div like .bx--combo-box
or .bx--checkbox-wrapper
, but other components like DatePicker
or TextInput
do not.
My thinking was that it might be convenient for users that want to select the TextInput div.bx--form-item
, but in retrospect it might be better to use something like .bx--text-input-wrapper
rather than a data attribute. And if we do add a wrapper class, then I think we should prevent TextInput
JS class from being instantiated for non-password text inputs. So a password text input would be div.bx--form-item[data-text-input]
while a non-password text input would be div.bx--form-item.bx--text-input-wrapper
. What do you think @asudoh?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@emyarod Thank you for putting your thoughts on this! I think it makes sense.
ee1db7f
to
6a594bc
Compare
@emyarod @designertyler I'm not so sure about this call on the show/hide password icon. This article touches on the topic: https://ux.stackexchange.com/questions/54162/icon-for-unmasking-passwords-open-or-closed-to-begin-with. I agree with the consensus there that since this is an action (show or hide password), that the icon should represent the result of the action, and not the current state. |
@claycrenshaw In our case the show/hide toggle is an option to change the state of the password field and the action is to log in or cancel. In that example shuffle/linear is an option to change the state of playback and play or pause is the action to stop or start music. In both cases the option (eye/shuffle) should show the active state and the action (play/log in) should show what action will happen. edit I think the stack overflow logic is correct, but they mistakingly call the eye toggle an action. |
so just to be clear: the password visibility button behavior is analogous to a checkbox, right? (in that the current state of the component is shown, as opposed to the result of clicking on the component being shown) I've currently implemented it according to @designertyler's previous description, but this is an interesting topic to discuss. I will note, though, that the pattern described can also be seen in Material Design 2.0 login forms |
6a594bc
to
811f69c
Compare
It's not a label; the state hidden or visible is self evident by the value displayed, either the password or ••••••••••••• it's a command - two commands, actually:
so the hide command only makes sense when the password value is visible; And yes, Material has this backwards. Let's not perpetuate their mistakes. |
thank you for the feedback @chrisconnors-ibm! Alright in that case then, my original implementation as shown in the GIF below would be the direction we want to proceed with, is that correct? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting there in code wise - Great to have a movie of the demo here so our designers can give this a final green light - Thanks @emyarod!
@@ -74,6 +73,35 @@ | |||
display: none; | |||
} | |||
} | |||
|
|||
&-wrapper svg[hidden='true'] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The existence hidden
attribute should be treated as hidden - So can we do: svg[hidden]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, I have refactored it so that it will remove the hidden
attribute entirely when we want to show the icon
I was initially selecting svg[hidden="true"]
here because I was toggling between hidden="true"
and hidden="false"
, but now I can select svg[hidden]
since the attribute will either be set or removed
// toggle action must come before querying the classList | ||
element.classList.toggle(this.options.passwordIsVisible); | ||
const passwordIsVisible = element.classList.contains(this.options.passwordIsVisible); | ||
const iconVisibilityOn = button.querySelector('svg.icon--visibility-on'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let’s put those selector in options
list.
0974fda
to
de3c3fc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @emyarod for your quick changes! LGTM 👍 from code wise. Please make sure sharing your work with our designers (e.g. by putting a movie in this PR or running gulp build:dev --rollup -e; cf push
in your project directory) so they can sign this off.
de3c3fc
to
e927794
Compare
@asudoh I'm not familiar with deploying to cloudfoundry, but I do have a GIF of the latest component behavior here, if that works: Are there any instructions or guides for pushing to cf? Also, is there anything I should modify with regards to the two remaining topics at the end of the PR description? |
@emyarod If you are familiar with CF, here's everything you need: gulp build:dev --rollup -e
cf login ...
cf push Ping me if it doesn't work for you and I can help you out! |
dfd3c33
to
d43d04f
Compare
thanks for your help @asudoh! this PR can be viewed at this link: https://carbon-dev-environment-relaxed-roan.mybluemix.net/demo/text-input |
fix(text-input): revert behavior of visibility icon on click
1ae2d57
to
8ea8579
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signing off, thanks @emyarod for your hard work on this and everybody for reviewing! Anybody don't hesitate to speak up in case I missed any pending discussions - Thanks!
🎉 This PR is included in version 9.17.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
…n-system#1060) * feat(Checkbox): add `title` attribute to checkbox label * fix(Checkbox): avoid empty title attribute
Closes #1058
This PR will add classes and logic to support toggling password visibility for text fields. Adding this feature will lay the groundwork for extending the React component as well (https://github.com/IBM/carbon-components-react/issues/1033)
Changelog
New
[data-text-input]
attribute to find password text input form groups.bx--text-input[data-toggle-password-visibility]
selector to find the password input field.bx--text-input--password__visibility
selector to find the password visibility toggle button.bx--text-input--password-visible
selector for text fields with visible passwordsChanged
Testing / Reviewing
In a password field, enter some text in the text field and click the visibility toggle button to see changes. Examples can also be found in the documentation