@schukai/monster 3.56.1 → 3.58.0

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/example/components/form/toggle-switch.mjs +7 -0
  3. package/package.json +1 -1
  4. package/source/components/datatable/change-button.mjs +8 -4
  5. package/source/components/datatable/dataset.mjs +1 -1
  6. package/source/components/datatable/filter.mjs +0 -1
  7. package/source/components/form/button.mjs +3 -3
  8. package/source/components/form/select.mjs +55 -15
  9. package/source/components/form/style/button-bar.pcss +2 -0
  10. package/source/components/form/style/button.pcss +2 -0
  11. package/source/components/form/style/select.pcss +1 -1
  12. package/source/components/form/style/toggle-switch.pcss +74 -0
  13. package/source/components/form/stylesheet/button-bar.mjs +1 -1
  14. package/source/components/form/stylesheet/button.mjs +1 -1
  15. package/source/components/form/stylesheet/select.mjs +1 -1
  16. package/source/components/form/stylesheet/toggle-switch.mjs +27 -0
  17. package/source/components/form/tabs.mjs +0 -1
  18. package/source/components/form/toggle-switch.mjs +430 -0
  19. package/source/data/transformer.mjs +30 -0
  20. package/source/dom/attributes.mjs +1 -1
  21. package/source/dom/customcontrol.mjs +6 -2
  22. package/source/dom/customelement.mjs +43 -5
  23. package/source/dom/events.mjs +3 -3
  24. package/source/dom/updater.mjs +43 -16
  25. package/source/i18n/translations.mjs +1 -1
  26. package/source/monster.mjs +7 -0
  27. package/source/types/version.mjs +1 -1
  28. package/test/cases/components/form/select.mjs +1 -1
  29. package/test/cases/components/form/toggle-switch.mjs +310 -0
  30. package/test/cases/components/form/tree-select.mjs +1 -8
  31. package/test/cases/data/transformer.mjs +16 -0
  32. package/test/cases/dom/customcontrol.mjs +53 -8
  33. package/test/cases/dom/customelement-initfromscripthost.mjs +0 -4
  34. package/test/cases/dom/customelement.mjs +30 -26
  35. package/test/cases/dom/updater.mjs +14 -3
  36. package/test/cases/monster.mjs +1 -1
  37. package/test/util/jsdom.mjs +9 -10
  38. package/test/web/import.js +1 -0
  39. package/test/web/test.html +2 -2
  40. package/test/web/tests.js +3966 -1415
package/CHANGELOG.md CHANGED
@@ -1,9 +1,55 @@
1
1
 
