@zag-js/dom-query
Advanced tools
Comparing version 0.80.0 to 0.81.0
@@ -1,17 +0,5 @@ | ||
interface EventMap extends DocumentEventMap, WindowEventMap, HTMLElementEventMap { | ||
} | ||
type Node$1 = Document | HTMLElement | EventTarget | null; | ||
type Target$1 = (() => Node$1) | Node$1; | ||
declare const addDomEvent: <K extends keyof EventMap>(target: Target$1, eventName: K, handler: (event: EventMap[K]) => void, options?: boolean | AddEventListenerOptions) => () => void; | ||
import { JSX, Nullable, MaybeFn } from '@zag-js/types'; | ||
type Booleanish = boolean | "true" | "false"; | ||
declare function getComputedStyle(el: Element): CSSStyleDeclaration; | ||
declare const dataAttr: (guard: boolean | undefined) => Booleanish; | ||
declare const ariaAttr: (guard: boolean | undefined) => "true" | undefined; | ||
declare const MAX_Z_INDEX = 2147483647; | ||
type Target = HTMLElement | EventTarget | null | undefined; | ||
declare function contains(parent: Target, child: Target): boolean; | ||
type DataUrlType = "image/png" | "image/jpeg" | "image/svg+xml"; | ||
@@ -36,6 +24,15 @@ interface DataUrlOptions { | ||
declare function getDocument(el: Element | Window | Node | Document | null | undefined): Document; | ||
declare function getDocumentElement(el: Element | Node | Window | Document | null | undefined): HTMLElement; | ||
declare function getWindow(el: Node | ShadowRoot | Document | null | undefined): Window & typeof globalThis; | ||
declare function getActiveElement(rootNode: Document | ShadowRoot): HTMLElement | null; | ||
type Booleanish = boolean | "true" | "false"; | ||
interface Point { | ||
x: number; | ||
y: number; | ||
} | ||
interface EventKeyOptions { | ||
dir?: "ltr" | "rtl" | undefined; | ||
orientation?: "horizontal" | "vertical" | undefined; | ||
} | ||
type NativeEvent<E> = JSX.ChangeEvent<any> extends E ? InputEvent : E extends JSX.SyntheticEvent<any, infer T> ? T : never; | ||
type AnyPointerEvent = MouseEvent | TouchEvent | PointerEvent; | ||
type MaybeElement$1 = Nullable<HTMLElement>; | ||
type MaybeElementOrFn = MaybeFn<MaybeElement$1>; | ||
@@ -47,51 +44,21 @@ declare function getBeforeInputValue(event: Pick<InputEvent, "currentTarget">): string; | ||
declare function isDownloadingEvent(event: Pick<MouseEvent, "altKey" | "currentTarget">): boolean; | ||
declare function isComposingEvent(event: any): any; | ||
type ItemToId<T> = (v: T) => string; | ||
interface Item { | ||
id: string; | ||
} | ||
declare const defaultItemToId: <T extends Item>(v: T) => string; | ||
declare function itemById<T extends Item>(v: T[], id: string, itemToId?: ItemToId<T>): T | undefined; | ||
declare function indexOfId<T extends Item>(v: T[], id: string, itemToId?: ItemToId<T>): number; | ||
declare function nextById<T extends Item>(v: T[], id: string, loop?: boolean): T; | ||
declare function prevById<T extends Item>(v: T[], id: string, loop?: boolean): T | null; | ||
interface SearchableItem { | ||
id: string; | ||
textContent: string | null; | ||
dataset?: any; | ||
} | ||
declare function getByText<T extends SearchableItem>(v: T[], text: string, currentId?: string | null, itemToId?: ItemToId<T>): T | undefined; | ||
interface TypeaheadState { | ||
keysSoFar: string; | ||
timer: number; | ||
} | ||
interface TypeaheadOptions<T> { | ||
state: TypeaheadState; | ||
activeId: string | null; | ||
key: string; | ||
timeout?: number | undefined; | ||
itemToId?: ItemToId<T> | undefined; | ||
} | ||
declare function getByTypeaheadImpl<T extends SearchableItem>(_items: T[], options: TypeaheadOptions<T>): T | undefined; | ||
declare const getByTypeahead: typeof getByTypeaheadImpl & { | ||
defaultOptions: { | ||
keysSoFar: string; | ||
timer: number; | ||
}; | ||
isValidEvent: typeof isValidTypeaheadEvent; | ||
declare function isComposingEvent(event: any): boolean; | ||
declare function isKeyboardClick(e: Pick<MouseEvent, "detail" | "clientX" | "clientY">): boolean; | ||
declare function isPrintableKey(e: Pick<KeyboardEvent, "key" | "ctrlKey" | "metaKey">): boolean; | ||
declare function isVirtualPointerEvent(e: PointerEvent): boolean; | ||
declare function isVirtualClick(e: MouseEvent | PointerEvent): boolean; | ||
declare const isLeftClick: (e: Pick<MouseEvent, "button">) => boolean; | ||
declare const isContextMenuEvent: (e: Pick<MouseEvent, "button" | "ctrlKey" | "metaKey">) => boolean; | ||
declare const isModifierKey: (e: Pick<KeyboardEvent, "ctrlKey" | "metaKey" | "altKey">) => boolean; | ||
declare const isTouchEvent: (event: AnyPointerEvent) => event is TouchEvent; | ||
declare function getEventKey(event: Pick<KeyboardEvent, "key">, options?: EventKeyOptions): string; | ||
declare function getNativeEvent<E>(event: E): NativeEvent<E>; | ||
declare function getEventStep(event: Pick<KeyboardEvent, "ctrlKey" | "metaKey" | "key" | "shiftKey">): 1 | 0.1 | 10; | ||
declare function getEventPoint(event: any, type?: "page" | "client"): { | ||
x: any; | ||
y: any; | ||
}; | ||
declare function isValidTypeaheadEvent(event: Pick<KeyboardEvent, "key" | "ctrlKey" | "metaKey">): boolean; | ||
declare function getComputedStyle(el: Element): CSSStyleDeclaration; | ||
declare function getParentNode(node: Node): Node; | ||
interface ScrollPosition { | ||
scrollLeft: number; | ||
scrollTop: number; | ||
interface DOMEventMap extends DocumentEventMap, WindowEventMap, HTMLElementEventMap { | ||
} | ||
declare function getScrollPosition(element: HTMLElement | Window): ScrollPosition; | ||
declare const addDomEvent: <K extends keyof DOMEventMap>(target: MaybeFn<EventTarget | null>, eventName: K, handler: (event: DOMEventMap[K]) => void, options?: boolean | AddEventListenerOptions) => () => void; | ||
@@ -107,2 +74,16 @@ interface InitialFocusOptions { | ||
interface ObserveAttributeOptions { | ||
attributes: string[]; | ||
callback(record: MutationRecord): void; | ||
defer?: boolean | undefined; | ||
} | ||
declare function observeAttributes(nodeOrFn: MaybeElementOrFn, options: ObserveAttributeOptions): () => void; | ||
interface ObserveChildrenOptions { | ||
callback: MutationCallback; | ||
defer?: boolean | undefined; | ||
} | ||
declare function observeChildren(nodeOrFn: MaybeElementOrFn, options: ObserveChildrenOptions): () => void; | ||
declare function clickIfLink(el: HTMLAnchorElement): void; | ||
declare const isHTMLElement: (el: any) => el is HTMLElement; | ||
@@ -116,26 +97,14 @@ declare const isDocument: (el: any) => el is Document; | ||
declare const isShadowRoot: (el: any) => el is ShadowRoot; | ||
declare const isInputElement: (el: any) => el is HTMLInputElement; | ||
declare const isAnchorElement: (el: HTMLElement | null | undefined) => el is HTMLAnchorElement; | ||
declare const isElementVisible: (el: Node) => boolean; | ||
declare function isEditableElement(el: HTMLElement | EventTarget | null): boolean; | ||
type Target = HTMLElement | EventTarget | null | undefined; | ||
declare function contains(parent: Target, child: Target): boolean; | ||
declare function getDocument(el: Element | Window | Node | Document | null | undefined): Document; | ||
declare function getDocumentElement(el: Element | Node | Window | Document | null | undefined): HTMLElement; | ||
declare function getWindow(el: Node | ShadowRoot | Document | null | undefined): Window & typeof globalThis; | ||
declare function getActiveElement(rootNode: Document | ShadowRoot): HTMLElement | null; | ||
declare function getParentNode(node: Node): Node; | ||
declare function isHiddenElement(node: HTMLElement): boolean; | ||
declare function isOverflowElement(el: HTMLElement): boolean; | ||
type MaybeElement$2 = HTMLElement | null; | ||
type NodeOrFn$2 = MaybeElement$2 | (() => MaybeElement$2); | ||
interface ObserveAttributeOptions { | ||
attributes: string[]; | ||
callback(record: MutationRecord): void; | ||
defer?: boolean | undefined; | ||
} | ||
declare function observeAttributes(nodeOrFn: NodeOrFn$2, options: ObserveAttributeOptions): () => void; | ||
type MaybeElement$1 = HTMLElement | null; | ||
type NodeOrFn$1 = MaybeElement$1 | (() => MaybeElement$1); | ||
interface ObserveChildrenOptions { | ||
callback: MutationCallback; | ||
defer?: boolean | undefined; | ||
} | ||
declare function observeChildren(nodeOrFn: NodeOrFn$1, options: ObserveChildrenOptions): () => void; | ||
type OverflowAncestor = Array<VisualViewport | Window | HTMLElement | null>; | ||
@@ -145,5 +114,16 @@ declare function getNearestOverflowAncestor(el: Node): HTMLElement; | ||
declare function isInView(el: HTMLElement | Window | VisualViewport, ancestor: HTMLElement | Window | VisualViewport): boolean; | ||
declare function isOverflowElement(el: HTMLElement): boolean; | ||
interface ScrollOptions extends ScrollIntoViewOptions { | ||
rootEl: HTMLElement | null; | ||
} | ||
declare function scrollIntoView(el: HTMLElement | null | undefined, options?: ScrollOptions): void; | ||
interface ScrollPosition { | ||
scrollLeft: number; | ||
scrollTop: number; | ||
} | ||
declare function getScrollPosition(element: HTMLElement | Window): ScrollPosition; | ||
declare const isDom: () => boolean; | ||
declare function getPlatform(): any; | ||
declare function getPlatform(): string; | ||
declare function getUserAgent(): string; | ||
declare const isTouchDevice: () => boolean; | ||
@@ -156,6 +136,87 @@ declare const isMac: () => boolean; | ||
declare const isWebKit: () => boolean; | ||
declare const isAndroid: () => boolean; | ||
type MaybeElement = HTMLElement | null; | ||
type NodeOrFn = MaybeElement | (() => MaybeElement); | ||
interface ProxyTabFocusOptions<T = MaybeElement> { | ||
interface PercentValueOptions { | ||
inverted?: boolean | { | ||
x?: boolean; | ||
y?: boolean; | ||
} | undefined; | ||
dir?: "ltr" | "rtl" | undefined; | ||
orientation?: "vertical" | "horizontal" | undefined; | ||
} | ||
declare function getRelativePoint(point: Point, element: HTMLElement): { | ||
offset: { | ||
x: number; | ||
y: number; | ||
}; | ||
percent: { | ||
x: number; | ||
y: number; | ||
}; | ||
getPercentValue: (options?: PercentValueOptions) => number; | ||
}; | ||
declare function requestPointerLock(doc: Document, fn?: (locked: boolean) => void): (() => void) | undefined; | ||
interface PointerMoveDetails { | ||
/** | ||
* The current position of the pointer. | ||
*/ | ||
point: Point; | ||
/** | ||
* The event that triggered the move. | ||
*/ | ||
event: PointerEvent; | ||
} | ||
interface PointerMoveHandlers { | ||
/** | ||
* Called when the pointer is released. | ||
*/ | ||
onPointerUp: VoidFunction; | ||
/** | ||
* Called when the pointer moves. | ||
*/ | ||
onPointerMove: (details: PointerMoveDetails) => void; | ||
} | ||
declare function trackPointerMove(doc: Document, handlers: PointerMoveHandlers): () => void; | ||
interface PressDetails { | ||
/** | ||
* The current position of the pointer. | ||
*/ | ||
point: Point; | ||
/** | ||
* The event that triggered the move. | ||
*/ | ||
event: PointerEvent; | ||
} | ||
interface TrackPressOptions { | ||
/** | ||
* The element that will be used to track the pointer events. | ||
*/ | ||
pointerNode: Element | null; | ||
/** | ||
* The element that will be used to track the keyboard focus events. | ||
*/ | ||
keyboardNode?: Element | null | undefined; | ||
/** | ||
* A function that determines if the key is valid for the press event. | ||
*/ | ||
isValidKey?(event: KeyboardEvent): boolean; | ||
/** | ||
* A function that will be called when the pointer is pressed. | ||
*/ | ||
onPress?(details: PressDetails): void; | ||
/** | ||
* A function that will be called when the pointer is pressed down. | ||
*/ | ||
onPressStart?(details: PressDetails): void; | ||
/** | ||
* A function that will be called when the pointer is pressed up or cancelled. | ||
*/ | ||
onPressEnd?(details: PressDetails): void; | ||
} | ||
declare function trackPress(options: TrackPressOptions): () => void; | ||
interface ProxyTabFocusOptions<T = MaybeElement$1> { | ||
triggerElement?: T | undefined; | ||
@@ -165,3 +226,3 @@ onFocus?: ((elementToFocus: HTMLElement) => void) | undefined; | ||
} | ||
declare function proxyTabFocus(container: NodeOrFn, options: ProxyTabFocusOptions<NodeOrFn>): () => void; | ||
declare function proxyTabFocus(container: MaybeElementOrFn, options: ProxyTabFocusOptions<MaybeElementOrFn>): () => void; | ||
@@ -171,5 +232,15 @@ type Root = Document | Element | null | undefined; | ||
declare function query<T extends Element = HTMLElement>(root: Root, selector: string): T | null; | ||
type ItemToId<T> = (v: T) => string; | ||
interface Item { | ||
id: string; | ||
} | ||
declare const defaultItemToId: <T extends Item>(v: T) => string; | ||
declare function itemById<T extends Item>(v: T[], id: string, itemToId?: ItemToId<T>): T | undefined; | ||
declare function indexOfId<T extends Item>(v: T[], id: string, itemToId?: ItemToId<T>): number; | ||
declare function nextById<T extends Item>(v: T[], id: string, loop?: boolean): T; | ||
declare function prevById<T extends Item>(v: T[], id: string, loop?: boolean): T | null; | ||
declare function nextTick(fn: VoidFunction): () => void; | ||
declare function raf(fn: VoidFunction): () => void; | ||
declare function queueBeforeEvent(el: EventTarget, type: string, cb: () => void): () => void; | ||
@@ -191,8 +262,9 @@ interface ScopeContext { | ||
interface ScrollOptions extends ScrollIntoViewOptions { | ||
rootEl: HTMLElement | null; | ||
interface SearchableItem { | ||
id: string; | ||
textContent: string | null; | ||
dataset?: any; | ||
} | ||
declare function scrollIntoView(el: HTMLElement | null | undefined, options?: ScrollOptions): void; | ||
declare function getByText<T extends SearchableItem>(v: T[], text: string, currentId?: string | null, itemToId?: ItemToId<T>): T | undefined; | ||
declare function set(element: Element, key: string, setup: () => () => void): () => void; | ||
declare function setAttribute(element: Element, attr: string, value: string): () => void; | ||
@@ -202,38 +274,55 @@ declare function setProperty<T extends Element, K extends keyof T & string>(element: T, property: K, value: T[K]): () => void; | ||
declare const MAX_Z_INDEX = 2147483647; | ||
declare const dataAttr: (guard: boolean | undefined) => Booleanish; | ||
declare const ariaAttr: (guard: boolean | undefined) => "true" | undefined; | ||
type IncludeContainerType = boolean | "if-empty"; | ||
/** | ||
* Returns the focusable elements within the element | ||
*/ | ||
declare const getFocusables: (container: Pick<HTMLElement, "querySelectorAll"> | null, includeContainer?: IncludeContainerType) => HTMLElement[]; | ||
/** | ||
* Whether this element is focusable | ||
*/ | ||
declare function isFocusable(element: HTMLElement | null): element is HTMLElement; | ||
declare function getFirstFocusable(container: HTMLElement | null, includeContainer?: IncludeContainerType): HTMLElement | null; | ||
/** | ||
* Returns the tabbable elements within the element | ||
*/ | ||
declare function getTabbables(container: HTMLElement | null, includeContainer?: IncludeContainerType): HTMLElement[]; | ||
/** | ||
* Whether this element is tabbable | ||
*/ | ||
declare function isTabbable(el: HTMLElement | null): el is HTMLElement; | ||
/** | ||
* Returns the first focusable element within the element | ||
*/ | ||
declare function getFirstTabbable(container: HTMLElement | null, includeContainer?: IncludeContainerType): HTMLElement | null; | ||
/** | ||
* Returns the last focusable element within the element | ||
*/ | ||
declare function getLastTabbable(container: HTMLElement | null, includeContainer?: IncludeContainerType): HTMLElement | null; | ||
/** | ||
* Returns the first and last focusable elements within the element | ||
*/ | ||
declare function getTabbableEdges(container: HTMLElement | null, includeContainer?: IncludeContainerType): [HTMLElement, HTMLElement] | [null, null]; | ||
/** | ||
* Returns the next tabbable element after the current element | ||
*/ | ||
declare function getNextTabbable(container: HTMLElement | null, current?: HTMLElement | null): HTMLElement | null; | ||
declare function getTabIndex(node: HTMLElement | SVGElement): number; | ||
interface DisableTextSelectionOptions<T = MaybeElement> { | ||
target?: T | undefined; | ||
doc?: Document | undefined; | ||
defer?: boolean | undefined; | ||
} | ||
declare function restoreTextSelection(options?: DisableTextSelectionOptions): void; | ||
type MaybeElement = HTMLElement | null | undefined; | ||
type NodeOrFn = MaybeElement | (() => MaybeElement); | ||
declare function disableTextSelection(options?: DisableTextSelectionOptions<NodeOrFn>): () => void; | ||
interface TypeaheadState { | ||
keysSoFar: string; | ||
timer: number; | ||
} | ||
interface TypeaheadOptions<T> { | ||
state: TypeaheadState; | ||
activeId: string | null; | ||
key: string; | ||
timeout?: number | undefined; | ||
itemToId?: ItemToId<T> | undefined; | ||
} | ||
declare function getByTypeaheadImpl<T extends SearchableItem>(baseItems: T[], options: TypeaheadOptions<T>): T | undefined; | ||
declare const getByTypeahead: typeof getByTypeaheadImpl & { | ||
defaultOptions: { | ||
keysSoFar: string; | ||
timer: number; | ||
}; | ||
isValidEvent: typeof isValidTypeaheadEvent; | ||
}; | ||
declare function isValidTypeaheadEvent(event: Pick<KeyboardEvent, "key" | "ctrlKey" | "metaKey">): boolean; | ||
interface ViewportSize { | ||
width: number; | ||
height: number; | ||
} | ||
declare function trackVisualViewport(doc: Document, fn: (data: ViewportSize) => void): () => void; | ||
declare const visuallyHiddenStyle: { | ||
@@ -251,2 +340,3 @@ readonly border: "0"; | ||
}; | ||
declare function setVisuallyHidden(el: HTMLElement): void; | ||
@@ -257,2 +347,2 @@ type ElementGetter = () => Element | null; | ||
export { type DataUrlOptions, type DataUrlType, type InitialFocusOptions, type ItemToId, MAX_Z_INDEX, type ObserveAttributeOptions, type ObserveChildrenOptions, type OverflowAncestor, type ScopeContext, type ScrollOptions, type ScrollPosition, type SearchableItem, type TypeaheadOptions, type TypeaheadState, addDomEvent, ariaAttr, contains, createScope, dataAttr, defaultItemToId, getActiveElement, getBeforeInputValue, getByText, getByTypeahead, getComputedStyle, getDataUrl, getDocument, getDocumentElement, getEventTarget, getFirstFocusable, getFirstTabbable, getFocusables, getInitialFocus, getLastTabbable, getNearestOverflowAncestor, getNextTabbable, getNodeName, getOverflowAncestors, getParentNode, getPlatform, getScrollPosition, getTabIndex, getTabbableEdges, getTabbables, getWindow, indexOfId, isApple, isComposingEvent, isDocument, isDom, isDownloadingEvent, isEditableElement, isFirefox, isFocusable, isHTMLElement, isHiddenElement, isInView, isIos, isMac, isNode, isOpeningInNewTab, isOverflowElement, isRootElement, isSafari, isSelfTarget, isShadowRoot, isTabbable, isTouchDevice, isValidTabEvent, isVisualViewport, isWebKit, isWindow, itemById, nextById, nextTick, observeAttributes, observeChildren, prevById, proxyTabFocus, query, queryAll, raf, scrollIntoView, set, setAttribute, setProperty, setStyle, visuallyHiddenStyle, waitForElement, waitForElements }; | ||
export { type DataUrlOptions, type DataUrlType, type DisableTextSelectionOptions, type InitialFocusOptions, type ItemToId, MAX_Z_INDEX, type ObserveAttributeOptions, type ObserveChildrenOptions, type OverflowAncestor, type PercentValueOptions, type PointerMoveDetails, type PointerMoveHandlers, type PressDetails, type ProxyTabFocusOptions, type ScopeContext, type ScrollOptions, type ScrollPosition, type SearchableItem, type TrackPressOptions, type TypeaheadOptions, type TypeaheadState, type ViewportSize, addDomEvent, ariaAttr, clickIfLink, contains, createScope, dataAttr, defaultItemToId, disableTextSelection, getActiveElement, getBeforeInputValue, getByText, getByTypeahead, getComputedStyle, getDataUrl, getDocument, getDocumentElement, getEventKey, getEventPoint, getEventStep, getEventTarget, getFirstFocusable, getFirstTabbable, getFocusables, getInitialFocus, getLastTabbable, getNativeEvent, getNearestOverflowAncestor, getNextTabbable, getNodeName, getOverflowAncestors, getParentNode, getPlatform, getRelativePoint, getScrollPosition, getTabIndex, getTabbableEdges, getTabbables, getUserAgent, getWindow, indexOfId, isAnchorElement, isAndroid, isApple, isComposingEvent, isContextMenuEvent, isDocument, isDom, isDownloadingEvent, isEditableElement, isElementVisible, isFirefox, isFocusable, isHTMLElement, isInView, isInputElement, isIos, isKeyboardClick, isLeftClick, isMac, isModifierKey, isNode, isOpeningInNewTab, isOverflowElement, isPrintableKey, isRootElement, isSafari, isSelfTarget, isShadowRoot, isTabbable, isTouchDevice, isTouchEvent, isValidTabEvent, isVirtualClick, isVirtualPointerEvent, isVisualViewport, isWebKit, isWindow, itemById, nextById, nextTick, observeAttributes, observeChildren, prevById, proxyTabFocus, query, queryAll, queueBeforeEvent, raf, requestPointerLock, restoreTextSelection, scrollIntoView, setAttribute, setProperty, setStyle, setVisuallyHidden, trackPointerMove, trackPress, trackVisualViewport, visuallyHiddenStyle, waitForElement, waitForElements }; |
'use strict'; | ||
// src/add-dom-event.ts | ||
var addDomEvent = (target, eventName, handler, options) => { | ||
const node = typeof target === "function" ? target() : target; | ||
node?.addEventListener(eventName, handler, options); | ||
return () => { | ||
node?.removeEventListener(eventName, handler, options); | ||
}; | ||
// src/shared.ts | ||
var clamp = (value) => Math.max(0, Math.min(1, value)); | ||
var wrap = (v, idx) => { | ||
return v.map((_, index) => v[(Math.max(idx, 0) + index) % v.length]); | ||
}; | ||
// src/attrs.ts | ||
var pipe = (...fns) => (arg) => fns.reduce((acc, fn) => fn(acc), arg); | ||
var noop = () => void 0; | ||
var isObject = (v) => typeof v === "object" && v !== null; | ||
var MAX_Z_INDEX = 2147483647; | ||
var dataAttr = (guard) => guard ? "" : void 0; | ||
var ariaAttr = (guard) => guard ? "true" : void 0; | ||
// src/constants.ts | ||
var MAX_Z_INDEX = 2147483647; | ||
// src/is.ts | ||
// src/node.ts | ||
var ELEMENT_NODE = 1; | ||
var DOCUMENT_NODE = 9; | ||
var DOCUMENT_FRAGMENT_NODE = 11; | ||
var isObject = (v) => typeof v === "object" && v !== null; | ||
var isHTMLElement = (el) => isObject(el) && el.nodeType === ELEMENT_NODE && typeof el.nodeName === "string"; | ||
@@ -37,11 +32,32 @@ var isDocument = (el) => isObject(el) && el.nodeType === DOCUMENT_NODE; | ||
var isShadowRoot = (el) => isNode(el) && el.nodeType === DOCUMENT_FRAGMENT_NODE && "host" in el; | ||
// src/contains.ts | ||
var isInputElement = (el) => isHTMLElement(el) && el.localName === "input"; | ||
var isAnchorElement = (el) => !!el?.matches("a[href]"); | ||
var isElementVisible = (el) => { | ||
if (!isHTMLElement(el)) return false; | ||
return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0; | ||
}; | ||
var TEXTAREA_SELECT_REGEX = /(textarea|select)/; | ||
function isEditableElement(el) { | ||
if (el == null || !isHTMLElement(el)) return false; | ||
try { | ||
return isInputElement(el) && el.selectionStart != null || TEXTAREA_SELECT_REGEX.test(el.localName) || el.isContentEditable || el.getAttribute("contenteditable") === "true" || el.getAttribute("contenteditable") === ""; | ||
} catch { | ||
return false; | ||
} | ||
} | ||
function contains(parent, child) { | ||
if (!parent || !child) return false; | ||
if (!isHTMLElement(parent) || !isHTMLElement(child)) return false; | ||
return parent === child || parent.contains(child); | ||
const rootNode = child.getRootNode?.(); | ||
if (parent === child) return true; | ||
if (parent.contains(child)) return true; | ||
if (rootNode && isShadowRoot(rootNode)) { | ||
let next = child; | ||
while (next) { | ||
if (parent === next) return true; | ||
next = next.parentNode || next.host; | ||
} | ||
} | ||
return false; | ||
} | ||
// src/env.ts | ||
function getDocument(el) { | ||
@@ -70,3 +86,17 @@ if (isDocument(el)) return el; | ||
} | ||
function getParentNode(node) { | ||
if (getNodeName(node) === "html") return node; | ||
const result = node.assignedSlot || node.parentNode || isShadowRoot(node) && node.host || getDocumentElement(node); | ||
return isShadowRoot(result) ? result.host : result; | ||
} | ||
// src/computed-style.ts | ||
var styleCache = /* @__PURE__ */ new WeakMap(); | ||
function getComputedStyle(el) { | ||
if (!styleCache.has(el)) { | ||
styleCache.set(el, getWindow(el).getComputedStyle(el)); | ||
} | ||
return styleCache.get(el); | ||
} | ||
// src/data-url.ts | ||
@@ -118,4 +148,11 @@ function getDataUrl(svg, opts) { | ||
} | ||
function getUserAgent() { | ||
const ua2 = navigator.userAgentData; | ||
if (ua2 && Array.isArray(ua2.brands)) { | ||
return ua2.brands.map(({ brand, version }) => `${brand}/${version}`).join(" "); | ||
} | ||
return navigator.userAgent; | ||
} | ||
var pt = (v) => isDom() && v.test(getPlatform()); | ||
var ua = (v) => isDom() && v.test(navigator.userAgent); | ||
var ua = (v) => isDom() && v.test(getUserAgent()); | ||
var vn = (v) => isDom() && v.test(navigator.vendor); | ||
@@ -129,2 +166,6 @@ var isTouchDevice = () => isDom() && !!navigator.maxTouchPoints; | ||
var isWebKit = () => ua(/AppleWebKit/); | ||
var isAndroid = () => { | ||
const re = /android/i; | ||
return pt(re) || ua(re); | ||
}; | ||
@@ -169,126 +210,77 @@ // src/event.ts | ||
function isComposingEvent(event) { | ||
return event.nativeEvent?.isComposing ?? event.isComposing; | ||
return getNativeEvent(event).isComposing; | ||
} | ||
// src/get-by-id.ts | ||
var defaultItemToId = (v) => v.id; | ||
function itemById(v, id, itemToId = defaultItemToId) { | ||
return v.find((item) => itemToId(item) === id); | ||
function isKeyboardClick(e) { | ||
return e.detail === 0 || e.clientX === 0 && e.clientY === 0; | ||
} | ||
function indexOfId(v, id, itemToId = defaultItemToId) { | ||
const item = itemById(v, id, itemToId); | ||
return item ? v.indexOf(item) : -1; | ||
function isPrintableKey(e) { | ||
return e.key.length === 1 && !e.ctrlKey && !e.metaKey; | ||
} | ||
function nextById(v, id, loop = true) { | ||
let idx = indexOfId(v, id); | ||
idx = loop ? (idx + 1) % v.length : Math.min(idx + 1, v.length - 1); | ||
return v[idx]; | ||
function isVirtualPointerEvent(e) { | ||
return e.width === 0 && e.height === 0 || e.width === 1 && e.height === 1 && e.pressure === 0 && e.detail === 0 && e.pointerType === "mouse"; | ||
} | ||
function prevById(v, id, loop = true) { | ||
let idx = indexOfId(v, id); | ||
if (idx === -1) return loop ? v[v.length - 1] : null; | ||
idx = loop ? (idx - 1 + v.length) % v.length : Math.max(0, idx - 1); | ||
return v[idx]; | ||
function isVirtualClick(e) { | ||
if (e.mozInputSource === 0 && e.isTrusted) return true; | ||
if (isAndroid() && e.pointerType) { | ||
return e.type === "click" && e.buttons === 1; | ||
} | ||
return e.detail === 0 && !e.pointerType; | ||
} | ||
// src/sanitize.ts | ||
var sanitize = (str) => str.split("").map((char) => { | ||
const code = char.charCodeAt(0); | ||
if (code > 0 && code < 128) return char; | ||
if (code >= 128 && code <= 255) return `/x${code.toString(16)}`.replace("/", "\\"); | ||
return ""; | ||
}).join("").trim(); | ||
// src/get-by-text.ts | ||
var getValueText = (item) => sanitize(item.dataset?.valuetext ?? item.textContent ?? ""); | ||
var match = (valueText, query2) => valueText.trim().toLowerCase().startsWith(query2.toLowerCase()); | ||
var wrap = (v, idx) => { | ||
return v.map((_, index) => v[(Math.max(idx, 0) + index) % v.length]); | ||
var isLeftClick = (e) => e.button === 0; | ||
var isContextMenuEvent = (e) => { | ||
return e.button === 2 || isMac() && e.ctrlKey && e.button === 0; | ||
}; | ||
function getByText(v, text, currentId, itemToId = defaultItemToId) { | ||
const index = currentId ? indexOfId(v, currentId, itemToId) : -1; | ||
let items = currentId ? wrap(v, index) : v; | ||
const isSingleKey = text.length === 1; | ||
if (isSingleKey) { | ||
items = items.filter((item) => itemToId(item) !== currentId); | ||
} | ||
return items.find((item) => match(getValueText(item), text)); | ||
var isModifierKey = (e) => e.ctrlKey || e.altKey || e.metaKey; | ||
var isTouchEvent = (event) => "touches" in event && event.touches.length > 0; | ||
var keyMap = { | ||
Up: "ArrowUp", | ||
Down: "ArrowDown", | ||
Esc: "Escape", | ||
" ": "Space", | ||
",": "Comma", | ||
Left: "ArrowLeft", | ||
Right: "ArrowRight" | ||
}; | ||
var rtlKeyMap = { | ||
ArrowLeft: "ArrowRight", | ||
ArrowRight: "ArrowLeft" | ||
}; | ||
function getEventKey(event, options = {}) { | ||
const { dir = "ltr", orientation = "horizontal" } = options; | ||
let key = event.key; | ||
key = keyMap[key] ?? key; | ||
const isRtl = dir === "rtl" && orientation === "horizontal"; | ||
if (isRtl && key in rtlKeyMap) key = rtlKeyMap[key]; | ||
return key; | ||
} | ||
// src/get-by-typeahead.ts | ||
function getByTypeaheadImpl(_items, options) { | ||
const { state, activeId, key, timeout = 350, itemToId } = options; | ||
const search = state.keysSoFar + key; | ||
const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]); | ||
const query2 = isRepeated ? search[0] : search; | ||
let items = _items.slice(); | ||
const next = getByText(items, query2, activeId, itemToId); | ||
function cleanup() { | ||
clearTimeout(state.timer); | ||
state.timer = -1; | ||
} | ||
function update(value) { | ||
state.keysSoFar = value; | ||
cleanup(); | ||
if (value !== "") { | ||
state.timer = +setTimeout(() => { | ||
update(""); | ||
cleanup(); | ||
}, timeout); | ||
} | ||
} | ||
update(search); | ||
return next; | ||
function getNativeEvent(event) { | ||
return event.nativeEvent ?? event; | ||
} | ||
var getByTypeahead = /* @__PURE__ */ Object.assign(getByTypeaheadImpl, { | ||
defaultOptions: { keysSoFar: "", timer: -1 }, | ||
isValidEvent: isValidTypeaheadEvent | ||
}); | ||
function isValidTypeaheadEvent(event) { | ||
return event.key.length === 1 && !event.ctrlKey && !event.metaKey; | ||
} | ||
// src/get-computed-style.ts | ||
var styleCache = /* @__PURE__ */ new WeakMap(); | ||
function getComputedStyle(el) { | ||
if (!styleCache.has(el)) { | ||
styleCache.set(el, getWindow(el).getComputedStyle(el)); | ||
var pageKeys = /* @__PURE__ */ new Set(["PageUp", "PageDown"]); | ||
var arrowKeys = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"]); | ||
function getEventStep(event) { | ||
if (event.ctrlKey || event.metaKey) { | ||
return 0.1; | ||
} else { | ||
const isPageKey = pageKeys.has(event.key); | ||
const isSkipKey = isPageKey || event.shiftKey && arrowKeys.has(event.key); | ||
return isSkipKey ? 10 : 1; | ||
} | ||
return styleCache.get(el); | ||
} | ||
// src/get-parent-node.ts | ||
function getParentNode(node) { | ||
if (getNodeName(node) === "html") { | ||
return node; | ||
} | ||
const result = ( | ||
// Step into the shadow DOM of the parent of a slotted node. | ||
node.assignedSlot || // DOM Element detected. | ||
node.parentNode || // ShadowRoot detected. | ||
isShadowRoot(node) && node.host || // Fallback. | ||
getDocumentElement(node) | ||
); | ||
return isShadowRoot(result) ? result.host : result; | ||
function getEventPoint(event, type = "client") { | ||
const point = isTouchEvent(event) ? event.touches[0] || event.changedTouches[0] : event; | ||
return { x: point[`${type}X`], y: point[`${type}Y`] }; | ||
} | ||
var addDomEvent = (target, eventName, handler, options) => { | ||
const node = typeof target === "function" ? target() : target; | ||
node?.addEventListener(eventName, handler, options); | ||
return () => { | ||
node?.removeEventListener(eventName, handler, options); | ||
}; | ||
}; | ||
// src/get-scroll-position.ts | ||
function getScrollPosition(element) { | ||
if (isHTMLElement(element)) { | ||
return { scrollLeft: element.scrollLeft, scrollTop: element.scrollTop }; | ||
} | ||
return { scrollLeft: element.scrollX, scrollTop: element.scrollY }; | ||
} | ||
// src/tabbable.ts | ||
var isHTMLElement2 = (element) => typeof element === "object" && element !== null && element.nodeType === 1; | ||
var isFrame = (element) => isHTMLElement2(element) && element.tagName === "IFRAME"; | ||
function isVisible(el) { | ||
if (!isHTMLElement2(el)) return false; | ||
return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0; | ||
} | ||
function hasNegativeTabIndex(element) { | ||
const tabIndex = parseInt(element.getAttribute("tabindex") || "0", 10); | ||
return tabIndex < 0; | ||
} | ||
var isFrame = (el) => isHTMLElement(el) && el.tagName === "IFRAME"; | ||
var hasTabIndex = (el) => !Number.isNaN(parseInt(el.getAttribute("tabindex") || "0", 10)); | ||
var hasNegativeTabIndex = (el) => parseInt(el.getAttribute("tabindex") || "0", 10) < 0; | ||
var focusableSelector = "input:not([type='hidden']):not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href], button:not([disabled]), [tabindex], iframe, object, embed, area[href], audio[controls], video[controls], [contenteditable]:not([contenteditable='false']), details > summary:first-of-type"; | ||
@@ -299,3 +291,3 @@ var getFocusables = (container, includeContainer = false) => { | ||
const include = includeContainer == true || includeContainer == "if-empty" && elements.length === 0; | ||
if (include && isHTMLElement2(container) && isFocusable(container)) { | ||
if (include && isHTMLElement(container) && isFocusable(container)) { | ||
elements.unshift(container); | ||
@@ -314,3 +306,3 @@ } | ||
if (!element || element.closest("[inert]")) return false; | ||
return element.matches(focusableSelector) && isVisible(element); | ||
return element.matches(focusableSelector) && isElementVisible(element); | ||
} | ||
@@ -366,10 +358,5 @@ function getFirstFocusable(container, includeContainer) { | ||
} | ||
var hasTabIndex = (node) => !Number.isNaN(parseInt(node.getAttribute("tabindex") || "0", 10)); | ||
var isContentEditable = (node) => ( | ||
// @ts-ignore | ||
node.isContentEditable || node.getAttribute("contenteditable") === "true" || node.getAttribute("contenteditable") === "" | ||
); | ||
function getTabIndex(node) { | ||
if (node.tabIndex < 0) { | ||
if ((/^(audio|video|details)$/.test(node.localName) || isContentEditable(node)) && !hasTabIndex(node)) { | ||
if ((/^(audio|video|details)$/.test(node.localName) || isEditableElement(node)) && !hasTabIndex(node)) { | ||
return 0; | ||
@@ -405,29 +392,2 @@ } | ||
// src/is-editable-element.ts | ||
function isEditableElement(el) { | ||
if (el == null || !isHTMLElement(el)) { | ||
return false; | ||
} | ||
try { | ||
const win = getWindow(el); | ||
return el instanceof win.HTMLInputElement && el.selectionStart != null || /(textarea|select)/.test(el.localName) || el.isContentEditable; | ||
} catch { | ||
return false; | ||
} | ||
} | ||
// src/is-hidden-element.ts | ||
function isHiddenElement(node) { | ||
if (node.parentElement && isHiddenElement(node.parentElement)) return true; | ||
return node.hidden; | ||
} | ||
// src/is-overflow-element.ts | ||
var OVERFLOW_RE = /auto|scroll|overlay|hidden|clip/; | ||
function isOverflowElement(el) { | ||
const win = getWindow(el); | ||
const { overflow, overflowX, overflowY, display } = win.getComputedStyle(el); | ||
return OVERFLOW_RE.test(overflow + overflowY + overflowX) && !["inline", "contents"].includes(display); | ||
} | ||
// src/raf.ts | ||
@@ -451,4 +411,16 @@ function nextTick(fn) { | ||
} | ||
function queueBeforeEvent(el, type, cb) { | ||
const cancelTimer = raf(() => { | ||
el.removeEventListener(type, exec, true); | ||
cb(); | ||
}); | ||
const exec = () => { | ||
cancelTimer(); | ||
cb(); | ||
}; | ||
el.addEventListener(type, exec, { once: true, capture: true }); | ||
return cancelTimer; | ||
} | ||
// src/observe-attributes.ts | ||
// src/mutation-observer.ts | ||
function observeAttributesImpl(node, options) { | ||
@@ -482,4 +454,2 @@ if (!node) return; | ||
} | ||
// src/observe-children.ts | ||
function observeChildrenImpl(node, options) { | ||
@@ -508,11 +478,17 @@ const { callback: fn } = options; | ||
// src/navigate.ts | ||
function clickIfLink(el) { | ||
const click = () => el.click(); | ||
if (isFirefox()) { | ||
queueBeforeEvent(el, "keyup", click); | ||
} else { | ||
queueMicrotask(click); | ||
} | ||
} | ||
// src/overflow.ts | ||
function getNearestOverflowAncestor(el) { | ||
const parentNode = getParentNode(el); | ||
if (isRootElement(parentNode)) { | ||
return getDocument(parentNode).body; | ||
} | ||
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) { | ||
return parentNode; | ||
} | ||
if (isRootElement(parentNode)) return getDocument(parentNode).body; | ||
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) return parentNode; | ||
return getNearestOverflowAncestor(parentNode); | ||
@@ -529,9 +505,5 @@ } | ||
} | ||
var getRect = (el) => { | ||
if (isHTMLElement(el)) { | ||
return el.getBoundingClientRect(); | ||
} | ||
if (isVisualViewport(el)) { | ||
return { top: 0, left: 0, bottom: el.height, right: el.width }; | ||
} | ||
var getElementRect = (el) => { | ||
if (isHTMLElement(el)) return el.getBoundingClientRect(); | ||
if (isVisualViewport(el)) return { top: 0, left: 0, bottom: el.height, right: el.width }; | ||
return { top: 0, left: 0, bottom: el.innerHeight, right: el.innerWidth }; | ||
@@ -541,7 +513,242 @@ }; | ||
if (!isHTMLElement(el)) return true; | ||
const ancestorRect = getRect(ancestor); | ||
const ancestorRect = getElementRect(ancestor); | ||
const elRect = el.getBoundingClientRect(); | ||
return elRect.top >= ancestorRect.top && elRect.left >= ancestorRect.left && elRect.bottom <= ancestorRect.bottom && elRect.right <= ancestorRect.right; | ||
} | ||
var OVERFLOW_RE = /auto|scroll|overlay|hidden|clip/; | ||
function isOverflowElement(el) { | ||
const win = getWindow(el); | ||
const { overflow, overflowX, overflowY, display } = win.getComputedStyle(el); | ||
return OVERFLOW_RE.test(overflow + overflowY + overflowX) && !["inline", "contents"].includes(display); | ||
} | ||
function isScrollable(el) { | ||
return el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth; | ||
} | ||
function scrollIntoView(el, options) { | ||
const { rootEl, ...scrollOptions } = options || {}; | ||
if (!el || !rootEl) return; | ||
if (!isOverflowElement(rootEl) || !isScrollable(rootEl)) return; | ||
el.scrollIntoView(scrollOptions); | ||
} | ||
function getScrollPosition(element) { | ||
if (isHTMLElement(element)) { | ||
return { scrollLeft: element.scrollLeft, scrollTop: element.scrollTop }; | ||
} | ||
return { scrollLeft: element.scrollX, scrollTop: element.scrollY }; | ||
} | ||
// src/point.ts | ||
function getRelativePoint(point, element) { | ||
const { left, top, width, height } = element.getBoundingClientRect(); | ||
const offset = { x: point.x - left, y: point.y - top }; | ||
const percent = { x: clamp(offset.x / width), y: clamp(offset.y / height) }; | ||
function getPercentValue(options = {}) { | ||
const { dir = "ltr", orientation = "horizontal", inverted } = options; | ||
const invertX = typeof inverted === "object" ? inverted.x : inverted; | ||
const invertY = typeof inverted === "object" ? inverted.y : inverted; | ||
if (orientation === "horizontal") { | ||
return dir === "rtl" || invertX ? 1 - percent.x : percent.x; | ||
} | ||
return invertY ? 1 - percent.y : percent.y; | ||
} | ||
return { offset, percent, getPercentValue }; | ||
} | ||
// src/pointer-lock.ts | ||
function requestPointerLock(doc, fn) { | ||
const body = doc.body; | ||
const supported = "pointerLockElement" in doc || "mozPointerLockElement" in doc; | ||
const isLocked = () => !!doc.pointerLockElement; | ||
function onPointerChange() { | ||
fn?.(isLocked()); | ||
} | ||
function onPointerError(event) { | ||
if (isLocked()) fn?.(false); | ||
console.error("PointerLock error occurred:", event); | ||
doc.exitPointerLock(); | ||
} | ||
if (!supported) return; | ||
try { | ||
body.requestPointerLock(); | ||
} catch { | ||
} | ||
const cleanup = [ | ||
addDomEvent(doc, "pointerlockchange", onPointerChange, false), | ||
addDomEvent(doc, "pointerlockerror", onPointerError, false) | ||
]; | ||
return () => { | ||
cleanup.forEach((cleanup2) => cleanup2()); | ||
doc.exitPointerLock(); | ||
}; | ||
} | ||
// src/text-selection.ts | ||
var state = "default"; | ||
var userSelect = ""; | ||
var elementMap = /* @__PURE__ */ new WeakMap(); | ||
function disableTextSelectionImpl(options = {}) { | ||
const { target, doc } = options; | ||
const docNode = doc ?? document; | ||
const rootEl = docNode.documentElement; | ||
if (isIos()) { | ||
if (state === "default") { | ||
userSelect = rootEl.style.webkitUserSelect; | ||
rootEl.style.webkitUserSelect = "none"; | ||
} | ||
state = "disabled"; | ||
} else if (target) { | ||
elementMap.set(target, target.style.userSelect); | ||
target.style.userSelect = "none"; | ||
} | ||
return () => restoreTextSelection({ target, doc: docNode }); | ||
} | ||
function restoreTextSelection(options = {}) { | ||
const { target, doc } = options; | ||
const docNode = doc ?? document; | ||
const rootEl = docNode.documentElement; | ||
if (isIos()) { | ||
if (state !== "disabled") return; | ||
state = "restoring"; | ||
setTimeout(() => { | ||
nextTick(() => { | ||
if (state === "restoring") { | ||
if (rootEl.style.webkitUserSelect === "none") { | ||
rootEl.style.webkitUserSelect = userSelect || ""; | ||
} | ||
userSelect = ""; | ||
state = "default"; | ||
} | ||
}); | ||
}, 300); | ||
} else { | ||
if (target && elementMap.has(target)) { | ||
const prevUserSelect = elementMap.get(target); | ||
if (target.style.userSelect === "none") { | ||
target.style.userSelect = prevUserSelect ?? ""; | ||
} | ||
if (target.getAttribute("style") === "") { | ||
target.removeAttribute("style"); | ||
} | ||
elementMap.delete(target); | ||
} | ||
} | ||
} | ||
function disableTextSelection(options = {}) { | ||
const { defer, target, ...restOptions } = options; | ||
const func = defer ? raf : (v) => v(); | ||
const cleanups2 = []; | ||
cleanups2.push( | ||
func(() => { | ||
const node = typeof target === "function" ? target() : target; | ||
cleanups2.push(disableTextSelectionImpl({ ...restOptions, target: node })); | ||
}) | ||
); | ||
return () => { | ||
cleanups2.forEach((fn) => fn?.()); | ||
}; | ||
} | ||
// src/pointer-move.ts | ||
function trackPointerMove(doc, handlers) { | ||
const { onPointerMove, onPointerUp } = handlers; | ||
const handleMove = (event) => { | ||
const point = getEventPoint(event); | ||
const distance = Math.sqrt(point.x ** 2 + point.y ** 2); | ||
const moveBuffer = event.pointerType === "touch" ? 10 : 5; | ||
if (distance < moveBuffer) return; | ||
if (event.pointerType === "mouse" && event.button === 0) { | ||
onPointerUp(); | ||
return; | ||
} | ||
onPointerMove({ point, event }); | ||
}; | ||
const cleanups2 = [ | ||
addDomEvent(doc, "pointermove", handleMove, false), | ||
addDomEvent(doc, "pointerup", onPointerUp, false), | ||
addDomEvent(doc, "pointercancel", onPointerUp, false), | ||
addDomEvent(doc, "contextmenu", onPointerUp, false), | ||
disableTextSelection({ doc }) | ||
]; | ||
return () => { | ||
cleanups2.forEach((cleanup) => cleanup()); | ||
}; | ||
} | ||
// src/press.ts | ||
function trackPress(options) { | ||
const { | ||
pointerNode, | ||
keyboardNode = pointerNode, | ||
onPress, | ||
onPressStart, | ||
onPressEnd, | ||
isValidKey = (e) => e.key === "Enter" | ||
} = options; | ||
if (!pointerNode) return noop; | ||
const win = getWindow(pointerNode); | ||
const doc = getDocument(pointerNode); | ||
let removeStartListeners = noop; | ||
let removeEndListeners = noop; | ||
let removeAccessibleListeners = noop; | ||
const getInfo = (event) => ({ | ||
point: getEventPoint(event), | ||
event | ||
}); | ||
function startPress(event) { | ||
onPressStart?.(getInfo(event)); | ||
} | ||
function cancelPress(event) { | ||
onPressEnd?.(getInfo(event)); | ||
} | ||
const startPointerPress = (startEvent) => { | ||
removeEndListeners(); | ||
const endPointerPress = (endEvent) => { | ||
const target = getEventTarget(endEvent); | ||
if (contains(pointerNode, target)) { | ||
onPress?.(getInfo(endEvent)); | ||
} else { | ||
onPressEnd?.(getInfo(endEvent)); | ||
} | ||
}; | ||
const removePointerUpListener = addDomEvent(win, "pointerup", endPointerPress, { passive: !onPress }); | ||
const removePointerCancelListener = addDomEvent(win, "pointercancel", cancelPress, { passive: !onPressEnd }); | ||
removeEndListeners = pipe(removePointerUpListener, removePointerCancelListener); | ||
if (doc.activeElement === keyboardNode && startEvent.pointerType === "mouse") { | ||
startEvent.preventDefault(); | ||
} | ||
startPress(startEvent); | ||
}; | ||
const removePointerListener = addDomEvent(pointerNode, "pointerdown", startPointerPress, { passive: !onPressStart }); | ||
const removeFocusListener = addDomEvent(keyboardNode, "focus", startAccessiblePress); | ||
removeStartListeners = pipe(removePointerListener, removeFocusListener); | ||
function startAccessiblePress() { | ||
const handleKeydown = (keydownEvent) => { | ||
if (!isValidKey(keydownEvent)) return; | ||
const handleKeyup = (keyupEvent) => { | ||
if (!isValidKey(keyupEvent)) return; | ||
const evt2 = new win.PointerEvent("pointerup"); | ||
const info = getInfo(evt2); | ||
onPress?.(info); | ||
onPressEnd?.(info); | ||
}; | ||
removeEndListeners(); | ||
removeEndListeners = addDomEvent(keyboardNode, "keyup", handleKeyup); | ||
const evt = new win.PointerEvent("pointerdown"); | ||
startPress(evt); | ||
}; | ||
const handleBlur = () => { | ||
const evt = new win.PointerEvent("pointercancel"); | ||
cancelPress(evt); | ||
}; | ||
const removeKeydownListener = addDomEvent(keyboardNode, "keydown", handleKeydown); | ||
const removeBlurListener = addDomEvent(keyboardNode, "blur", handleBlur); | ||
removeAccessibleListeners = pipe(removeKeydownListener, removeBlurListener); | ||
} | ||
return () => { | ||
removeStartListeners(); | ||
removeEndListeners(); | ||
removeAccessibleListeners(); | ||
}; | ||
} | ||
// src/proxy-tab-focus.ts | ||
@@ -572,6 +779,3 @@ function proxyTabFocusImpl(container, options = {}) { | ||
} | ||
doc?.addEventListener("keydown", onKeyDown, true); | ||
return () => { | ||
doc?.removeEventListener("keydown", onKeyDown, true); | ||
}; | ||
return addDomEvent(doc, "keydown", onKeyDown, true); | ||
} | ||
@@ -601,2 +805,21 @@ function proxyTabFocus(container, options) { | ||
} | ||
var defaultItemToId = (v) => v.id; | ||
function itemById(v, id, itemToId = defaultItemToId) { | ||
return v.find((item) => itemToId(item) === id); | ||
} | ||
function indexOfId(v, id, itemToId = defaultItemToId) { | ||
const item = itemById(v, id, itemToId); | ||
return item ? v.indexOf(item) : -1; | ||
} | ||
function nextById(v, id, loop = true) { | ||
let idx = indexOfId(v, id); | ||
idx = loop ? (idx + 1) % v.length : Math.min(idx + 1, v.length - 1); | ||
return v[idx]; | ||
} | ||
function prevById(v, id, loop = true) { | ||
let idx = indexOfId(v, id); | ||
if (idx === -1) return loop ? v[v.length - 1] : null; | ||
idx = loop ? (idx - 1 + v.length) % v.length : Math.max(0, idx - 1); | ||
return v[idx]; | ||
} | ||
@@ -622,15 +845,23 @@ // src/scope.ts | ||
// src/scroll-into-view.ts | ||
function isScrollable(el) { | ||
return el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth; | ||
} | ||
function scrollIntoView(el, options) { | ||
const { rootEl, ...scrollOptions } = options || {}; | ||
if (!el || !rootEl) { | ||
return; | ||
// src/searchable.ts | ||
var sanitize = (str) => str.split("").map((char) => { | ||
const code = char.charCodeAt(0); | ||
if (code > 0 && code < 128) return char; | ||
if (code >= 128 && code <= 255) return `/x${code.toString(16)}`.replace("/", "\\"); | ||
return ""; | ||
}).join("").trim(); | ||
var getValueText = (el) => { | ||
return sanitize(el.dataset?.valuetext ?? el.textContent ?? ""); | ||
}; | ||
var match = (valueText, query2) => { | ||
return valueText.trim().toLowerCase().startsWith(query2.toLowerCase()); | ||
}; | ||
function getByText(v, text, currentId, itemToId = defaultItemToId) { | ||
const index = currentId ? indexOfId(v, currentId, itemToId) : -1; | ||
let items = currentId ? wrap(v, index) : v; | ||
const isSingleKey = text.length === 1; | ||
if (isSingleKey) { | ||
items = items.filter((item) => itemToId(item) !== currentId); | ||
} | ||
if (!isOverflowElement(rootEl) || !isScrollable(rootEl)) { | ||
return; | ||
} | ||
el.scrollIntoView(scrollOptions); | ||
return items.find((item) => match(getValueText(item), text)); | ||
} | ||
@@ -709,2 +940,51 @@ | ||
// src/typeahead.ts | ||
function getByTypeaheadImpl(baseItems, options) { | ||
const { state: state2, activeId, key, timeout = 350, itemToId } = options; | ||
const search = state2.keysSoFar + key; | ||
const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]); | ||
const query2 = isRepeated ? search[0] : search; | ||
let items = baseItems.slice(); | ||
const next = getByText(items, query2, activeId, itemToId); | ||
function cleanup() { | ||
clearTimeout(state2.timer); | ||
state2.timer = -1; | ||
} | ||
function update(value) { | ||
state2.keysSoFar = value; | ||
cleanup(); | ||
if (value !== "") { | ||
state2.timer = +setTimeout(() => { | ||
update(""); | ||
cleanup(); | ||
}, timeout); | ||
} | ||
} | ||
update(search); | ||
return next; | ||
} | ||
var getByTypeahead = /* @__PURE__ */ Object.assign(getByTypeaheadImpl, { | ||
defaultOptions: { keysSoFar: "", timer: -1 }, | ||
isValidEvent: isValidTypeaheadEvent | ||
}); | ||
function isValidTypeaheadEvent(event) { | ||
return event.key.length === 1 && !event.ctrlKey && !event.metaKey; | ||
} | ||
// src/visual-viewport.ts | ||
function trackVisualViewport(doc, fn) { | ||
const win = doc?.defaultView || window; | ||
const onResize = () => { | ||
fn?.(getViewportSize(win)); | ||
}; | ||
onResize(); | ||
return addDomEvent(win.visualViewport ?? win, "resize", onResize); | ||
} | ||
function getViewportSize(win) { | ||
return { | ||
width: win.visualViewport?.width || win.innerWidth, | ||
height: win.visualViewport?.height || win.innerHeight | ||
}; | ||
} | ||
// src/visually-hidden.ts | ||
@@ -723,2 +1003,5 @@ var visuallyHiddenStyle = { | ||
}; | ||
function setVisuallyHidden(el) { | ||
Object.assign(el.style, visuallyHiddenStyle); | ||
} | ||
@@ -757,2 +1040,3 @@ // src/wait-for.ts | ||
exports.ariaAttr = ariaAttr; | ||
exports.clickIfLink = clickIfLink; | ||
exports.contains = contains; | ||
@@ -762,2 +1046,3 @@ exports.createScope = createScope; | ||
exports.defaultItemToId = defaultItemToId; | ||
exports.disableTextSelection = disableTextSelection; | ||
exports.getActiveElement = getActiveElement; | ||
@@ -771,2 +1056,5 @@ exports.getBeforeInputValue = getBeforeInputValue; | ||
exports.getDocumentElement = getDocumentElement; | ||
exports.getEventKey = getEventKey; | ||
exports.getEventPoint = getEventPoint; | ||
exports.getEventStep = getEventStep; | ||
exports.getEventTarget = getEventTarget; | ||
@@ -778,2 +1066,3 @@ exports.getFirstFocusable = getFirstFocusable; | ||
exports.getLastTabbable = getLastTabbable; | ||
exports.getNativeEvent = getNativeEvent; | ||
exports.getNearestOverflowAncestor = getNearestOverflowAncestor; | ||
@@ -785,2 +1074,3 @@ exports.getNextTabbable = getNextTabbable; | ||
exports.getPlatform = getPlatform; | ||
exports.getRelativePoint = getRelativePoint; | ||
exports.getScrollPosition = getScrollPosition; | ||
@@ -790,6 +1080,10 @@ exports.getTabIndex = getTabIndex; | ||
exports.getTabbables = getTabbables; | ||
exports.getUserAgent = getUserAgent; | ||
exports.getWindow = getWindow; | ||
exports.indexOfId = indexOfId; | ||
exports.isAnchorElement = isAnchorElement; | ||
exports.isAndroid = isAndroid; | ||
exports.isApple = isApple; | ||
exports.isComposingEvent = isComposingEvent; | ||
exports.isContextMenuEvent = isContextMenuEvent; | ||
exports.isDocument = isDocument; | ||
@@ -799,12 +1093,17 @@ exports.isDom = isDom; | ||
exports.isEditableElement = isEditableElement; | ||
exports.isElementVisible = isElementVisible; | ||
exports.isFirefox = isFirefox; | ||
exports.isFocusable = isFocusable; | ||
exports.isHTMLElement = isHTMLElement; | ||
exports.isHiddenElement = isHiddenElement; | ||
exports.isInView = isInView; | ||
exports.isInputElement = isInputElement; | ||
exports.isIos = isIos; | ||
exports.isKeyboardClick = isKeyboardClick; | ||
exports.isLeftClick = isLeftClick; | ||
exports.isMac = isMac; | ||
exports.isModifierKey = isModifierKey; | ||
exports.isNode = isNode; | ||
exports.isOpeningInNewTab = isOpeningInNewTab; | ||
exports.isOverflowElement = isOverflowElement; | ||
exports.isPrintableKey = isPrintableKey; | ||
exports.isRootElement = isRootElement; | ||
@@ -816,3 +1115,6 @@ exports.isSafari = isSafari; | ||
exports.isTouchDevice = isTouchDevice; | ||
exports.isTouchEvent = isTouchEvent; | ||
exports.isValidTabEvent = isValidTabEvent; | ||
exports.isVirtualClick = isVirtualClick; | ||
exports.isVirtualPointerEvent = isVirtualPointerEvent; | ||
exports.isVisualViewport = isVisualViewport; | ||
@@ -830,10 +1132,16 @@ exports.isWebKit = isWebKit; | ||
exports.queryAll = queryAll; | ||
exports.queueBeforeEvent = queueBeforeEvent; | ||
exports.raf = raf; | ||
exports.requestPointerLock = requestPointerLock; | ||
exports.restoreTextSelection = restoreTextSelection; | ||
exports.scrollIntoView = scrollIntoView; | ||
exports.set = set; | ||
exports.setAttribute = setAttribute; | ||
exports.setProperty = setProperty; | ||
exports.setStyle = setStyle; | ||
exports.setVisuallyHidden = setVisuallyHidden; | ||
exports.trackPointerMove = trackPointerMove; | ||
exports.trackPress = trackPress; | ||
exports.trackVisualViewport = trackVisualViewport; | ||
exports.visuallyHiddenStyle = visuallyHiddenStyle; | ||
exports.waitForElement = waitForElement; | ||
exports.waitForElements = waitForElements; |
{ | ||
"name": "@zag-js/dom-query", | ||
"version": "0.80.0", | ||
"version": "0.81.0", | ||
"description": "The dom helper library for zag.js machines", | ||
@@ -30,2 +30,5 @@ "keywords": [ | ||
}, | ||
"dependencies": { | ||
"@zag-js/types": "0.81.0" | ||
}, | ||
"module": "dist/index.mjs", | ||
@@ -32,0 +35,0 @@ "types": "dist/index.d.ts", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
110440
2404
1
+ Added@zag-js/types@0.81.0
+ Added@zag-js/types@0.81.0(transitive)
+ Addedcsstype@3.1.3(transitive)