~repos /gromer

#golang#htmx#ssr

git clone https://pyrossh.dev/repos/gromer.git

gromer is a framework and cli to build multipage web apps in golang using htmx and alpinejs.


e36141a2 Peter John

3 years ago
remove todo css
_example/assets/css/todo.css DELETED
@@ -1,513 +0,0 @@
1
- hr {
2
- margin: 20px 0;
3
- border: 0;
4
- border-top: 1px dashed #c5c5c5;
5
- border-bottom: 1px dashed #f7f7f7;
6
- }
7
-
8
- .learn a {
9
- font-weight: normal;
10
- text-decoration: none;
11
- color: #b83f45;
12
- }
13
-
14
- .learn a:hover {
15
- text-decoration: underline;
16
- color: #787e7e;
17
- }
18
-
19
- .learn h3,
20
- .learn h4,
21
- .learn h5 {
22
- margin: 10px 0;
23
- font-weight: 500;
24
- line-height: 1.2;
25
- color: #000;
26
- }
27
-
28
- .learn h3 {
29
- font-size: 24px;
30
- }
31
-
32
- .learn h4 {
33
- font-size: 18px;
34
- }
35
-
36
- .learn h5 {
37
- margin-bottom: 0;
38
- font-size: 14px;
39
- }
40
-
41
- .learn ul {
42
- padding: 0;
43
- margin: 0 0 30px 25px;
44
- }
45
-
46
- .learn li {
47
- line-height: 20px;
48
- }
49
-
50
- .learn p {
51
- font-size: 15px;
52
- font-weight: 300;
53
- line-height: 1.3;
54
- margin-top: 0;
55
- margin-bottom: 0;
56
- }
57
-
58
- #issue-count {
59
- display: none;
60
- }
61
-
62
- .quote {
63
- border: none;
64
- margin: 20px 0 60px 0;
65
- }
66
-
67
- .quote p {
68
- font-style: italic;
69
- }
70
-
71
- .quote p:before {
72
- content: '“';
73
- font-size: 50px;
74
- opacity: 0.15;
75
- position: absolute;
76
- top: -20px;
77
- left: 3px;
78
- }
79
-
80
- .quote p:after {
81
- content: '”';
82
- font-size: 50px;
83
- opacity: 0.15;
84
- position: absolute;
85
- bottom: -42px;
86
- right: 3px;
87
- }
88
-
89
- .quote footer {
90
- position: absolute;
91
- bottom: -40px;
92
- right: 0;
93
- }
94
-
95
- .quote footer img {
96
- border-radius: 3px;
97
- }
98
-
99
- .quote footer a {
100
- margin-left: 5px;
101
- vertical-align: middle;
102
- }
103
-
104
- .speech-bubble {
105
- position: relative;
106
- padding: 10px;
107
- background: rgba(0, 0, 0, 0.04);
108
- border-radius: 5px;
109
- }
110
-
111
- .speech-bubble:after {
112
- content: '';
113
- position: absolute;
114
- top: 100%;
115
- right: 30px;
116
- border: 13px solid transparent;
117
- border-top-color: rgba(0, 0, 0, 0.04);
118
- }
119
-
120
- .learn-bar > .learn {
121
- position: absolute;
122
- width: 272px;
123
- top: 8px;
124
- left: -300px;
125
- padding: 10px;
126
- border-radius: 5px;
127
- background-color: rgba(255, 255, 255, 0.6);
128
- transition-property: left;
129
- transition-duration: 500ms;
130
- }
131
-
132
- @media (min-width: 899px) {
133
- .learn-bar {
134
- width: auto;
135
- padding-left: 300px;
136
- }
137
-
138
- .learn-bar > .learn {
139
- left: 8px;
140
- }
141
- }
142
-
143
- html,
144
- body {
145
- margin: 0;
146
- padding: 0;
147
- }
148
-
149
- button {
150
- margin: 0;
151
- padding: 0;
152
- border: 0;
153
- background: none;
154
- font-size: 100%;
155
- vertical-align: baseline;
156
- font-family: inherit;
157
- font-weight: inherit;
158
- color: inherit;
159
- -webkit-appearance: none;
160
- appearance: none;
161
- -webkit-font-smoothing: antialiased;
162
- -moz-osx-font-smoothing: grayscale;
163
- }
164
-
165
- body {
166
- font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
167
- line-height: 1.4em;
168
- background: #f5f5f5;
169
- color: #4d4d4d;
170
- min-width: 230px;
171
- max-width: 550px;
172
- margin: 0 auto;
173
- -webkit-font-smoothing: antialiased;
174
- -moz-osx-font-smoothing: grayscale;
175
- font-weight: 300;
176
- }
177
-
178
- :focus {
179
- outline: 0;
180
- }
181
-
182
- .hidden {
183
- display: none;
184
- }
185
-
186
- .todoapp {
187
- background: #fff;
188
- margin: 130px 0 40px 0;
189
- position: relative;
190
- box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
191
- }
192
-
193
- .todoapp input::-webkit-input-placeholder {
194
- font-style: italic;
195
- font-weight: 300;
196
- color: #e6e6e6;
197
- }
198
-
199
- .todoapp input::-moz-placeholder {
200
- font-style: italic;
201
- font-weight: 300;
202
- color: #e6e6e6;
203
- }
204
-
205
- .todoapp input::input-placeholder {
206
- font-style: italic;
207
- font-weight: 300;
208
- color: #e6e6e6;
209
- }
210
-
211
- .todoapp h1 {
212
- position: absolute;
213
- top: -155px;
214
- width: 100%;
215
- font-size: 100px;
216
- font-weight: 100;
217
- text-align: center;
218
- color: rgba(175, 47, 47, 0.15);
219
- -webkit-text-rendering: optimizeLegibility;
220
- -moz-text-rendering: optimizeLegibility;
221
- text-rendering: optimizeLegibility;
222
- }
223
-
224
- .new-todo,
225
- .edit {
226
- position: relative;
227
- margin: 0;
228
- width: 100%;
229
- font-size: 24px;
230
- font-family: inherit;
231
- font-weight: inherit;
232
- line-height: 1.4em;
233
- border: 0;
234
- color: inherit;
235
- padding: 6px;
236
- border: 1px solid #999;
237
- box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
238
- box-sizing: border-box;
239
- -webkit-font-smoothing: antialiased;
240
- -moz-osx-font-smoothing: grayscale;
241
- }
242
-
243
- .new-todo {
244
- padding: 16px 16px 16px 60px;
245
- border: none;
246
- background: rgba(0, 0, 0, 0.003);
247
- box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
248
- }
249
-
250
- .main {
251
- position: relative;
252
- z-index: 2;
253
- border-top: 1px solid #e6e6e6;
254
- }
255
-
256
- .toggle-all {
257
- text-align: center;
258
- border: none; /* Mobile Safari */
259
- opacity: 0;
260
- position: absolute;
261
- }
262
-
263
- .toggle-all + label {
264
- width: 60px;
265
- height: 34px;
266
- font-size: 0;
267
- position: absolute;
268
- top: -52px;
269
- left: -13px;
270
- -webkit-transform: rotate(90deg);
271
- transform: rotate(90deg);
272
- }
273
-
274
- .toggle-all + label:before {
275
- content: '❯';
276
- font-size: 22px;
277
- color: #e6e6e6;
278
- padding: 10px 27px 10px 27px;
279
- }
280
-
281
- .toggle-all:checked + label:before {
282
- color: #737373;
283
- }
284
-
285
- .todo-list {
286
- margin: 0;
287
- padding: 0;
288
- list-style: none;
289
- }
290
-
291
- .todo-list li {
292
- position: relative;
293
- font-size: 24px;
294
- border-bottom: 1px solid #ededed;
295
- }
296
-
297
- .todo-list li:last-child {
298
- border-bottom: none;
299
- }
300
-
301
- .todo-list li.editing {
302
- border-bottom: none;
303
- padding: 0;
304
- }
305
-
306
- .todo-list li.editing .edit {
307
- display: block;
308
- width: 506px;
309
- padding: 12px 16px;
310
- margin: 0 0 0 43px;
311
- }
312
-
313
- .todo-list li.editing .view {
314
- display: none;
315
- }
316
-
317
- .todo-list li .toggle {
318
- text-align: center;
319
- width: 40px;
320
- /* auto, since non-WebKit browsers doesn't support input styling */
321
- height: auto;
322
- position: absolute;
323
- top: 0;
324
- bottom: 0;
325
- margin: auto 0;
326
- border: none; /* Mobile Safari */
327
- -webkit-appearance: none;
328
- appearance: none;
329
- }
330
-
331
- .todo-list li .toggle {
332
- opacity: 0;
333
- }
334
-
335
- .todo-list li .toggle + label {
336
- /*
337
- Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433
338
- IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/
339
- */
340
- background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E');
341
- background-repeat: no-repeat;
342
- background-position: center left;
343
- }
344
-
345
- .todo-list li .toggle:checked + label {
346
- background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E');
347
- }
348
-
349
- .todo-list li label {
350
- word-break: break-all;
351
- padding: 15px 15px 15px 60px;
352
- display: block;
353
- line-height: 1.2;
354
- transition: color 0.4s;
355
- }
356
-
357
- .todo-list li.completed label {
358
- color: #d9d9d9;
359
- text-decoration: line-through;
360
- }
361
-
362
- .todo-list li .destroy {
363
- display: none;
364
- position: absolute;
365
- top: 0;
366
- right: 10px;
367
- bottom: 0;
368
- width: 40px;
369
- height: 40px;
370
- margin: auto 0;
371
- font-size: 30px;
372
- color: #cc9a9a;
373
- margin-bottom: 11px;
374
- transition: color 0.2s ease-out;
375
- }
376
-
377
- .todo-list li .destroy:hover {
378
- color: #af5b5e;
379
- }
380
-
381
- .todo-list li .destroy:after {
382
- content: '×';
383
- }
384
-
385
- .todo-list li:hover .destroy {
386
- display: block;
387
- }
388
-
389
- .todo-list li .edit {
390
- display: none;
391
- }
392
-
393
- .todo-list li.editing:last-child {
394
- margin-bottom: -1px;
395
- }
396
-
397
- .footer {
398
- color: #777;
399
- padding: 10px 15px;
400
- height: 20px;
401
- text-align: center;
402
- border-top: 1px solid #e6e6e6;
403
- }
404
-
405
- .footer:before {
406
- content: '';
407
- position: absolute;
408
- right: 0;
409
- bottom: 0;
410
- left: 0;
411
- height: 50px;
412
- overflow: hidden;
413
- box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2);
414
- }
415
-
416
- .todo-count {
417
- float: left;
418
- text-align: left;
419
- }
420
-
421
- .todo-count strong {
422
- font-weight: 300;
423
- }
424
-
425
- .filters {
426
- margin: 0;
427
- padding: 0;
428
- list-style: none;
429
- position: absolute;
430
- right: 0;
431
- left: 0;
432
- }
433
-
434
- .filters li {
435
- display: inline;
436
- }
437
-
438
- .filters li a {
439
- color: inherit;
440
- margin: 3px;
441
- padding: 3px 7px;
442
- text-decoration: none;
443
- border: 1px solid transparent;
444
- border-radius: 3px;
445
- }
446
-
447
- .filters li a:hover {
448
- border-color: rgba(175, 47, 47, 0.1);
449
- }
450
-
451
- .filters li a.selected {
452
- border-color: rgba(175, 47, 47, 0.2);
453
- }
454
-
455
- .clear-completed,
456
- html .clear-completed:active {
457
- float: right;
458
- position: relative;
459
- line-height: 20px;
460
- text-decoration: none;
461
- cursor: pointer;
462
- }
463
-
464
- .clear-completed:hover {
465
- text-decoration: underline;
466
- }
467
-
468
- .info {
469
- margin: 65px auto 0;
470
- color: #bfbfbf;
471
- font-size: 10px;
472
- text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
473
- text-align: center;
474
- }
475
-
476
- .info p {
477
- line-height: 1;
478
- }
479
-
480
- .info a {
481
- color: inherit;
482
- text-decoration: none;
483
- font-weight: 400;
484
- }
485
-
486
- .info a:hover {
487
- text-decoration: underline;
488
- }
489
-
490
- /*
491
- Hack to remove background from Mobile Safari.
492
- Can't use it globally since it destroys checkboxes in Firefox
493
- */
494
- @media screen and (-webkit-min-device-pixel-ratio: 0) {
495
- .toggle-all,
496
- .todo-list li .toggle {
497
- background: none;
498
- }
499
-
500
- .todo-list li .toggle {
501
- height: 40px;
502
- }
503
- }
504
-
505
- @media (max-width: 430px) {
506
- .footer {
507
- height: 50px;
508
- }
509
-
510
- .filters {
511
- bottom: 10px;
512
- }
513
- }
_example/components/page.go CHANGED
@@ -8,6 +8,219 @@ import (
8
8
  . "github.com/pyros2097/gromer/handlebars"
9
9
  )
