@schukai/monster 3.67.0 → 3.68.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.
@@ -12,43 +12,32 @@
12
12
  * SPDX-License-Identifier: AGPL-3.0
13
13
  */
14
14
 
15
- import { instanceSymbol } from "../../constants.mjs";
16
- import { internalSymbol } from "../../constants.mjs";
17
- import { CustomControl } from "../../dom/customcontrol.mjs";
18
- import { Observer } from "../../types/observer.mjs";
19
- import { ProxyObserver } from "../../types/proxyobserver.mjs";
15
+ import {instanceSymbol} from "../../constants.mjs";
16
+ import {internalSymbol} from "../../constants.mjs";
17
+ import {CustomControl} from "../../dom/customcontrol.mjs";
18
+ import {Observer} from "../../types/observer.mjs";
19
+ import {ProxyObserver} from "../../types/proxyobserver.mjs";
20
20
 
21
- import { addAttributeToken } from "../../dom/attributes.mjs";
21
+ import {addAttributeToken} from "../../dom/attributes.mjs";
22
22
  import {
23
- assembleMethodSymbol,
24
- registerCustomElement,
25
- updaterTransformerMethodsSymbol,
23
+ assembleMethodSymbol,
24
+ registerCustomElement,
25
+ updaterTransformerMethodsSymbol,
26
26
  } from "../../dom/customelement.mjs";
27
- import { isObject } from "../../types/is.mjs";
28
- import { ToggleSwitchStyleSheet } from "./stylesheet/toggle-switch.mjs";
27
+ import {isObject, isFunction} from "../../types/is.mjs";
28
+ import {ToggleSwitchStyleSheet} from "./stylesheet/toggle-switch.mjs";
29
29
  import {
30
- ATTRIBUTE_ERRORMESSAGE,
31
- ATTRIBUTE_ROLE,
30
+ ATTRIBUTE_ERRORMESSAGE,
31
+ ATTRIBUTE_ROLE,
32
32
  } from "../../dom/constants.mjs";
33
- export { ToggleSwitch };
34
33
 
35
- /**
36
- * @private
37
- * @type {symbol}
38
- */
39
- const switchElementSymbol = Symbol("switchElement");
34
+ export {ToggleSwitch};
40
35
 
41
36
  /**
42
37
  * @private
43
38
  * @type {symbol}
44
39
  */
45
- const switchElementSymbolOn = Symbol("switchElementOn");
46
-
47
- /**
48
- * @private
49
- * @type {symbol}
50
- */
51
- const switchElementSymbolOff = Symbol("switchElementOff");
40
+ const switchElementSymbol = Symbol("switchElement");
52
41
 
53
42
  /**
54
43
  * @type {string}
@@ -80,324 +69,344 @@ export const STATE_OFF = "off";
80
69
  * @summary A simple toggle switch
81
70
  */
