@schukai/monster 3.58.4 → 3.59.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.
@@ -106,7 +106,7 @@ class Overlay extends CustomElement {
106
106
  * @returns {symbol}
107
107
  */
108
108
  static get [instanceSymbol]() {
109
- return Symbol.for("@schukai/component-host/overlay@@instance");
109
+ return Symbol.for("@schukai/monster/components/host/overlay@@instance");
110
110
  }
111
111
 
112
112
  /**
@@ -39,18 +39,10 @@ const viewerElementSymbol = Symbol("viewerElement");
39
39
  * Or you can create this CustomControl directly in Javascript:
40
40
  *
41
41
  * ```js
42
- * import '@schukai/component-state/source/viewer.mjs';
42
+ * import '@schukai/monster/components/host/viewer.mjs';
43
43
  * document.createElement('monster-viewer');
44
44
  * ```
45
45
  *
46
- * The Body should have a class "hidden" to ensure that the styles are applied correctly.
47
- *
48
- * ```css
49
- * body.hidden {
50
- * visibility: hidden;
51
- * }
52
- * ```
53
- *
54
46
  * @startuml viewer.png
55
47
  * skinparam monochrome true
56
48
  * skinparam shadowing false
@@ -62,10 +54,6 @@ const viewerElementSymbol = Symbol("viewerElement");
62
54
  * @copyright schukai GmbH
63
55
  * @memberOf Monster.Components.Host
64
56
  * @summary A simple viewer component
65
- * @fires Monster.Components.Host.Viewer.event:monster-viewer-before-open
66
- * @fires Monster.Components.Host.Viewer.event:monster-viewer-open
67
- * @fires Monster.Components.Host.Viewer.event:monster-viewer-before-close
68
- * @fires Monster.Components.Host.Viewer.event:monster-viewer-closed
69
57
  */
70
58
  class Viewer extends CustomElement {
71
59
  /**
@@ -73,7 +61,7 @@ class Viewer extends CustomElement {
73
61
  * @returns {symbol}
74
62
  */
75
63
  static get [instanceSymbol]() {
76
- return Symbol.for("@schukai/component-host/viewer@@instance");
64
+ return Symbol.for("@schukai/monster/components/host/viewer@@instance");
77
65
  }
78
66
 
79
67
  /**
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright 2023 schukai GmbH
3
+ * SPDX-License-Identifier: AGPL-3.0
4
+ */
5
+
6
+ /**
7
+ * Namespace for all layout related functions.
8
+ *
9
+ * @namespace Monster.Components.Layout
10
+ * @memberOf Monster
11
+ * @author schukai GmbH
12
+ */
13
+ const ns = {};
@@ -0,0 +1,341 @@
1
+ /**
2
+ * Copyright 2023 schukai GmbH
3
+ * SPDX-License-Identifier: AGPL-3.0
4
+ */
5
+
6
+ import {
7
+ assembleMethodSymbol,
8
+ CustomElement,
9
+ registerCustomElement,
10
+ } from "../../dom/customelement.mjs";
11
+ import "../notify/notify.mjs";
12
+ import {Observer} from "../../types/observer.mjs";
13
+ import {SplitScreenStyleSheet} from "./stylesheet/split-screen.mjs";
14
+ import {instanceSymbol} from "../../constants.mjs";
15
+ import {internalSymbol} from "../../constants.mjs";
16
+
17
+ export {SplitScreen, TYPE_VERTICAL, TYPE_HORIZONTAL};
18
+
19
+ /**
20
+ * @private
21
+ * @type {symbol}
22
+ */
23
+ const splitScreenElementSymbol = Symbol("splitScreenElement");
24
+
25
+ /**
26
+ * @private
27
+ * @type {symbol}
28
+ */
29
+ const draggerElementSymbol = Symbol("draggerElement");
30
+ /**
31
+ * @private
32
+ * @type {symbol}
33
+ */
34
+ const startPanelElementSymbol = Symbol("startPanelElement");
35
+ /**
36
+ * @private
37
+ * @type {symbol}
38
+ */
39
+ const endPanelElementSymbol = Symbol("endPanelElement");
40
+ /**
41
+ * @private
42
+ * @type {symbol}
43
+ */
44
+ const handleElementSymbol = Symbol("handleElement");
45
+
46
+ /**
47
+ *
48
+ * @type {string}
49
+ */
50
+ const TYPE_VERTICAL = "vertical";
51
+ /**
52
+ *
53
+ * @type {string}
54
+ */
55
+ const TYPE_HORIZONTAL = "horizontal";
56
+
57
+
58
+ /**
59
+ * The Viewer component is used to show a PDF, HTML or Image.
60
+ *
61
+ * <img src="./images/splitscreen.png">
62
+ *
63
+ * You can create this control either by specifying the HTML tag <monster-splitscreen />` directly in the HTML or using
64
+ * Javascript via the `document.createElement('monster-split-screen');` method.
65
+ *
66
+ * ```html
67
+ * <monster-split-screen></monster-split-screen>
68
+ * ```
69
+ *
70
+ * Or you can create this CustomControl directly in Javascript:
71
+ *
72
+ * ```js
73
+ * import '@schukai/monster/components/layout/split-screen.mjs';
74
+ * document.createElement('monster-split-screen');
75
+ * ```
76
+ *
77
+ * @startuml splitscreen.png
78
+ * skinparam monochrome true
79
+ * skinparam shadowing false
80
+ * HTMLElement <|-- CustomElement
81
+ * CustomElement <|-- CustomControl
82
+ * CustomControl <|-- SplitScreen
83
+ * @enduml
84
+ *
85
+ * @copyright schukai GmbH
86
+ * @memberOf Monster.Components.Layout
87
+ * @summary A simple split screen layout
88
+ */
89
+ class SplitScreen extends CustomElement {
90
+
91
+ /**
92
+ * This method is called by the `instanceof` operator.
93
+ * @returns {symbol}
94
+ */
95
+ static get [instanceSymbol]() {
96
+ return Symbol.for("@schukai/monster/components/layout/splitscreen");
97
+ }
98
+
99
+ /**
100
+ * To set the options via the html tag the attribute `data-monster-options` must be used.
101
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
102
+ *
103
+ * The individual configuration values can be found in the table.
104
+ *
105
+ * @property {Object} templates Template definitions
106
+ * @property {string} templates.main Main template
107
+ * @property {Object} classes Css classes
108
+ * @property {Object} features Feature definitions
109
+ */
110
+ get defaults() {
111
+ return Object.assign({}, super.defaults, {
112
+ templates: {
113
+ main: getTemplate(),
114
+ },
115
+ splitType: TYPE_VERTICAL,
116
+ dimension: "20%",
117
+ classes: {},
118
+ features: {},
119
+ });
120
+ }
121
+
122
+ setContent(html) {
123
+ this.setOption("content", html);
124
+ return this;
125
+ }
126
+
127
+ /**
128
+ *
129
+ * @returns {Monster.Components.Host.Viewer}
130
+ */
131
+ [assembleMethodSymbol]() {
132
+ super[assembleMethodSymbol]();
133
+
134
+ initControlReferences.call(this);
135
+ initEventHandler.call(this);
136
+ applyPanelDimensions.call(this);
137
+ }
138
+
139
+ setDimension(dimension) {
140
+ // check if percent and greater than100
141
+ if (dimension.includes("%")) {
142
+ if (parseInt(dimension) > 100) {
143
+ throw new Error("dimension must be less than 100%");
144
+ } else if (parseInt(dimension) < 0) {
145
+ throw new Error("dimension must be greater than 0%");
146
+ }
147
+ }
148
+
149
+ this.setOption("dimension", dimension);
150
+ return this;
151
+ }
152
+
153
+
154
+ /**
155
+ *
156
+ * @return {string}
157
+ */
158
+ static getTag() {
159
+ return "monster-split-screen";
160
+ }
161
+
162
+ /**
163
+ * @return {CSSStyleSheet[]}
164
+ */
165
+ static getCSSStyleSheet() {
166
+ return [SplitScreenStyleSheet];
167
+ }
168
+ }
169
+
170
+
171
+ /**
172
+ * Set the dimensions of the panel based on the split type.
173
+ */
174
+ function applyPanelDimensions() {
175
+
176
+ const splitType = this.getOption("splitType");
177
+ const dimension = this.getOption("dimension");
178
+
179
+ if (splitType === TYPE_VERTICAL) {
180
+ this[startPanelElementSymbol].style.width = dimension;
181
+ this[endPanelElementSymbol].style.width = `calc(100% - ${dimension} - 5px)`;
182
+ this[draggerElementSymbol].style.cursor = "ew-resize";
183
+ this[splitScreenElementSymbol].classList.add("vertical");
184
+ this[splitScreenElementSymbol].classList.remove("horizontal");
185
+
186
+ } else {
187
+ this[startPanelElementSymbol].style.height = dimension;
188
+ this[endPanelElementSymbol].style.height = `calc(100% - ${dimension} - 5px)`;
189
+ this[draggerElementSymbol].style.cursor = "ns-resize";
190
+ this[splitScreenElementSymbol].classList.add("horizontal");
191
+ this[splitScreenElementSymbol].classList.remove("vertical");
192
+
193
+ }
194
+ }
195
+
196
+
197
+ /**
198
+ * @private
199
+ * @return {Select}
200
+ * @throws {Error} no shadow-root is defined
201
+ */
202
+ function initControlReferences() {
203
+ if (!this.shadowRoot) {
204
+ throw new Error("no shadow-root is defined");
205
+ }
206
+
207
+ this[splitScreenElementSymbol] = this.shadowRoot.querySelector("[data-monster-role=split-screen]");
208
+ this[draggerElementSymbol] = this.shadowRoot.querySelector("[data-monster-role=dragger]");
209
+ this[handleElementSymbol] = this.shadowRoot.querySelector("[data-monster-role=handle]");
210
+
211
+ this[startPanelElementSymbol] = this.shadowRoot.querySelector("[data-monster-role=startPanel]");
212
+ this[endPanelElementSymbol] = this.shadowRoot.querySelector("[data-monster-role=endPanel]");
213
+
214
+ }
215
+
216
+ /**
217
+ * @private
218
+ */
219
+ function initEventHandler() {
220
+ const self = this;
221
+
222
+ this[internalSymbol].getSubject().isDragging = false;
223
+
224
+ this[draggerElementSymbol].addEventListener('dblclick', () => {
225
+ self[internalSymbol].getSubject().isDragging = false;
226
+ applyPanelDimensions.call(this);
227
+ });
228
+
229
+ const resizeObserver = new ResizeObserver((entries) => {
230
+ for (let entry of entries) {
231
+ console.log(entry.contentRect.width);
232
+ }
233
+ });
234
+
235
+ resizeObserver.observe(this[splitScreenElementSymbol]);
236
+
237
+
238
+ this[draggerElementSymbol].addEventListener('mousedown', () => {
239
+ self[internalSymbol].getSubject().isDragging = true;
240
+
241
+ document.addEventListener('mousemove', (e) => {
242
+ e.preventDefault();
243
+ if (!self[internalSymbol].getSubject().isDragging) {
244
+ return;
245
+ }
246
+
247
+ if (self.getOption("splitType") === TYPE_HORIZONTAL) {
248
+ const containerOffsetTop = self[splitScreenElementSymbol].offsetTop;
249
+ const topPanel = self[startPanelElementSymbol];
250
+ const bottomPanel = self[endPanelElementSymbol];
251
+ const newTopHeight = e.clientY - containerOffsetTop;
252
+ topPanel.style.height = `${newTopHeight}px`;
253
+ bottomPanel.style.height = `calc(100% - ${newTopHeight}px - 5px)`; // 5px is dragger height
254
+
255
+
256
+ } else {
257
+
258
+ const containerOffsetLeft = self[splitScreenElementSymbol].offsetLeft;
259
+ const leftPanel = self[startPanelElementSymbol];
260
+ const rightPanel = self[endPanelElementSymbol];
261
+ const newLeftWidth = e.clientX - containerOffsetLeft;
262
+ leftPanel.style.width = `${newLeftWidth}px`;
263
+ rightPanel.style.width = `calc(100% - ${newLeftWidth}px - 5px)`; // 5px is dragger width
264
+ }
265
+
266
+ });
267
+
268
+ document.addEventListener('mouseup', (e) => {
269
+ self[internalSymbol].getSubject().isDragging = false;
270
+ document.removeEventListener('mousemove', (e) => {
271
+ if (!self[internalSymbol].getSubject().isDragging) {
272
+ return;
273
+ }
274
+
275
+ if (self.getOption("splitType") === TYPE_VERTICAL) {
276
+ const containerOffsetTop = self[splitScreenElementSymbol].offsetTop;
277
+ const topPanel = self[startPanelElementSymbol];
278
+ const bottomPanel = self[endPanelElementSymbol];
279
+ const newTopHeight = e.clientY - containerOffsetTop;
280
+ topPanel.style.height = `${newTopHeight}px`;
281
+ bottomPanel.style.height = `calc(100% - ${newTopHeight}px - 5px)`; // 5px is dragger height
282
+
283
+ } else {
284
+ const containerOffsetLeft = self[splitScreenElementSymbol].offsetLeft;
285
+ const newLeftWidth = e.clientX - containerOffsetLeft;
286
+ const leftPanel = self[startPanelElementSymbol];
287
+ const rightPanel = self[endPanelElementSymbol];
288
+ leftPanel.style.width = `${newLeftWidth}px`;
289
+ rightPanel.style.width = `calc(100% - ${newLeftWidth}px - 5px)`; // 5px is dragger width
290
+ }
291
+ });
292
+ document.removeEventListener('mouseup', (e) => {
293
+ self[internalSymbol].getSubject().isDragging = false;
294
+ });
295
+ });
296
+ });
297
+
298
+ let lastDimension = this.getOption("dimension");
299
+ let lastType = this.getOption("splitType");
300
+ this[internalSymbol].attachObserver(
301
+ new Observer(() => {
302
+ if (lastDimension !== this.getOption("dimension")) {
303
+ lastDimension = this.getOption("dimension");
304
+ applyPanelDimensions.call(this);
305
+ }
306
+
307
+ if (lastType !== this.getOption("splitType")) {
308
+ lastType = this.getOption("splitType");
309
+ applyPanelDimensions.call(this);
310
+ }
311
+
312
+ }));
313
+
314
+
315
+ return this;
316
+
317
+ }
318
+
319
+ /**
320
+ * @private
321
+ * @return {string}
322
+ */
323
+ function getTemplate() {
324
+ // language=HTML
325
+ return `
326
+ <div data-monster-role="split-screen" part="container">
327
+ <div data-monster-role="startPanel" class="panel" part="startPanel">
328
+ <slot name="start"></slot>
329
+ </div>
330
+ <div data-monster-role="dragger" part="dragger">
331
+ <div data-monster-role="handle"></div>
332
+ </div>
333
+ <div data-monster-role="endPanel" class="panel" part="endPanel">
334
+ <slot name="end"></slot>
335
+ </div>
336
+
337
+
338
+ </div>`;
339
+ }
340
+
341
+ registerCustomElement(SplitScreen);
@@ -0,0 +1,59 @@
1
+
2
+
3
+ [data-monster-role="split-screen"] {
4
+
5
+ box-sizing: border-box;
6
+ display: flex;
7
+ width: 100%;
8
+ height: auto;
9
+ flex-direction: row;
10
+ margin: 0;
11
+ padding: 0;
12
+
13
+ & .panel {
14
+ flex-grow: 1;
15
+ overflow: auto;
16
+ }
17
+
18
+ [data-monster-role="dragger"] {
19
+ background-color: var(--monster-bg-color-primary-4);
20
+ color: var(--monster-color-primary-4);
21
+ width: var(--monster-border-width);
22
+ height: auto;
23
+
24
+ position: relative;
25
+
26
+ & [data-monster-role=handle] {
27
+ position: absolute;
28
+ top: 50%;
29
+ left: 50%;
30
+ transform: translate(-50%, -50%);
31
+ cursor: pointer;
32
+ width: 5px;
33
+ height: 120px;
34
+ background-color: var(--monster-bg-color-primary-3);
35
+ color: var(--monster-color-primary-3);
36
+ z-index: var(--monster-z-index-outline);
37
+ }
38
+ }
39
+
40
+ &.horizontal {
41
+ flex-direction: column;
42
+
43
+ [data-monster-role="dragger"] {
44
+ width: 100%;
45
+ height: var(--monster-border-width);
46
+
47
+ & [data-monster-role=handle] {
48
+ width: 120px;
49
+ height: 5px;
50
+ }
51
+
52
+ }
53
+
54
+
55
+ }
56
+
57
+ }
58
+
59
+
@@ -27,9 +27,6 @@ nav[data-monster-role=nav] {
27
27
  border-bottom-style: var(--monster-border-style);
28
28
  box-shadow: var(--monster-box-shadow-1);
29
29
  border-color: var(--monster-bg-color-primary-2);
30
-
31
- flex-wrap: nowrap;
32
-
33
30
  }
34
31
 
35
32
  [data-monster-role=nav] button .remove-tab {
@@ -0,0 +1,27 @@
1
+
2
+ /**
3
+ * Copyright schukai GmbH and contributors 2024. All Rights Reserved.
4
+ * Node module: @schukai/monster
5
+ * This file is licensed under the AGPLv3 License.
6
+ * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
7
+ */
8
+
9
+ import {addAttributeToken} from "../../../dom/attributes.mjs";
10
+ import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
11
+
12
+ export {SplitScreenStyleSheet}
13
+
14
+ /**
15
+ * @private
16
+ * @type {CSSStyleSheet}
17
+ */
18
+ const SplitScreenStyleSheet = new CSSStyleSheet();
19
+
20
+ try {
21
+ SplitScreenStyleSheet.insertRule(`
22
+ @layer splitscreen {
23
+ [data-monster-role=split-screen]{box-sizing:border-box;display:flex;flex-direction:row;height:auto;margin:0;padding:0;width:100%}[data-monster-role=split-screen] .panel{flex-grow:1;overflow:auto}[data-monster-role=split-screen] [data-monster-role=dragger]{background-color:var(--monster-bg-color-primary-4);color:var(--monster-color-primary-4);height:auto;position:relative;width:var(--monster-border-width)}[data-monster-role=split-screen] [data-monster-role=dragger] [data-monster-role=handle]{background-color:var(--monster-bg-color-primary-3);color:var(--monster-color-primary-3);cursor:pointer;height:120px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:5px;z-index:var(--monster-z-index-outline)}.horizontal[data-monster-role=split-screen]{flex-direction:column}.horizontal[data-monster-role=split-screen] [data-monster-role=dragger]{height:var(--monster-border-width);width:100%}.horizontal[data-monster-role=split-screen] [data-monster-role=dragger] [data-monster-role=handle]{height:5px;width:120px}
24
+ }`, 0);
25
+ } catch (e) {
26
+ addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + "");
27
+ }