10
10
 
11
+ var _ = Css(`
12
+ hr {
13
+ margin: 20px 0;
14
+ border: 0;
15
+ border-top: 1px dashed #c5c5c5;
16
+ border-bottom: 1px dashed #f7f7f7;
17
+ }
18
+
19
+ html,
20
+ body {
21
+ margin: 0;
22
+ padding: 0;
23
+ }
24
+
25
+ button {
26
+ margin: 0;
27
+ padding: 0;
28
+ border: 0;
29
+ background: none;
30
+ font-size: 100%;
31
+ vertical-align: baseline;
32
+ font-family: inherit;
33
+ font-weight: inherit;
34
+ color: inherit;
35
+ -webkit-appearance: none;
36
+ appearance: none;
37
+ -webkit-font-smoothing: antialiased;
38
+ -moz-osx-font-smoothing: grayscale;
39
+ }
40
+
41
+ body {
42
+ font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
43
+ line-height: 1.4em;
44
+ background: #f5f5f5;
45
+ color: #4d4d4d;
46
+ min-width: 230px;
47
+ max-width: 550px;
48
+ margin: 0 auto;
49
+ -webkit-font-smoothing: antialiased;
50
+ -moz-osx-font-smoothing: grayscale;
51
+ font-weight: 300;
52
+ }
53
+
54
+ :focus {
55
+ outline: 0;
56
+ }
57
+
58
+ .hidden {
59
+ display: none;
60
+ }
61
+
62
+ .new-todo,
63
+ .edit {
64
+ position: relative;
65
+ margin: 0;
66
+ width: 100%;
67
+ font-size: 24px;
68
+ font-family: inherit;
69
+ font-weight: inherit;
70
+ line-height: 1.4em;
71
+ border: 0;
72
+ color: inherit;
73
+ padding: 6px;
74
+ border: 1px solid #999;
75
+ box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
76
+ box-sizing: border-box;
77
+ -webkit-font-smoothing: antialiased;
78
+ -moz-osx-font-smoothing: grayscale;
79
+ }
80
+
81
+ .new-todo {
82
+ padding: 16px 16px 16px 60px;
83
+ border: none;
84
+ background: rgba(0, 0, 0, 0.003);
85
+ box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
86
+ }
87
+
88
+ .main {
89
+ position: relative;
90
+ z-index: 2;
91
+ border-top: 1px solid #e6e6e6;
92
+ }
93
+
94
+ .toggle-all {
95
+ text-align: center;
96
+ border: none; /* Mobile Safari */
97
+ opacity: 0;
98
+ position: absolute;
99
+ }
100
+
101
+ .toggle-all + label {
102
+ width: 60px;
103
+ height: 34px;
104
+ font-size: 0;
105
+ position: absolute;
106
+ top: -52px;
107
+ left: -13px;
108
+ -webkit-transform: rotate(90deg);
109
+ transform: rotate(90deg);
110
+ }
111
+
112
+ .toggle-all + label:before {
113
+ content: '❯';
114
+ font-size: 22px;
115
+ color: #e6e6e6;
116
+ padding: 10px 27px 10px 27px;
117
+ }
118
+
119
+ .toggle-all:checked + label:before {
120
+ color: #737373;
121
+ }
122
+
123
+ .footer {
124
+ color: #777;
125
+ padding: 10px 15px;
126
+ height: 20px;
127
+ text-align: center;
128
+ border-top: 1px solid #e6e6e6;
129
+ }
130
+
131
+ .footer:before {
132
+ content: '';
133
+ position: absolute;
134
+ right: 0;
135
+ bottom: 0;
136
+ left: 0;
137
+ height: 50px;
138
+ overflow: hidden;
139
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2);
140
+ }
141
+
142
+ .filters {
143
+ margin: 0;
144
+ padding: 0;
145
+ list-style: none;
146
+ position: absolute;
147
+ right: 0;
148
+ left: 0;
149
+ }
150
+
151
+ .filters li {
152
+ display: inline;
153
+ }
154
+
155
+ .filters li a {
156
+ color: inherit;
157
+ margin: 3px;
158
+ padding: 3px 7px;
159
+ text-decoration: none;
160
+ border: 1px solid transparent;
161
+ border-radius: 3px;
162
+ }
163
+
164
+ .filters li a:hover {
165
+ border-color: rgba(175, 47, 47, 0.1);
166
+ }
167
+
168
+ .filters li a.selected {
169
+ border-color: rgba(175, 47, 47, 0.2);
170
+ }
171
+
172
+ .clear-completed,
173
+ html .clear-completed:active {
174
+ float: right;
175
+ position: relative;
176
+ line-height: 20px;
177
+ text-decoration: none;
178
+ cursor: pointer;
179
+ }
180
+
181
+ .clear-completed:hover {
182
+ text-decoration: underline;
183
+ }
184
+
185
+ .info {
186
+ margin: 65px auto 0;
187
+ color: #bfbfbf;
188
+ font-size: 10px;
189
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
190
+ text-align: center;
191
+ }
192
+
193
+ .info p {
194
+ line-height: 1;
195
+ }
196
+
197
+ .info a {
198
+ color: inherit;
199
+ text-decoration: none;
200
+ font-weight: 400;
201
+ }
202
+
203
+ .info a:hover {
204
+ text-decoration: underline;
205
+ }
206
+
207
+ @media screen and (-webkit-min-device-pixel-ratio: 0) {
208
+ .toggle-all {
209
+ background: none;
210
+ }
211
+ }
212
+
213
+ @media (max-width: 430px) {
214
+ .footer {
215
+ height: 50px;
216
+ }
217
+
218
+ .filters {
219
+ bottom: 10px;
220
+ }
221
+ }
222
+ `)
223
+
11
224
  type PageProps struct {
12
225
  Title string `json:"title"`
13
226
  Children template.HTML `json:"children"`
@@ -27,7 +240,6 @@ func Page(props PageProps) *Template {
27
240
  <meta name="keywords" content="pyros.sh, pyrossh, gromer" />
28
241
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0, viewport-fit=cover" />
29
242
  <link rel="icon" href="{{ iconUrl }}" />
30
- <link rel="stylesheet" href="{{ todoCssUrl }}" />
31
243
  <link rel="stylesheet" href="{{ stylesCssUrl }}" />
32
244
  <script src="{{ htmxJsUrl }}"></script>
33
245
  <script src="{{ alpineJsUrl }}" defer=""></script>
@@ -38,7 +250,6 @@ func Page(props PageProps) *Template {
38
250
  </html>
39
251
  `).Props(
40
252
  "iconUrl", gromer.GetAssetUrl(assets.FS, "images/icon.png"),
41
- "todoCssUrl", gromer.GetAssetUrl(assets.FS, "css/todo.css"),
42
253
  "stylesCssUrl", gromer.GetStylesUrl(),
43
254
  "htmxJsUrl", gromer.GetAssetUrl(assets.FS, "js/htmx@1.7.0.js"),
44
255
  "alpineJsUrl", gromer.GetAssetUrl(assets.FS, "js/alpinejs@3.9.6.js"),
_example/containers/TodoCount.go CHANGED
@@ -9,6 +9,14 @@ import (
9
9
  )
10
10
 
11
11
  var _ = Css(`
12
+ .todo-count {
13
+ float: left;
14
+ text-align: left;
15
+ }
16
+
17
+ .todo-count strong {
18
+ font-weight: 300;
19
+ }
12
20
  `)
13
21
 
14
22
  type TodoCountProps struct {
_example/containers/TodoList.go CHANGED
@@ -9,6 +9,124 @@ import (
9
9
  )
10
10
 
11
11
  var _ = Css(`
12
+ .todo-list {
13
+ margin: 0;
14
+ padding: 0;
15
+ list-style: none;
16
+ }
17
+
18
+ .todo-list li {
19
+ position: relative;
20
+ font-size: 24px;
21
+ border-bottom: 1px solid #ededed;
22
+ }
23
+
24
+ .todo-list li:last-child {
25
+ border-bottom: none;
26
+ }
27
+
28
+ .todo-list li.editing {
29
+ border-bottom: none;
30
+ padding: 0;
31
+ }
32
+
33
+ .todo-list li.editing .edit {
34
+ display: block;
35
+ width: 506px;
36
+ padding: 12px 16px;
37
+ margin: 0 0 0 43px;
38
+ }
39
+
40
+ .todo-list li.editing .view {
41
+ display: none;
42
+ }
43
+
44
+ .todo-list li .toggle {
45
+ text-align: center;
46
+ width: 40px;
47
+ /* auto, since non-WebKit browsers doesn't support input styling */
48
+ height: auto;
49
+ position: absolute;
50
+ top: 0;
51
+ bottom: 0;
52
+ margin: auto 0;
53
+ border: none; /* Mobile Safari */
54
+ -webkit-appearance: none;
55
+ appearance: none;
56
+ }
57
+
58
+ .todo-list li .toggle {
59
+ opacity: 0;
60
+ }
61
+
62
+ .todo-list li .toggle + label {
63
+ background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E');
64
+ background-repeat: no-repeat;
65
+ background-position: center left;
66
+ }
67
+
68
+ .todo-list li .toggle:checked + label {
69
+ background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E');
70
+ }
71
+
72
+ .todo-list li label {
73
+ word-break: break-all;
74
+ padding: 15px 15px 15px 60px;
75
+ display: block;
76
+ line-height: 1.2;
77
+ transition: color 0.4s;
78
+ }
79
+
80
+ .todo-list li.completed label {
81
+ color: #d9d9d9;
82
+ text-decoration: line-through;
83
+ }
84
+
85
+ .todo-list li .destroy {
86
+ display: none;
87
+ position: absolute;
88
+ top: 0;
89
+ right: 10px;
90
+ bottom: 0;
91
+ width: 40px;
92
+ height: 40px;
93
+ margin: auto 0;
94
+ font-size: 30px;
95
+ color: #cc9a9a;
96
+ margin-bottom: 11px;
97
+ transition: color 0.2s ease-out;
98
+ }
99
+
100
+ .todo-list li .destroy:hover {
101
+ color: #af5b5e;
102
+ }
103
+
104
+ .todo-list li .destroy:after {
105
+ content: '×';
106
+ }
107
+
108
+ .todo-list li:hover .destroy {
109
+ display: block;
110
+ }
111
+
112
+ .todo-list li .edit {
113
+ display: none;
114
+ }
115
+
116
+ .todo-list li.editing:last-child {
117
+ margin-bottom: -1px;
118
+ }
119
+
120
+ @media screen and (-webkit-min-device-pixel-ratio: 0) {
121
+ .todo-list li .toggle {
122
+ background: none;
123
+ }
124
+
125
+ .todo-list li .toggle {
126
+ height: 40px;
127
+ }
128
+ }
129
+
12
130
  `)
13
131
 
14
132
  type TodoListProps struct {
@@ -27,7 +145,7 @@ func TodoList(ctx context.Context, props TodoListProps) (*Template, error) {
27
145
  return nil, err
28
146
  }
29
147
  return Html(`
30
- <ul id="todo-list" class="todo-list">
148
+ <ul id="todo-list" class="relative">
31
149
  {{#each todos as |todo|}}
32
150
  {{#Todo todo=todo}}{{/Todo}}
33
151
  {{/each}}
_example/pages/get.go CHANGED
@@ -7,6 +7,46 @@ import (
7
7
  . "github.com/pyros2097/gromer/handlebars"
8
8
  )
9
9
 
10
+ var _ = Css(`
11
+ .todoapp {
12
+ background: #fff;
13
+ margin: 130px 0 40px 0;
14
+ position: relative;
15
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
16
+ }
17
+
18
+ .todoapp input::-webkit-input-placeholder {
19
+ font-style: italic;
20
+ font-weight: 300;
21
+ color: #e6e6e6;
22
+ }
23
+
24
+ .todoapp input::-moz-placeholder {
25
+ font-style: italic;
26
+ font-weight: 300;
27
+ color: #e6e6e6;
28
+ }
29
+
30
+ .todoapp input::input-placeholder {
31
+ font-style: italic;
32
+ font-weight: 300;
33
+ color: #e6e6e6;
34
+ }
35
+
36
+ .todoapp h1 {
37
+ position: absolute;
38
+ top: -155px;
39
+ width: 100%;
40
+ font-size: 100px;
41
+ font-weight: 100;
42
+ text-align: center;
43
+ color: rgba(175, 47, 47, 0.15);
44
+ -webkit-text-rendering: optimizeLegibility;
45
+ -moz-text-rendering: optimizeLegibility;
46
+ text-rendering: optimizeLegibility;
47
+ }
48
+ `)
49
+
10
50
  type GetParams struct {
11
51
  Page int `json:"page"`
12
52
  Filter string `json:"filter"`
_example/pages/post.go CHANGED
@@ -25,13 +25,16 @@ func POST(ctx context.Context, params PostParams) (HtmlContent, int, error) {
25
25
  return HtmlErr(500, err)
26
26
  }
27
27
  for _, t := range allTodos {
28
+ if t.Completed {
28
- _, err := todos.DeleteTodo(ctx, t.ID)
29
+ _, err := todos.DeleteTodo(ctx, t.ID)
29
- if err != nil {
30
+ if err != nil {
30
- return HtmlErr(500, err)
31
+ return HtmlErr(500, err)
32
+ }
31
33
  }
32
34
  }
33
35
  return Html(`
34
- {{#TodoList id="todo-list"}}{{/TodoList}}
36
+ {{#TodoList id="todo-list" page=1 filter="all"}}{{/TodoList}}
37
+ {{#TodoCount filter="all" page=1}}{{/TodoCount}}
35
38
  `).Render()
36
39
  } else if params.Intent == "create" {
37
40
  todo, err := todos.CreateTodo(ctx, params.Text)