fix(web): make the armed stop press legible without hover
The armed state relied on a color swap through --dsw-alias-label-error, a token the themes never define, so the confirm step was effectively invisible. The first press now widens the button into a labeled danger pill (确认停止 / Confirm stop) tinted with the real state-error token StateDot uses; the stream-failure notice moves off the same phantom token. Component spec pins the inline label.
This commit is contained in:
1 parent
8f3103b511
commit
bb1d472e94
4 files changed
+22
-4
No files matched your search
@@ -119,15 +119,26 @@
|
||||
color: var(--dsw-alias-label-secondary);
|
||||
}
|
||||
|
||||
/* The armed press widens into a labeled danger pill so the confirm step is
|
||||
legible without hover; the state-error token is the one StateDot uses. */
|
||||
.stopArmed,
|
||||
.stopArmed:hover,
|
||||
.stopArmed:focus-visible {
|
||||
background: var(--dsw-alias-fill-l1);
|
||||
color: var(--dsw-alias-label-error, var(--dsw-alias-label-secondary));
|
||||
gap: 4px;
|
||||
width: auto;
|
||||
padding: 0 8px;
|
||||
background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent);
|
||||
color: var(--dsw-alias-state-error-primary);
|
||||
}
|
||||
|
||||
.stopLabel {
|
||||
font-size: 11px;
|
||||
line-height: 18px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.stopFailed {
|
||||
color: var(--dsw-alias-label-error, var(--dsw-alias-label-secondary));
|
||||
color: var(--dsw-alias-state-error-primary);
|
||||
}
|
||||
|
||||
.row {
|
||||
@@ -268,5 +279,5 @@
|
||||
}
|
||||
|
||||
.noticeError {
|
||||
color: var(--dsw-alias-label-error, var(--dsw-alias-label-secondary));
|
||||
color: var(--dsw-alias-state-error-primary);
|
||||
}
|
||||
@@ -329,6 +329,9 @@ function TaskItem({ row, view, expanded, now, onToggle, kill, t }: {
|
||||
onClick={kill.onPress}
|
||||
>
|
||||
<IconStopFill16 size={12} />
|
||||
{/* The armed press must be legible without hover: the button
|
||||
widens into a labeled confirm pill instead of a tint only. */}
|
||||
{kill.state === 'armed' ? <span className={css.stopLabel}>{t('kill.confirmAction')}</span> : null}
|
||||
</button>
|
||||
)
|
||||
: null}
|
||||
|
||||
@@ -16,6 +16,7 @@ export const zh = {
|
||||
'row.collapseAria': '收起 {label} 的实时输出',
|
||||
'kill.stop': '停止任务 {label}',
|
||||
'kill.confirm': '再次点击确认停止',
|
||||
'kill.confirmAction': '确认停止',
|
||||
'kill.failed': '停止失败',
|
||||
'status.running': '运行中',
|
||||
'status.stopping': '正在停止',
|
||||
@@ -56,6 +57,7 @@ export const en: Record<ActivityKey, string> = {
|
||||
'row.collapseAria': 'Hide live output of {label}',
|
||||
'kill.stop': 'Stop task {label}',
|
||||
'kill.confirm': 'Click again to confirm',
|
||||
'kill.confirmAction': 'Confirm stop',
|
||||
'kill.failed': 'Stop failed',
|
||||
'status.running': 'running',
|
||||
'status.stopping': 'stopping',
|
||||
|
||||
@@ -405,6 +405,8 @@ describe('ActivityListAction human kill', () => {
|
||||
expect(killJob).not.toHaveBeenCalled()
|
||||
expect(stop.getAttribute('data-kill-state')).toBe('armed')
|
||||
expect(screen.getByTitle(zh['kill.confirm'])).toBe(stop)
|
||||
// The armed step is legible without hover: the button carries the label.
|
||||
expect(stop.textContent).toBe(zh['kill.confirmAction'])
|
||||
await act(async () => { fireEvent.click(stop) })
|
||||
expect(killJob).toHaveBeenCalledWith(SESSION, 'bash-1')
|
||||
// An admitted kill stays pending: the unary response and the jobs frames
|
||||
|
||||
Reference in new issue
Block a user