@@ -11,31 +11,40 @@ import { escapeKey } from "./utils.js"
11
11
*/
12
12
export class Theme < TValues extends Record < string , InterpolatedVars < any > | ControlVar < any , any > > = Record < string , InterpolatedVars < any > | ControlVar < any , any > > > extends Base {
13
13
protected ready : boolean = false
14
+
14
15
els : HTMLElement [ ] = [ ]
16
+
15
17
css : Record < string , string > = { }
18
+
16
19
value : TValues = { } as any
20
+
17
21
options : { escapeChar : string } = {
18
22
/** For replacing invalid css variable key characters. */
19
23
escapeChar : "-" ,
20
24
}
25
+
21
26
protected _listeners : Record < string , ( ( ) => void ) [ ] > = { change : [ ] }
27
+
22
28
constructor ( value : TValues , opts : Partial < Theme < TValues > [ "options" ] > = { } ) {
23
29
super ( )
24
30
this . add ( value )
25
31
this . setOpts ( opts )
26
32
this . recompute ( false )
27
33
this . ready = true
28
34
}
35
+
29
36
setOpts ( value : Partial < Theme < TValues > [ "options" ] > = { } ) : void {
30
37
this . options = { ...this . options , ...value }
31
38
if ( ! this . ready ) return
32
39
this . notify ( )
33
40
}
41
+
34
42
add ( value : Record < string , ControlVar < any , any > | InterpolatedVars < any > > ) : void {
35
43
for ( const key of keys ( value ) ) {
36
44
this . _add ( key , value [ key ] )
37
45
}
38
46
}
47
+
39
48
protected _add ( key : string , value : InterpolatedVars < any > | ControlVar < any , any > ) : void {
40
49
if ( this . value [ key ] ) throw new Error ( `Key ${ key } already exists in theme. Use set to change the value.` )
41
50
if ( this . ready ) { this . value [ key ] ?. removeDep ( this ) }
@@ -46,6 +55,7 @@ export class Theme<TValues extends Record<string, InterpolatedVars<any> | Contro
46
55
47
56
if ( this . ready ) { this . notify ( ) }
48
57
}
58
+
49
59
remove ( key : string ) : void {
50
60
if ( ! this . value [ key ] ) return
51
61
if ( this . ready ) { this . value [ key ] ?. removeDep ( this ) }
@@ -57,6 +67,7 @@ export class Theme<TValues extends Record<string, InterpolatedVars<any> | Contro
57
67
// NOTE the use of _, we don't need to recompute other keys
58
68
if ( this . ready ) { this . notify ( ) }
59
69
}
70
+
60
71
set ( key : string , value : InterpolatedVars < any > | ControlVar < any , any > ) : void {
61
72
if ( this . ready ) { this . value [ key ] ?. removeDep ( this ) }
62
73
@@ -66,6 +77,7 @@ export class Theme<TValues extends Record<string, InterpolatedVars<any> | Contro
66
77
67
78
if ( this . ready ) { this . notify ( { recompute : false } ) }
68
79
}
80
+
69
81
protected notify ( { recompute = true } : { recompute ?: boolean } = { } ) : void {
70
82
if ( ! this . ready ) return
71
83
if ( recompute ) this . recompute ( false )
@@ -77,15 +89,18 @@ export class Theme<TValues extends Record<string, InterpolatedVars<any> | Contro
77
89
this . _lastPropertiesSet = Theme . setElVariables ( el , this . css , this . _lastPropertiesSet )
78
90
}
79
91
}
92
+
80
93
on ( type : "change" , cb : ( ) => void ) : void {
81
94
this . _listeners [ type ] . push ( cb )
82
95
}
96
+
83
97
off ( type : "change" , cb : ( ) => void ) : void {
84
98
const i = this . _listeners [ type ] . findIndex ( cb )
85
99
if ( i > - 1 ) {
86
100
this . _listeners [ type ] . splice ( i , 1 )
87
101
}
88
102
}
103
+
89
104
protected _generateCss (
90
105
res : Record < string , string > ,
91
106
key : string ,
@@ -127,7 +142,9 @@ export class Theme<TValues extends Record<string, InterpolatedVars<any> | Contro
127
142
}
128
143
this . css = res
129
144
}
145
+
130
146
protected _lastPropertiesSet : string [ ] = [ ]
147
+
131
148
// todo move to utils?
132
149
/**
133
150
* Set css variables on an element.
@@ -147,6 +164,7 @@ export class Theme<TValues extends Record<string, InterpolatedVars<any> | Contro
147
164
}
148
165
return newLastPropertiesSet
149
166
}
167
+
150
168
/**
151
169
* Attach to an element and automatically set and update the theme's properties on it.
152
170
*
@@ -156,6 +174,7 @@ export class Theme<TValues extends Record<string, InterpolatedVars<any> | Contro
156
174
this . els . push ( el )
157
175
this . _lastPropertiesSet = Theme . setElVariables ( el , this . css , this . _lastPropertiesSet )
158
176
}
177
+
159
178
detach ( el : HTMLElement = document . documentElement ) : void {
160
179
const existing = this . els . indexOf ( el )
161
180
if ( existing >= 0 ) {
@@ -168,6 +187,7 @@ export class Theme<TValues extends Record<string, InterpolatedVars<any> | Contro
168
187
console . warn ( "Was not attached to element:" , el )
169
188
}
170
189
}
190
+
171
191
/**
172
192
* Write theme variables to get autocomplete while developing. Only works from node.
173
193
*
0 commit comments