82
71
  class ToggleSwitch extends CustomControl {
83
- /**
84
- * To set the options via the html tag the attribute `data-monster-options` must be used.
85
- * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
86
- *
87
- * The individual configuration values can be found in the table.
88
- *
89
- * @property {string} value=current value of the element
90
- * @property {Boolean} disabled=disabled=false Disabled state
91
- * @property {Object} classes
92
- * @property {string} classes.on=specifies the class for the on state.
93
- * @property {string} classes.off=specifies the class for the off state.
94
- * @property {Object} values
95
- * @property {string} values.off=specifies the value of the element if it is not selected
96
- * @property {Object} labels
97
- * @property {string} labels.on=specifies the label for the on state.
98
- * @property {string} labels.off=specifies the label for the off state.
99
- * @property {Object} templates
100
- * @property {string} templates.main=specifies the main template used by the control.
101
- *
102
- * @since 3.57.0
103
- */
104
- get defaults() {
105
- return Object.assign({}, super.defaults, {
106
- value: null,
107
- disabled: false,
108
- classes: {
109
- on: "monster-theme-on",
110
- off: "monster-theme-off",
111
- handle: "monster-theme-primary-1",
112
- },
113
- values: {
114
- on: "on",
115
- off: "off",
116
- },
117
- labels: {
118
- "toggle-switch-on": "ON",
119
- "toggle-switch-off": "OFF",
120
- },
121
- templates: {
122
- main: getTemplate(),
123
- },
124
- });
125
- }
126
-
127
- /**
128
- *
129
- * @return {Monster.Components.Form.ToggleSwitch}
130
- */
131
- [assembleMethodSymbol]() {
132
- const self = this;
133
- super[assembleMethodSymbol]();
134
- initControlReferences.call(this);
135
- initEventHandler.call(this);
136
-
137
- /**
138
- * init value to off
139
- * if the value was not defined before inserting it into the HTML
140
- */
141
- if (self.getOption("value") === null) {
142
- self.setOption("value", self.getOption("values.off"));
143
- }
144
-
145
- /**
146
- * value from attribute
147
- */
148
- if (self.hasAttribute("value")) {
149
- self.setOption("value", self.getAttribute("value"));
150
- }
151
-
152
- /**
153
- * validate value
154
- */
155
- validateAndSetValue.call(self);
156
-
157
- if (this.state === STATE_ON) {
158
- toggleClassOn.call(self);
159
- } else {
160
- toggleClassOff.call(self);
161
- }
162
-
163
- /**
164
- * is called when options changed
165
- */
166
- self[internalSymbol].attachObserver(
167
- new Observer(function () {
168
- if (isObject(this) && this instanceof ProxyObserver) {
169
- validateAndSetValue.call(self);
170
- toggleClass.call(self);
171
- }
172
- }),
173
- );
174
-
175
- return this;
176
- }
177
-
178
- /**
179
- * updater transformer methods for pipe
180
- *
181
- * @return {function}
182
- */
183
- [updaterTransformerMethodsSymbol]() {
184
- return {
185
- "state-callback": (Wert) => {
186
- return this.state;
187
- },
188
- };
189
- }
190
-
191
- /**
192
- * @return [CSSStyleSheet]
193
- */
194
- static getCSSStyleSheet() {
195
- return [ToggleSwitchStyleSheet];
196
- }
197
-
198
- /**
199
- * toggle switch
200
- *
201
- * ```
202
- * e = document.querySelector('monster-toggle-switch');
203
- * e.click()
204
- * ```
205
- */
206
- click() {
207
- toggleValues.call(this);
208
- }
209
-
210
- /**
211
- * toggle switch on/off
212
- *
213
- * ```
214
- * e = document.querySelector('monster-toggle-switch');
215
- * e.toggle()
216
- * ```
217
- *
218
- * @return {ToggleSwitch}
219
- */
220
- toggle() {
221
- this.click();
222
- return this;
223
- }
224
-
225
- /**
226
- * toggle switch on
227
- *
228
- * ```
229
- * e = document.querySelector('monster-toggle-switch');
230
- * e.toggleOn()
231
- * ```
232
- *
233
- * @return {ToggleSwitch}
234
- */
235
- toggleOn() {
236
- this.setOption("value", this.getOption("values.on"));
237
- return this;
238
- }
239
-
240
- /**
241
- * toggle switch off
242
- *
243
- * ```
244
- * e = document.querySelector('monster-toggle-switch');
245
- * e.toggleOff()
246
- * ```
247
- *
248
- * @return {ToggleSwitch}
249
- */
250
- toggleOff() {
251
- this.setOption("value", this.getOption("values.off"));
252
- return this;
253
- }
254
-
255
- /**
256
- * returns the status of the element
257
- *
258
- * ```
259
- * e = document.querySelector('monster-toggle-switch');
260
- * console.log(e.state)
261
- * // ↦ off
262
- * ```
263
- *
264
- * @return {string}
265
- */
266
- get state() {
267
- return this.getOption("value") === this.getOption("values.on")
268
- ? STATE_ON
269
- : STATE_OFF;
270
- }
271
-
272
- /**
273
- * The current value of the Switch
274
- *
275
- * ```
276
- * e = document.querySelector('monster-toggle-switch');
277
- * console.log(e.value)
278
- * // ↦ on
279
- * ```
280
- *
281
- * @return {string}
282
- */
283
- get value() {
284
- return this.state === STATE_ON
285
- ? this.getOption("values.on")
286
- : this.getOption("values.off");
287
- }
288
-
289
- /**
290
- * Set value
291
- *
292
- * ```
293
- * e = document.querySelector('monster-toggle-switch');
294
- * e.value="on"
295
- * ```
296
- *
297
- * @property {string} value
298
- */
299
- set value(value) {
300
- this.setOption("value", value);
301
- }
302
-
303
- /**
304
- * This method is called by the `instanceof` operator.
305
- * @returns {symbol}
306
- * @since 2.1.0
307
- */
308
- static get [instanceSymbol]() {
309
- return Symbol.for(
310
- "@schukai/monster/components/form/toggle-switch@@instance",
311
- );
312
- }
313
-
314
- static getTag() {
315
- return "monster-toggle-switch";
316
- }
72
+ /**
73
+ * To set the options via the html tag the attribute `data-monster-options` must be used.
74
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
75
+ *
76
+ * The individual configuration values can be found in the table.
77
+ *
78
+ * @property {string} value=current value of the element
79
+ * @property {Boolean} disabled=disabled=false Disabled state
80
+ * @property {Object} classes
81
+ * @property {string} classes.on=specifies the class for the on state.
82
+ * @property {string} classes.off=specifies the class for the off state.
83
+ * @property {Object} values
84
+ * @property {string} values.off=specifies the value of the element if it is not selected
85
+ * @property {Object} labels
86
+ * @property {string} labels.on=specifies the label for the on state.
87
+ * @property {string} labels.off=specifies the label for the off state.
88
+ * @property {string} actions
89
+ * @property {string} actions.on=specifies the action for the on state.
90
+ * @property {string} actions.off=specifies the action for the off state.
91
+ * @property {Object} templates
92
+ * @property {string} templates.main=specifies the main template used by the control.
93
+ *
94
+ * @since 3.57.0
95
+ */
96
+ get defaults() {
97
+ return Object.assign({}, super.defaults, {
98
+ value: null,
99
+ disabled: false,
100
+ classes: {
101
+ on: "monster-theme-on",
102
+ off: "monster-theme-off",
103
+ handle: "monster-theme-primary-1",
104
+ },
105
+ values: {
106
+ on: "on",
107
+ off: "off",
108
+ },
109
+ labels: {
110
+ "toggle-switch-on": "ON",
111
+ "toggle-switch-off": "OFF",
112
+ },
113
+ templates: {
114
+ main: getTemplate(),
115
+ },
116
+ actions: {
117
+ on: () => {
118
+ throw new Error("the on action is not defined");
119
+ },
120
+ off: () => {
121
+ throw new Error("the off action is not defined");
122
+ },
123
+ }
124
+ });
125
+ }
126
+
127
+ /**
128
+ * @return {ToggleSwitch}
129
+ */
130
+ [assembleMethodSymbol]() {
131
+ const self = this;
132
+ super[assembleMethodSymbol]();
133
+ initControlReferences.call(this);
134
+ initEventHandler.call(this);
135
+
136
+ /**
137
+ * init value to off
138
+ * if the value was not defined before inserting it into the HTML
139
+ */
140
+ if (self.getOption("value") === null) {
141
+ self.setOption("value", self.getOption("values.off"));
142
+ }
143
+
144
+ /**
145
+ * value from attribute
146
+ */
147
+ if (self.hasAttribute("value")) {
148
+ self.setOption("value", self.getAttribute("value"));
149
+ }
150
+
151
+ /**
152
+ * validate value
153
+ */
154
+ validateAndSetValue.call(self);
155
+
156
+ if (this.state === STATE_ON) {
157
+ toggleClassOn.call(self);
158
+ } else {
159
+ toggleClassOff.call(self);
160
+ }
161
+
162
+ /**
163
+ * is called when options changed
164
+ */
165
+ self[internalSymbol].attachObserver(
166
+ new Observer(function () {
167
+ if (isObject(this) && this instanceof ProxyObserver) {
168
+ validateAndSetValue.call(self);
169
+ toggleClass.call(self);
170
+ }
171
+ }),
172
+ );
173
+
174
+ return this;
175
+ }
176
+
177
+ /**
178
+ * updater transformer methods for pipe
179
+ *
180
+ * @return {function}
181
+ */
182
+ [updaterTransformerMethodsSymbol]() {
183
+ return {
184
+ "state-callback": (Wert) => {
185
+ return this.state;
186
+ },
187
+ };
188
+ }
189
+
190
+ /**
191
+ * @return [CSSStyleSheet]
192
+ */
193
+ static getCSSStyleSheet() {
194
+ return [ToggleSwitchStyleSheet];
195
+ }
196
+
197
+ /**
198
+ * toggle switch
199
+ *
200
+ * ```
201
+ * e = document.querySelector('monster-toggle-switch');
202
+ * e.click()
203
+ * ```
204
+ */
205
+ click() {
206
+ toggleValues.call(this);
207
+ }
208
+
209
+ /**
210
+ * toggle switch on/off
211
+ *
212
+ * ```
213
+ * e = document.querySelector('monster-toggle-switch');
214
+ * e.toggle()
215
+ * ```
216
+ *
217
+ * @return {ToggleSwitch}
218
+ */
219
+ toggle() {
220
+ this.click();
221
+ return this;
222
+ }
223
+
224
+ /**
225
+ * toggle switch on
226
+ *
227
+ * ```
228
+ * e = document.querySelector('monster-toggle-switch');
229
+ * e.toggleOn()
230
+ * ```
231
+ *
232
+ * @return {ToggleSwitch}
233
+ */
234
+ toggleOn() {
235
+ this.setOption("value", this.getOption("values.on"));
236
+ return this;
237
+ }
238
+
239
+ /**
240
+ * toggle switch off
241
+ *
242
+ * ```
243
+ * e = document.querySelector('monster-toggle-switch');
244
+ * e.toggleOff()
245
+ * ```
246
+ *
247
+ * @return {ToggleSwitch}
248
+ */
249
+ toggleOff() {
250
+ this.setOption("value", this.getOption("values.off"));
251
+ return this;
252
+ }
253
+
254
+ /**
255
+ * returns the status of the element
256
+ *
257
+ * ```
258
+ * e = document.querySelector('monster-toggle-switch');
259
+ * console.log(e.state)
260
+ * // ↦ off
261
+ * ```
262
+ *
263
+ * @return {string}
264
+ */
265
+ get state() {
266
+ return this.getOption("value") === this.getOption("values.on")
267
+ ? STATE_ON
268
+ : STATE_OFF;
269
+ }
270
+
271
+ /**
272
+ * The current value of the Switch
273
+ *
274
+ * ```
275
+ * e = document.querySelector('monster-toggle-switch');
276
+ * console.log(e.value)
277
+ * // ↦ on
278
+ * ```
279
+ *
280
+ * @return {string}
281
+ */
282
+ get value() {
283
+ return this.state === STATE_ON
284
+ ? this.getOption("values.on")
285
+ : this.getOption("values.off");
286
+ }
287
+
288
+ /**
289
+ * Set value
290
+ *
291
+ * ```
292
+ * e = document.querySelector('monster-toggle-switch');
293
+ * e.value="on"
294
+ * ```
295
+ *
296
+ * @property {string} value
297
+ */
298
+ set value(value) {
299
+ this.setOption("value", value);
300
+ }
301
+
302
+ /**
303
+ * This method is called by the `instanceof` operator.
304
+ * @returns {symbol}
305
+ * @since 2.1.0
306
+ */
307
+ static get [instanceSymbol]() {
308
+ return Symbol.for(
309
+ "@schukai/monster/components/form/toggle-switch@@instance",
310
+ );
311
+ }
312
+
313
+ static getTag() {
314
+ return "monster-toggle-switch";
315
+ }
317
316
  }
