Skip to content

Commit 1a8ea0c

Browse files
committed
feature #1000 new TogglePassword component (feymo)
This PR was squashed before being merged into the 2.x branch. Discussion ---------- new TogglePassword component | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | Tickets | N/A | License | MIT Hello to the Symfony UX community ! This PR propose a new Symfony UX Component. The `TogglePassword` component allows users to switch visibility on password inputs through a dedicated button. Default style is provided and english language is used for labels but everything is customizable to fit projects requirements. Here are screenshots previews for the default rendering : <img width="312" alt="image" src="https://github.com/symfony/ux/assets/60115888/749c1614-407f-48c5-85ac-2a99fa63663d"> <img width="312" alt="image" src="https://github.com/symfony/ux/assets/60115888/9cf6af11-5943-44b7-bc36-3c0cbd811b4e"> Thanks you all in advance for your feedbacks and comments on the relevance of a component like this within Symfony UX ! 😄 _Edit:_ The TogglePassword component propose : - A `FormExtension` transforming any `PasswordType` field into a Toggle Password by adding the `toggle` option ; - A form theme with complete style, English labels and SVG icons for "toggable" password field "out of the box" ; - Translation support for both toggle labels (with `TranslatableMessage` object or translation key string with domain) and the option to disable translation ; - Customization for : labels, icons, classes for the toggle button element, and classes for the container element. Commits ------- b1bf8f0 new TogglePassword component
2 parents 3c13a1b + b1bf8f0 commit 1a8ea0c

25 files changed

+1093
-0
lines changed

src/TogglePassword/.gitattributes

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/.gitattributes export-ignore
2+
/.gitignore export-ignore
3+
/.symfony.bundle.yaml export-ignore
4+
/phpunit.xml.dist export-ignore
5+
/assets/src export-ignore
6+
/assets/test export-ignore
7+
/assets/jest.config.js export-ignore
8+
/tests export-ignore

src/TogglePassword/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vendor/
2+
composer.lock
3+
.phpunit.result.cache
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
branches: ["2.x"]
2+
maintained_branches: ["2.x"]
3+
doc_dir: "doc"

src/TogglePassword/LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2023-present Fabien Potencier
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

