mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-11-09 20:07:43 +08:00
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.
60 lines
2.0 KiB
TypeScript
60 lines
2.0 KiB
TypeScript
/**
|
|
* Document-wide input tracking shared by tooltips and focus-ring styles.
|
|
* Tooltips follow the last input; rings follow navigation or a key followed by
|
|
* focus on a different control. Modifiers and refocusing alone keep rings silent.
|
|
* Module-level listeners live for the document lifetime; Node imports are inert.
|
|
*/
|
|
|
|
/** Modality values published on the document element. */
|
|
export const INPUT_MODALITY = { pointer: 'pointer', keyboard: 'keyboard' } as const
|
|
|
|
/** Attribute carrying whether focus navigation last owned focus. */
|
|
export const INPUT_MODALITY_ATTRIBUTE = 'data-input-modality'
|
|
|
|
const FOCUS_NAVIGATION = new Set(['Tab', 'Home', 'End', 'PageUp', 'PageDown'])
|
|
|
|
let pointer = false
|
|
let pointerOwnsFocus = false
|
|
let keyFocusOrigin: EventTarget | undefined
|
|
|
|
function publish(): void {
|
|
document.documentElement.setAttribute(INPUT_MODALITY_ATTRIBUTE, pointerOwnsFocus ? INPUT_MODALITY.pointer : INPUT_MODALITY.keyboard)
|
|
}
|
|
|
|
/**
|
|
* Whether the last input came from a pointer, independently of ring visibility.
|
|
* @returns True after pointer input; false after any key.
|
|
*/
|
|
export function pointerModality(): boolean {
|
|
return pointer
|
|
}
|
|
|
|
if (typeof window !== 'undefined') {
|
|
window.addEventListener('pointerdown', () => {
|
|
pointer = true
|
|
pointerOwnsFocus = true
|
|
keyFocusOrigin = undefined
|
|
publish()
|
|
}, true)
|
|
window.addEventListener('keydown', (event) => {
|
|
pointer = false
|
|
if (event.isComposing) {
|
|
keyFocusOrigin = undefined
|
|
return
|
|
}
|
|
// composedPath preserves the real control inside an open shadow root.
|
|
keyFocusOrigin = event.composedPath()[0]
|
|
if (!FOCUS_NAVIGATION.has(event.key) && !event.key.startsWith('Arrow')) return
|
|
pointerOwnsFocus = false
|
|
publish()
|
|
}, true)
|
|
window.addEventListener('focusin', (event) => {
|
|
if (keyFocusOrigin === undefined || event.composedPath()[0] === keyFocusOrigin) return
|
|
keyFocusOrigin = undefined
|
|
if (!pointerOwnsFocus) return
|
|
pointerOwnsFocus = false
|
|
publish()
|
|
}, true)
|
|
window.addEventListener('blur', () => { keyFocusOrigin = undefined })
|
|
}
|