Skip to content

Commit a17f51a

Browse files
CopilotMathiasVDA
andcommitted
Redesign YASQE buttons with modern styling and keyboard shortcuts
Co-authored-by: MathiasVDA <15101339+MathiasVDA@users.noreply.github.com>
1 parent 1bdcac3 commit a17f51a

File tree

4 files changed

+133
-59
lines changed

4 files changed

+133
-59
lines changed

packages/yasqe/src/defaults.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ SELECT * WHERE {
8787
const yasqe: Yasqe = _yasqe;
8888
yasqe.getInputField().blur();
8989
},
90+
F11: function (_yasqe: any) {
91+
const yasqe: Yasqe = _yasqe;
92+
yasqe.toggleFullscreen();
93+
},
9094
},
9195

9296
createShareableLink: function (yasqe: Yasqe) {

packages/yasqe/src/imgs.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ export var fullscreen =
1313
export var fullscreenExit =
1414
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/></svg>';
1515
export var format =
16-
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 3v18h18v-2H5V3H3zm14 4V5l-4 4 4 4V9h4V7h-4zM7 9v2h10V9H7zm0 4v2h10v-2H7zm0 4v2h10v-2H7z"/></svg>';
16+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M288 64c0 17.7-14.3 32-32 32H32C14.3 96 0 81.7 0 64S14.3 32 32 32H256c17.7 0 32 14.3 32 32zm0 256c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H256c17.7 0 32 14.3 32 32zM0 192c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 448c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg>';
17+
export var save =
18+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M433.94 129.94l-83.88-83.88A48 48 0 0 0 316.12 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V195.88a48 48 0 0 0-14.06-33.94zM224 416a64 64 0 1 1 0-128 64 64 0 0 1 0 128zm96-224a16 16 0 0 1-16 16H144a16 16 0 0 1-16-16V80a16 16 0 0 1 16-16h160a16 16 0 0 1 16 16z"/></svg>';
1719
export var snippet =
1820
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/></svg>';
1921
export var chevronDown =

packages/yasqe/src/index.ts

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,48 @@ export class Yasqe extends CodeMirror {
246246
}
247247

248248
/**
249-
* draw share link button
249+
* Draw query btn (FIRST)
250+
*/
251+
if (this.config.showQueryButton) {
252+
this.queryBtn = document.createElement("button");
253+
addClass(this.queryBtn, "yasqe_queryButton");
254+
255+
/**
256+
* Add text label
257+
*/
258+
const queryTextLabel = document.createElement("span");
259+
queryTextLabel.className = "yasqe_queryButton_text";
260+
queryTextLabel.textContent = "Run query";
261+
this.queryBtn.appendChild(queryTextLabel);
262+
263+
/**
264+
* Add busy/valid/error btns
265+
*/
266+
const queryEl = drawSvgStringAsElement(imgs.query);
267+
addClass(queryEl, "queryIcon");
268+
this.queryBtn.appendChild(queryEl);
269+
270+
const warningIcon = drawSvgStringAsElement(imgs.warning);
271+
addClass(warningIcon, "warningIcon");
272+
this.queryBtn.appendChild(warningIcon);
273+
274+
this.queryBtn.onclick = () => {
275+
if (this.config.queryingDisabled) return; // Don't do anything
276+
if (this.req) {
277+
this.abortQuery();
278+
} else {
279+
this.query().catch(() => {}); //catch this to avoid unhandled rejection
280+
}
281+
};
282+
this.queryBtn.title = "Run query (Ctrl+Enter)";
283+
this.queryBtn.setAttribute("aria-label", "Run query");
284+
285+
buttons.appendChild(this.queryBtn);
286+
this.updateQueryButton();
287+
}
288+
289+
/**
290+
* draw share link button (SECOND)
250291
*/
251292
if (this.config.createShareableLink) {
252293
var svgShare = drawSvgStringAsElement(imgs.share);
@@ -481,41 +522,24 @@ export class Yasqe extends CodeMirror {
481522
}
482523
};
483524
}
525+
484526
/**
485-
* Draw query btn
527+
* Draw save button (THIRD)
486528
*/
487-
if (this.config.showQueryButton) {
488-
this.queryBtn = document.createElement("button");
489-
addClass(this.queryBtn, "yasqe_queryButton");
490-
491-
/**
492-
* Add busy/valid/error btns
493-
*/
494-
const queryEl = drawSvgStringAsElement(imgs.query);
495-
addClass(queryEl, "queryIcon");
496-
this.queryBtn.appendChild(queryEl);
497-
498-
const warningIcon = drawSvgStringAsElement(imgs.warning);
499-
addClass(warningIcon, "warningIcon");
500-
this.queryBtn.appendChild(warningIcon);
501-
502-
this.queryBtn.onclick = () => {
503-
if (this.config.queryingDisabled) return; // Don't do anything
504-
if (this.req) {
505-
this.abortQuery();
506-
} else {
507-
this.query().catch(() => {}); //catch this to avoid unhandled rejection
508-
}
509-
};
510-
this.queryBtn.title = "Run query";
511-
this.queryBtn.setAttribute("aria-label", "Run query");
512-
513-
buttons.appendChild(this.queryBtn);
514-
this.updateQueryButton();
515-
}
529+
const saveBtn = document.createElement("button");
530+
addClass(saveBtn, "yasqe_saveButton");
531+
const saveIcon = drawSvgStringAsElement(imgs.save);
532+
addClass(saveIcon, "saveIcon");
533+
saveBtn.appendChild(saveIcon);
534+
saveBtn.onclick = () => {
535+
this.saveQuery();
536+
};
537+
saveBtn.title = "Save query (Ctrl+S)";
538+
saveBtn.setAttribute("aria-label", "Save query");
539+
buttons.appendChild(saveBtn);
516540

