mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 18:26:17 +00:00
42 lines
1.6 KiB
TypeScript
42 lines
1.6 KiB
TypeScript
import { isHtmlElement } from "./domEditingDom";
|
|
|
|
// `data-hf-group` selection semantics: a group wrapper is selected as one unit
|
|
// until the user drills into it; once drilled in, clicks resolve to its children
|
|
// (or to the next nested group inside it). One level of drill-in at a time keeps
|
|
// nested groups navigable.
|
|
|
|
export type GroupCapture =
|
|
| { kind: "unit"; element: HTMLElement } // select this group wrapper as one unit
|
|
| { kind: "child" } // resolve the clicked element normally
|
|
| { kind: "out-of-scope" }; // clicked outside the drilled-into group → select nothing
|
|
|
|
// Layer-tree roots: the drilled-into group's element children, else the doc root.
|
|
export function groupScopedLayerRoots(
|
|
root: HTMLElement,
|
|
activeGroupElement: HTMLElement | null,
|
|
): HTMLElement[] {
|
|
const els = activeGroupElement?.isConnected ? Array.from(activeGroupElement.children) : [root];
|
|
return els.filter(isHtmlElement);
|
|
}
|
|
|
|
export function resolveGroupCapture(
|
|
startEl: HTMLElement,
|
|
activeGroupElement: HTMLElement | null,
|
|
): GroupCapture {
|
|
const groups: HTMLElement[] = [];
|
|
for (let n: HTMLElement | null = startEl; n; n = n.parentElement) {
|
|
if (n.hasAttribute("data-hf-group")) groups.push(n);
|
|
}
|
|
const result = ((): GroupCapture => {
|
|
if (!activeGroupElement) {
|
|
const outermost = groups[groups.length - 1];
|
|
return outermost ? { kind: "unit", element: outermost } : { kind: "child" };
|
|
}
|
|
const idx = groups.indexOf(activeGroupElement);
|
|
if (idx === -1) return { kind: "out-of-scope" };
|
|
const nestedInside = groups[idx - 1];
|
|
return nestedInside ? { kind: "unit", element: nestedInside } : { kind: "child" };
|
|
})();
|
|
return result;
|
|
}
|