Move the icons to the comment toolbar of the textarea

Moving the icons to the toolbar means they are always displayed for
easier use, as well as not getting in the way when you try to
continue editing longer text in the textarea

This change also updates the code to dynamically add these
buttons to any new textarea rather than waiting for the click

As a nice addition while restyling, it also now makes use of
the existing GitLab tooltips system
This commit is contained in:
Robert Hunt 2021-02-11 16:02:01 +00:00
parent 289925d074
commit 5b7ea782c4
No known key found for this signature in database
GPG Key ID: BFFDFB9EBA4EE49F
3 changed files with 53 additions and 27 deletions

BIN
demo.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

@ -1,37 +1,42 @@
.has-conventional-comments-buttons.comment-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
}
.has-conventional-comments-buttons.comment-toolbar .toolbar-text {
margin: 0;
}
.has-conventional-comments-buttons.comment-toolbar .uploading-container {
float: none;
margin-right: 0;
}
#conventionalCommentButtonContainer { #conventionalCommentButtonContainer {
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
position: absolute; margin-left:0;
bottom: 0;
left: 0;
opacity: 0;
width: 25px;
height: 60px;
transition: all 0.3s;
overflow: hidden;
}
#conventionalCommentButtonContainer:hover {
width: 300px;
opacity: 1;
} }
#conventionalCommentButtonContainer .buttonContainer { #conventionalCommentButtonContainer .buttonContainer {
display: flex; display: flex;
flex-direction: column-reverse; flex-direction: row;
height: 25px; height: 25px;
width: 25px; width: 25px;
overflow: hidden; overflow: hidden;
transition: all 0.3s; transition: all 0.3s;
} }
#conventionalCommentButtonContainer .buttonContainer:hover { #conventionalCommentButtonContainer .buttonContainer.hasBlockingButton:hover {
height: 60px; width: 50px;
} }
#conventionalCommentButtonContainer button { #conventionalCommentButtonContainer button {
margin-right: 0.5rem; margin-right: 0.5rem;
background: transparent;
border: none; border: none;
color: #666;
height: 25px; height: 25px;
width: 25px; width: 25px;
outline: 0; outline: 0;
@ -42,10 +47,26 @@
width: 13px; width: 13px;
} }
#conventionalCommentButtonContainer button:hover {
color: #1068bf;
}
#conventionalCommentButtonContainer button:focus { #conventionalCommentButtonContainer button:focus {
outline: 0; outline: 0;
} }
.gl-dark #conventionalCommentButtonContainer button {
color: #999;
}
.gl-dark #conventionalCommentButtonContainer button:hover {
color: #63a6e9;
}
#conventionalCommentButtonContainer button.blocking { #conventionalCommentButtonContainer button.blocking {
color: red; color: red;
} }
#conventionalCommentButtonContainer button.blocking:hover {
color: #f57f6c;
}

@ -81,10 +81,15 @@ const semanticButtonClickHandler = (e, { textarea, label, blocking }) => {
const buttonGenerator = (textarea, parent, label, blocking) => { const buttonGenerator = (textarea, parent, label, blocking) => {
const button = document.createElement("button"); const button = document.createElement("button");
button.classList.add("has-tooltip")
button.setAttribute("data-title", semanticLabels[label].text);
button.innerHTML = semanticLabels[label].icon; button.innerHTML = semanticLabels[label].icon;
if (blocking) { if (blocking) {
button.classList.add("blocking"); button.classList.add("blocking");
button.setAttribute("data-title", `${semanticLabels[label].text} (blocking)`);
} }
button.addEventListener("click", (e) => button.addEventListener("click", (e) =>
semanticButtonClickHandler(e, { textarea, label, blocking }) semanticButtonClickHandler(e, { textarea, label, blocking })
); );
@ -96,28 +101,28 @@ const buttonPairGenerator = (textarea, parent, label) => {
buttonContainer.classList.add("buttonContainer"); buttonContainer.classList.add("buttonContainer");
buttonGenerator(textarea, buttonContainer, label, false); buttonGenerator(textarea, buttonContainer, label, false);
if (semanticLabels[label].blocking) { if (semanticLabels[label].blocking) {
buttonContainer.classList.add("hasBlockingButton");
buttonGenerator(textarea, buttonContainer, label, true); buttonGenerator(textarea, buttonContainer, label, true);
} }
parent.appendChild(buttonContainer); parent.appendChild(buttonContainer);
}; };
const addSemanticButton = (element) => { const addSemanticButton = (element) => {
const parent = element.closest("div"); const parent = element.closest(".div-dropzone-wrapper").querySelector(".comment-toolbar");
const container = document.createElement("div"); const container = document.createElement("div");
container.id = "conventionalCommentButtonContainer"; container.id = "conventionalCommentButtonContainer";
Object.keys(semanticLabels).forEach((label) => { Object.keys(semanticLabels).forEach((label) => {
buttonPairGenerator(element, container, label); buttonPairGenerator(element, container, label);
}); });
parent.appendChild(container); parent.classList.remove("clearfix");
parent.classList.add('has-conventional-comments-buttons');
parent.prepend(container);
}; };
document.addEventListener("click", (e) => { setInterval(function () {
if ( document.querySelectorAll("#note_note:not([data-semantic-button-initialized]), #note-body:not([data-semantic-button-initialized])").forEach(function(note) {
(e.target.id === "note_note" || e.target.id === "note-body") && note.dataset.semanticButtonInitialized = "true";
!e.target.dataset.semanticButtonInitialized addSemanticButton(note);
) { });
e.target.dataset.semanticButtonInitialized = true; }, 1000);
addSemanticButton(e.target);
}
});