src/TogglePassword/README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Symfony UX TogglePassword
2+
3+
Symfony UX TogglePassword is a Symfony bundle providing visibility toggle for password inputs
4+
in Symfony Forms. It is part of [the Symfony UX initiative](https://symfony.com/ux).
5+
6+
It allows visitors to switch the type of password field to text and vice versa.
7+
8+
**This repository is a READ-ONLY sub-tree split**. See
9+
https://github.com/symfony/ux to create issues or submit pull requests.
10+
11+
## Sponsor
12+
13+
The Symfony UX packages are [backed][1] by [Mercure.rocks][2].
14+
15+
Create real-time experiences in minutes! Mercure.rocks provides a realtime API service
16+
that is tightly integrated with Symfony: create UIs that update in live with UX Turbo,
17+
send notifications with the Notifier component, expose async APIs with API Platform and
18+
create low level stuffs with the Mercure component. We maintain and scale the complex
19+
infrastructure for you!
20+
21+
Help Symfony by [sponsoring][3] its development!
22+
23+
## Resources
24+
25+
- [Documentation](https://symfony.com/bundles/ux-toggle-password/current/index.html)
26+
- [Report issues](https://github.com/symfony/ux/issues) and
27+
[send Pull Requests](https://github.com/symfony/ux/pulls)
28+
in the [main Symfony UX repository](https://github.com/symfony/ux)
29+
30+
[1]: https://symfony.com/backers
31+
[2]: https://mercure.rocks
32+
[3]: https://symfony.com/sponsor
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Controller } from '@hotwired/stimulus';
2+
export default class extends Controller<HTMLInputElement> {
3+
readonly visibleLabelValue: string;
4+
readonly visibleIconValue: string;
5+
readonly hiddenLabelValue: string;
6+
readonly hiddenIconValue: string;
7+
readonly buttonClassesValue: Array<string>;
8+
static values: {
9+
visibleLabel: StringConstructor;
10+
visibleIcon: StringConstructor;
11+
hiddenLabel: StringConstructor;
12+
hiddenIcon: StringConstructor;
13+
buttonClasses: ArrayConstructor;
14+
};
15+
isDisplayed: boolean;
16+
visibleIcon: string;
17+
hiddenIcon: string;
18+
connect(): void;
19+
private createButton;
20+
toggle(event: any): void;
21+
private dispatchEvent;
22+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { Controller } from '@hotwired/stimulus';
2+
3+
class default_1 extends Controller {
4+
constructor() {
5+
super(...arguments);
6+
this.isDisplayed = false;
7+
this.visibleIcon = `<svg xmlns="http://www.w3.org/2000/svg" class="toggle-password-icon" viewBox="0 0 20 20" fill="currentColor">
8+
<path d="M10 12a2 2 0 100-4 2 2 0 000 4z" />
9+
<path fill-rule="evenodd" d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clip-rule="evenodd" />
10+
</svg>`;
11+
this.hiddenIcon = `<svg xmlns="http://www.w3.org/2000/svg" class="toggle-password-icon" viewBox="0 0 20 20" fill="currentColor">
12+
<path fill-rule="evenodd" d="M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z" clip-rule="evenodd" />
13+
<path d="M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z" />
14+
</svg>`;
15+
}
16+
connect() {
17+
if (this.visibleIconValue !== 'Default') {
18+
this.visibleIcon = this.visibleIconValue;
19+
}
20+
if (this.hiddenIconValue !== 'Default') {
21+
this.hiddenIcon = this.hiddenIconValue;
22+
}
23+
const button = this.createButton();
24+
this.element.insertAdjacentElement('afterend', button);
25+
this.dispatchEvent('connect', { element: this.element, button: button });
26+
}
27+
createButton() {
28+
const button = document.createElement('button');
29+
button.type = 'button';
30+
button.classList.add(...this.buttonClassesValue);
31+
button.setAttribute('tabindex', '-1');
32+
button.addEventListener('click', this.toggle.bind(this));
33+
button.innerHTML = this.visibleIcon + ' ' + this.visibleLabelValue;
34+
return button;
35+
}
36+
toggle(event) {
37+
this.isDisplayed = !this.isDisplayed;
38+
const toggleButtonElement = event.currentTarget;
39+
toggleButtonElement.innerHTML = this.isDisplayed
40+
? this.hiddenIcon + ' ' + this.hiddenLabelValue
41+
: this.visibleIcon + ' ' + this.visibleLabelValue;
42+
this.element.setAttribute('type', this.isDisplayed ? 'text' : 'password');
43+
this.dispatchEvent(this.isDisplayed ? 'show' : 'hide', { element: this.element, button: toggleButtonElement });
44+
}
45+
dispatchEvent(name, payload) {
46+
this.dispatch(name, { detail: payload, prefix: 'toggle-password' });
47+
}
48+
}
49+
default_1.values = {
50+
visibleLabel: String,
51+
visibleIcon: String,
52+
hiddenLabel: String,
53+
hiddenIcon: String,
54+
buttonClasses: Array,
55+
};
56+
57+
export { default_1 as default };

src/TogglePassword/assets/dist/style.min.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('../../../jest.config.js');
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "@symfony/ux-toggle-password",
3+
"description": "Toggle visibility of password inputs for Symfony Forms",
4+
"license": "MIT",
5+
"version": "1.0.0",
6+
"main": "dist/controller.js",
7+
"types": "dist/controller.d.ts",
8+
"config": {
9+
"css_source": "src/style.css"
10+
},
11+
"symfony": {
12+
"controllers": {
13+
"toggle-password": {
14+
"main": "dist/controller.js",
15+
"fetch": "eager",
16+
"enabled": true,
17+
"autoimport": {
18+
"@symfony/ux-toggle-password/dist/style.min.css": true
19+
}
20+
}
21+
},
22+
"importmap": {
23+
"@hotwired/stimulus": "^3.0.0"
24+
}
25+
},
26+
"peerDependencies": {
27+
"@hotwired/stimulus": "^3.0.0"
28+
},
29+
"devDependencies": {
30+
"@hotwired/stimulus": "^3.0.0"
31+
}
32+
}

0 commit comments

Comments
 (0)