@react-hive/honey-utils 3.11.0 → 3.13.0

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/README.md CHANGED
@@ -546,6 +546,8 @@ function divide(a: number, b: number): number {
546
546
 
547
547
  ### String Utilities
548
548
 
549
+ ---
550
+
549
551
  - `isString(value: unknown): value is string` - Checks if a value is a `string`.
550
552
  - `isNilOrEmptyString(value: unknown): value is null | undefined` - Checks if a value is `null`, `undefined`, or an empty string.
551
553
  - `toKebabCase(input: string): string` - Converts a string to kebab-case.
@@ -555,10 +557,14 @@ function divide(a: number, b: number): number {
555
557
 
556
558
  ### Object Utilities
557
559
 
560
+ ---
561
+
558
562
  - `definedProps<T extends object>(obj: T): DefinedProps<T>` - Creates a new object by removing all properties whose values are `undefined`.
559
563
 
560
564
  ### Array Utilities
561
565
 
566
+ ---
567
+
562
568
  - `isArray(value: unknown): value is unknown[]` - Checks if a value is an array.
563
569
  - `isEmptyArray(value: unknown): value is []` - Checks if a value is an empty array.
564
570
  - `compact<T>(array: (T | Falsy)[]): T[]` – Returns a new array with all falsy values (false, null, undefined, 0, '', NaN) removed, preserving only truthy items of type `T`.
@@ -571,6 +577,8 @@ function divide(a: number, b: number): number {
571
577
 
572
578
  ### Function Utilities
573
579
 
580
+ ---
581
+
574
582
  - `isFunction(value: unknown): value is Function` - Checks if a value is a `function`.
575
583
  - `noop(): void` - A no-operation function.
576
584
  - `not<Args extends any[]>(fn: (...args: Args) => any): (...args: Args) => boolean` - Creates a new function that negates the result of the given predicate function. Useful for logical inversions, e.g., turning `isEven` into `isOdd`.
@@ -582,6 +590,8 @@ function divide(a: number, b: number): number {
582
590
 
583
591
  ### Type Guards
584
592
 
593
+ ---
594
+
585
595
  - `assert(condition: any, message: string): asserts condition` - Asserts that a condition is truthy, throwing an error with the provided message if it's not.
586
596
  - `isNumber(value: unknown): value is number` - Checks if a value is a `number`.
587
597
  - `isBool(value: unknown): value is boolean` - Checks if a value is a `boolean`.
@@ -605,32 +615,58 @@ function divide(a: number, b: number): number {
605
615
 
606
616
  ### Math Utilities
607
617
 
618
+ ---
619
+
608
620
  - `calculateEuclideanDistance(startX: number, startY: number, endX: number, endY: number): number` - Calculates the Euclidean distance between two points.
609
621
  - `calculateMovingSpeed(distance: number, elapsedTime: number): number` - Calculates moving speed.
610
622
  - `calculatePercentage(value: number, percentage: number): number` - Calculates the specified percentage of a value.
611
623
 
624
+ ### ENV
625
+
626
+ ---
627
+
628
+ #### Storage
629
+
630
+ - `isLocalStorageReadable(): boolean` - Determines whether `localStorage` can be safely read from. This check works even when writes fail (e.g., due to `QuotaExceededError`) and ensures that calling `getItem()` does not throw in restricted environments.
631
+ - `getLocalStorageCapabilities(): LocalStorageCapabilities` - Detects the browser's read and write capabilities for `localStorage`. Readability is determined by safe execution of `getItem()`, while writability requires successful `setItem()` and `removeItem()`.
632
+
633
+ ### Geometry
634
+
635
+ ---
636
+
637
+ #### Layout
638
+
639
+ - `calculateCenterOffset(options: CalculateCenterOffsetOptions): number` - Calculates a clamped offset value that centers an element within a container along a single axis. Returns a negative value suitable for use in a CSS `translate` transform, or `0` when no overflow exists.
640
+
612
641
  ### DOM Utilities
613
642
 
614
- - `parse2DMatrix(element: HTMLElement): { translateX: number, translateY: number, scaleX: number, scaleY: number, skewX: number, skewY: number }` - Extracts transformation values (translate, scale, skew) from the 2D transformation matrix of a given HTML element.
643
+ ---
644
+
615
645
  - `cloneBlob(blob: Blob): Blob` - Creates a clone of a Blob object with the same content and type as the original.
616
- - `getDOMRectIntersectionRatio(sourceRect: DOMRect, targetRect: DOMRect): number` - Calculates the ratio of the `targetRect` that is overlapped by the `sourceRect`. Returns a number between `0` (no overlap) and `1` (fully covered).
617
646
  - `getElementOffsetRect(element: HTMLElement): DOMRect` - Returns a `DOMRect` representing the element's layout position using `offsetLeft`, `offsetTop`, and `clientWidth`/`clientHeight`.
618
647
  - `isAnchorHtmlElement(element: HTMLElement): element is HTMLAnchorElement` - Determines whether the provided element is an `<a>` tag. Acts as a type guard that narrows the element to `HTMLAnchorElement`.
619
648
  - `isContentEditableHtmlElement(element: HTMLElement): boolean` - Returns `true` if the element has `contenteditable="true"`, making it user-editable and implicitly focusable.
620
- - `isHtmlElementFocusable(element: Nullable<HTMLElement>): boolean` - Checks whether an element is considered focusable according to browser rules. Factors include: visibility, `display`, `disabled`, `tabindex`, native focusable tags, `contenteditable`, and presence of a non-null `tabindex`.
621
- - `getFocusableHtmlElements(container: HTMLElement): HTMLElement[]` - Returns all focusable descendant elements within a container, using `isHtmlElementFocusable` to filter them.
622
- - `moveFocusWithinContainer(direction: FocusMoveDirection, container?: Nullable<HTMLElement>, options?: MoveFocusWithinContainerOptions): void` - Moves focus to the next or previous focusable element within a container. Supports cyclic navigation, optional wrapping control, and custom focus index resolution for advanced keyboard navigation patterns (e.g. roving tabindex).
649
+
650
+ #### File
651
+
652
+ - `downloadFile(file: Downloadable, options?: DownloadFileOptions): void` - Initiates a file download in a browser environment from a URL string or binary source (`Blob` / `MediaSource`). Automatically creates and revokes object URLs when required and safely no-ops in non-DOM environments (e.g. SSR).
653
+
654
+ #### Layout
655
+
623
656
  - `hasXOverflow(element: HTMLElement): boolean` - Checks whether an element has horizontal overflow. Returns `true` if the content overflows beyond the visible width.
624
657
  - `getXOverflowWidth(element: HTMLElement): number` - Calculates the horizontal overflow width of an element. Returns the number of pixels by which the content exceeds the visible width, or `0` when no horizontal overflow exists.
625
658
  - `hasYOverflow(element: HTMLElement): boolean` - Checks whether an element has vertical overflow. Returns `true` if the content overflows beyond the visible height.
626
659
  - `getYOverflowHeight(element: HTMLElement): number` - Calculates the vertical overflow height of an element. Returns the number of pixels by which the content exceeds the visible height, or `0` when no vertical overflow exists.
627
- - `calculateCenterOffset(options: CalculateCenterOffsetOptions): number` - Calculates a clamped offset value that centers an element within a container along a single axis. Returns a negative value suitable for use in a CSS `translate` transform, or `0` when no overflow exists.
628
660
  - `centerElementInContainer(containerElement: HTMLElement, elementToCenter: HTMLElement, options?: CenterElementInContainerOptions): void` - Translates a container so that a target element is visually centered within its visible bounds using CSS transforms. Centering is applied independently per axis and only when an overflow exists.
629
- - `isLocalStorageReadable(): boolean` - Determines whether `localStorage` can be safely read from. This check works even when writes fail (e.g., due to `QuotaExceededError`) and ensures that calling `getItem()` does not throw in restricted environments.
630
- - `getLocalStorageCapabilities(): LocalStorageCapabilities` - Detects the browser's read and write capabilities for `localStorage`. Readability is determined by safe execution of `getItem()`, while writability requires successful `setItem()` and `removeItem()`.
661
+
662
+ #### Transform
663
+
664
+ - `parse2DMatrix(element: HTMLElement): { translateX: number, translateY: number, scaleX: number, scaleY: number, skewX: number, skewY: number }` - Extracts transformation values (translate, scale, skew) from the 2D transformation matrix of a given HTML element.
631
665
 
632
666
  ### File Utilities
633
667
 
668
+ ---
669
+
634
670
  - `isFile(value: unknown): value is File` - Checks if a value is a `File`.
635
671
  - `parseFileName(fileName: string): [baseName: string, extension: string]` - Splits a file name into its base name and extension using the last `.` as the separator. Handles edge cases such as hidden files (`.gitignore`), multi-dot names (`archive.tar.gz`), and names ending with a dot (`"file."`). The extension is returned in lowercase.
636
672
  - `fileListToFiles(fileList: FileList | null): File[]` - Converts a `FileList` object (such as the one returned from an `<input type="file">`) into a standard array of `File` objects. Returns an empty array when the input is `null`.
@@ -640,6 +676,8 @@ function divide(a: number, b: number): number {
640
676
 
641
677
  ### Asynchronous Utilities
642
678
 
679
+ ---
680
+
643
681
  - `isPromise<T = unknown>(value: unknown): value is Promise<T>` - Checks if a value is a `Promise`.
644
682
  - `runSequential<Item, Result>(array: Item[], fn: (item, index, array) => Promise<Result>): Promise<Result[]>` - Runs asynchronous operations on each array item *sequentially* and returns the results in the original order.
645
683
  - `runParallel<Item, Result>(array: Item[], fn: (item, index, array) => Promise<Result>): Promise<Result[]>` - Executes an asynchronous function for each array item *in parallel* and returns a promise of all results.
@@ -650,6 +688,25 @@ function divide(a: number, b: number): number {
650
688
  - `everyAsync<Item>(array: Item[], predicate): Promise<boolean>` - Returns `true` if **all** items in the array pass the async predicate.
651
689
  - `findAsync<Item>(array: Item[], predicate): Promise<Nullable<Item>>` - Returns the first array item that passes the async predicate, or `null` if no match is found.
652
690
 
691
+ ### Intersection Utilities
692
+
693
+ ---
694
+
695
+ - `getDOMRectIntersectionRatio(sourceRect: DOMRect, targetRect: DOMRect): number` - Calculates the ratio of the `targetRect` that is overlapped by the `sourceRect`. Returns a number between `0` (no overlap) and `1` (fully covered).
696
+ - `resolveAxisDelta(delta: AxisDelta, axis: Axis, options: ResolveAxisDeltaOptions): AxisDelta` – Resolves a raw two-dimensional input delta into an axis-aligned delta based on the specified axis. Supports optional vertical-to-horizontal fallback (useful for mouse wheels) and optional direction inversion for synthetic scrolling.
697
+
698
+ ### A11y
699
+
700
+ ---
701
+
702
+ #### Focus
703
+
704
+ - `isHtmlElementFocusable(element: Nullable<HTMLElement>): boolean` - Checks whether an element is considered focusable according to browser rules. Factors include: visibility, `display`, `disabled`, `tabindex`, native focusable tags, `contenteditable`, and presence of a non-null `tabindex`.
705
+ - `getFocusableHtmlElements(container: HTMLElement): HTMLElement[]` - Returns all focusable descendant elements within a container, using `isHtmlElementFocusable` to filter them.
706
+ - `moveFocusWithinContainer(direction: FocusMoveDirection, container?: Nullable<HTMLElement>, options?: MoveFocusWithinContainerOptions): void` - Moves focus to the next or previous focusable element within a container. Supports cyclic navigation, optional wrapping control, and custom focus index resolution for advanced keyboard navigation patterns (e.g. roving tabindex).
707
+
708
+ ---
709
+
653
710
  ## Contributing
654
711
 
655
712
  Contributions are welcome! Please feel free to submit a Pull Request.
package/dist/README.md CHANGED
@@ -546,6 +546,8 @@ function divide(a: number, b: number): number {
546
546
 
547
547
  ### String Utilities
548
548
 
549
+ ---
550
+
549
551
  - `isString(value: unknown): value is string` - Checks if a value is a `string`.
550
552
  - `isNilOrEmptyString(value: unknown): value is null | undefined` - Checks if a value is `null`, `undefined`, or an empty string.
551
553
  - `toKebabCase(input: string): string` - Converts a string to kebab-case.
@@ -555,10 +557,14 @@ function divide(a: number, b: number): number {
555
557
 
556
558
  ### Object Utilities
557
559
 
560
+ ---
561
+
558
562
  - `definedProps<T extends object>(obj: T): DefinedProps<T>` - Creates a new object by removing all properties whose values are `undefined`.
559
563
 
560
564
  ### Array Utilities
561
565
 
566
+ ---
567
+
562
568
  - `isArray(value: unknown): value is unknown[]` - Checks if a value is an array.
563
569
  - `isEmptyArray(value: unknown): value is []` - Checks if a value is an empty array.
564
570
  - `compact<T>(array: (T | Falsy)[]): T[]` – Returns a new array with all falsy values (false, null, undefined, 0, '', NaN) removed, preserving only truthy items of type `T`.
@@ -571,6 +577,8 @@ function divide(a: number, b: number): number {
571
577
 
572
578
  ### Function Utilities
573
579
 
580
+ ---
581
+
574
582
  - `isFunction(value: unknown): value is Function` - Checks if a value is a `function`.
575
583
  - `noop(): void` - A no-operation function.
576
584
  - `not<Args extends any[]>(fn: (...args: Args) => any): (...args: Args) => boolean` - Creates a new function that negates the result of the given predicate function. Useful for logical inversions, e.g., turning `isEven` into `isOdd`.
@@ -582,6 +590,8 @@ function divide(a: number, b: number): number {
582
590
 
583
591
  ### Type Guards
584
592
 
593
+ ---
594
+
585
595
  - `assert(condition: any, message: string): asserts condition` - Asserts that a condition is truthy, throwing an error with the provided message if it's not.
586
596
  - `isNumber(value: unknown): value is number` - Checks if a value is a `number`.
587
597
  - `isBool(value: unknown): value is boolean` - Checks if a value is a `boolean`.
@@ -605,32 +615,58 @@ function divide(a: number, b: number): number {
605
615
 
606
616
  ### Math Utilities
607
617
 
618
+ ---
619
+
608
620
  - `calculateEuclideanDistance(startX: number, startY: number, endX: number, endY: number): number` - Calculates the Euclidean distance between two points.
609
621
  - `calculateMovingSpeed(distance: number, elapsedTime: number): number` - Calculates moving speed.
610
622
  - `calculatePercentage(value: number, percentage: number): number` - Calculates the specified percentage of a value.
611
623
 
624
+ ### ENV
625
+
626
+ ---
627
+
628
+ #### Storage
629
+
630
+ - `isLocalStorageReadable(): boolean` - Determines whether `localStorage` can be safely read from. This check works even when writes fail (e.g., due to `QuotaExceededError`) and ensures that calling `getItem()` does not throw in restricted environments.
631
+ - `getLocalStorageCapabilities(): LocalStorageCapabilities` - Detects the browser's read and write capabilities for `localStorage`. Readability is determined by safe execution of `getItem()`, while writability requires successful `setItem()` and `removeItem()`.
632
+
633
+ ### Geometry
634
+
635
+ ---
636
+
637
+ #### Layout
638
+
639
+ - `calculateCenterOffset(options: CalculateCenterOffsetOptions): number` - Calculates a clamped offset value that centers an element within a container along a single axis. Returns a negative value suitable for use in a CSS `translate` transform, or `0` when no overflow exists.
640
+
612
641
  ### DOM Utilities
613
642
 
614
- - `parse2DMatrix(element: HTMLElement): { translateX: number, translateY: number, scaleX: number, scaleY: number, skewX: number, skewY: number }` - Extracts transformation values (translate, scale, skew) from the 2D transformation matrix of a given HTML element.
643
+ ---
644
+
615
645
  - `cloneBlob(blob: Blob): Blob` - Creates a clone of a Blob object with the same content and type as the original.
616
- - `getDOMRectIntersectionRatio(sourceRect: DOMRect, targetRect: DOMRect): number` - Calculates the ratio of the `targetRect` that is overlapped by the `sourceRect`. Returns a number between `0` (no overlap) and `1` (fully covered).
617
646
  - `getElementOffsetRect(element: HTMLElement): DOMRect` - Returns a `DOMRect` representing the element's layout position using `offsetLeft`, `offsetTop`, and `clientWidth`/`clientHeight`.
618
647
  - `isAnchorHtmlElement(element: HTMLElement): element is HTMLAnchorElement` - Determines whether the provided element is an `<a>` tag. Acts as a type guard that narrows the element to `HTMLAnchorElement`.
619
648
  - `isContentEditableHtmlElement(element: HTMLElement): boolean` - Returns `true` if the element has `contenteditable="true"`, making it user-editable and implicitly focusable.
620
- - `isHtmlElementFocusable(element: Nullable<HTMLElement>): boolean` - Checks whether an element is considered focusable according to browser rules. Factors include: visibility, `display`, `disabled`, `tabindex`, native focusable tags, `contenteditable`, and presence of a non-null `tabindex`.
621
- - `getFocusableHtmlElements(container: HTMLElement): HTMLElement[]` - Returns all focusable descendant elements within a container, using `isHtmlElementFocusable` to filter them.
622
- - `moveFocusWithinContainer(direction: FocusMoveDirection, container?: Nullable<HTMLElement>, options?: MoveFocusWithinContainerOptions): void` - Moves focus to the next or previous focusable element within a container. Supports cyclic navigation, optional wrapping control, and custom focus index resolution for advanced keyboard navigation patterns (e.g. roving tabindex).
649
+
650
+ #### File
651
+
652
+ - `downloadFile(file: Downloadable, options?: DownloadFileOptions): void` - Initiates a file download in a browser environment from a URL string or binary source (`Blob` / `MediaSource`). Automatically creates and revokes object URLs when required and safely no-ops in non-DOM environments (e.g. SSR).
653
+
654
+ #### Layout
655
+
623
656
  - `hasXOverflow(element: HTMLElement): boolean` - Checks whether an element has horizontal overflow. Returns `true` if the content overflows beyond the visible width.
624
657
  - `getXOverflowWidth(element: HTMLElement): number` - Calculates the horizontal overflow width of an element. Returns the number of pixels by which the content exceeds the visible width, or `0` when no horizontal overflow exists.
625
658
  - `hasYOverflow(element: HTMLElement): boolean` - Checks whether an element has vertical overflow. Returns `true` if the content overflows beyond the visible height.
626
659
  - `getYOverflowHeight(element: HTMLElement): number` - Calculates the vertical overflow height of an element. Returns the number of pixels by which the content exceeds the visible height, or `0` when no vertical overflow exists.
627
- - `calculateCenterOffset(options: CalculateCenterOffsetOptions): number` - Calculates a clamped offset value that centers an element within a container along a single axis. Returns a negative value suitable for use in a CSS `translate` transform, or `0` when no overflow exists.
628
660
  - `centerElementInContainer(containerElement: HTMLElement, elementToCenter: HTMLElement, options?: CenterElementInContainerOptions): void` - Translates a container so that a target element is visually centered within its visible bounds using CSS transforms. Centering is applied independently per axis and only when an overflow exists.
629
- - `isLocalStorageReadable(): boolean` - Determines whether `localStorage` can be safely read from. This check works even when writes fail (e.g., due to `QuotaExceededError`) and ensures that calling `getItem()` does not throw in restricted environments.
630
- - `getLocalStorageCapabilities(): LocalStorageCapabilities` - Detects the browser's read and write capabilities for `localStorage`. Readability is determined by safe execution of `getItem()`, while writability requires successful `setItem()` and `removeItem()`.
661
+
662
+ #### Transform
663
+
664
+ - `parse2DMatrix(element: HTMLElement): { translateX: number, translateY: number, scaleX: number, scaleY: number, skewX: number, skewY: number }` - Extracts transformation values (translate, scale, skew) from the 2D transformation matrix of a given HTML element.
631
665
 
632
666
  ### File Utilities
633
667
 
668
+ ---
669
+
634
670
  - `isFile(value: unknown): value is File` - Checks if a value is a `File`.
635
671
  - `parseFileName(fileName: string): [baseName: string, extension: string]` - Splits a file name into its base name and extension using the last `.` as the separator. Handles edge cases such as hidden files (`.gitignore`), multi-dot names (`archive.tar.gz`), and names ending with a dot (`"file."`). The extension is returned in lowercase.
636
672
  - `fileListToFiles(fileList: FileList | null): File[]` - Converts a `FileList` object (such as the one returned from an `<input type="file">`) into a standard array of `File` objects. Returns an empty array when the input is `null`.
@@ -640,6 +676,8 @@ function divide(a: number, b: number): number {
640
676
 
641
677
  ### Asynchronous Utilities
642
678
 
679
+ ---
680
+
643
681
  - `isPromise<T = unknown>(value: unknown): value is Promise<T>` - Checks if a value is a `Promise`.
644
682
  - `runSequential<Item, Result>(array: Item[], fn: (item, index, array) => Promise<Result>): Promise<Result[]>` - Runs asynchronous operations on each array item *sequentially* and returns the results in the original order.
645
683
  - `runParallel<Item, Result>(array: Item[], fn: (item, index, array) => Promise<Result>): Promise<Result[]>` - Executes an asynchronous function for each array item *in parallel* and returns a promise of all results.
@@ -650,6 +688,25 @@ function divide(a: number, b: number): number {
650
688
  - `everyAsync<Item>(array: Item[], predicate): Promise<boolean>` - Returns `true` if **all** items in the array pass the async predicate.
651
689
  - `findAsync<Item>(array: Item[], predicate): Promise<Nullable<Item>>` - Returns the first array item that passes the async predicate, or `null` if no match is found.
652
690
 
691
+ ### Intersection Utilities
692
+
693
+ ---
694
+
695
+ - `getDOMRectIntersectionRatio(sourceRect: DOMRect, targetRect: DOMRect): number` - Calculates the ratio of the `targetRect` that is overlapped by the `sourceRect`. Returns a number between `0` (no overlap) and `1` (fully covered).
696
+ - `resolveAxisDelta(delta: AxisDelta, axis: Axis, options: ResolveAxisDeltaOptions): AxisDelta` – Resolves a raw two-dimensional input delta into an axis-aligned delta based on the specified axis. Supports optional vertical-to-horizontal fallback (useful for mouse wheels) and optional direction inversion for synthetic scrolling.
697
+
698
+ ### A11y
699
+
700
+ ---
701
+
702
+ #### Focus
703
+
704
+ - `isHtmlElementFocusable(element: Nullable<HTMLElement>): boolean` - Checks whether an element is considered focusable according to browser rules. Factors include: visibility, `display`, `disabled`, `tabindex`, native focusable tags, `contenteditable`, and presence of a non-null `tabindex`.
705
+ - `getFocusableHtmlElements(container: HTMLElement): HTMLElement[]` - Returns all focusable descendant elements within a container, using `isHtmlElementFocusable` to filter them.
706
+ - `moveFocusWithinContainer(direction: FocusMoveDirection, container?: Nullable<HTMLElement>, options?: MoveFocusWithinContainerOptions): void` - Moves focus to the next or previous focusable element within a container. Supports cyclic navigation, optional wrapping control, and custom focus index resolution for advanced keyboard navigation patterns (e.g. roving tabindex).
707
+
708
+ ---
709
+
653
710
  ## Contributing
654
711
 
655
712
  Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Collects all focusable descendant elements within a container.
3
+ *
4
+ * The function queries *all* elements under the container and filters them
5
+ * using `isHtmlElementFocusable`, producing a reliable list of elements
6
+ * that can receive keyboard focus in real-world browser conditions.
7
+ *
8
+ * @param container - The root container whose focusable children will be found.
9
+ *
10
+ * @returns An array of focusable HTMLElements in DOM order.
11
+ */
12
+ export declare const getFocusableHtmlElements: (container: HTMLElement) => HTMLElement[];
@@ -0,0 +1,3 @@
1
+ export * from './is-html-element-focusable';
2
+ export * from './get-focusable-html-elements';
3
+ export * from './move-focus-within-container';
@@ -0,0 +1,21 @@
1
+ import type { Nullable } from '../../types';
2
+ export declare const FOCUSABLE_HTML_TAGS: string[];
3
+ /**
4
+ * Determines whether an HTMLElement is focusable under standard browser rules.
5
+ *
6
+ * The function checks a combination of factors:
7
+ * - The element must be rendered (not `display: none` or `visibility: hidden`).
8
+ * - Disabled form controls are never focusable.
9
+ * - Elements with `tabindex="-1"` are intentionally removed from the focus order.
10
+ * - Certain native HTML elements are inherently focusable (e.g. inputs, buttons, anchors with `href`).
11
+ * - Elements with `contenteditable="true"` are treated as focusable.
12
+ * - Any element with a valid `tabindex` (not null) is considered focusable.
13
+ *
14
+ * This logic approximates how browsers and the accessibility tree
15
+ * determine real-world focusability—not just tabindex presence.
16
+ *
17
+ * @param element - The element to test. `null` or `undefined` will return `false`.
18
+ *
19
+ * @returns Whether the element is focusable.
20
+ */
21
+ export declare const isHtmlElementFocusable: (element: Nullable<HTMLElement>) => boolean;
@@ -0,0 +1,52 @@
1
+ import type { Nullable } from '../../types';
2
+ export type FocusMoveDirection = 'next' | 'previous';
3
+ export interface MoveFocusWithinContainerOptions {
4
+ /**
5
+ * Whether focus navigation should wrap around when reaching
6
+ * the beginning or end of the focusable elements list.
7
+ *
8
+ * When enabled, moving past the last element focuses the first,
9
+ * and moving before the first focuses the last.
10
+ *
11
+ * @default true
12
+ */
13
+ wrap?: boolean;
14
+ /**
15
+ * Custom resolver for determining the next focus index.
16
+ *
17
+ * When provided, this function overrides the default navigation logic
18
+ * and receives full control over how the focus moves.
19
+ *
20
+ * @param currentIndex - Index of the currently focused element.
21
+ * @param direction - Direction in which focus is moving.
22
+ * @param elements - Ordered list of focusable elements within the container.
23
+ *
24
+ * @returns The index of the element to focus next, or `null` to prevent focus movement.
25
+ */
26
+ getNextIndex?: (currentIndex: number, direction: FocusMoveDirection, elements: HTMLElement[]) => Nullable<number>;
27
+ }
28
+ /**
29
+ * Moves focus to the next or previous focusable element within a container.
30
+ *
31
+ * This utility is commonly used to implement accessible keyboard navigation patterns such as:
32
+ * - roving tabindex
33
+ * - custom dropdowns
34
+ * - tablists
35
+ * - menus
36
+ * - horizontal or vertical navigation groups
37
+ *
38
+ * Focus movement is scoped to a container and operates on the list of
39
+ * focusable descendants returned by `getFocusableHtmlElements`.
40
+ *
41
+ * @param direction - Direction in which focus should move (`'next'` or `'previous'`).
42
+ * @param container - Optional container that defines the focus scope.
43
+ * If omitted, the parent element of the currently focused element is used.
44
+ * @param options - Optional configuration controlling wrapping behavior and custom index resolution.
45
+ *
46
+ * @remarks
47
+ * - This function reads from and mutates the document's focus state.
48
+ * - If no active element exists, no container can be resolved,
49
+ * or the active element is not part of the focusable set, no action is taken.
50
+ * - When `getNextIndex` is provided, it fully overrides the default wrapping and directional logic.
51
+ */
52
+ export declare const moveFocusWithinContainer: (direction: FocusMoveDirection, container?: Nullable<HTMLElement>, { wrap, getNextIndex }?: MoveFocusWithinContainerOptions) => void;
@@ -0,0 +1 @@
1
+ export * from './focus';
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Creates a clone of a Blob object.
3
+ *
4
+ * @param blob - The Blob object to clone.
5
+ *
6
+ * @returns A new Blob with the same content and type as the original.
7
+ */
8
+ export declare const cloneBlob: (blob: Blob) => Blob;
9
+ /**
10
+ * Returns the bounding DOMRect of an element based on offset and client dimensions.
11
+ *
12
+ * This utility is useful when you need a stable, layout-based rect
13
+ * without triggering a reflow via `getBoundingClientRect()`.
14
+ *
15
+ * @param element - The target HTML element.
16
+ * @returns A `DOMRect` representing the element’s offset position and size.
17
+ */
18
+ export declare const getElementOffsetRect: (element: HTMLElement) => DOMRect;
19
+ /**
20
+ * Determines whether the given HTMLElement is an HTMLAnchorElement.
21
+ *
22
+ * Acts as a type guard so that TypeScript narrows `element` to
23
+ * `HTMLAnchorElement` when the function returns `true`.
24
+ *
25
+ * An element qualifies as an anchor by having a tag name of `"A"`.
26
+ *
27
+ * @param element - The element to test.
28
+ *
29
+ * @returns Whether the element is an anchor element.
30
+ */
31
+ export declare const isAnchorHtmlElement: (element: HTMLElement) => element is HTMLAnchorElement;
32
+ /**
33
+ * Checks whether an element is explicitly marked as contenteditable.
34
+ *
35
+ * Browsers treat elements with `contenteditable="true"` as focusable,
36
+ * even if they are not normally keyboard-focusable.
37
+ *
38
+ * @param element - The element to inspect.
39
+ *
40
+ * @returns True if `contenteditable="true"` is set.
41
+ */
42
+ export declare const isContentEditableHtmlElement: (element: HTMLElement) => boolean;
@@ -0,0 +1,35 @@
1
+ export type Downloadable = Blob | MediaSource | string;
2
+ export interface DownloadFileOptions {
3
+ /**
4
+ * Suggested filename for the downloaded file.
5
+ *
6
+ * When provided, the browser will attempt to save the file using this name.
7
+ * If omitted and the source is a URL string, the browser may infer the name
8
+ * from the URL.
9
+ */
10
+ fileName?: string;
11
+ /**
12
+ * Target browsing context for the download link.
13
+ */
14
+ target?: '_self' | '_blank';
15
+ }
16
+ /**
17
+ * Initiates a file download in a browser environment.
18
+ *
19
+ * This utility supports downloading from:
20
+ * - a URL string
21
+ * - a `Blob`
22
+ * - a `MediaSource`
23
+ *
24
+ * For non-string inputs, an object URL is created temporarily and
25
+ * automatically revoked after the download is triggered.
26
+ *
27
+ * @remarks
28
+ * - This function performs direct DOM manipulation and must be executed in a browser environment.
29
+ * - In non-DOM contexts (e.g. SSR), the function exits without side effects.
30
+ * - Object URLs are revoked asynchronously to avoid Safari-related issues.
31
+ *
32
+ * @param file - The file source to download (URL string or binary object).
33
+ * @param options - Optional configuration controlling filename and link target.
34
+ */
35
+ export declare const downloadFile: (file: Downloadable, { fileName, target }?: DownloadFileOptions) => void;
@@ -0,0 +1 @@
1
+ export * from './download-file';
@@ -0,0 +1,4 @@
1
+ export * from './dom';
2
+ export * from './file';
3
+ export * from './layout';
4
+ export * from './transform';
@@ -0,0 +1,30 @@
1
+ type Axis = 'x' | 'y' | 'both';
2
+ export interface CenterElementInContainerOptions {
3
+ /**
4
+ * Axis (or axes) along which centering is applied.
5
+ *
6
+ * @default 'both'
7
+ */
8
+ axis?: Axis;
9
+ }
10
+ /**
11
+ * Translates a container so that a target element is visually centered within its visible bounds.
12
+ *
13
+ * Centering is achieved by applying a CSS `transform: translate(...)` to the
14
+ * container element rather than using native scrolling.
15
+ *
16
+ * ### Behavior
17
+ * - Centering is calculated independently for each enabled axis.
18
+ * - Translation is applied only when the container content overflows on that axis.
19
+ * - When no overflow exists, the container remains untransformed for that axis.
20
+ *
21
+ * ### Notes
22
+ * - This function performs immediate DOM reads and writes.
23
+ * - The resulting transform is clamped to valid scrollable bounds.
24
+ *
25
+ * @param containerElement - The container whose content is translated.
26
+ * @param elementToCenter - The descendant element to align to the container’s center.
27
+ * @param options - Optional configuration controlling which axis or axes are centered.
28
+ */
29
+ export declare const centerElementInContainer: (containerElement: HTMLElement, elementToCenter: HTMLElement, { axis }?: CenterElementInContainerOptions) => void;
30
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from './overflow';
2
+ export * from './center-element-in-container';
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Checks whether an element has horizontal overflow.
3
+ *
4
+ * @param element - The element to check.
5
+ *
6
+ * @returns `true` if the content overflows horizontally.
7
+ */
8
+ export declare const hasXOverflow: (element: HTMLElement) => boolean;
9
+ /**
10
+ * Calculates the horizontal overflow width of an element.
11
+ *
12
+ * The overflow width represents how much wider the content is compared
13
+ * to the visible container area.
14
+ *
15
+ * @param element - The scrollable container element.
16
+ *
17
+ * @returns The overflow width in pixels. Returns `0` when the content does not overflow horizontally.
18
+ */
19
+ export declare const getXOverflowWidth: (element: HTMLElement) => number;
20
+ /**
21
+ * Checks whether an element has vertical overflow.
22
+ *
23
+ * @param element - The element to check.
24
+ *
25
+ * @returns `true` if the content overflows vertically.
26
+ */
27
+ export declare const hasYOverflow: (element: HTMLElement) => boolean;
28
+ /**
29
+ * Calculates the vertical overflow height of an element.
30
+ *
31
+ * The overflow height represents how much taller the content is compared
32
+ * to the visible container area.
33
+ *
34
+ * @param element - The scrollable container element.
35
+ *
36
+ * @returns The overflow height in pixels. Returns `0` when the content does not overflow vertically.
37
+ */
38
+ export declare const getYOverflowHeight: (element: HTMLElement) => number;
@@ -0,0 +1 @@
1
+ export * from './parse-2d-matrix';
@@ -0,0 +1,25 @@
1
+ interface HTMLElementTransformationValues {
2
+ translateX: number;
3
+ translateY: number;
4
+ scaleX: number;
5
+ scaleY: number;
6
+ skewX: number;
7
+ skewY: number;
8
+ }
9
+ /**
10
+ * Extracts transformation values (translate, scale, skew) from the 2D transformation matrix of a given HTML element.
11
+ *
12
+ * Only works with 2D transforms (i.e., `matrix(a, b, c, d, e, f)`).
13
+ *
14
+ * @param element - The element with a CSS transform applied.
15
+ * @returns An object with parsed transformation values.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * const values = parse2DMatrix(myElement);
20
+ * console.log(values.translateX);
21
+ * console.log(values.scaleX);
22
+ * ```
23
+ */
24
+ export declare const parse2DMatrix: (element: HTMLElement) => HTMLElementTransformationValues;
25
+ export {};
@@ -0,0 +1 @@
1
+ export * from './storage';
@@ -0,0 +1 @@
1
+ export * from './local-storage';
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Determines whether the browser environment allows safe read access to
3
+ * `localStorage`. Some platforms (e.g., Safari Private Mode, sandboxed iframes)
4
+ * expose `localStorage` but still throw when accessed.
5
+ *
6
+ * This function **only tests read access**, making it safe even when write
7
+ * operations would fail due to `QuotaExceededError` or storage restrictions.
8
+ *
9
+ * @returns `true` if `localStorage` exists and calling `getItem()` does not
10
+ * throw; otherwise `false`.
11
+ */
12
+ export declare const isLocalStorageReadable: () => boolean;
13
+ interface LocalStorageCapabilities {
14
+ readable: boolean;
15
+ writable: boolean;
16
+ }
17
+ interface LocalStorageCapabilities {
18
+ readable: boolean;
19
+ writable: boolean;
20
+ }
21
+ /**
22
+ * Determines whether the browser's `localStorage` supports safe read and write operations.
23
+ * This function performs two independent checks:
24
+ *
25
+ * **1. Readability**
26
+ * - Verified by calling `localStorage.getItem()` inside a `try` block.
27
+ * - Fails in environments where storage access throws immediately (e.g., disabled storage,
28
+ * sandboxed iframes, strict privacy modes, SSR).
29
+ *
30
+ * **2. Writeability**
31
+ * - Verified by attempting to `setItem()` and then `removeItem()` using a temporary key.
32
+ * - Can fail due to:
33
+ * - `QuotaExceededError` when storage is full.
34
+ * - Disabled write access (e.g., Safari Private Mode).
35
+ * - Security-restricted contexts (third-party frames, hardened privacy settings)
36
+ *
37
+ * @returns An object describing the detected `localStorage` capabilities.
38
+ */
39
+ export declare const getLocalStorageCapabilities: () => LocalStorageCapabilities;
40
+ export {};
@@ -0,0 +1 @@
1
+ export * from './layout';