@schukai/monster 4.137.8 → 4.138.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 (140) hide show
  1. package/package.json +1 -1
  2. package/source/components/accessibility/stylesheet/locale-picker.mjs +1 -1
  3. package/source/components/content/stylesheet/camera-capture.mjs +1 -1
  4. package/source/components/content/stylesheet/copy.mjs +1 -1
  5. package/source/components/content/stylesheet/fetch-box.mjs +1 -1
  6. package/source/components/content/stylesheet/viewer.mjs +1 -1
  7. package/source/components/content/viewer/stylesheet/html.mjs +1 -1
  8. package/source/components/content/viewer/stylesheet/message.mjs +1 -1
  9. package/source/components/data/stylesheet/kpi-tile.mjs +1 -1
  10. package/source/components/data/stylesheet/metric-graph.mjs +1 -1
  11. package/source/components/data/stylesheet/metric.mjs +1 -1
  12. package/source/components/datatable/columnbar.mjs +11 -8
  13. package/source/components/datatable/pagination.mjs +9 -19
  14. package/source/components/datatable/stylesheet/change-button.mjs +1 -1
  15. package/source/components/datatable/stylesheet/column-bar.mjs +1 -1
  16. package/source/components/datatable/stylesheet/dataset.mjs +1 -1
  17. package/source/components/datatable/stylesheet/datasource.mjs +1 -1
  18. package/source/components/datatable/stylesheet/datatable.mjs +1 -1
  19. package/source/components/datatable/stylesheet/embedded-pagination.mjs +1 -1
  20. package/source/components/datatable/stylesheet/filter-button.mjs +1 -1
  21. package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +1 -1
  22. package/source/components/datatable/stylesheet/filter-date-range.mjs +1 -1
  23. package/source/components/datatable/stylesheet/filter-range.mjs +1 -1
  24. package/source/components/datatable/stylesheet/filter-select.mjs +1 -1
  25. package/source/components/datatable/stylesheet/filter.mjs +1 -1
  26. package/source/components/datatable/stylesheet/pagination.mjs +1 -1
  27. package/source/components/datatable/stylesheet/save-button.mjs +1 -1
  28. package/source/components/datatable/stylesheet/status.mjs +1 -1
  29. package/source/components/form/button-bar.mjs +7 -1054
  30. package/source/components/form/control-bar.mjs +1162 -0
  31. package/source/components/form/style/button-bar.pcss +9 -4
  32. package/source/components/form/style/confirm-button.pcss +6 -1
  33. package/source/components/form/style/control-bar.pcss +91 -0
  34. package/source/components/form/stylesheet/action-button.mjs +1 -1
  35. package/source/components/form/stylesheet/button-bar.mjs +1 -1
  36. package/source/components/form/stylesheet/button.mjs +1 -1
  37. package/source/components/form/stylesheet/buy-box.mjs +1 -1
  38. package/source/components/form/stylesheet/cart-control.mjs +1 -1
  39. package/source/components/form/stylesheet/confirm-button.mjs +1 -1
  40. package/source/components/form/stylesheet/context-error.mjs +1 -1
  41. package/source/components/form/stylesheet/context-help.mjs +1 -1
  42. package/source/components/form/stylesheet/control-bar.mjs +38 -0
  43. package/source/components/form/stylesheet/digits.mjs +1 -1
  44. package/source/components/form/stylesheet/dropzone.mjs +1 -1
  45. package/source/components/form/stylesheet/field-layout.mjs +1 -1
  46. package/source/components/form/stylesheet/field-set.mjs +1 -1
  47. package/source/components/form/stylesheet/form.mjs +1 -1
  48. package/source/components/form/stylesheet/input-group.mjs +1 -1
  49. package/source/components/form/stylesheet/invalid.mjs +1 -1
  50. package/source/components/form/stylesheet/login.mjs +1 -1
  51. package/source/components/form/stylesheet/message-state-button.mjs +1 -1
  52. package/source/components/form/stylesheet/password.mjs +1 -1
  53. package/source/components/form/stylesheet/popper-button.mjs +1 -1
  54. package/source/components/form/stylesheet/quantity.mjs +1 -1
  55. package/source/components/form/stylesheet/register-wizard.mjs +1 -1
  56. package/source/components/form/stylesheet/repeat-field-set-items.mjs +1 -1
  57. package/source/components/form/stylesheet/repeat-field-set.mjs +1 -1
  58. package/source/components/form/stylesheet/select.mjs +1 -1
  59. package/source/components/form/stylesheet/sheet.mjs +1 -1
  60. package/source/components/form/stylesheet/state-button.mjs +1 -1
  61. package/source/components/form/stylesheet/toggle-switch.mjs +1 -1
  62. package/source/components/form/stylesheet/tree-select.mjs +1 -1
  63. package/source/components/form/stylesheet/variant-select.mjs +1 -1
  64. package/source/components/form/stylesheet/wizard.mjs +1 -1
  65. package/source/components/host/stylesheet/call-button.mjs +1 -1
  66. package/source/components/host/stylesheet/host.mjs +1 -1
  67. package/source/components/host/stylesheet/toggle-button.mjs +1 -1
  68. package/source/components/layout/stylesheet/board.mjs +1 -1
  69. package/source/components/layout/stylesheet/collapse.mjs +1 -1
  70. package/source/components/layout/stylesheet/details.mjs +1 -1
  71. package/source/components/layout/stylesheet/full-screen.mjs +1 -1
  72. package/source/components/layout/stylesheet/iframe.mjs +1 -1
  73. package/source/components/layout/stylesheet/overlay.mjs +1 -1
  74. package/source/components/layout/stylesheet/panel.mjs +1 -1
  75. package/source/components/layout/stylesheet/popper.mjs +1 -1
  76. package/source/components/layout/stylesheet/slider.mjs +1 -1
  77. package/source/components/layout/stylesheet/split-panel.mjs +1 -1
  78. package/source/components/layout/stylesheet/tabs.mjs +1 -1
  79. package/source/components/layout/stylesheet/width-toggle.mjs +1 -1
  80. package/source/components/navigation/site-navigation.mjs +4 -2
  81. package/source/components/navigation/stylesheet/site-navigation.mjs +1 -1
  82. package/source/components/navigation/stylesheet/table-of-content.mjs +1 -1
  83. package/source/components/navigation/stylesheet/wizard-navigation.mjs +1 -1
  84. package/source/components/notify/stylesheet/message.mjs +1 -1
  85. package/source/components/notify/stylesheet/notify.mjs +1 -1
  86. package/source/components/state/stylesheet/log.mjs +1 -1
  87. package/source/components/state/stylesheet/state.mjs +1 -1
  88. package/source/components/state/stylesheet/thread.mjs +1 -1
  89. package/source/components/style/accessibility.css +6 -6
  90. package/source/components/style/badge.css +49 -49
  91. package/source/components/style/border.css +4 -4
  92. package/source/components/style/button.css +96 -92
  93. package/source/components/style/card.css +21 -15
  94. package/source/components/style/common.css +20 -11
  95. package/source/components/style/control.css +3 -3
  96. package/source/components/style/data-grid.css +82 -82
  97. package/source/components/style/floating-ui.css +25 -25
  98. package/source/components/style/form.css +12 -10
  99. package/source/components/style/host.css +3 -3
  100. package/source/components/style/icons.css +266 -266
  101. package/source/components/style/link.css +4 -2
  102. package/source/components/style/normalize.css +2 -2
  103. package/source/components/style/popper.css +21 -21
  104. package/source/components/style/property.css +3 -2
  105. package/source/components/style/ripple.css +4 -4
  106. package/source/components/style/skeleton.css +10 -10
  107. package/source/components/style/spinner.css +1 -1
  108. package/source/components/style/table.css +10 -10
  109. package/source/components/style/theme.css +2 -2
  110. package/source/components/style/typography.css +29 -29
  111. package/source/components/stylesheet/accessibility.mjs +1 -1
  112. package/source/components/stylesheet/badge.mjs +1 -1
  113. package/source/components/stylesheet/border.mjs +1 -1
  114. package/source/components/stylesheet/button.mjs +1 -1
  115. package/source/components/stylesheet/card.mjs +1 -1
  116. package/source/components/stylesheet/common.mjs +1 -1
  117. package/source/components/stylesheet/control.mjs +1 -1
  118. package/source/components/stylesheet/data-grid.mjs +1 -1
  119. package/source/components/stylesheet/floating-ui.mjs +1 -1
  120. package/source/components/stylesheet/form.mjs +1 -1
  121. package/source/components/stylesheet/host.mjs +1 -1
  122. package/source/components/stylesheet/icons.mjs +1 -1
  123. package/source/components/stylesheet/link.mjs +1 -1
  124. package/source/components/stylesheet/popper.mjs +1 -1
  125. package/source/components/stylesheet/ripple.mjs +1 -1
  126. package/source/components/stylesheet/skeleton.mjs +1 -1
  127. package/source/components/stylesheet/spinner.mjs +1 -1
  128. package/source/components/stylesheet/table.mjs +1 -1
  129. package/source/components/stylesheet/theme.mjs +1 -1
  130. package/source/components/stylesheet/typography.mjs +1 -1
  131. package/source/components/time/stylesheet/day.mjs +1 -1
  132. package/source/components/time/stylesheet/month-calendar.mjs +1 -1
  133. package/source/components/time/timeline/stylesheet/appointment.mjs +1 -1
  134. package/source/components/time/timeline/stylesheet/segment.mjs +1 -1
  135. package/source/components/tree-menu/stylesheet/tree-menu.mjs +1 -1
  136. package/source/dom/resource/data.mjs +5 -2
  137. package/source/monster.mjs +1 -0
  138. package/test/cases/components/form/button-bar.mjs +27 -0
  139. package/test/cases/components/form/confirm-button.mjs +14 -0
  140. package/test/cases/components/form/control-bar.mjs +230 -0
