You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

@rc-component/util

Package Overview
Dependencies
Maintainers
5
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rc-component/util - npm Package Compare versions

Comparing version
1.5.0
to
1.6.0
+11
-7
es/Dom/focus.d.ts
export declare function getFocusNodeList(node: HTMLElement, includePositive?: boolean): HTMLElement[];
/** @deprecated Do not use since this may failed when used in async */
export declare function saveLastFocusNode(): void;
/** @deprecated Do not use since this may failed when used in async */
export declare function clearLastFocusNode(): void;
/** @deprecated Do not use since this may failed when used in async */
export declare function backLastFocusNode(): void;
export declare function limitTabRange(node: HTMLElement, e: KeyboardEvent): void;
export interface InputFocusOptions extends FocusOptions {

@@ -16,1 +9,12 @@ cursor?: 'start' | 'end' | 'all';

export declare function triggerFocus(element?: HTMLElement, option?: InputFocusOptions): void;
/**
* Lock focus in the element.
* It will force back to the first focusable element when focus leaves the element.
*/
export declare function lockFocus(element: HTMLElement): VoidFunction;
/**
* Lock focus within an element.
* When locked, focus will be restricted to focusable elements within the specified element.
* If multiple elements are locked, only the last locked element will be effective.
*/
export declare function useLockFocus(lock: boolean, getElement: () => HTMLElement | null): void;

@@ -0,1 +1,2 @@

import { useEffect } from 'react';
import isVisible from "./isVisible";

@@ -42,40 +43,2 @@ function focusable(node, includePositive = false) {

}
let lastFocusElement = null;
/** @deprecated Do not use since this may failed when used in async */
export function saveLastFocusNode() {
lastFocusElement = document.activeElement;
}
/** @deprecated Do not use since this may failed when used in async */
export function clearLastFocusNode() {
lastFocusElement = null;
}
/** @deprecated Do not use since this may failed when used in async */
export function backLastFocusNode() {
if (lastFocusElement) {
try {
// 元素可能已经被移动了
lastFocusElement.focus();
/* eslint-disable no-empty */
} catch (e) {
// empty
}
/* eslint-enable no-empty */
}
}
export function limitTabRange(node, e) {
if (e.keyCode === 9) {
const tabNodeList = getFocusNodeList(node);
const lastTabNode = tabNodeList[e.shiftKey ? 0 : tabNodeList.length - 1];
const leavingTab = lastTabNode === document.activeElement || node === document.activeElement;
if (leavingTab) {
const target = tabNodeList[e.shiftKey ? tabNodeList.length - 1 : 0];
target.focus();
e.preventDefault();
}
}
}
// Used for `rc-input` `rc-textarea` `rc-input-number`

@@ -106,2 +69,90 @@ /**

}
}
// ======================================================
// == Lock Focus ==
// ======================================================
let lastFocusElement = null;
let focusElements = [];
function getLastElement() {
return focusElements[focusElements.length - 1];
}
function hasFocus(element) {
const {
activeElement
} = document;
return element === activeElement || element.contains(activeElement);
}
function syncFocus() {
const lastElement = getLastElement();
const {
activeElement
} = document;
if (lastElement && !hasFocus(lastElement)) {
const focusableList = getFocusNodeList(lastElement);
const matchElement = focusableList.includes(lastFocusElement) ? lastFocusElement : focusableList[0];
matchElement?.focus();
} else {
lastFocusElement = activeElement;
}
}
function onWindowKeyDown(e) {
if (e.key === 'Tab') {
const {
activeElement
} = document;
const lastElement = getLastElement();
const focusableList = getFocusNodeList(lastElement);
const last = focusableList[focusableList.length - 1];
if (e.shiftKey && activeElement === focusableList[0]) {
// Tab backward on first focusable element
lastFocusElement = last;
} else if (!e.shiftKey && activeElement === last) {
// Tab forward on last focusable element
lastFocusElement = focusableList[0];
}
}
}
/**
* Lock focus in the element.
* It will force back to the first focusable element when focus leaves the element.
*/
export function lockFocus(element) {
if (element) {
// Refresh focus elements
focusElements = focusElements.filter(ele => ele !== element);
focusElements.push(element);
// Just add event since it will de-duplicate
window.addEventListener('focusin', syncFocus);
window.addEventListener('keydown', onWindowKeyDown, true);
syncFocus();
}
// Always return unregister function
return () => {
lastFocusElement = null;
focusElements = focusElements.filter(ele => ele !== element);
if (focusElements.length === 0) {
window.removeEventListener('focusin', syncFocus);
window.removeEventListener('keydown', onWindowKeyDown, true);
}
};
}
/**
* Lock focus within an element.
* When locked, focus will be restricted to focusable elements within the specified element.
* If multiple elements are locked, only the last locked element will be effective.
*/
export function useLockFocus(lock, getElement) {
useEffect(() => {
if (lock) {
const element = getElement();
if (element) {
return lockFocus(element);
}
}
}, [lock]);
}

@@ -1,7 +0,5 @@

type ScrollBarSize = {
export default function getScrollBarSize(fresh?: boolean): number;
export declare function getTargetScrollBarSize(target: HTMLElement): {
width: number;
height: number;
};
export default function getScrollBarSize(fresh?: boolean): number;
export declare function getTargetScrollBarSize(target: HTMLElement): ScrollBarSize;
export {};
export declare function getFocusNodeList(node: HTMLElement, includePositive?: boolean): HTMLElement[];
/** @deprecated Do not use since this may failed when used in async */
export declare function saveLastFocusNode(): void;
/** @deprecated Do not use since this may failed when used in async */
export declare function clearLastFocusNode(): void;
/** @deprecated Do not use since this may failed when used in async */
export declare function backLastFocusNode(): void;
export declare function limitTabRange(node: HTMLElement, e: KeyboardEvent): void;
export interface InputFocusOptions extends FocusOptions {

@@ -16,1 +9,12 @@ cursor?: 'start' | 'end' | 'all';

export declare function triggerFocus(element?: HTMLElement, option?: InputFocusOptions): void;
/**
* Lock focus in the element.
* It will force back to the first focusable element when focus leaves the element.
*/
export declare function lockFocus(element: HTMLElement): VoidFunction;
/**
* Lock focus within an element.
* When locked, focus will be restricted to focusable elements within the specified element.
* If multiple elements are locked, only the last locked element will be effective.
*/
export declare function useLockFocus(lock: boolean, getElement: () => HTMLElement | null): void;

@@ -6,8 +6,7 @@ "use strict";

});
exports.backLastFocusNode = backLastFocusNode;
exports.clearLastFocusNode = clearLastFocusNode;
exports.getFocusNodeList = getFocusNodeList;
exports.limitTabRange = limitTabRange;
exports.saveLastFocusNode = saveLastFocusNode;
exports.lockFocus = lockFocus;
exports.triggerFocus = triggerFocus;
exports.useLockFocus = useLockFocus;
var _react = require("react");
var _isVisible = _interopRequireDefault(require("./isVisible"));

@@ -55,40 +54,2 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

}
let lastFocusElement = null;
/** @deprecated Do not use since this may failed when used in async */
function saveLastFocusNode() {
lastFocusElement = document.activeElement;
}
/** @deprecated Do not use since this may failed when used in async */
function clearLastFocusNode() {
lastFocusElement = null;
}
/** @deprecated Do not use since this may failed when used in async */
function backLastFocusNode() {
if (lastFocusElement) {
try {
// 元素可能已经被移动了
lastFocusElement.focus();
/* eslint-disable no-empty */
} catch (e) {
// empty
}
/* eslint-enable no-empty */
}
}
function limitTabRange(node, e) {
if (e.keyCode === 9) {
const tabNodeList = getFocusNodeList(node);
const lastTabNode = tabNodeList[e.shiftKey ? 0 : tabNodeList.length - 1];
const leavingTab = lastTabNode === document.activeElement || node === document.activeElement;
if (leavingTab) {
const target = tabNodeList[e.shiftKey ? tabNodeList.length - 1 : 0];
target.focus();
e.preventDefault();
}
}
}
// Used for `rc-input` `rc-textarea` `rc-input-number`

