11import { h } from "@commontools/common-html" ;
2- import { recipe , NAME , UI , handler } from "@commontools/common-builder" ;
3- import { z } from "zod" ;
4-
5- const inc = handler < { } , { count : number } > ( ( { } , state ) => {
6- state . count += 1 ;
7- } ) ;
8-
9- const updateValue = handler < { detail : { value : string } } , { value : string } > (
10- ( { detail } , state ) => {
11- detail ?. value && ( state . value = detail . value ) ;
12- } ,
13- ) ;
14-
15- const Counter = z
16- . object ( {
17- title : z . string ( ) . default ( "untitled counter" ) ,
18- count : z . number ( ) . default ( 0 ) ,
19- } )
20- . describe ( "A counter" ) ;
21-
22- export default recipe ( Counter , ( { title, count } ) => {
23- return {
24- [ NAME ] : title ,
25- [ UI ] : (
26- < os-container >
27- < common-input
28- value = { title }
29- placeholder = "Name of counter"
30- oncommon-input = { updateValue ( { value : title } ) }
31- />
32- < p > { count } </ p >
33- < button onclick = { inc ( { count } ) } > Inc</ button >
34- </ os-container >
35- ) ,
36- count,
37- } ;
38- } ) ;
2+ import { Spell , type OpaqueRef } from "@commontools/common-builder" ;
3+
4+ type CounterState = {
5+ title : string ;
6+ count : number ;
7+ } ;
8+
9+ export class CounterSpell extends Spell < CounterState > {
10+ constructor ( ) {
11+ super ( ) ;
12+
13+ this . addEventListener ( "increment" , self => {
14+ const { count } = self ;
15+ this . update ( self , { count : count + 1 } ) ;
16+ } ) ;
17+
18+ this . addEventListener ( "title" , ( self , { detail : { value } } ) => {
19+ this . update ( self , { title : value } ) ;
20+ } ) ;
21+ }
22+
23+ override init ( ) {
24+ return {
25+ title : "untitled counter" ,
26+ count : 0 ,
27+ } ;
28+ }
29+
30+ override render ( { title, count } : OpaqueRef < CounterState > ) {
31+ return (
32+ < div >
33+ < common-input value = { title } oncommon-input = { this . dispatch ( "title" ) } />
34+ < p > count: { count } </ p >
35+ < common-button onclick = { this . dispatch ( "increment" ) } > Increment</ common-button >
36+ </ div >
37+ ) ;
38+ }
39+ }
40+
41+ const counter = new CounterSpell ( ) . compile ( "Counter" ) ;
42+
43+ export default counter ;
0 commit comments