lightview 1.6.6-b → 1.7.1-b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/components/chart/chart.html +15 -0
- package/components/chart/example.html +34 -0
- package/components/chart.html +22 -18
- package/components/components.js +93 -0
- package/components/gantt/example.html +27 -0
- package/components/gantt/gantt.html +35 -0
- package/components/gauge/example.html +28 -0
- package/components/gauge/guage.html +19 -0
- package/components/timeline.html +81 -0
- package/examples/counter.html +1 -1
- package/examples/duration.html +279 -0
- package/examples/forgeinform.html +1 -1
- package/examples/invalid-template-literals.html +1 -4
- package/examples/medium/remote.html +3 -2
- package/examples/message.html +0 -1
- package/examples/object-bound-form.html +32 -0
- package/examples/timeline.html +21 -0
- package/examples/todo.html +38 -0
- package/examples/types.html +2 -2
- package/lightview.js +271 -213
- package/package.json +1 -1
- package/test/basic.html +8 -4
- package/types.js +73 -2
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>Lightview:Examples:Duration timewave timeview</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<script>
|
|
9
|
+
const isDate = (value) => value && typeof(value)==="object" && value instanceof Date;
|
|
10
|
+
const durationMilliseconds = {
|
|
11
|
+
ms: 1,
|
|
12
|
+
s: 1000,
|
|
13
|
+
m: 1000 * 60,
|
|
14
|
+
h: 1000 * 60 * 60,
|
|
15
|
+
d: 1000 * 60 * 60 * 24,
|
|
16
|
+
w: 1000 * 60 * 60 * 24 * 7,
|
|
17
|
+
mo: 1000 * 60 * 60 * 2 * 365.2424177, // (1000 * 60 * 60 * 24 * 365.2424177)/12
|
|
18
|
+
q: 1000 * 60 * 60 * 6 * 365.2424177, // (1000 * 60 * 60 * 24 * 365.2424177)/4
|
|
19
|
+
y: 1000 * 60 * 60 * 24 * 365.2424177
|
|
20
|
+
};
|
|
21
|
+
const dateMath = {
|
|
22
|
+
y(date,y) {
|
|
23
|
+
date.setYear(date.getYear()+y);
|
|
24
|
+
},
|
|
25
|
+
q(date,q) {
|
|
26
|
+
const newmonth = (q * 3) + date.getMonth();
|
|
27
|
+
date.setMonth(newmonth>11 ? newmonth - 12 : newmonth);
|
|
28
|
+
},
|
|
29
|
+
mo(date,mo) {
|
|
30
|
+
const newmonth = mo + date.getMonth();
|
|
31
|
+
date.setMonth(newmonth>11 ? newmonth - 12 : newmonth);
|
|
32
|
+
},
|
|
33
|
+
w(date,w) {
|
|
34
|
+
const dayofyear = Math.floor((date - new Date(date.getFullYear(), 0, 0)) / durationMilliseconds["d"]),
|
|
35
|
+
newdayofyear = dayofyear + (w * 7),
|
|
36
|
+
newtime = date.getTime() + (newdayofyear + durationMilliseconds["d"])
|
|
37
|
+
date.setTime(newtime);
|
|
38
|
+
},
|
|
39
|
+
d(date,d) {
|
|
40
|
+
const dayofyear = Math.floor((date - new Date(date.getFullYear(), 0, 0)) / durationMilliseconds["d"]),
|
|
41
|
+
newdayofyear = dayofyear + d,
|
|
42
|
+
newtime = date.getTime() + (newdayofyear + durationMilliseconds["d"])
|
|
43
|
+
date.setTime(newtime);
|
|
44
|
+
},
|
|
45
|
+
h(date,h) {
|
|
46
|
+
const newhour = h + date.getHours();
|
|
47
|
+
date.setHours(newhour>23 ? 24-newhour : newhour);
|
|
48
|
+
},
|
|
49
|
+
m(date,m) {
|
|
50
|
+
const newminutes = m + date.getMinutes();
|
|
51
|
+
date.setMinutes(newminutes>59 ? 60-newminutes : newminutes);
|
|
52
|
+
},
|
|
53
|
+
s(date,s) {
|
|
54
|
+
const newseconds = s + date.getSeconds();
|
|
55
|
+
date.setSeconds(newseconds>59 ? 60-newseconds : newseconds);
|
|
56
|
+
},
|
|
57
|
+
ms(date,ms) {
|
|
58
|
+
const newmseconds = ms + date.getMilliseconds()
|
|
59
|
+
date.setMilliseconds(newmseconds>999 ? 1000-newmseconds : newmseconds);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const parseDuration = (value) => {
|
|
63
|
+
const type = typeof(value);
|
|
64
|
+
if(value && type==="object" && value instanceof D) return value.valueOf();
|
|
65
|
+
if(type==="number") return value;
|
|
66
|
+
if(type==="string") {
|
|
67
|
+
const parts = value.split(" ");
|
|
68
|
+
let ms = 0;
|
|
69
|
+
for(const part of parts) {
|
|
70
|
+
const num = parseFloat(part),
|
|
71
|
+
suffix = part.substring((num+"").length);
|
|
72
|
+
if(typeof(num)==="number" && !isNaN(num) && suffix in durationMilliseconds) {
|
|
73
|
+
ms += durationMilliseconds[suffix] * num;
|
|
74
|
+
} else {
|
|
75
|
+
throw new TypeError(`${part} in ${value} is not a valid duration`)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return ms;
|
|
79
|
+
}
|
|
80
|
+
if(isDate(value)) return value.getTime();
|
|
81
|
+
return null;
|
|
82
|
+
};
|
|
83
|
+
function Period(start,end) {
|
|
84
|
+
if(!this || !(this instanceof Period)) return new Period(start,end);
|
|
85
|
+
Object.defineProperty(this,"start",{
|
|
86
|
+
set(value) {
|
|
87
|
+
if (!value || typeof (value) !== "object" || !(value instanceof Date)) throw new TypeError(`Period boundary must be a Date`);
|
|
88
|
+
start = value;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
Object.defineProperty(this,"end",{
|
|
92
|
+
set(value) {
|
|
93
|
+
if (!value || typeof (value) !== "object" || !(value instanceof Date)) throw new TypeError(`Period boundary must be a Date`);
|
|
94
|
+
end = value;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
Object.defineProperty(this,"valueOf",{ value:() => {
|
|
98
|
+
const t1 = start.getTime(),
|
|
99
|
+
t2 = end.getTime();
|
|
100
|
+
return D(Math.max(t1,t2)-Math.min(t1,t2))
|
|
101
|
+
}});
|
|
102
|
+
Object.defineProperty(this,"length",{get() { return this.valueOf();}});
|
|
103
|
+
this.start = start;
|
|
104
|
+
this.end = end;
|
|
105
|
+
}
|
|
106
|
+
function Clock(date=new Date(),{tz,hz}={}) {
|
|
107
|
+
if(typeof(date)==="number") date = new Date(date);
|
|
108
|
+
if(!date || typeof(date)!=="object" || !(date instanceof Date)) throw new TypeError(`Clock() expects a Date not ${JSON.stringify(date)}`);
|
|
109
|
+
let tzoffset = now.getTimezoneOffset(),
|
|
110
|
+
diff = 0;
|
|
111
|
+
if(tz) {
|
|
112
|
+
const thereLocaleStr = date.toLocaleString('en-US', {timeZone: tz}),
|
|
113
|
+
thereDate = new Date(thereLocaleStr);
|
|
114
|
+
diff = thereDate.getTime() - date.getTime();
|
|
115
|
+
tzoffset = Math.round(tzoffset - (diff / (1000 * 60)));
|
|
116
|
+
} else {
|
|
117
|
+
tzoffset = date.getTimezoneOffset();
|
|
118
|
+
}
|
|
119
|
+
if(hz) {
|
|
120
|
+
if(hz>60) console.warn(`Clock set to run faster than ${hz}hz. Excess CPU load beyond typical DOM refresh rate.`);
|
|
121
|
+
const warp = date.getTime() - Date.now();
|
|
122
|
+
setInterval(() => {
|
|
123
|
+
date = new Date(Date.now() + warp);
|
|
124
|
+
},1000/Math.abs(hz))
|
|
125
|
+
}
|
|
126
|
+
const extensions = {
|
|
127
|
+
plus(duration,times=1) {
|
|
128
|
+
if(typeof(duration)==="number") duration = D(duration);
|
|
129
|
+
if(!D.is(duration)) throw new TypeError(`${JSON.stringify(duration)} is not a duration`);
|
|
130
|
+
const parts = duration.toJSON().split(" "),
|
|
131
|
+
result = new Date(date);
|
|
132
|
+
Object.entries(dateMath).forEach(([key,math]) => {
|
|
133
|
+
parts.some((part) => {
|
|
134
|
+
if(part.endsWith(key)) {
|
|
135
|
+
math(result,parseFloat(part)*times);
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
});
|
|
140
|
+
return new Clock(result,{tz},true);
|
|
141
|
+
},
|
|
142
|
+
minus(duration) {
|
|
143
|
+
this.plus(duration,-1);
|
|
144
|
+
},
|
|
145
|
+
clone({tz,hz}={}) {
|
|
146
|
+
const thereDate = new Clock(new Date(),{tz}),
|
|
147
|
+
thereOffset = thereDate.getTimezoneOffset(),
|
|
148
|
+
offset = tzoffset - thereOffset,
|
|
149
|
+
newDate = new Date(date.getTime() + offset * 1000 * 60)
|
|
150
|
+
return new Clock(newDate,{tz,hz});
|
|
151
|
+
},
|
|
152
|
+
getTimezoneOffset() {
|
|
153
|
+
return tzoffset;
|
|
154
|
+
},
|
|
155
|
+
toString() {
|
|
156
|
+
const string = date.toString(),
|
|
157
|
+
offset = tzoffset / 60,
|
|
158
|
+
fraction = offset % 1,
|
|
159
|
+
minutes = (1 - fraction) >= .017 ? `${Math.round(fraction * 60)}` : "00", // .017 = 1 minute
|
|
160
|
+
hours = `${Math.abs(Math.round(offset))}`,
|
|
161
|
+
gmt = `GMT${offset>0 ? "-" : "+"}${hours.padStart(2,"0")}${minutes.padStart(2,"0")}`,
|
|
162
|
+
zone = tz ? ` (${tz})` : "";
|
|
163
|
+
return string.replace(/GMT.*/g,gmt) + zone;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
const proxy = new Proxy(date,{
|
|
167
|
+
get(target,property) {
|
|
168
|
+
let value = extensions[property];
|
|
169
|
+
if(value!==undefined) return value;
|
|
170
|
+
if(property==="weekDay") {
|
|
171
|
+
return target.getDay()+1;
|
|
172
|
+
}
|
|
173
|
+
if(property==="dayOfMonth") {
|
|
174
|
+
return target.getDate();
|
|
175
|
+
}
|
|
176
|
+
if(property==="dayOfYear" || property==="ordinal") {
|
|
177
|
+
return Math.floor((target - new Date(target.getFullYear(), 0, 0)) / durationMilliseconds["d"])
|
|
178
|
+
}
|
|
179
|
+
if(property==="isInLeapYear") {
|
|
180
|
+
const year = date.getFullYear();
|
|
181
|
+
return !(year % 4 || !(year % 100) && year % 400);
|
|
182
|
+
}
|
|
183
|
+
if(property==="offset") {
|
|
184
|
+
return tzoffset;
|
|
185
|
+
}
|
|
186
|
+
if(property==="weekOfYear") {
|
|
187
|
+
return Math.floor(((target - new Date(target.getFullYear(), 0, 0)) / durationMilliseconds["d"]) / 7)
|
|
188
|
+
}
|
|
189
|
+
value = date[property];
|
|
190
|
+
if(typeof(value)==="function") return value.bind(target);
|
|
191
|
+
if(typeof(property)==="string" && !property.startsWith("get")) {
|
|
192
|
+
let fname = "get" + property[0].toUpperCase() + property.substring(1);
|
|
193
|
+
if(typeof(target[fname])==="function") return target[fname]();
|
|
194
|
+
fname += "s";
|
|
195
|
+
if(typeof(target[fname])==="function") return target[fname]();
|
|
196
|
+
}
|
|
197
|
+
return value;
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
return proxy;
|
|
201
|
+
}
|
|
202
|
+
Clock.min = (...clocks) => {
|
|
203
|
+
const mintime = clocks.reduce((mintime,clock) => {
|
|
204
|
+
const t = clock.getTime() + clock.getTimezoneOffset() * 1000 * 60;
|
|
205
|
+
mintime = Math.min(t,mintime);
|
|
206
|
+
},Infinity);
|
|
207
|
+
return clocks.reduce((min,clock) => {
|
|
208
|
+
if((clock.getTime() + clock.getTimezoneOffset() * 1000 * 60)===mintime) {
|
|
209
|
+
min.push(clock);
|
|
210
|
+
}
|
|
211
|
+
return min;
|
|
212
|
+
},[])
|
|
213
|
+
}
|
|
214
|
+
Clock.max = (...clocks) => {
|
|
215
|
+
const maxtime = clocks.reduce((mintime,clock) => {
|
|
216
|
+
const t = clock.getTime() + clock.getTimezoneOffset() * 1000 * 60;
|
|
217
|
+
mintime = Math.max(t,mintime);
|
|
218
|
+
},-Infinity);
|
|
219
|
+
return clocks.reduce((min,clock) => {
|
|
220
|
+
if((clock.getTime() + clock.getTimezoneOffset() * 1000 * 60)===maxtime) {
|
|
221
|
+
min.push(clock);
|
|
222
|
+
}
|
|
223
|
+
return min;
|
|
224
|
+
},[])
|
|
225
|
+
}
|
|
226
|
+
function D(value,type) {
|
|
227
|
+
if(!this || !(this instanceof D)) return new D(value,type);
|
|
228
|
+
let duration = value;
|
|
229
|
+
if(isDate(duration)) {
|
|
230
|
+
if(type && type!=="ms") throw new TypeError(`A date can't be used to initialize ${type}`);
|
|
231
|
+
duration = value.getTime()+"ms";
|
|
232
|
+
} else if(typeof(duration)==="number") {
|
|
233
|
+
duration += type||"ms";
|
|
234
|
+
}
|
|
235
|
+
const valueof = parseDuration(duration);
|
|
236
|
+
if(valueof==null) throw new TypeError(`${typeof(value)==="string" ? value : JSON.stringify(value)}${type!==undefined ? type :""} is not a valid duration`);
|
|
237
|
+
Object.defineProperty(this,"type",{get() { return type; }});
|
|
238
|
+
Object.defineProperty(this,"valueOf",{value:() => valueof});
|
|
239
|
+
Object.defineProperty(this,"toJSON",{value:() => duration});
|
|
240
|
+
return this;
|
|
241
|
+
}
|
|
242
|
+
D.is = (value) => value && typeof(value)==="object" && value instanceof D;
|
|
243
|
+
D.prototype.to = function(type="ms") {
|
|
244
|
+
const value = this.valueOf();
|
|
245
|
+
if(type==="Date") {
|
|
246
|
+
if(this instanceof Period) throw new TypeError(`Cannot convert Period to Date`);
|
|
247
|
+
return new Date(value);
|
|
248
|
+
}
|
|
249
|
+
if(!(type in durationMilliseconds)) throw new TypeError(`${type} is not a valid duration type`);
|
|
250
|
+
return value / durationMilliseconds[type];
|
|
251
|
+
}
|
|
252
|
+
D.prototype.days = function() { return this.to("d"); }
|
|
253
|
+
D.prototype.Date = function() { return this.to("Date"); }
|
|
254
|
+
D.Period = Period;
|
|
255
|
+
Period.is = (value) => value && typeof(value)==="object" && value instanceof Period;
|
|
256
|
+
Period.prototype = {...D.prototype};
|
|
257
|
+
delete Period.prototype.Date;
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
console.log(JSON.stringify(D(D("1d") + D("1w") + D("1w 2d")).days()));
|
|
261
|
+
const now = new Date(),
|
|
262
|
+
d = D(now) + D("1d"),
|
|
263
|
+
nyc = Clock(now,{tz:"America/New_York",hz:60}),
|
|
264
|
+
chicago = nyc.clone({tz:"America/Chicago"}),
|
|
265
|
+
toronto = nyc.clone({tz:"America/Toronto"}),
|
|
266
|
+
seattle = toronto.clone({tz:"America/Los_Angeles"});
|
|
267
|
+
console.log(now,new Date(D(d)),new Date(d));
|
|
268
|
+
console.log(D(1) instanceof D);
|
|
269
|
+
console.log(now.getTime(),D(now,"ms").valueOf());
|
|
270
|
+
console.log(JSON.stringify(Clock(now).plus(D("1mo"))));
|
|
271
|
+
console.log(Clock(now).weekOfYear,Clock(now).dayOfYear);
|
|
272
|
+
console.log(nyc.toString());
|
|
273
|
+
console.log(toronto.toString());
|
|
274
|
+
console.log(chicago.toString());
|
|
275
|
+
console.log(seattle.toString());
|
|
276
|
+
setInterval(() => console.log(nyc.toString()),1000*60);
|
|
277
|
+
</script>
|
|
278
|
+
</body>
|
|
279
|
+
</html>
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
<option>tomato</option>
|
|
28
28
|
<option>cheese</option>
|
|
29
29
|
</select>
|
|
30
|
-
<br><button l-on:click="placeOrder">Place Order</button>
|
|
30
|
+
<br><button l-on:click="${placeOrder}">Place Order</button>
|
|
31
31
|
</p>
|
|
32
32
|
Expose: <input type="checkbox" value="${checked}">
|
|
33
33
|
<p l-if="${checked}">
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
</head>
|
|
7
7
|
<body>
|
|
8
8
|
<p>
|
|
9
|
-
<button l-on:click="bump">Click count:${count}</button>
|
|
9
|
+
<button l-on:click="${bump}">Click count:${count}</button>
|
|
10
10
|
</p>
|
|
11
11
|
<div style="margin:20px">
|
|
12
12
|
<p>
|
|
@@ -24,9 +24,6 @@
|
|
|
24
24
|
<p>
|
|
25
25
|
${function(){return \${test}})()}
|
|
26
26
|
</p>
|
|
27
|
-
<p>
|
|
28
|
-
${window.alert("ok")}
|
|
29
|
-
</p>
|
|
30
27
|
</div>
|
|
31
28
|
|
|
32
29
|
<script type="lightview/module">
|
|
@@ -15,13 +15,14 @@
|
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
17
17
|
<!--
|
|
18
|
-
layout the
|
|
18
|
+
layout the dashboard using the chart component r-chart
|
|
19
19
|
-->
|
|
20
20
|
<div style="width:100%;text-align:center">
|
|
21
21
|
<!--
|
|
22
22
|
set the initial value 0 for all components in a relaxed JSON5 configuration data block
|
|
23
|
+
add the attributes hidden and l-unhide to eliminate flicker and display of Loading ....
|
|
23
24
|
-->
|
|
24
|
-
<r-chart id="dashboard" style="display:inline-block" type="Gauge" title="Server Status"
|
|
25
|
+
<r-chart id="dashboard" style="display:inline-block" type="Gauge" title="Server Status">
|
|
25
26
|
[
|
|
26
27
|
['Label', 'Value'], // gauge will always take two columns, Label and Value
|
|
27
28
|
['Memory', 0],
|
package/examples/message.html
CHANGED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<title>Form</title>
|
|
6
|
+
<script src="../lightview.js?as=x-body"></script>
|
|
7
|
+
</head>
|
|
8
|
+
|
|
9
|
+
<body>
|
|
10
|
+
<form value="${hamburger}" style="margin:20px;padding:5px;border:1px;border-style:solid;">
|
|
11
|
+
<div>Hamburger options:</div>
|
|
12
|
+
<select value="${hamburger.options}" multiple>
|
|
13
|
+
<option value="lettuce">lettuce</option>
|
|
14
|
+
<option value="tomato">tomato</option>
|
|
15
|
+
<option>cheese</option>
|
|
16
|
+
</select>
|
|
17
|
+
<p id="variables">
|
|
18
|
+
|
|
19
|
+
</p>
|
|
20
|
+
</form>
|
|
21
|
+
<script type="lightview/module">
|
|
22
|
+
self.addEventListener("connected",() => {
|
|
23
|
+
hamburger.options = ["cheese"];
|
|
24
|
+
observe(() => {
|
|
25
|
+
const el = self.getElementById("variables");
|
|
26
|
+
el.innerText = JSON.stringify(hamburger);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
</script>
|
|
30
|
+
</body>
|
|
31
|
+
|
|
32
|
+
</html>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>Chart</title>
|
|
4
|
+
<link href="../components/timeline.html" rel="module">
|
|
5
|
+
<script src="../lightview.js"></script>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<l-timeline id="myPieChart" style="max-width:750px" type="PieChart" title="How Much Pizza I Ate Last Night">
|
|
9
|
+
// Chart will resize automatically to a max-width of 750px and repaint on type and title changes.
|
|
10
|
+
// The component DOM element also exposes a method `el.addRow(row:array)` to dynamically add data
|
|
11
|
+
// And, `el.init()` will re-render from the initial data and current attributes.
|
|
12
|
+
[
|
|
13
|
+
[{ type: 'string', id: 'Position' },{ type: 'string', id: 'Name' },{ type: 'date', id: 'Start' },{ type: 'date', id: 'End' }],
|
|
14
|
+
[ '1', 'George Washington', '1789-03-30','1797-02-04'] // Date(1789, 3, 30), Date(1797, 2, 4)
|
|
15
|
+
//[ '2', 'John Adams', Date(1797, 2, 4), Date(1801, 2, 4) ],
|
|
16
|
+
//[ '3', 'Thomas Jefferson', Date(1801, 2, 4), Date(1809, 2, 4) ]]);
|
|
17
|
+
]
|
|
18
|
+
</l-timeline>
|
|
19
|
+
|
|
20
|
+
</body>
|
|
21
|
+
</html>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>Lightview:Examples:ToDo</title>
|
|
4
|
+
<script src="../lightview.js?as=x-body"></script>
|
|
5
|
+
</head>
|
|
6
|
+
<body>
|
|
7
|
+
<input type="text" value="${newItem}" placeholder="new todo item...">
|
|
8
|
+
<button l-on:click="${addToList}">Add</button>
|
|
9
|
+
<div l-for="${todoList}">
|
|
10
|
+
<input value="${item.status}" type="checkbox">
|
|
11
|
+
<span class="${item.status ? 'checked' : ''}">${item.text}</span>
|
|
12
|
+
<span l-on:click="({self}) => self.removeFromList(${index})">X>
|
|
13
|
+
<br/>
|
|
14
|
+
</div>
|
|
15
|
+
<script type="lightview/module">
|
|
16
|
+
self.variables(
|
|
17
|
+
{ todoList: Array },
|
|
18
|
+
{
|
|
19
|
+
reactive,
|
|
20
|
+
set: [
|
|
21
|
+
{text: 'Write my first post', status: true},
|
|
22
|
+
{text: 'Upload the post to the blog', status: false}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
self.addToList = () => {
|
|
27
|
+
todoList = [...todoList, {text: newItem, status: false}];
|
|
28
|
+
newItem = '';
|
|
29
|
+
};
|
|
30
|
+
self.removeFromList = (index) => {
|
|
31
|
+
todoList.splice(index, 1);
|
|
32
|
+
};
|
|
33
|
+
</script>
|
|
34
|
+
<style>
|
|
35
|
+
.checked { text-decoration: line-through; }
|
|
36
|
+
</style>
|
|
37
|
+
</body>
|
|
38
|
+
</html>
|
package/examples/types.html
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
<body>
|
|
10
10
|
<div style="margin:20px">
|
|
11
11
|
<p>
|
|
12
|
-
<button l-on:click="run">Run</button>
|
|
13
|
-
<button l-on:click="clear">Clear</button>
|
|
12
|
+
<button l-on:click="${run}">Run</button>
|
|
13
|
+
<button l-on:click="${clear}">Clear</button>
|
|
14
14
|
</p>
|
|
15
15
|
<p id="console"></p>
|
|
16
16
|
</div>
|