fix(desktop): stabilize provider list cards

This commit is contained in:
apale7 2026-04-20 02:45:26 +08:00
parent f3de590e1b
commit a9448125f1
2 changed files with 32 additions and 6 deletions

View File

@ -772,6 +772,14 @@ export default function App() {
} }
} }
function onResourceCardKeyDown(event: KeyboardEvent<HTMLElement>, onActivate: () => void) {
if (event.key !== 'Enter' && event.key !== ' ') {
return
}
event.preventDefault()
onActivate()
}
async function onSavePrefs(event: FormEvent) { async function onSavePrefs(event: FormEvent) {
event.preventDefault() event.preventDefault()
setPrefsStatus(i18n.t('messages.saving')) setPrefsStatus(i18n.t('messages.saving'))
@ -1375,11 +1383,13 @@ export default function App() {
</article> </article>
) : null} ) : null}
{filteredProviders.map((provider) => ( {filteredProviders.map((provider) => (
<button <article
key={provider.id} key={provider.id}
type="button"
className={`resource-card ${providerDetailOpen && selectedProviderId === provider.id ? 'active' : ''}`} className={`resource-card ${providerDetailOpen && selectedProviderId === provider.id ? 'active' : ''}`}
role="button"
tabIndex={0}
onClick={() => onEditProvider(provider)} onClick={() => onEditProvider(provider)}
onKeyDown={(event) => onResourceCardKeyDown(event, () => onEditProvider(provider))}
> >
<div className="resource-card-top"> <div className="resource-card-top">
<div className="resource-card-heading"> <div className="resource-card-heading">
@ -1409,7 +1419,7 @@ export default function App() {
<span className="resource-meta-value">{provider.apiKeyMasked || t('providers.apiKeyNotSet')}</span> <span className="resource-meta-value">{provider.apiKeyMasked || t('providers.apiKeyNotSet')}</span>
</div> </div>
</div> </div>
</button> </article>
))} ))}
</div> </div>
</article> </article>
@ -1490,11 +1500,13 @@ export default function App() {
</article> </article>
) : null} ) : null}
{filteredAliases.map((alias) => ( {filteredAliases.map((alias) => (
<button <article
key={alias.alias} key={alias.alias}
type="button"
className={`resource-card ${aliasDetailOpen && selectedAliasId === alias.alias ? 'active' : ''}`} className={`resource-card ${aliasDetailOpen && selectedAliasId === alias.alias ? 'active' : ''}`}
role="button"
tabIndex={0}
onClick={() => onEditAlias(alias)} onClick={() => onEditAlias(alias)}
onKeyDown={(event) => onResourceCardKeyDown(event, () => onEditAlias(alias))}
> >
<div className="resource-card-top"> <div className="resource-card-top">
<div className="resource-card-heading"> <div className="resource-card-heading">
@ -1530,7 +1542,7 @@ export default function App() {
</span> </span>
</div> </div>
</div> </div>
</button> </article>
))} ))}
</div> </div>
</article> </article>

View File

@ -845,12 +845,16 @@ html[data-theme='dark'] button.ghost-danger:hover {
display: grid; display: grid;
gap: 0.88rem; gap: 0.88rem;
width: 100%; width: 100%;
min-height: auto;
height: auto;
padding: 1rem 1.05rem; padding: 1rem 1.05rem;
border: 1px solid var(--border); border: 1px solid var(--border);
border-radius: 20px; border-radius: 20px;
background: var(--panel); background: var(--panel);
text-align: left; text-align: left;
box-shadow: none; box-shadow: none;
align-content: start;
overflow: visible;
transition: transition:
border-color 160ms ease, border-color 160ms ease,
background 160ms ease, background 160ms ease,
@ -858,6 +862,15 @@ html[data-theme='dark'] button.ghost-danger:hover {
transform 160ms ease; transform 160ms ease;
} }
.resource-card[role='button'] {
cursor: pointer;
}
.resource-card[role='button']:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.resource-card:hover { .resource-card:hover {
border-color: var(--border-strong); border-color: var(--border-strong);
box-shadow: var(--shadow-md); box-shadow: var(--shadow-md);
@ -934,6 +947,7 @@ html[data-theme='dark'] button.ghost-danger:hover {
display: grid; display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 0.7rem; gap: 0.7rem;
align-items: stretch;
} }
.resource-meta-item { .resource-meta-item {