@schukai/monster 3.98.2 → 3.99.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 (35) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/package.json +1 -1
  3. package/source/components/datatable/columnbar.mjs +19 -20
  4. package/source/components/datatable/datatable.mjs +94 -80
  5. package/source/components/datatable/filter/date-range.mjs +19 -20
  6. package/source/components/datatable/filter/input.mjs +19 -20
  7. package/source/components/datatable/filter/range.mjs +19 -19
  8. package/source/components/datatable/filter-button.mjs +19 -20
  9. package/source/components/datatable/filter.mjs +48 -31
  10. package/source/components/datatable/pagination.mjs +19 -20
  11. package/source/components/datatable/save-button.mjs +19 -20
  12. package/source/components/datatable/stylesheet/datatable.mjs +13 -6
  13. package/source/components/form/action-button.mjs +2 -1
  14. package/source/components/form/api-button.mjs +4 -4
  15. package/source/components/form/button-bar.mjs +2 -3
  16. package/source/components/form/button.mjs +1 -0
  17. package/source/components/form/context-error.mjs +1 -0
  18. package/source/components/form/field-set.mjs +21 -21
  19. package/source/components/form/popper-button.mjs +274 -273
  20. package/source/components/form/reload.mjs +1 -0
  21. package/source/components/form/select.mjs +56 -34
  22. package/source/components/form/toggle-switch.mjs +2 -2
  23. package/source/components/layout/details.mjs +19 -20
  24. package/source/components/layout/tabs.mjs +19 -20
  25. package/source/components/notify/monitor-attribute-errors.mjs +184 -179
  26. package/source/data/buildtree.mjs +1 -1
  27. package/source/dom/customelement.mjs +944 -945
  28. package/source/dom/error.mjs +106 -0
  29. package/source/monster.mjs +1 -0
  30. package/source/types/version.mjs +1 -1
  31. package/test/cases/dom/customcontrol.mjs +1 -1
  32. package/test/cases/dom/customelement.mjs +3 -3
  33. package/test/cases/monster.mjs +1 -1
  34. package/test/web/test.html +2 -2
  35. package/test/web/tests.js +334 -63
@@ -12,26 +12,27 @@
12
12
  * SPDX-License-Identifier: AGPL-3.0
13
13
  */
14
14
 
15
- import { instanceSymbol } from "../../constants.mjs";
16
- import { addAttributeToken } from "../../dom/attributes.mjs";
15
+ import {instanceSymbol} from "../../constants.mjs";
16
+ import {addAttributeToken} from "../../dom/attributes.mjs";
17
17
  import {
18
- ATTRIBUTE_ERRORMESSAGE,
19
- ATTRIBUTE_ROLE,
18
+ ATTRIBUTE_ERRORMESSAGE,
19
+ ATTRIBUTE_ROLE,
20
20
  } from "../../dom/constants.mjs";
21
21
  import {
22
- assembleMethodSymbol,
23
- registerCustomElement,
22
+ assembleMethodSymbol,
23
+ registerCustomElement,
24
24
  } from "../../dom/customelement.mjs";
25
- import { getDocument } from "../../dom/util.mjs";
26
- import { isFunction } from "../../types/is.mjs";
27
- import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
28
- import { Popper } from "./popper.mjs";
29
- import { STYLE_DISPLAY_MODE_BLOCK } from "./constants.mjs";
30
- import { PopperButtonStyleSheet } from "./stylesheet/popper-button.mjs";
31
- import { positionPopper } from "./util/floating-ui.mjs";
25
+ import {getDocument} from "../../dom/util.mjs";
26
+ import {isFunction} from "../../types/is.mjs";
27
+ import {DeadMansSwitch} from "../../util/deadmansswitch.mjs";
28
+ import {Popper} from "./popper.mjs";
29
+ import {STYLE_DISPLAY_MODE_BLOCK} from "./constants.mjs";
30
+ import {PopperButtonStyleSheet} from "./stylesheet/popper-button.mjs";
31
+ import {positionPopper} from "./util/floating-ui.mjs";
32
32
  import "./button.mjs";
33
+ import {addErrorAttribute} from "../../dom/error.mjs";
33
34
 
