Files
deepseek-harness/packages/client/ui-primitives/src/ConnectionIndicator.module.css
T
mektpoy bca9cecc7d fix(client): keep pointer focus silent through descendant and editable rings
Pointer suppression previously cleared `outline-color` on the focused element
alone, so a ring painted by a descendant, a pseudo-element, or a `box-shadow`
stayed visible, and editable text controls lost the focus feedback they need on
click.

Ring colour now flows through `--dsw-focus-ring-color`, which component outlines
and focus-ring shadows read alongside the brand token. Every ring that inherits
the variable is suppressed together, and `body :focus-visible:not(:read-write)`
limits the suppression to rings while editable controls keep their own feedback.

Keyboard modality returns on Tab, Home, End, PageUp, or PageDown, and on focus
reaching a different control after a non-composing key. IME composition keys,
refocusing the same control, and window blur leave rings silent. The desktop
preload menubar suppresses its own ring inside its shadow root, where the
document-level attribute does not reach.
2026-09-22 20:28:10 +08:00

115 lines
2.1 KiB
CSS

.indicator {
flex: none;
display: inline-grid;
grid-template-columns: 14px max-content;
align-items: center;
column-gap: 4px;
height: 28px;
padding: 0 8px;
box-sizing: border-box;
border: 1px solid transparent;
border-radius: 13px;
font-family: inherit;
font-size: 12px;
font-weight: 500;
line-height: 18px;
white-space: nowrap;
transition:
background-color 160ms ease-out,
color 160ms ease-out,
border-color 160ms ease-out,
opacity 150ms ease-out;
animation: indicator-enter 150ms ease-out;
}
.leaving {
opacity: 0;
}
@keyframes indicator-enter {
from {
opacity: 0;
}
}
.warning {
background: var(--dsw-alias-state-warn-tertiary);
color: var(--dsw-alias-state-warn-label);
border-color: color-mix(in srgb, var(--dsw-alias-state-warn-label) 20%, transparent);
cursor: pointer;
}
.warning:hover {
background: color-mix(
in srgb,
var(--dsw-alias-state-warn-tertiary),
var(--dsw-alias-state-warn-primary) 6%
);
}
.warning:active {
background: color-mix(
in srgb,
var(--dsw-alias-state-warn-tertiary),
var(--dsw-alias-state-warn-primary) 10%
);
}
.warning:focus-visible {
outline: var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-brand-primary));
outline-offset: 2px;
}
.success {
background: var(--dsw-alias-state-success-tertiary);
color: var(--dsw-alias-state-success-primary);
border-color: color-mix(in srgb, var(--dsw-alias-state-success-primary) 20%, transparent);
}
.icon {
display: grid;
place-items: center;
width: 14px;
height: 14px;
}
.label {
text-align: left;
}
.dots {
display: inline-block;
width: 1em;
text-align: left;
}
.secondDot {
animation: reveal-second-dot 1.5s step-end infinite;
}
.thirdDot {
animation: reveal-third-dot 1.5s step-end infinite;
}
@keyframes reveal-second-dot {
0%, 33.32% { opacity: 0; }
33.33%, 100% { opacity: 1; }
}
@keyframes reveal-third-dot {
0%, 66.65% { opacity: 0; }
66.66%, 100% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
.indicator,
.secondDot,
.thirdDot {
animation: none;
}
.indicator {
transition: none;
}
}