зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1911121 - Create a LoginForm Component for Contextual Password Manager. r=fluent-reviewers,desktop-theme-reviewers,bolsson,hjones,issammani,ayeddi,dao,accessibility-frontend-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D218341
This commit is contained in:
Родитель
f8904f7f9b
Коммит
0815749aa8
|
@ -85,6 +85,9 @@ var gExceptionPaths = [
|
|||
|
||||
// Strip on Share parameter lists
|
||||
"chrome://global/content/antitracking/",
|
||||
|
||||
// CSS file is referenced inside JS in login-form.mjs
|
||||
"chrome://global/content/megalist/LoginFormComponent/",
|
||||
];
|
||||
|
||||
// These are not part of the omni.ja file, so we find them only when running
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
|
||||
:host {
|
||||
display: grid;
|
||||
grid-template-areas: "label label" "input actions";
|
||||
grid-template-areas: "label" "input" "explainer";
|
||||
grid-template-columns: minmax(0, auto) min-content;
|
||||
grid-gap: var(--space-small);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
@ -29,38 +30,23 @@ input.input-field {
|
|||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
appearance: textfield;
|
||||
grid-area: input;
|
||||
|
||||
& + .explainer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.reveal-password-button {
|
||||
grid-area: actions;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
min-width: 0;
|
||||
background: url("chrome://browser/content/aboutlogins/icons/password.svg") center no-repeat;
|
||||
grid-area: input;
|
||||
justify-self: end;
|
||||
cursor: pointer;
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
color: inherit;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.reveal-password-button.revealed {
|
||||
background-image: url("chrome://browser/content/aboutlogins/icons/password-hide.svg");
|
||||
.origin-input {
|
||||
grid-area: input;
|
||||
}
|
||||
|
||||
/** button.reveal-password-button needed to override --in-content-button-background-hover in common-shared.css **/
|
||||
button.reveal-password-button:hover {
|
||||
opacity: 0.6;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/** button.reveal-password-button needed to override --in-content-button-background-active in common-shared.css **/
|
||||
button.reveal-password-button:hover:active {
|
||||
opacity: 1;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
.explainer {
|
||||
grid-area: explainer;
|
||||
}
|
||||
|
|
|
@ -16,22 +16,28 @@ export const stylesTemplate = () =>
|
|||
export const editableFieldTemplate = ({
|
||||
type,
|
||||
value,
|
||||
inputId,
|
||||
disabled,
|
||||
onFocus,
|
||||
onBlur,
|
||||
labelL10nId,
|
||||
noteL10nId,
|
||||
}) =>
|
||||
html`
|
||||
<label for="input" class="field-label" data-l10n-id=${labelL10nId}> </label>
|
||||
<input
|
||||
id="input"
|
||||
class="input-field"
|
||||
data-l10n-id=${ifDefined(inputId)}
|
||||
type=${type}
|
||||
value=${value}
|
||||
aria-describedby="explainer"
|
||||
?disabled=${disabled}
|
||||
@focus=${onFocus}
|
||||
@blur=${onBlur}
|
||||
/>
|
||||
<div class="actions">
|
||||
<slot name="actions"></slot>
|
||||
</div>
|
||||
<span
|
||||
id="explainer"
|
||||
role="note"
|
||||
class="explainer text-deemphasized"
|
||||
data-l10n-id=${ifDefined(noteL10nId)}
|
||||
></span>
|
||||
`;
|
||||
|
|
|
@ -13,7 +13,14 @@ class LoginOriginField extends MozLitElement {
|
|||
|
||||
get readonlyTemplate() {
|
||||
return html`
|
||||
<label
|
||||
for="origin"
|
||||
class="field-label"
|
||||
data-l10n-id="login-item-origin-label"
|
||||
>
|
||||
</label>
|
||||
<a
|
||||
id="origin"
|
||||
class="origin-input"
|
||||
dir="auto"
|
||||
target="_blank"
|
||||
|
@ -29,12 +36,13 @@ class LoginOriginField extends MozLitElement {
|
|||
render() {
|
||||
return html`
|
||||
${stylesTemplate()}
|
||||
<label class="field-label" data-l10n-id="login-item-origin-label"></label>
|
||||
${this.readonly
|
||||
? this.readonlyTemplate
|
||||
: editableFieldTemplate({
|
||||
type: "url",
|
||||
value: this.value,
|
||||
labelL10nId: "login-item-origin-label",
|
||||
noteL10nId: "passwords-origin-tooltip",
|
||||
})}
|
||||
`;
|
||||
}
|
||||
|
|
|
@ -34,13 +34,15 @@ class LoginPasswordField extends MozLitElement {
|
|||
: this._value;
|
||||
}
|
||||
|
||||
#revealIconSrc(concealed) {
|
||||
return concealed
|
||||
? "chrome://browser/content/aboutlogins/icons/password-hide.svg"
|
||||
: "chrome://browser/content/aboutlogins/icons/password.svg";
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
${stylesTemplate()}
|
||||
<label
|
||||
class="field-label"
|
||||
data-l10n-id="login-item-password-label"
|
||||
></label>
|
||||
${editableFieldTemplate({
|
||||
type: this.#type,
|
||||
value: this.#password,
|
||||
|
@ -48,7 +50,18 @@ class LoginPasswordField extends MozLitElement {
|
|||
disabled: this.readonly,
|
||||
onFocus: this.handleFocus,
|
||||
onBlur: this.handleBlur,
|
||||
labelL10nId: "login-item-password-label",
|
||||
noteL10nId: "passwords-password-tooltip",
|
||||
})}
|
||||
<moz-button
|
||||
data-l10n-id=${this.visible
|
||||
? "login-item-password-conceal-checkbox"
|
||||
: "login-item-password-reveal-checkbox"}
|
||||
class="reveal-password-button"
|
||||
type="icon ghost"
|
||||
iconSrc=${this.#revealIconSrc(this.visible)}
|
||||
@click=${this.toggleVisibility}
|
||||
></moz-button>
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -69,7 +82,6 @@ class LoginPasswordField extends MozLitElement {
|
|||
if (this.visible) {
|
||||
this.onPasswordVisible?.();
|
||||
}
|
||||
this.input.focus();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,14 +14,12 @@ class LoginUsernameField extends MozLitElement {
|
|||
render() {
|
||||
return html`
|
||||
${stylesTemplate()}
|
||||
<label
|
||||
class="field-label"
|
||||
data-l10n-id="login-item-username-label"
|
||||
></label>
|
||||
${editableFieldTemplate({
|
||||
type: "text",
|
||||
value: this.value,
|
||||
disabled: this.readonly,
|
||||
labelL10nId: "login-item-username-label",
|
||||
noteL10nId: "passwords-username-tooltip",
|
||||
})}
|
||||
`;
|
||||
}
|
||||
|
|
|
@ -100,6 +100,13 @@ export async function insertFTLIfNeeded(fileName) {
|
|||
`browser/branding/nightly/locales/en-US/${rest}`
|
||||
);
|
||||
ftlContents = imported.default;
|
||||
} else if (root == "preview") {
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
let imported = await import(
|
||||
/* webpackInclude: /\.ftl$/ */
|
||||
`toolkit/components/satchel/megalist/content/${rest}`
|
||||
);
|
||||
ftlContents = imported.default;
|
||||
}
|
||||
|
||||
if (loadedResources.has(fileName)) {
|
||||
|
|
|
@ -27,6 +27,8 @@ module.exports = {
|
|||
`${projectRoot}/browser/components/backup/content/**/*.stories.mjs`,
|
||||
// Reader View components stories
|
||||
`${projectRoot}/toolkit/components/reader/**/*.stories.mjs`,
|
||||
// megalist components stories
|
||||
`${projectRoot}/toolkit/components/satchel/megalist/content/**/*.stories.mjs`,
|
||||
// Everything else
|
||||
"../stories/**/*.stories.@(js|jsx|mjs|ts|tsx|md)",
|
||||
// Design system files
|
||||
|
|
|
@ -115,6 +115,8 @@ login-item-copied-username-button-text = Copied!
|
|||
login-item-password-label = Password
|
||||
login-item-password-reveal-checkbox =
|
||||
.aria-label = Show password
|
||||
login-item-password-conceal-checkbox =
|
||||
.aria-label = Hide password
|
||||
login-item-copy-password-button-text = Copy
|
||||
login-item-copied-password-button-text = Copied!
|
||||
about-logins-login-item-save-changes-button = Save
|
||||
|
|
|
@ -8,3 +8,4 @@ toolkit.jar:
|
|||
content/global/megalist/MegalistAlpha.mjs (megalist/content/MegalistAlpha.mjs)
|
||||
content/global/megalist/PasswordCard.mjs (megalist/content/PasswordCard.mjs)
|
||||
content/global/megalist/Dialog.mjs (megalist/content/Dialog.mjs)
|
||||
content/global/megalist/LoginFormComponent/login-form.css (megalist/content/LoginFormComponent/login-form.css)
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
.delete-login-button-container {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* Add spacing between fieldset legend text and fields */
|
||||
login-origin-field {
|
||||
margin-block-start: var(--space-medium);
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { html, when } from "chrome://global/content/vendor/lit.all.mjs";
|
||||
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
|
||||
|
||||
/* eslint-disable-next-line import/no-unassigned-import, mozilla/no-browser-refs-in-toolkit */
|
||||
import "chrome://browser/content/aboutlogins/components/input-field/login-origin-field.mjs";
|
||||
/* eslint-disable-next-line import/no-unassigned-import, mozilla/no-browser-refs-in-toolkit */
|
||||
import "chrome://browser/content/aboutlogins/components/input-field/login-username-field.mjs";
|
||||
/* eslint-disable-next-line import/no-unassigned-import, mozilla/no-browser-refs-in-toolkit */
|
||||
import "chrome://browser/content/aboutlogins/components/input-field/login-password-field.mjs";
|
||||
|
||||
export class LoginForm extends MozLitElement {
|
||||
static properties = {
|
||||
type: { type: String, reflect: true },
|
||||
};
|
||||
|
||||
render() {
|
||||
const heading =
|
||||
this.type !== "edit" ? "passwords-create-label" : "passwords-edit-label";
|
||||
|
||||
return html`<link
|
||||
rel="stylesheet"
|
||||
href="chrome://global/content/megalist/LoginFormComponent/login-form.css"
|
||||
/>
|
||||
<moz-card>
|
||||
${when(
|
||||
this.type === "edit",
|
||||
() => html`
|
||||
<div class="delete-login-button-container">
|
||||
<moz-button
|
||||
class="delete-login-button"
|
||||
type="icon"
|
||||
iconSrc="chrome://global/skin/icons/delete.svg"
|
||||
></moz-button>
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
<form>
|
||||
<moz-fieldset data-l10n-id=${heading}>
|
||||
<login-origin-field></login-origin-field>
|
||||
<login-username-field></login-username-field>
|
||||
<login-password-field></login-password-field>
|
||||
<moz-button-group>
|
||||
<moz-button data-l10n-id="login-item-cancel-button"></moz-button>
|
||||
<moz-button
|
||||
data-l10n-id="login-item-save-new-button"
|
||||
type="primary"
|
||||
>
|
||||
</moz-button>
|
||||
</moz-button-group>
|
||||
</moz-fieldset>
|
||||
</form>
|
||||
</moz-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("login-form", LoginForm);
|
|
@ -0,0 +1,17 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import { html } from "lit.all.mjs";
|
||||
import "./login-form.mjs";
|
||||
|
||||
export default {
|
||||
title: "Domain-specific UI Widgets/Credential Management/Login Form",
|
||||
component: "login-form",
|
||||
};
|
||||
|
||||
window.MozXULElement.insertFTLIfNeeded("preview/megalist.ftl");
|
||||
|
||||
export const AddLoginForm = () => html`<login-form type="add"></login-form>`;
|
||||
export const EditLoginForm = () => html`<login-form type="edit"></login-form>`;
|
|
@ -146,6 +146,16 @@ passwords-radiobutton-all = All ({ $total })
|
|||
# $total (number) - Total number of alerts
|
||||
passwords-radiobutton-alerts = Alerts ({ $total })
|
||||
|
||||
## Login Form
|
||||
|
||||
passwords-create-label =
|
||||
.label = Add password
|
||||
passwords-edit-label =
|
||||
.label = Edit password
|
||||
passwords-origin-tooltip = Enter the exact address where you’ll sign in to this site.
|
||||
passwords-username-tooltip = Enter the username, email address, or account number you use to sign in.
|
||||
passwords-password-tooltip = Enter the password used to sign in to this account.
|
||||
|
||||
## Payments
|
||||
|
||||
payments-command-create = Add Payment Method
|
||||
|
|
Загрузка…
Ссылка в новой задаче