added style for select

This commit is contained in:
olcxja 2026-08-22 09:22:22 +02:00
commit c0a645b4e5
6 changed files with 268 additions and 24 deletions

View file

@ -4364,19 +4364,41 @@ async function switchSettingsTab(tabName) {
}
async function populateLanguageDropdown() {
let sel = document.getElementById("settings-language");
if (!sel) return;
let container = document.getElementById("settings-language");
let optionsContainer = document.getElementById("settings-language-options");
let display = document.getElementById("settings-language-display");
if (!container || !optionsContainer || !display) return;
try {
let path = window.location.pathname.replace("/login/index.html", "/").replace("index.html", "");
let res = await fetchAsync(`${path}blah/index.json`);
let json = JSON.parse(res);
sel.innerHTML = "";
optionsContainer.innerHTML = "";
window._langDropdownListener = window._langDropdownListener || ((e) => {
let cont = document.getElementById("settings-language");
if (cont && !cont.contains(e.target)) {
cont.classList.remove('open');
}
});
document.removeEventListener('click', window._langDropdownListener);
document.addEventListener('click', window._langDropdownListener);
for (let code in json) {
let opt = document.createElement("option");
opt.value = code;
opt.textContent = json[code].native + " (" + json[code].english + ")";
if (code === lang) opt.selected = true;
sel.appendChild(opt);
let opt = document.createElement("div");
opt.className = "custom-select-option";
let text = json[code].native + " (" + json[code].english + ")";
opt.textContent = text;
if (code === lang) {
opt.classList.add("selected");
display.textContent = text;
display.classList.remove("blah");
}
opt.onclick = () => {
display.textContent = text;
container.classList.remove("open");
changeLanguage(code);
};
optionsContainer.appendChild(opt);
}
} catch (e) {
console.error("Failed to load languages", e);

View file

@ -415,10 +415,15 @@ var appearanceSettings = `
<herotitle><blah>title.appearance</blah></herotitle>
<br>
<div class="input-group">
<label for="settings-language"><blah>title.language</blah></label>
<select id="settings-language" onchange="changeLanguage(this.value)" style="border-radius: 0.8rem; background-color: rgba(255, 255, 255, 0.05); margin: var(--button-margin); padding: var(--button-margin); padding-left: calc(var(--button-margin) * 2); padding-right: 1.5rem; height: var(--button-height); display: flex; cursor: pointer; align-items: center; justify-content: flex-start; border: var(--border-width) solid var(--light-border-color); color: var(--text-color); font-family: inherit; font-size: inherit; appearance: none; outline: none;">
<option value="" class="blah">title.loading</option>
</select>
<label><blah>title.language</blah></label>
<div class="custom-select" id="settings-language">
<div class="custom-select-value" onclick="this.parentElement.classList.toggle('open')">
<span id="settings-language-display" class="blah">title.loading</span>
${ICONS.chevronDown({ className: "chevron", style: "width: 1.2rem; height: 1.2rem; opacity: 0.7;" })}
</div>
<div class="custom-select-options" id="settings-language-options">
</div>
</div>
</div>
</div>
`;

View file

@ -1181,3 +1181,98 @@ input:checked + .toggle-slider:before {
0% { transform: scale(0); }
100% { transform: scale(1); }
}
/* Custom Select */
.custom-select {
position: relative;
border-radius: 0.8rem;
background-color: rgba(255, 255, 255, 0.05);
margin: var(--button-margin);
height: var(--button-height);
display: flex;
cursor: pointer;
align-items: center;
border: var(--border-width) solid var(--light-border-color);
color: var(--text-color);
width: calc(100% - (var(--button-margin) * 2));
outline: none;
user-select: none;
z-index: 2; /* to appear above other elements if necessary */
}
.custom-select-value {
padding: var(--button-margin);
padding-left: calc(var(--button-margin) * 2);
padding-right: 1.5rem;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
.custom-select-value span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.custom-select .chevron {
transition: transform 0.2s ease;
}
.custom-select.open .chevron {
transform: rotate(180deg);
}
.custom-select-options {
position: absolute;
top: calc(100% + 0.4rem);
left: 0;
width: 100%;
background-color: var(--main-bg-color);
border: var(--border-width) solid var(--light-border-color);
border-radius: 0.8rem;
max-height: 15rem;
overflow-y: auto;
z-index: 100;
opacity: 0;
visibility: hidden;
transform: translateY(-10px);
transition: all 0.2s ease;
box-shadow: 0 4px 12px rgba(0,0,0,0.5);
padding: 0.4rem;
pointer-events: none;
}
.custom-select.open .custom-select-options {
opacity: 1;
visibility: visible;
transform: translateY(0);
pointer-events: auto;
}
.custom-select-option {
padding: var(--button-margin) calc(var(--button-margin) * 2);
height: var(--button-height);
display: flex;
align-items: center;
border-radius: 0.8rem;
background-color: transparent;
cursor: pointer;
transition: background-color 0.2s;
text-align: left;
margin-bottom: 0.2rem;
}
.custom-select-option:last-child {
margin-bottom: 0;
}
.custom-select-option:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.custom-select-option.selected {
background-color: rgba(255, 255, 255, 0.15);
font-weight: bold;
}

View file

@ -4364,19 +4364,41 @@ async function switchSettingsTab(tabName) {
}
async function populateLanguageDropdown() {
let sel = document.getElementById("settings-language");
if (!sel) return;
let container = document.getElementById("settings-language");
let optionsContainer = document.getElementById("settings-language-options");
let display = document.getElementById("settings-language-display");
if (!container || !optionsContainer || !display) return;
try {
let path = window.location.pathname.replace("/login/index.html", "/").replace("index.html", "");
let res = await fetchAsync(`${path}blah/index.json`);
let json = JSON.parse(res);
sel.innerHTML = "";
optionsContainer.innerHTML = "";
window._langDropdownListener = window._langDropdownListener || ((e) => {
let cont = document.getElementById("settings-language");
if (cont && !cont.contains(e.target)) {
cont.classList.remove('open');
}
});
document.removeEventListener('click', window._langDropdownListener);
document.addEventListener('click', window._langDropdownListener);
for (let code in json) {
let opt = document.createElement("option");
opt.value = code;
opt.textContent = json[code].native + " (" + json[code].english + ")";
if (code === lang) opt.selected = true;
sel.appendChild(opt);
let opt = document.createElement("div");
opt.className = "custom-select-option";
let text = json[code].native + " (" + json[code].english + ")";
opt.textContent = text;
if (code === lang) {
opt.classList.add("selected");
display.textContent = text;
display.classList.remove("blah");
}
opt.onclick = () => {
display.textContent = text;
container.classList.remove("open");
changeLanguage(code);
};
optionsContainer.appendChild(opt);
}
} catch (e) {
console.error("Failed to load languages", e);

View file

@ -415,10 +415,15 @@ var appearanceSettings = `
<herotitle><blah>title.appearance</blah></herotitle>
<br>
<div class="input-group">
<label for="settings-language"><blah>title.language</blah></label>
<select id="settings-language" onchange="changeLanguage(this.value)" style="border-radius: 0.8rem; background-color: rgba(255, 255, 255, 0.05); margin: var(--button-margin); padding: var(--button-margin); padding-left: calc(var(--button-margin) * 2); padding-right: 1.5rem; height: var(--button-height); display: flex; cursor: pointer; align-items: center; justify-content: flex-start; border: var(--border-width) solid var(--light-border-color); color: var(--text-color); font-family: inherit; font-size: inherit; appearance: none; outline: none;">
<option value="" class="blah">title.loading</option>
</select>
<label><blah>title.language</blah></label>
<div class="custom-select" id="settings-language">
<div class="custom-select-value" onclick="this.parentElement.classList.toggle('open')">
<span id="settings-language-display" class="blah">title.loading</span>
${ICONS.chevronDown({ className: "chevron", style: "width: 1.2rem; height: 1.2rem; opacity: 0.7;" })}
</div>
<div class="custom-select-options" id="settings-language-options">
</div>
</div>
</div>
</div>
`;

View file

@ -1181,3 +1181,98 @@ input:checked + .toggle-slider:before {
0% { transform: scale(0); }
100% { transform: scale(1); }
}
/* Custom Select */
.custom-select {
position: relative;
border-radius: 0.8rem;
background-color: rgba(255, 255, 255, 0.05);
margin: var(--button-margin);
height: var(--button-height);
display: flex;
cursor: pointer;
align-items: center;
border: var(--border-width) solid var(--light-border-color);
color: var(--text-color);
width: calc(100% - (var(--button-margin) * 2));
outline: none;
user-select: none;
z-index: 2; /* to appear above other elements if necessary */
}
.custom-select-value {
padding: var(--button-margin);
padding-left: calc(var(--button-margin) * 2);
padding-right: 1.5rem;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
.custom-select-value span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.custom-select .chevron {
transition: transform 0.2s ease;
}
.custom-select.open .chevron {
transform: rotate(180deg);
}
.custom-select-options {
position: absolute;
top: calc(100% + 0.4rem);
left: 0;
width: 100%;
background-color: var(--main-bg-color);
border: var(--border-width) solid var(--light-border-color);
border-radius: 0.8rem;
max-height: 15rem;
overflow-y: auto;
z-index: 100;
opacity: 0;
visibility: hidden;
transform: translateY(-10px);
transition: all 0.2s ease;
box-shadow: 0 4px 12px rgba(0,0,0,0.5);
padding: 0.4rem;
pointer-events: none;
}
.custom-select.open .custom-select-options {
opacity: 1;
visibility: visible;
transform: translateY(0);
pointer-events: auto;
}
.custom-select-option {
padding: var(--button-margin) calc(var(--button-margin) * 2);
height: var(--button-height);
display: flex;
align-items: center;
border-radius: 0.8rem;
background-color: transparent;
cursor: pointer;
transition: background-color 0.2s;
text-align: left;
margin-bottom: 0.2rem;
}
.custom-select-option:last-child {
margin-bottom: 0;
}
.custom-select-option:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.custom-select-option.selected {
background-color: rgba(255, 255, 255, 0.15);
font-weight: bold;
}