@cueloop/client 0.1.0-alpha.61 → 0.1.0-alpha.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/src/prototype-browser.ts +15 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cueloop/client",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.63",
|
|
4
4
|
"description": "The cueloop review UI: projection renderer, keyboard grammar, review rail",
|
|
5
5
|
"homepage": "https://github.com/mmurakaru/cueloop#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"access": "public"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@cueloop/daemon": "0.1.0-alpha.
|
|
30
|
-
"@cueloop/extension-api": "0.1.0-alpha.
|
|
31
|
-
"@cueloop/integration-obsidian": "0.1.0-alpha.
|
|
32
|
-
"@cueloop/schema": "0.1.0-alpha.
|
|
29
|
+
"@cueloop/daemon": "0.1.0-alpha.63",
|
|
30
|
+
"@cueloop/extension-api": "0.1.0-alpha.63",
|
|
31
|
+
"@cueloop/integration-obsidian": "0.1.0-alpha.63",
|
|
32
|
+
"@cueloop/schema": "0.1.0-alpha.63",
|
|
33
33
|
"@opentui/core": "^0.5.8",
|
|
34
34
|
"@opentui/keymap": "0.5.8",
|
|
35
35
|
"@opentui/react": "^0.5.8",
|
package/src/prototype-browser.ts
CHANGED
|
@@ -242,15 +242,24 @@ function elementAtScript(x: number, y: number): unknown {
|
|
|
242
242
|
|
|
243
243
|
return parts.join(" > ");
|
|
244
244
|
};
|
|
245
|
+
// Prefer the nearest focusable target before falling back to its component container.
|
|
246
|
+
const focusableTarget = (start: Element | null): Element | null => {
|
|
247
|
+
for (
|
|
248
|
+
let element: Element | null = start;
|
|
249
|
+
element && element !== document.body;
|
|
250
|
+
element = element.parentElement
|
|
251
|
+
) {
|
|
252
|
+
if (element instanceof HTMLElement && element.tabIndex >= 0) {
|
|
253
|
+
return element;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return null;
|
|
258
|
+
};
|
|
245
259
|
const hit = document.elementFromPoint(x, y);
|
|
246
260
|
|
|
247
261
|
if (!(hit instanceof Element)) return null;
|
|
248
|
-
|
|
249
|
-
// grid is the target, not the grid. Everything else climbs to its component.
|
|
250
|
-
const control = hit.closest(
|
|
251
|
-
"button, a, [role='button'], input, select, textarea, label, summary",
|
|
252
|
-
);
|
|
253
|
-
const node = control ?? componentRoot(hit);
|
|
262
|
+
const node = focusableTarget(hit) ?? componentRoot(hit);
|
|
254
263
|
const selector = selectorFor(node);
|
|
255
264
|
|
|
256
265
|
if (!selector) return null;
|