@schukai/monster 3.67.0 → 3.68.0

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