@pageboard/html 0.10.6 → 0.10.10

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.
@@ -54,6 +54,7 @@ exports.input_property = {
54
54
  // /.api/form wraps it into block.data
55
55
  list.shift();
56
56
  name = list.join('.');
57
+ const id = scope.$id;
57
58
  let prop = el;
58
59
  let propKey;
59
60
  let required = false;
@@ -63,6 +64,7 @@ exports.input_property = {
63
64
  required = prop.required && prop.required.indexOf(propKey) >= 0;
64
65
  if (cases) {
65
66
  prop = cases[propKey];
67
+ name = list.slice(0, i - 1).concat(list.slice(i + 1)).join('.');
66
68
  cases = null;
67
69
  } else {
68
70
  if (prop.select && prop.select.$data == `0/${propKey}`) {
@@ -77,8 +79,14 @@ exports.input_property = {
77
79
  }
78
80
  node.textContent = "";
79
81
  if (prop.nullable) required = false;
80
- let listOf = prop.anyOf || prop.oneOf;
81
- let propType;
82
+ let propType = prop;
83
+ let multiple = d.multiple;
84
+ if (prop.type == "array" && prop.items && Array.isArray(prop.items) == false) {
85
+ propType = prop.items;
86
+ multiple = true;
87
+ }
88
+
89
+ let listOf = propType.anyOf || propType.oneOf;
82
90
  if (listOf) {
83
91
  const listOfNo = listOf.filter((item) => item.type != "null");
84
92
  if (listOfNo.length != listOf.length) {
@@ -87,7 +95,7 @@ exports.input_property = {
87
95
  if (listOfNo.length == 1 && listOfNo[0].const === undefined) {
88
96
  propType = listOfNo[0];
89
97
  listOf = null;
90
- } else if (d.multiple) {
98
+ } else if (multiple) {
91
99
  listOf = listOfNo;
92
100
  }
93
101
  } else if (Array.isArray(prop.type)) {
@@ -106,7 +114,6 @@ exports.input_property = {
106
114
  listOf = null; // cannot deal with this for now
107
115
  }
108
116
  }
109
- if (!propType) propType = prop;
110
117
 
111
118
  if (listOf) {
112
119
  if (listOf.length <= d.radios) {
@@ -126,7 +133,8 @@ exports.input_property = {
126
133
  content = content.lastElementChild;
127
134
  for (const item of listOf) {
128
135
  content.appendChild(view.render({
129
- type: d.multiple ? 'input_checkbox' : 'input_radio',
136
+ type: multiple ? 'input_checkbox' : 'input_radio',
137
+ id,
130
138
  data: {
131
139
  name: name,
132
140
  value: item.type == "null" ? null : item.const,
@@ -151,10 +159,11 @@ exports.input_property = {
151
159
  }));
152
160
  }
153
161
  node.appendChild(view.render({
162
+ id,
154
163
  type: 'input_select',
155
164
  data: {
156
165
  name: name,
157
- multiple: d.multiple,
166
+ multiple: multiple,
158
167
  placeholder: prop.description,
159
168
  disabled: d.disabled,
160
169
  required: required
@@ -170,15 +179,16 @@ exports.input_property = {
170
179
  if (propType.minimum != null && propType.maximum != null) {
171
180
  if (propType.maximum - propType.minimum <= d.range) {
172
181
  return node.appendChild(view.render({
182
+ id,
173
183
  type: 'input_range',
174
184
  data: {
175
185
  name: name,
176
186
  min: propType.minimum,
177
187
  max: propType.maximum,
178
- value: d.multiple ? `${propType.minimum}⩽${propType.maximum}` : propType.default,
188
+ value: multiple ? `${propType.minimum}⩽${propType.maximum}` : propType.default,
179
189
  disabled: d.disabled,
180
190
  required: required,
181
- multiple: d.multiple,
191
+ multiple: multiple,
182
192
  step: step
183
193
  },
184
194
  content: {
@@ -188,6 +198,7 @@ exports.input_property = {
188
198
  }
189
199
  }
190
200
  node.appendChild(view.render({
201
+ id,
191
202
  type: 'input_number',
192
203
  data: {
193
204
  name: name,
@@ -204,6 +215,7 @@ exports.input_property = {
204
215
  }));
205
216
  } else if (propType.type == "boolean") {
206
217
  node.appendChild(view.render({
218
+ id,
207
219
  type: 'input_checkbox',
208
220
  data: {
209
221
  name: name,
@@ -221,6 +233,7 @@ exports.input_property = {
221
233
  type = 'input_text';
222
234
  }
223
235
  node.appendChild(view.render({
236
+ id,
224
237
  type: type,
225
238
  data: {
226
239
  name: name,
@@ -240,6 +253,7 @@ exports.input_property = {
240
253
  type = 'input_text';
241
254
  }
242
255
  node.appendChild(view.render({
256
+ id,
243
257
  type: type,
244
258
  data: {
245
259
  name: name,
@@ -255,7 +269,7 @@ exports.input_property = {
255
269
  }));
256
270
  } else if (propType.$helper && propType.$helper.name == "href") {
257
271
  const limits = {
258
- files: d.multiple ? null : 1
272
+ files: multiple ? null : 1
259
273
  };
260
274
  const filter = propType.$helper.filter;
261
275
  if (filter && filter.type) {
@@ -266,6 +280,7 @@ exports.input_property = {
266
280
  });
267
281
  }
268
282
  node.appendChild(view.render({
283
+ id,
269
284
  type: 'input_file',
270
285
  data: {
271
286
  name: name,
@@ -280,10 +295,11 @@ exports.input_property = {
280
295
  }));
281
296
  } else {
282
297
  node.appendChild(view.render({
298
+ id,
283
299
  type: 'input_text',
284
300
  data: {
285
301
  name: name,
286
- type: propType.format ? 'text' : 'textarea',
302
+ type: (propType.pattern || propType.format) ? 'text' : 'textarea',
287
303
  disabled: d.disabled,
288
304
  default: propType.default,
289
305
  placeholder: propType.description,
@@ -5,6 +5,25 @@ exports.fieldset = {
5
5
  group: 'block',
6
6
  context: 'form//',
7
7
  properties: {
8
+ name: {
9
+ title: 'Show if input named',
10
+ type: 'string',
11
+ format: 'singleline',
12
+ nullable: true,
13
+ $helper: {
14
+ name: 'element-property',
15
+ existing: true
16
+ }
17
+ },
18
+ value: {
19
+ title: 'matches this value',
20
+ type: 'string',
21
+ format: 'singleline',
22
+ $filter: {
23
+ name: 'element-value',
24
+ using: 'name'
25
+ }
26
+ },
8
27
  plain: {
9
28
  title: 'Without borders',
10
29
  type: 'boolean',
@@ -12,7 +31,8 @@ exports.fieldset = {
12
31
  }
13
32
  },
14
33
  contents: "fieldset_legend block+",
15
- html: '<fieldset class="[plain|?]"></fieldset>'
34
+ html: '<fieldset class="[plain|?]" data-name="[name]" data-value="[value]" is="element-fieldset"></fieldset>',
35
+ scripts: ["../ui/fieldset.js"]
16
36
  };
17
37
 
18
38
  exports.fieldset_legend = {
@@ -204,8 +224,8 @@ exports.input_text = {
204
224
  };
205
225
 
206
226
  exports.input_number = {
207
- title: 'Number input',
208
- icon: '<i class="text cursor icon">n</i>',
227
+ title: 'Number',
228
+ icon: '<i class="text cursor icon"></i>',
209
229
  menu: "form",
210
230
  required: ["name"],
211
231
  group: "block",
@@ -339,8 +359,8 @@ exports.input_checkbox = {
339
359
  <div class="ui [toggle|?] checkbox">
340
360
  <input type="checkbox" required="[required]" disabled="[disabled]"
341
361
  name="[name]" value="[value]" checked="[checked]"
342
- id="for-[name][value|or:|pre:-]" />
343
- <label block-content="label" for="for-[name][value|or:|pre:-]">Label</label>
362
+ id="for-[name][value|or:|pre:-]-[$id|slice:0:6]" />
363
+ <label block-content="label" for="for-[name][value|or:|pre:-]-[$id|slice:0:6]">Label</label>
344
364
  </div>
345
365
  </div>`,
346
366
  stylesheets: [
@@ -385,8 +405,8 @@ exports.input_radio = {
385
405
  <div class="ui radio checkbox">
386
406
  <input type="radio" disabled="[disabled]"
387
407
  name="[name]" value="[value|or:]" checked="[checked]"
388
- id="for-[name][value|or:|pre:-]" />
389
- <label block-content="label" for="for-[name][value|or:|pre:-]">Label</label>
408
+ id="for-[name][value|or:|pre:-]-[$id|slice:0:6]" />
409
+ <label block-content="label" for="for-[name][value|or:|pre:-]-[$id|slice:0:6]">Label</label>
390
410
  </div>
391
411
  </div>`,
392
412
  stylesheets: [
package/elements/form.js CHANGED
@@ -17,7 +17,7 @@ exports.query_form = {
17
17
  description: 'Checks schema and helps adding form controls',
18
18
  nullable: true,
19
19
  type: 'string',
20
- format: 'id',
20
+ format: 'name',
21
21
  $filter: {
22
22
  name: 'element',
23
23
  contentless: true,
@@ -128,7 +128,7 @@ exports.heading = {
128
128
  id: {
129
129
  nullable: true,
130
130
  type: 'string',
131
- format: 'id'
131
+ pattern: '^[a-z0-9-]*$'
132
132
  }
133
133
  },
134
134
  contents: {
@@ -38,20 +38,14 @@
38
38
  z-index: 1;
39
39
  top: 0;
40
40
  right: 0;
41
+ height: 100%;
42
+ width: 100%;
41
43
  -ms-transform-origin: 0 0;
42
44
  -webkit-transform-origin: 0 0;
43
45
  -webkit-transform-style: preserve-3d;
44
46
  transform-origin: 0 0;
45
47
  transform-style: flat;
46
48
  }
47
- .noUi-connect {
48
- height: 100%;
49
- width: 100%;
50
- }
51
- .noUi-origin {
52
- height: 10%;
53
- width: 10%;
54
- }
55
49
  /* Offset direction
56
50
  */
57
51
  .noUi-txt-dir-rtl.noUi-horizontal .noUi-origin {
@@ -62,6 +56,7 @@
62
56
  * connect elements.
63
57
  */
64
58
  .noUi-vertical .noUi-origin {
59
+ top: -100%;
65
60
  width: 0;
66
61
  }
67
62
  .noUi-horizontal .noUi-origin {
@@ -102,7 +97,7 @@
102
97
  width: 28px;
103
98
  height: 34px;
104
99
  right: -6px;
105
- top: -17px;
100
+ bottom: -17px;
106
101
  }
107
102
  .noUi-txt-dir-rtl.noUi-horizontal .noUi-handle {
108
103
  left: -17px;
package/lib/nouislider.js CHANGED
@@ -281,17 +281,8 @@
281
281
  }
282
282
  }
283
283
  Spectrum.prototype.getDistance = function (value) {
284
- var index;
285
284
  var distances = [];
286
- for (index = 0; index < this.xNumSteps.length - 1; index++) {
287
- // last "range" can't contain step size as it is purely an endpoint.
288
- var step = this.xNumSteps[index];
289
- if (step && (value / step) % 1 !== 0) {
290
- throw new Error("noUiSlider: 'limit', 'margin' and 'padding' of " +
291
- this.xPct[index] +
292
- "% range must be divisible by step.");
293
- }
294
- // Calculate percentual distance in current range of limit, margin or padding
285
+ for (var index = 0; index < this.xNumSteps.length - 1; index++) {
295
286
  distances[index] = fromPercentage(this.xVal, value, index);
296
287
  }
297
288
  return distances;
@@ -1896,7 +1887,7 @@
1896
1887
  scope_Locations[handleNumber] = to;
1897
1888
  // Convert the value to the slider stepping/range.
1898
1889
  scope_Values[handleNumber] = scope_Spectrum.fromStepping(to);
1899
- var translation = 10 * (transformDirection(to, 0) - scope_DirOffset);
1890
+ var translation = transformDirection(to, 0) - scope_DirOffset;
1900
1891
  var translateRule = "translate(" + inRuleOrder(translation + "%", "0") + ")";
1901
1892
  scope_Handles[handleNumber].style[options.transformRule] = translateRule;
1902
1893
  updateConnect(handleNumber);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pageboard/html",
3
- "version": "0.10.6",
3
+ "version": "0.10.10",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -19,14 +19,14 @@
19
19
  },
20
20
  "homepage": "https://github.com/pageboard/client#readme",
21
21
  "dependencies": {
22
- "postinstall": "^0.7.3",
22
+ "postinstall": "^0.7.4",
23
23
  "semantic-ui-css": "^2.4.1"
24
24
  },
25
25
  "devDependencies": {
26
- "formdata-polyfill": "^4.0.7",
27
- "nouislider": "^15.4.0",
26
+ "formdata-polyfill": "^4.0.10",
27
+ "nouislider": "^15.5.0",
28
28
  "object-fit-images": "^3.2.4",
29
- "postinstall-bundle": "^0.7.3"
29
+ "postinstall-bundle": "^0.7.4"
30
30
  },
31
31
  "postinstall": {
32
32
  "semantic-ui-css/components": "link lib/components",
package/ui/fieldset.js ADDED
@@ -0,0 +1,36 @@
1
+ class HTMLCustomFieldSetElement extends HTMLFieldSetElement {
2
+ static defaults = {
3
+ dataName: null,
4
+ dataValue: null
5
+ };
6
+ constructor() {
7
+ super();
8
+ this.init?.();
9
+ }
10
+
11
+ #update() {
12
+ if (this.isContentEditable || !this.options.name) return;
13
+ const name = this.options.name.split(".").slice(1).join('.');
14
+ const val = this.form?.read(true)?.[name];
15
+ this.disabled = this.hidden = val != this.options.value;
16
+ }
17
+
18
+ patch() {
19
+ this.#update();
20
+ }
21
+ setup() {
22
+ this.form?.addEventListener('change', this);
23
+ }
24
+ close() {
25
+ this.form?.removeEventListener('change', this);
26
+ }
27
+ handleEvent(e) {
28
+ if (e.type == "change") {
29
+ this.#update();
30
+ }
31
+ }
32
+ }
33
+
34
+ Page.ready(() => {
35
+ VirtualHTMLElement.define(`element-fieldset`, HTMLCustomFieldSetElement, 'fieldset');
36
+ });
package/ui/form.js CHANGED
@@ -87,6 +87,8 @@ class HTMLCustomFormElement extends HTMLFormElement {
87
87
  }
88
88
  }
89
89
  const btn = document.activeElement;
90
+ // FIXME https://github.com/whatwg/html/issues/3195 use e.submitter polyfill
91
+ // https://github.com/whatwg/xhr/issues/262 it's a mess
90
92
  if (btn && btn.type == "submit" && btn.name && btn.value) {
91
93
  query[btn.name] = btn.value;
92
94
  }
package/ui/select.js CHANGED
@@ -100,11 +100,15 @@ class HTMLElementSelect extends VirtualHTMLElement {
100
100
  }
101
101
  #setPlaceholder(str) {
102
102
  const text = this.#text;
103
- text.textContent = str || this.options.placeholder;
104
- text.classList.add('default');
103
+ if (!str) str = this.options.placeholder;
105
104
 
106
105
  const defaultOption = this.#select.querySelector('option[value=""]');
107
- if (defaultOption) defaultOption.innerHTML = str || "-";
106
+ if (defaultOption) {
107
+ if (!str) str = defaultOption.innerHTML;
108
+ else defaultOption.innerHTML = str;
109
+ }
110
+ text.textContent = str;
111
+ text.classList.add('default');
108
112
  }
109
113
 
110
114
  #menuOption(val) {
@@ -124,11 +128,13 @@ class HTMLElementSelect extends VirtualHTMLElement {
124
128
  const select = this.#select;
125
129
  if (!select) return;
126
130
  const menu = this.#menu;
127
- select.innerHTML = '<option selected value="">-</option>';
128
- menu.children.forEach(item => select.insertAdjacentHTML(
129
- 'beforeEnd',
130
- `<option value="${item.dataset.value || item.innerText.trim()}">${item.innerHTML}</option>`
131
- ));
131
+ menu.children.forEach(item => {
132
+ const val = item.dataset.value || item.innerText != "-" && item.innerText.trim() || "";
133
+ select.insertAdjacentHTML(
134
+ 'beforeEnd',
135
+ `<option value="${val}">${item.innerHTML}</option>`
136
+ );
137
+ });
132
138
  }
133
139
  setup(state) {
134
140
  this.#observer = new MutationObserver((mutations) => this.#fillSelect());
@@ -154,6 +160,12 @@ class HTMLElementSelect extends VirtualHTMLElement {
154
160
  for (const node of this.querySelectorAll('.ui.label')) node.remove();
155
161
  }
156
162
  select.name = this.options.name;
163
+ if (!select.required) {
164
+ const menu = this.#menu;
165
+ if (!menu.querySelector('element-select-option[data-value=""]')) {
166
+ menu.insertAdjacentHTML('afterBegin', `<element-select-option data-value="" block-type="input_select_option" class="item">-</element-select-option>`);
167
+ }
168
+ }
157
169
  this.#fillSelect();
158
170
  }
159
171