Skip to content

Commit

Permalink
Merge
Browse files Browse the repository at this point in the history
  • Loading branch information
flaviendelangle committed Oct 28, 2024
2 parents 8765825 + d01d1bf commit f49dc88
Show file tree
Hide file tree
Showing 75 changed files with 2,627 additions and 365 deletions.
18 changes: 9 additions & 9 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ coverage:
adapters:
target: 100%
paths:
- 'packages/x-date-pickers/src/AdapterDateFns/AdapterDateFns.ts'
- 'packages/x-date-pickers/src/AdapterDateFnsV3/AdapterDateFnsV3.ts'
- 'packages/x-date-pickers/src/AdapterDateFnsJalali/AdapterDateFnsJalali.ts'
- 'packages/x-date-pickers/src/AdapterDateFnsJalaliV3/AdapterDateFnsJalaliV3.ts'
- 'packages/x-date-pickers/src/AdapterDayjs/AdapterDayjs.ts'
- 'packages/x-date-pickers/src/AdapterLuxon/AdapterLuxon.ts'
- 'packages/x-date-pickers/src/AdapterMoment/AdapterMoment.ts'
- 'packages/x-date-pickers/src/AdapterMomentHijri/AdapterMomentHijri.ts'
- 'packages/x-date-pickers/src/AdapterMomentJalaali/AdapterMomentJalaali.ts'
- packages/x-date-pickers/src/AdapterDateFns/AdapterDateFns.ts
- packages/x-date-pickers/src/AdapterDateFnsV3/AdapterDateFnsV3.ts
- packages/x-date-pickers/src/AdapterDateFnsJalali/AdapterDateFnsJalali.ts
- packages/x-date-pickers/src/AdapterDateFnsJalaliV3/AdapterDateFnsJalaliV3.ts
- packages/x-date-pickers/src/AdapterDayjs/AdapterDayjs.ts
- packages/x-date-pickers/src/AdapterLuxon/AdapterLuxon.ts
- packages/x-date-pickers/src/AdapterMoment/AdapterMoment.ts
- packages/x-date-pickers/src/AdapterMomentHijri/AdapterMomentHijri.ts
- packages/x-date-pickers/src/AdapterMomentJalaali/AdapterMomentJalaali.ts
patch: off

comment: false
71 changes: 65 additions & 6 deletions docs/data/charts/tooltip/CustomAxisTooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,80 @@ import NoSsr from '@mui/material/NoSsr';
import Popper from '@mui/material/Popper';
import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
import { useAxisTooltip, useMouseTracker } from '@mui/x-charts/ChartsTooltip';
import { useAxisTooltip } from '@mui/x-charts/ChartsTooltip';
import { useSvgRef } from '@mui/x-charts/hooks';
import { generateVirtualElement } from './generateVirtualElement';

function usePointer() {
const svgRef = useSvgRef();
const popperRef = React.useRef(null);
const virtualElement = React.useRef(generateVirtualElement({ x: 0, y: 0 }));

// Use a ref to avoid rerendering on every mousemove event.
const [pointer, setPointer] = React.useState({
isActive: false,
isMousePointer: false,
pointerHeight: 0,
});

React.useEffect(() => {
const element = svgRef.current;
if (element === null) {
return () => {};
}

const handleOut = (event) => {
if (event.pointerType !== 'mouse') {
setPointer((prev) => ({
...prev,
isActive: false,
}));
}
};

const handleEnter = (event) => {
setPointer({
isActive: true,
isMousePointer: event.pointerType === 'mouse',
pointerHeight: event.height,
});
};

const handleMove = (event) => {
virtualElement.current = generateVirtualElement({
x: event.clientX,
y: event.clientY,
});
popperRef.current?.update();
};

element.addEventListener('pointerenter', handleEnter);
element.addEventListener('pointerup', handleOut);
element.addEventListener('pointermove', handleMove);

return () => {
element.removeEventListener('pointerenter', handleEnter);
element.removeEventListener('pointerup', handleOut);
element.removeEventListener('pointermove', handleMove);
};
}, [svgRef]);

return { ...pointer, popperRef, anchorEl: virtualElement.current };
}