2
+ ## [3.58.0] - 2024-03-17
3
+
4
+ ### Add Features
5
+
6
+ - new select feature emptyValueIfNoOptions [#142](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/142)
7
+ ### Changes
8
+
9
+ - update deploy script
10
+ - lint code
11
+ - build-webtest
12
+ - lint code
13
+ - code format
14
+ - release and publish to npm new version 3.57.0
15
+ - tests and more
16
+
17
+ ## [3.57.0] - 2024-03-06
18
+
19
+ ### Add Features
20
+
21
+ - [#162](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/162)
22
+ - new updaterTransformerMethodsSymbol method [#163](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/163)
23
+ - new updaterTransformerMethodsSymbol method [#163](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/163)
24
+ ### Bug Fixes
25
+
26
+ - [#165](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/165)
27
+ - bind this to callback and fix timing [#158](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/158) [#164](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/164)
28
+ - add arrowdown handler [#160](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/160) [#161](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/161)
29
+ - add arrowdown handler [#160](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/160) [#161](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/161)
30
+ ### Changes
31
+
32
+ - tests and more
33
+ - fix tests
34
+ - updates [#160](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/160)
35
+ - whitespace [#160](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/160)
36
+ - optimize outline [#160](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/160)
37
+ - optimize outline [#160](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/160)
38
+ - rename internal function [#160](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/160)
39
+ - fix missing fs bug
40
+ - release and publish to npm new version 3.56.1
41
+ ### Documentation
42
+
43
+ - typo [#160](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/160)
44
+
2
45
  ## [3.56.1] - 2024-02-26
3
46
 
4
47
  ### Bug Fixes
5
48
 
6
49
  - [3] is not the right way [#151](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/151)
50
+ ### Changes
51
+
52
+ - release and publish to npm new version 3.56.1
7
53
 
8
54
  ## [3.56.0] - 2024-02-26
9
55
 
@@ -0,0 +1,7 @@
1
+ import {Switch} from '@schukai/component-form/source/toggle-switch.js';
2
+
3
+ // create element
4
+ const toggleSwitch = document.createElement('monster-toggle-switch');
5
+
6
+ // insert element into the DOM
7
+ document.body.appendChild(toggleSwitch);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schukai/monster",
3
- "version": "3.56.1",
3
+ "version": "3.58.0",
4
4
  "description": "Monster is a simple library for creating fast, robust and lightweight websites.",
5
5
  "keywords": [
6
6
  "framework",
@@ -5,8 +5,8 @@
5
5
 
6
6
  import { instanceSymbol } from "../../constants.mjs";
7
7
  import { diff } from "../../data/diff.mjs";
8
- import {addAttributeToken} from "../../dom/attributes.mjs";
9
- import {ATTRIBUTE_ERRORMESSAGE} from "../../dom/constants.mjs";
8
+ import { addAttributeToken } from "../../dom/attributes.mjs";
9
+ import { ATTRIBUTE_ERRORMESSAGE } from "../../dom/constants.mjs";
10
10
  import {
11
11
  assembleMethodSymbol,
12
12
  CustomElement,
@@ -116,7 +116,7 @@ class ChangeButton extends CustomElement {
116
116
  * This method is responsible for assembling the component.
117
117
  */
118
118
  [assembleMethodSymbol]() {
119
- super[assembleMethodSymbol]();;
119
+ super[assembleMethodSymbol]();
120
120
 
121
121
  initControlReferences.call(this);
122
122
  initEventHandler.call(this);
@@ -213,7 +213,11 @@ function getIndex() {
213
213
 
214
214
  const ref = row.getAttribute("data-monster-insert-reference");
215
215
  if (!ref) {
216
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "reference is missing or empty");
216
+ addAttributeToken(
217
+ this,
218
+ ATTRIBUTE_ERRORMESSAGE,
219
+ "reference is missing or empty",
220
+ );
217
221
  return;
218
222
  }
219
223
 
@@ -136,7 +136,7 @@ class DataSet extends CustomElement {
136
136
  return "monster-dataset";
137
137
  }
138
138
 
139
- write() {;
139
+ write() {
140
140
 
141
141
  return new Promise((resolve, reject) => {
142
142
  if (!this[datasourceLinkedElementSymbol]) {
@@ -815,7 +815,6 @@ function updateFilterTabs() {
815
815
  * @returns {Promise<*>}
816
816
  */
817
817
  function doSearch({ showEffect } = { showEffect: true }) {
818
-
819
818
  this.resetFailureMessage();
820
819
 
821
820
  if (showEffect) {
@@ -85,7 +85,7 @@ class Button extends CustomControl {
85
85
  [assembleMethodSymbol]() {
86
86
  super[assembleMethodSymbol]();
87
87
  initControlReferences.call(this);
88
- initEventhandler.call(this);
88
+ initEventHandler.call(this);
89
89
  return this;
90
90
  }
91
91
 
@@ -257,10 +257,10 @@ class Button extends CustomControl {
257
257
 
258
258
  /**
259
259
  * @private
260
- * @return {initEventhandler}
260
+ * @return {initEventHandler}
261
261
  * @fires Monster.Components.Form.event:monster-button-clicked
262
262
  */
263
- function initEventhandler() {
263
+ function initEventHandler() {
264
264
  const self = this;
265
265
  const button = this[buttonElementSymbol];
266
266
 
@@ -24,6 +24,7 @@ import {
24
24
  assembleMethodSymbol,
25
25
  getSlottedElements,
26
26
  registerCustomElement,
27
+ updaterTransformerMethodsSymbol,
27
28
  } from "../../dom/customelement.mjs";
28
29
  import {
29
30
  findTargetElementFromEvent,
@@ -386,8 +387,8 @@ class Select extends CustomControl {
386
387
  * @property {Object} toggleEventType=click,touch List of event types to be observed for opening the dropdown
387
388
  * @property {boolean} delegatesFocus=false lorem [see mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus)
388
389
  * @property {Object[]} options Selection of key identifier pairs available for selection and displayed in the dropdown.
389
- * @property {string} options[].label Label
390
- * @property {string} options[].value Value
390
+ * @property {string} options[].label
391
+ * @property {string} options[].value
391
392
  * @property {string} options[].visibility hidden or visible
392
393
  * @property {Array} selection Selected options
393
394
  * @property {Integer} showMaxOptions=10 Maximum number of visible options before a scroll bar should be displayed.
@@ -410,6 +411,7 @@ class Select extends CustomControl {
410
411
  * @property {Boolean} features.clear=true Display of a delete key for deleting the specific selection
411
412
  * @property {Boolean} features.lazyLoad=false Load options when first opening the dropdown
412
413
  * @property {Boolean} features.closeOnSelect=false Close the dropdown when an option is selected (since 3.54.0)
414
+ * @property {Boolean} features.emptyValueIfNoOptions=false If no options are available, the selection is set to an empty array
413
415
  * @property {Boolean} filter.defaultValue=* Default filter value, if the filter is empty
414
416
  * @property {Boolean} filter.mode=options Filter mode, values: options, remote, disabled
415
417
  * @property {Object} templates Template definitions
@@ -444,6 +446,7 @@ class Select extends CustomControl {
444
446
  clear: true,
445
447
  lazyLoad: false,
446
448
  closeOnSelect: false,
449
+ emptyValueIfNoOptions: false,
447
450
  },
448
451
  url: null,
449
452
  labels: {
@@ -523,6 +526,16 @@ class Select extends CustomControl {
523
526
 
524
527
  const lazyLoadFlag = self.getOption("features.lazyLoad");
525
528
 
529
+ if (self.hasAttribute("value")) {
530
+ new Processing(10, () => {
531
+ this.value = this.getAttribute("value");
532
+ })
533
+ .run()
534
+ .catch((e) => {
535
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
536
+ });
537
+ }
538
+
526
539
  if (self.getOption("url") !== null && !lazyLoadFlag) {
527
540
  setStatusOrRemoveBadges.call(this, "loading");
528
541
 
@@ -1010,6 +1023,15 @@ function handleToggleKeyboardEvents(event) {
1010
1023
  toggle.call(this);
1011
1024
  event.preventDefault();
1012
1025
  break;
1026
+ case "ArrowDown":
1027
+ show.call(this);
1028
+ activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
1029
+ event.preventDefault();
1030
+ break;
1031
+ case "ArrowUp":
1032
+ hide.call(this);
1033
+ event.preventDefault();
1034
+ break;
1013
1035
  }
1014
1036
  }
1015
1037
 
@@ -1239,9 +1261,9 @@ function activateCurrentOption(direction) {
1239
1261
  }
1240
1262
  }
1241
1263
  } else {
1264
+ let found = false;
1242
1265
  while (focused.previousSibling) {
1243
1266
  focused = focused.previousSibling;
1244
-
1245
1267
  if (
1246
1268
  focused instanceof HTMLElement &&
1247
1269
  focused.hasAttribute(ATTRIBUTE_ROLE) &&
@@ -1249,9 +1271,13 @@ function activateCurrentOption(direction) {
1249
1271
  focused.matches("[data-monster-visibility=visible]") &&
1250
1272
  focused.matches(":not([data-monster-filtered=true])")
1251
1273
  ) {
1274
+ found = true;
1252
1275
  break;
1253
1276
  }
1254
1277
  }
1278
+ if (found === false) {
1279
+ focusFilter.call(this);
1280
+ }
1255
1281
  }
1256
1282
  }
1257
1283
 
@@ -1266,7 +1292,11 @@ function activateCurrentOption(direction) {
1266
1292
  focused.focus();
1267
1293
  focused.setAttribute(`${ATTRIBUTE_PREFIX}focused`, true);
1268
1294
  }
1269
- }).run();
1295
+ })
1296
+ .run()
1297
+ .catch((e) => {
1298
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1299
+ });
1270
1300
  }
1271
1301
 
1272
1302
  /**
@@ -1608,6 +1638,7 @@ function gatherState() {
1608
1638
  const elements = this.shadowRoot.querySelectorAll(
1609
1639
  `input[type=${type}]:checked`,
1610
1640
  );
1641
+
1611
1642
  for (const e of elements) {
1612
1643
  selection.push({
1613
1644
  label: getSelectionLabel.call(this, e.value),
@@ -1691,7 +1722,10 @@ function areOptionsAvailableAndInit() {
1691
1722
 
1692
1723
  this.setOption("messages.control", msg);
1693
1724
  this.setOption("messages.summary", "");
1694
- this.setOption("selection", []);
1725
+
1726
+ if (this.getOption("features.emptyValueIfNoOptions") === true) {
1727
+ this.value = "";
1728
+ }
1695
1729
  addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, noOptionsAvailableMessage);
1696
1730
  return false;
1697
1731
  }
@@ -1900,7 +1934,11 @@ function setSelection(selection) {
1900
1934
  }
1901
1935
  });
1902
1936
  }
1903
- }).run();
1937
+ })
1938
+ .run()
1939
+ .catch((e) => {
1940
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1941
+ });
1904
1942
  }
1905
1943
 
1906
1944
  /**
@@ -1910,8 +1948,7 @@ function setSelection(selection) {
1910
1948
  * @throws {TypeError} the result cannot be parsed
1911
1949
  * @throws {TypeError} unsupported response
1912
1950
  */
1913
- function fetchData(url) {;
1914
-
1951
+ function fetchData(url) {
1915
1952
  if (!url) url = this.getOption("url");
1916
1953
  if (!url) return Promise.resolve();
1917
1954
 
@@ -1957,8 +1994,7 @@ function hide() {
1957
1994
  /**
1958
1995
  * @private
1959
1996
  */
1960
- function show() {;
1961
-
1997
+ function show() {
1962
1998
  if (this.getOption("disabled", undefined) === true) {
1963
1999
  return;
1964
2000
  }
@@ -2008,8 +2044,11 @@ function show() {;
2008
2044
 
2009
2045
  return;
2010
2046
  }
2011
- //debugger
2012
- //const optionsAvailable = areOptionsAvailableAndInit.call(this);
2047
+
2048
+ const options = getOptionElements.call(this);
2049
+ if (options.length === 0) {
2050
+ return;
2051
+ }
2013
2052
 
2014
2053
  this[popperElementSymbol].style.visibility = "hidden";
2015
2054
  this[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
@@ -2234,7 +2273,7 @@ function initEventHandler() {
2234
2273
  * @private
2235
2274
  * @return {Select}
2236
2275
  */
2237
- function setStatusOrRemoveBadges(suggestion) {;
2276
+ function setStatusOrRemoveBadges(suggestion) {
2238
2277
  setTimeout(() => {
2239
2278
  const selection = this.getOption("selection");
2240
2279
  const clearAllFlag =
@@ -2368,7 +2407,7 @@ function getTemplate() {
2368
2407
  data-monster-attributes="
2369
2408
  data-monster-filtered path:options.filtered,
2370
2409
  data-monster-visibility path:options.visibility">
2371
- <label part="option" role="option">
2410
+ <label part="option">
2372
2411
  <input data-monster-role="option-control"
2373
2412
  data-monster-attributes="
2374
2413
  type path:type,
@@ -2378,7 +2417,8 @@ function getTemplate() {
2378
2417
  part path:type | prefix:option- | suffix: form,
2379
2418
  class path:options.class
2380
2419
  " tabindex="-1">
2381
- <div data-monster-replace="path:options | index:label" part="option-label"></div>
2420
+ <div data-monster-replace="path:options | index:label"
2421
+ part="option-label"></div>
2382
2422
  </label>
2383
2423
  </div>
2384
2424
  </template>
@@ -5,6 +5,8 @@
5
5
  @import "../../style/typography.pcss";
6
6
  @import "../../style/floating-ui.pcss";
7
7
 
8
+ :host(monster-button-bar){display:flex;align-items:stretch;}
9
+
8
10
  div[data-monster-role="control"] {
9
11
  position: relative;
10
12
  height: 100%;
@@ -2,6 +2,8 @@
2
2
  @import "../../style/button.pcss";
3
3
  @import "../../style/border.pcss";
4
4
 
5
+ :host(monster-button){display:flex;}
6
+
5
7
  [data-monster-role="control"] {
6
8
  display: flex;
7
9
  align-items: stretch;
@@ -256,7 +256,7 @@ div[data-monster-role=selection] {
256
256
 
257
257
  [data-monster-role=option][data-monster-focused=true] {
258
258
  outline: 1px dashed var(--monster-color-selection-2);
259
- outline-offset: 2px;
259
+ outline-offset: -2px;
260
260
  }
261
261
 
262
262
  [data-monster-role=option] > label:focus,
@@ -0,0 +1,74 @@
1
+ @import "../../style/color.pcss";
2
+ @import "../../style/theme.pcss";
3
+ @import "../../style/border.pcss";
4
+
5
+ [data-monster-role=control] {
6
+
7
+ font-family: inherit;
8
+ font-size: 100%;
9
+ padding: 0.4rem 0.6rem;
10
+ margin: 0;
11
+ outline: none;
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ [data-monster-role=control]:focus {
16
+ outline: 1px dashed var(--monster-color-selection-3);
17
+ outline-offset: 2px;
18
+ }
19
+
20
+ .switch {
21
+ position: relative;
22
+ display: inline-block;
23
+ width: 60px;
24
+ height: 34px;
25
+
26
+ border-color: var(--monster-bg-color-primary-3);
27
+ border-width: thin;
28
+ border-style: var(--monster-border-style);
29
+ transition: background-color 0.2s;
30
+ display: grid;
31
+ grid-template-columns: 1fr 1fr;
32
+ }
33
+
34
+ .switch-radio input[type="radio"] {
35
+ display: none;
36
+ }
37
+
38
+ .label{
39
+ height: 34px;
40
+ display: block;
41
+ text-align: center;
42
+ line-height: 34px;
43
+ user-select: none;
44
+ }
45
+
46
+ .switch-slider {
47
+ position: absolute;
48
+ top: 4px;
49
+ bottom: 4px;
50
+ left: 4px;
51
+ right: 28px;
52
+ background-color: var(--monster-bg-color-primary-4);
53
+ transition: 0.2s;
54
+ }
55
+
56
+ .switch[data-monster-state="on"] .label.off {
57
+ visibility: hidden;
58
+ }
59
+ .switch[data-monster-state="on"] .label.on {
60
+ visibility: visible;
61
+ }
62
+ .switch[data-monster-state="off"] .label.off {
63
+ visibility: visible;
64
+ }
65
+ .switch[data-monster-state="off"] .label.on {
66
+ visibility: hidden;
67
+ }
68
+
69
+
70
+ .switch[data-monster-state="on"] .switch-slider {
71
+ transform: translateX(24px);
72
+
73
+ }
74
+