@pageboard/html 0.11.6 → 0.11.7

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.
@@ -41,6 +41,7 @@ exports.input_property = {
41
41
  fuse: function(node, d, scope) {
42
42
  const view = scope.$view;
43
43
  const doc = scope.$doc;
44
+ const dateFormats = ["date", "time", "date-time"];
44
45
  let name = d.name;
45
46
  if (!name) {
46
47
  return node;
@@ -242,8 +243,40 @@ exports.input_property = {
242
243
  label: prop.title
243
244
  }
244
245
  }));
245
- } else if (propType.type == "string" && ["date", "time", "date-time"].includes(propType.format)) {
246
+ } else if (propType.type == "object" && Object.keys(propType.properties).sort().join(' ') == "end start" && dateFormats.includes(propType.properties.start.format) && dateFormats.includes(propType.properties.end.format)) {
246
247
  node.appendChild(view.render({
248
+ id,
249
+ type: 'input_date_slot',
250
+ data: {
251
+ nameStart: name,
252
+ nameEnd: name,
253
+ format: propType.properties.start.format.replace('-', ''),
254
+ disabled: d.disabled,
255
+ required: required,
256
+ step: propType.properties.start.step
257
+ },
258
+ content: {
259
+ label: prop.title
260
+ }
261
+ }));
262
+ } else if (propType.type == "string" && dateFormats.includes(propType.format)) {
263
+ if (d.multiple) node.appendChild(view.render({
264
+ id,
265
+ type: 'input_date_slot',
266
+ data: {
267
+ nameStart: name,
268
+ nameEnd: name,
269
+ format: propType.format.replace('-', ''),
270
+ default: propType.default,
271
+ disabled: d.disabled,
272
+ required: required,
273
+ step: propType.step
274
+ },
275
+ content: {
276
+ label: prop.title
277
+ }
278
+ }));
279
+ else node.appendChild(view.render({
247
280
  id,
248
281
  type: 'input_date_time',
249
282
  data: {
@@ -233,7 +233,7 @@ exports.input_range = {
233
233
  menu: "form",
234
234
  group: "block",
235
235
  context: 'form//',
236
- properties: {
236
+ properties: Object.assign({}, exports.input_number.properties, {
237
237
  multiple: {
238
238
  title: 'Multiple',
239
239
  type: 'boolean',
@@ -242,10 +242,14 @@ exports.input_range = {
242
242
  pips: {
243
243
  title: 'Pips',
244
244
  type: 'boolean',
245
- default: true
245
+ default: false
246
246
  },
247
- ...exports.input_number.properties
248
- },
247
+ step: {
248
+ title: 'Step',
249
+ type: "number",
250
+ default: 10
251
+ }
252
+ }),
249
253
  contents: {
250
254
  id: 'label',
251
255
  nodes: 'inline*'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pageboard/html",
3
- "version": "0.11.6",
3
+ "version": "0.11.7",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "devDependencies": {
26
26
  "formdata-polyfill": "^4.0.10",
27
- "nouislider": "^15.5.1",
27
+ "nouislider": "^15.6.0",
28
28
  "object-fit-images": "^3.2.4",
29
29
  "postinstall-bundle": "^0.7.4"
30
30
  },
@@ -122,6 +122,12 @@ class HTMLElementFieldsetList extends VirtualHTMLElement {
122
122
  while (node.previousSibling) node.previousSibling.remove();
123
123
  node = node.parentNode;
124
124
  }
125
+ {
126
+ const hidden = tpl.ownerDocument.createElement('input');
127
+ hidden.type = "hidden";
128
+ hidden.name = prefix.slice(0, -1);
129
+ tpl.appendChild(hidden);
130
+ }
125
131
  }
126
132
  tpl = tpl.fuse({ $fieldset }, scope);
127
133
 
package/ui/fieldset.css CHANGED
@@ -11,7 +11,7 @@ fieldset.plain {
11
11
  fieldset.plain > legend {
12
12
  display:none;
13
13
  }
14
- fieldset:not(.plain) > legend {
14
+ fieldset:not(.plain) > legend:not(:empty) {
15
15
  padding-left:0.1em;
16
16
  padding-right:0.2em;
17
17
  }
package/ui/form.js CHANGED
@@ -51,10 +51,16 @@ class HTMLCustomFormElement extends HTMLFormElement {
51
51
  // build array-like values
52
52
  const old = query[key];
53
53
  if (old !== undefined) {
54
- if (!Array.isArray(old)) {
55
- query[key] = old == null ? [] : [old];
54
+ if (old == null) {
55
+ if (val == null) {
56
+ // keep it that way
57
+ } else {
58
+ query[key] = [];
59
+ }
60
+ } else if (val != null) {
61
+ if (!Array.isArray(old)) query[key] = [old];
62
+ query[key].push(val);
56
63
  }
57
- if (val !== undefined) query[key].push(val);
58
64
  } else {
59
65
  query[key] = val;
60
66
  }
@@ -119,9 +125,16 @@ class HTMLCustomFormElement extends HTMLFormElement {
119
125
  if (name in query && !vars.includes(name)) vars.push(name);
120
126
  const val = query[name];
121
127
  const str = ((v) => {
122
- if (v == null) return "";
123
- else if (typeof v == "object") return v;
124
- else return v.toString();
128
+ if (v == null) {
129
+ return "";
130
+ } else if (Array.isArray(v)) {
131
+ if (["radio", "checkbox"].includes(elem.type)) return v;
132
+ else return v.shift();
133
+ } else if (typeof v == "object") {
134
+ return v;
135
+ } else {
136
+ return v.toString();
137
+ }
125
138
  })(val);
126
139
  switch (elem.type) {
127
140
  case 'submit':
@@ -29,11 +29,14 @@ class HTMLElementInputDateSlot extends VirtualHTMLElement {
29
29
  const [startEl, endEl] = this.#inputs();
30
30
  const isStart = input == startEl;
31
31
 
32
- let start = startEl.valueAsDate;
32
+ const start = startEl.valueAsDate;
33
33
  let end = endEl.valueAsDate;
34
34
  if (!start && !end) return;
35
- if (!start) start = new Date(end);
36
- else if (!end) end = new Date(start);
35
+ if (!start) {
36
+ endEl.valueAsDate = null;
37
+ return;
38
+ }
39
+ if (!end) end = new Date(start);
37
40
  let startPart, endPart;
38
41
  let equal = true;
39
42
  for (const Part of ['FullYear', 'Month', 'Date', 'Hours', 'Minutes', 'Seconds']) {
package/ui/input-date.js CHANGED
@@ -26,7 +26,7 @@ class HTMLElementInputDate extends HTMLInputElement {
26
26
  return d;
27
27
  }
28
28
  set valueAsDate(d) {
29
- let t = d.getTime();
29
+ let t = d?.getTime();
30
30
  if (!d || Number.isNaN(t)) {
31
31
  super.value = "";
32
32
  return;
package/ui/input-range.js CHANGED
@@ -16,11 +16,12 @@ class HTMLElementInputRange extends HTMLInputElement {
16
16
  max: (x) => parseFloat(x) || 100,
17
17
  value: (x) => this.parse(x),
18
18
  step: (x) => parseFloat(x) || 1,
19
- multiple: true,
20
- pips: true,
19
+ multiple: false,
20
+ pips: false
21
21
  };
22
22
 
23
23
  get helper() {
24
+ if (!this.parentNode) return null;
24
25
  let node = this.parentNode.querySelector('.noUi-target');
25
26
  if (!node) {
26
27
  node = this.ownerDocument.createElement('div');
@@ -43,19 +44,35 @@ class HTMLElementInputRange extends HTMLInputElement {
43
44
  this.rangeValue = this.constructor.parse(str);
44
45
  this.updateSlider();
45
46
  }
47
+ convertOptions(opts) {
48
+ return {
49
+ step: Math.max(opts.step ?? 10, Math.round((opts.max - opts.min) / 10)),
50
+ range: {
51
+ min: opts.min ?? 0,
52
+ max: opts.max ?? 100
53
+ },
54
+ pips: opts.pips ? {
55
+ mode: 'steps',
56
+ density: 100
57
+ } : false,
58
+ };
59
+ }
46
60
  updateSlider() {
47
61
  const helper = this.helper;
48
- if (!helper.noUiSlider) return;
49
- let [start, stop] = this.options.value || [];
62
+ const slider = helper?.noUiSlider;
63
+ if (!slider) return;
64
+ const opts = this.options;
65
+ let [start, stop] = opts.value || [];
50
66
  let indet = false;
51
67
  if (start == null) {
52
- start = this.options.min;
53
- if (stop == null) stop = this.options.max;
68
+ start = opts.min;
69
+ if (stop == null) stop = opts.max;
54
70
  indet = true;
55
71
  }
56
72
  if (stop == null) stop = start;
57
73
 
58
- helper.noUiSlider.set([start, stop]);
74
+ slider.set([start, stop]);
75
+ slider.updateOptions(this.convertOptions(opts));
59
76
  helper.classList.toggle('indeterminate', indet);
60
77
  }
61
78
  patch(state) {
@@ -64,19 +81,12 @@ class HTMLElementInputRange extends HTMLInputElement {
64
81
  setup(state) {
65
82
  const opts = this.options;
66
83
  const helper = this.helper;
67
- if (!helper.noUiSlider) window.noUiSlider.create(helper, {
84
+ if (!helper) return;
85
+ if (!helper.noUiSlider) window.noUiSlider.create(helper, Object.assign({
68
86
  start: opts.multiple ? [null, null] : [null],
69
- step: opts.step,
70
- range: {
71
- min: opts.min,
72
- max: opts.max
73
- },
74
- pips: opts.pips ? {
75
- mode: 'steps',
76
- density: 100
77
- } : false,
78
87
  connect: true
79
- }).on('change', (values) => {
88
+ }, this.convertOptions(opts))).on('change', (values) => {
89
+ if (this.isContentEditable) return;
80
90
  const isInt = parseInt(opts.step) == opts.step;
81
91
  helper.classList.remove('indeterminate');
82
92
  if (isInt) values = values.map((n) => parseInt(n));
@@ -91,6 +101,7 @@ class HTMLElementInputRange extends HTMLInputElement {
91
101
  this.patch(state);
92
102
  }
93
103
  handleEvent(e) {
104
+ if (this.isContentEditable) return;
94
105
  if (e.type == "dblclick" || e.keyCode == 8 || e.keyCode == 46) {
95
106
  this.fill();
96
107
  this.dispatchEvent(new Event('change', {
@@ -102,6 +113,7 @@ class HTMLElementInputRange extends HTMLInputElement {
102
113
 
103
114
  close() {
104
115
  const helper = this.helper;
116
+ if (!helper) return;
105
117
  if (helper.noUiSlider) helper.noUiSlider.destroy();
106
118
  helper.removeEventListener('keydown', this, true);
107
119
  helper.removeEventListener('dblclick', this, true);