Fix tab container logic bug (#2840)

# Description of Changes

Please provide a summary of the changes, including:

Overhauled logic for tab-containers on sign page to fix compatibility
issues with new Tooltip system

Closes #(2839)

---

## Checklist

### General

- [x ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ x] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md)
(if applicable)
- [ x] I have performed a self-review of my own code
- [x ] My changes generate no new warnings

### Documentation

- [ x] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ x] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ x] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing)
for more details.
This commit is contained in:
reecebrowne 2025-01-31 23:03:32 +00:00 committed by GitHub
parent b865f4379f
commit d9eda14521
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 28 additions and 30 deletions

View File

@ -43,37 +43,36 @@ function toolsManager() {
} }
window.tooltipSetup = () => { window.tooltipSetup = () => {
const tooltipElements = document.querySelectorAll("[title]"); const tooltipElements = document.querySelectorAll('[title]');
tooltipElements.forEach((element) => { tooltipElements.forEach((element) => {
const tooltipText = element.getAttribute("title"); const tooltipText = element.getAttribute('title');
element.removeAttribute("title"); element.removeAttribute('title');
element.setAttribute('data-title, tooltipText');
const customTooltip = document.createElement("div"); const customTooltip = document.createElement('div');
customTooltip.className = "btn-tooltip"; customTooltip.className = 'btn-tooltip';
customTooltip.textContent = tooltipText; customTooltip.textContent = tooltipText;
document.body.appendChild(customTooltip); document.body.appendChild(customTooltip);
element.addEventListener("mouseenter", (event) => { element.addEventListener('mouseenter', (event) => {
customTooltip.style.display = "block"; customTooltip.style.display = 'block';
customTooltip.style.left = `${event.pageX + 10}px`; // Position tooltip slightly away from the cursor customTooltip.style.left = `${event.pageX + 10}px`; // Position tooltip slightly away from the cursor
customTooltip.style.top = `${event.pageY + 10}px`; customTooltip.style.top = `${event.pageY + 10}px`;
}); });
// Update the position of the tooltip as the user moves the mouse // Update the position of the tooltip as the user moves the mouse
element.addEventListener("mousemove", (event) => { element.addEventListener('mousemove', (event) => {
customTooltip.style.left = `${event.pageX + 10}px`; customTooltip.style.left = `${event.pageX + 10}px`;
customTooltip.style.top = `${event.pageY + 10}px`; customTooltip.style.top = `${event.pageY + 10}px`;
}); });
// Hide the tooltip when the mouse leaves // Hide the tooltip when the mouse leaves
element.addEventListener("mouseleave", () => { element.addEventListener('mouseleave', () => {
customTooltip.style.display = "none"; customTooltip.style.display = 'none';
}); });
}); });
} };
document.addEventListener("DOMContentLoaded", () => { document.addEventListener('DOMContentLoaded', () => {
tooltipSetup(); tooltipSetup();
}); });

View File

@ -1,15 +1,14 @@
TabContainer = { TabContainer = {
initTabGroups() { initTabGroups() {
const groups = document.querySelectorAll(".tab-group"); const groups = document.querySelectorAll('.tab-group');
const unloadedGroups = [...groups].filter((g) => !g.initialised); const unloadedGroups = [...groups].filter((g) => !g.initialised);
unloadedGroups.forEach((group) => { unloadedGroups.forEach((group) => {
const containers = group.querySelectorAll(".tab-container"); const containers = group.querySelectorAll('.tab-container');
const tabTitles = [...containers].map((c) => c.getAttribute("title")); const tabTitles = [...containers].map((c) => c.getAttribute('data-title'));
const tabList = document.createElement('div');
const tabList = document.createElement("div"); tabList.classList.add('tab-buttons');
tabList.classList.add("tab-buttons");
tabTitles.forEach((title) => { tabTitles.forEach((title) => {
const tabButton = document.createElement("button"); const tabButton = document.createElement('button');
tabButton.innerHTML = title; tabButton.innerHTML = title;
tabButton.onclick = (e) => { tabButton.onclick = (e) => {
this.setActiveTab(e.target); this.setActiveTab(e.target);
@ -24,15 +23,15 @@ TabContainer = {
}); });
}, },
setActiveTab(tabButton) { setActiveTab(tabButton) {
const group = tabButton.closest(".tab-group"); const group = tabButton.closest('.tab-group');
group.querySelectorAll(".active").forEach((el) => el.classList.remove("active")); group.querySelectorAll('.active').forEach((el) => el.classList.remove('active'));
tabButton.classList.add("active"); tabButton.classList.add('active');
group.querySelector(`[title="${tabButton.innerHTML}"]`).classList.add("active"); group.querySelector(`[data-title="${tabButton.innerHTML}"]`).classList.add('active');
}, },
}; };
document.addEventListener("DOMContentLoaded", () => { document.addEventListener('DOMContentLoaded', () => {
TabContainer.initTabGroups(); TabContainer.initTabGroups();
}); });

View File

@ -43,13 +43,13 @@
</div> </div>
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script> <script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
<div class="tab-group show-on-file-selected"> <div class="tab-group show-on-file-selected">
<div class="tab-container" th:title="#{sign.upload}"> <div class="tab-container" th:title="#{sign.upload}" th:data-title="#{sign.upload}">
<div <div
th:replace="~{fragments/common :: fileSelector(name='image-upload', disableMultipleFiles=false, multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}"> th:replace="~{fragments/common :: fileSelector(name='image-upload', disableMultipleFiles=false, multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}">
</div> </div>
</div> </div>
<div class="tab-container drawing-pad-container" th:title="#{sign.draw}"> <div class="tab-container drawing-pad-container" th:title="#{sign.draw}" th:data-title="#{sign.draw}">
<canvas id="drawing-pad-canvas"></canvas> <canvas id="drawing-pad-canvas"></canvas>
<br> <br>
<button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()" <button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()"
@ -58,7 +58,7 @@
th:text="#{sign.add}"></button> th:text="#{sign.add}"></button>
</div> </div>
<div class="tab-container" th:title="#{sign.saved}"> <div class="tab-container" th:title="#{sign.saved}" th:data-title="#{sign.saved}">
<div class="saved-signatures-section" th:if="${not #lists.isEmpty(signatures)}"> <div class="saved-signatures-section" th:if="${not #lists.isEmpty(signatures)}">
<!-- Preview Modal --> <!-- Preview Modal -->
@ -130,7 +130,7 @@
</div> </div>
</div> </div>
<div class="tab-container" th:title="#{sign.text}"> <div class="tab-container" th:title="#{sign.text}" th:data-title="#{sign.text}">
<label class="form-check-label" for="sigText" th:text="#{text}"></label> <label class="form-check-label" for="sigText" th:text="#{text}"></label>
<textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea> <textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea>
<label th:text="#{font}"></label> <label th:text="#{font}"></label>