/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import * as React from 'react';
import {memo, useCallback, useContext} from 'react';
import {areEqual} from 'react-window';
import {minBarWidth} from './constants';
import {getGradientColor} from './utils';
import ChartNode from './ChartNode';
import {SettingsContext} from '../Settings/SettingsContext';
import type {ItemData} from './CommitRanked';
type Props = {
data: ItemData,
index: number,
style: Object,
...
};
function CommitRankedListItem({data, index, style}: Props) {
const {
chartData,
onElementMouseEnter,
onElementMouseLeave,
scaleX,
selectedFiberIndex,
selectFiber,
width,
} = data;
const node = chartData.nodes[index];
const {lineHeight} = useContext(SettingsContext);
const handleClick = useCallback(
(event: $FlowFixMe) => {
event.stopPropagation();
const {id, name} = node;
selectFiber(id, name);
},
[node, selectFiber],
);
const handleMouseEnter = () => {
const {id, name} = node;
onElementMouseEnter({id, name});
};
const handleMouseLeave = () => {
onElementMouseLeave();
};
// List items are absolutely positioned using the CSS "top" attribute.
// The "left" value will always be 0.
// Since height is fixed, and width is based on the node's duration,
// We can ignore those values as well.
const top = parseInt(style.top, 10);
return (
<ChartNode
color={getGradientColor(node.value / chartData.maxValue)}
height={lineHeight}
isDimmed={index < selectedFiberIndex}
key={node.id}
label={node.label}
onClick={handleClick}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
width={Math.max(minBarWidth, scaleX(node.value, width))}
x={0}
y={top}
/>
);
}
export default (memo(
CommitRankedListItem,
areEqual,
): React.ComponentType<Props>);