@node-projects/web-component-designer 0.0.61 → 0.0.65
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/.vscode/settings.json +1 -1
- package/ACKNOWLEDGMENTS +7 -0
- package/dist/elements/controls/DesignerTabControl.js +4 -2
- package/dist/elements/controls/PlainScrollbar.d.ts +15 -0
- package/dist/elements/controls/PlainScrollbar.js +482 -0
- package/dist/elements/controls/SimpleSplitView.d.ts +11 -0
- package/dist/elements/controls/SimpleSplitView.js +67 -0
- package/dist/elements/controls/SimpleSplitView2.d.ts +11 -0
- package/dist/elements/controls/SimpleSplitView2.js +63 -0
- package/dist/elements/controls/aa.d.ts +24 -0
- package/dist/elements/controls/aa.js +98 -0
- package/dist/elements/documentContainer.d.ts +6 -1
- package/dist/elements/documentContainer.js +51 -14
- package/dist/elements/helper/PathDataPolyfill.d.ts +5 -1
- package/dist/elements/helper/PathDataPolyfill.js +49 -1
- package/dist/elements/helper/contextMenu/ContextMenuHelper.js +1 -0
- package/dist/elements/services/DefaultServiceBootstrap.js +8 -0
- package/dist/elements/services/htmlParserService/NodeHtmlParserService.js +2 -0
- package/dist/elements/services/undoService/UndoService.js +3 -0
- package/dist/elements/widgets/codeView/code-view-monaco.js +2 -2
- package/dist/elements/widgets/designerView/IDesignerCanvas.d.ts +4 -0
- package/dist/elements/widgets/designerView/designerCanvas.d.ts +8 -1
- package/dist/elements/widgets/designerView/designerCanvas.js +48 -22
- package/dist/elements/widgets/designerView/designerView.d.ts +2 -1
- package/dist/elements/widgets/designerView/designerView.js +68 -18
- package/dist/elements/widgets/designerView/extensions/MouseOverExtension.js +1 -1
- package/dist/elements/widgets/designerView/extensions/PositionExtension.js +4 -4
- package/dist/elements/widgets/designerView/extensions/PrimarySelectionDefaultExtension.js +2 -2
- package/dist/elements/widgets/designerView/extensions/ResizeExtension.d.ts +2 -1
- package/dist/elements/widgets/designerView/extensions/ResizeExtension.js +19 -15
- package/dist/elements/widgets/designerView/extensions/RotateExtension.js +1 -1
- package/dist/elements/widgets/designerView/extensions/SelectionDefaultExtension.js +1 -1
- package/dist/elements/widgets/designerView/extensions/TransformOriginExtension.js +2 -2
- package/dist/elements/widgets/designerView/overlayLayerView.d.ts +1 -0
- package/dist/elements/widgets/designerView/overlayLayerView.js +6 -0
- package/dist/elements/widgets/designerView/tools/DrawEllipsisTool.d.ts +13 -0
- package/dist/elements/widgets/designerView/tools/DrawEllipsisTool.js +72 -0
- package/dist/elements/widgets/designerView/tools/DrawLineTool.d.ts +13 -0
- package/dist/elements/widgets/designerView/tools/DrawLineTool.js +75 -0
- package/dist/elements/widgets/designerView/tools/DrawPathTool.d.ts +0 -2
- package/dist/elements/widgets/designerView/tools/DrawPathTool.js +5 -18
- package/dist/elements/widgets/designerView/tools/DrawRectTool.d.ts +18 -0
- package/dist/elements/widgets/designerView/tools/DrawRectTool.js +86 -0
- package/dist/elements/widgets/designerView/tools/NamedTools.d.ts +3 -0
- package/dist/elements/widgets/designerView/tools/NamedTools.js +3 -0
- package/dist/elements/widgets/designerView/tools/PanTool.js +14 -0
- package/dist/elements/widgets/designerView/tools/PointerTool.js +7 -0
- package/dist/elements/widgets/designerView/tools/RectangleSelectorTool.js +2 -2
- package/dist/elements/widgets/propertyGrid/PropertyGrid.js +1 -0
- package/dist/elements/widgets/propertyGrid/PropertyGridWithHeader.js +1 -0
- package/dist/elements/widgets/treeView/treeView.js +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/package.json +1 -1
package/.vscode/settings.json
CHANGED
package/ACKNOWLEDGMENTS
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Acknowledgments
|
|
2
|
+
|
|
3
|
+
- Thanks to @notwaldorf who created the original `wizzywid` project (MIT License).
|
|
4
|
+
https://github.com/PolymerLabs/wizzywid
|
|
5
|
+
This was a start for this whole project (even if mostly nothing of the original code is left)
|
|
6
|
+
- Thanks to @chdh for plain-scrollbar component
|
|
7
|
+
https://github.com/chdh/plain-scrollbar
|
|
@@ -20,7 +20,8 @@ export class DesignerTabControl extends BaseCustomWebComponentLazyAppend {
|
|
|
20
20
|
}
|
|
21
21
|
.header {
|
|
22
22
|
display: inline-flex;
|
|
23
|
-
user-select: none;
|
|
23
|
+
user-select: none;
|
|
24
|
+
-webkit-user-select: none;
|
|
24
25
|
flex-direction: row;
|
|
25
26
|
cursor: pointer;
|
|
26
27
|
height: 30px;
|
|
@@ -45,7 +46,8 @@ export class DesignerTabControl extends BaseCustomWebComponentLazyAppend {
|
|
|
45
46
|
}
|
|
46
47
|
.more-container {
|
|
47
48
|
z-index: 1;
|
|
48
|
-
user-select: none;
|
|
49
|
+
user-select: none;
|
|
50
|
+
-webkit-user-select: none;
|
|
49
51
|
background-color: var(--dark-grey, #232733);
|
|
50
52
|
right: 0;
|
|
51
53
|
top: 30px;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class PlainScrollbar extends HTMLElement {
|
|
2
|
+
private widget;
|
|
3
|
+
constructor();
|
|
4
|
+
connectedCallback(): void;
|
|
5
|
+
disconnectedCallback(): void;
|
|
6
|
+
get thumbSize(): number;
|
|
7
|
+
set thumbSize(v: number);
|
|
8
|
+
get value(): number;
|
|
9
|
+
set value(v: number);
|
|
10
|
+
get orientation(): string;
|
|
11
|
+
set orientation(s: string);
|
|
12
|
+
get orientationBoolean(): boolean;
|
|
13
|
+
static get observedAttributes(): string[];
|
|
14
|
+
attributeChangedCallback(attrName: string, _oldValue: string | null, newValue: string | null): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
//included from: https://github.com/chdh/plain-scrollbar
|
|
2
|
+
class Widget {
|
|
3
|
+
host;
|
|
4
|
+
root;
|
|
5
|
+
trough;
|
|
6
|
+
button1; // up/left button
|
|
7
|
+
button2; // down/right button
|
|
8
|
+
thumb;
|
|
9
|
+
isConnected = false;
|
|
10
|
+
thumbSize = 0.3; // relative thumb size (0..1)
|
|
11
|
+
value = 0; // current scrollbar position (0..1)
|
|
12
|
+
orientation = false; // false=horizontal, true=vertical
|
|
13
|
+
clickRepeatDelay = 300; // click repetition delay time in ms
|
|
14
|
+
clickRepeatInterval = 100; // click repetition interval time in ms
|
|
15
|
+
defaultThumbMinSize = 25; // default for minimum thumb size in pixels
|
|
16
|
+
dragStartPos; // dragging start pointer position (clientX/Y)
|
|
17
|
+
dragStartValue; // dragging start scrollbar position
|
|
18
|
+
eventTimeoutId;
|
|
19
|
+
pointerCaptureId; // `undefined` = no capture active
|
|
20
|
+
pointerCaptureElement;
|
|
21
|
+
// User interaction state:
|
|
22
|
+
thumbDragging; // true while user is dragging the thumb
|
|
23
|
+
button1Active; // true while user has pointer clicked down on button 1
|
|
24
|
+
button2Active; // true while user has pointer clicked down on button 2
|
|
25
|
+
troughActive; // true while user has pointer clicked down on trough
|
|
26
|
+
constructor(host) {
|
|
27
|
+
this.host = host;
|
|
28
|
+
host.attachShadow({ mode: "open" });
|
|
29
|
+
const shadowRoot = host.shadowRoot;
|
|
30
|
+
shadowRoot.innerHTML = scrollbarHtmlTemplate;
|
|
31
|
+
this.root = shadowRoot.querySelector("#root");
|
|
32
|
+
this.trough = shadowRoot.querySelector("#trough");
|
|
33
|
+
this.button1 = shadowRoot.querySelector("#button1");
|
|
34
|
+
this.button2 = shadowRoot.querySelector("#button2");
|
|
35
|
+
this.thumb = shadowRoot.querySelector("#thumb");
|
|
36
|
+
this.trough.addEventListener("pointerdown", this.onTroughPointerDown);
|
|
37
|
+
this.trough.addEventListener("pointerup", this.onPointerUp);
|
|
38
|
+
this.trough.addEventListener("pointercancel", this.onPointerUp);
|
|
39
|
+
this.button1.addEventListener("pointerdown", (event) => this.onButtonPointerDown(event, 1));
|
|
40
|
+
this.button1.addEventListener("pointerup", this.onPointerUp);
|
|
41
|
+
this.button1.addEventListener("pointercancel", this.onPointerUp);
|
|
42
|
+
this.button1.addEventListener("contextmenu", (e) => e.preventDefault()); // to prevent popup on long touch
|
|
43
|
+
this.button2.addEventListener("pointerdown", (event) => this.onButtonPointerDown(event, 2));
|
|
44
|
+
this.button2.addEventListener("pointerup", this.onPointerUp);
|
|
45
|
+
this.button2.addEventListener("pointercancel", this.onPointerUp);
|
|
46
|
+
this.button2.addEventListener("contextmenu", (e) => e.preventDefault()); // to prevent popup on long touch
|
|
47
|
+
this.thumb.addEventListener("pointerdown", this.onThumbPointerDown);
|
|
48
|
+
this.thumb.addEventListener("pointerup", this.onPointerUp);
|
|
49
|
+
this.thumb.addEventListener("pointercancel", this.onPointerUp);
|
|
50
|
+
this.thumb.addEventListener("pointermove", this.onThumbPointerMove);
|
|
51
|
+
this.resetInteractionState();
|
|
52
|
+
}
|
|
53
|
+
resetInteractionState() {
|
|
54
|
+
this.thumbDragging = false;
|
|
55
|
+
this.button1Active = false;
|
|
56
|
+
this.button2Active = false;
|
|
57
|
+
this.troughActive = false;
|
|
58
|
+
}
|
|
59
|
+
connectedCallback() {
|
|
60
|
+
this.isConnected = true;
|
|
61
|
+
this.resetInteractionState();
|
|
62
|
+
this.updateLayout();
|
|
63
|
+
this.updateStyle();
|
|
64
|
+
}
|
|
65
|
+
disconnectedCallback() {
|
|
66
|
+
this.isConnected = false;
|
|
67
|
+
this.resetInteractionState();
|
|
68
|
+
this.stopEventRepetition();
|
|
69
|
+
this.stopPointerCapture();
|
|
70
|
+
}
|
|
71
|
+
updateLayout() {
|
|
72
|
+
if (!this.isConnected) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
this.root.classList.toggle("horizontal", !this.orientation);
|
|
76
|
+
this.root.classList.toggle("vertical", this.orientation);
|
|
77
|
+
this.thumb.style.display = (this.thumbSize == 0) ? "none" : "";
|
|
78
|
+
this.thumb.style.height = this.orientation ? percent(this.getEffectiveThumbSize()) : "";
|
|
79
|
+
this.thumb.style.width = this.orientation ? "" : percent(this.getEffectiveThumbSize());
|
|
80
|
+
this.thumb.style.top = "";
|
|
81
|
+
this.thumb.style.left = "";
|
|
82
|
+
this.updateThumbPosition();
|
|
83
|
+
}
|
|
84
|
+
updateStyle() {
|
|
85
|
+
if (!this.isConnected) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
this.thumb.classList.toggle("active", this.thumbDragging);
|
|
89
|
+
this.button1.classList.toggle("active", this.button1Active);
|
|
90
|
+
this.button2.classList.toggle("active", this.button2Active);
|
|
91
|
+
void this.troughActive;
|
|
92
|
+
} // tslint:disable-line
|
|
93
|
+
updateThumbPosition() {
|
|
94
|
+
const v = (1 - this.getEffectiveThumbSize()) * this.value;
|
|
95
|
+
if (this.orientation) {
|
|
96
|
+
this.thumb.style.top = percent(v);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
this.thumb.style.left = percent(v);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
getThroughSize() {
|
|
103
|
+
return this.orientation ? this.trough.clientHeight : this.trough.clientWidth;
|
|
104
|
+
}
|
|
105
|
+
computeThumbMoveValue(distancePixels) {
|
|
106
|
+
const troughSlidePixels = this.getThroughSize() * (1 - this.getEffectiveThumbSize());
|
|
107
|
+
if (troughSlidePixels < EPS) {
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
return distancePixels / troughSlidePixels;
|
|
111
|
+
}
|
|
112
|
+
setThumbSize(newThumbSize) {
|
|
113
|
+
const clippedNewThumbSize = Math.max(0, Math.min(1, newThumbSize));
|
|
114
|
+
if (clippedNewThumbSize == this.thumbSize) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
this.thumbSize = clippedNewThumbSize;
|
|
118
|
+
this.updateLayout();
|
|
119
|
+
}
|
|
120
|
+
getThumbMinSize() {
|
|
121
|
+
const s = this.getCssVar("--plain-scrollbar-thumb-min-size");
|
|
122
|
+
if (!s) {
|
|
123
|
+
return this.defaultThumbMinSize;
|
|
124
|
+
}
|
|
125
|
+
const px = decodePxValue(s);
|
|
126
|
+
if (!px) {
|
|
127
|
+
return this.defaultThumbMinSize;
|
|
128
|
+
}
|
|
129
|
+
return px;
|
|
130
|
+
}
|
|
131
|
+
getEffectiveThumbSize() {
|
|
132
|
+
const thumbMinSize = this.getThumbMinSize();
|
|
133
|
+
const throughSize = this.getThroughSize();
|
|
134
|
+
if (!throughSize) {
|
|
135
|
+
return this.thumbSize;
|
|
136
|
+
}
|
|
137
|
+
const min = Math.min(1, thumbMinSize / throughSize);
|
|
138
|
+
return Math.max(min, this.thumbSize);
|
|
139
|
+
}
|
|
140
|
+
setValue(newValue) {
|
|
141
|
+
const clippedNewValue = Math.max(0, Math.min(1, newValue));
|
|
142
|
+
if (clippedNewValue == this.value) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
this.value = clippedNewValue;
|
|
146
|
+
this.updateThumbPosition();
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
setOrientation(newOrientation) {
|
|
150
|
+
if (newOrientation == this.orientation) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
this.orientation = newOrientation;
|
|
154
|
+
this.updateLayout();
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
getCssVar(varName) {
|
|
158
|
+
const s = getComputedStyle(this.root).getPropertyValue(varName);
|
|
159
|
+
if (!s) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
return s.trim();
|
|
163
|
+
}
|
|
164
|
+
//--- Outgoing events -------------------------------------------------------
|
|
165
|
+
fireEvent(eventSubType) {
|
|
166
|
+
const event = new CustomEvent("scrollbar-input", { detail: eventSubType });
|
|
167
|
+
this.host.dispatchEvent(event);
|
|
168
|
+
}
|
|
169
|
+
fireEventRepeatedly(eventSubType, repeatDelay, repeatInterval, repeatCounter = 0) {
|
|
170
|
+
this.stopEventRepetition();
|
|
171
|
+
this.fireEvent(eventSubType);
|
|
172
|
+
const delay = (repeatCounter == 0) ? repeatDelay : repeatInterval;
|
|
173
|
+
const f = () => this.fireEventRepeatedly(eventSubType, repeatDelay, repeatInterval, repeatCounter + 1);
|
|
174
|
+
this.eventTimeoutId = setTimeout(f, delay);
|
|
175
|
+
}
|
|
176
|
+
stopEventRepetition() {
|
|
177
|
+
if (this.eventTimeoutId) {
|
|
178
|
+
clearTimeout(this.eventTimeoutId);
|
|
179
|
+
this.eventTimeoutId = undefined;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//--- Pointer input ----------------------------------------------------------
|
|
183
|
+
startPointerCapture(element, pointerId) {
|
|
184
|
+
this.stopPointerCapture();
|
|
185
|
+
element.setPointerCapture(pointerId);
|
|
186
|
+
this.pointerCaptureElement = element;
|
|
187
|
+
this.pointerCaptureId = pointerId;
|
|
188
|
+
}
|
|
189
|
+
stopPointerCapture() {
|
|
190
|
+
if (!this.pointerCaptureId) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
this.pointerCaptureElement.releasePointerCapture(this.pointerCaptureId);
|
|
194
|
+
this.pointerCaptureId = undefined;
|
|
195
|
+
}
|
|
196
|
+
onTroughPointerDown = (event) => {
|
|
197
|
+
if (!this.isConnected || this.pointerCaptureId) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (!event.isPrimary || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.button != 0) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const r = this.trough.getBoundingClientRect();
|
|
204
|
+
const pos = this.orientation ? event.clientY - r.top : event.clientX - r.left;
|
|
205
|
+
const threshold = (this.orientation ? r.height : r.width) * (1 - this.getEffectiveThumbSize()) * this.value;
|
|
206
|
+
const direction = pos > threshold;
|
|
207
|
+
const eventSubType = direction ? "incrementLarge" : "decrementLarge";
|
|
208
|
+
this.troughActive = true;
|
|
209
|
+
event.preventDefault();
|
|
210
|
+
this.startPointerCapture(this.trough, event.pointerId);
|
|
211
|
+
this.fireEventRepeatedly(eventSubType, this.clickRepeatDelay, this.clickRepeatInterval);
|
|
212
|
+
};
|
|
213
|
+
onButtonPointerDown = (event, buttonNo) => {
|
|
214
|
+
if (!this.isConnected || this.pointerCaptureId) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (!event.isPrimary || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.button != 0) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
switch (buttonNo) {
|
|
221
|
+
case 1:
|
|
222
|
+
this.button1Active = true;
|
|
223
|
+
break;
|
|
224
|
+
case 2:
|
|
225
|
+
this.button2Active = true;
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
const eventSubType = (buttonNo == 1) ? "decrementSmall" : "incrementSmall";
|
|
229
|
+
this.updateStyle();
|
|
230
|
+
event.preventDefault();
|
|
231
|
+
const buttonElement = (buttonNo == 1) ? this.button1 : this.button2;
|
|
232
|
+
this.startPointerCapture(buttonElement, event.pointerId);
|
|
233
|
+
this.fireEventRepeatedly(eventSubType, this.clickRepeatDelay, this.clickRepeatInterval);
|
|
234
|
+
};
|
|
235
|
+
onThumbPointerDown = (event) => {
|
|
236
|
+
if (!this.isConnected || this.pointerCaptureId) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (!event.isPrimary || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.button != 0) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
this.dragStartPos = this.orientation ? event.clientY : event.clientX;
|
|
243
|
+
this.dragStartValue = this.value;
|
|
244
|
+
this.thumbDragging = true;
|
|
245
|
+
this.updateStyle();
|
|
246
|
+
event.preventDefault();
|
|
247
|
+
this.startPointerCapture(this.thumb, event.pointerId);
|
|
248
|
+
};
|
|
249
|
+
onThumbPointerMove = (event) => {
|
|
250
|
+
if (!this.isConnected) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
if (!event.isPrimary || !this.thumbDragging) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const pos = this.orientation ? event.clientY : event.clientX;
|
|
257
|
+
const deltaPixels = pos - this.dragStartPos;
|
|
258
|
+
const deltaValue = this.computeThumbMoveValue(deltaPixels);
|
|
259
|
+
const newValue = this.dragStartValue + deltaValue;
|
|
260
|
+
event.preventDefault();
|
|
261
|
+
if (this.setValue(newValue)) {
|
|
262
|
+
this.fireEvent("value");
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
onPointerUp = (event) => {
|
|
266
|
+
if (!this.isConnected) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
if (!event.isPrimary) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
this.resetInteractionState();
|
|
273
|
+
this.updateStyle();
|
|
274
|
+
this.stopEventRepetition();
|
|
275
|
+
this.stopPointerCapture();
|
|
276
|
+
event.preventDefault();
|
|
277
|
+
};
|
|
278
|
+
} // end class
|
|
279
|
+
//--- Custom Element -----------------------------------------------------------
|
|
280
|
+
export class PlainScrollbar extends HTMLElement {
|
|
281
|
+
widget;
|
|
282
|
+
constructor() {
|
|
283
|
+
super();
|
|
284
|
+
const value = parseFloat(this.getAttribute("value"));
|
|
285
|
+
this.widget = new Widget(this);
|
|
286
|
+
if (!isNaN(value))
|
|
287
|
+
this.widget.value = value;
|
|
288
|
+
}
|
|
289
|
+
/* @Override */ connectedCallback() {
|
|
290
|
+
this.widget.connectedCallback();
|
|
291
|
+
}
|
|
292
|
+
/* @Override */ disconnectedCallback() {
|
|
293
|
+
this.widget.disconnectedCallback();
|
|
294
|
+
}
|
|
295
|
+
//--- Element properties ----------------------------------------------------
|
|
296
|
+
// Size of the thumb, relative to the trough.
|
|
297
|
+
// A value between 0 and 1.
|
|
298
|
+
// 0 is used to hide the thumb. Small values greater than 0 are overridden by `plain-scrollbar-thumb-min-size`.
|
|
299
|
+
get thumbSize() {
|
|
300
|
+
return this.widget.thumbSize;
|
|
301
|
+
}
|
|
302
|
+
set thumbSize(v) {
|
|
303
|
+
this.widget.setThumbSize(v);
|
|
304
|
+
}
|
|
305
|
+
// The current position of the scrollbar.
|
|
306
|
+
// A value between 0 and 1.
|
|
307
|
+
get value() {
|
|
308
|
+
return this.widget.value;
|
|
309
|
+
}
|
|
310
|
+
set value(v) {
|
|
311
|
+
this.widget.setValue(v);
|
|
312
|
+
}
|
|
313
|
+
// Orientation of the scrollbar.
|
|
314
|
+
// "horizontal" or "vertical".
|
|
315
|
+
get orientation() {
|
|
316
|
+
return formatOrientation(this.widget.orientation);
|
|
317
|
+
}
|
|
318
|
+
set orientation(s) {
|
|
319
|
+
if (this.widget.setOrientation(decodeOrientation(s))) {
|
|
320
|
+
this.setAttribute("orientation", this.orientation);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
// Returns false=horizontal, true=vertical.
|
|
324
|
+
get orientationBoolean() {
|
|
325
|
+
return this.widget.orientation;
|
|
326
|
+
}
|
|
327
|
+
//--- Element attributes ----------------------------------------------------
|
|
328
|
+
/* @Override */ static get observedAttributes() {
|
|
329
|
+
return ["orientation"];
|
|
330
|
+
}
|
|
331
|
+
/* @Override */ attributeChangedCallback(attrName, _oldValue, newValue) {
|
|
332
|
+
switch (attrName) {
|
|
333
|
+
case "orientation": {
|
|
334
|
+
if (newValue) {
|
|
335
|
+
this.widget.setOrientation(decodeOrientation(newValue));
|
|
336
|
+
}
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
} // end class
|
|
342
|
+
//------------------------------------------------------------------------------
|
|
343
|
+
const EPS = 1E-9;
|
|
344
|
+
const buttonSize = "var(--plain-scrollbar-button-size, 13px)";
|
|
345
|
+
const buttonPath = '<path d="M -60 30 h 120 L 0 -30 z" stroke-width="0"/>';
|
|
346
|
+
const scrollbarStyle = `
|
|
347
|
+
:host {
|
|
348
|
+
display: block;
|
|
349
|
+
contain: content;
|
|
350
|
+
background-color: #f8f8f8;
|
|
351
|
+
border-style: solid;
|
|
352
|
+
border-width: 1px;
|
|
353
|
+
border-color: #dddddd;
|
|
354
|
+
}
|
|
355
|
+
#root {
|
|
356
|
+
touch-action: none;
|
|
357
|
+
user-select: none;
|
|
358
|
+
box-sizing: border-box;
|
|
359
|
+
position: relative;
|
|
360
|
+
width: 100%;
|
|
361
|
+
height: 100%;
|
|
362
|
+
}
|
|
363
|
+
#trough {
|
|
364
|
+
position: absolute;
|
|
365
|
+
}
|
|
366
|
+
#root.vertical #trough {
|
|
367
|
+
width: 100%;
|
|
368
|
+
top: ${buttonSize};
|
|
369
|
+
bottom: ${buttonSize};
|
|
370
|
+
}
|
|
371
|
+
#root.horizontal #trough {
|
|
372
|
+
height: 100%;
|
|
373
|
+
left: ${buttonSize};
|
|
374
|
+
right: ${buttonSize};
|
|
375
|
+
}
|
|
376
|
+
#thumb {
|
|
377
|
+
box-sizing: border-box;
|
|
378
|
+
position: absolute;
|
|
379
|
+
width: 100%;
|
|
380
|
+
height: 100%;
|
|
381
|
+
background-color: var(--plain-scrollbar-thumb-background-color, #f0f0f0);
|
|
382
|
+
border-style: solid;
|
|
383
|
+
border-width: var(--plain-scrollbar-thumb-border-width, 1px);
|
|
384
|
+
border-color: var(--plain-scrollbar-thumb-border-color, #b8b8b8);
|
|
385
|
+
border-radius: var(--plain-scrollbar-thumb-border-radius, 4px);
|
|
386
|
+
transition: background-color 50ms linear;
|
|
387
|
+
}
|
|
388
|
+
#thumb:hover {
|
|
389
|
+
background-color: var(--plain-scrollbar-thumb-background-color-hover, #e0e0e0);
|
|
390
|
+
}
|
|
391
|
+
#thumb.active {
|
|
392
|
+
background-color: var(--plain-scrollbar-thumb-background-color-active, #c0c0c0);
|
|
393
|
+
}
|
|
394
|
+
#button1,
|
|
395
|
+
#button2 {
|
|
396
|
+
box-sizing: border-box;
|
|
397
|
+
position: absolute;
|
|
398
|
+
display: block;
|
|
399
|
+
fill: var(--plain-scrollbar-button-color, #606060);
|
|
400
|
+
}
|
|
401
|
+
#root.vertical #button1 {
|
|
402
|
+
top: 0;
|
|
403
|
+
width: 100%;
|
|
404
|
+
height: ${buttonSize};
|
|
405
|
+
}
|
|
406
|
+
#root.vertical #button2 {
|
|
407
|
+
bottom: 0;
|
|
408
|
+
width: 100%;
|
|
409
|
+
height: ${buttonSize};
|
|
410
|
+
}
|
|
411
|
+
#root.horizontal #button1 {
|
|
412
|
+
left: 0;
|
|
413
|
+
height: 100%;
|
|
414
|
+
width: ${buttonSize};
|
|
415
|
+
}
|
|
416
|
+
#root.horizontal #button2 {
|
|
417
|
+
right: 0;
|
|
418
|
+
height: 100%;
|
|
419
|
+
width: ${buttonSize};
|
|
420
|
+
}
|
|
421
|
+
#upArrow,
|
|
422
|
+
#downArrow,
|
|
423
|
+
#leftArrow,
|
|
424
|
+
#rightArrow {
|
|
425
|
+
display: none;
|
|
426
|
+
width: 100%;
|
|
427
|
+
height: 100%;
|
|
428
|
+
}
|
|
429
|
+
#root.vertical #upArrow,
|
|
430
|
+
#root.vertical #downArrow {
|
|
431
|
+
display: block;
|
|
432
|
+
}
|
|
433
|
+
#root.horizontal #leftArrow,
|
|
434
|
+
#root.horizontal #rightArrow {
|
|
435
|
+
display: block;
|
|
436
|
+
}
|
|
437
|
+
#button1:hover,
|
|
438
|
+
#button2:hover {
|
|
439
|
+
background-color: var(--plain-scrollbar-button-color-hover, #e0e0e0);
|
|
440
|
+
}
|
|
441
|
+
#button1.active,
|
|
442
|
+
#button2.active {
|
|
443
|
+
background-color: var(--plain-scrollbar-button-color-active, #c0c0c0);
|
|
444
|
+
}
|
|
445
|
+
`;
|
|
446
|
+
const scrollbarHtmlTemplate = `
|
|
447
|
+
<style>${scrollbarStyle}</style>
|
|
448
|
+
<div id="root" part="root">
|
|
449
|
+
<div id="button1" part="button button1">
|
|
450
|
+
<svg id="upArrow" part="arrow upArrow" viewBox="-100 -100 200 200">${buttonPath}</svg>
|
|
451
|
+
<svg id="leftArrow" part="arrow leftArrow" viewBox="-100 -100 200 200"><g transform="rotate(-90)">${buttonPath}</g></svg>
|
|
452
|
+
</div>
|
|
453
|
+
<div id="trough" part="trough">
|
|
454
|
+
<div id="thumb" part="thumb"></div>
|
|
455
|
+
</div>
|
|
456
|
+
<div id="button2" part="button button2">
|
|
457
|
+
<svg id="downArrow" part="arrow downArrow" viewBox="-100 -100 200 200"><g transform="rotate(180)">${buttonPath}</g></svg>
|
|
458
|
+
<svg id="rightArrow" part="arrow rightArrow" viewBox="-100 -100 200 200"><g transform="rotate(90)">${buttonPath}</g></svg>
|
|
459
|
+
</div>
|
|
460
|
+
</div>
|
|
461
|
+
`;
|
|
462
|
+
//------------------------------------------------------------------------------
|
|
463
|
+
function formatOrientation(b) {
|
|
464
|
+
return b ? "vertical" : "horizontal";
|
|
465
|
+
}
|
|
466
|
+
function decodeOrientation(s) {
|
|
467
|
+
switch (s) {
|
|
468
|
+
case "vertical": return true;
|
|
469
|
+
case "horizontal": return false;
|
|
470
|
+
default: throw new Error("Invalid orientation value \"" + s + "\".");
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
function percent(v) {
|
|
474
|
+
return (v * 100).toFixed(3) + "%";
|
|
475
|
+
}
|
|
476
|
+
function decodePxValue(s) {
|
|
477
|
+
if (!s || !s.endsWith("px")) {
|
|
478
|
+
return undefined;
|
|
479
|
+
}
|
|
480
|
+
return Number(s.substring(0, s.length - 2));
|
|
481
|
+
}
|
|
482
|
+
customElements.define("node-projects-plain-scrollbar", PlainScrollbar);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCustomWebComponentConstructorAppend } from "@node-projects/base-custom-webcomponent";
|
|
2
|
+
export declare class SimpleSplitView extends BaseCustomWebComponentConstructorAppend {
|
|
3
|
+
static readonly style: CSSStyleSheet;
|
|
4
|
+
static readonly template: HTMLTemplateElement;
|
|
5
|
+
static properties: {
|
|
6
|
+
orientation: StringConstructor;
|
|
7
|
+
};
|
|
8
|
+
orientation: 'vertical' | 'horizontal';
|
|
9
|
+
constructor();
|
|
10
|
+
ready(): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { BaseCustomWebComponentConstructorAppend, css, html } from "@node-projects/base-custom-webcomponent";
|
|
2
|
+
export class SimpleSplitView extends BaseCustomWebComponentConstructorAppend {
|
|
3
|
+
static style = css `
|
|
4
|
+
:host {
|
|
5
|
+
display: block;
|
|
6
|
+
}
|
|
7
|
+
#split {
|
|
8
|
+
position: relative;
|
|
9
|
+
height: 100%;
|
|
10
|
+
width: 100%;
|
|
11
|
+
grid-template-rows: calc(var(--split) * 1%) 5px calc((100 - var(--split)) * 1%);
|
|
12
|
+
display: grid;
|
|
13
|
+
align-items: center;
|
|
14
|
+
}
|
|
15
|
+
#splitter {
|
|
16
|
+
user-select: none;
|
|
17
|
+
-webkit-user-select: none;
|
|
18
|
+
}
|
|
19
|
+
:host(:not([orientation="vertical"])) > div > #splitter {
|
|
20
|
+
cursor: ew-resize;
|
|
21
|
+
width: 5px;
|
|
22
|
+
}
|
|
23
|
+
:host([orientation="vertical"]) > div > #splitter {
|
|
24
|
+
cursor: ns-resize;
|
|
25
|
+
height: 5px;
|
|
26
|
+
}`;
|
|
27
|
+
static template = html `
|
|
28
|
+
<div id="split" style="--split: 50;">
|
|
29
|
+
<slot name="top"></slot>
|
|
30
|
+
<div id="splitter"></div>
|
|
31
|
+
<slot name="bottom"></slot>
|
|
32
|
+
</div>`;
|
|
33
|
+
static properties = {
|
|
34
|
+
orientation: String
|
|
35
|
+
};
|
|
36
|
+
orientation = 'vertical';
|
|
37
|
+
constructor() {
|
|
38
|
+
super();
|
|
39
|
+
}
|
|
40
|
+
ready() {
|
|
41
|
+
this._parseAttributesToProperties();
|
|
42
|
+
this.setAttribute('orientation', this.orientation);
|
|
43
|
+
const split = this._getDomElement("split");
|
|
44
|
+
const splitter = this._getDomElement("splitter");
|
|
45
|
+
let start = null;
|
|
46
|
+
splitter.addEventListener('pointerdown', (e) => {
|
|
47
|
+
splitter.setPointerCapture(e.pointerId);
|
|
48
|
+
start = true;
|
|
49
|
+
});
|
|
50
|
+
splitter.addEventListener('pointerup', (e) => {
|
|
51
|
+
splitter.releasePointerCapture(e.pointerId);
|
|
52
|
+
start = null;
|
|
53
|
+
});
|
|
54
|
+
splitter.addEventListener('pointermove', (e) => {
|
|
55
|
+
if (start !== null) {
|
|
56
|
+
let splitValue = parseFloat(split.style.getPropertyValue('--split'));
|
|
57
|
+
if (this.orientation === 'horizontal')
|
|
58
|
+
splitValue += e.movementX * 100 / split.clientWidth;
|
|
59
|
+
else
|
|
60
|
+
splitValue += e.movementY * 100 / split.clientHeight;
|
|
61
|
+
if (!isNaN(splitValue))
|
|
62
|
+
split.style.setProperty("--split", splitValue);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
customElements.define('node-projects-simple-split-view', SimpleSplitView);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCustomWebComponentConstructorAppend } from "@node-projects/base-custom-webcomponent";
|
|
2
|
+
export declare class SimpleSplitView extends BaseCustomWebComponentConstructorAppend {
|
|
3
|
+
static readonly style: CSSStyleSheet;
|
|
4
|
+
static readonly template: HTMLTemplateElement;
|
|
5
|
+
static properties: {
|
|
6
|
+
orientation: StringConstructor;
|
|
7
|
+
};
|
|
8
|
+
orientation: 'vertical' | 'horizontal';
|
|
9
|
+
constructor();
|
|
10
|
+
ready(): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { BaseCustomWebComponentConstructorAppend, css, html } from "@node-projects/base-custom-webcomponent";
|
|
2
|
+
export class SimpleSplitView extends BaseCustomWebComponentConstructorAppend {
|
|
3
|
+
static style = css `
|
|
4
|
+
:host {
|
|
5
|
+
display: block;
|
|
6
|
+
}
|
|
7
|
+
#split {
|
|
8
|
+
position: relative;
|
|
9
|
+
height: 100%;
|
|
10
|
+
width: 100%;
|
|
11
|
+
grid-template-rows: calc(var(--split) * 1%) 5px calc((100 - var(--split)) * 1%);
|
|
12
|
+
display: grid;
|
|
13
|
+
align-items: center;
|
|
14
|
+
}
|
|
15
|
+
:host(:not([orientation="vertical"])) > div > #splitter {
|
|
16
|
+
cursor: ew-resize;
|
|
17
|
+
width: 5px;
|
|
18
|
+
}
|
|
19
|
+
:host([orientation="vertical"]) > div > #splitter {
|
|
20
|
+
cursor: ns-resize;
|
|
21
|
+
height: 5px;
|
|
22
|
+
}`;
|
|
23
|
+
static template = html `
|
|
24
|
+
<div id="split" style="--split: 50;">
|
|
25
|
+
<slot name="top"></slot>
|
|
26
|
+
<div id="splitter"></div>
|
|
27
|
+
<slot name="bottom"></slot>
|
|
28
|
+
</div>`;
|
|
29
|
+
static properties = {
|
|
30
|
+
orientation: String
|
|
31
|
+
};
|
|
32
|
+
orientation = 'vertical';
|
|
33
|
+
constructor() {
|
|
34
|
+
super();
|
|
35
|
+
}
|
|
36
|
+
ready() {
|
|
37
|
+
this._parseAttributesToProperties();
|
|
38
|
+
this.setAttribute('orientation', this.orientation);
|
|
39
|
+
const split = this._getDomElement("split");
|
|
40
|
+
const splitter = this._getDomElement("splitter");
|
|
41
|
+
let start = null;
|
|
42
|
+
splitter.addEventListener('pointerdown', (e) => {
|
|
43
|
+
splitter.setPointerCapture(e.pointerId);
|
|
44
|
+
start = true;
|
|
45
|
+
});
|
|
46
|
+
splitter.addEventListener('pointerup', (e) => {
|
|
47
|
+
splitter.releasePointerCapture(e.pointerId);
|
|
48
|
+
start = null;
|
|
49
|
+
});
|
|
50
|
+
splitter.addEventListener('pointermove', (e) => {
|
|
51
|
+
if (start !== null) {
|
|
52
|
+
let splitValue = parseFloat(split.style.getPropertyValue('--split'));
|
|
53
|
+
if (this.orientation === 'horizontal')
|
|
54
|
+
splitValue += e.movementX * 100 / split.clientWidth;
|
|
55
|
+
else
|
|
56
|
+
splitValue += e.movementY * 100 / split.clientHeight;
|
|
57
|
+
if (!isNaN(splitValue))
|
|
58
|
+
split.style.setProperty("--split", splitValue);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
customElements.define('node-projects-simple-split-view', SimpleSplitView);
|