@schukai/monster 3.112.3 → 3.113.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
 
4
4
 
5
+ ## [3.113.0] - 2025-03-20
6
+
7
+ ### Add Features
8
+
9
+ - new resizeobserver for slider [#301](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/301)
10
+ - [#301](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/301) Dateien für issue angelegt
11
+ - [#301](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/301) breakpoints monster-slider
12
+ ### Changes
13
+
14
+ - update project
15
+
16
+
17
+
18
+ ## [3.112.4] - 2025-03-12
19
+
20
+ ### Bug Fixes
21
+
22
+ - optimize the day control [#298](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/298)
23
+
24
+
25
+
5
26
  ## [3.112.3] - 2025-03-11
6
27
 
7
28
  ### Bug Fixes
package/package.json CHANGED
@@ -1 +1 @@
1
- {"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.6.13","@popperjs/core":"^2.11.8","buffer":"^6.0.3"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"3.112.3"}
1
+ {"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.6.13","@popperjs/core":"^2.11.8","buffer":"^6.0.3"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"3.113.0"}
@@ -140,7 +140,7 @@ class Popper extends CustomElement {
140
140
  /**
141
141
  * This method is called by the `connectedCallback` method on the first call.
142
142
  *
143
- * @return {Void}
143
+ * @return {void}
144
144
  */
145
145
  [assembleMethodSymbol]() {
146
146
  super[assembleMethodSymbol]();
@@ -73,6 +73,8 @@ const configSymbol = Symbol("config");
73
73
  * @since 3.74.0
74
74
  * @copyright schukai GmbH
75
75
  * @summary A beautiful Slider that can make your life easier and also looks good.
76
+ * @fires monster-slider-resized
77
+ * @fires monster-slider-moved
76
78
  */
77
79
  class Slider extends CustomElement {
78
80
  /**
@@ -97,12 +99,21 @@ class Slider extends CustomElement {
97
99
  draggingPos: 0,
98
100
  startPos: 0,
99
101
  autoPlayInterval: null,
102
+
103
+ eventHandler: {
104
+ mouseOverPause: null,
105
+ mouseout: null,
106
+ touchstart : null,
107
+ touchend: null
108
+ }
109
+
100
110
  };
101
111
 
102
112
  // set --monster-slides-width
103
113
  const slides = this.shadowRoot.querySelector(
104
114
  `[${ATTRIBUTE_ROLE}="slider"]`,
105
115
  );
116
+
106
117
  const slidesVisible = getVisibleSlidesFromContainerWidth.call(this);
107
118
  slides.style.setProperty(
108
119
  "--monster-slides-width",
@@ -283,6 +294,11 @@ function initThumbnails() {
283
294
  "[data-monster-role='thumbnails']",
284
295
  );
285
296
 
297
+ // remove all thumbnails
298
+ while (thumbnails.firstChild) {
299
+ thumbnails.removeChild(thumbnails.firstChild);
300
+ }
301
+
286
302
  const { originSlides } = getSlidesAndTotal.call(this);
287
303
 
288
304
  originSlides.forEach((x, index) => {
@@ -354,26 +370,49 @@ function initAutoPlay() {
354
370
  }, startDelay);
355
371
 
356
372
  if (autoPlay.mouseOverPause) {
357
- this.addEventListener("mouseover", () => {
358
- clearInterval(this[configSymbol].autoPlayInterval);
359
- });
360
373
 
361
- this.addEventListener("mouseout", () => {
362
- if (this[configSymbol].isDragging) {
363
- return;
374
+ if(this[configSymbol].eventHandler.mouseOverPause===null) {
375
+ this[configSymbol].eventHandler.mouseOverPause = () => {
376
+ clearInterval(this[configSymbol].autoPlayInterval);
364
377
  }
365
- start();
366
- });
378
+
379
+ this.addEventListener("mouseover",this[configSymbol].eventHandler.mouseOverPause);
380
+ }
381
+
382
+ if(this[configSymbol].eventHandler.mouseout===null) {
383
+
384
+ this[configSymbol].eventHandler.mouseout = () => {
385
+ if (this[configSymbol].isDragging) {
386
+ return;
387
+ }
388
+ start();
389
+ }
390
+
391
+ this.addEventListener("mouseout", this[configSymbol].eventHandler.mouseout);
392
+ }
393
+
367
394
  }
368
395
 
369
396
  if (autoPlay.touchPause) {
370
- this.addEventListener("touchstart", () => {
371
- clearInterval(this[configSymbol].autoPlayInterval);
372
- });
397
+ if(this[configSymbol].eventHandler.touchstart===null) {
398
+ this[configSymbol].eventHandler.touchstart = () => {
399
+ clearInterval(this[configSymbol].autoPlayInterval);
400
+ }
373
401
 
374
- this.addEventListener("touchend", () => {
375
- start();
376
- });
402
+ this.addEventListener("touchstart",this[configSymbol].eventHandler.touchstart);
403
+ }
404
+
405
+ if(this[configSymbol].eventHandler.touchend===null) {
406
+
407
+ this[configSymbol].eventHandler.touchend = () => {
408
+ if (this[configSymbol].isDragging) {
409
+ return;
410
+ }
411
+ start();
412
+ }
413
+
414
+ this.addEventListener("touchend", this[configSymbol].eventHandler.touchend);
415
+ }
377
416
  }
378
417
  }
379
418
 
@@ -602,6 +641,7 @@ function moveTo(index, animation) {
602
641
  /**
603
642
  * @private
604
643
  * @return {initEventHandler}
644
+ * @fires monster-slider-resized
605
645
  */
606
646
  function initEventHandler() {
607
647
  const self = this;
@@ -632,6 +672,44 @@ function initEventHandler() {
632
672
  );
633
673
  }
634
674
 
675
+
676
+ const initialSize = {
677
+ width: this[sliderElementSymbol]?.offsetWidth || 0,
678
+ height: this[sliderElementSymbol]?.offsetHeight || 0
679
+ };
680
+
681
+ const resizeObserver = new ResizeObserver(entries => {
682
+ for (let entry of entries) {
683
+ const {width, height} = entry.contentRect;
684
+ if (width !== initialSize.width || height !== initialSize.height) {
685
+
686
+ self.stopAutoPlay();
687
+
688
+ if (this.getOption("features.thumbnails")) {
689
+ initThumbnails.call(this);
690
+ }
691
+
692
+ const slidesVisible = getVisibleSlidesFromContainerWidth.call(this);
693
+ this[sliderElementSymbol].style.setProperty(
694
+ "--monster-slides-width",
695
+ `${100 / slidesVisible}%`,
696
+ );
697
+
698
+ moveTo.call(self,0,false)
699
+ self.startAutoPlay();
700
+
701
+ fireCustomEvent(self, "monster-slider-resized", {
702
+ width: width,
703
+ height: height
704
+ });
705
+ }
706
+ }
707
+ });
708
+
709
+ resizeObserver.observe(this[sliderElementSymbol]);
710
+
711
+
712
+
635
713
  return this;
636
714
  }
637
715
 
@@ -729,6 +807,7 @@ function initControlReferences() {
729
807
  this[thumbnailElementSymbol] = this.shadowRoot.querySelector(
730
808
  `[${ATTRIBUTE_ROLE}="thumbnails"]`,
731
809
  );
810
+
732
811
  }
733
812
 
734
813
  /**
@@ -0,0 +1,423 @@
1
+ /**
2
+ * Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
3
+ * Node module: @schukai/monster
4
+ *
5
+ * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
6
+ * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
7
+ *
8
+ * For those who do not wish to adhere to the AGPLv3, a commercial license is available.
9
+ * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
10
+ * For more information about purchasing a commercial license, please contact schukai GmbH.
11
+ */
12
+
13
+ import { instanceSymbol } from "../../constants.mjs";
14
+ import { ATTRIBUTE_ROLE } from "../../dom/constants.mjs";
15
+ import { CustomElement } from "../../dom/customelement.mjs";
16
+ import {
17
+ assembleMethodSymbol,
18
+ registerCustomElement,
19
+ } from "../../dom/customelement.mjs";
20
+ import { DayStyleSheet } from "./stylesheet/day.mjs";
21
+ import { isString } from "../../types/is.mjs";
22
+ import { getLocaleOfDocument } from "../../dom/locale.mjs";
23
+ import { Observer } from "../../types/observer.mjs";
24
+ import { Processing } from "../../util/processing.mjs";
25
+
26
+ export { Day };
27
+
28
+ /**
29
+ * @private
30
+ * @type {symbol}
31
+ */
32
+ const dayElementSymbol = Symbol("dayElement");
33
+
34
+ /**
35
+ * @private
36
+ * @type {symbol}
37
+ */
38
+ const dayMonthElementSymbol = Symbol("dayMonthElement");
39
+ /**
40
+ * @private
41
+ * @type {symbol}
42
+ */
43
+ const dayDayElementSymbol = Symbol("dayDayElement");
44
+ /**
45
+ * @private
46
+ * @type {symbol}
47
+ */
48
+ const dayWeekdayElementSymbol = Symbol("dayWeekdayElement");
49
+ /**
50
+ * @private
51
+ * @type {symbol}
52
+ */
53
+ const dayLabelElementSymbol = Symbol("dayLabelElement");
54
+
55
+ /**
56
+ * A Day Control
57
+ *
58
+ * @fragments /fragments/components/time/day/
59
+ *
60
+ * @example /examples/components/time/day-simple
61
+ * @example /examples/components/time/day-simple-small
62
+ *
63
+ * @since 3.113.0
64
+ * @copyright schukai GmbH
65
+ * @summary A day control that displays the day, month, weekday and a label.
66
+ */
67
+ class Day extends CustomElement {
68
+ /**
69
+ *
70
+ */
71
+ constructor() {
72
+ super();
73
+ initOptionObserver.call(this);
74
+ }
75
+
76
+ /**
77
+ * This method is called by the `instanceof` operator.
78
+ * @returns {symbol}
79
+ */
80
+ static get [instanceSymbol]() {
81
+ return Symbol.for("@schukai/monster/components/time/day@@instance");
82
+ }
83
+
84
+ /**
85
+ *
86
+ * @return {Components.Time.Day
87
+ */
88
+ [assembleMethodSymbol]() {
89
+ super[assembleMethodSymbol]();
90
+ initControlReferences.call(this);
91
+ updateDate.call(this);
92
+ return this;
93
+ }
94
+
95
+ /**
96
+ * To set the options via the HTML Tag, the attribute `data-monster-options` must be used.
97
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
98
+ *
99
+ * The individual configuration values can be found in the table.
100
+ *
101
+ * @property {Object} templates Template definitions
102
+ * @property {string} templates.main Main template
103
+ * @property {string} date The date of the day
104
+ */
105
+ get defaults() {
106
+ return Object.assign({}, super.defaults, {
107
+ templates: {
108
+ main: getTemplate(),
109
+ },
110
+
111
+ date: null,
112
+
113
+ day: null,
114
+ month: null,
115
+ weekday: null,
116
+ label: null,
117
+
118
+ disabled: false,
119
+ });
120
+ }
121
+
122
+ /**
123
+ * @return {string}
124
+ */
125
+ static getTag() {
126
+ return "monster-day";
127
+ }
128
+
129
+ /**
130
+ * @return {CSSStyleSheet[]}
131
+ */
132
+ static getCSSStyleSheet() {
133
+ return [DayStyleSheet];
134
+ }
135
+
136
+ /**
137
+ * @return {string[]}
138
+ * @since 1.15.0
139
+ */
140
+ static get observedAttributes() {
141
+ return ["data-monster-option-date"];
142
+ }
143
+ }
144
+
145
+ /**
146
+ * @private
147
+ */
148
+ function initOptionObserver() {
149
+ const self = this;
150
+
151
+ let lastDate = this.getOption("date");
152
+
153
+ self.attachObserver(
154
+ new Observer(function () {
155
+ new Processing(() => {
156
+ if (lastDate !== self.getOption("date")) {
157
+ lastDate = self.getOption("date");
158
+ updateDate.call(self);
159
+ }
160
+ }).run();
161
+ }),
162
+ );
163
+ }
164
+
165
+ /**
166
+ * @private
167
+ */
168
+ function updateDate() {
169
+ const labels = getLabels.call(this);
170
+
171
+ let date = this.getOption("date");
172
+
173
+ let day = null;
174
+ let label = null;
175
+
176
+ if (date === null) {
177
+ date = new Date();
178
+ } else if (isString(date)) {
179
+ date = new Date(date);
180
+ }
181
+
182
+ if (!(date instanceof Date)) {
183
+ return;
184
+ }
185
+
186
+ day = date.getDate();
187
+
188
+ const locale = getLocaleOfDocument();
189
+
190
+ this.setOption("day", day);
191
+ this.setOption(
192
+ "month",
193
+ new Intl.DateTimeFormat(locale.toString(), {
194
+ month: "short",
195
+ }).format(date),
196
+ );
197
+
198
+ this.setOption(
199
+ "weekday",
200
+ new Intl.DateTimeFormat(locale.toString(), {
201
+ weekday: "long",
202
+ }).format(date),
203
+ );
204
+
205
+ if (date.toDateString() === new Date().toDateString()) {
206
+ label = labels.today;
207
+ } else if (
208
+ date.toDateString() ===
209
+ new Date(new Date().setDate(new Date().getDate() - 1)).toDateString()
210
+ ) {
211
+ label = labels.yesterday;
212
+ } else if (
213
+ date.toDateString() ===
214
+ new Date(new Date().setDate(new Date().getDate() + 1)).toDateString()
215
+ ) {
216
+ label = labels.tomorrow;
217
+ }
218
+
219
+ this.setOption("label", label);
220
+ }
221
+
222
+ function getLabels() {
223
+ switch (getLocaleOfDocument().language) {
224
+ case "de": // German
225
+ return {
226
+ today: "Heute",
227
+ tomorrow: "Morgen",
228
+ yesterday: "Gestern",
229
+ };
230
+
231
+ case "es": // Spanish
232
+ return {
233
+ today: "Hoy",
234
+ tomorrow: "Mañana",
235
+ yesterday: "Ayer",
236
+ };
237
+
238
+ case "zh": // Mandarin
239
+ return {
240
+ today: "今天",
241
+ tomorrow: "明天",
242
+ yesterday: "昨天",
243
+ };
244
+
245
+ case "hi": // Hindi
246
+ return {
247
+ today: "आज",
248
+ tomorrow: "कल",
249
+ yesterday: "बीता कल",
250
+ };
251
+
252
+ case "bn": // Bengali
253
+ return {
254
+ today: "আজ",
255
+ tomorrow: "আগামীকাল",
256
+ yesterday: "গতকাল",
257
+ };
258
+
259
+ case "pt": // Portuguese
260
+ return {
261
+ today: "Hoje",
262
+ tomorrow: "Amanhã",
263
+ yesterday: "Ontem",
264
+ };
265
+
266
+ case "ru": // Russian
267
+ return {
268
+ today: "Сегодня",
269
+ tomorrow: "Завтра",
270
+ yesterday: "Вчера",
271
+ };
272
+
273
+ case "ja": // Japanese
274
+ return {
275
+ today: "今日",
276
+ tomorrow: "明日",
277
+ yesterday: "昨日",
278
+ };
279
+
280
+ case "pa": // Western Punjabi
281
+ return {
282
+ today: "ਅਜ",
283
+ tomorrow: "ਕਲ",
284
+ yesterday: "ਬੀਤੇ ਕਲ",
285
+ };
286
+
287
+ case "mr": // Marathi
288
+ return {
289
+ today: "आज",
290
+ tomorrow: "उद्या",
291
+ yesterday: "काल",
292
+ };
293
+
294
+ case "fr": // French
295
+ return {
296
+ today: "Aujourd'hui",
297
+ tomorrow: "Demain",
298
+ yesterday: "Hier",
299
+ };
300
+
301
+ case "it": // Italian
302
+ return {
303
+ today: "Oggi",
304
+ tomorrow: "Domani",
305
+ yesterday: "Ieri",
306
+ };
307
+
308
+ case "nl": // Dutch
309
+ return {
310
+ today: "Vandaag",
311
+ tomorrow: "Morgen",
312
+ yesterday: "Gisteren",
313
+ };
314
+
315
+ case "sv": // Swedish
316
+ return {
317
+ today: "Idag",
318
+ tomorrow: "Imorgon",
319
+ yesterday: "Igår",
320
+ };
321
+
322
+ case "pl": // Polish
323
+ return {
324
+ today: "Dziś",
325
+ tomorrow: "Jutro",
326
+ yesterday: "Wczoraj",
327
+ };
328
+
329
+ case "da": // Danish
330
+ return {
331
+ today: "I dag",
332
+ tomorrow: "I morgen",
333
+ yesterday: "I går",
334
+ };
335
+
336
+ case "fi": // Finnish
337
+ return {
338
+ today: "Tänään",
339
+ tomorrow: "Huomenna",
340
+ yesterday: "Eilen",
341
+ };
342
+
343
+ case "no": // Norwegian
344
+ return {
345
+ today: "I dag",
346
+ tomorrow: "I morgen",
347
+ yesterday: "I går",
348
+ };
349
+
350
+ case "cs": // Czech
351
+ return {
352
+ today: "Dnes",
353
+ tomorrow: "Zítra",
354
+ yesterday: "Včera",
355
+ };
356
+
357
+ default:
358
+ return {
359
+ today: "Today",
360
+ tomorrow: "Tomorrow",
361
+ yesterday: "Yesterday",
362
+ };
363
+ }
364
+ }
365
+
366
+ /**
367
+ * @private
368
+ * @param format
369
+ * @returns {*[]}
370
+ */
371
+ function getWeekdays(format = "long") {
372
+ const locale = getLocaleOfDocument();
373
+
374
+ const weekdays = [];
375
+ for (let i = 1; i < 8; i++) {
376
+ const date = new Date(1970, 0, 4 + i); // 4. Jan. 1970 = Sonntag
377
+ weekdays.push(
378
+ new Intl.DateTimeFormat(locale, { weekday: format }).format(date),
379
+ );
380
+ }
381
+
382
+ return weekdays;
383
+ }
384
+
385
+ /**
386
+ * @private
387
+ * @return {void}
388
+ */
389
+ function initControlReferences() {
390
+ this[dayElementSymbol] = this.shadowRoot.querySelector(
391
+ `[${ATTRIBUTE_ROLE}="control"]`,
392
+ );
393
+ this[dayMonthElementSymbol] = this.shadowRoot.querySelector(
394
+ `[${ATTRIBUTE_ROLE}="month"]`,
395
+ );
396
+ this[dayDayElementSymbol] = this.shadowRoot.querySelector(
397
+ `[${ATTRIBUTE_ROLE}="day"]`,
398
+ );
399
+ this[dayWeekdayElementSymbol] = this.shadowRoot.querySelector(
400
+ `[${ATTRIBUTE_ROLE}="weekday"]`,
401
+ );
402
+ this[dayLabelElementSymbol] = this.shadowRoot.querySelector(
403
+ `[${ATTRIBUTE_ROLE}="label"]`,
404
+ );
405
+ }
406
+
407
+ /**
408
+ * @private
409
+ * @return {string}
410
+ */
411
+ function getTemplate() {
412
+ // language=HTML
413
+ return `
414
+ <div data-monster-role="control" part="control">
415
+ <div class="month" data-monster-role="month" part="month" data-monster-replace="path:month"></div>
416
+ <div data-monster-role="day" part="day" data-monster-replace="path:day">12</div>
417
+ <div style="width: 100%; height: 0;" part="divider"></div>
418
+ <div data-monster-role="weekday" part="weekday" data-monster-replace="path:weekday">Wed</div>
419
+ <div data-monster-role="label" part="label" data-monster-replace="path:label">Tomorrow</div>
420
+ </div>`;
421
+ }
422
+
423
+ registerCustomElement(Day);