mirror of
https://github.com/nexu-io/open-design.git
synced 2026-05-31 19:04:39 +07:00
fix(web): use wrapper+icon pattern for agent model select to fix duplicate chevrons (#1831)
Some checks failed
ci / Packaged mac smoke (push) Blocked by required conditions
ci / Packaged windows smoke (push) Blocked by required conditions
ci / Detect PR change scopes (push) Failing after 3s
ci / Validate workspace (push) Has been skipped
Docker image / build-and-push (push) Failing after 12s
nix-check / build (push) Failing after 2s
ci / Packaged linux headless smoke (push) Has been skipped
Some checks failed
ci / Packaged mac smoke (push) Blocked by required conditions
ci / Packaged windows smoke (push) Blocked by required conditions
ci / Detect PR change scopes (push) Failing after 3s
ci / Validate workspace (push) Has been skipped
Docker image / build-and-push (push) Failing after 12s
nix-check / build (push) Failing after 2s
ci / Packaged linux headless smoke (push) Has been skipped
Native macOS browser sometimes renders its own disclosure indicator even with appearance:none, stacking it on top of the CSS background-image SVG chevron. Apply the same orbit-template-select-wrap pattern: clear the background-image via explicit wrapper class, use an absolutely-positioned Icon component for a single, controlled chevron. Affects both the model picker and reasoning picker selects in the agent-model-row.
This commit is contained in:
parent
9a64fccdc0
commit
1896c699a8
2 changed files with 70 additions and 52 deletions
|
|
@ -2185,47 +2185,40 @@ export function SettingsDialog({
|
|||
<span className="field-label">
|
||||
{t('settings.modelPicker')}
|
||||
</span>
|
||||
<select
|
||||
value={selectValue}
|
||||
onChange={(e) => {
|
||||
if (e.target.value === CUSTOM_MODEL_SENTINEL) {
|
||||
// Switching to "Custom…" should clear the
|
||||
// value so the input below opens empty for
|
||||
// typing. Keep an explicit edit-mode flag so
|
||||
// intermediate values like `gpt-5` do not
|
||||
// collapse the custom input while typing
|
||||
// `gpt-5.5`.
|
||||
setAgentCustomModelIds((prev) => {
|
||||
const next = new Set(prev);
|
||||
next.add(selected.id);
|
||||
return next;
|
||||
});
|
||||
setChoice({ model: '' });
|
||||
} else {
|
||||
setAgentCustomModelIds((prev) => {
|
||||
if (!prev.has(selected.id)) return prev;
|
||||
const next = new Set(prev);
|
||||
next.delete(selected.id);
|
||||
return next;
|
||||
});
|
||||
setChoice({ model: e.target.value });
|
||||
}
|
||||
}}
|
||||
>
|
||||
{renderModelOptions(selected.models!)}
|
||||
<option value={CUSTOM_MODEL_SENTINEL}>
|
||||
{t('settings.modelCustom')}
|
||||
</option>
|
||||
</select>
|
||||
<div className="agent-model-select-wrap">
|
||||
<select
|
||||
value={selectValue}
|
||||
onChange={(e) => {
|
||||
if (e.target.value === CUSTOM_MODEL_SENTINEL) {
|
||||
setAgentCustomModelIds((prev) => {
|
||||
const next = new Set(prev);
|
||||
next.add(selected.id);
|
||||
return next;
|
||||
});
|
||||
setChoice({ model: '' });
|
||||
} else {
|
||||
setAgentCustomModelIds((prev) => {
|
||||
if (!prev.has(selected.id)) return prev;
|
||||
const next = new Set(prev);
|
||||
next.delete(selected.id);
|
||||
return next;
|
||||
});
|
||||
setChoice({ model: e.target.value });
|
||||
}
|
||||
}}
|
||||
>
|
||||
{renderModelOptions(selected.models!)}
|
||||
<option value={CUSTOM_MODEL_SENTINEL}>
|
||||
{t('settings.modelCustom')}
|
||||
</option>
|
||||
</select>
|
||||
<Icon
|
||||
name="chevron-down"
|
||||
size={12}
|
||||
className="agent-model-select-chevron"
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
{/*
|
||||
Hint sits with its own field so the user reads
|
||||
"Default vs Custom…" right next to the dropdown
|
||||
that exposes those options. Older layouts parked
|
||||
this paragraph at the bottom of the section, past
|
||||
the Memory picker, where it got mistaken for
|
||||
memory documentation.
|
||||
*/}
|
||||
<p className="hint agent-model-row-hint">
|
||||
{t('settings.modelPickerHint')}
|
||||
</p>
|
||||
|
|
@ -2251,18 +2244,25 @@ export function SettingsDialog({
|
|||
<span className="field-label">
|
||||
{t('settings.reasoningPicker')}
|
||||
</span>
|
||||
<select
|
||||
value={reasoningValue}
|
||||
onChange={(e) =>
|
||||
setChoice({ reasoning: e.target.value })
|
||||
}
|
||||
>
|
||||
{selected.reasoningOptions!.map((r) => (
|
||||
<option key={r.id} value={r.id}>
|
||||
{r.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<div className="agent-model-select-wrap">
|
||||
<select
|
||||
value={reasoningValue}
|
||||
onChange={(e) =>
|
||||
setChoice({ reasoning: e.target.value })
|
||||
}
|
||||
>
|
||||
{selected.reasoningOptions!.map((r) => (
|
||||
<option key={r.id} value={r.id}>
|
||||
{r.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<Icon
|
||||
name="chevron-down"
|
||||
size={12}
|
||||
className="agent-model-select-chevron"
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
) : null}
|
||||
<MemoryModelInline
|
||||
|
|
|
|||
|
|
@ -5007,6 +5007,24 @@ a.avatar-item:visited {
|
|||
color: var(--text-muted);
|
||||
}
|
||||
.agent-model-row .hint { margin: 0; font-size: 11.5px; }
|
||||
.agent-model-select-wrap {
|
||||
position: relative;
|
||||
}
|
||||
.agent-model-select-wrap select {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
background-image: none;
|
||||
padding-right: 28px;
|
||||
width: 100%;
|
||||
}
|
||||
.agent-model-select-chevron {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--text-soft);
|
||||
pointer-events: none;
|
||||
}
|
||||
.agent-cli-env {
|
||||
padding: 10px 12px;
|
||||
border: 1px solid var(--border-soft);
|
||||
|
|
|
|||
Loading…
Reference in a new issue