alchemy-form 0.1.1 → 0.1.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 0.1.2 (2022-01-28)
2
+
3
+ * Add readonly attribute to fields
4
+ * Clear text input on focus out + improve accessibility of alchemy-select
5
+ * Add widget settings to alchemy-field
6
+ * Enable setting the language mode of ace editor
7
+
1
8
  ## 0.1.1 (2021-09-12)
2
9
 
3
10
  * `alchemy-table` will now use the `FieldConfig#getDisplayValueIn(data)` method
@@ -3,6 +3,12 @@ alchemy-select {
3
3
  position: relative;
4
4
  display: block;
5
5
 
6
+ --active-item-bg: #a7deff;
7
+ --active-item-fg: #272727;
8
+
9
+ --selected-item-bg: #31317a;
10
+ --selected-item-fg: #f5f5f5;
11
+
6
12
  .dropdown-content,
7
13
  .value-wrapper,
8
14
  .dropdown {
@@ -10,8 +16,6 @@ alchemy-select {
10
16
  }
11
17
 
12
18
  &:focus {
13
- outline: 0 !important;
14
-
15
19
  .value-wrapper {
16
20
  border-color: rgba(82, 168, 236, 0.8) !important;
17
21
  }
@@ -31,6 +35,12 @@ alchemy-select {
31
35
  flex-wrap: wrap;
32
36
  //box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
33
37
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
38
+
39
+ align-items: center;
40
+
41
+ input.type-area {
42
+ height: 1.5rem;
43
+ }
34
44
  }
35
45
 
36
46
  &[aria-expanded="true"] .value-wrapper {
@@ -149,11 +159,15 @@ alchemy-select {
149
159
  .dropdown [role="option"] {
150
160
 
151
161
  &:hover,
152
- &.focused,
153
- &[selected] {
162
+ &.focused {
154
163
  background-color: var(--active-item-bg, #f5fafd);
155
164
  color: var(--active-item-fg, #495c68);
156
165
  }
166
+
167
+ &[selected] {
168
+ background-color: var(--selected-item-bg, #f5fafd);
169
+ color: var(--selected-item-fg, #495c68);
170
+ }
157
171
  }
158
172
 
159
173
  &[aria-expanded="true"] .dropdown {
@@ -54,6 +54,24 @@ Field.setAttribute('field-name');
54
54
  */
55
55
  Field.setAttribute('field-view');
56
56
 
57
+ /**
58
+ * Is this a read only field?
59
+ *
60
+ * @author Jelle De Loecker <jelle@elevenways.be>
61
+ * @since 0.1.2
62
+ * @version 0.1.2
63
+ */
64
+ Field.setAttribute('readonly', {boolean: true});
65
+
66
+ /**
67
+ * Widget settings for use in the views
68
+ *
69
+ * @author Jelle De Loecker <jelle@elevenways.be>
70
+ * @since 0.1.2
71
+ * @version 0.1.2
72
+ */
73
+ Field.setAssignedProperty('widget_settings');
74
+
57
75
  /**
58
76
  * Get the parent alchemy-form element
59
77
  *
@@ -108,7 +108,7 @@ Form.setProperty(function main_error_area() {
108
108
  *
109
109
  * @author Jelle De Loecker <jelle@elevenways.be>
110
110
  * @since 0.1.0
111
- * @version 0.1.0
111
+ * @version 0.1.2
112
112
  */
113
113
  Form.setProperty(function value() {
114
114
 
@@ -125,6 +125,10 @@ Form.setProperty(function value() {
125
125
  for (i = 0; i < fields.length; i++) {
126
126
  field = fields[i];
127
127
 
128
+ if (field && field.readonly) {
129
+ continue;
130
+ }
131
+
128
132
  result[field.field_name] = field.value;
129
133
  }
130
134
 
@@ -403,6 +403,7 @@ AlchemySelect.setMethod(function introduced() {
403
403
  const that = this;
404
404
 
405
405
  this._initAttributes();
406
+ this.enableFocusWithinEvent();
406
407
 
407
408
  if (this.sortable) {
408
409
  this.makeSortable();
@@ -417,6 +418,13 @@ AlchemySelect.setMethod(function introduced() {
417
418
  });
418
419
  }
419
420
 
421
+ this.addEventListener('focus-without', function onFocusOut(e) {
422
+ that.type_area.value = '';
423
+ that.refitTypeArea(e);
424
+ that.applyLocalFilter();
425
+ that.close();
426
+ });
427
+
420
428
  // Give the type area focus when clicking on the wrapper
421
429
  this.wrapper.addEventListener('click', function onClick(e) {
422
430
  that.open();
@@ -430,24 +438,26 @@ AlchemySelect.setMethod(function introduced() {
430
438
 
431
439
  this.addEventListener('keydown', function onKeydown(e) {
432
440
 
441
+ console.log('keydown:', e);
442
+
433
443
  // Only listen for keydowns on the alchemy-select itself
434
444
  if (e.target != that) {
435
445
  return;
436
446
  }
437
447
 
438
- if (e.key == 'Space' || e.key == 'Enter') {
448
+ if (e.code == 'Space' || e.code == 'Enter') {
439
449
  that.open(e);
440
- } else if (e.key == 'Escape') {
450
+ } else if (e.code == 'Escape') {
441
451
  that.close(e);
442
452
  }
443
453
  });
444
454
 
445
455
  this.dropdown_content.addEventListener('keydown', function onKeydown(e) {
446
- if (e.key == 'ArrowUp' || e.key == 'ArrowDown') {
456
+ if (e.code == 'ArrowUp' || e.code == 'ArrowDown') {
447
457
  that.handleArrowKey(e);
448
- } else if (e.key == 'Escape') {
458
+ } else if (e.code == 'Escape') {
449
459
  that.close(e);
450
- } else if (e.key == 'Enter') {
460
+ } else if (e.code == 'Enter') {
451
461
  that.selectFocusedElement(e);
452
462
  }
453
463
  });
@@ -1123,6 +1133,7 @@ AlchemySelect.setMethod(function open(event) {
1123
1133
  * @param {Event} event The optional event
1124
1134
  */
1125
1135
  AlchemySelect.setMethod(function close(event) {
1136
+ this.removeAttribute('aria-activedescendant');
1126
1137
  this.setAttribute('aria-expanded', 'false');
1127
1138
  this.type_area.setAttribute('aria-expanded', 'false');
1128
1139
  this.type_area.setAttribute('tabindex', '-1');
@@ -1130,7 +1141,7 @@ AlchemySelect.setMethod(function close(event) {
1130
1141
  this.classList.remove('open');
1131
1142
  this.emit('close');
1132
1143
 
1133
- if (event === true || (event && event.key == 'Escape')) {
1144
+ if (event === true || (event && event.code == 'Escape')) {
1134
1145
  this.focus();
1135
1146
  this.result_info.textContent = 'Gesloten';
1136
1147
  }
@@ -1303,7 +1314,7 @@ AlchemySelect.setMethod(function handleArrowKey(event) {
1303
1314
  this.open();
1304
1315
  }
1305
1316
 
1306
- if (event.key == 'ArrowUp') {
1317
+ if (event.code == 'ArrowUp') {
1307
1318
  direction = -1;
1308
1319
  } else {
1309
1320
  // Down
@@ -1391,18 +1402,27 @@ AlchemySelect.setMethod(function _focusOnOption(option_element) {
1391
1402
  option_element = this.dropdown_content.children[option_element];
1392
1403
  }
1393
1404
 
1405
+ this.setAttribute('aria-activedescendant', null);
1406
+
1394
1407
  for (i = 0; i < this.dropdown_content.children.length; i++) {
1395
1408
  element = this.dropdown_content.children[i];
1396
1409
 
1397
1410
  if (element == option_element) {
1398
1411
  element.classList.add('focused');
1399
- element.setAttribute('tabindex', 0);
1412
+ //element.setAttribute('tabindex', 0);
1400
1413
  this._selected_entry = element._entry;
1401
1414
  selected_index = i;
1402
- element.focus();
1415
+
1416
+ //element.focus();
1417
+
1418
+ if (!element.id) {
1419
+ element.id = this.hawkejs_view.getId();
1420
+ }
1421
+
1422
+ this.setAttribute('aria-activedescendant', element.id);
1403
1423
  } else {
1404
1424
  element.classList.remove('focused');
1405
- element.setAttribute('tabindex', '-1');
1425
+ //element.setAttribute('tabindex', '-1');
1406
1426
  }
1407
1427
  }
1408
1428
 
@@ -1507,7 +1527,7 @@ AlchemySelect.setMethod(function advanceCaret(direction) {
1507
1527
  */
1508
1528
  AlchemySelect.setMethod(function onTypeAreaKeydown(e, is_input) {
1509
1529
 
1510
- switch (e.key) {
1530
+ switch (e.code) {
1511
1531
  case 'ArrowUp':
1512
1532
  case 'ArrowDown':
1513
1533
  this.handleArrowKey(e);
@@ -1529,6 +1549,10 @@ AlchemySelect.setMethod(function onTypeAreaKeydown(e, is_input) {
1529
1549
  this.removeItem(this.type_area.previousSibling);
1530
1550
  break;
1531
1551
 
1552
+ case 'Enter':
1553
+ this.selectFocusedElement(e);
1554
+ break;
1555
+
1532
1556
  case 'Delete':
1533
1557
  if (this.type_area.value.length) {
1534
1558
  return;
@@ -1549,7 +1573,7 @@ AlchemySelect.setMethod(function onTypeAreaKeydown(e, is_input) {
1549
1573
  */
1550
1574
  AlchemySelect.setMethod(function onTypeAreaKeyup(e, is_input) {
1551
1575
 
1552
- switch (e.key) {
1576
+ switch (e.code) {
1553
1577
  case 'ArrowUp':
1554
1578
  case 'ArrowDown':
1555
1579
  case 'ArrowLeft':
@@ -1818,13 +1842,13 @@ AlchemySelect.setMethod(function measureString(str, element, event) {
1818
1842
  code === 32 // space
1819
1843
  );
1820
1844
 
1821
- if (event.key == 'Delete' || event.key == 'Backspace') {
1845
+ if (event.code == 'Delete' || event.code == 'Backspace') {
1822
1846
  selection = this._getSelection(this.type_area);
1823
1847
  if (selection.length) {
1824
1848
  str = str.substring(0, selection.start) + str.substring(selection.start + selection.length);
1825
- } else if (event.key == 'Backspace' && selection.start) {
1849
+ } else if (event.code == 'Backspace' && selection.start) {
1826
1850
  str = str.substring(0, selection.start - 1) + str.substring(selection.start);
1827
- } else if (event.key == 'Delete' && typeof selection.start !== 'undefined') {
1851
+ } else if (event.code == 'Delete' && typeof selection.start !== 'undefined') {
1828
1852
  str = str.substring(0, selection.start) + str.substring(selection.start + 1);
1829
1853
  }
1830
1854
  } else if (printable) {
@@ -80,5 +80,20 @@ CodeInput.setMethod(async function introduced() {
80
80
  editor.session.setUseWrapMode(true);
81
81
  editor.setFontSize(16);
82
82
 
83
+ let parent_field = this.queryParents('alchemy-field');
84
+
85
+ if (parent_field && parent_field.widget_settings && parent_field.widget_settings.language_mode) {
86
+
87
+ let mode = parent_field.widget_settings.language_mode;
88
+
89
+ // Even though it correctly downloads the language mode file without it,
90
+ // it still requires the `ace/mode/` prefix
91
+ if (mode.indexOf('/') == -1) {
92
+ mode = 'ace/mode/' + mode;
93
+ }
94
+
95
+ editor.session.setMode(mode);
96
+ }
97
+
83
98
  this._editor = editor;
84
99
  });
@@ -33,7 +33,7 @@ AlchemyField.constitute(function prepareSchema() {
33
33
  *
34
34
  * @author Jelle De Loecker <jelle@elevenways.be>
35
35
  * @since 0.1.0
36
- * @version 0.1.0
36
+ * @version 0.1.2
37
37
  */
38
38
  AlchemyField.setMethod(function populateWidget() {
39
39
 
@@ -46,6 +46,14 @@ AlchemyField.setMethod(function populateWidget() {
46
46
  field_el.field_view = config.view;
47
47
  }
48
48
 
49
+ if (config.readonly) {
50
+ field_el.readonly = true;
51
+ }
52
+
53
+ if (config.widget_settings) {
54
+ field_el.widget_settings = config.widget_settings;
55
+ }
56
+
49
57
  this.element.append(field_el);
50
58
  });
51
59
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "alchemy-form",
3
3
  "description": "Form plugin for Alchemy",
4
- "version": "0.1.1",
4
+ "version": "0.1.2",
5
5
  "repository": {
6
6
  "type" : "git",
7
7
  "url" : "https://github.com/11ways/alchemy-form.git"
@@ -11,6 +11,6 @@
11
11
  },
12
12
  "license": "MIT",
13
13
  "engines": {
14
- "node" : ">=8.9.0"
14
+ "node" : ">=12.0.0"
15
15
  }
16
16
  }
@@ -1 +1 @@
1
- <div class="code-editor"><% Hawkejs.replaceChildren($0, child_nodes) %></div>
1
+ <div class="code-editor"><% Blast.Classes.Hawkejs.replaceChildren($0, child_nodes) %></div>