@@ -13,142 +13,11 @@
13
13
  */
14
14
 
15
15
  import { instanceSymbol } from "../../constants.mjs";
16
- import { Pathfinder } from "../../data/pathfinder.mjs";
17
- import {
18
- addAttributeToken,
19
- removeAttributeToken,
20
- } from "../../dom/attributes.mjs";
21
- import {
22
- ATTRIBUTE_ERRORMESSAGE,
23
- ATTRIBUTE_ROLE,
24
- } from "../../dom/constants.mjs";
25
- import {
26
- assembleMethodSymbol,
27
- getSlottedElements,
28
- registerCustomElement,
29
- } from "../../dom/customelement.mjs";
30
- import {
31
- CustomElement,
32
- attributeObserverSymbol,
33
- } from "../../dom/customelement.mjs";
34
- import { findTargetElementFromEvent } from "../../dom/events.mjs";
35
- import { getDocument } from "../../dom/util.mjs";
36
- import { getGlobal } from "../../types/global.mjs";
37
- import { ID } from "../../types/id.mjs";
38
- import { Observer } from "../../types/observer.mjs";
39
- import { STYLE_DISPLAY_MODE_BLOCK } from "./constants.mjs";
16
+ import { registerCustomElement } from "../../dom/customelement.mjs";
40
17
  import { ButtonBarStyleSheet } from "./stylesheet/button-bar.mjs";
