@matdata/yasgui 5.7.0 → 5.8.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@matdata/yasgui",
3
3
  "description": "Yet Another SPARQL GUI",
4
- "version": "5.7.0",
4
+ "version": "5.8.0",
5
5
  "main": "build/yasgui.min.js",
6
6
  "types": "build/ts/src/index.d.ts",
7
7
  "license": "MIT",
@@ -33,8 +33,8 @@
33
33
  "jsuri": "^1.3.1",
34
34
  "lodash-es": "^4.17.15",
35
35
  "sortablejs": "^1.10.2",
36
- "@matdata/yasgui-graph-plugin": "^1.3.0",
37
- "@matdata/yasgui-table-plugin": "^1.0.0"
36
+ "@matdata/yasgui-graph-plugin": "^1.4.0",
37
+ "@matdata/yasgui-table-plugin": "^1.1.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/autosuggest-highlight": "^3.1.0",
package/src/Tab.ts CHANGED
@@ -78,6 +78,8 @@ export class Tab extends EventEmitter {
78
78
  private settingsModal?: TabSettingsModal;
79
79
  private currentOrientation: "vertical" | "horizontal";
80
80
  private orientationToggleButton?: HTMLButtonElement;
81
+ private verticalResizerEl?: HTMLDivElement;
82
+ private editorWrapperEl?: HTMLDivElement;
81
83
 
82
84
  constructor(yasgui: Yasgui, conf: PersistedJson) {
83
85
  super();
@@ -115,6 +117,7 @@ export class Tab extends EventEmitter {
115
117
  // Useful for adding an infos div that goes alongside the editor without needing to rebuild the whole Yasgui class
116
118
  const editorWrapper = document.createElement("div");
117
119
  editorWrapper.className = "editorwrapper";
120
+ this.editorWrapperEl = editorWrapper;
118
121
  const controlbarAndYasqeDiv = document.createElement("div");
119
122
  //controlbar
120
123
  this.controlBarEl = document.createElement("div");
@@ -132,6 +135,10 @@ export class Tab extends EventEmitter {
132
135
 
133
136
  this.initTabSettingsMenu();
134
137
  this.rootEl.appendChild(editorWrapper);
138
+
139
+ // Add vertical resizer for horizontal layout
140
+ this.drawVerticalResizer();
141
+
135
142
  this.rootEl.appendChild(this.yasrWrapperEl);
136
143
  this.initControlbar();
137
144
  this.initYasqe();
@@ -321,6 +328,12 @@ export class Tab extends EventEmitter {
321
328
  tab.updateOrientationToggleIcon();
322
329
  }
323
330
 
331
+ // Reset editor wrapper width when switching orientations
332
+ if (tab.editorWrapperEl) {
333
+ tab.editorWrapperEl.style.width = "";
334
+ tab.editorWrapperEl.style.flex = "";
335
+ }
336
+
324
337
  // Refresh components to adjust to new layout
325
338
  if (tab.yasqe) {
326
339
  tab.yasqe.refresh();
@@ -986,7 +999,94 @@ WHERE {
986
999
  });
987
1000
  }
988
1001
 
1002
+ private drawVerticalResizer() {
1003
+ if (this.verticalResizerEl || !this.rootEl) return;
1004
+ this.verticalResizerEl = document.createElement("div");
1005
+ addClass(this.verticalResizerEl, "verticalResizeWrapper");
1006
+ const chip = document.createElement("div");
1007
+ addClass(chip, "verticalResizeChip");
1008
+ this.verticalResizerEl.appendChild(chip);
1009
+ this.verticalResizerEl.addEventListener("mousedown", this.initVerticalDrag, false);
1010
+ this.verticalResizerEl.addEventListener("dblclick", this.resetVerticalSplit, false);
1011
+ this.rootEl.appendChild(this.verticalResizerEl);
1012
+ }
1013
+
1014
+ private initVerticalDrag = () => {
1015
+ document.documentElement.addEventListener("mousemove", this.doVerticalDrag, false);
1016
+ document.documentElement.addEventListener("mouseup", this.stopVerticalDrag, false);
1017
+ };
1018
+
1019
+ private calculateVerticalDragOffset(event: MouseEvent): number {
1020
+ if (!this.rootEl) return 0;
1021
+
1022
+ let parentOffset = 0;
1023
+ if (this.rootEl.offsetParent) {
1024
+ parentOffset = (this.rootEl.offsetParent as HTMLElement).offsetLeft;
1025
+ }
1026
+
1027
+ let scrollOffset = 0;
1028
+ let parentElement = this.rootEl.parentElement;
1029
+ while (parentElement) {
1030
+ scrollOffset += parentElement.scrollLeft;
1031
+ parentElement = parentElement.parentElement;
1032
+ }
1033
+
1034
+ return event.clientX - parentOffset - this.rootEl.offsetLeft + scrollOffset;
1035
+ }
1036
+
1037
+ private doVerticalDrag = (event: MouseEvent) => {
1038
+ if (!this.editorWrapperEl || !this.rootEl) return;
1039
+
1040
+ const offset = this.calculateVerticalDragOffset(event);
1041
+ const totalWidth = this.rootEl.offsetWidth;
1042
+
1043
+ // Ensure minimum widths (at least 200px for each panel)
1044
+ const minWidth = 200;
1045
+ const maxWidth = totalWidth - minWidth - 10; // 10px for resizer
1046
+
1047
+ const newWidth = Math.max(minWidth, Math.min(maxWidth, offset));
1048
+ this.editorWrapperEl.style.width = newWidth + "px";
1049
+ this.editorWrapperEl.style.flex = "0 0 " + newWidth + "px";
1050
+ };
1051
+
1052
+ private stopVerticalDrag = () => {
1053
+ document.documentElement.removeEventListener("mousemove", this.doVerticalDrag, false);
1054
+ document.documentElement.removeEventListener("mouseup", this.stopVerticalDrag, false);
1055
+
1056
+ // Refresh editors after resizing
1057
+ if (this.yasqe) {
1058
+ this.yasqe.refresh();
1059
+ }
1060
+ if (this.yasr) {
1061
+ this.yasr.refresh();
1062
+ }
1063
+ };
1064
+
1065
+ private resetVerticalSplit = () => {
1066
+ if (!this.editorWrapperEl) return;
1067
+
1068
+ // Reset to 50/50 split
1069
+ this.editorWrapperEl.style.width = "";
1070
+ this.editorWrapperEl.style.flex = "1 1 50%";
1071
+
1072
+ // Refresh editors after resizing
1073
+ if (this.yasqe) {
1074
+ this.yasqe.refresh();
1075
+ }
1076
+ if (this.yasr) {
1077
+ this.yasr.refresh();
1078
+ }
1079
+ };
1080
+
989
1081
  destroy() {
1082
+ // Clean up vertical resizer event listeners
1083
+ if (this.verticalResizerEl) {
1084
+ this.verticalResizerEl.removeEventListener("mousedown", this.initVerticalDrag, false);
1085
+ this.verticalResizerEl.removeEventListener("dblclick", this.resetVerticalSplit, false);
1086
+ }
1087
+ document.documentElement.removeEventListener("mousemove", this.doVerticalDrag, false);
1088
+ document.documentElement.removeEventListener("mouseup", this.stopVerticalDrag, false);
1089
+
990
1090
  this.removeAllListeners();
991
1091
  this.settingsModal?.destroy();
992
1092
  this.endpointSelect?.destroy();
@@ -1,14 +1,19 @@
1
1
  @use "sass:color";
2
+
2
3
  $minTabHeight: 35px;
4
+
3
5
  .yasgui {
4
6
  .tabsList {
7
+ flex-shrink: 0; // Prevent tabs from shrinking
8
+ display: flex;
9
+ flex-wrap: wrap;
10
+
5
11
  .sortable-placeholder {
6
12
  min-width: 100px;
7
13
  min-height: $minTabHeight;
8
14
  border: 2px dotted color.adjust(#555, $lightness: 20%);
9
15
  }
10
- display: flex;
11
- flex-wrap: wrap;
16
+
12
17
  a {
13
18
  cursor: pointer;
14
19
  display: flex;
@@ -18,6 +23,7 @@ $minTabHeight: 35px;
18
23
  border-bottom: 2px solid transparent;
19
24
  box-sizing: border-box;
20
25
  }
26
+
21
27
  .themeToggle {
22
28
  cursor: pointer;
23
29
  height: 100%;
@@ -60,10 +66,12 @@ $minTabHeight: 35px;
60
66
  &:focus-visible {
61
67
  transform: scale(1.1);
62
68
  }
69
+
63
70
  &:focus {
64
71
  color: #faa857;
65
72
  }
66
73
  }
74
+
67
75
  .tab {
68
76
  position: relative;
69
77
  $activeColor: #337ab7;
@@ -82,6 +90,7 @@ $minTabHeight: 35px;
82
90
  animation-timing-function: ease;
83
91
  animation-iteration-count: infinite;
84
92
  }
93
+
85
94
  @keyframes slide {
86
95
  0% {
87
96
  left: 0;
@@ -96,24 +105,30 @@ $minTabHeight: 35px;
96
105
  right: 0;
97
106
  }
98
107
  }
108
+
99
109
  &.active .loader {
100
110
  background-color: $hoverColor;
101
111
  }
112
+
102
113
  &:hover .loader {
103
114
  background-color: $activeColor;
104
115
  }
116
+
105
117
  &.querying .loader {
106
118
  display: block;
107
119
  }
120
+
108
121
  &.active a {
109
122
  border-bottom-color: $activeColor;
110
123
  color: var(--yasgui-text-primary, #555);
111
124
  }
125
+
112
126
  input {
113
127
  display: none;
114
128
  outline: none;
115
129
  border: none;
116
130
  }
131
+
117
132
  &.renaming {
118
133
  span {
119
134
  display: none;
@@ -125,6 +140,7 @@ $minTabHeight: 35px;
125
140
  display: block;
126
141
  }
127
142
  }
143
+
128
144
  a {
129
145
  font-weight: 600;
130
146
  color: var(--yasgui-text-secondary, color.adjust(#555, $lightness: 20%));
@@ -135,14 +151,17 @@ $minTabHeight: 35px;
135
151
  padding: 0px 24px 0px 30px;
136
152
  white-space: nowrap;
137
153
  overflow: hidden;
154
+
138
155
  &:hover {
139
156
  border-bottom-color: $hoverColor;
140
157
  color: var(--yasgui-text-primary, #555);
141
158
  }
159
+
142
160
  &:focus {
143
161
  border-bottom-color: #faa857;
144
162
  color: var(--yasgui-text-primary, #555);
145
163
  }
164
+
146
165
  .closeTab {
147
166
  color: var(--yasgui-text-primary, #000);
148
167
  margin-left: 7px;
@@ -151,6 +170,7 @@ $minTabHeight: 35px;
151
170
  opacity: 0.2;
152
171
  font-weight: 700;
153
172
  padding: 2px;
173
+
154
174
  &:hover {
155
175
  opacity: 0.5;
156
176
  }
package/src/index.scss CHANGED
@@ -1,4 +1,12 @@
1
+ // Main YASGUI container - fills 100% of parent element
2
+ // Parent element (typically body) should have height: 100%; width: 100%
1
3
  .yasgui {
4
+ display: flex;
5
+ flex-direction: column;
6
+ height: 100%;
7
+ width: 100%;
8
+ min-height: 800px; // Minimum to ensure usable UI (control bar + editor + yasr min)
9
+
2
10
  a {
3
11
  color: #337ab7;
4
12
  text-decoration: none;
@@ -28,6 +36,15 @@
28
36
  }
29
37
  }
30
38
 
39
+ // Container for tab panels - takes remaining height after tabsList
40
+ > div:not(.tabsList) {
41
+ flex: 1;
42
+ display: flex;
43
+ flex-direction: column;
44
+ min-height: 0; // Required for flex children to shrink properly
45
+ overflow: hidden;
46
+ }
47
+
31
48
  //css taken from https://www.muicss.com/docs/v1/css-js/forms
32
49
  $focusColor: #337ab7;
33
50
  $font-size: 15px;
package/src/tab.scss CHANGED
@@ -2,8 +2,16 @@
2
2
  .tabPanel {
3
3
  display: none;
4
4
  position: relative;
5
+ flex: 1;
6
+ min-height: 0;
7
+
5
8
  &.active {
6
- display: block;
9
+ display: flex;
10
+ flex-direction: column;
11
+ }
12
+
13
+ .yasrWrapperEl {
14
+ height: 100%;
7
15
  }
8
16
 
9
17
  // Hide editor wrapper when yasr is in fullscreen
@@ -34,45 +42,95 @@
34
42
  display: flex;
35
43
  flex-direction: row;
36
44
  gap: 10px;
37
- // Allow flexible height - can use 100vh or be constrained by parent
38
- min-height: var(--yasgui-min-height);
39
- max-height: calc(100vh - var(--yasgui-header-height));
45
+ height: 100%;
40
46
  }
41
47
 
42
48
  .editorwrapper {
43
- flex: 1;
49
+ flex: 1 1 50%;
44
50
  display: flex;
45
51
  flex-direction: column;
46
- }
47
-
48
- // Make YASQE fill the vertical space in horizontal mode
49
- .yasqe {
50
- display: flex;
51
- flex-direction: column;
52
- flex: 1;
53
- min-height: 0;
52
+ min-width: 400px;
53
+ max-width: 50%;
54
+ height: 100%;
54
55
  overflow: hidden;
55
56
 
56
- .CodeMirror {
57
- height: calc(100vh - var(--yasgui-header-height)) !important;
57
+ // Unnamed div container needs full height
58
+ > div {
59
+ height: 100%;
60
+ flex: 1;
61
+ display: flex;
62
+ flex-direction: column;
63
+
64
+ // Container for tab panels - takes remaining height after tabsList
65
+ > div:not(.controlbar) {
66
+ flex: 1;
67
+ display: flex;
68
+ flex-direction: column;
69
+ min-height: 0; // Required for flex children to shrink properly
70
+ overflow: hidden;
71
+
72
+ // Make YASQE fill the vertical space in horizontal mode
73
+ .yasqe {
74
+ flex: 1;
75
+ display: flex;
76
+ flex-direction: column;
77
+ height: 100%;
78
+ overflow: hidden;
79
+
80
+ .CodeMirror {
81
+ flex: 1;
82
+ height: 100%;
83
+ }
84
+ }
85
+ }
58
86
  }
59
87
  }
60
88
 
61
89
  .yasrWrapperEl {
62
- flex: 1;
90
+ flex: 1 1 50%;
63
91
  min-width: 0;
64
- height: calc(100vh - var(--yasgui-tabList-height)) !important;
65
- overflow: hidden;
92
+ min-height: 400px;
66
93
  }
67
94
 
68
95
  .yasr {
69
96
  margin-top: 0;
70
97
  height: 100%;
71
98
  }
99
+
100
+ // Hide horizontal resize wrapper in horizontal mode (vertical resizer is used instead)
101
+ .horizontalResizeWrapper {
102
+ display: none;
103
+ }
104
+ }
105
+
106
+ // Vertical resizer for horizontal layout
107
+ .verticalResizeWrapper {
108
+ display: none; // Hidden by default (shown only in horizontal mode)
109
+ width: 10px;
110
+ flex-shrink: 0;
111
+ align-items: center;
112
+ justify-content: center;
113
+ cursor: col-resize;
114
+ position: relative;
115
+ z-index: 10;
116
+
117
+ &:hover .verticalResizeChip {
118
+ visibility: visible;
119
+ }
120
+ }
121
+
122
+ .verticalResizeChip {
123
+ width: 4px;
124
+ height: 20%;
125
+ background-color: #d1d1d1;
126
+ visibility: hidden;
127
+ border-radius: 2px;
128
+ }
129
+
130
+ // Show vertical resizer only in horizontal mode
131
+ &.orientation-horizontal .verticalResizeWrapper {
132
+ display: flex;
72
133
  }
73
- }
74
- .yasr {
75
- margin-top: 5px;
76
134
  }
77
135
 
78
136
  .tabContextButton {
@@ -91,9 +149,9 @@
91
149
  .svgImg {
92
150
  width: 15px;
93
151
  height: 15px;
94
- font-family: initial; //font families can slightly misalign svgs with the .svgimg div
152
+ font-family: initial;
95
153
  }
96
- // IE11 Needs this specified otherwise it will not resize the svg
154
+
97
155
  svg {
98
156
  width: 20px;
99
157
  height: 20px;
@@ -108,6 +166,7 @@
108
166
  .controlbar {
109
167
  display: flex;
110
168
  align-content: center;
169
+ flex-shrink: 0;
111
170
  max-height: 35px;
112
171
  }
113
172
  }
package/src/themes.scss CHANGED
@@ -38,10 +38,8 @@
38
38
  --yasgui-nav-bg: #eee;
39
39
  --yasgui-match-highlight-bg: #dbdeed;
40
40
 
41
- // Layout dimensions (used for horizontal orientation)
42
- --yasgui-header-height: 150px; // Height to subtract from viewport in horizontal layout
43
- --yasgui-tabList-height: 70px; // Height to subtract from yasr in horizontal layout
44
- --yasgui-min-height: 400px; // Minimum height for horizontal layout panels
41
+ // Minimum heights
42
+ --yasgui-yasr-min-height: 400px; // Minimum height for yasr
45
43
 
46
44
  --yasgui-endpoint-button-bg: #337ab7;
47
45
  --yasgui-endpoint-button-border: #337ab7;
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  // Version information for YASGUI
2
2
  // This file is auto-generated during build - do not edit manually
3
- export const VERSION = "5.7.0";
3
+ export const VERSION = "5.8.0";