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

feat(text-input): add password visibility toggle for text fields #1060

Merged

Conversation

emyarod
Copy link
Member

@emyarod emyarod commented Sep 4, 2018

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

  • password visibility toggle button
  • [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 passwords
  • examples text fields with password visibility toggle in documentation

Changed

  • existing documentation examples styling

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

<div class="bx--form-item" data-text-input>
  <label for="text-input-3" class="bx--label">Text Input label</label>
  <input
    id="text-input-3"
    type="password"
    class="bx--text-input"
    placeholder="Optional placeholder text"
    data-toggle-password-visibility
  >
  <button class="bx--text-input--password__visibility">
    <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>
  </button>
</div>

@emyarod emyarod force-pushed the toggle-password-visibility branch from 83a1a0d to cb3fae9 Compare September 4, 2018 19:58
@emyarod emyarod force-pushed the toggle-password-visibility branch 3 times, most recently from 78cca1a to b179020 Compare September 6, 2018 16:42
@emyarod emyarod changed the title [WIP] feat(text-input): add password visibility toggle for text fields feat(text-input): add password visibility toggle for text fields Sep 6, 2018
@emyarod emyarod changed the title feat(text-input): add password visibility toggle for text fields [WIP] feat(text-input): add password visibility toggle for text fields Sep 6, 2018
@alisonjoseph
Copy link
Member

@IBM/carbon-designers @IBM/carbon-developers

@emyarod emyarod force-pushed the toggle-password-visibility branch from 9d2fe7a to 2fa48ab Compare September 6, 2018 18:46
@designertyler
Copy link
Contributor

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.

@emyarod
Copy link
Member Author

emyarod commented Sep 6, 2018

Thanks for the clarification @designertyler! I have updated my PR to reflect this

Copy link
Contributor

@asudoh asudoh left a 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>';
Copy link
Contributor

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?

Copy link
Member Author

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

Copy link
Contributor

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()},
Copy link
Contributor

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">
Copy link
Contributor

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? 🤔

Copy link
Member Author

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?

Copy link
Contributor

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.

@emyarod emyarod force-pushed the toggle-password-visibility branch 2 times, most recently from ee1db7f to 6a594bc Compare September 7, 2018 19:35
@claycrenshaw
Copy link
Contributor

@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.

@designertyler
Copy link
Contributor

designertyler commented Sep 7, 2018

@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.

@emyarod
Copy link
Member Author

emyarod commented Sep 7, 2018

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

kapture 2018-09-07 at 15 10 33

kapture 2018-09-07 at 15 05 17

@emyarod emyarod force-pushed the toggle-password-visibility branch from 6a594bc to 811f69c Compare September 7, 2018 20:58
@chrisconnors-ibm
Copy link
Contributor

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:

  • slash eye = hide
  • open eye = show

so the hide command only makes sense when the password value is visible;
the show command only makes sense when the password value is hidden.

And yes, Material has this backwards. Let's not perpetuate their mistakes.

@emyarod
Copy link
Member Author

emyarod commented Sep 7, 2018

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?

kapture 2018-09-07 at 16 56 44

Copy link
Contributor

@asudoh asudoh left a 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'] {
Copy link
Contributor

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]?

Copy link
Member Author

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');
Copy link
Contributor

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.

@emyarod emyarod force-pushed the toggle-password-visibility branch from 0974fda to de3c3fc Compare September 11, 2018 13:56
Copy link
Contributor

@asudoh asudoh left a 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.

@emyarod emyarod force-pushed the toggle-password-visibility branch from de3c3fc to e927794 Compare September 11, 2018 19:53
@emyarod
Copy link
Member Author

emyarod commented Sep 11, 2018

@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?

@asudoh
Copy link
Contributor

asudoh commented Sep 12, 2018

@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!

@emyarod emyarod force-pushed the toggle-password-visibility branch 2 times, most recently from dfd3c33 to d43d04f Compare September 12, 2018 20:24
@emyarod
Copy link
Member Author

emyarod commented Sep 12, 2018

thanks for your help @asudoh! this PR can be viewed at this link: https://carbon-dev-environment-relaxed-roan.mybluemix.net/demo/text-input

@emyarod emyarod force-pushed the toggle-password-visibility branch from 1ae2d57 to 8ea8579 Compare September 19, 2018 20:31
Copy link
Contributor

@asudoh asudoh left a 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!

@alisonjoseph alisonjoseph merged commit 57257f2 into carbon-design-system:master Sep 20, 2018
@carbon-bot
Copy link
Contributor

🎉 This PR is included in version 9.17.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants