mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
docs: add signal forms playground template
(cherry picked from commit e0eb619c03)
This commit is contained in:
parent
c2c0140532
commit
ccb0264edb
3 changed files with 152 additions and 0 deletions
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"type": "editor-only",
|
||||
"title": "Signals forms template",
|
||||
"openFiles": ["src/main.ts", "src/main.css"]
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
max-width: 400px;
|
||||
padding: 1rem;
|
||||
font-family:
|
||||
Inter,
|
||||
system-ui,
|
||||
-apple-system,
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 0.5rem;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
font-size: 1rem;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: none;
|
||||
border-color: #4285f4;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0.75rem 1.5rem;
|
||||
background-color: #4285f4;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 1rem;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #357ae8;
|
||||
}
|
||||
|
||||
button:active {
|
||||
background-color: #2a65c8;
|
||||
}
|
||||
|
||||
.error-list {
|
||||
color: red;
|
||||
font-size: 0.875rem;
|
||||
margin: 0.25rem 0 0 0;
|
||||
padding-left: 0;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
.error-list p {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
import {bootstrapApplication} from '@angular/platform-browser';
|
||||
import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
|
||||
// @ts-ignore There's a known issue with type support in the playground editor for signal forms
|
||||
import {form, Field, required, email, debounce, submit} from '@angular/forms/signals';
|
||||
|
||||
interface LoginData {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
template: `
|
||||
<form (submit)="onSubmit($event)">
|
||||
<div>
|
||||
<label>
|
||||
Email:
|
||||
<input type="email" [field]="loginForm.email" />
|
||||
</label>
|
||||
|
||||
@if (loginForm.email().invalid()) {
|
||||
<ul class="error-list">
|
||||
@for (error of loginForm.email().errors(); track $index) {
|
||||
<li>{{ error.message }}</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
Password:
|
||||
<input type="password" [field]="loginForm.password" />
|
||||
</label>
|
||||
|
||||
@if (loginForm.password().invalid()) {
|
||||
<div class="error">
|
||||
@for (error of loginForm.password().errors(); track $index) {
|
||||
<p>{{ error.message }}</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<button type="submit">Log In</button>
|
||||
</form>
|
||||
`,
|
||||
styleUrl: 'main.css',
|
||||
imports: [Field],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class LoginApp {
|
||||
loginModel = signal<LoginData>({
|
||||
email: '',
|
||||
password: '',
|
||||
});
|
||||
|
||||
loginForm = form(this.loginModel, (schemaPath) => {
|
||||
debounce(schemaPath.email, 500);
|
||||
required(schemaPath.email, {message: 'Email is required'});
|
||||
email(schemaPath.email, {message: 'Enter a valid email address'});
|
||||
debounce(schemaPath.password, 500);
|
||||
required(schemaPath.password, {message: 'Password is required'});
|
||||
});
|
||||
|
||||
onSubmit(event: Event) {
|
||||
event.preventDefault();
|
||||
submit(this.loginForm, async () => {
|
||||
// Perform login logic here
|
||||
const credentials = this.loginModel();
|
||||
console.log('Logging in with:', credentials);
|
||||
// e.g., await this.authService.login(credentials);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bootstrapApplication(LoginApp);
|
||||
Loading…
Reference in a new issue