mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-04 14:57:42 +00:00
fix: scope tooltip elevation to dialogs and restore dialog close button size
Tooltips go back to z-150 globally; inside a dialog they now borrow the depth-aware popover z-index so they still clear nested dialogs (the Tool Library item dialog) without outranking freshly opened modals everywhere else. The default dialog close icon returns to its original size, and the lc-field pointer-focus suppression ships with the package next to Input and Textarea so external consumers get the whole mechanism from @librechat/client.
This commit is contained in:
parent
5c1e0b831a
commit
f6eccee9c7
7 changed files with 23 additions and 13 deletions
|
|
@ -2663,7 +2663,7 @@ html {
|
|||
}
|
||||
|
||||
.tooltip {
|
||||
z-index: 900;
|
||||
z-index: 150;
|
||||
cursor: pointer;
|
||||
border-radius: 0.275rem;
|
||||
background-color: var(--surface-primary);
|
||||
|
|
@ -2697,16 +2697,6 @@ html {
|
|||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Shared Input/Textarea (.lc-field): show the focus ring for keyboard users
|
||||
only. Text inputs match :focus-visible on pointer focus too (a UA heuristic
|
||||
CSS cannot distinguish), so the ring is gated on the tracked input modality. */
|
||||
html[data-input-modality='pointer'] .lc-field:focus,
|
||||
html[data-input-modality='pointer'] .lc-field:focus-visible {
|
||||
border-color: var(--border-light);
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.popover-ui {
|
||||
display: flex;
|
||||
max-height: min(var(--popover-available-height, 1700px), 1700px);
|
||||
|
|
|
|||
11
packages/client/src/components/Field.css
Normal file
11
packages/client/src/components/Field.css
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* Shared Input/Textarea (.lc-field): show the focus ring for keyboard users
|
||||
only. Text inputs match :focus-visible on pointer focus too (a UA heuristic
|
||||
CSS cannot distinguish), so the ring is gated on the input modality tracked
|
||||
by useInputModality (mount it once near the app root). Without the hook the
|
||||
attribute is absent and the ring always shows — the safe fallback. */
|
||||
html[data-input-modality='pointer'] .lc-field:focus,
|
||||
html[data-input-modality='pointer'] .lc-field:focus-visible {
|
||||
border-color: var(--border-light);
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import * as React from 'react';
|
||||
import { cn } from '~/utils';
|
||||
import './Field.css';
|
||||
|
||||
export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
|
||||
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ const DialogContent: React.ForwardRefExoticComponent<
|
|||
{children}
|
||||
{showCloseButton && (
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-ring-primary ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||
<X className="size-4" aria-hidden="true" />
|
||||
<X className="h-6 w-6" aria-hidden="true" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import * as React from 'react';
|
||||
import TextareaAutosize from 'react-textarea-autosize';
|
||||
import { cn } from '~/utils';
|
||||
import './Field.css';
|
||||
|
||||
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
.tooltip {
|
||||
z-index: 900;
|
||||
z-index: 150;
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
border-radius: 0.275rem;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
import DOMPurify from 'dompurify';
|
||||
import * as Ariakit from '@ariakit/react';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { useDialogDepth, usePopoverZIndex } from './OriginalDialog';
|
||||
import { cn } from '~/utils';
|
||||
import './Tooltip.css';
|
||||
|
||||
|
|
@ -35,6 +36,11 @@ const TooltipPopup = memo(function TooltipPopup({
|
|||
}) {
|
||||
const mounted = Ariakit.useStoreState(store, (state) => state.mounted);
|
||||
const placement = Ariakit.useStoreState(store, (state) => state.placement);
|
||||
/** Tooltips portal to body at z-150, which nested dialogs (z 200+) cover —
|
||||
* inside a dialog, borrow the popover's depth-aware z-index; outside, keep
|
||||
* the stylesheet default so tooltips never outrank freshly opened dialogs. */
|
||||
const dialogDepth = useDialogDepth();
|
||||
const popoverZIndex = usePopoverZIndex();
|
||||
|
||||
const sanitizer = useMemo(() => {
|
||||
const instance = DOMPurify();
|
||||
|
|
@ -89,6 +95,7 @@ const TooltipPopup = memo(function TooltipPopup({
|
|||
className="tooltip"
|
||||
render={
|
||||
<motion.div
|
||||
style={dialogDepth > 0 ? { zIndex: popoverZIndex } : undefined}
|
||||
initial={{ opacity: 0, x, y }}
|
||||
animate={{ opacity: 1, x: 0, y: 0 }}
|
||||
exit={{ opacity: 0, x, y }}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue