Skip to content

Commit 390a28e

Browse files
committed
fix comments 20-11
1 parent b0f1076 commit 390a28e

File tree

6 files changed

+94
-41
lines changed

6 files changed

+94
-41
lines changed

ui-manchette-with-spacetimechart/src/stories/base-with-waypoint-menu.stories.tsx

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable import/no-unresolved */
21
import React, { useRef, useState } from 'react';
32

43
import { EyeClosed, Telescope } from '@osrd-project/ui-icons';
@@ -34,9 +33,11 @@ const ManchetteWithSpaceTimeWrapper = ({
3433
const manchetteWithSpaceTimeChartRef = useRef<HTMLDivElement>(null);
3534

3635
const [activeWaypointId, setActiveWaypointPointId] = useState<string>();
37-
const [activeWaypointRef, setActiveWaypointRef] = useState<React.RefObject<HTMLDivElement>>();
36+
// const [activeWaypointRef, setActiveWaypointRef] = useState<React.RefObject<HTMLDivElement>>();
3837

39-
const isElementInView = useElementInView(activeWaypointRef, manchetteWithSpaceTimeChartRef);
38+
// const isElementInView = useElementInView(activeWaypointRef, manchetteWithSpaceTimeChartRef, {
39+
// rootMargin: `0px 0px ${MANCHETTE_ACTIONS_HEIGHT} 0px`,
40+
// });
4041

4142
const menuItems: MenuItem[] = [
4243
{
@@ -58,11 +59,11 @@ const ManchetteWithSpaceTimeWrapper = ({
5859
];
5960

6061
const handleWaypointClick = (
61-
waypointId: string,
62-
waypointRef: React.RefObject<HTMLDivElement>
62+
waypointId: string
63+
// waypointRef: React.RefObject<HTMLDivElement>
6364
) => {
6465
setActiveWaypointPointId(waypointId);
65-
setActiveWaypointRef(waypointRef);
66+
// setActiveWaypointRef(waypointRef);
6667
};
6768

6869
const { manchetteProps, spaceTimeChartProps, handleScroll } = useManchettesWithSpaceTimeChart(
@@ -93,7 +94,8 @@ const ManchetteWithSpaceTimeWrapper = ({
9394
waypointMenuData={{
9495
activeWaypointId,
9596
menu: <Menu items={menuItems} />,
96-
isWaypointInView: isElementInView,
97+
// isWaypointInView: isElementInView,
98+
scrollableParentRef: manchetteWithSpaceTimeChartRef,
9799
}}
98100
/>
99101
<div

ui-manchette-with-spacetimechart/src/stories/useElementInView.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
import { useState, useEffect, type RefObject } from 'react';
2-
3-
const MANCHETTE_ACTIONS_HEIGHT = '-40px';
4-
52
/**
63
* Check if an element is in the viewport of a container
74
* @param ref the element we want to observe
@@ -16,7 +13,7 @@ const useElementInView = <T extends HTMLElement>(
1613
containerRef?: RefObject<HTMLElement>,
1714
options: IntersectionObserverInit = {
1815
threshold: 1,
19-
rootMargin: `0px 0px ${MANCHETTE_ACTIONS_HEIGHT} 0px`,
16+
rootMargin: `0px`,
2017
}
2118
): boolean => {
2219
const [isInView, setIsInView] = useState(false);

ui-manchette/src/components/Waypoint.tsx

+11-4
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,30 @@ import cx from 'classnames';
55
import { type InteractiveWaypoint } from '../types';
66
import '@osrd-project/ui-core/dist/theme.css';
77
import { positionMmToKm } from '../utils';
8+
import useElementInView from '../hooks/useElementInView';
9+
10+
const MANCHETTE_ACTIONS_HEIGHT = '-40px';
811

912
type WaypointProps = {
1013
waypoint: InteractiveWaypoint;
1114
isActive: boolean;
1215
waypointMenu?: React.ReactNode;
13-
waypointsContainerRef: React.RefObject<HTMLDivElement>;
14-
isWaypointInView?: boolean;
16+
scrollableParentRef?: React.RefObject<HTMLElement>;
1517
};
1618

1719
const Waypoint = ({
1820
waypoint: { name, secondaryCode, id, position, display, onClick },
1921
isActive,
2022
waypointMenu,
21-
isWaypointInView,
23+
scrollableParentRef,
2224
}: WaypointProps) => {
2325
const waypointRef = useRef<HTMLDivElement>(null);
2426

27+
const isWaypointInView = useElementInView(waypointRef, scrollableParentRef, {
28+
rootMargin: `0px 0px ${MANCHETTE_ACTIONS_HEIGHT} 0px`,
29+
});
30+
31+
console.log('waypoint', { waypointMenu, scrollableParentRef, isWaypointInView });
2532
if (!display) return null;
2633

2734
return (
@@ -31,7 +38,7 @@ const Waypoint = ({
3138
})}
3239
id={id}
3340
onClick={() => {
34-
if (onClick) onClick(id, waypointRef);
41+
if (onClick) onClick(id);
3542
}}
3643
>
3744
<div ref={waypointRef} className="waypoint-position justify-self-start text-end">
+19-24
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef } from 'react';
1+
import React from 'react';
22

33
import Waypoint from './Waypoint';
44
import type { WaypointMenuData, InteractiveWaypoint } from '../types';
@@ -8,28 +8,23 @@ type WaypointListProps = {
88
waypointMenuData?: WaypointMenuData;
99
};
1010

11-
const WaypointList = ({ waypoints, waypointMenuData }: WaypointListProps) => {
12-
const waypointsContainerRef = useRef<HTMLDivElement>(null);
13-
14-
return (
15-
<div ref={waypointsContainerRef} className="waypoint-list ">
16-
{waypoints.map((waypoint) => (
17-
<div
18-
key={waypoint.id}
19-
className="waypoint-wrapper flex flex-col justify-start"
20-
style={waypoint.styles}
21-
>
22-
<Waypoint
23-
waypoint={waypoint}
24-
isActive={waypointMenuData?.activeWaypointId === waypoint.id}
25-
waypointMenu={waypointMenuData?.menu}
26-
waypointsContainerRef={waypointsContainerRef}
27-
isWaypointInView={waypointMenuData?.isWaypointInView}
28-
/>
29-
</div>
30-
))}
31-
</div>
32-
);
33-
};
11+
const WaypointList = ({ waypoints, waypointMenuData }: WaypointListProps) => (
12+
<div className="waypoint-list ">
13+
{waypoints.map((waypoint) => (
14+
<div
15+
key={waypoint.id}
16+
className="waypoint-wrapper flex flex-col justify-start"
17+
style={waypoint.styles}
18+
>
19+
<Waypoint
20+
waypoint={waypoint}
21+
isActive={waypointMenuData?.activeWaypointId === waypoint.id}
22+
waypointMenu={waypointMenuData?.menu}
23+
scrollableParentRef={waypointMenuData?.scrollableParentRef}
24+
/>
25+
</div>
26+
))}
27+
</div>
28+
);
3429

3530
export default WaypointList;
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { useState, useEffect, type RefObject } from 'react';
2+
/**
3+
* Check if an element is in the viewport of a container
4+
* @param ref the element we want to observe
5+
* @param containerRef the container we want to observe the element in (needs to be the first scrollable parent)
6+
* @param options the options for the intersection observer
7+
* - threshold is used to configure how much of the element needs to be visible before the callback is invoked
8+
* - rootMargin is used to configure the margin around the root (container) where the intersection observer will trigger
9+
* @returns a boolean indicating if the element is in the viewport
10+
*/
11+
const useElementInView = <T extends HTMLElement>(
12+
ref?: RefObject<T>,
13+
containerRef?: RefObject<HTMLElement>,
14+
options: IntersectionObserverInit = {
15+
threshold: 1,
16+
rootMargin: `0px`,
17+
}
18+
): boolean => {
19+
const [isInView, setIsInView] = useState(false);
20+
21+
useEffect(() => {
22+
const currentRef = ref?.current;
23+
const root = containerRef?.current || null;
24+
25+
if (!currentRef) {
26+
// If the user implementing ui-manchette doesn't provide a ref to handle the menu visibility,
27+
// the menu should always be visible
28+
setIsInView(true);
29+
return;
30+
}
31+
32+
const observer = new IntersectionObserver(
33+
([entry]) => {
34+
setIsInView(entry.isIntersecting);
35+
},
36+
{
37+
...options,
38+
root,
39+
}
40+
);
41+
42+
observer.observe(currentRef.parentElement!);
43+
44+
return () => observer.disconnect();
45+
}, [ref, containerRef, options]);
46+
47+
return isInView;
48+
};
49+
50+
export default useElementInView;

ui-manchette/src/types.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ export type Waypoint = {
1010
export type InteractiveWaypoint = Waypoint & {
1111
styles?: CSSProperties;
1212
display?: boolean;
13-
onClick?: (waypointId: string, waypointRef: React.RefObject<HTMLDivElement>) => void;
13+
onClick?: (waypointId: string) => void;
1414
};
1515

1616
export type WaypointMenuData = {
1717
menu: React.ReactNode;
1818
activeWaypointId?: string;
19-
isWaypointInView?: boolean;
19+
// isWaypointInView?: boolean;
20+
// Ref of the scrollable parent of the waypoints list to enable the menu hidding behavior
21+
scrollableParentRef?: React.RefObject<HTMLElement>;
2022
};
2123

2224
export type ProjectPathTrainResult = {

0 commit comments

Comments
 (0)