diff --git a/frontend/src/components/Galaxy.css b/frontend/src/components/Galaxy.css index 56ba59e..e08c47c 100644 --- a/frontend/src/components/Galaxy.css +++ b/frontend/src/components/Galaxy.css @@ -96,8 +96,18 @@ se limite à la moitié gauche sur grand écran et descend sous le message sur téléphone */ .family-tabs--lowered { max-width: calc(50vw - 200px); } +/* Fiche ouverte sur grand écran (à gauche, 384 px depuis 24 px) : la barre passe à sa droite */ +@media (min-width: 769px) { + body:has(.person-card) .family-tabs { left: 424px; max-width: calc(100vw - 424px - 96px); } + /* Recherche ouverte (environ 540 px à droite) : la barre s'arrête avant elle et se fond au bord */ + body:has(.expandable-search.expanded) .family-tabs { max-width: calc(100vw - 16px - 560px); } + body:has(.person-card):has(.expandable-search.expanded) .family-tabs { max-width: calc(100vw - 424px - 560px); } +} + @media (max-width: 768px) { .family-tabs { top: 10px; left: 10px; max-width: calc(100vw - 84px); } .family-tabs--lowered { top: 64px; max-width: calc(100vw - 20px); } + /* Recherche ouverte sur téléphone : elle prend toute la largeur du haut, la barre passe dessous */ + body:has(.expandable-search.expanded) .family-tabs { top: 80px; max-width: calc(100vw - 20px); } .family-tab { font-size: 14px; padding: 6px 12px 7px; } } diff --git a/frontend/src/components/Galaxy.jsx b/frontend/src/components/Galaxy.jsx index 7478c6f..0cbf709 100644 --- a/frontend/src/components/Galaxy.jsx +++ b/frontend/src/components/Galaxy.jsx @@ -51,6 +51,7 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, selectedPersonId, searchHighlig const [tabs, setTabs] = useState([]) const [activeKey, setActiveKey] = useState(focusPersonId != null ? String(focusPersonId) : null) const tabsCacheRef = useRef({ rev: -1, start: undefined, tabs: [] }) + const pendingFocusRef = useRef(null) // personne cherchée dans un autre onglet, visée après le changement const activeTabRef = useRef(null) const familyTabsRef = useRef(familyTabs) useEffect(() => { familyTabsRef.current = familyTabs }, [familyTabs]) @@ -406,6 +407,14 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, selectedPersonId, searchHighlig focusPerson: (personId) => { const canvas = canvasRef.current const node = layoutDataRef.current?.children.find(n => n.id === `p-${personId}`) + // Rangée dans un autre onglet : on ouvre cet onglet, la personne est visée une fois l'arbre posé + if (!node && familyTabsRef.current) { + const id = String(personId) + const all = tabsCacheRef.current.tabs + const home = all.find((tb) => tb.personIds?.has(id) && !(tb.hinges || []).map(String).includes(id)) || all.find((tb) => tb.personIds?.has(id)) || all[0] + if (home && home.key !== activeTabRef.current?.key) { pendingFocusRef.current = id; setActiveKey(home.key) } + return + } if (!canvas || !node) return const rect = canvas.getBoundingClientRect() const pos = getAnimatedPos(node, performance.now()) @@ -618,6 +627,11 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, selectedPersonId, searchHighlig layoutDataRef.current = result needsRedrawRef.current = true setLayoutReady(true) + if (pendingFocusRef.current) { + const id = pendingFocusRef.current + pendingFocusRef.current = null + requestAnimationFrame(() => zoomApiRef?.current?.focusPerson?.(id)) + } }, [graphRevision, activeKey, familyTabs]) // Sync selectedPersonId