mirror of
https://github.com/IliesAllali/parenthese.git
synced 2026-11-13 16:22:03 +00:00
barre d'onglets fondue aux bords, fil croisant la rangée des parents = pastille, le sang garde ses chaînes
- La barre d'onglets signale par un fondu le côté qui défile encore. - Un fil de famille reliée deux fois qui passerait sous d'autres couples de la rangée des parents devient une pastille, comme celui qui passerait devant la rangée de l'enfant (archétype cousins mis à jour). - Une belle-famille en construction ne s'approprie pas une chaîne du sang de la référence dont les parents sont ailleurs : elle ira sous eux. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
e23618806b
commit
3df9abe63f
4 files changed
+33
-8
No files matched your search
@@ -61,6 +61,10 @@
|
||||
padding: 4px;
|
||||
}
|
||||
.family-tabs::-webkit-scrollbar { display: none; }
|
||||
/* Bords coupés : un fondu de chaque côté qui défile encore */
|
||||
.family-tabs.has-left { mask-image: linear-gradient(to right, transparent, #000 36px); -webkit-mask-image: linear-gradient(to right, transparent, #000 36px); }
|
||||
.family-tabs.has-right { mask-image: linear-gradient(to left, transparent, #000 36px); -webkit-mask-image: linear-gradient(to left, transparent, #000 36px); }
|
||||
.family-tabs.has-left.has-right { mask-image: linear-gradient(to right, transparent, #000 36px, #000 calc(100% - 36px), transparent); -webkit-mask-image: linear-gradient(to right, transparent, #000 36px, #000 calc(100% - 36px), transparent); }
|
||||
|
||||
.family-tab {
|
||||
flex: 0 0 auto;
|
||||
|
||||
@@ -58,8 +58,22 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, selectedPersonId, searchHighlig
|
||||
useEffect(() => { startRefRef.current = focusPersonId; setActiveKey(focusPersonId != null ? String(focusPersonId) : null) }, [focusPersonId])
|
||||
// Lu au calcul du cadrage et par le réordonnancement : la référence de l'arbre affiché
|
||||
const focusPersonIdRef = useRef(focusPersonId)
|
||||
// Sur téléphone, la barre défile : l'onglet ouvert par un badge se met en vue, sans animation
|
||||
useEffect(() => { document.querySelector('.family-tab.is-active')?.scrollIntoView({ behavior: 'auto', inline: 'nearest', block: 'nearest' }) }, [activeKey, tabs])
|
||||
// La barre défile quand les onglets débordent : l'onglet ouvert se met en vue (sans animation) et les bords
|
||||
// coupés se signalent par un fondu
|
||||
const tabsBarRef = useRef(null)
|
||||
const [tabsEdges, setTabsEdges] = useState('')
|
||||
const updateTabsEdges = useCallback(() => {
|
||||
const el = tabsBarRef.current
|
||||
if (!el) return
|
||||
const left = el.scrollLeft > 2, right = el.scrollLeft + el.clientWidth < el.scrollWidth - 2
|
||||
setTabsEdges(`${left ? ' has-left' : ''}${right ? ' has-right' : ''}`)
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
document.querySelector('.family-tab.is-active')?.scrollIntoView({ behavior: 'auto', inline: 'nearest', block: 'nearest' })
|
||||
updateTabsEdges()
|
||||
window.addEventListener('resize', updateTabsEdges)
|
||||
return () => window.removeEventListener('resize', updateTabsEdges)
|
||||
}, [activeKey, tabs, updateTabsEdges])
|
||||
// Clic sur un badge : l'onglet de cette famille (ou, depuis un onglet, celui d'où l'on vient)
|
||||
const openFamily = useCallback((tabKey) => { if (tabKey != null) setActiveKey(String(tabKey)) }, [])
|
||||
// Propriétaire : un portrait vide survolé montre « + photo »
|
||||
@@ -1076,7 +1090,7 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, selectedPersonId, searchHighlig
|
||||
<div className="path-label-overlay">{displayLabel}</div>
|
||||
)}
|
||||
{familyTabs && tabs.length > 1 && (
|
||||
<nav className={`family-tabs${annotationHandlers ? ' family-tabs--lowered' : ''}`} aria-label={tr('Familles')}>
|
||||
<nav ref={tabsBarRef} onScroll={updateTabsEdges} className={`family-tabs${annotationHandlers ? ' family-tabs--lowered' : ''}${tabsEdges}`} aria-label={tr('Familles')}>
|
||||
{tabs.map((tb) => {
|
||||
const active = tb.key === (tabs.some((x) => x.key === activeKey) ? activeKey : tabs[0].key)
|
||||
return (
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
┬──────────────┴───┬
|
||||
│ │
|
||||
P1────•───P1w P2────•───P2w
|
||||
│ │
|
||||
┬────┴ ┬─────────────┴
|
||||
│ │
|
||||
│
|
||||
┬────┴
|
||||
│
|
||||
C1────•───C2
|
||||
│
|
||||
┼
|
||||
│
|
||||
K
|
||||
renvoi : P2+P2w → C2
|
||||
@@ -58,7 +58,10 @@ export function filCroiseAutreFamille(nodes, childrenOfUnion, spouseKeysOf, u, c
|
||||
const fratrie = [...new Set([c, ...(childrenOfUnion.get(u) || [])])]
|
||||
const excluded = new Set([...fratrie, ...fratrie.flatMap(k => [...(spouseKeysOf.get(k) || [])])])
|
||||
const lo = Math.min(cx(u), cx(c)), hi = Math.max(cx(u), cx(c))
|
||||
return nodes.some(n => n._type === 'person' && n._generation === kid._generation && !excluded.has(n.id)
|
||||
const un = byIdLocal.get(u)
|
||||
const parents = new Set([un?._data?.p1Key, un?._data?.p2Key].filter(Boolean))
|
||||
return nodes.some(n => n._type === 'person' && !excluded.has(n.id) && !parents.has(n.id)
|
||||
&& (n._generation === kid._generation || n._generation === kid._generation - 1)
|
||||
&& n.x + n.width > lo && n.x < hi)
|
||||
}
|
||||
|
||||
@@ -320,7 +323,10 @@ function layoutOnce(graphData, referenceId, forcedSide, familyTabs = true) {
|
||||
}
|
||||
kidsOfChain.forEach(({ unionId, kid }, i) => {
|
||||
const kc = chainOf.get(kid)
|
||||
if (placed.has(kc) || tabOfChain.has(kc)) {
|
||||
// Belle-famille en construction : une chaîne dont aucun membre du sang n'est enfant de cette union, mais
|
||||
// dont un membre du sang a ses parents ailleurs, ira sous ces parents-là (le sang de la référence gagne)
|
||||
const duSang = anchor && !kc.some(id => blood.has(id) && parentUnionOf.get(id) === unionId) && kc.some(id => blood.has(id) && byId.get(id)._type === 'person' && parentUnionOf.has(id))
|
||||
if (placed.has(kc) || tabOfChain.has(kc) || duSang) {
|
||||
external.push({ kid, unionId })
|
||||
externalEdges.add(`${unionId}>${kid}`)
|
||||
childBlocks.push({ ...ghostBlock(kid), unionId })
|
||||
|
||||
Reference in new issue
Block a user