@@ -119,2 +80,90 @@ /**

}
}
// ======================================================
// == Lock Focus ==
// ======================================================
let lastFocusElement = null;
let focusElements = [];
function getLastElement() {
return focusElements[focusElements.length - 1];
}
function hasFocus(element) {
const {
activeElement
} = document;
return element === activeElement || element.contains(activeElement);
}
function syncFocus() {
const lastElement = getLastElement();
const {
activeElement
} = document;
if (lastElement && !hasFocus(lastElement)) {
const focusableList = getFocusNodeList(lastElement);
const matchElement = focusableList.includes(lastFocusElement) ? lastFocusElement : focusableList[0];
matchElement?.focus();
} else {
lastFocusElement = activeElement;
}
}
function onWindowKeyDown(e) {
if (e.key === 'Tab') {
const {
activeElement
} = document;
const lastElement = getLastElement();
const focusableList = getFocusNodeList(lastElement);
const last = focusableList[focusableList.length - 1];
if (e.shiftKey && activeElement === focusableList[0]) {
// Tab backward on first focusable element
lastFocusElement = last;
} else if (!e.shiftKey && activeElement === last) {
// Tab forward on last focusable element
lastFocusElement = focusableList[0];
}
}
}
/**
* Lock focus in the element.
* It will force back to the first focusable element when focus leaves the element.
*/
function lockFocus(element) {
if (element) {
// Refresh focus elements
focusElements = focusElements.filter(ele => ele !== element);
focusElements.push(element);
// Just add event since it will de-duplicate
window.addEventListener('focusin', syncFocus);
window.addEventListener('keydown', onWindowKeyDown, true);
syncFocus();
}
// Always return unregister function
return () => {
lastFocusElement = null;
focusElements = focusElements.filter(ele => ele !== element);
if (focusElements.length === 0) {
window.removeEventListener('focusin', syncFocus);
window.removeEventListener('keydown', onWindowKeyDown, true);
}
};
}
/**
* Lock focus within an element.
* When locked, focus will be restricted to focusable elements within the specified element.
* If multiple elements are locked, only the last locked element will be effective.
*/
function useLockFocus(lock, getElement) {
(0, _react.useEffect)(() => {
if (lock) {
const element = getElement();
if (element) {
return lockFocus(element);
}
}
}, [lock]);
}

@@ -1,7 +0,5 @@

type ScrollBarSize = {
export default function getScrollBarSize(fresh?: boolean): number;
export declare function getTargetScrollBarSize(target: HTMLElement): {
width: number;
height: number;
};
export default function getScrollBarSize(fresh?: boolean): number;
export declare function getTargetScrollBarSize(target: HTMLElement): ScrollBarSize;
export {};
{
"name": "@rc-component/util",
"version": "1.5.0",
"version": "1.6.0",
"description": "Common Utils For React Component",

@@ -5,0 +5,0 @@ "keywords": [