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

Decide how we want the show/hide password component to be implemented #4512

Closed
1 task
Tracked by #4063
querkmachine opened this issue Nov 27, 2023 · 3 comments
Closed
1 task
Tracked by #4063
Assignees

Comments

@querkmachine
Copy link
Member

querkmachine commented Nov 27, 2023

There are a few different ways that we could implement the show/hide password toggle component (herein, just 'password component' for brevity) within the current structure of Frontend. Each method has pros, cons, and repercussions on how we manage other components and the documentation going forward.

Comparison of methods

On a high level, the choice is between an entirely new standalone component, new "hybrid" component that inherits existing components, or creating a variant of the existing text input component.

Standalone component

As a standalone component, it would reimplement some existing features where we need them to be significantly different—such as the password input itself—as well as providing unique wrapping elements and styles.

This gives the component the flexibility to diverge as much as it needs to, at the expense of duplicating some code that already exists.

However, this can also be beneficial, as it allows the password component to be more focused and intentional, rather than sharing parameters and features that the text input has that wouldn't make sense on a password toggle.

The duplication can be partially mitigated on the CSS front by importing the text input's styles, creating a stylistic dependency between them, which is something we already do elsewhere.

In terms of documentation, standalone components usually receive similarly standalone guidance in the Design System, linking to related guidance where necessary.

Existing standalone components in Frontend

  • Most components are standalone, which makes sense as most of them are distinct in function, code, and appearance.
  • The checkboxes and radios are functionally and stylistically alike enough that they could be the same component, but we've decided to keep them separate as it's ultimately easier to manage the duplication than to maintain and document them as a single thing.

"Hybrid" component

As a hybrid component, the component would directly use the text input (and, potentially, button) macros within itself, immediately inheriting the capabilities of each of them and combining them with new code and styles.

This reduces duplication within the Design System code at the expense of more tightly coupling these components to one another.

Whilst this theoretically reduces maintenance, by reducing duplication, it also adds a maintenance task as we would need to ensure that future updates to the text input and button components do not have an adverse effect on the password component.

There is a new form of duplication introduced in how developers interface with the component too, as we would need to 'forward' parameters from the password component down to the child components. In some cases we won't want this to happen, or we would want the default value of a parameter to be different to what the child component otherwise uses, which can create more complex logic.

We cannot currently do this perfectly. Nunjucks does not have a native filter for merging configuration objects and we cannot assume a service team has a way to implement their own (nor should we expect them to do so for the component to function). This means that solutions tend to either be a bit messy and/or limit what options a developer is able to change.

In terms of documentation, hybrid components also usually receive standalone guidance in the Design System, linking to the child components where necessary. There is an additional burden when documenting Nunjucks parameters, as not all parameters that exist on a child component may be accessible from the parent.

Existing "hybrid" components in Frontend

  • Many components are some degree of "hybrid". For example, most form control components inherit the (internal) label, hint and error components.
  • The most hybrid-y components we have are probably the character count and exit this page components, which respectively inherit and extend the textarea and button components for their primary functionality.

Variant of an existing component

As a variant of an existing component, the password component would be an integrated part of the existing text input component.

This means it would, as much as is possible, use the existing HTML, CSS and JavaScript of that component. The password toggle and associated JavaScript would likely be activated by a Nunjucks parameter or the presence of the data-module attribute.

This reduces duplication of code to the highest order, at the expense of making the code more complex and harder to work with going forward. It also necessitates more thorough testing, as there is now a larger combination of options that could potentially interfere with one another.

Being completely integrated with the text input means that all options are available and ungated. This provides the greatest flexibility for developers, but also means that they have the freedom to do things that are counter to the security and accessibility goals of the password component (e.g. setting a maxlength, pattern or inputmode that restricts what passwords a user can enter).

Documentation would be similarly integrated into the existing text input component's guidance. This can be beneficial—in that much of the guidance for text inputs is also true of password inputs—but also means that password-specific guidance can be harder to locate.

Existing component variants in frontend

  • The summary list's card interface is a good example of new styles and functionality being introduced according to what Nunjucks parameters are provided.
  • The button component partially does this with JS, as some JavaScript exists only to support links that visually appear as buttons.

Done when

  • We've decided which of these approaches we want to take and consulted with the working group
@stevenjmesser
Copy link

@querkmachine, thanks for writing this, it's helpful to have the detail. However, which option would you propose we take and why? For example, pick which option you think seems most sensible and explain the trade-offs. That'll help start a quick discussion.

We have pattern guidance on passwords which would probably reference the show/hide password component, though you and @Ciandelle will need to check any guidance that @calvin-lau-sig7 and @CharlotteDowns have prepared re. Accessible Authentication. They might be able to offer thoughts on where the guidance might best sit.

@querkmachine
Copy link
Member Author

querkmachine commented Dec 5, 2023

@stevenjmesser I didn't want to potentially influence others' decision-making. 😅

I did have a short discussion with @andysellick on Slack where we determined that the variant approach might be more difficult to implement in GOV.UK's context—or, at least, result in loading password-related JS for every text input, which is undesirable. That is likely to be true in other services too.

We have some issues with the existing 'hybrid' ones that we cannot easily resolve. Many of our open character count issues are about being unable to configure things in certain ways or certain text and elements being hardcoded, for example, which are often because we cannot easily merge or change the configuration of the child textarea.

So my preference would be to build it as a standalone component. It's some code and guidance duplication, but like the radios and checkboxes example, I think it's a manageably small amount of duplication.

@owenatgov
Copy link
Contributor

owenatgov commented Dec 18, 2023

Following an internal chat, we've decided that for now we're going to pick the standalone approach. @querkmachine has outlined the concerns about hybrid in its comment above. Hybrid would be idea to avoid code duplication and we've discussed mitigations however there are a few minor lingering concerns:

  1. We can avoid blocking text input attributes if this becomes a necessity by adding attributes to the text input API, however there's a risk that this could mean we have a massive API for a single component due to specific internal needs
  2. The text input also includes a label, a hint and an error message which means we have limited control over these components if we discover we need it.

Something that was discussed was creating a "publicly undocumented" flat input component which just includes an input element, which would give us more freedom for reuse between the text input and this. I'll be making an issue to explore this soon.

We can revisit this as we progress this work and refine specific needs. For now we've explored this and are happy to move forward.

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

No branches or pull requests

3 participants