@schukai/monster 3.56.1 → 3.58.0

Sign up to get free protection for your applications and to get access to all the features.
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
+