Skip to content

Commit c85f50d

Browse files
committed
fix menu overflow
1 parent 84999d7 commit c85f50d

File tree

8 files changed

+73
-42
lines changed

8 files changed

+73
-42
lines changed

storybook/.storybook/main.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ const config: StorybookConfig = {
2424
},
2525
staticDirs: ['../public'],
2626
logLevel: 'debug',
27-
// async viteFinal(config) {
28-
// return mergeConfig(config, {
29-
// resolve: {
30-
// preserveSymlinks: true,
31-
// },
32-
// });
33-
// },
27+
async viteFinal(config) {
28+
return mergeConfig(config, {
29+
resolve: {
30+
preserveSymlinks: true,
31+
},
32+
});
33+
},
3434
};
3535
export default config;
3636

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React, { useRef } from 'react';
22

3-
import Manchette from '@osrd-project/ui-manchette';
4-
import type { ProjectPathTrainResult, Waypoint } from '@osrd-project/ui-manchette/dist/types';
3+
import Manchette, { type ProjectPathTrainResult, type Waypoint } from '@osrd-project/ui-manchette';
54
import { PathLayer, SpaceTimeChart } from '@osrd-project/ui-spacetimechart';
65
import type { Meta } from '@storybook/react';
76

ui-manchette-with-spacetimechart/src/styles/menu.css

-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
.menu {
2-
position: absolute;
3-
z-index: 12;
42
@apply bg-grey-5;
53
width: 305px;
6-
top: 30px;
7-
left: 0;
84
border: 0.0625rem solid #b6b2af;
95
border-radius: 0.5rem;
106
box-shadow:

ui-manchette/src/components/Waypoint.tsx

+51-24
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef } from 'react';
1+
import React, { useLayoutEffect, useRef, useState } from 'react';
22

33
import cx from 'classnames';
44

@@ -8,6 +8,8 @@ import '@osrd-project/ui-core/dist/theme.css';
88
import { positionMmToKm } from '../utils';
99

1010
const MANCHETTE_ACTIONS_HEIGHT = '-40px';
11+
// Waypoint height minus its position offset
12+
const MENU_OFFSET = 2;
1113

1214
type WaypointProps = {
1315
waypoint: InteractiveWaypoint;
@@ -23,37 +25,62 @@ const Waypoint = ({
2325
scrollableParentRef,
2426
}: WaypointProps) => {
2527
const waypointRef = useRef<HTMLDivElement>(null);
28+
const menuRef = useRef<HTMLDivElement>(null);
29+
const [menuPositionTop, setMenuPositionTop] = useState(0);
2630

27-
const isWaypointInView = useElementInView(waypointRef, scrollableParentRef, {
28-
threshold: 1,
29-
rootMargin: `0px 0px ${MANCHETTE_ACTIONS_HEIGHT} 0px`,
31+
const isWaypointInView = useElementInView(
32+
isActive ? waypointRef : undefined,
33+
scrollableParentRef,
34+
{
35+
threshold: 1,
36+
rootMargin: `0px 0px ${MANCHETTE_ACTIONS_HEIGHT} 0px`,
37+
}
38+
);
39+
40+
// We have to omit the dependency array here otherwise the menu won't move on scroll
41+
// eslint-disable-next-line react-hooks/exhaustive-deps
42+
useLayoutEffect(() => {
43+
// Having the waypoint div in position relative has the side effect of making the menu
44+
// not overflowing the waypoint list. So we need to position it with this logic.
45+
if (waypointRef.current) {
46+
const { bottom } = waypointRef.current?.getBoundingClientRect();
47+
setMenuPositionTop(bottom - MENU_OFFSET);
48+
}
3049
});
3150

3251
if (!display) return null;
3352

3453
return (
35-
<div
36-
className={cx('flex waypoint items-baseline', {
37-
'menu-active': isActive,
38-
})}
39-
id={id}
40-
onClick={() => {
41-
if (onClick) onClick(id);
42-
}}
43-
>
44-
<div ref={waypointRef} className="waypoint-position justify-self-start text-end">
45-
{positionMmToKm(position)}
46-
</div>
54+
<>
55+
<div
56+
ref={waypointRef}
57+
className={cx('flex waypoint items-baseline', {
58+
'menu-active': isActive,
59+
})}
60+
id={id}
61+
onClick={() => {
62+
if (onClick) onClick(id);
63+
}}
64+
>
65+
<div className="waypoint-position justify-self-start text-end">
66+
{positionMmToKm(position)}
67+
</div>
4768

48-
<div className="waypoint-name mx-2 justify-self-start">{name}</div>
49-
<div className="waypoint-separator"></div>
50-
<div className="waypoint-ch font-mono justify-self-end">{secondaryCode}</div>
51-
<div className="waypoint-separator"></div>
69+
<div className="waypoint-name mx-2 justify-self-start">{name}</div>
70+
<div className="waypoint-separator"></div>
71+
<div className="waypoint-ch font-mono justify-self-end">{secondaryCode}</div>
72+
<div className="waypoint-separator"></div>
5273

53-
<div className="waypoint-type"></div>
54-
<div className="waypoint-separator"></div>
55-
{waypointMenu && isActive && isWaypointInView && waypointMenu}
56-
</div>
74+
<div className="waypoint-type"></div>
75+
<div className="waypoint-separator"></div>
76+
{waypointMenu && isActive && isWaypointInView && (
77+
<div className="menu-wrapper" ref={menuRef} style={{ top: menuPositionTop }}>
78+
{waypointMenu}
79+
</div>
80+
)}
81+
</div>
82+
<div className="last-separator"></div>
83+
</>
5784
);
5885
};
5986

ui-manchette/src/components/WaypointList.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const WaypointList = ({ waypoints, waypointMenuData }: WaypointListProps) => (
1313
{waypoints.map((waypoint) => (
1414
<div
1515
key={waypoint.id}
16-
className="waypoint-wrapper flex flex-col justify-start"
16+
className="waypoint-wrapper flex justify-start"
1717
style={waypoint.styles}
1818
>
1919
<Waypoint

ui-manchette/src/hooks/useElementInView.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const useElementInView = <T extends HTMLElement>(
3939
}
4040
);
4141

42-
observer.observe(currentRef.parentElement!);
42+
observer.observe(currentRef);
4343

4444
return () => observer.disconnect();
4545
}, [ref, containerRef, options]);

ui-manchette/src/styles/waypoint-list.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.waypoint-list {
22
width: 349px;
33
border-bottom-left-radius: 0.25rem;
4-
padding-inline: 0.5rem 1.625rem;
4+
padding-left: 0.5rem;
55

66
@apply bg-white-100;
77

ui-manchette/src/styles/waypoint.css

+11-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
line-height: 1.5rem;
55
padding-block: 3px 5px;
66
width: 315px;
7-
position: relative;
87
&-separator {
98
position: relative;
109
opacity: 0.6;
@@ -81,12 +80,22 @@
8180
}
8281
}
8382

83+
.menu-wrapper {
84+
position: absolute;
85+
z-index: 12;
86+
}
87+
}
88+
89+
.last-separator {
90+
width: 26px;
91+
height: 2rem;
92+
93+
position: relative;
8494
&::after {
8595
content: '';
8696
position: absolute;
8797
display: inline-block;
8898
bottom: 16px;
89-
right: -1.625rem;
9099
width: 1.625rem;
91100
height: 0.5px;
92101
opacity: 0.6;

0 commit comments

Comments
 (0)