8000 docs: add signals code example recipe book · angular/angular@611eeb6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 611eeb6

Browse files
committed
docs: add signals code example recipe book
1 parent ed5062a commit 611eeb6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

109 files changed

+3511
-0
lines changed

adev/src/app/sub-navigation-data.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
101101
path: 'guide/signals/resource',
102102
contentPath: 'guide/signals/resource',
103103
},
104+
{
105+
label: 'Code Examples',
106+
path: 'guide/signals/code-examples',
107+
contentPath: 'guide/signals/code-examples',
108+
},
104109
],
105110
},
106111
{
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
:host {
2+
display: block;
3+
font-family: sans-serif;
4+
}
5+
6+
.container {
7+
background-color: #2c2c2c;
8+
color: #e0e0e0;
9+
padding: 24px;
10+
border-radius: 8px;
11+
max-width: 800px;
12+
margin: auto;
13+
}
14+
15+
h2 {
16+
margin-top: 0;
17+
font-size: 1.3em;
18+
color: #ffffff;
19+
}
20+
21+
p {
22+
color: #b0b0b0;
23+
font-size: 0.9em;
24+
line-height: 1.6;
25+
max-width: 90%;
26+
}
27+
28+
code {
29+
background-color: #444;
30+
padding: 2px 5px;
31+
border-radius: 4px;
32+
font-family: monospace;
33+
}
34+
35+
button {
36+
border: none;
37+
border-radius: 5px;
38+
padding: 12px 24px;
39+
font-size: 1em;
40+
font-weight: bold;
41+
color: white;
42+
background-color: #c82333;
43+
cursor: pointer;
44+
transition: background-color 0.2s;
45+
margin-top: 16px;
46+
margin-bottom: 24px;
47+
}
48+
49+
button:hover {
50+
background-color: #dc3545;
51+
}
52+
53+
.list-box {
54+
background-color: #1e1e1e;
55+
padding: 20px 24px;
56+
border-radius: 8px;
57+
border-left: 4px solid #007bff;
58+
}
59+
60+
h3 {
61+
margin-top: 0;
62+
margin-bottom: 12px;
63+
font-weight: 600;
64+
font-size: 1.1em;
65+
color: #ffffff;
66+
}
67+
68+
ul {
69+
padding-left: 20px;
70+
margin: 0;
71+
}
72+
73+
li {
74+
padding: 4px 0;
75+
color: #d0d0d0;
76+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<div class="container">
2+
<h2>Demo: Accumulating List</h2>
3+
<p>Click "Load More" to trigger the <code>nextPageData</code> source signal. The <code>linkedSignal</code> for <code>allItems</code> will run its computation, appending the new data to the previous list.</p>
4+
5+
<button (click)="loadNextPage()">Load More</button>
6+
7+
<div class="list-box">
8+
<h3>All Items:</h3>
9+
<ul>
10+
@for (item of allItems(); track $index) {
11+
<li>{{ item }}</li>
12+
}
13+
</ul>
14+
</div>
15+
</div>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import {Component, signal, linkedSignal} from '@angular/core';
2+
3+
@Component({
4+
selector: 'app-accumulator',
5+
templateUrl: './app.html',
6+
styleUrl: './app.css',
7+
})
8+
export class Accumulator {
9+
nextPageData = signal<string[]>([]);
10+
page = 1;
11+
12+
allItems = linkedSignal<string[], string[]>({
13+
source: () => this.nextPageData(),
14+
computation: (newData, previous) => {
15+
const initialValue = ['Item A', 'Item B', 'Item C'];
16+
return [...(previous?.value ?? initialValue), ...newData];
17+
},
18+
});
19+
20+
loadNextPage() {
21+
this.page++;
22+
// In a real app, this would come from an API call
23+
const moreItems = [`Page ${this.page} Item 1`, `Page ${this.page} Item 2`];
24+
this.nextPageData.set(moreItems);
25+
}
26+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<!-- #docregion -->
3+
<html lang="en">
4+
<head>
5+
<base href="/">
6+
7+
<title>Accumulator Example</title>
8+
<meta charset="UTF-8">
9+
<meta name="viewport" content="width=device-width, initial-scale=1">
10+
</head>
11+
12+
<body>
13+
<app-accumulator></app-accumulator>
14+
</body>
15+
16+
</html>
17+
<!-- #enddocregion -->
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import {bootstrapApplication} from '@angular/platform-browser';
2+
3+
import {Accumulator} from './app/app';
4+
5+
bootstrapApplication(Accumulator);
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
:host {
2+
display: block;
3+
font-family: sans-serif;
4+
}
5+
6+
.container {
7+
background-color: #2c2c2c;
8+
color: #e0e0e0;
9+
padding: 24px;
10+
border-radius: 8px;
11+
max-width: 800px;
12+
margin: auto;
13+
}
14+
15+
h2 {
16+
margin-top: 0;
17+
font-size: 1.3em;
18+
color: #ffffff;
19+
}
20+
21+
p {
22+
color: #b0b0b0;
23+
font-size: 0.9em;
24+
line-height: 1.6;
25+
max-width: 90%;
26+
}
27+
28+
code {
29+
background-color: #444;
30+
padding: 3px 6px;
31+
border-radius: 4px;
32+
font-family: monospace;
33+
}
34+
35+
.box {
36+
padding: 24px;
37+
border-radius: 8px;
38+
margin-top: 24px;
39+
}
40+
41+
.parent-box {
42+
background-color: #1e1e1e;
43+
}
44+
45+
.child-box {
46+
border: 1px solid #007bff;
47+
}
48+
49+
h3 {
50+
margin-top: 0;
51+
margin-bottom: 16px;
52+
font-weight: 600;
53+
font-size: 1.1em;
54+
color: #ffffff;
55+
}
56+
57+
button {
58+
border: none;
59+
border-radius: 5px;
60+
padding: 12px 24px;
61+
font-size: 1em;
62+
font-weight: bold;
63+
color: white;
64+
background-color: #c82333;
65+
cursor: pointer;
66+
transition: background-color 0.2s;
67+
}
68+
69+
button:hover {
70+
background-color: #dc3545;
71+
}
72+
73+
.status-display {
74+
margin-top: 16px;
75+
padding-left: 12px;
76+
border-left: 4px solid #007bff;
77+
font-size: 1.1em;
78+
color: #d0d0d0;
79+
}
80+
81+
.status-display strong {
82+
color: #ffffff;
83+
font-weight: 600;
84+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<div class="container">
2+
<h2>Demo: Reacting to Child State</h2>
3+
<p>The parent uses <code>viewChild()</code> to get a reference to the child panel, then uses a <code>computed</code> signal to derive its status.</p>
4+
5+
<div class="box parent-box">
6+
<h3>Parent Component</h3>
7+
<button (click)="toggleChild()">Toggle Child Panel</button>
8+
<div class="status-display">
9+
Child panel status: <strong>{{ childStatus() }}</strong>
10+
</div>
11+
</div>
12+
13+
<div class="box child-box">
14+
<h3>Simulated Child Panel</h3>
15+
<app-child #panel></app-child>
16+
</div>
17+
</div>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {Component, computed, viewChild} from '@angular/core';
2+
import {Child} from './child';
3+
4+
@Component({
5+
selector: 'app-child-panel',
6+
templateUrl: './app.html',
7+
styleUrl: './app.css',
8+
imports: [Child],
9+
})
10+
export class ChildPanel {
11+
childPanel = viewChild.required<Child>('panel');
12+
13+
childStatus = computed(() => {
14+
const panel = this.childPanel();
15+
return panel.isExpanded() ? 'Expanded' : 'Collapsed';
16+
});
17+
18+
toggleChild() {
19+
this.childPanel().toggle();
20+
}
21+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.panel-content {
2+
background-color: #3a3a3a;
3+
color: #e0e0e0;
4+
padding: 20px;
5+
border-radius: 6px;
6+
text-align: center;
7+
}

0 commit comments

Comments
 (0)
0