---
title: "React Popup Using as a tooltip Example | Mobiscroll"
component: "Popup"
framework: "React"
library_version: "6.1.5"
url: "https://demo.mobiscroll.com/react/popup/show-hide-tooltip-hover-in-out"
---

# Using as a tooltip - React Popup demo

Use the React popup with custom content on event hover within the various event calendar views. For React and Next.JS.

- [Live demo](https://demo.mobiscroll.com/react/popup/show-hide-tooltip-hover-in-out)
- [View React JS code on GitHub](https://github.com/acidb/mobiscroll-demos-react/tree/main/src/demos/pickers/popup/show-hide-tooltip-hover-in-out)
- [View React TS code on GitHub](https://github.com/acidb/mobiscroll-demos-react-ts/tree/main/src/demos/pickers/popup/show-hide-tooltip-hover-in-out)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/javascript/popup/show-hide-tooltip-hover-in-out.md), [jQuery](https://demo.mobiscroll.com/jquery/popup/show-hide-tooltip-hover-in-out.md), [Angular](https://demo.mobiscroll.com/angular/popup/show-hide-tooltip-hover-in-out.md), [Vue](https://demo.mobiscroll.com/vue/popup/show-hide-tooltip-hover-in-out.md)

## Description

Use the popup as a tooltip that gives a quick glance at more event details than just the labels. This approach is perfect for providing access to information without cluttering the interface.

The popup takes care of auto-positioning, taking the guesswork out of where it should show up. It also gives you full control over the content where you can use any Mobiscroll or custom component.

**Looking for more advanced event tooltip ideas?** [Check out this example →](https://demo.mobiscroll.com/react/scheduler/custom-event-tooltip)

## What this demo shows

- A desktop-style monthly event calendar view with event labels rendered inside day cells.
- **Event labels** Events are shown as labels, with different visual styles based on the event type or event data.
- **Event selection** Clicking an event label highlights the selected event.
- **Day hover state** Hovering over a day cell highlights the day number with a gray background.
- **Day selection** Clicking an empty area of a day cell selects that day and highlights the day number with a blue background.
- **Calendar header** The top-left side shows the current month and year, while the top-right side includes blue previous and next navigation arrows with a `Today` button between them.
- **Drag navigation** The calendar can be dragged left or right to navigate between weeks.
- **Custom event tooltip** Hovering over an event opens a popup as a tooltip below the hovered event.
- **Tooltip header** The tooltip header shows the title of the event.
- **Tooltip details** The tooltip body shows the exact start end and time of the hovered event.

## Best for

- **Appointment calendars** Showin appointments with exact start and end time.
- **Healthcare scheduling** Building calendar views where users need quick access to appointment details without opening a separate page.
- **Event detail previews** Displaying structured event information in a custom tooltip anchored to the hovered event.

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/react/popup/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/react/popup/api#opt-themeVariant) - option
- [`data`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-data) - option
- [`view`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-view) - option
- [`onEventHoverIn`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventHoverIn) - event
- [`onEventHoverOut`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventHoverOut) - event
- [`display`](https://mobiscroll.com/docs/react/popup/api#opt-display) - option
- [`anchor`](https://mobiscroll.com/docs/react/popup/api#opt-anchor) - option
- [`touchUi`](https://mobiscroll.com/docs/react/popup/api#opt-touchUi) - option
- [`isOpen`](https://mobiscroll.com/docs/react/popup/api#opt-isOpen) - option
- [`width`](https://mobiscroll.com/docs/react/popup/api#opt-width) - option
- [`showOverlay`](https://mobiscroll.com/docs/react/popup/api#opt-showOverlay) - option

## Code

### JSX

```jsx
import { Eventcalendar, formatDate, Page, Popup, setOptions } from '@mobiscroll/react';
import { useCallback, useMemo, useRef, useState } from 'react';

setOptions({
  theme: 'ios',
  themeVariant: 'light'
});

function App() {
  const myEvents = useMemo(
    () => [
      {
        title: 'CEO Strategy Meeting',
        start: '2026-10-01T10:00',
        end: '2026-10-01T11:00',
        color: '#FF5733',
      },
      {
        title: 'Board of Directors Briefing',
        start: '2026-10-03T14:00',
        end: '2026-10-03T15:00',
        color: '#33C4FF',
      },
      {
        title: 'Quarterly Review',
        start: '2026-10-05T09:00',
        end: '2026-10-05T10:00',
        color: '#33FF77',
      },
      {
        title: 'Executive Team Lunch',
        start: '2026-10-07T12:00',
        end: '2026-10-07T13:00',
        color: '#FFC733',
      },
      {
        title: 'Investor Meeting',
        start: '2026-10-10T11:00',
        end: '2026-10-10T12:00',
        color: '#9B59B6',
      },
      {
        title: 'Product Launch Review',
        start: '2026-10-12T13:00',
        end: '2026-10-12T14:00',
        color: '#FF6347',
      },
      {
        title: 'Press Conference Preparation',
        start: '2026-10-14T16:00',
        end: '2026-10-14T17:00',
        color: '#1E90FF',
      },
      {
        title: 'Client Partnership Discussion',
        start: '2026-10-18T10:00',
        end: '2026-10-18T11:00',
        color: '#FFD700',
      },
      {
        title: 'CEO’s Weekly Report',
        start: '2026-10-20T09:00',
        end: '2026-10-20T10:00',
        color: '#20B2AA',
      },
      {
        title: 'Town Hall Meeting',
        start: '2026-10-25T14:00',
        end: '2026-10-25T15:00',
        color: '#FF4500',
      },
    ],
    [],
  );

  const [isPopupOpen, setPopupOpen] = useState(false);
  const [myAnchor, setAnchor] = useState();
  const [eventTitle, setEventTitle] = useState({});
  const [eventStart, setEventStart] = useState({});
  const [eventEnd, setEventEnd] = useState({});
  const timerRef = useRef(null);

  const handleEventHoverIn = useCallback((args) => {
    if (timerRef.current) {
      clearTimeout(timerRef.current);
    }
    setEventTitle(args.event.title);
    setEventStart(formatDate('hh:mm A', new Date(args.event.start)));
    setEventEnd(formatDate('hh:mm A', new Date(args.event.end)));
    setAnchor(args.domEvent.target);
    setPopupOpen(true);
  }, []);

  const handleEventHoverOut = useCallback(() => {
    timerRef.current = setTimeout(() => {
      setPopupOpen(false);
    }, 200);
  }, []);

  const handleMouseEnter = useCallback(() => {
    if (timerRef.current) {
      clearTimeout(timerRef.current);
    }
  }, []);

  const handleMouseLeave = useCallback(() => {
    timerRef.current = setTimeout(() => {
      setPopupOpen(false);
    }, 200);
  }, []);

  const myView = useMemo(
    () => ({
      calendar: { type: 'month' },
    }),
    [],
  );

  return (
    <Page>
      <Eventcalendar data={myEvents} view={myView} onEventHoverIn={handleEventHoverIn} onEventHoverOut={handleEventHoverOut} />
      <Popup display="anchored" anchor={myAnchor} touchUi={false} isOpen={isPopupOpen} width={250} showOverlay={false}>
        <div onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
          <div className="mds-tooltip-event-title-cont">
            <span>{eventTitle}</span>
          </div>
          <div className="mds-tooltip-start-cont mbsc-flex">
            <span className="mds-tooltip-label">Start:</span>
            <span>{eventStart}</span>
          </div>
          <div className="mds-tooltip-end-cont mbsc-flex">
            <span className="mds-tooltip-label">End:</span>
            <span>{eventEnd}</span>
          </div>
        </div>
      </Popup>
    </Page>
  );
}

export default App;
```

### TSX

```tsx
import {
  Eventcalendar,
  formatDate,
  MbscCalendarEvent,
  MbscEventcalendarView,
  Page,
  Popup,
  setOptions,
} from '@mobiscroll/react';
import { useCallback, useMemo, useRef, useState } from 'react';

setOptions({
  theme: 'ios',
  themeVariant: 'light'
});

function App() {
  const myEvents = useMemo<MbscCalendarEvent[]>(
    () => [
      {
        title: 'CEO Strategy Meeting',
        start: '2026-10-01T10:00',
        end: '2026-10-01T11:00',
        color: '#FF5733',
      },
      {
        title: 'Board of Directors Briefing',
        start: '2026-10-03T14:00',
        end: '2026-10-03T15:00',
        color: '#33C4FF',
      },
      {
        title: 'Quarterly Review',
        start: '2026-10-05T09:00',
        end: '2026-10-05T10:00',
        color: '#33FF77',
      },
      {
        title: 'Executive Team Lunch',
        start: '2026-10-07T12:00',
        end: '2026-10-07T13:00',
        color: '#FFC733',
      },
      {
        title: 'Investor Meeting',
        start: '2026-10-10T11:00',
        end: '2026-10-10T12:00',
        color: '#9B59B6',
      },
      {
        title: 'Product Launch Review',
        start: '2026-10-12T13:00',
        end: '2026-10-12T14:00',
        color: '#FF6347',
      },
      {
        title: 'Press Conference Preparation',
        start: '2026-10-14T16:00',
        end: '2026-10-14T17:00',
        color: '#1E90FF',
      },
      {
        title: 'Client Partnership Discussion',
        start: '2026-10-18T10:00',
        end: '2026-10-18T11:00',
        color: '#FFD700',
      },
      {
        title: 'CEO’s Weekly Report',
        start: '2026-10-20T09:00',
        end: '2026-10-20T10:00',
        color: '#20B2AA',
      },
      {
        title: 'Town Hall Meeting',
        start: '2026-10-25T14:00',
        end: '2026-10-25T15:00',
        color: '#FF4500',
      },
    ],
    [],
  );

  const [isPopupOpen, setPopupOpen] = useState<boolean>(false);
  const [myAnchor, setAnchor] = useState<HTMLElement>();
  const [eventTitle, setEventTitle] = useState<string>('');
  const [eventStart, setEventStart] = useState<string>('');
  const [eventEnd, setEventEnd] = useState<string>('');
  const timerRef = useRef<ReturnType<typeof setTimeout>>(undefined);

  const handleEventHoverIn = useCallback((args: MbscCalendarEvent) => {
    if (timerRef.current) {
      clearTimeout(timerRef.current);
    }
    setEventTitle(args.event.title);
    setEventStart(formatDate('hh:mm A', new Date(args.event.start)));
    setEventEnd(formatDate('hh:mm A', new Date(args.event.end)));
    setAnchor(args.domEvent.target as HTMLElement);
    setPopupOpen(true);
  }, []);

  const handleEventHoverOut = useCallback(() => {
    timerRef.current = setTimeout(() => {
      setPopupOpen(false);
    }, 200);
  }, []);

  const handleMouseEnter = useCallback(() => {
    if (timerRef.current) {
      clearTimeout(timerRef.current);
    }
  }, []);

  const handleMouseLeave = useCallback(() => {
    timerRef.current = setTimeout(() => {
      setPopupOpen(false);
    }, 200);
  }, []);

  const myView = useMemo<MbscEventcalendarView>(
    () => ({
      calendar: { type: 'month' },
    }),
    [],
  );

  return (
    <Page>
      <Eventcalendar data={myEvents} view={myView} onEventHoverIn={handleEventHoverIn} onEventHoverOut={handleEventHoverOut} />
      <Popup display="anchored" anchor={myAnchor} touchUi={false} isOpen={isPopupOpen} width={250} showOverlay={false}>
        <div onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
          <div className="mds-tooltip-event-title-cont">
            <span>{eventTitle}</span>
          </div>
          <div className="mds-tooltip-start-cont mbsc-flex">
            <span className="mds-tooltip-label">Start:</span>
            <span>{eventStart}</span>
          </div>
          <div className="mds-tooltip-end-cont mbsc-flex">
            <span className="mds-tooltip-label">End:</span>
            <span>{eventEnd}</span>
          </div>
        </div>
      </Popup>
    </Page>
  );
}

export default App;
```

### CSS

```css
.mds-tooltip-event-title-cont {
  margin-bottom: 15px;
  text-align: center;
  font-size: 16px;
}

.mds-tooltip-start-cont,
.mds-tooltip-end-cont {
  justify-content: space-between;
  margin-bottom: 5px;
  font-size: 14px;
  padding: 5px 0;
  border-bottom: 1px solid #ddd;
}

.mds-tooltip-label {
  font-weight: 600;
}
```

## Implementation notes

- `Eventcalendar`'s `onEventHoverIn`/`(onEventHoverIn)`/`@event-hover-in` fires when the pointer enters an event; its handler reads `args.event` for the title/start/end and `args.domEvent.target` for the hovered element, formats the times with `formatDate('hh:mm A', ...)`, and opens the tooltip popup anchored to that element (`anchor`/`[anchor]`/`:anchor` set to the target, then `isOpen`/`:isOpen` set `true` in React/Vue or `popup.open()` called in Angular/JS after clearing any pending close timer).
- `onEventHoverOut`/`(onEventHoverOut)`/`@event-hover-out` doesn't close the popup immediately - it starts a `setTimeout` (200ms) that hides it (`isOpen = false` / `popup.close()`), giving the pointer time to move from the event onto the tooltip itself without it flickering closed.
- The tooltip content wraps its own `mouseenter`/`mouseleave` handlers (`onMouseEnter`/`onMouseLeave` in React, `@mouseenter`/`@mouseleave` in Vue, `(mouseenter)`/`(mouseleave)` in Angular): entering the tooltip clears the pending close timeout so it stays open; leaving it restarts the same 200ms close timer, so the two hover targets (event + tooltip) act as one continuous hover region.
- `Popup` options for the tooltip: `display: 'anchored'`, `touchUi: false` (keeps it in anchored/popover mode even in touch environments, since it's not meant to become a mobile action sheet), `showOverlay: false` (no dimmed backdrop, since it's a lightweight tooltip, not a modal), and `width: 250`.
- `Popup` has no `buttons` option set - it's dismiss-only via hover-out, with no footer actions.
- `Eventcalendar`'s `view` is `{ calendar: { type: 'month' } }`, rendering the month grid that the tooltip is anchored against.

## Run it in your project

1. If not signed up yet, or don't own a license, you can [start a free trial](https://mobiscroll.com/starttrial).

2. Clone the repository:

   ```
   git clone https://github.com/acidb/mobiscroll-demos-react.git
   ```

3. If not installed yet, install the Mobiscroll CLI from NPM:

   ```
   npm install -g @mobiscroll/cli
   ```

4. Config Mobiscroll - open a terminal window in the root directory and run:

   ```
   mobiscroll config react
   ```

5. Install dependencies - open a terminal window in the root directory and run:

   ```
   npm install
   ```

6. Run the project:

   ```
   npm run dev
   ```

On a trial, add `--trial` to the config command: `mobiscroll config react --trial`.

Running a demo locally requires a Mobiscroll trial or a license; setup is per framework at https://mobiscroll.com/docs/react/getting-started/installation

## Related demos

- Previous: [Event creation modal](https://demo.mobiscroll.com/react/popup/add-event-modal.md) - Use the React popup for event add/edit modals. Trigger within the event calendar component and load your own custom forms.
- Next: [Range picker with presets](https://demo.mobiscroll.com/react/popup/range-picker-popup-presets.md) - Use the React popup to create advanced range picker components with presets and more.
