black-yt commited on
Commit
11d2469
·
1 Parent(s): 4996a87

Render model dropdown as portal

Browse files
Files changed (2) hide show
  1. frontend/static/app.css +5 -9
  2. 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: absolute;
253
- top: calc(100% + 8px);
254
- right: 0;
255
- z-index: 30;
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-dropdown.open .model-options {
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() {