318
317
 
319
318
  /**
320
319
  * @private
321
320
  */
322
321
  function initControlReferences() {
323
- this[switchElementSymbol] = this.shadowRoot.querySelector(
324
- `[${ATTRIBUTE_ROLE}=switch]`,
325
- );
322
+ this[switchElementSymbol] = this.shadowRoot.querySelector(
323
+ `[${ATTRIBUTE_ROLE}=switch]`,
324
+ );
326
325
  }
327
326
 
328
327
  /**
329
328
  * @private
330
329
  */
331
330
  function toggleClassOn() {
332
- this[switchElementSymbol].classList.remove(this.getOption("classes.off")); // change color
333
- this[switchElementSymbol].classList.add(this.getOption("classes.on")); // change color
331
+ this[switchElementSymbol].classList.remove(this.getOption("classes.off")); // change color
332
+ this[switchElementSymbol].classList.add(this.getOption("classes.on")); // change color
334
333
  }
335
334
 
336
335
  /**
337
336
  * @private
338
337
  */
339
338
  function toggleClassOff() {
340
- this[switchElementSymbol].classList.remove(this.getOption("classes.on")); // change color
341
- this[switchElementSymbol].classList.add(this.getOption("classes.off")); // change color
339
+ this[switchElementSymbol].classList.remove(this.getOption("classes.on")); // change color
340
+ this[switchElementSymbol].classList.add(this.getOption("classes.off")); // change color
342
341
  }