34
- export { PopperButton };
35
+ export {PopperButton};
35
36
 
36
37
  /**
37
38
  * @private
@@ -140,205 +141,205 @@ const arrowElementSymbol = Symbol("arrowElement");
140
141
  * @fires monster-changed
141
142
  */
142
143
  class PopperButton extends Popper {
143
- /**
144
- * This method is called by the `instanceof` operator.
145
- * @return {symbol}
146
- * @since 2.1.0
147
- */
148
- static get [instanceSymbol]() {
149
- return Symbol.for(
150
- "@schukai/monster/components/form/popper-button@@instance",
151
- );
152
- }
153
-
154
- /**
155
- * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
156
- * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
157
- *
158
- * The individual configuration values can be found in the table.
159
- *
160
- * @property {Object} templates - The templates for the control.
161
- * @property {string} templates.main - The main template.
162
- * @property {object} labels - The labels for the control.
163
- * @property {string} labels.button - The label for the button.
164
- * @property {string} content - The content of the popper.
165
- * @property {object} popper - The popper options.
166
- * @extends {Button.defaults}
167
- */
168
- get defaults() {
169
- return Object.assign({}, super.defaults, {
170
- templates: {
171
- main: getTemplate(),
172
- },
173
- actions: {
174
- click: (e) => {
175
- this.toggleDialog();
176
- },
177
- },
178
- classes: {
179
- button: "monster-button",
180
- },
181
- labels: {
182
- button: '<slot name="button"></slot>',
183
- },
184
- mode: "click",
185
- value: null,
186
- });
187
- }
188
-
189
- /**
190
- *
191
- * @return {Monster.Components.Form.PopperButton}
192
- */
193
- [assembleMethodSymbol]() {
194
- super[assembleMethodSymbol]();
195
- initControlReferences.call(this);
196
- initEventHandler.call(this);
197
-
198
- return this;
199
- }
200
-
201
- /**
202
- * @return {string}
203
- */
204
- static getTag() {
205
- return "monster-popper-button";
206
- }
207
-
208
- /**
209
- * @return {CSSStyleSheet[]}
210
- */
211
- static getCSSStyleSheet() {
212
- const styles = super.getCSSStyleSheet();
213
- styles.push(PopperButtonStyleSheet);
214
- return styles;
215
- }
216
-
217
- /**
218
- * @return {void}
219
- */
220
- connectedCallback() {
221
- super.connectedCallback();
222
-
223
- const document = getDocument();
224
-
225
- for (const [, type] of Object.entries(["click", "touch"])) {
226
- // close on outside ui-events
227
- document.addEventListener(type, this[closeEventHandler]);
228
- }
229
-
230
- updatePopper.call(this);
231
- attachResizeObserver.call(this);
232
- }
233
-
234
- /**
235
- * @return {void}
236
- */
237
- disconnectedCallback() {
238
- super.disconnectedCallback();
239
-
240
- // close on outside ui-events
241
- for (const [, type] of Object.entries(["click", "touch"])) {
242
- document.removeEventListener(type, this[closeEventHandler]);
243
- }
244
-
245
- disconnectResizeObserver.call(this);
246
- }
247
-
248
- /**
249
- * The Button.click() method simulates a click on the internal button element.
250
- *
251
- * @since 3.27.0
252
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click}
253
- */
254
- click() {
255
- if (this.getOption("disabled") === true) {
256
- return;
257
- }
258
-
259
- if (
260
- this[buttonElementSymbol] &&
261
- isFunction(this[buttonElementSymbol].click)
262
- ) {
263
- this[buttonElementSymbol].click();
264
- }
265
- }
266
-
267
- /**
268
- * The Button.focus() method sets focus on the internal button element.
269
- *
270
- * @since 3.27.0
271
- * @param {Object} options
272
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus}
273
- */
274
- focus(options) {
275
- if (this.getOption("disabled") === true) {
276
- return;
277
- }
278
-
279
- if (
280
- this[buttonElementSymbol] &&
281
- isFunction(this[buttonElementSymbol].focus)
282
- ) {
283
- this[buttonElementSymbol].focus(options);
284
- }
285
- }
286
-
287
- /**
288
- * The Button.blur() method removes focus from the internal button element.
289
- */
290
- blur() {
291
- if (
292
- this[buttonElementSymbol] &&
293
- isFunction(this[buttonElementSymbol].blur)
294
- ) {
295
- this[buttonElementSymbol].blur();
296
- }
297
- }
298
-
299
- /**
300
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals}
301
- * @return {boolean}
302
- */
303
- static get formAssociated() {
304
- return true;
305
- }
306
-
307
- /**
308
- * The current selection of the Select
309
- *
310
- * ```
311
- * e = document.querySelector('monster-select');
312
- * console.log(e.value)
313
- * // ↦ 1
314
- * // ↦ ['1','2']
315
- * ```
316
- *
317
- * @property {string|array}
318
- */
319
- get value() {
320
- return this.getOption("value");
321
- }
322
-
323
- /**
324
- * Set selection
325
- *
326
- * ```
327
- * e = document.querySelector('monster-select');
328
- * e.value=1
329
- * ```
330
- *
331
- * @property {string|array} value
332
- * @throws {Error} unsupported type
333
- */
334
- set value(value) {
335
- this.setOption("value", value);
336
- try {
337
- this?.setFormValue(this.value);
338
- } catch (e) {
339
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
340
- }
341
- }
144
+ /**
145
+ * This method is called by the `instanceof` operator.
146
+ * @return {symbol}
147
+ * @since 2.1.0
148
+ */
149
+ static get [instanceSymbol]() {
150
+ return Symbol.for(
151
+ "@schukai/monster/components/form/popper-button@@instance",
152
+ );
153
+ }
154
+
155
+ /**
156
+ * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
157
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
158
+ *
159
+ * The individual configuration values can be found in the table.
160
+ *
161
+ * @property {Object} templates - The templates for the control.
162
+ * @property {string} templates.main - The main template.
163
+ * @property {object} labels - The labels for the control.
164
+ * @property {string} labels.button - The label for the button.
165
+ * @property {string} content - The content of the popper.
166
+ * @property {object} popper - The popper options.
167
+ * @extends {Button.defaults}
168
+ */
169
+ get defaults() {
170
+ return Object.assign({}, super.defaults, {
171
+ templates: {
172
+ main: getTemplate(),
173
+ },
174
+ actions: {
175
+ click: (e) => {
176
+ this.toggleDialog();
177
+ },
178
+ },
179
+ classes: {
180
+ button: "monster-button",
181
+ },
182
+ labels: {
183
+ button: '<slot name="button"></slot>',
184
+ },
185
+ mode: "click",
186
+ value: null,
187
+ });
188
+ }
189
+
190
+ /**
191
+ *
192
+ * @return {Monster.Components.Form.PopperButton}
193
+ */
194
+ [assembleMethodSymbol]() {
195
+ super[assembleMethodSymbol]();
196
+ initControlReferences.call(this);
197
+ initEventHandler.call(this);
198
+
199
+ return this;
200
+ }
201
+
202
+ /**
203
+ * @return {string}
204
+ */
205
+ static getTag() {
206
+ return "monster-popper-button";
207
+ }
208
+
209
+ /**
210
+ * @return {CSSStyleSheet[]}
211
+ */
212
+ static getCSSStyleSheet() {
213
+ const styles = super.getCSSStyleSheet();
214
+ styles.push(PopperButtonStyleSheet);
215
+ return styles;
216
+ }
217
+
218
+ /**
219
+ * @return {void}
220
+ */
221
+ connectedCallback() {
222
+ super.connectedCallback();
223
+
224
+ const document = getDocument();
225
+
226
+ for (const [, type] of Object.entries(["click", "touch"])) {
227
+ // close on outside ui-events
228
+ document.addEventListener(type, this[closeEventHandler]);
229
+ }
230
+
231
+ updatePopper.call(this);
232
+ attachResizeObserver.call(this);
233
+ }
234
+
235
+ /**
236
+ * @return {void}
237
+ */
238
+ disconnectedCallback() {
239
+ super.disconnectedCallback();
240
+
241
+ // close on outside ui-events
242
+ for (const [, type] of Object.entries(["click", "touch"])) {
243
+ document.removeEventListener(type, this[closeEventHandler]);
244
+ }
245
+
246
+ disconnectResizeObserver.call(this);
247
+ }
248
+
249
+ /**
250
+ * The Button.click() method simulates a click on the internal button element.
251
+ *
252
+ * @since 3.27.0
253
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click}
254
+ */
255
+ click() {
256
+ if (this.getOption("disabled") === true) {
257
+ return;
258
+ }
259
+
260
+ if (
261
+ this[buttonElementSymbol] &&
262
+ isFunction(this[buttonElementSymbol].click)
263
+ ) {
264
+ this[buttonElementSymbol].click();
265
+ }
266
+ }
267
+
268
+ /**
269
+ * The Button.focus() method sets focus on the internal button element.
270
+ *
271
+ * @since 3.27.0
272
+ * @param {Object} options
273
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus}
274
+ */
275
+ focus(options) {
276
+ if (this.getOption("disabled") === true) {
277
+ return;
278
+ }
279
+
280
+ if (
281
+ this[buttonElementSymbol] &&
282
+ isFunction(this[buttonElementSymbol].focus)
283
+ ) {
284
+ this[buttonElementSymbol].focus(options);
285
+ }
286
+ }
287
+
288
+ /**
289
+ * The Button.blur() method removes focus from the internal button element.
290
+ */
291
+ blur() {
292
+ if (
293
+ this[buttonElementSymbol] &&
294
+ isFunction(this[buttonElementSymbol].blur)
295
+ ) {
296
+ this[buttonElementSymbol].blur();
297
+ }
298
+ }
299
+
300
+ /**
301
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals}
302
+ * @return {boolean}
303
+ */
304
+ static get formAssociated() {
305
+ return true;
306
+ }
307
+
308
+ /**
309
+ * The current selection of the Select
310
+ *
311
+ * ```
312
+ * e = document.querySelector('monster-select');
313
+ * console.log(e.value)
314
+ * // ↦ 1
315
+ * // ↦ ['1','2']
316
+ * ```
317
+ *
318
+ * @property {string|array}
319
+ */
320
+ get value() {
321
+ return this.getOption("value");
322
+ }
323
+
324
+ /**
325
+ * Set selection
326
+ *
327
+ * ```
328
+ * e = document.querySelector('monster-select');
329
+ * e.value=1
330
+ * ```
331
+ *
332
+ * @property {string|array} value
333
+ * @throws {Error} unsupported type
334
+ */
335
+ set value(value) {
336
+ this.setOption("value", value);
337
+ try {
338
+ this?.setFormValue(this.value);
339
+ } catch (e) {
340
+ addErrorAttribute(this, e);
341
+ }
342
+ }
342
343
  }
