@clayui/shared
Advanced tools
Comparing version 3.82.0 to 3.83.0
@@ -24,6 +24,8 @@ /** | ||
export { useMousePosition } from './useMousePosition'; | ||
export { useNavigation } from './useNavigation'; | ||
export { useNavigation, isTypeahead, getFocusableList } from './useNavigation'; | ||
export { useOverlayPosition } from './useOverlayPositon'; | ||
export { useHover } from './useHover'; | ||
export { useIsMobileDevice } from './useIsMobileDevice'; | ||
export type { AlignPoints } from './useOverlayPositon'; | ||
export type { IBaseProps as IPortalBaseProps } from './Portal'; | ||
export type { InternalDispatch } from './useInternalState'; |
@@ -66,2 +66,14 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "getFocusableList", { | ||
enumerable: true, | ||
get: function get() { | ||
return _useNavigation.getFocusableList; | ||
} | ||
}); | ||
Object.defineProperty(exports, "isTypeahead", { | ||
enumerable: true, | ||
get: function get() { | ||
return _useNavigation.isTypeahead; | ||
} | ||
}); | ||
exports.noop = void 0; | ||
@@ -98,2 +110,8 @@ Object.defineProperty(exports, "observeRect", { | ||
}); | ||
Object.defineProperty(exports, "useHover", { | ||
enumerable: true, | ||
get: function get() { | ||
return _useHover.useHover; | ||
} | ||
}); | ||
Object.defineProperty(exports, "useId", { | ||
@@ -117,2 +135,8 @@ enumerable: true, | ||
}); | ||
Object.defineProperty(exports, "useIsMobileDevice", { | ||
enumerable: true, | ||
get: function get() { | ||
return _useIsMobileDevice.useIsMobileDevice; | ||
} | ||
}); | ||
Object.defineProperty(exports, "useMousePosition", { | ||
@@ -177,2 +201,6 @@ enumerable: true, | ||
var _useHover = require("./useHover"); | ||
var _useIsMobileDevice = require("./useIsMobileDevice"); | ||
/** | ||
@@ -179,0 +207,0 @@ * SPDX-FileCopyrightText: © 2019 Liferay, Inc. <https://liferay.com> |
@@ -13,3 +13,3 @@ /** | ||
menuRef: React.RefObject<HTMLElement>; | ||
onClose: () => void; | ||
onClose: (action: 'escape' | 'blur') => void; | ||
portalRef?: React.RefObject<HTMLElement>; | ||
@@ -16,0 +16,0 @@ suppress?: Array<React.RefObject<HTMLElement>>; |
@@ -30,9 +30,2 @@ "use strict"; | ||
/** | ||
* Inert is a new native feature to better handle DOM arias that are not | ||
* assertive to a SR or that should ignore any user interaction. | ||
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/inert | ||
*/ | ||
var hasInertSupport = typeof window !== 'undefined' && // @ts-ignore | ||
typeof document.createElement('div').inert === 'boolean'; | ||
/** | ||
* Overlay component is used for components like dialog and modal. | ||
@@ -42,3 +35,2 @@ * For example, Autocomplete, DatePicker, ColorPicker, DropDown are components | ||
*/ | ||
function Overlay(_ref) { | ||
@@ -64,3 +56,3 @@ var children = _ref.children, | ||
if (portalRef && !((_portalRef$current = portalRef.current) !== null && _portalRef$current !== void 0 && _portalRef$current.contains(event.target)) && triggerRef.current && !triggerRef.current.contains(event.target)) { | ||
onClose(); | ||
onClose('blur'); | ||
} | ||
@@ -85,3 +77,3 @@ }, [onClose]), isOpen, true, [isOpen, onClose]); | ||
onClose(); | ||
onClose('escape'); | ||
} | ||
@@ -92,3 +84,3 @@ }, [onClose]), isOpen && isKeyboardDismiss, true, [isOpen, onClose]); | ||
onInteract: function onInteract() { | ||
onClose(); | ||
onClose('blur'); | ||
}, | ||
@@ -102,5 +94,7 @@ ref: portalRef !== null && portalRef !== void 0 ? portalRef : menuRef, | ||
return ref.current; | ||
}) : menuRef.current; | ||
}) : menuRef.current; // Inert is a new native feature to better handle DOM arias that are not | ||
// assertive to a SR or that should ignore any user interaction. | ||
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/inert | ||
if (isModal && hasInertSupport) { | ||
if (isModal && (0, _ariaHidden.supportsInert)()) { | ||
unsuppressCallbackRef.current = (0, _ariaHidden.suppressOthers)(elements); | ||
@@ -107,0 +101,0 @@ return function () { |
@@ -5,3 +5,3 @@ /** | ||
*/ | ||
/// <reference types="react" /> | ||
import React from 'react'; | ||
declare type Props<T> = { | ||
@@ -17,5 +17,10 @@ /** | ||
/** | ||
* The id of the currently active item that is highlighted. | ||
* Typically used when navigation is not done via focus. | ||
*/ | ||
active?: string; | ||
/** | ||
* Reference of the parent element of the focusable elements. | ||
*/ | ||
containeRef: React.MutableRefObject<T>; | ||
containerRef: React.MutableRefObject<T>; | ||
/** | ||
@@ -26,2 +31,6 @@ * Flag to indicate if navigation should loop. | ||
/** | ||
* Callback is called when the intent is to move to the element. | ||
*/ | ||
onNavigate?: (element: HTMLElement, index: number | null) => void; | ||
/** | ||
* Indicates whether the element's orientation is horizontal or vertical. | ||
@@ -40,5 +49,10 @@ */ | ||
}; | ||
export declare function useNavigation<T extends HTMLElement | null>({ activation, containeRef, loop, orientation, typeahead, visible, }: Props<T>): { | ||
onKeyDown: (event: React.KeyboardEvent<HTMLElement>) => void; | ||
export declare function useNavigation<T extends HTMLElement | null>({ activation, active, containerRef, loop, onNavigate, orientation, typeahead, visible, }: Props<T>): { | ||
accessibilityFocus: (tab: HTMLElement, tabs?: Array<HTMLElement>) => void; | ||
navigationProps: { | ||
onKeyDown: (event: React.KeyboardEvent<HTMLElement>) => void; | ||
}; | ||
}; | ||
export declare function getFocusableList<T extends HTMLElement | null>(containeRef: React.MutableRefObject<T>): HTMLElement[]; | ||
export declare function isTypeahead(event: React.KeyboardEvent<HTMLElement>): boolean; | ||
export {}; |
@@ -6,2 +6,4 @@ "use strict"; | ||
}); | ||
exports.getFocusableList = getFocusableList; | ||
exports.isTypeahead = isTypeahead; | ||
exports.useNavigation = useNavigation; | ||
@@ -33,5 +35,7 @@ | ||
activation = _ref$activation === void 0 ? 'manual' : _ref$activation, | ||
containeRef = _ref.containeRef, | ||
active = _ref.active, | ||
containerRef = _ref.containerRef, | ||
_ref$loop = _ref.loop, | ||
loop = _ref$loop === void 0 ? false : _ref$loop, | ||
onNavigate = _ref.onNavigate, | ||
_ref$orientation = _ref.orientation, | ||
@@ -46,5 +50,8 @@ orientation = _ref$orientation === void 0 ? 'horizontal' : _ref$orientation, | ||
var prevIndexRef = (0, _react.useRef)(-1); | ||
var matchIndexRef = (0, _react.useRef)(null); | ||
var matchIndexRef = (0, _react.useRef)(null); // An event can be scheduled when the content is not visible in the DOM, it | ||
// will be executed in sequence after the element is visible in the DOM. | ||
var pendingEventStack = (0, _react.useRef)([]); | ||
(0, _react.useEffect)(function () { | ||
if (visible) { | ||
if (!visible) { | ||
clearTimeout(timeoutIdRef.current); | ||
@@ -55,4 +62,21 @@ matchIndexRef.current = null; | ||
}, [visible]); | ||
var accessibilityFocus = (0, _react.useCallback)(function (tab, tabs) { | ||
onNavigate(tab, tabs ? tabs.indexOf(tab) : null); | ||
var child = containerRef.current.firstElementChild; | ||
if (isScrollable(child)) { | ||
maintainScrollVisibility(tab, child); | ||
} | ||
if (!isElementInView(tab)) { | ||
tab.scrollIntoView({ | ||
behavior: 'smooth', | ||
block: 'nearest' | ||
}); | ||
} | ||
}, []); | ||
var onKeyDown = (0, _react.useCallback)(function (event) { | ||
if (!containeRef.current) { | ||
if (!containerRef.current) { | ||
event.persist(); | ||
pendingEventStack.current.push(event); | ||
return; | ||
@@ -65,11 +89,3 @@ } | ||
if (keys.includes(event.key) || typeahead && !alternativeKeys.includes(event.key)) { | ||
var tabs = Array.from(containeRef.current.querySelectorAll(_useFocusManagement.FOCUSABLE_ELEMENTS.join(','))).filter(function (element) { | ||
return (0, _useFocusManagement.isFocusable)({ | ||
contentEditable: element.contentEditable, | ||
disabled: element.getAttribute('disabled') !== null, | ||
offsetParent: element.offsetParent, | ||
tabIndex: 0, | ||
tagName: element.tagName | ||
}); | ||
}); | ||
var tabs = getFocusableList(containerRef); | ||
var tab; | ||
@@ -86,2 +102,8 @@ | ||
if (typeof active === 'string') { | ||
position = tabs.findIndex(function (element) { | ||
return element.getAttribute('id') === active; | ||
}); | ||
} | ||
if (position === -1) { | ||
@@ -114,3 +136,3 @@ break; | ||
if (!event.currentTarget.contains(target)) { | ||
if (event.currentTarget && !event.currentTarget.contains(target)) { | ||
return; | ||
@@ -130,2 +152,4 @@ } | ||
event.stopPropagation(); | ||
if (stringRef.current === event.key) { | ||
@@ -145,5 +169,5 @@ stringRef.current = ''; | ||
tab = orderedList.find(function (element) { | ||
var _element$innerText; | ||
var _ref2, _element$innerText; | ||
return ((_element$innerText = element.innerText) === null || _element$innerText === void 0 ? void 0 : _element$innerText.toLowerCase().indexOf(stringRef.current.toLocaleLowerCase())) === 0; | ||
return ((_ref2 = (_element$innerText = element.innerText) !== null && _element$innerText !== void 0 ? _element$innerText : element.textContent) === null || _ref2 === void 0 ? void 0 : _ref2.toLowerCase().indexOf(stringRef.current.toLocaleLowerCase())) === 0; | ||
}); | ||
@@ -161,4 +185,9 @@ | ||
event.preventDefault(); | ||
tab.focus(); | ||
if (onNavigate) { | ||
accessibilityFocus(tab, tabs); | ||
} else { | ||
tab.focus(); | ||
} | ||
if (activation === 'automatic') { | ||
@@ -169,6 +198,73 @@ tab.click(); | ||
} | ||
}, []); | ||
return { | ||
}, [active]); | ||
(0, _react.useEffect)(function () { | ||
// Moves the scroll to the element with visual "focus" if it exists. | ||
if (visible && containerRef.current && active && onNavigate) { | ||
var child = containerRef.current.firstElementChild; | ||
var activeElement = containerRef.current.querySelector("#".concat(active)); | ||
if (activeElement && isScrollable(child)) { | ||
maintainScrollVisibility(activeElement, child); | ||
} | ||
} | ||
}, [visible]); | ||
(0, _react.useEffect)(function () { | ||
if (visible && pendingEventStack.current.length !== 0) { | ||
for (var _index = 0; _index < pendingEventStack.current.length; _index++) { | ||
var event = pendingEventStack.current.shift(); | ||
onKeyDown(event); | ||
} | ||
} | ||
}, [visible]); | ||
var navigationProps = { | ||
onKeyDown: onKeyDown | ||
}; | ||
return { | ||
accessibilityFocus: accessibilityFocus, | ||
navigationProps: navigationProps | ||
}; | ||
} | ||
function getFocusableList(containeRef) { | ||
if (!containeRef.current) { | ||
return []; | ||
} | ||
return Array.from(containeRef.current.querySelectorAll(_useFocusManagement.FOCUSABLE_ELEMENTS.join(','))).filter(function (element) { | ||
return (0, _useFocusManagement.isFocusable)({ | ||
contentEditable: element.contentEditable, | ||
disabled: element.getAttribute('disabled') !== null, | ||
offsetParent: element.offsetParent, | ||
tabIndex: 0, | ||
tagName: element.tagName | ||
}); | ||
}); | ||
} | ||
function isTypeahead(event) { | ||
return event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey; | ||
} | ||
function isElementInView(element) { | ||
var bounding = element.getBoundingClientRect(); | ||
return bounding.top >= 0 && bounding.left >= 0 && bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) && bounding.right <= (window.innerWidth || document.documentElement.clientWidth); | ||
} | ||
function isScrollable(element) { | ||
return element && element.clientHeight < element.scrollHeight; | ||
} | ||
function maintainScrollVisibility(activeElement, scrollParent) { | ||
var offsetHeight = activeElement.offsetHeight, | ||
offsetTop = activeElement.offsetTop; | ||
var parentOffsetHeight = scrollParent.offsetHeight, | ||
scrollTop = scrollParent.scrollTop; | ||
var isAbove = offsetTop < scrollTop; | ||
var isBelow = offsetTop + offsetHeight > scrollTop + parentOffsetHeight; | ||
if (isAbove) { | ||
scrollParent.scrollTo(0, offsetTop); | ||
} else if (isBelow) { | ||
scrollParent.scrollTo(0, offsetTop - parentOffsetHeight + offsetHeight); | ||
} | ||
} |
{ | ||
"name": "@clayui/shared", | ||
"version": "3.82.0", | ||
"version": "3.83.0", | ||
"description": "ClayShared component", | ||
@@ -29,3 +29,3 @@ "license": "BSD-3-Clause", | ||
"dependencies": { | ||
"@clayui/button": "^3.82.0", | ||
"@clayui/button": "^3.83.0", | ||
"@clayui/link": "^3.56.0", | ||
@@ -46,3 +46,3 @@ "@clayui/provider": "^3.77.0", | ||
], | ||
"gitHead": "ee9029ba2b53a94656be608165a77497b2b6708a" | ||
"gitHead": "9b7680bbf4487ceba9b2ff6521fab431c79e97d9" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
163553
77
4594
Updated@clayui/button@^3.83.0