mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
🏃 feat: Keep Modals Open on Escape in Dropdown Menus (#10975)
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
Publish `@librechat/client` to NPM / build-and-publish (push) Waiting to run
Publish `librechat-data-provider` to NPM / build (push) Waiting to run
Publish `librechat-data-provider` to NPM / publish-npm (push) Blocked by required conditions
Publish `@librechat/data-schemas` to NPM / build-and-publish (push) Waiting to run
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Waiting to run
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
Publish `@librechat/client` to NPM / build-and-publish (push) Waiting to run
Publish `librechat-data-provider` to NPM / build (push) Waiting to run
Publish `librechat-data-provider` to NPM / publish-npm (push) Blocked by required conditions
Publish `@librechat/data-schemas` to NPM / build-and-publish (push) Waiting to run
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Waiting to run
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Waiting to run
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions
* fix: filter dropdown now closable with escape, doesn't close whole modal * refactor: simplify escapekeydown handler logic for tooltips and dropdown menus * refactor: more specific conditions for preventDefault
This commit is contained in:
parent
23279b4b14
commit
d8b788aecc
1 changed files with 23 additions and 13 deletions
|
|
@ -78,29 +78,39 @@ const DialogContent = React.forwardRef<
|
|||
},
|
||||
ref,
|
||||
) => {
|
||||
/* Handle Escape key to prevent closing dialog if a tooltip is open
|
||||
const contentRef = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
React.useImperativeHandle(ref, () => contentRef.current as HTMLDivElement, []);
|
||||
|
||||
/* Handle Escape key to prevent closing dialog if a tooltip or dropdown is open
|
||||
(this is a workaround in order to achieve WCAG compliance which requires
|
||||
that our tooltips be dismissable with Escape key) */
|
||||
const handleEscapeKeyDown = React.useCallback(
|
||||
(event: KeyboardEvent) => {
|
||||
const tooltips = document.querySelectorAll('.tooltip');
|
||||
if (!contentRef.current) {
|
||||
propsOnEscapeKeyDown?.(event);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const tooltip of Array.from(tooltips)) {
|
||||
const computedStyle = window.getComputedStyle(tooltip);
|
||||
const opacity = parseFloat(computedStyle.opacity);
|
||||
const tooltips = contentRef.current.querySelectorAll('.tooltip');
|
||||
const dropdownMenus = contentRef.current.querySelectorAll('[role="menu"]');
|
||||
|
||||
if (
|
||||
tooltip.parentElement &&
|
||||
computedStyle.display !== 'none' &&
|
||||
computedStyle.visibility !== 'hidden' &&
|
||||
opacity > 0
|
||||
) {
|
||||
for (const tooltip of tooltips) {
|
||||
const style = window.getComputedStyle(tooltip);
|
||||
if (style.display !== 'none') {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (const dropdownMenu of dropdownMenus) {
|
||||
const style = window.getComputedStyle(dropdownMenu);
|
||||
if (style.display !== 'none') {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Call the original handler if it exists
|
||||
propsOnEscapeKeyDown?.(event);
|
||||
},
|
||||
[propsOnEscapeKeyDown],
|
||||
|
|
@ -110,7 +120,7 @@ const DialogContent = React.forwardRef<
|
|||
<DialogPortal>
|
||||
<DialogOverlay className={overlayClassName} />
|
||||
<DialogPrimitive.Content
|
||||
ref={ref}
|
||||
ref={contentRef}
|
||||
onEscapeKeyDown={handleEscapeKeyDown}
|
||||
className={cn(
|
||||
'max-w-11/12 fixed left-[50%] top-[50%] z-50 grid max-h-[90vh] w-full translate-x-[-50%] translate-y-[-50%] gap-4 overflow-y-auto rounded-2xl bg-background p-6 text-text-primary shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue