parent
82ee1ed1e4
commit
5258149a34
@ -1,4 +1,5 @@
|
||||
import { Alert } from "./alert";
|
||||
import { Input } from "./input/input";
|
||||
import("./locale-picker").then(({ LocalePicker }) => {
|
||||
customElements.define("btrix-locale-picker", LocalePicker);
|
||||
});
|
||||
@ -19,3 +20,4 @@ import("./not-found").then(({ NotFound }) => {
|
||||
});
|
||||
|
||||
customElements.define("btrix-alert", Alert);
|
||||
customElements.define("btrix-input", Input);
|
||||
|
52
frontend/src/components/input/input.css
Normal file
52
frontend/src/components/input/input.css
Normal file
@ -0,0 +1,52 @@
|
||||
.sl-label {
|
||||
font-size: var(--sl-input-label-font-size-medium);
|
||||
margin-bottom: var(--sl-spacing-3x-small);
|
||||
}
|
||||
|
||||
.sl-input-wrapper {
|
||||
position: relative;
|
||||
font-size: var(--sl-input-font-size-medium);
|
||||
height: var(--sl-input-height-medium);
|
||||
}
|
||||
|
||||
.sl-input {
|
||||
width: 100%;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
min-width: 0;
|
||||
height: calc(
|
||||
var(--sl-input-height-medium) - var(--sl-input-border-width) * 2
|
||||
);
|
||||
color: var(--sl-input-color);
|
||||
background-color: var(--sl-input-background-color);
|
||||
border: solid var(--sl-input-border-width) var(--sl-input-border-color);
|
||||
border-radius: var(--sl-input-border-radius-medium);
|
||||
box-shadow: none;
|
||||
padding: var(--sl-input-spacing-medium);
|
||||
cursor: inherit;
|
||||
-webkit-appearance: none;
|
||||
transition: var(--sl-transition-fast) border,
|
||||
var(--sl-transition-fast) box-shadow,
|
||||
var(--sl-transition-fast) background-color;
|
||||
}
|
||||
|
||||
.sl-input:hover {
|
||||
border-color: var(--sl-input-border-color-hover);
|
||||
}
|
||||
|
||||
.sl-input:focus {
|
||||
border-color: var(--sl-input-border-color-focus);
|
||||
box-shadow: var(--sl-focus-ring);
|
||||
}
|
||||
|
||||
.sl-input:not(:only-child) {
|
||||
padding-right: calc(var(--sl-spacing-x-small) * 2 + 2em);
|
||||
}
|
||||
|
||||
.sl-input-icon-button {
|
||||
position: absolute;
|
||||
top: calc(var(--sl-input-border-width) + var(--sl-spacing-3x-small));
|
||||
right: 0;
|
||||
margin-right: var(--sl-spacing-x-small);
|
||||
}
|
81
frontend/src/components/input/input.ts
Normal file
81
frontend/src/components/input/input.ts
Normal file
@ -0,0 +1,81 @@
|
||||
import { html } from "lit";
|
||||
import { property, state } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import LiteElement from "../../utils/LiteElement";
|
||||
import "./input.css";
|
||||
|
||||
/**
|
||||
* Styled input element in the light DOM.
|
||||
* Use instead of `sl-input` when disabling shadow DOM is necessary
|
||||
* (e.g. for password manager autocomplete)
|
||||
* See https://github.com/ikreymer/browsertrix-cloud/issues/72
|
||||
* and https://github.com/shoelace-style/shoelace/issues/413
|
||||
*
|
||||
* Usage example:
|
||||
* ```ts
|
||||
* <btrix-input label="Email" name="email"></btrix-input>
|
||||
* ```
|
||||
*/
|
||||
export class Input extends LiteElement {
|
||||
@property()
|
||||
label?: string;
|
||||
|
||||
@property({ type: String })
|
||||
id: string = "";
|
||||
|
||||
@property({ type: String })
|
||||
name?: string;
|
||||
|
||||
@property({ type: String })
|
||||
type?: string;
|
||||
|
||||
@property({ type: String })
|
||||
placeholder?: string;
|
||||
|
||||
@property()
|
||||
autocomplete?: any;
|
||||
|
||||
@property()
|
||||
required?: any;
|
||||
|
||||
@property({ type: Boolean })
|
||||
togglePassword?: boolean;
|
||||
|
||||
@state()
|
||||
isPasswordVisible: boolean = false;
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="sl-label">
|
||||
<label for=${this.id}>${this.label}</label>
|
||||
</div>
|
||||
<div class="sl-input-wrapper">
|
||||
<input
|
||||
class="sl-input"
|
||||
id=${this.id}
|
||||
name=${ifDefined(this.name)}
|
||||
type=${this.type === "password" && this.isPasswordVisible
|
||||
? "text"
|
||||
: ifDefined(this.type as any)}
|
||||
autocomplete=${ifDefined(this.autocomplete)}
|
||||
placeholder=${ifDefined(this.placeholder)}
|
||||
?required=${Boolean(this.required)}
|
||||
/>
|
||||
${this.togglePassword
|
||||
? html`
|
||||
<sl-icon-button
|
||||
class="sl-input-icon-button"
|
||||
name=${this.isPasswordVisible ? "eye-slash" : "eye"}
|
||||
@click=${this.onTogglePassword}
|
||||
></sl-icon-button>
|
||||
`
|
||||
: ""}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private onTogglePassword() {
|
||||
this.isPasswordVisible = !this.isPasswordVisible;
|
||||
}
|
||||
}
|
@ -62,7 +62,7 @@ export class SignUpForm extends LiteElement {
|
||||
/>
|
||||
`
|
||||
: html`
|
||||
<sl-input
|
||||
<btrix-input
|
||||
id="email"
|
||||
name="email"
|
||||
type="email"
|
||||
@ -71,23 +71,23 @@ export class SignUpForm extends LiteElement {
|
||||
autocomplete="email"
|
||||
required
|
||||
>
|
||||
</sl-input>
|
||||
</btrix-input>
|
||||
`}
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
<sl-input
|
||||
<btrix-input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
label=${msg("Create a password")}
|
||||
autocomplete="new-password"
|
||||
toggle-password
|
||||
togglePassword
|
||||
required
|
||||
>
|
||||
</sl-input>
|
||||
</btrix-input>
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
<sl-input
|
||||
<btrix-input
|
||||
id="name"
|
||||
name="name"
|
||||
label=${msg("Your name")}
|
||||
@ -96,7 +96,7 @@ export class SignUpForm extends LiteElement {
|
||||
})}
|
||||
autocomplete="nickname"
|
||||
>
|
||||
</sl-input>
|
||||
</btrix-input>
|
||||
<p class="mt-2 text-sm text-gray-500">
|
||||
<span class="text-gray-400">${msg("(optional)")}</span> ${msg(
|
||||
"Your name will be visible to archive collaborators."
|
||||
|
@ -224,28 +224,43 @@ export class LogInPage extends LiteElement {
|
||||
}
|
||||
|
||||
return html`
|
||||
<style>
|
||||
input {
|
||||
transition: var(--sl-transition-fast) color,
|
||||
var(--sl-transition-fast) border,
|
||||
var(--sl-transition-fast) box-shadow,
|
||||
var(--sl-transition-fast) background-color;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
border-color: var(--sl-input-border-color-focus);
|
||||
box-shadow: var(--sl-focus-ring);
|
||||
outline: 0;
|
||||
}
|
||||
</style>
|
||||
<sl-form @sl-submit="${this.onSubmitLogIn}" aria-describedby="formError">
|
||||
<div class="mb-5">
|
||||
<sl-input
|
||||
<btrix-input
|
||||
id="email"
|
||||
name="username"
|
||||
label=${msg("Email")}
|
||||
type="email"
|
||||
label="${msg("Email")}"
|
||||
autocomplete="username"
|
||||
required
|
||||
>
|
||||
</sl-input>
|
||||
</btrix-input>
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
<sl-input
|
||||
<btrix-input
|
||||
id="password"
|
||||
name="password"
|
||||
label=${msg("Password")}
|
||||
type="password"
|
||||
label="${msg("Password")}"
|
||||
autocomplete="current-password"
|
||||
togglePassword
|
||||
required
|
||||
>
|
||||
</sl-input>
|
||||
</btrix-input>
|
||||
</div>
|
||||
|
||||
${formError}
|
||||
@ -280,14 +295,15 @@ export class LogInPage extends LiteElement {
|
||||
aria-describedby="formError"
|
||||
>
|
||||
<div class="mb-5">
|
||||
<sl-input
|
||||
<btrix-input
|
||||
id="email"
|
||||
name="email"
|
||||
type="email"
|
||||
label="${msg("Your email address")}"
|
||||
autocomplete="username"
|
||||
required
|
||||
>
|
||||
</sl-input>
|
||||
</btrix-input>
|
||||
</div>
|
||||
|
||||
${formError}
|
||||
|
@ -33,16 +33,16 @@ export class ResetPassword extends LiteElement {
|
||||
<div class="md:bg-white md:shadow-xl md:rounded-lg md:px-12 md:py-12">
|
||||
<sl-form @sl-submit="${this.onSubmit}" aria-describedby="formError">
|
||||
<div class="mb-5">
|
||||
<sl-input
|
||||
<btrix-input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
label="${msg("New password")}"
|
||||
autocomplete="new-password"
|
||||
toggle-password
|
||||
togglePassword
|
||||
required
|
||||
>
|
||||
</sl-input>
|
||||
</btrix-input>
|
||||
</div>
|
||||
|
||||
${formError}
|
||||
|
Loading…
Reference in New Issue
Block a user