@pageboard/html 0.10.9 → 0.10.14

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/ui/card.css CHANGED
@@ -6,19 +6,19 @@
6
6
  max-width:100%;
7
7
  }
8
8
  .ui.square > .ui > .image::after {
9
- content: '';
9
+ content: "";
10
10
  display: block;
11
11
  height: 0;
12
12
  padding-bottom: 100%;
13
13
  }
14
14
  .ui.tall > .ui > .image::after {
15
- content: '';
15
+ content: "";
16
16
  display: block;
17
17
  height: 0;
18
18
  padding-bottom: 150%;
19
19
  }
20
20
  .ui.wide > .ui > .image::after {
21
- content: '';
21
+ content: "";
22
22
  display: block;
23
23
  height: 0;
24
24
  padding-bottom:50%;
@@ -34,10 +34,10 @@
34
34
  background: #FFFFFF;
35
35
  padding: 0em;
36
36
  border: none;
37
- border-radius: 0.28571429rem;
37
+ border-radius: 0.2857rem;
38
38
  box-shadow: 0px 1px 3px 0px #D4D4D5, 0px 0px 0px 1px #D4D4D5;
39
39
  transition: box-shadow 0.1s ease, transform 0.1s ease;
40
- z-index: '';
40
+ z-index: auto;
41
41
  margin: 0.875em 0.5em;
42
42
  float: none;
43
43
  font-size: 1em;
@@ -67,7 +67,7 @@
67
67
  .ui.cards::after,
68
68
  .ui.cards > .ui::after {
69
69
  display: block;
70
- content: ' ';
70
+ content: " ";
71
71
  height: 0px;
72
72
  clear: both;
73
73
  overflow: hidden;
@@ -84,14 +84,14 @@
84
84
  ---------------*/
85
85
 
86
86
  .ui.cards > .ui > :first-child {
87
- border-radius: 0.28571429rem 0.28571429rem 0em 0em !important;
87
+ border-radius: 0.2857rem 0.2857rem 0em 0em !important;
88
88
  border-top: none !important;
89
89
  }
90
90
  .ui.cards > .ui > :last-child {
91
- border-radius: 0em 0em 0.28571429rem 0.28571429rem !important;
91
+ border-radius: 0em 0em 0.2857rem 0.2857rem !important;
92
92
  }
93
93
  .ui.cards > .ui > :only-child {
94
- border-radius: 0.28571429rem !important;
94
+ border-radius: 0.2857rem !important;
95
95
  }
96
96
 
97
97
  /*--------------
@@ -103,7 +103,7 @@
103
103
  display: block;
104
104
  flex: 0 0 auto;
105
105
  padding: 0em;
106
- background: rgba(0, 0, 0, 0.05);
106
+ background: rgba(0 0 0 / 5%);
107
107
  overflow: hidden;
108
108
  }
109
109
  .ui.cards > .ui > .image > img {
@@ -123,17 +123,17 @@
123
123
  .ui.cards > .ui > .content {
124
124
  flex-grow: 1;
125
125
  border: none;
126
- border-top: 1px solid rgba(34, 36, 38, 0.1);
126
+ border-top: 1px solid rgba(34 36 38 / 10%);
127
127
  background: none;
128
128
  margin: 0em;
129
- padding: 1em 1em;
129
+ padding: 1em;
130
130
  box-shadow: none;
131
131
  font-size: 1em;
132
132
  border-radius: 0em;
133
133
  }
134
134
  .ui.cards > .ui > .content::after {
135
135
  display: block;
136
- content: ' ';
136
+ content: " ";
137
137
  height: 0px;
138
138
  clear: both;
139
139
  overflow: hidden;
@@ -141,17 +141,17 @@
141
141
  }
142
142
  .ui.cards > .ui > .content > .header {
143
143
  display: block;
144
- margin: '';
145
- font-family: 'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif;
146
- color: rgba(0, 0, 0, 0.85);
144
+ margin: 0;
145
+ font-family: Lato, "Helvetica Neue", Arial, Helvetica, sans-serif;
146
+ color: rgba(0 0 0 / 85%);
147
147
  }
148
148
 
149
149
  /* Default Header Size */
150
150
  .ui.cards > .ui > .content > .header:not(.ui) {
151
151
  font-weight: bold;
152
- font-size: 1.28571429em;
153
- margin-top: -0.21425em;
154
- line-height: 1.28571429em;
152
+ font-size: 1.2857em;
153
+ margin-top: -0.2142em;
154
+ line-height: 1.2857em;
155
155
  }
156
156
  .ui.cards > .ui > .content > .meta + .description,
157
157
  .ui.cards > .ui > .content > .header + .description {
@@ -190,7 +190,7 @@
190
190
  .ui.cards > .ui .content img {
191
191
  display: inline-block;
192
192
  vertical-align: middle;
193
- width: '';
193
+ width: "";
194
194
  }
195
195
  .ui.cards > .ui img.avatar,
196
196
  .ui.cards > .ui .avatar img {
@@ -205,7 +205,7 @@
205
205
 
206
206
  .ui.cards > .ui > .content > .description {
207
207
  clear: both;
208
- color: rgba(0, 0, 0, 0.68);
208
+ color: rgba(0 0 0 / 68%);
209
209
  }
210
210
 
211
211
  /*--------------
@@ -225,7 +225,7 @@
225
225
 
226
226
  .ui.cards > .ui .meta {
227
227
  font-size: 1em;
228
- color: rgba(0, 0, 0, 0.4);
228
+ color: rgb(0 0 0 / 40%);
229
229
  }
230
230
  .ui.cards > .ui .meta * {
231
231
  margin-right: 0.3em;
@@ -245,16 +245,16 @@
245
245
 
246
246
  /* Generic */
247
247
  .ui.cards > .ui > .content a:not(.ui) {
248
- color: '';
248
+ color: "";
249
249
  transition: color 0.1s ease;
250
250
  }
251
251
  .ui.cards > .ui > .content a:not(.ui):hover {
252
- color: '';
252
+ color: "";
253
253
  }
254
254
 
255
255
  /* Header */
256
256
  .ui.cards > .ui > .content > a.header {
257
- color: rgba(0, 0, 0, 0.85);
257
+ color: rgb(0 0 0 / 85%);
258
258
  }
259
259
  .ui.cards > .ui > .content > a.header:hover {
260
260
  color: #1e70bf;
@@ -262,10 +262,10 @@
262
262
 
263
263
  /* Meta */
264
264
  .ui.cards > .ui .meta > a:not(.ui) {
265
- color: rgba(0, 0, 0, 0.4);
265
+ color: rgb(0 0 0 / 40%);
266
266
  }
267
267
  .ui.cards > .ui .meta > a:not(.ui):hover {
268
- color: rgba(0, 0, 0, 0.87);
268
+ color: rgb(0 0 0 / 87%);
269
269
  }
270
270
 
271
271
  /*--------------
@@ -283,7 +283,7 @@
283
283
  ---------------*/
284
284
 
285
285
  .ui.cards > .ui .dimmer {
286
- background-color: '';
286
+ background-color: "";
287
287
  z-index: 10;
288
288
  }
289
289
 
@@ -298,11 +298,11 @@
298
298
  /* Icon */
299
299
  .ui.cards > .ui > .content .star.icon {
300
300
  cursor: pointer;
301
- opacity: 0.75;
301
+ opacity: 75%;
302
302
  transition: color 0.1s ease;
303
303
  }
304
304
  .ui.cards > .ui > .content .star.icon:hover {
305
- opacity: 1;
305
+ opacity: 100%;
306
306
  color: #FFB70A;
307
307
  }
308
308
  .ui.cards > .ui > .content .active.star.icon {
@@ -315,11 +315,11 @@
315
315
  /* Icon */
316
316
  .ui.cards > .ui > .content .like.icon {
317
317
  cursor: pointer;
318
- opacity: 0.75;
318
+ opacity: 75%;
319
319
  transition: color 0.1s ease;
320
320
  }
321
321
  .ui.cards > .ui > .content .like.icon:hover {
322
- opacity: 1;
322
+ opacity: 100%;
323
323
  color: #FF2733;
324
324
  }
325
325
  .ui.cards > .ui > .content .active.like.icon {
@@ -334,20 +334,20 @@
334
334
  max-width: 100%;
335
335
  min-height: 0em !important;
336
336
  flex-grow: 0;
337
- border-top: 1px solid rgba(0, 0, 0, 0.05) !important;
337
+ border-top: 1px solid rgb(0 0 0 / 5%) !important;
338
338
  position: static;
339
339
  background: none;
340
340
  width: auto;
341
- margin: 0em 0em;
341
+ margin: 0em;
342
342
  padding: 0.75em 1em;
343
343
  top: 0em;
344
344
  left: 0em;
345
- color: rgba(0, 0, 0, 0.4);
345
+ color: rgb(0 0 0 / 40%);
346
346
  box-shadow: none;
347
347
  transition: color 0.1s ease;
348
348
  }
349
349
  .ui.cards > .ui > .extra a:not(.ui) {
350
- color: rgba(0, 0, 0, 0.4);
350
+ color: rgb(0 0 0 / 40%);
351
351
  }
352
352
  .ui.cards > .ui > .extra a:not(.ui):hover {
353
353
  color: #1e70bf;
@@ -364,11 +364,11 @@
364
364
  --------------------*/
365
365
 
366
366
  .ui.raised.cards > .ui {
367
- box-shadow: 0px 0px 0px 1px #D4D4D5, 0px 2px 4px 0px rgba(34, 36, 38, 0.12), 0px 2px 10px 0px rgba(34, 36, 38, 0.15);
367
+ box-shadow: 0px 0px 0px 1px #D4D4D5, 0px 2px 4px 0px rgb(34 36 38 / 12%), 0px 2px 10px 0px rgb(34 36 38 / 15%);
368
368
  }
369
369
  .ui.raised.cards > a.ui:hover,
370
370
  .ui.link.cards > .raised.ui:hover {
371
- box-shadow: 0px 0px 0px 1px #D4D4D5, 0px 2px 4px 0px rgba(34, 36, 38, 0.15), 0px 2px 10px 0px rgba(34, 36, 38, 0.25);
371
+ box-shadow: 0px 0px 0px 1px #D4D4D5, 0px 2px 4px 0px rgb(34 36 38 / 15%), 0px 2px 10px 0px rgb(34 36 38 / 25%);
372
372
  }
373
373
 
374
374
  /*-------------------
@@ -434,7 +434,7 @@
434
434
  margin-right: -1em;
435
435
  }
436
436
  .ui.three.cards > .ui {
437
- width: calc(33.33333333% - 2em);
437
+ width: calc(33.3333% - 2em);
438
438
  margin-left: 1em;
439
439
  margin-right: 1em;
440
440
  }
@@ -461,7 +461,7 @@
461
461
  margin-right: -0.75em;
462
462
  }
463
463
  .ui.six.cards > .ui {
464
- width: calc(16.66666667% - 1.5em);
464
+ width: calc(16.6667% - 1.5em);
465
465
  margin-left: 0.75em;
466
466
  margin-right: 0.75em;
467
467
  }
@@ -470,7 +470,7 @@
470
470
  margin-right: -0.5em;
471
471
  }
472
472
  .ui.seven.cards > .ui {
473
- width: calc(14.28571429% - 1em);
473
+ width: calc(14.2857% - 1em);
474
474
  margin-left: 0.5em;
475
475
  margin-right: 0.5em;
476
476
  }
@@ -489,7 +489,7 @@
489
489
  margin-right: -0.5em;
490
490
  }
491
491
  .ui.nine.cards > .ui {
492
- width: calc(11.11111111% - 1em);
492
+ width: calc(11.1111% - 1em);
493
493
  margin-left: 0.5em;
494
494
  margin-right: 0.5em;
495
495
  font-size: 10px;
@@ -561,7 +561,7 @@
561
561
  margin-right: -1em;
562
562
  }
563
563
  .ui.seven.doubling.cards > .ui {
564
- width: calc(33.33333333% - 2em);
564
+ width: calc(33.3333% - 2em);
565
565
  margin-left: 1em;
566
566
  margin-right: 1em;
567
567
  }
@@ -570,7 +570,7 @@
570
570
  margin-right: -1em;
571
571
  }
572
572
  .ui.eight.doubling.cards > .ui {
573
- width: calc(33.33333333% - 2em);
573
+ width: calc(33.3333% - 2em);
574
574
  margin-left: 1em;
575
575
  margin-right: 1em;
576
576
  }
@@ -579,7 +579,7 @@
579
579
  margin-right: -1em;
580
580
  }
581
581
  .ui.nine.doubling.cards > .ui {
582
- width: calc(33.33333333% - 2em);
582
+ width: calc(33.3333% - 2em);
583
583
  margin-left: 1em;
584
584
  margin-right: 1em;
585
585
  }
@@ -588,7 +588,7 @@
588
588
  margin-right: -1em;
589
589
  }
590
590
  .ui.ten.doubling.cards > .ui {
591
- width: calc(33.33333333% - 2em);
591
+ width: calc(33.3333% - 2em);
592
592
  margin-left: 1em;
593
593
  margin-right: 1em;
594
594
  }
@@ -628,7 +628,7 @@
628
628
  margin-right: -1em;
629
629
  }
630
630
  .ui.five.doubling.cards > .ui {
631
- width: calc(33.33333333% - 2em);
631
+ width: calc(33.3333% - 2em);
632
632
  margin-left: 1em;
633
633
  margin-right: 1em;
634
634
  }
@@ -637,7 +637,7 @@
637
637
  margin-right: -1em;
638
638
  }
639
639
  .ui.six.doubling.cards > .ui {
640
- width: calc(33.33333333% - 2em);
640
+ width: calc(33.3333% - 2em);
641
641
  margin-left: 1em;
642
642
  margin-right: 1em;
643
643
  }
@@ -684,7 +684,7 @@
684
684
  .ui.stackable.cards > .ui {
685
685
  display: block !important;
686
686
  height: auto !important;
687
- margin: 1em 1em;
687
+ margin: 1em;
688
688
  padding: 0 !important;
689
689
  width: calc(100% - 2em) !important;
690
690
  }
@@ -1,5 +1,4 @@
1
1
  class HTMLElementFieldsetList extends VirtualHTMLElement {
2
- #size
3
2
  fill(values, scope) {
4
3
  const list = this.listFromValues(Object.assign({}, values));
5
4
  this.resize(list.length, scope);
@@ -8,7 +7,7 @@ class HTMLElementFieldsetList extends VirtualHTMLElement {
8
7
  patch(state) {
9
8
  this.ownTpl.prerender();
10
9
  if (this.isContentEditable) return;
11
- if (!this.#size) this.resize(0, state.scope);
10
+ if (!this.size) this.resize(0, state.scope);
12
11
  }
13
12
 
14
13
  setup(state) {
@@ -17,8 +16,8 @@ class HTMLElementFieldsetList extends VirtualHTMLElement {
17
16
 
18
17
  resize(size, scope) {
19
18
  const len = Math.max(Number(this.dataset.size) || 0, size);
20
- if (this.#size == len) return;
21
- this.#size = len;
19
+ if (this.size == len) return;
20
+ this.size = len;
22
21
 
23
22
  const tpl = this.ownTpl.content.cloneNode(true);
24
23
  for (const node of tpl.querySelectorAll('[block-id]')) {
package/ui/form.css CHANGED
@@ -3,20 +3,11 @@ fieldset.plain {
3
3
  padding-right:0;
4
4
  padding-left:0;
5
5
  }
6
- textarea::-webkit-selection,
7
- input::-webkit-selection {
8
- background-color: rgba(100, 100, 100, 0.4);
9
- color: rgba(0, 0, 0, 0.87);
10
- }
11
- textarea::-moz-selection,
12
- input::-moz-selection {
13
- background-color: rgba(100, 100, 100, 0.4);
14
- color: rgba(0, 0, 0, 0.87);
15
- }
6
+
16
7
  textarea::selection,
17
8
  input::selection {
18
- background-color: rgba(100, 100, 100, 0.4);
19
- color: rgba(0, 0, 0, 0.87);
9
+ background-color: rgb(100 100 100 / 40%);
10
+ color: rgb(0 0 0 / 87%);
20
11
  }
21
12
 
22
13
  label[for] {
package/ui/form.js CHANGED
@@ -14,7 +14,7 @@ class HTMLCustomFormElement extends HTMLFormElement {
14
14
  if (name && name == this.name) {
15
15
  state.vars.submit = true;
16
16
  }
17
- const vars = state.templatesQuery(this);
17
+ const vars = state.templatesQuery(this) || {};
18
18
  for (const [key, val] of Object.entries(vars)) {
19
19
  this.setAttribute('data-' + key, val);
20
20
  }
@@ -80,6 +80,9 @@ class HTMLCustomFormElement extends HTMLFormElement {
80
80
  if (defVal == "") defVal = null;
81
81
  if (!withDefaults && query[node.name] == defVal) {
82
82
  query[node.name] = undefined;
83
+ } else {
84
+ // not yet using form-associated custom input
85
+ query[node.name] = node.value;
83
86
  }
84
87
  }
85
88
  if (query[node.name] === undefined && withDefaults) {
@@ -181,6 +184,9 @@ class HTMLCustomFormElement extends HTMLFormElement {
181
184
  if (!this.action) return;
182
185
  window.sessionStorage.removeItem(this.action);
183
186
  }
187
+ handleReset(e, state) {
188
+ this.reset();
189
+ }
184
190
  handleSubmit(e, state) {
185
191
  if (e.type == "submit") e.preventDefault();
186
192
  if (this.isContentEditable) return;
@@ -234,9 +240,9 @@ class HTMLCustomFormElement extends HTMLFormElement {
234
240
 
235
241
  const data = { $query };
236
242
  return Promise.all(Array.from(form.elements).filter((node) => {
237
- return node.type == "file";
243
+ return Boolean(node.presubmit);
238
244
  }).map((input) => {
239
- return input.closest('element-input-file').upload();
245
+ return input.presubmit();
240
246
  })).then(() => {
241
247
  data.$query = state.query;
242
248
  data.$request = form.read(true);
@@ -338,6 +344,8 @@ HTMLInputElement.prototype.fill = function (val) {
338
344
  if (val == null) val = "";
339
345
  if (this.type == "radio" || this.type == "checkbox") {
340
346
  this.checked = val;
347
+ } else if (this.type == "file") {
348
+ this.setAttribute('value', val);
341
349
  } else {
342
350
  this.value = val;
343
351
  }
@@ -354,6 +362,8 @@ HTMLInputElement.prototype.reset = function () {
354
362
  HTMLInputElement.prototype.save = function () {
355
363
  if (this.type == "radio" || this.type == "checkbox") {
356
364
  this.defaultChecked = this.checked;
365
+ } else if (this.type == "file") {
366
+ this.defaultValue = this.getAttribute('value');
357
367
  } else {
358
368
  this.defaultValue = this.value;
359
369
  }
@@ -438,6 +448,7 @@ Page.ready((state) => {
438
448
  if (action == "toggle") {
439
449
  action = val ? "enable" : "disable";
440
450
  }
451
+ // NB: call Class methods to deal with uninstantiated custom form
441
452
  if (action == "enable") {
442
453
  HTMLCustomFormElement.prototype.enable.call(form);
443
454
  } else if (action == "disable") {
@@ -457,6 +468,7 @@ Page.ready((state) => {
457
468
  // new way
458
469
  }
459
470
  HTMLCustomFormElement.prototype.fill.call(form, linearizeValues(values), state.scope);
471
+ HTMLCustomFormElement.prototype.save.call(form);
460
472
  }
461
473
  } else if (action == "read") {
462
474
  const obj = {};
@@ -0,0 +1,76 @@
1
+ class HTMLElementInputDateSlot extends VirtualHTMLElement {
2
+ handleChange(e, state) {
3
+ this.update(e.target);
4
+ }
5
+
6
+ get type() {
7
+ const type = this.getAttribute('type');
8
+ const step = this.step;
9
+ if (step) {
10
+ if (step >= 86400) return "date";
11
+ else if (type == "date") return "datetime-local";
12
+ }
13
+ return type;
14
+ }
15
+ set type(f) {
16
+ this.setAttribute('type', f);
17
+ }
18
+ get step() {
19
+ const step = parseInt(this.getAttribute('step'));
20
+ if (Number.isNaN(step)) return null;
21
+ else return step;
22
+ }
23
+ set step(val) {
24
+ if (!val) this.removeAttribute('step');
25
+ else this.setAttribute('step', val);
26
+ }
27
+
28
+ update(input) {
29
+ const [startEl, endEl] = this.#inputs();
30
+ const isStart = input == startEl;
31
+
32
+ let start = startEl.valueAsDate;
33
+ let end = endEl.valueAsDate;
34
+ if (!start && !end) return;
35
+ if (!start) start = new Date(end);
36
+ else if (!end) end = new Date(start);
37
+ let startPart, endPart;
38
+ let equal = true;
39
+ for (const Part of ['FullYear', 'Month', 'Date', 'Hours', 'Minutes', 'Seconds']) {
40
+ startPart = start[`get${Part}`]();
41
+ endPart = end[`get${Part}`]();
42
+ if (startPart > endPart && equal) {
43
+ if (isStart) {
44
+ end[`set${Part}`](startPart);
45
+ } else {
46
+ start[`set${Part}`](endPart);
47
+ }
48
+ } else if (startPart != endPart) {
49
+ equal = false;
50
+ }
51
+ }
52
+ endEl.valueAsDate = end;
53
+ startEl.valueAsDate = start;
54
+ }
55
+ #inputs() {
56
+ return Array.from(this.querySelectorAll('input'));
57
+ }
58
+
59
+ patch(state) {
60
+ const [ start, end ] = this.#inputs();
61
+ const type = this.type;
62
+ let step = this.step;
63
+ if (step) {
64
+ if (type == "date") step = Math.round(step / 86400);
65
+ start.setAttribute('step', step);
66
+ end.setAttribute('step', step);
67
+ } else {
68
+ start.removeAttribute('step');
69
+ end.removeAttribute('step');
70
+ }
71
+ start.type = end.type = type;
72
+ }
73
+ }
74
+
75
+ VirtualHTMLElement.define('element-input-date-slot', HTMLElementInputDateSlot);
76
+
@@ -0,0 +1,69 @@
1
+ class HTMLElementInputDate extends HTMLInputElement {
2
+ constructor() {
3
+ super();
4
+ if (this.init) this.init();
5
+ }
6
+
7
+ setAttribute(name, value) {
8
+ if (name == "value") {
9
+ this.value = value;
10
+ value = super.value;
11
+ }
12
+ super.setAttribute(name, value);
13
+ }
14
+
15
+ get valueAsDate() {
16
+ let str = super.value;
17
+ if (!str) return null;
18
+ if (this.type == "time") {
19
+ str = `1970-01-01T${str}`;
20
+ }
21
+ const d = new Date(str + 'Z');
22
+ const t = d.getTime();
23
+ if (Number.isNaN(t)) return null;
24
+ const tz = d.getTimezoneOffset();
25
+ d.setTime(t + tz * 60 * 1000);
26
+ return d;
27
+ }
28
+ set valueAsDate(d) {
29
+ let t = d.getTime();
30
+ if (!d || Number.isNaN(t)) {
31
+ super.value = "";
32
+ return;
33
+ }
34
+ d = new Date(t);
35
+ const step = this.step * 1000;
36
+ if (step) {
37
+ t = Math.round(t / step) * step;
38
+ d.setTime(t);
39
+ }
40
+ const tz = d.getTimezoneOffset();
41
+ d.setTime(t - tz * 60 * 1000);
42
+ const str = d.toISOString().replace(/Z$/, '');
43
+ if (this.type == "time") {
44
+ super.value = str.split('T')[1];
45
+ } else if (this.type == "date") {
46
+ super.value = str.split('T')[0];
47
+ } else {
48
+ super.value = str;
49
+ }
50
+ }
51
+
52
+ get value() {
53
+ return this.valueAsDate?.toISOString();
54
+ }
55
+ set value(str) {
56
+ this.valueAsDate = new Date(str);
57
+ }
58
+
59
+ get type() {
60
+ return super.type;
61
+ }
62
+ set type(t) {
63
+ const str = super.value;
64
+ super.type = t;
65
+ this.value = str;
66
+ }
67
+ }
68
+
69
+ VirtualHTMLElement.define('element-input-date', HTMLElementInputDate, 'input');