343
344
 
344
345
  /**
@@ -346,67 +347,67 @@ class PopperButton extends Popper {
346
347
  * @return {initEventHandler}
347
348
  */
348
349
  function initEventHandler() {
349
- this[closeEventHandler] = (event) => {
350
- const path = event.composedPath();
351
-
352
- for (const [, element] of Object.entries(path)) {
353
- if (element === this) {
354
- return;
355
- }
356
- }
357
- this.hideDialog();
358
- };
359
-
360
- return this;
350
+ this[closeEventHandler] = (event) => {
351
+ const path = event.composedPath();
352
+
353
+ for (const [, element] of Object.entries(path)) {
354
+ if (element === this) {
355
+ return;
356
+ }
357
+ }
358
+ this.hideDialog();
359
+ };
360
+
361
+ return this;
361
362
  }
362
363
 
363
364
  /**
364
365
  * @private
365
366
  */
366
367
  function attachResizeObserver() {
367
- // against flickering
368
- this[resizeObserverSymbol] = new ResizeObserver(() => {
369
- if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
370
- try {
371
- this[timerCallbackSymbol].touch();
372
- return;
373
- } catch (e) {
374
- delete this[timerCallbackSymbol];
375
- }
376
- }
377
-
378
- this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
379
- updatePopper.call(this);
380
- });
381
- });
382
-
383
- this[resizeObserverSymbol].observe(this.parentElement);
368
+ // against flickering
369
+ this[resizeObserverSymbol] = new ResizeObserver(() => {
370
+ if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
371
+ try {
372
+ this[timerCallbackSymbol].touch();
373
+ return;
374
+ } catch (e) {
375
+ delete this[timerCallbackSymbol];
376
+ }
377
+ }
378
+
379
+ this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
380
+ updatePopper.call(this);
381
+ });
382
+ });
383
+
384
+ this[resizeObserverSymbol].observe(this.parentElement);
384
385
  }