41
- import { positionPopper } from "./util/floating-ui.mjs";
42
- import { convertToPixels } from "../../dom/dimension.mjs";
43
- import { addErrorAttribute } from "../../dom/error.mjs";
44
- import { Processing } from "../../util/processing.mjs";
45
- export { ButtonBar };
46
-
47
- /**
48
- * @private
49
- * @type {symbol}
50
- */
51
- /**
52
- * local symbol
53
- * @private
54
- * @type {symbol}
55
- */
56
- const resizeObserverSymbol = Symbol("windowResizeObserver");
57
-
58
- /**
59
- * @private
60
- * @type {symbol}
61
- */
62
- const dimensionsSymbol = Symbol("dimensions");
63
-
64
- /**
65
- * @private
66
- * @type {symbol}
67
- */
68
- const controlElementSymbol = Symbol("controlElement");
69
-
70
- /**
71
- * @private
72
- * @type {symbol}
73
- */
74
- const buttonBarSlotElementSymbol = Symbol("buttonBarSlotElement");
75
-
76
- /**
77
- * @private
78
- * @type {symbol}
79
- */
80
- const popperSlotElementSymbol = Symbol("popperSlotElement");
81
-
82
- /**
83
- * @private
84
- * @type {symbol}
85
- */
86
- const buttonBarElementSymbol = Symbol("buttonBarElement");
87
-
88
- /**
89
- * @private
90
- * @type {symbol}
91
- */
92
- const popperElementSymbol = Symbol("popperElement");
93
-
94
- /**
95
- * local symbol
96
- * @private
97
- * @type {symbol}
98
- */
99
- const closeEventHandler = Symbol("closeEventHandler");
100
-
101
- /**
102
- * @private
103
- * @type {symbol}
104
- */
105
- const popperSwitchEventHandler = Symbol("popperSwitchEventHandler");
106
-
107
- /**
108
- * @private
109
- * @type {symbol}
110
- */
111
- const popperNavElementSymbol = Symbol("popperNavElement");
112
-
113
- /**
114
- * @private
115
- * @type {symbol}
116
- */
117
- const mutationObserverSymbol = Symbol("mutationObserver");
118
-
119
- /**
120
- * @private
121
- * @type {symbol}
122
- */
123
- const switchElementSymbol = Symbol("switchElement");
18
+ import { ControlBar } from "./control-bar.mjs";
124
19
 
125
- /**
126
- * @private
127
- * @type {symbol}
128
- */
129
- const layoutStateSymbol = Symbol("layoutState");
130
- const layoutFrameSymbol = Symbol("layoutFrame");
131
- const layoutTokenSymbol = Symbol("layoutToken");
132
- const observedLayoutNodesSignatureSymbol = Symbol("observedLayoutNodesSignature");
133
-
134
- /**
135
- * @private
136
- * @type {WeakMap<HTMLElement, number>}
137
- */
138
- const layoutNodeIds = new WeakMap();
139
- let layoutNodeId = 0;
140
-
141
- /**
142
- * @private
143
- * @type {string}
144
- */
145
- const ATTRIBUTE_POPPER_POSITION = "data-monster-popper-position";
146
-
147
- /**
148
- * @private
149
- * @type {string}
150
- */
151
- const ATTRIBUTE_LAYOUT_ALIGNMENT = "data-monster-layout-alignment";
20
+ export { ButtonBar };
152
21
 
153
22
  /**
154
23
  * A button bar control.
@@ -161,7 +30,7 @@ const ATTRIBUTE_LAYOUT_ALIGNMENT = "data-monster-layout-alignment";
161
30
  * @summary A responsive button bar that groups multiple actions and moves overflowed buttons into a menu.
162
31
  * @fires monster-fetched
163
32
  */