export function CustomAxisTooltip() {
const tooltipData = useAxisTooltip();
const mousePosition = useMouseTracker(); // Track the mouse position on chart.
const { isActive, isMousePointer, pointerHeight, popperRef, anchorEl } =
usePointer();

if (!tooltipData || !mousePosition) {
if (!tooltipData || !isActive) {
// No data to display
return null;
}

// The pointer type can be used to have different behavior based on pointer type.
const isMousePointer = mousePosition?.pointerType === 'mouse';
// Adapt the tooltip offset to the size of the pointer.
const yOffset = isMousePointer ? 0 : 40 - mousePosition.height;
const yOffset = isMousePointer ? 0 : 40 - pointerHeight;

return (
<NoSsr>
Expand All @@ -29,7 +87,8 @@ export function CustomAxisTooltip() {
}}
open
placement={isMousePointer ? 'top-end' : 'top'}
anchorEl={generateVirtualElement(mousePosition)}
anchorEl={anchorEl}
popperRef={popperRef}
modifiers={[
{
name: 'offset',
Expand Down
79 changes: 72 additions & 7 deletions docs/data/charts/tooltip/CustomAxisTooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,88 @@
import * as React from 'react';
import NoSsr from '@mui/material/NoSsr';
import Popper from '@mui/material/Popper';
import Popper, { PopperProps } from '@mui/material/Popper';
import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
import { useAxisTooltip, useMouseTracker } from '@mui/x-charts/ChartsTooltip';
import { useAxisTooltip } from '@mui/x-charts/ChartsTooltip';
import { useSvgRef } from '@mui/x-charts/hooks';
import { generateVirtualElement } from './generateVirtualElement';

type PointerState = {
isActive: boolean;
isMousePointer: boolean;
pointerHeight: number;
};

function usePointer(): PointerState & Pick<PopperProps, 'popperRef' | 'anchorEl'> {
const svgRef = useSvgRef();
const popperRef: PopperProps['popperRef'] = React.useRef(null);
const virtualElement = React.useRef(generateVirtualElement({ x: 0, y: 0 }));

// Use a ref to avoid rerendering on every mousemove event.
const [pointer, setPointer] = React.useState<PointerState>({
isActive: false,
isMousePointer: false,
pointerHeight: 0,
});

React.useEffect(() => {
const element = svgRef.current;
if (element === null) {
return () => {};
}

const handleOut = (event: PointerEvent) => {
if (event.pointerType !== 'mouse') {
setPointer((prev) => ({
...prev,
isActive: false,
}));
}
};

const handleEnter = (event: PointerEvent) => {
setPointer({
isActive: true,
isMousePointer: event.pointerType === 'mouse',
pointerHeight: event.height,
});
};

const handleMove = (event: PointerEvent) => {
virtualElement.current = generateVirtualElement({
x: event.clientX,
y: event.clientY,
});
popperRef.current?.update();
};

element.addEventListener('pointerenter', handleEnter);
element.addEventListener('pointerup', handleOut);
element.addEventListener('pointermove', handleMove);

return () => {
element.removeEventListener('pointerenter', handleEnter);
element.removeEventListener('pointerup', handleOut);
element.removeEventListener('pointermove', handleMove);
};
}, [svgRef]);

return { ...pointer, popperRef, anchorEl: virtualElement.current };
}

export function CustomAxisTooltip() {
const tooltipData = useAxisTooltip();
const mousePosition = useMouseTracker(); // Track the mouse position on chart.
const { isActive, isMousePointer, pointerHeight, popperRef, anchorEl } =
usePointer();

if (!tooltipData || !mousePosition) {
if (!tooltipData || !isActive) {
// No data to display
return null;
}

// The pointer type can be used to have different behavior based on pointer type.
const isMousePointer = mousePosition?.pointerType === 'mouse';
// Adapt the tooltip offset to the size of the pointer.
const yOffset = isMousePointer ? 0 : 40 - mousePosition.height;
const yOffset = isMousePointer ? 0 : 40 - pointerHeight;

return (
<NoSsr>
Expand All @@ -29,7 +93,8 @@ export function CustomAxisTooltip() {
}}
open
placement={isMousePointer ? 'top-end' : 'top'}
anchorEl={generateVirtualElement(mousePosition)}
anchorEl={anchorEl}
popperRef={popperRef}
modifiers={[
{
name: 'offset',
Expand Down
72 changes: 65 additions & 7 deletions docs/data/charts/tooltip/CustomItemTooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,79 @@ import Popper from '@mui/material/Popper';
import Paper from '@mui/material/Paper';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import { useItemTooltip, useMouseTracker } from '@mui/x-charts/ChartsTooltip';
import { useItemTooltip } from '@mui/x-charts/ChartsTooltip';
import { useSvgRef } from '@mui/x-charts/hooks';
import { generateVirtualElement } from './generateVirtualElement';

function usePointer() {
const svgRef = useSvgRef();
const popperRef = React.useRef(null);
const virtualElement = React.useRef(generateVirtualElement({ x: 0, y: 0 }));

// Use a ref to avoid rerendering on every mousemove event.
const [pointer, setPointer] = React.useState({
isActive: false,
isMousePointer: false,
pointerHeight: 0,
});

React.useEffect(() => {
const element = svgRef.current;
if (element === null) {
return () => {};
}

const handleOut = (event) => {
if (event.pointerType !== 'mouse') {
setPointer((prev) => ({
...prev,
isActive: false,
}));
}
};

const handleEnter = (event) => {
setPointer({
isActive: true,
isMousePointer: event.pointerType === 'mouse',
pointerHeight: event.height,
});
};

const handleMove = (event) => {
virtualElement.current = generateVirtualElement({
x: event.clientX,
y: event.clientY,
});
popperRef.current?.update();
};

element.addEventListener('pointerenter', handleEnter);
element.addEventListener('pointerup', handleOut);
element.addEventListener('pointermove', handleMove);

return () => {
element.removeEventListener('pointerenter', handleEnter);
element.removeEventListener('pointerup', handleOut);
element.removeEventListener('pointermove', handleMove);
};
}, [svgRef]);

return { ...pointer, popperRef, anchorEl: virtualElement.current };
}

export function CustomItemTooltip() {
const tooltipData = useItemTooltip();
const mousePosition = useMouseTracker(); // Track the mouse position on chart.
const { isActive, isMousePointer, pointerHeight, popperRef, anchorEl } =
usePointer();

if (!tooltipData || !mousePosition) {
if (!tooltipData || !isActive) {
// No data to display
return null;
}

// The pointer type can be used to have different behavior based on pointer type.
const isMousePointer = mousePosition?.pointerType === 'mouse';
// Adapt the tooltip offset to the size of the pointer.
const yOffset = isMousePointer ? 0 : 40 - mousePosition.height;
const yOffset = isMousePointer ? 0 : 40 - pointerHeight;

return (
<NoSsr>
Expand All @@ -30,7 +87,8 @@ export function CustomItemTooltip() {
}}
open
placement={isMousePointer ? 'top-end' : 'top'}
anchorEl={generateVirtualElement(mousePosition)}
anchorEl={anchorEl}
popperRef={popperRef}
modifiers={[
{
name: 'offset',
Expand Down
Loading

0 comments on commit f49dc88

Please sign in to comment.