385
386
 
386
387
  function disconnectResizeObserver() {
387
- if (this[resizeObserverSymbol] instanceof ResizeObserver) {
388
- this[resizeObserverSymbol].disconnect();
389
- }
388
+ if (this[resizeObserverSymbol] instanceof ResizeObserver) {
389
+ this[resizeObserverSymbol].disconnect();
390
+ }
390
391
  }
391
392
 
392
393
  /**
393
394
  * @private
394
395
  */
395
396
  function updatePopper() {
396
- if (this[popperElementSymbol].style.display !== STYLE_DISPLAY_MODE_BLOCK) {
397
- return;
398
- }
399
-
400
- if (this.getOption("disabled", false) === true) {
401
- return;
402
- }
403
-
404
- positionPopper.call(
405
- this,
406
- this[controlElementSymbol],
407
- this[popperElementSymbol],
408
- this.getOption("popper", {}),
409
- );
397
+ if (this[popperElementSymbol].style.display !== STYLE_DISPLAY_MODE_BLOCK) {
398
+ return;
399
+ }
400
+
401
+ if (this.getOption("disabled", false) === true) {
402
+ return;
403
+ }
404
+
405
+ positionPopper.call(
406
+ this,
407
+ this[controlElementSymbol],
408
+ this[popperElementSymbol],
409
+ this.getOption("popper", {}),
410
+ );
410
411
  }
