@nick-skriabin/glyph 0.1.37 → 0.1.38
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/dist/index.cjs +55 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +55 -68
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2076,6 +2076,18 @@ function render(element, opts = {}) {
|
|
|
2076
2076
|
}
|
|
2077
2077
|
}
|
|
2078
2078
|
return result;
|
|
2079
|
+
},
|
|
2080
|
+
getActiveElements() {
|
|
2081
|
+
const activeIds = getActiveFocusableIds();
|
|
2082
|
+
const result = [];
|
|
2083
|
+
for (const id of activeIds) {
|
|
2084
|
+
if (skippableIds.has(id)) continue;
|
|
2085
|
+
const node = focusRegistry.get(id);
|
|
2086
|
+
if (node) {
|
|
2087
|
+
result.push({ id, node });
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
return result;
|
|
2079
2091
|
}
|
|
2080
2092
|
};
|
|
2081
2093
|
const layoutSubscriptions = /* @__PURE__ */ new Map();
|
|
@@ -4347,7 +4359,6 @@ function DialogOverlay({ dialog, onDismiss }) {
|
|
|
4347
4359
|
)
|
|
4348
4360
|
);
|
|
4349
4361
|
}
|
|
4350
|
-
var JumpNavContext = React15.createContext(null);
|
|
4351
4362
|
function generateHints(count, chars) {
|
|
4352
4363
|
const hints = [];
|
|
4353
4364
|
const charList = chars.split("");
|
|
@@ -4378,25 +4389,13 @@ function JumpNav({
|
|
|
4378
4389
|
};
|
|
4379
4390
|
const [isActive, setIsActive] = React15.useState(false);
|
|
4380
4391
|
const [inputBuffer, setInputBuffer] = React15.useState("");
|
|
4381
|
-
const [hasChildJumpNav, setHasChildJumpNav] = React15.useState(false);
|
|
4382
4392
|
const [elements, setElements] = React15.useState([]);
|
|
4383
4393
|
const inputCtx = React15.useContext(InputContext);
|
|
4384
4394
|
const focusCtx = React15.useContext(FocusContext);
|
|
4385
4395
|
const layoutCtx = React15.useContext(LayoutContext);
|
|
4386
|
-
const parentJumpNav = React15.useContext(JumpNavContext);
|
|
4387
|
-
const wrapperRef = React15.useRef(null);
|
|
4388
4396
|
React15.useEffect(() => {
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
}
|
|
4392
|
-
}, [parentJumpNav]);
|
|
4393
|
-
const contextValue = React15.useMemo(() => ({
|
|
4394
|
-
isChildActive: hasChildJumpNav,
|
|
4395
|
-
registerChildJumpNav: () => {
|
|
4396
|
-
setHasChildJumpNav(true);
|
|
4397
|
-
return () => setHasChildJumpNav(false);
|
|
4398
|
-
}
|
|
4399
|
-
}), [hasChildJumpNav]);
|
|
4397
|
+
log("Mounted, inputCtx:", !!inputCtx, "focusCtx:", !!focusCtx, "enabled:", enabled);
|
|
4398
|
+
}, []);
|
|
4400
4399
|
const parseKey = React15.useCallback((keyStr) => {
|
|
4401
4400
|
const parts = keyStr.toLowerCase().split("+");
|
|
4402
4401
|
return {
|
|
@@ -4408,45 +4407,34 @@ function JumpNav({
|
|
|
4408
4407
|
};
|
|
4409
4408
|
}, []);
|
|
4410
4409
|
const activationKeyParsed = parseKey(activationKey);
|
|
4411
|
-
const findFocusableDescendants = React15.useCallback((node) => {
|
|
4412
|
-
const result = [];
|
|
4413
|
-
function walk(n) {
|
|
4414
|
-
if (n.focusId) {
|
|
4415
|
-
result.push({
|
|
4416
|
-
id: n.focusId,
|
|
4417
|
-
node: n,
|
|
4418
|
-
layout: layoutCtx?.getLayout(n) ?? n.layout
|
|
4419
|
-
});
|
|
4420
|
-
}
|
|
4421
|
-
for (const child of n.children) {
|
|
4422
|
-
walk(child);
|
|
4423
|
-
}
|
|
4424
|
-
}
|
|
4425
|
-
walk(node);
|
|
4426
|
-
return result;
|
|
4427
|
-
}, [layoutCtx]);
|
|
4428
4410
|
const refreshElements = React15.useCallback(() => {
|
|
4429
|
-
if (!
|
|
4430
|
-
log("refreshElements: no
|
|
4411
|
+
if (!focusCtx?.getActiveElements) {
|
|
4412
|
+
log("refreshElements: no getActiveElements");
|
|
4431
4413
|
return;
|
|
4432
4414
|
}
|
|
4433
|
-
const
|
|
4434
|
-
log("
|
|
4435
|
-
|
|
4415
|
+
const active = focusCtx.getActiveElements();
|
|
4416
|
+
log("getActiveElements returned", active.length, "elements");
|
|
4417
|
+
const mapped = active.map(({ id, node }) => ({
|
|
4418
|
+
id,
|
|
4419
|
+
node,
|
|
4420
|
+
layout: layoutCtx?.getLayout(node) ?? node.layout
|
|
4421
|
+
}));
|
|
4422
|
+
mapped.sort((a, b) => {
|
|
4436
4423
|
if (a.layout.y !== b.layout.y) {
|
|
4437
4424
|
return a.layout.y - b.layout.y;
|
|
4438
4425
|
}
|
|
4439
4426
|
return a.layout.x - b.layout.x;
|
|
4440
4427
|
});
|
|
4441
|
-
setElements(
|
|
4442
|
-
}, [
|
|
4428
|
+
setElements(mapped);
|
|
4429
|
+
}, [focusCtx, layoutCtx, log]);
|
|
4443
4430
|
const wasActiveRef = React15.useRef(false);
|
|
4444
4431
|
React15.useEffect(() => {
|
|
4445
4432
|
if (isActive && !wasActiveRef.current) {
|
|
4433
|
+
log("Activated! Refreshing elements...");
|
|
4446
4434
|
refreshElements();
|
|
4447
4435
|
}
|
|
4448
4436
|
wasActiveRef.current = isActive;
|
|
4449
|
-
}, [isActive, refreshElements]);
|
|
4437
|
+
}, [isActive, refreshElements, log]);
|
|
4450
4438
|
const visibleElements = elements.filter(
|
|
4451
4439
|
(el) => el.layout.width > 0 && el.layout.height > 0
|
|
4452
4440
|
);
|
|
@@ -4460,19 +4448,19 @@ function JumpNav({
|
|
|
4460
4448
|
});
|
|
4461
4449
|
return map;
|
|
4462
4450
|
}, [visibleElements, visibleHints]);
|
|
4463
|
-
React15.useEffect(() => {
|
|
4464
|
-
log("Mounted, inputCtx:", !!inputCtx, "enabled:", enabled, "activationKey:", activationKey);
|
|
4465
|
-
log("Parsed key:", activationKeyParsed);
|
|
4466
|
-
}, []);
|
|
4467
4451
|
React15.useEffect(() => {
|
|
4468
4452
|
if (!inputCtx || !enabled) {
|
|
4469
4453
|
log("Not subscribing - inputCtx:", !!inputCtx, "enabled:", enabled);
|
|
4470
4454
|
return;
|
|
4471
4455
|
}
|
|
4472
|
-
log("Subscribing to priority input");
|
|
4456
|
+
log("Subscribing to priority input, activation key:", activationKey);
|
|
4473
4457
|
const handler = (key) => {
|
|
4474
|
-
|
|
4475
|
-
|
|
4458
|
+
const nameMatch = key.name === activationKeyParsed.name;
|
|
4459
|
+
const ctrlMatch = !!key.ctrl === activationKeyParsed.ctrl;
|
|
4460
|
+
const altMatch = !!key.alt === activationKeyParsed.alt;
|
|
4461
|
+
const shiftMatch = !!key.shift === activationKeyParsed.shift;
|
|
4462
|
+
const metaMatch = !!key.meta === activationKeyParsed.meta;
|
|
4463
|
+
if (!isActive && nameMatch && ctrlMatch && altMatch && shiftMatch && metaMatch) {
|
|
4476
4464
|
log("Activation key matched! Activating...");
|
|
4477
4465
|
setIsActive(true);
|
|
4478
4466
|
setInputBuffer("");
|
|
@@ -4480,6 +4468,7 @@ function JumpNav({
|
|
|
4480
4468
|
}
|
|
4481
4469
|
if (isActive) {
|
|
4482
4470
|
if (key.name === "escape") {
|
|
4471
|
+
log("Escape pressed, deactivating");
|
|
4483
4472
|
setIsActive(false);
|
|
4484
4473
|
setInputBuffer("");
|
|
4485
4474
|
return true;
|
|
@@ -4490,8 +4479,10 @@ function JumpNav({
|
|
|
4490
4479
|
}
|
|
4491
4480
|
if (key.sequence && key.sequence.length === 1 && /[a-z]/i.test(key.sequence)) {
|
|
4492
4481
|
const newBuffer = inputBuffer + key.sequence.toLowerCase();
|
|
4482
|
+
log("Buffer:", newBuffer);
|
|
4493
4483
|
const targetId = visibleHintMap.get(newBuffer);
|
|
4494
4484
|
if (targetId) {
|
|
4485
|
+
log("Jumping to", targetId);
|
|
4495
4486
|
focusCtx?.requestFocus(targetId);
|
|
4496
4487
|
setIsActive(false);
|
|
4497
4488
|
setInputBuffer("");
|
|
@@ -4510,10 +4501,20 @@ function JumpNav({
|
|
|
4510
4501
|
return false;
|
|
4511
4502
|
};
|
|
4512
4503
|
return inputCtx.subscribePriority(handler);
|
|
4513
|
-
}, [inputCtx, enabled, isActive, activationKeyParsed, inputBuffer, visibleHintMap, focusCtx,
|
|
4504
|
+
}, [inputCtx, enabled, isActive, activationKeyParsed, inputBuffer, visibleHintMap, focusCtx, activationKey, log]);
|
|
4514
4505
|
const hintsOverlay = isActive ? React15__default.default.createElement(
|
|
4515
|
-
|
|
4516
|
-
|
|
4506
|
+
"box",
|
|
4507
|
+
{
|
|
4508
|
+
// Portal-like wrapper - fullscreen absolute overlay
|
|
4509
|
+
style: {
|
|
4510
|
+
position: "absolute",
|
|
4511
|
+
top: 0,
|
|
4512
|
+
left: 0,
|
|
4513
|
+
width: "100%",
|
|
4514
|
+
height: "100%",
|
|
4515
|
+
zIndex: 99998
|
|
4516
|
+
}
|
|
4517
|
+
},
|
|
4517
4518
|
...visibleElements.map((el, i) => {
|
|
4518
4519
|
const hint = visibleHints[i];
|
|
4519
4520
|
if (!hint) return null;
|
|
@@ -4558,24 +4559,10 @@ function JumpNav({
|
|
|
4558
4559
|
}, inputBuffer ? `Jump: ${inputBuffer}_` : "Press a key to jump \u2022 ESC to cancel")
|
|
4559
4560
|
)
|
|
4560
4561
|
) : null;
|
|
4561
|
-
const wrappedChildren = React15__default.default.createElement(
|
|
4562
|
-
"box",
|
|
4563
|
-
{
|
|
4564
|
-
ref: (node) => {
|
|
4565
|
-
wrapperRef.current = node;
|
|
4566
|
-
},
|
|
4567
|
-
style: {
|
|
4568
|
-
// Invisible wrapper - takes full size of parent
|
|
4569
|
-
flexGrow: 1,
|
|
4570
|
-
flexDirection: "column"
|
|
4571
|
-
}
|
|
4572
|
-
},
|
|
4573
|
-
children
|
|
4574
|
-
);
|
|
4575
4562
|
return React15__default.default.createElement(
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4563
|
+
React15__default.default.Fragment,
|
|
4564
|
+
null,
|
|
4565
|
+
children,
|
|
4579
4566
|
hintsOverlay
|
|
4580
4567
|
);
|
|
4581
4568
|
}
|
|
@@ -4685,7 +4672,7 @@ function useFocusRegistry() {
|
|
|
4685
4672
|
});
|
|
4686
4673
|
const updateElements = React15.useCallback(() => {
|
|
4687
4674
|
if (!focusCtx) return;
|
|
4688
|
-
const registered = focusCtx.getRegisteredElements?.() ?? [];
|
|
4675
|
+
const registered = focusCtx.getActiveElements?.() ?? focusCtx.getRegisteredElements?.() ?? [];
|
|
4689
4676
|
const mapped = registered.map(({ id, node }) => ({
|
|
4690
4677
|
id,
|
|
4691
4678
|
node,
|