517541
/**
518-
* Draw format btn
542+
* Draw format btn (FOURTH)
519543
*/
520544
if (this.config.showFormatButton) {
521545
const formatBtn = document.createElement("button");
@@ -532,7 +556,7 @@ export class Yasqe extends CodeMirror {
532556
}
533557

534558
/**
535-
* Draw fullscreen btn
559+
* Draw fullscreen btn (FIFTH)
536560
*/
537561
this.fullscreenBtn = document.createElement("button");
538562
addClass(this.fullscreenBtn, "yasqe_fullscreenButton");
@@ -926,7 +950,7 @@ export class Yasqe extends CodeMirror {
926950
this.queryBtn.title = this.config.queryingDisabled;
927951
} else {
928952
removeClass(this.queryBtn, "query_disabled");
929-
this.queryBtn.title = "Run query";
953+
this.queryBtn.title = "Run query (Ctrl+Enter)";
930954
this.queryBtn.setAttribute("aria-label", "Run query");
931955
}
932956
if (!status) {

packages/yasqe/src/scss/buttons.scss

Lines changed: 68 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@
8181
height: 25px;
8282
width: 25px;
8383
}
84+
85+
&:hover {
86+
svg {
87+
fill: #337ab7;
88+
}
89+
}
8490
}
8591

8692
button {
@@ -163,29 +169,57 @@
163169
}
164170
}
165171
.yasqe_queryButton {
166-
display: inline-block;
172+
display: inline-flex;
173+
align-items: center;
174+
gap: 8px;
167175
position: relative;
168-
border: none;
169-
background: none;
170-
padding: 0;
176+
border: 1px solid #337ab7;
177+
background: #337ab7;
178+
padding: 8px 16px;
171179
cursor: pointer;
172-
width: $queryButtonWidth;
173-
height: $queryButtonHeight;
180+
border-radius: 4px;
181+
color: white;
182+
font-weight: 500;
183+
font-size: 14px;
184+
transition: all 0.2s ease;
185+
186+
.yasqe_queryButton_text {
187+
display: inline-block;
188+
line-height: 1;
189+
}
174190

175191
.queryIcon {
176-
display: block;
192+
display: inline-flex;
193+
align-items: center;
177194
svg {
178-
width: $queryButtonWidth;
179-
height: $queryButtonHeight;
195+
width: 16px;
196+
height: 16px;
197+
fill: white;
180198
}
181199
}
200+
201+
&:hover {
202+
background: #2868a0;
203+
border-color: #2868a0;
204+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
205+
}
206+
207+
&:active {
208+
background: #1f5180;
209+
border-color: #1f5180;
210+
}
211+
182212
.svgImg {
183213
position: absolute;
184214
height: inherit;
185215
top: 0;
186216
}
187217

188218
&.busy {
219+
background: #5a8fc2;
220+
border-color: #5a8fc2;
221+
cursor: wait;
222+
189223
svg {
190224
#loadingIcon {
191225
stroke-dasharray: 100;
@@ -210,30 +244,34 @@
210244

211245
.warningIcon {
212246
display: none;
247+
position: absolute;
248+
top: -4px;
249+
right: -4px;
250+
251+
svg {
252+
width: 18px;
253+
height: 18px;
254+
fill: #ffc107;
255+
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3));
256+
}
213257
}
214258

215259
&.query_error {
216260
.warningIcon {
217261
display: block;
218-
top: 5px;
219-
right: 0px;
220-
221-
svg {
222-
width: 15px;
223-
height: 15px;
224-
225-
g {
226-
fill: red;
227-
}
228-
}
229262
}
230263
}
231264

232265
&.query_disabled {
233266
cursor: not-allowed;
234-
.queryIcon {
235-
opacity: 0.5;
236-
filter: alpha(opacity=50);
267+
opacity: 0.6;
268+
background: #95b3d0;
269+
border-color: #95b3d0;
270+
271+
&:hover {
272+
background: #95b3d0;
273+
border-color: #95b3d0;
274+
box-shadow: none;
237275
}
238276
}
239277

@@ -244,7 +282,7 @@
244282
}
245283
}
246284

247-
.yasqe_saveManagedQueryButton {
285+
.yasqe_saveButton {
248286
display: inline-block;
249287
border: none;
250288
background: none;
@@ -256,6 +294,12 @@
256294
height: 25px;
257295
width: 25px;
258296
}
297+
298+
&:hover {
299+
svg {
300+
fill: #337ab7;
301+
}
302+
}
259303
}
260304

261305
.yasqe_formatButton {

0 commit comments

Comments
 (0)