343
342
 
344
343
  /**
345
344
  * @private
346
345
  */
347
346
  function toggleClass() {
348
- if (this.getOption("value") === this.getOption("values.on")) {
349
- toggleClassOn.call(this);
350
- } else {
351
- toggleClassOff.call(this);
352
- }
347
+ if (this.getOption("value") === this.getOption("values.on")) {
348
+ toggleClassOn.call(this);
349
+ } else {
350
+ toggleClassOff.call(this);
351
+ }
353
352
  }
354
353
 
355
354
  /**
356
355
  * @private
357
356
  */
358
357
  function toggleValues() {
359
- if (this.getOption("disabled") === true) {
360
- return;
361
- }
362
-
363
- if (this.getOption("value") === this.getOption("values.on")) {
364
- this.setOption("value", this.getOption("values.off"));
365
- this?.setFormValue(this.getOption("value")); // set form value
366
- } else {
367
- this.setOption("value", this.getOption("values.on"));
368
- this?.setFormValue(this.getOption("values.off")); // set form value
369
- }
370
-
371
- this.setOption("state", this.state);
358
+ if (this.getOption("disabled") === true) {
359
+ return;
360
+ }
361
+
362
+ let callback, value;
363
+
364
+ if (this.getOption("value") === this.getOption("values.on")) {
365
+ value = this.getOption("values.off");
366
+ callback = this.getOption("actions.off");
367
+ } else {
368
+ value = this.getOption("values.on");
369
+ callback = this.getOption("actions.on");
370
+ }
371
+
372
+ this.setOption("value", value);
373
+ this?.setFormValue(value);
374
+
375
+ if (isFunction(callback)) {
376
+ callback.call(this)();
377
+ }
378
+
379
+
380
+ this.setOption("state", this.state);
372
381
  }
