mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-11-20 17:21:24 +03:00
B: Fix tooltips for tabbed views
This commit is contained in:
parent
73e74bdd2d
commit
f63d9cf93e
|
|
@ -1,10 +1,11 @@
|
|||
'use client';
|
||||
|
||||
import { useLayoutEffect } from 'react';
|
||||
import { useLayoutEffect, useRef } from 'react';
|
||||
|
||||
import { useConceptNavigation } from '@/app/navigation/navigation-context';
|
||||
|
||||
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/tabs';
|
||||
import { useResetAttribute } from '@/hooks/use-reset-attribute';
|
||||
import { useAppLayoutStore } from '@/stores/app-layout';
|
||||
|
||||
import { EditorOssCard } from './editor-oss-card';
|
||||
|
|
@ -22,6 +23,9 @@ export function OssTabs({ activeTab }: OssTabsProps) {
|
|||
|
||||
const hideFooter = useAppLayoutStore(state => state.hideFooter);
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
useResetAttribute(containerRef, 'data-tooltip-id');
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const oldTitle = document.title;
|
||||
document.title = schema.title;
|
||||
|
|
@ -68,7 +72,7 @@ export function OssTabs({ activeTab }: OssTabsProps) {
|
|||
<TabLabel label='Граф' />
|
||||
</TabList>
|
||||
|
||||
<div className='overflow-x-hidden'>
|
||||
<div ref={containerRef} className='overflow-x-hidden'>
|
||||
<TabPanel>
|
||||
<EditorOssCard />
|
||||
</TabPanel>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { useWindowSize } from '@/hooks/use-window-size';
|
|||
import { useFitHeight, useMainHeight } from '@/stores/app-layout';
|
||||
import { useModificationStore } from '@/stores/modification';
|
||||
import { usePreferencesStore } from '@/stores/preferences';
|
||||
import { globalIDs, PARAMETER } from '@/utils/constants';
|
||||
import { globalIDs } from '@/utils/constants';
|
||||
|
||||
import { useMutatingRSForm } from '../../../backend/use-mutating-rsform';
|
||||
import { ViewConstituents } from '../../../components/view-constituents';
|
||||
|
|
@ -43,7 +43,6 @@ export function EditorConstituenta() {
|
|||
const { isModified } = useModificationStore();
|
||||
|
||||
const [toggleReset, setToggleReset] = useState(false);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const isProcessing = useMutatingRSForm();
|
||||
const disabled = !activeCst || !isContentEditable || isProcessing;
|
||||
|
|
@ -62,35 +61,6 @@ export function EditorConstituenta() {
|
|||
}
|
||||
}, [activeCst, selectedCst, setSelectedCst]);
|
||||
|
||||
useEffect(() => {
|
||||
// Trigger tooltip re-initialization after component mounts and tab becomes visible
|
||||
// This ensures tooltips work when loading the page directly with this tab active
|
||||
// React-tabs hides inactive panels with CSS (display: none), so react-tooltip v5
|
||||
// needs to re-scan the DOM when elements become visible
|
||||
const timeoutId = setTimeout(() => {
|
||||
if (!containerRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Force react-tooltip to re-scan by temporarily removing and re-adding data-tooltip-id
|
||||
// This triggers react-tooltip's internal MutationObserver to re-register the elements
|
||||
const tooltipElements = containerRef.current.querySelectorAll('[data-tooltip-id]');
|
||||
tooltipElements.forEach(element => {
|
||||
if (element instanceof HTMLElement) {
|
||||
const tooltipId = element.getAttribute('data-tooltip-id');
|
||||
if (tooltipId) {
|
||||
element.removeAttribute('data-tooltip-id');
|
||||
requestAnimationFrame(() => {
|
||||
element.setAttribute('data-tooltip-id', tooltipId);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}, PARAMETER.minimalTimeout);
|
||||
|
||||
return () => clearTimeout(timeoutId);
|
||||
}, []);
|
||||
|
||||
function handleInput(event: React.KeyboardEvent<HTMLDivElement>) {
|
||||
if (disabled) {
|
||||
return;
|
||||
|
|
@ -130,7 +100,6 @@ export function EditorConstituenta() {
|
|||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
tabIndex={-1}
|
||||
className={clsx(
|
||||
'relative ',
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
'use client';
|
||||
|
||||
import { useLayoutEffect } from 'react';
|
||||
import { useLayoutEffect, useRef } from 'react';
|
||||
|
||||
import { useConceptNavigation } from '@/app/navigation/navigation-context';
|
||||
|
||||
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/tabs';
|
||||
import { useResetAttribute } from '@/hooks/use-reset-attribute';
|
||||
import { useAppLayoutStore } from '@/stores/app-layout';
|
||||
import { useModificationStore } from '@/stores/modification';
|
||||
|
||||
|
|
@ -88,6 +89,9 @@ export function RSTabs({ activeID, activeTab }: RSTabsProps) {
|
|||
navigateRSForm({ tab: index as RSTabID, activeID: selectedCst.length > 0 ? selectedCst.at(-1) : undefined });
|
||||
}
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
useResetAttribute(containerRef, 'data-tooltip-id');
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
selectedIndex={activeTab}
|
||||
|
|
@ -104,7 +108,7 @@ export function RSTabs({ activeID, activeTab }: RSTabsProps) {
|
|||
<TabLabel label='Граф' />
|
||||
</TabList>
|
||||
|
||||
<div className='overflow-x-hidden'>
|
||||
<div ref={containerRef} className='overflow-x-hidden'>
|
||||
<TabPanel>
|
||||
<EditorRSFormCard />
|
||||
</TabPanel>
|
||||
|
|
|
|||
36
rsconcept/frontend/src/hooks/use-reset-attribute.ts
Normal file
36
rsconcept/frontend/src/hooks/use-reset-attribute.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { PARAMETER } from '@/utils/constants';
|
||||
|
||||
export function useResetAttribute(elementRef: React.RefObject<HTMLElement | null>, attribute: string) {
|
||||
useEffect(() => {
|
||||
// Trigger tooltip re-initialization after component mounts and tab becomes visible
|
||||
// This ensures tooltips work when loading the page directly with this tab active
|
||||
// React-tabs hides inactive panels with CSS (display: none), so react-tooltip v5
|
||||
// needs to re-scan the DOM when elements become visible
|
||||
const timeoutId = setTimeout(() => {
|
||||
if (!elementRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Force react-tooltip to re-scan by temporarily removing and re-adding data-tooltip-id
|
||||
// This triggers react-tooltip's internal MutationObserver to re-register the elements
|
||||
const tooltipElements = elementRef.current.querySelectorAll(`[${attribute}]`);
|
||||
tooltipElements.forEach(element => {
|
||||
if (element instanceof HTMLElement) {
|
||||
const value = element.getAttribute(attribute);
|
||||
if (value) {
|
||||
element.removeAttribute(attribute);
|
||||
requestAnimationFrame(() => {
|
||||
element.setAttribute(attribute, value);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}, PARAMETER.minimalTimeout);
|
||||
|
||||
return () => clearTimeout(timeoutId);
|
||||
}, [elementRef, attribute]);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user