Spaces:
Running
Running
Render model dropdown as portal
Browse files- frontend/static/app.css +5 -9
- frontend/static/app.js +15 -1
frontend/static/app.css
CHANGED
|
@@ -136,10 +136,6 @@ button {
|
|
| 136 |
box-shadow: var(--surface-shadow);
|
| 137 |
}
|
| 138 |
|
| 139 |
-
.topbar:has(.model-dropdown.open) {
|
| 140 |
-
z-index: 20;
|
| 141 |
-
}
|
| 142 |
-
|
| 143 |
.brand {
|
| 144 |
display: flex;
|
| 145 |
align-items: center;
|
|
@@ -249,10 +245,10 @@ button {
|
|
| 249 |
}
|
| 250 |
|
| 251 |
.model-options {
|
| 252 |
-
position:
|
| 253 |
-
top:
|
| 254 |
-
right:
|
| 255 |
-
z-index:
|
| 256 |
display: grid;
|
| 257 |
gap: 4px;
|
| 258 |
min-width: 220px;
|
|
@@ -268,7 +264,7 @@ button {
|
|
| 268 |
transition: opacity 0.16s ease, transform 0.16s ease;
|
| 269 |
}
|
| 270 |
|
| 271 |
-
.model-
|
| 272 |
opacity: 1;
|
| 273 |
pointer-events: auto;
|
| 274 |
transform: translateY(0) scale(1);
|
|
|
|
| 136 |
box-shadow: var(--surface-shadow);
|
| 137 |
}
|
| 138 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
.brand {
|
| 140 |
display: flex;
|
| 141 |
align-items: center;
|
|
|
|
| 245 |
}
|
| 246 |
|
| 247 |
.model-options {
|
| 248 |
+
position: fixed;
|
| 249 |
+
top: var(--model-options-top, 64px);
|
| 250 |
+
right: var(--model-options-right, 16px);
|
| 251 |
+
z-index: 80;
|
| 252 |
display: grid;
|
| 253 |
gap: 4px;
|
| 254 |
min-width: 220px;
|
|
|
|
| 264 |
transition: opacity 0.16s ease, transform 0.16s ease;
|
| 265 |
}
|
| 266 |
|
| 267 |
+
.model-options.open {
|
| 268 |
opacity: 1;
|
| 269 |
pointer-events: auto;
|
| 270 |
transform: translateY(0) scale(1);
|
frontend/static/app.js
CHANGED
|
@@ -218,9 +218,17 @@
|
|
| 218 |
function closeModelDropdown() {
|
| 219 |
if (!modelDropdown || !modelDropdownButton) return;
|
| 220 |
modelDropdown.classList.remove("open");
|
|
|
|
| 221 |
modelDropdownButton.setAttribute("aria-expanded", "false");
|
| 222 |
}
|
| 223 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
function setModelValue(value) {
|
| 225 |
if (!modelSelect || !value) return;
|
| 226 |
modelSelect.value = value;
|
|
@@ -241,11 +249,14 @@
|
|
| 241 |
|
| 242 |
function setupModelDropdown() {
|
| 243 |
if (!modelDropdown || !modelDropdownButton || !modelOptions || !modelSelect) return;
|
|
|
|
| 244 |
setModelValue(modelSelect.value || "gpt-5.5");
|
| 245 |
modelDropdownButton.addEventListener("click", function () {
|
| 246 |
if (modelDropdownButton.disabled) return;
|
| 247 |
var shouldOpen = !modelDropdown.classList.contains("open");
|
|
|
|
| 248 |
modelDropdown.classList.toggle("open", shouldOpen);
|
|
|
|
| 249 |
modelDropdownButton.setAttribute("aria-expanded", shouldOpen ? "true" : "false");
|
| 250 |
});
|
| 251 |
modelOptions.querySelectorAll(".model-option").forEach(function (option) {
|
|
@@ -255,11 +266,14 @@
|
|
| 255 |
});
|
| 256 |
});
|
| 257 |
document.addEventListener("click", function (event) {
|
| 258 |
-
if (!modelDropdown.contains(event.target)) closeModelDropdown();
|
| 259 |
});
|
| 260 |
document.addEventListener("keydown", function (event) {
|
| 261 |
if (event.key === "Escape") closeModelDropdown();
|
| 262 |
});
|
|
|
|
|
|
|
|
|
|
| 263 |
}
|
| 264 |
|
| 265 |
function updateComposerMode() {
|
|
|
|
| 218 |
function closeModelDropdown() {
|
| 219 |
if (!modelDropdown || !modelDropdownButton) return;
|
| 220 |
modelDropdown.classList.remove("open");
|
| 221 |
+
if (modelOptions) modelOptions.classList.remove("open");
|
| 222 |
modelDropdownButton.setAttribute("aria-expanded", "false");
|
| 223 |
}
|
| 224 |
|
| 225 |
+
function positionModelOptions() {
|
| 226 |
+
if (!modelDropdownButton || !modelOptions) return;
|
| 227 |
+
var rect = modelDropdownButton.getBoundingClientRect();
|
| 228 |
+
modelOptions.style.setProperty("--model-options-top", Math.round(rect.bottom + 8) + "px");
|
| 229 |
+
modelOptions.style.setProperty("--model-options-right", Math.max(12, Math.round(window.innerWidth - rect.right)) + "px");
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
function setModelValue(value) {
|
| 233 |
if (!modelSelect || !value) return;
|
| 234 |
modelSelect.value = value;
|
|
|
|
| 249 |
|
| 250 |
function setupModelDropdown() {
|
| 251 |
if (!modelDropdown || !modelDropdownButton || !modelOptions || !modelSelect) return;
|
| 252 |
+
if (modelOptions.parentElement !== document.body) document.body.appendChild(modelOptions);
|
| 253 |
setModelValue(modelSelect.value || "gpt-5.5");
|
| 254 |
modelDropdownButton.addEventListener("click", function () {
|
| 255 |
if (modelDropdownButton.disabled) return;
|
| 256 |
var shouldOpen = !modelDropdown.classList.contains("open");
|
| 257 |
+
if (shouldOpen) positionModelOptions();
|
| 258 |
modelDropdown.classList.toggle("open", shouldOpen);
|
| 259 |
+
modelOptions.classList.toggle("open", shouldOpen);
|
| 260 |
modelDropdownButton.setAttribute("aria-expanded", shouldOpen ? "true" : "false");
|
| 261 |
});
|
| 262 |
modelOptions.querySelectorAll(".model-option").forEach(function (option) {
|
|
|
|
| 266 |
});
|
| 267 |
});
|
| 268 |
document.addEventListener("click", function (event) {
|
| 269 |
+
if (!modelDropdown.contains(event.target) && !modelOptions.contains(event.target)) closeModelDropdown();
|
| 270 |
});
|
| 271 |
document.addEventListener("keydown", function (event) {
|
| 272 |
if (event.key === "Escape") closeModelDropdown();
|
| 273 |
});
|
| 274 |
+
window.addEventListener("resize", function () {
|
| 275 |
+
if (modelDropdown.classList.contains("open")) positionModelOptions();
|
| 276 |
+
});
|
| 277 |
}
|
| 278 |
|
| 279 |
function updateComposerMode() {
|