Skip to content

Commit d5a8143

Browse files
committed
Address #45
1 parent 994498b commit d5a8143

18 files changed

+599
-153
lines changed

projects/demo/src/app/content/signal-factories/sequence-signal-page.component.ts

+18-2
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,40 @@ import { DemoHostComponent } from '../../controls/demo-host.component';
33
import { MemberPageHeaderComponent } from '../../controls/member-page-header.component';
44
import { FibonacciDemoComponent } from '../../demos/sequence-signal/fibonacci-demo/fibonacci-demo.component';
55
import { ToggleDemoComponent } from '../../demos/sequence-signal/toggle-demo/toggle-demo.component';
6+
import { ChoicesDemoComponent } from '../../demos/sequence-signal/choices-demo/choices-demo.component';
67

78

89
@Component({
910
selector: 'app-timer-signal-page',
10-
imports: [DemoHostComponent, FibonacciDemoComponent, ToggleDemoComponent, MemberPageHeaderComponent],
11+
imports: [ChoicesDemoComponent, DemoHostComponent, FibonacciDemoComponent, ToggleDemoComponent, MemberPageHeaderComponent],
1112
template: `
1213
<app-member-page-header fnName="sequenceSignal" />
1314
<p>
1415
This accepts a sequence of values, and moves to the next value after every call to next.
15-
The sequence can be something simple as a toggle between states, or a complex sequence generated by a function.
16+
The sequence can be something as simple as an array of two values to toggle between states,
17+
or as complex as a sequence generated by a function.
18+
</p>
19+
<p>
20+
This signal can accept anything that implements the <code class="inline">Iterator</code> spec or that matches the <code class="inline">ArrayLike</code> interface.
21+
A special type called <code class="inline">Cursor</code> can also be provided to allow more custom behavior.
22+
This type is very similar to an <code class="inline">Iterator</code>, but has explicit methods to reset and move to specific values.
23+
</p>
24+
<p>
25+
This signal has <code class="inline">set</code> and <code class="inline">update</code> methods like any writeable signal.
26+
These methods will throw errors if the values aren't present in the sequence.
1627
</p>
1728
<div class="flex flex-col gap-6">
1829
<app-demo-host name="Simple Toggle" pattern="sequence-signal/toggle-demo/toggle-demo.component">
1930
<app-toggle-demo />
2031
</app-demo-host>
2132
<app-demo-host name="Generated Fibonacci Sequence" pattern="sequence-signal/fibonacci-demo/">
33+
<p>This uses an iterator to move through a sequence of fibonacci numbers.</p>
2234
<app-fibonacci-demo />
2335
</app-demo-host>
36+
<app-demo-host name="Choices with Model Binding" pattern="sequence-signal/choices-demo/choices-demo.component">
37+
<p>This will use a radio button to select a choice, and will update the model binding to the selected choice.</p>
38+
<app-choices-demo />
39+
</app-demo-host>
2440
</div>
2541
`,
2642
changeDetection: ChangeDetectionStrategy.OnPush
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<div class="flex flex-row gap-3">
2+
<div class="flex flex-col gap-1">
3+
<div class="flex flex-row items-center gap-3">
4+
<input type="radio" class="radio checked:bg-blue-500" value="a" [(ngModel)]="$sequenceChoices" /> Choice A
5+
</div>
6+
<div class="flex flex-row items-center gap-3">
7+
<input type="radio" class="radio checked:bg-blue-500" value="b" [(ngModel)]="$sequenceChoices" /> Choice B
8+
</div>
9+
<div class="flex flex-row items-center gap-3">
10+
<input type="radio" class="radio checked:bg-blue-500" value="c" [(ngModel)]="$sequenceChoices" /> Choice C
11+
</div>
12+
</div>
13+
<button type="button" class="btn btn-primary" (click)="$sequenceChoices.next()">Next Choice</button>
14+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { ChangeDetectionStrategy, Component } from '@angular/core';
2+
import { FormsModule } from '@angular/forms';
3+
import { sequenceSignal } from '@ddtmm/angular-signal-generators';
4+
5+
@Component({
6+
selector: 'app-choices-demo',
7+
imports: [FormsModule],
8+
templateUrl: './choices-demo.component.html',
9+
changeDetection: ChangeDetectionStrategy.OnPush
10+
})
11+
export class ChoicesDemoComponent {
12+
readonly $sequenceChoices = sequenceSignal(['a', 'b', 'c']);
13+
}

projects/demo/src/app/demos/sequence-signal/fibonacci-demo/fibonacci-demo.component.html

+6-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
<div class="text-lg">{{$fibonacci()}}</div>
55
</div>
66
<div class="px-3">
7-
<label for="fibonacciStepSize" class="label">Step Size: {{fibonacciStepSize}}</label>
8-
<input id="fibonacciStepSize" class="range" type="range" min="-10" max="10" [(ngModel)]="fibonacciStepSize" />
7+
<label for="fibonacciStepSize" class="label">Step Size: {{$fibonacciStepSize()}}</label>
8+
<input id="fibonacciStepSize" class="range" type="range" min="0" max="10" [(ngModel)]="$fibonacciStepSize" />
9+
</div>
10+
<div class="join">
11+
<button type="button" class="btn btn-primary join-item" (click)="$fibonacci.next($fibonacciStepSize())">Next</button>
12+
<button type="button" class="btn btn-primary join-item" (click)="$fibonacci.reset()">Reset</button>
913
</div>
10-
<button type="button" class="btn btn-primary" (click)="$fibonacci.next(fibonacciStepSize)">Next</button>
1114
</div>
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ChangeDetectionStrategy, Component } from '@angular/core';
1+
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
22
import { FormsModule } from '@angular/forms';
33
import { sequenceSignal } from '@ddtmm/angular-signal-generators';
44

@@ -9,20 +9,19 @@ import { sequenceSignal } from '@ddtmm/angular-signal-generators';
99
changeDetection: ChangeDetectionStrategy.OnPush
1010
})
1111
export class FibonacciDemoComponent {
12-
readonly $fibonacci = sequenceSignal((() => {
13-
let values = [1, 2];
14-
return {
15-
next: (relativeChange: number) => {
16-
for (let i = 0; i < relativeChange; i++) {
17-
values = [values[1], values[0] + values[1]];
12+
readonly $fibonacci = sequenceSignal({
13+
[Symbol.iterator]() {
14+
let current = 0;
15+
let next = 1;
16+
17+
return {
18+
next() {
19+
const value = current;
20+
[current, next] = [next, current + next];
21+
return { value, done: false };
1822
}
19-
for (let i = relativeChange; i < 0; i++) {
20-
values = [Math.max(1, values[1] - values[0]), Math.max(values[0], 2)];
21-
}
22-
return { hasValue: true, value: values[0] };
23-
},
24-
reset: () => values = [1, 2]
25-
};
26-
})());
27-
fibonacciStepSize = 1;
23+
};
24+
}
25+
});
26+
readonly $fibonacciStepSize = signal(1);
2827
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
<div>
2-
<button type="button" class="btn btn-primary" (click)="$trueFalseToggle.next()">TOGGLE ME</button>
3-
<div class="label">Current Value</div>
1+
<div class="flex flex-row gap-3 items-center">
2+
<button type="button" class="btn btn-sm btn-primary" (click)="$trueFalseToggle.next()">TOGGLE ME</button>
3+
<div class="label">Current Value:</div>
44
<div>{{$trueFalseToggle()}}</div>
55
</div>

projects/demo/src/app/home-demos/sequence-signal-home-demo.component.ts

+4-17
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,19 @@
11
import { ChangeDetectionStrategy, Component } from '@angular/core';
2-
import { FormsModule } from '@angular/forms';
32
import { sequenceSignal } from '@ddtmm/angular-signal-generators';
4-
import { HomeBoxComponent } from '../controls/home-box.component';
53
import { ContentsClassDirective } from '../controls/contents-class.directive';
4+
import { HomeBoxComponent } from '../controls/home-box.component';
5+
import { ChoicesDemoComponent } from "../demos/sequence-signal/choices-demo/choices-demo.component";
66

77
@Component({
8-
imports: [FormsModule, HomeBoxComponent],
8+
imports: [ChoicesDemoComponent, HomeBoxComponent],
99
hostDirectives: [ContentsClassDirective],
1010
template: `
1111
<app-home-box fnName="sequenceSignal">
1212
<div>
1313
The Sequence Signal is useful for situations where you want to easily cycle between options.
1414
</div>
1515
<div class="divider">Example</div>
16-
<div class="flex flex-row gap-3">
17-
<div class="flex flex-col gap-1">
18-
<div class="flex flex-row items-center gap-3">
19-
<input type="radio" class="radio checked:bg-blue-500" value="a" [ngModel]="sequenceChoices()" /> Choice A
20-
</div>
21-
<div class="flex flex-row items-center gap-3">
22-
<input type="radio" class="radio checked:bg-blue-500" value="b" [ngModel]="sequenceChoices()" /> Choice B
23-
</div>
24-
<div class="flex flex-row items-center gap-3">
25-
<input type="radio" class="radio checked:bg-blue-500" value="c" [ngModel]="sequenceChoices()" /> Choice C
26-
</div>
27-
</div>
28-
<button type="button" class="btn btn-primary" (click)="sequenceChoices.next()">Next Choice</button>
29-
</div>
16+
<app-choices-demo />
3017
</app-home-box>
3118
`,
3219
changeDetection: ChangeDetectionStrategy.OnPush

0 commit comments

Comments
 (0)