164
- class ButtonBar extends CustomElement {
33
+ class ButtonBar extends ControlBar {
165
34
  /**
166
35
  * This method is called by the `instanceof` operator.
167
36
  * @return {symbol}
@@ -172,66 +41,15 @@ class ButtonBar extends CustomElement {
172
41
 
173
42
  /**
174
43
  * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
175
- * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
176
- *
177
- * The individual configuration values can be found in the table.
178
44
  *
179
- * @property {Object} templates Template definitions
180
- * @property {string} templates.main Main template
181
- * @property {Object} labels
182
- * @property {Object} popper FloatingUI popper configuration
183
- * @property {string} popper.placement=top Placement of the popper
184
- * @property {Array<string>} popper.middleware Middleware for the popper
45
+ * @return {Object}
185
46
  */
186
47
  get defaults() {
187
- const obj = Object.assign({}, super.defaults, {
48
+ return Object.assign({}, super.defaults, {
188
49
  templates: {
189
50
  main: getTemplate(),
190
51
  },
191
- labels: {},
192
- layout: {
193
- alignment: "left",
194
- },
195
- popper: {
196
- placement: "left",
197
- middleware: ["flip", "shift", "offset:5"],
198
- },
199
52
  });
200
-
201
- initDefaultsFromAttributes.call(this, obj);
202
-
203
- return obj;
204
- }
205
-
206
- /**
207
- * This method is called internal and should not be called directly.
208
- */
209
- [assembleMethodSymbol]() {
210
- super[assembleMethodSymbol]();
211
-
212
- this[dimensionsSymbol] = new Pathfinder({ data: {} });
213
- this[layoutStateSymbol] = {
214
- scheduled: false,
215
- running: false,
216
- needsMeasure: true,
217
- needsLayout: true,
218
- needsObserve: true,
219
- suppressSlotChange: false,
220
- suppressMutation: false,
221
- };
222
-
223
- initControlReferences.call(this);
224
- initEventHandler.call(this);
225
-
226
- // setup structure
227
- initButtonBar.call(this);
228
- initPopperSwitch.call(this);
229
- applyLayoutAlignment.call(this);
230
- this.attachObserver(
231
- new Observer(() => {
232
- applyLayoutAlignment.call(this);
233
- }),
234
- );
235
53
  }
236
54
 
237
55
  /**
@@ -240,7 +58,7 @@ class ButtonBar extends CustomElement {
240
58
  * @return {CSSStyleSheet[]}
241
59
  */
242
60
  static getCSSStyleSheet() {
243
- return [ButtonBarStyleSheet];
61
+ return [...super.getCSSStyleSheet(), ButtonBarStyleSheet];
244
62
  }
245
63
 
246
64
  /**
@@ -251,871 +69,6 @@ class ButtonBar extends CustomElement {
251
69
  static getTag() {
252
70
  return "monster-button-bar";
253
71
  }
254
-
255
- /**
256
- * This method is called by the dom and should not be called directly.
257
- *
258
- * @return {void}
259
- */
260
- connectedCallback() {
261
- super.connectedCallback();
262
-
263
- const document = getDocument();
264
-
265
- for (const [, type] of Object.entries(["click", "touch"])) {
266
- // close on outside ui-events
267
- document.addEventListener(type, this[closeEventHandler]);
268
- }
269
-
270
- scheduleLayout.call(this, { measure: true, layout: true, observe: true });
271
- }
272
-
273
- /**
274
- * This method determines which attributes are to be monitored by `attributeChangedCallback()`.
275
- *
276
- * @return {string[]}
277
- */
278
- static get observedAttributes() {
279
- const attributes = super.observedAttributes;
280
- attributes.push(ATTRIBUTE_POPPER_POSITION);
281
- return attributes;
282
- }
283
-
284
- /**
285
- * This method is called by the dom and should not be called directly.
286
- *
287
- * @return {void}
288
- */
289
- disconnectedCallback() {
290
- super.disconnectedCallback();
291
-
292
- const document = getDocument();
293
-
294
- // close on outside ui-events
295
- for (const [, type] of Object.entries(["click", "touch"])) {
296
- document.removeEventListener(type, this[closeEventHandler]);
297
- }
298
-
299
- if (typeof this[layoutFrameSymbol] === "number") {
300
- cancelAnimationFrame(this[layoutFrameSymbol]);
301
- }
302
- delete this[layoutFrameSymbol];
303
- this[layoutTokenSymbol] = (this[layoutTokenSymbol] || 0) + 1;
304
-
305
- disconnectResizeObserver.call(this);
306
- if (this[mutationObserverSymbol]) {
307
- this[mutationObserverSymbol].disconnect();
308
- }
309
- }
310
-
311
- /**
312
- * Close the slotted dialog.
313
- * @return {ButtonBar}
314
- */
315
- hideDialog() {
316
- hide.call(this);
317
- return this;
318
- }
319
-
320
- /**
321
- * Open the slotted dialog.
322
- * @return {ButtonBar}
323
- */
324
- showDialog() {
325
- show.call(this);
326
- return this;
327
- }
328
-
329
- /**
330
- * Toggle the slotted dialog.
331
- * @return {ButtonBar}
332
- */
333
- toggleDialog() {
334
- toggle.call(this);
335
- return this;
336
- }
337
- }
338
-
339
- /**
340
- * @private
341
- * @param obj
342
- * @return {*}
343
- */
344
- function initDefaultsFromAttributes(obj) {
345
- if (this.hasAttribute(ATTRIBUTE_POPPER_POSITION)) {
346
- obj.popper.placement = this.getAttribute(ATTRIBUTE_POPPER_POSITION);
347
- }
348
-
349
- return obj;
350
- }
351
-
352
- /**
353
- * @private
354
- * @param {HTMLElement} element
355
- * @return {boolean}
356
- */
357
- function isElementTrulyVisible(element) {
358
- if (!(element instanceof HTMLElement)) {
359
- return false;
360
- }
361
- const computedStyle = getComputedStyle(element);
362
- return (
363
- computedStyle.display !== "none" &&
364
- computedStyle.visibility !== "hidden" &&
365
- computedStyle.opacity !== "0" &&
366
- element.offsetWidth > 0 &&
367
- element.offsetHeight > 0
368
- );
369
- }
370
-
371
- /**
372
- * @private
373
- * @param {HTMLElement} element
374
- * @return {boolean}
375
- */
376
- function isElementSelfHidden(element) {
377
- if (!(element instanceof HTMLElement)) {
378
- return true;
379
- }
380
-
381
- const computedStyle = getComputedStyle(element);
382
- return (
383
- element.hidden === true ||
384
- element.hasAttribute("hidden") ||
385
- computedStyle.display === "none" ||
386
- computedStyle.visibility === "hidden"
387
- );
388
- }
389
-
390
- /**
391
- * @private
392
- */
393
- function initEventHandler() {
394
- const self = this;
395
-
396
- const mutationCallback = (mutationList) => {
397
- if (self[layoutStateSymbol]?.suppressMutation) {
398
- return;
399
- }
400
-
401
- let needsRecalc = false;
402
- for (const mutation of mutationList) {
403
- if (mutation.type === "attributes") {
404
- const target = mutation.target;
405
- if (target instanceof HTMLElement) {
406
- const ref = target.getAttribute("data-monster-reference");
407
- if (ref) {
408
- if (!isElementTrulyVisible(target)) {
409
- self[dimensionsSymbol].setVia(`data.button.${ref}`, 0);
410
- }
411
- needsRecalc = true;
412
- }
413
- }
414
- }
415
- }
416
- if (needsRecalc) {
417
- scheduleLayout.call(self, { measure: true, layout: true });
418
- }
419
- };
420
-
421
- /**
422
- * @param {Event} event
423
- */
424
- self[closeEventHandler] = (event) => {
425
- const path = event.composedPath();
426
- for (const element of path) {
427
- if (element === self) return;
428
- }
429
- hide.call(self);
430
- };
431
-
432
- if (self[buttonBarSlotElementSymbol]) {
433
- self[buttonBarSlotElementSymbol].addEventListener("slotchange", () => {
434
- if (self[layoutStateSymbol]?.suppressSlotChange) {
435
- return;
436
- }
437
- scheduleLayout.call(self, {
438
- measure: true,
439
- layout: true,
440
- observe: true,
441
- });
442
- });
443
- }
444
-
445
- if (self[popperElementSymbol]) {
446
- self[popperElementSymbol].addEventListener("slotchange", () => {
447
- if (self[layoutStateSymbol]?.suppressSlotChange) {
448
- return;
449
- }
450
- scheduleLayout.call(self, {
451
- measure: true,
452
- layout: true,
453
- observe: true,
454
- });
455
- });
456
- }
457
-
458
- self[attributeObserverSymbol][ATTRIBUTE_POPPER_POSITION] = function (value) {
459
- self.setOption("classes.button", value);
460
- };
461
-
462
- self[resizeObserverSymbol] = new ResizeObserver(() => {
463
- scheduleLayout.call(self, { measure: true, layout: true });
464
- });
465
- self[mutationObserverSymbol] = new MutationObserver(mutationCallback);
466
-
467
- initSlotChangedHandler.call(self);
468
- }
469
-
470
- function initSlotChangedHandler() {
471
- this[buttonBarElementSymbol].addEventListener("slotchange", () => {
472
- if (this[layoutStateSymbol]?.suppressSlotChange) {
473
- return;
474
- }
475
- scheduleLayout.call(this, { observe: true });
476
- });
477
- }
478
-
479
- function scheduleLayout(options = {}) {
480
- if (!this[layoutStateSymbol]) {
481
- return;
482
- }
483
-
484
- const state = this[layoutStateSymbol];
485
- state.needsMeasure = state.needsMeasure || options.measure === true;
486
- state.needsLayout = state.needsLayout || options.layout === true;
487
- state.needsObserve = state.needsObserve || options.observe === true;
488
-
489
- if (state.scheduled || state.running) {
490
- return;
491
- }
492
-
493
- scheduleLayoutFrame.call(this);
494
- }
495
-
496
- function scheduleLayoutFrame() {
497
- const state = this[layoutStateSymbol];
498
- if (!state || state.scheduled || state.running) {
499
- return;
500
- }
501
-
502
- state.scheduled = true;
503
- const token = (this[layoutTokenSymbol] || 0) + 1;
504
- this[layoutTokenSymbol] = token;
505
- this[layoutFrameSymbol] = requestAnimationFrame(() => {
506
- if (this[layoutTokenSymbol] !== token) {
507
- return;
508
- }
509
- delete this[layoutFrameSymbol];
510
- runLayout.call(this);
511
- });
512
- }
513
-
514
- function runLayout() {
515
- const state = this[layoutStateSymbol];
516
- if (!state) {
517
- return;
518
- }
519
-
520
- state.scheduled = false;
521
- if (!this.isConnected) {
522
- return;
523
- }
524
-
525
- if (state.running) {
526
- return;
527
- }
528
-
529
- const needsObserve = state.needsObserve;
530
- const needsMeasure = state.needsMeasure;
531
- const needsLayout = state.needsLayout;
532
-
533
- state.needsObserve = false;
534
- state.needsMeasure = false;
535
- state.needsLayout = false;
536
- state.running = true;
537
-
538
- new Processing(() => {
539
- if (needsObserve) {
540
- updateResizeObserverObservation.call(this);
541
- }
542
-
543
- if (needsMeasure) {
544
- try {
545
- calculateButtonBarDimensions.call(this);
546
- } catch (error) {
547
- addErrorAttribute(
548
- this,
549
- error?.message || "An error occurred while calculating dimensions",
550
- );
551
- }
552
- }
553
-
554
- if (needsLayout) {
555
- try {
556
- rearrangeButtons.call(this);
557
- } catch (error) {
558
- addErrorAttribute(
559
- this,
560
- error?.message || "An error occurred while rearranging the buttons",
561
- );
562
- }
563
- }
564
-
565
- return updatePopper.call(this);
566
- })
567
- .run()
568
- .catch((error) => {
569
- addErrorAttribute(
570
- this,
571
- error?.message ||
572
- "An error occurred while running the button bar layout",
573
- );
574
- })
575
- .finally(() => {
576
- state.running = false;
577
- if (state.needsObserve || state.needsMeasure || state.needsLayout) {
578
- scheduleLayoutFrame.call(this);
579
- }
580
- });
581
- }
582
-
583
- /**
584
- * @private
585
- * @return {Object}
586
- */
587
- function rearrangeButtons() {
588
- let space = 0;
589
- try {
590
- space = this[dimensionsSymbol].getVia("data.space");
591
- } catch {}
592
-
593
- const buttonReferences = this[dimensionsSymbol].getVia(
594
- "data.buttonReferences",
595
- [],
596
- );
597
- const hasButtons = buttonReferences.length > 0;
598
-
599
- const buttonEntries = [];
600
-
601
- for (const ref of buttonReferences) {
602
- let elements = getSlottedElements.call(
603
- this,
604
- '[data-monster-reference="' + ref + '"]',
605
- null,
606
- ); // null ↦ o
607
- if (elements.size === 0) {
608
- elements = getSlottedElements.call(
609
- this,
610
- '[data-monster-reference="' + ref + '"]',
611
- "popper",
612
- ); // null ↦ o
613
- }
614
-
615
- const nextValue = elements.values().next();
616
- if (!nextValue) {
617
- continue;
618
- }
619
-
620
- const element = nextValue?.value;
621
- if (!(element instanceof HTMLElement)) {
622
- continue;
623
- }
624
-
625
- let buttonWidth = 0;
626
- try {
627
- buttonWidth = this[dimensionsSymbol].getVia(`data.button.${ref}`);
628
- } catch (e) {
629
- // If the path does not exist, pathfinder throws an error.
630
- // In this case, we assume the width is 0.
631
- // This can happen for buttons that have never been visible.
632
- }
633
- buttonEntries.push({
634
- element,
635
- width: buttonWidth,
636
- hidden: isElementSelfHidden(element),
637
- });
638
- }
639
-
640
- const switchWidth = this[dimensionsSymbol].getVia("data.switchWidth") || 2;
641
-
642
- const layoutButtons = (availableSpace) => {
643
- if (availableSpace < 0) {
644
- availableSpace = 0;
645
- }
646
- let sum = 0;
647
- const visibleButtonsInMainSlot = [];
648
- const buttonsToMoveToPopper = [];
649
-
650
- for (const entry of buttonEntries) {
651
- if (entry.hidden) {
652
- visibleButtonsInMainSlot.push(entry.element);
653
- continue;
654
- }
655
-
656
- if (sum + entry.width > availableSpace) {
657
- buttonsToMoveToPopper.push(entry.element);
658
- } else {
659
- sum += entry.width;
660
- visibleButtonsInMainSlot.push(entry.element);
661
- }
662
- }
663
-
664
- return { visibleButtonsInMainSlot, buttonsToMoveToPopper };
665
- };
666
-
667
- let layout = layoutButtons(space);
668
- if (layout.buttonsToMoveToPopper.length > 0) {
669
- layout = layoutButtons(space - switchWidth);
670
- }
671
-
672
- const shouldShowSwitch =
673
- layout.buttonsToMoveToPopper.length > 0 && hasButtons;
674
-
675
- suppressLayoutFeedback.call(this);
676
-
677
- for (const button of layout.buttonsToMoveToPopper) {
678
- if (button.getAttribute("slot") !== "popper") {
679
- button.setAttribute("slot", "popper");
680
- }
681
- }
682
-
683
- for (const button of layout.visibleButtonsInMainSlot) {
684
- if (button.hasAttribute("slot")) {
685
- button.removeAttribute("slot");
686
- }
687
- }
688
-
689
- setSwitchVisible.call(this, shouldShowSwitch);
690
- if (!shouldShowSwitch) {
691
- hide.call(this);
692
- }
693
- }
694
-
695
- /**
696
- * @private
697
- * @param {HTMLElement} node
698
- * @return {number}
699
- */
700
- function calcBoxWidth(node) {
701
- const dim = getGlobal()?.getComputedStyle(node);
702
- if (dim === null) {
703
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "no computed style");
704
- throw new Error("no computed style");
705
- }
706
- const bounding = node.getBoundingClientRect();
707
-
708
- return (
709
- convertToPixels(dim["border-left-width"]) +
710
- convertToPixels(dim["padding-left"]) +
711
- convertToPixels(dim["margin-left"]) +
712
- bounding["width"] +
713
- convertToPixels(dim["border-right-width"]) +
714
- convertToPixels(dim["margin-right"]) +
715
- convertToPixels(dim["padding-left"])
716
- );
717
- }
718
-
719
- /**
720
- * @private
721
- * @return {Object}
722
- */
723
- function calculateButtonBarDimensions() {
724
- if (!(this.parentElement instanceof HTMLElement)) {
725
- this[dimensionsSymbol].setVia("data.space", 0);
726
- this[dimensionsSymbol].setVia("data.visible", false);
727
- this[dimensionsSymbol].setVia("data.calculated", true);
728
- this[dimensionsSymbol].setVia("data.buttonReferences", []);
729
- return;
730
- }
731
-
732
- const computedStyle = getComputedStyle(this.parentElement);
733
-
734
- if (computedStyle === null) {
735
- throw new Error("no computed style");
736
- }
737
-
738
- let width = this.parentElement.clientWidth;
739
- if (computedStyle.getPropertyValue("box-sizing") !== "border-box") {
740
- width = computedStyle.getPropertyValue("width");
741
-
742
- let pixel = 0;
743
- try {
744
- pixel = convertToPixels(width);
745
- } catch (e) {
746
- addErrorAttribute(
747
- this,
748
- e?.message || "An error occurred while calculating the dimensions",
749
- );
750
- }
751
-
752
- this[dimensionsSymbol].setVia("data.space", pixel);
753
- } else {
754
- let borderWidth = getComputedStyle(this).getPropertyValue(
755
- "--monster-border-width",
756
- );
757
- if (borderWidth === null || borderWidth === "") {
758
- borderWidth = "0px";
759
- }
760
-
761
- let borderWidthWithoutUnit = 0;
762
- try {
763
- borderWidthWithoutUnit = convertToPixels(borderWidth);
764
- } catch (e) {
765
- addErrorAttribute(
766
- this,
767
- e?.message || "An error occurred while calculating the dimensions",
768
- );
769
- }
770
-
771
- // space to be allocated
772
- this[dimensionsSymbol].setVia(
773
- "data.space",
774
- width - 2 * borderWidthWithoutUnit,
775
- );
776
- }
777
-
778
- this[dimensionsSymbol].setVia("data.visible", !(width === 0));
779
-
780
- const buttonReferences = [];
781
-
782
- // Get all buttons, regardless of their current slot
783
- const allButtons = Array.from(getSlottedElements.call(this, ":scope", null));
784
- const popperButtons = Array.from(
785
- getSlottedElements.call(this, ":scope", "popper"),
786
- );
787
-
788
- const combinedButtons = [...allButtons, ...popperButtons].filter(
789
- (button, index, self) => {
790
- // Filter out duplicates based on data-monster-reference if present, or element itself
791
- return (
792
- self.findIndex(
793
- (b) =>
794
- b.dataset.monsterReference === button.dataset.monsterReference ||
795
- b === button,
796
- ) === index
797
- );
798
- },
799
- );
800
-
801
- for (const button of combinedButtons) {
802
- if (!(button instanceof HTMLElement)) {
803
- continue;
804
- }
805
-
806
- if (!button.hasAttribute("data-monster-reference")) {
807
- button.setAttribute("data-monster-reference", new ID("btn").toString());
808
- }
809
-
810
- const ref = button.getAttribute("data-monster-reference");
811
- if (ref === null) continue;
812
-
813
- buttonReferences.push(ref);
814
-
815
- // Only calculate width for visible buttons. Assume invisible ones
816
- // (e.g. in popper) have their width calculated previously and stored.
817
- if (isElementTrulyVisible(button)) {
818
- this[dimensionsSymbol].setVia(
819
- `data.button.${ref}`,
820
- calcBoxWidth.call(this, button),
821
- );
822
- }
823
- }
824
-
825
- if (this[switchElementSymbol]) {
826
- this[dimensionsSymbol].setVia(
827
- "data.switchWidth",
828
- this[switchElementSymbol].offsetWidth,
829
- );
830
- }
831
-
832
- this[dimensionsSymbol].setVia("data.calculated", true);
833
- this[dimensionsSymbol].setVia("data.buttonReferences", buttonReferences);
834
- }
835
-
836
- /**
837
- * @private
838
- */
839
- function updateResizeObserverObservation() {
840
- const observedNodes = getLayoutObservedNodes.call(this);
841
- const signature = getLayoutObservedNodesSignature(observedNodes);
842
- if (this[observedLayoutNodesSignatureSymbol] === signature) {
843
- return;
844
- }
845
- this[observedLayoutNodesSignatureSymbol] = signature;
846
-
847
- this[resizeObserverSymbol].disconnect();
848
- if (this[mutationObserverSymbol]) {
849
- this[mutationObserverSymbol].disconnect();
850
- }
851
-
852
- observedNodes.forEach((node) => {
853
- this[resizeObserverSymbol].observe(node);
854
- if (node !== this.parentElement && this[mutationObserverSymbol]) {
855
- this[mutationObserverSymbol].observe(node, {
856
- attributes: true,
857
- attributeFilter: ["style", "class", "hidden"],
858
- });
859
- }
860
- });
861
- }
862
-
863
- /**
864
- * @private
865
- * @return {HTMLElement[]}
866
- */
867
- function getLayoutObservedNodes() {
868
- const observedNodes = [];
869
- const slottedNodes = getSlottedElements.call(this);
870
- slottedNodes.forEach((node) => {
871
- if (node instanceof HTMLElement) {
872
- observedNodes.push(node);
873
- }
874
- });
875
-
876
- let parent = this.parentNode;
877
- while (!(parent instanceof HTMLElement) && parent !== null) {
878
- parent = parent.parentNode;
879
- }
880
-
881
- if (parent instanceof HTMLElement) {
882
- observedNodes.push(parent);
883
- }
884
-
885
- return observedNodes;
886
- }
887
-
888
- /**
889
- * @private
890
- * @param {HTMLElement[]} nodes
891
- * @return {string}
892
- */
893
- function getLayoutObservedNodesSignature(nodes) {
894
- return nodes.map(getLayoutNodeId).join("|");
895
- }
896
-
897
- /**
898
- * @private
899
- * @param {HTMLElement} node
900
- * @return {number}
901
- */
902
- function getLayoutNodeId(node) {
903
- let id = layoutNodeIds.get(node);
904
- if (id === undefined) {
905
- id = ++layoutNodeId;
906
- layoutNodeIds.set(node, id);
907
- }
908
- return id;
909
- }
910
-
911
- /**
912
- * @private
913
- * @return {void}
914
- */
915
- function suppressLayoutFeedback() {
916
- const state = this[layoutStateSymbol];
917
- if (!state) {
918
- return;
919
- }
920
-
921
- state.suppressSlotChange = true;
922
- state.suppressMutation = true;
923
- queueMicrotask(() => {
924
- state.suppressSlotChange = false;
925
- state.suppressMutation = false;
926
- });
927
- }
928
-
929
- /**
930
- * @private
931
- * @param {boolean} visible
932
- * @return {void}
933
- */
934
- function setSwitchVisible(visible) {
935
- if (!(this[switchElementSymbol] instanceof HTMLElement)) {
936
- return;
937
- }
938
-
939
- if (visible) {
940
- if (this[switchElementSymbol].hasAttribute("hidden")) {
941
- this[switchElementSymbol].removeAttribute("hidden");
942
- }
943
- if (this[switchElementSymbol].classList.contains("hidden")) {
944
- this[switchElementSymbol].classList.remove("hidden");
945
- }
946
- return;
947
- }
948
-
949
- if (!this[switchElementSymbol].hasAttribute("hidden")) {
950
- this[switchElementSymbol].setAttribute("hidden", "");
951
- }
952
- if (!this[switchElementSymbol].classList.contains("hidden")) {
953
- this[switchElementSymbol].classList.add("hidden");
954
- }
955
- }
956
-
957
- /**
958
- * @private
959
- */
960
- function disconnectResizeObserver() {
961
- if (this[resizeObserverSymbol] instanceof ResizeObserver) {
962
- this[resizeObserverSymbol].disconnect();
963
- }
964
- this[observedLayoutNodesSignatureSymbol] = null;
965
- }
966
-
967
- /**
968
- * @private
969
- */
970
- function toggle() {
971
- if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
972
- hide.call(this);
973
- } else {
974
- show.call(this);
975
- }
976
- }
977
-
978
- /**
979
- * @private
980
- */
981
- function hide() {
982
- this[popperElementSymbol].style.display = "none";
983
- removeAttributeToken(this[controlElementSymbol], "class", "open");
984
- }
985
-
986
- /**
987
- * @private
988
- * @this PopperButton
989
- */
990
- function show() {
991
- if (this.getOption("disabled", false) === true) {
992
- return;
993
- }
994
-
995
- if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
996
- return;
997
- }
998
-
999
- this[popperElementSymbol].style.visibility = "hidden";
1000
- this[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
1001
-
1002
- addAttributeToken(this[controlElementSymbol], "class", "open");
1003
-
1004
- updatePopper.call(this);
1005
- }
1006
-
1007
- /**
1008
- * @private
1009
- */
1010
- function updatePopper() {
1011
- if (this[popperElementSymbol].style.display !== STYLE_DISPLAY_MODE_BLOCK) {
1012
- return;
1013
- }
1014
-
1015
- if (this.getOption("disabled", false) === true) {
1016
- return;
1017
- }
1018
-
1019
- positionPopper.call(
1020
- this,
1021
- this[switchElementSymbol],
1022
- this[popperElementSymbol],
1023
- this.getOption("popper", {}),
1024
- );
1025
- }
1026
-
1027
- /**
1028
- * @private
1029
- */
1030
- function applyLayoutAlignment() {
1031
- if (!(this[buttonBarElementSymbol] instanceof HTMLElement)) {
1032
- return;
1033
- }
1034
-
1035
- const alignment = this.getOption("layout.alignment", "left");
1036
-
1037
- if (alignment === "right") {
1038
- this[buttonBarElementSymbol].setAttribute(
1039
- ATTRIBUTE_LAYOUT_ALIGNMENT,
1040
- "right",
1041
- );
1042
- return;
1043
- }
1044
-
1045
- this[buttonBarElementSymbol].setAttribute(ATTRIBUTE_LAYOUT_ALIGNMENT, "left");
1046
- }
1047
-
1048
- /**
1049
- * @private
1050
- * @return {Select}
1051
- * @throws {Error} no shadow-root is defined
1052
- */
1053
- function initControlReferences() {
1054
- if (!this.shadowRoot) {
1055
- throw new Error("no shadow-root is defined");
1056
- }
1057
-
1058
- this[controlElementSymbol] = this.shadowRoot.querySelector(
1059
- `[${ATTRIBUTE_ROLE}=control]`,
1060
- );
1061
- this[buttonBarElementSymbol] = this.shadowRoot.querySelector(
1062
- `[${ATTRIBUTE_ROLE}=button-bar]`,
1063
- );
1064
- this[popperElementSymbol] = this.shadowRoot.querySelector(
1065
- `[${ATTRIBUTE_ROLE}=popper]`,
1066
- );
1067
- this[popperNavElementSymbol] = this.shadowRoot.querySelector(
1068
- `[${ATTRIBUTE_ROLE}=popper-nav]`,
1069
- );
1070
- this[switchElementSymbol] = this.shadowRoot.querySelector(
1071
- `[${ATTRIBUTE_ROLE}=switch]`,
1072
- );
1073
-
1074
- this[buttonBarSlotElementSymbol] = null;
1075
- if (this[buttonBarElementSymbol])
1076
- this[buttonBarSlotElementSymbol] =
1077
- this[buttonBarElementSymbol].querySelector(`slot`);
1078
- this[popperSlotElementSymbol] = null;
1079
- if (this[popperElementSymbol])
1080
- this[popperSlotElementSymbol] =
1081
- this[popperElementSymbol].querySelector(`slot`);
1082
- }
1083
-
1084
- /**
1085
- * @private
1086
- * @return {Promise<unknown>}
1087
- * @throws {Error} no shadow-root is defined
1088
- *
1089
- */
1090
- function initButtonBar() {
1091
- if (!this.shadowRoot) {
1092
- throw new Error("no shadow-root is defined");
1093
- }
1094
-
1095
- scheduleLayout.call(this, { measure: true, layout: true, observe: true });
1096
- }
1097
-
1098
- /**
1099
- * @private
1100
- */
1101
- function initPopperSwitch() {
1102
- /**
1103
- * @param {Event} event
1104
- */
1105
- this[popperSwitchEventHandler] = (event) => {
1106
- const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "switch");
1107
-
1108
- if (element instanceof HTMLButtonElement) {
1109
- toggle.call(this);
1110
- }
1111
- };
1112
-
1113
- for (const type of ["click", "touch"]) {
1114
- this[switchElementSymbol].addEventListener(
1115
- type,
1116
- this[popperSwitchEventHandler],
1117
- );
1118
- }
1119
72
  }
1120
73
 
1121
74
  /**