411
412
 
412
413
  /**
@@ -414,21 +415,21 @@ function updatePopper() {
414
415
  * @return {Select}
415
416
  */
416
417
  function initControlReferences() {
417
- this[controlElementSymbol] = this.shadowRoot.querySelector(
418
- `[${ATTRIBUTE_ROLE}=control]`,
419
- );
418
+ this[controlElementSymbol] = this.shadowRoot.querySelector(
419
+ `[${ATTRIBUTE_ROLE}=control]`,
420
+ );
420
421
 
421
- this[buttonElementSymbol] = this.shadowRoot.querySelector(
422
- `[${ATTRIBUTE_ROLE}=button]`,
423
- );
422
+ this[buttonElementSymbol] = this.shadowRoot.querySelector(
423
+ `[${ATTRIBUTE_ROLE}=button]`,
424
+ );
424
425
 
425
- this[popperElementSymbol] = this.shadowRoot.querySelector(
426
- `[${ATTRIBUTE_ROLE}=popper]`,
427
- );
426
+ this[popperElementSymbol] = this.shadowRoot.querySelector(
427
+ `[${ATTRIBUTE_ROLE}=popper]`,
428
+ );
428
429
 
429
- this[arrowElementSymbol] = this.shadowRoot.querySelector(
430
- `[${ATTRIBUTE_ROLE}=arrow]`,
431
- );
430
+ this[arrowElementSymbol] = this.shadowRoot.querySelector(
431
+ `[${ATTRIBUTE_ROLE}=arrow]`,
432
+ );
432
433
  }
433
434
 
434
435
  /**
@@ -436,8 +437,8 @@ function initControlReferences() {
436
437
  * @return {string}
437
438
  */
438
439
  function getTemplate() {
439
- // language=HTML
440
- return `
440
+ // language=HTML
441
+ return `
441
442
  <div data-monster-role="control" part="control">
442
443
  <button data-monster-attributes="disabled path:disabled | if:true, class path:classes.button"
443
444
  data-monster-role="button"
@@ -28,6 +28,7 @@ import {
28
28
  import { isString } from "../../types/is.mjs";
29
29
  import { ATTRIBUTE_FORM_RELOAD, ATTRIBUTE_FORM_URL } from "./constants.mjs";
30
30
  import { loadAndAssignContent } from "./util/fetch.mjs";
31
+ import {addErrorAttribute} from "../../dom/error.mjs";
31
32
 
32
33
  export { Reload };
33
34