373
382
 
374
383
  /**
375
384
  * @private
376
385
  */
377
386
  function validateAndSetValue() {
378
- const value = this.getOption("value");
379
-
380
- const validatedValues = [];
381
- validatedValues.push(this.getOption("values.on"));
382
- validatedValues.push(this.getOption("values.off"));
383
-
384
- if (validatedValues.includes(value) === false) {
385
- addAttributeToken(
386
- this,
387
- ATTRIBUTE_ERRORMESSAGE,
388
- 'The value "' +
389
- value +
390
- '" must be "' +
391
- this.getOption("values.on") +
392
- '" or "' +
393
- this.getOption("values.off"),
394
- );
395
- this.setOption("disabled", true);
396
- this.formDisabledCallback(true);
397
- } else {
398
- this.setOption("disabled", false);
399
- this.formDisabledCallback(false);
400
- }
387
+ const value = this.getOption("value");
388
+
389
+ const validatedValues = [];
390
+ validatedValues.push(this.getOption("values.on"));
391
+ validatedValues.push(this.getOption("values.off"));
392
+
393
+ if (validatedValues.includes(value) === false) {
394
+ addAttributeToken(
395
+ this,
396
+ ATTRIBUTE_ERRORMESSAGE,
397
+ 'The value "' +
398
+ value +
399
+ '" must be "' +
400
+ this.getOption("values.on") +
401
+ '" or "' +
402
+ this.getOption("values.off"),
403
+ );
404
+ this.setOption("disabled", true);
405
+ this.formDisabledCallback(true);
406
+ } else {
407
+ this.setOption("disabled", false);
408
+ this.formDisabledCallback(false);
409
+ }
401
410
  }
402
411
 
403
412
  /**
@@ -405,16 +414,16 @@ function validateAndSetValue() {
405
414
  * @return {initEventHandler}
406
415
  */
407
416
  function initEventHandler() {
408
- const self = this;
409
- self.addEventListener("keyup", function (event) {
410
- if (event.code === "Space") {
411
- self[switchElementSymbol].click();
412
- }
413
- });
414
- self.addEventListener("click", function (event) {
415
- toggleValues.call(self);
416
- });
417
- return this;
417
+ const self = this;
418
+ self.addEventListener("keyup", function (event) {
419
+ if (event.code === "Space") {
420
+ self[switchElementSymbol].click();
421
+ }
422
+ });
423
+ self.addEventListener("click", function (event) {
424
+ toggleValues.call(self);
425
+ });
426
+ return this;
418
427
  }
419
428
 
420
429
  /**
@@ -422,10 +431,10 @@ function initEventHandler() {
422
431
  * @return {string}
423
432
  */
424
433
  function getTemplate() {
425
- // language=HTML
426
- return `
434
+ // language=HTML
435
+ return `
427
436
  <div data-monster-role="control" part="control" tabindex="0">
428
- <div class="switch" data-monster-role="switch"
437
+ <div class="switch" data-monster-role="switch"
429
438
  data-monster-attributes="data-monster-state path:value | call:state-callback">
430
439
  <div class="label on" data-monster-replace="path:labels.toggle-switch-on"></div>
431
440
  <div class="label off" data-monster-replace="path:labels.toggle-switch-off"></div>