forked from Github/frigate
swr events refactor
This commit is contained in:
@@ -64,7 +64,6 @@ export default function Button({
|
||||
color = 'blue',
|
||||
disabled = false,
|
||||
href,
|
||||
size,
|
||||
type = 'contained',
|
||||
...attrs
|
||||
}) {
|
||||
@@ -81,11 +80,11 @@ export default function Button({
|
||||
classes = classes.replace(/(?:focus|active|hover):[^ ]+/g, '');
|
||||
}
|
||||
|
||||
const handleMousenter = useCallback((event) => {
|
||||
const handleMousenter = useCallback(() => {
|
||||
setHovered(true);
|
||||
}, []);
|
||||
|
||||
const handleMouseleave = useCallback((event) => {
|
||||
const handleMouseleave = useCallback(() => {
|
||||
setHovered(false);
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -7,27 +7,35 @@ export default function ButtonsTabbed({
|
||||
setHeader = null,
|
||||
headers = [''],
|
||||
className = 'text-gray-600 py-0 px-4 block hover:text-gray-500',
|
||||
selectedClassName = `${className} focus:outline-none border-b-2 font-medium border-gray-500`
|
||||
selectedClassName = `${className} focus:outline-none border-b-2 font-medium border-gray-500`,
|
||||
}) {
|
||||
const [selected, setSelected] = useState(0);
|
||||
const captitalize = (str) => { return (`${str.charAt(0).toUpperCase()}${str.slice(1)}`); };
|
||||
const captitalize = (str) => {
|
||||
return `${str.charAt(0).toUpperCase()}${str.slice(1)}`;
|
||||
};
|
||||
|
||||
const getHeader = useCallback((i) => {
|
||||
return (headers.length === viewModes.length ? headers[i] : captitalize(viewModes[i]));
|
||||
}, [headers, viewModes]);
|
||||
const getHeader = useCallback(
|
||||
(i) => {
|
||||
return headers.length === viewModes.length ? headers[i] : captitalize(viewModes[i]);
|
||||
},
|
||||
[headers, viewModes]
|
||||
);
|
||||
|
||||
const handleClick = useCallback((i) => {
|
||||
setSelected(i);
|
||||
setViewMode && setViewMode(viewModes[i]);
|
||||
setHeader && setHeader(getHeader(i));
|
||||
}, [setViewMode, setHeader, setSelected, viewModes, getHeader]);
|
||||
const handleClick = useCallback(
|
||||
(i) => {
|
||||
setSelected(i);
|
||||
setViewMode && setViewMode(viewModes[i]);
|
||||
setHeader && setHeader(getHeader(i));
|
||||
},
|
||||
[setViewMode, setHeader, setSelected, viewModes, getHeader]
|
||||
);
|
||||
|
||||
setHeader && setHeader(getHeader(selected));
|
||||
return (
|
||||
<nav className="flex justify-end">
|
||||
{viewModes.map((item, i) => {
|
||||
return (
|
||||
<button onClick={() => handleClick(i)} className={i === selected ? selectedClassName : className}>
|
||||
<button key={i} onClick={() => handleClick(i)} className={i === selected ? selectedClassName : className}>
|
||||
{captitalize(item)}
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@ import ArrowRightDouble from '../icons/ArrowRightDouble';
|
||||
|
||||
const todayTimestamp = new Date().setHours(0, 0, 0, 0).valueOf();
|
||||
|
||||
const Calender = ({ onChange, calenderRef, close }) => {
|
||||
const Calendar = ({ onChange, calendarRef, close }) => {
|
||||
const keyRef = useRef([]);
|
||||
|
||||
const date = new Date();
|
||||
@@ -159,8 +159,8 @@ const Calender = ({ onChange, calenderRef, close }) => {
|
||||
after,
|
||||
before:
|
||||
day.timestamp >= todayTimestamp
|
||||
? new Date(todayTimestamp).setHours(24, 0, 0, 0)
|
||||
: new Date(day.timestamp).setHours(24, 0, 0, 0),
|
||||
? new Date(todayTimestamp).setHours(24, 0, 0, 0)
|
||||
: new Date(day.timestamp).setHours(24, 0, 0, 0),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -243,26 +243,26 @@ const Calender = ({ onChange, calenderRef, close }) => {
|
||||
const days =
|
||||
state.monthDetails &&
|
||||
state.monthDetails.map((day, idx) => {
|
||||
return (
|
||||
<div
|
||||
onClick={() => onDateClick(day)}
|
||||
onkeydown={(e) => handleKeydown(e, day, idx)}
|
||||
ref={(ref) => (keyRef.current[idx] = ref)}
|
||||
tabIndex={day.month === 0 ? day.date : null}
|
||||
className={`h-12 w-12 float-left flex flex-shrink justify-center items-center cursor-pointer ${
|
||||
day.month !== 0 ? ' opacity-50 bg-gray-700 dark:bg-gray-700 pointer-events-none' : ''
|
||||
}
|
||||
return (
|
||||
<div
|
||||
onClick={() => onDateClick(day)}
|
||||
onkeydown={(e) => handleKeydown(e, day, idx)}
|
||||
ref={(ref) => (keyRef.current[idx] = ref)}
|
||||
tabIndex={day.month === 0 ? day.date : null}
|
||||
className={`h-12 w-12 float-left flex flex-shrink justify-center items-center cursor-pointer ${
|
||||
day.month !== 0 ? ' opacity-50 bg-gray-700 dark:bg-gray-700 pointer-events-none' : ''
|
||||
}
|
||||
${isFirstDayInRange(day) ? ' rounded-l-xl ' : ''}
|
||||
${isSelectedRange(day) ? ' bg-blue-600 dark:hover:bg-blue-600' : ''}
|
||||
${isLastDayInRange(day) ? ' rounded-r-xl ' : ''}
|
||||
${isCurrentDay(day) && !isLastDayInRange(day) ? 'rounded-full bg-gray-100 dark:hover:bg-gray-100 ' : ''}`}
|
||||
key={idx}
|
||||
>
|
||||
<div className="font-light">
|
||||
<span className="text-gray-400">{day.date}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
key={idx}
|
||||
>
|
||||
<div className="font-light">
|
||||
<span className="text-gray-400">{day.date}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
@@ -280,7 +280,7 @@ const Calender = ({ onChange, calenderRef, close }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="select-none w-96 flex flex-shrink" ref={calenderRef}>
|
||||
<div className="select-none w-96 flex flex-shrink" ref={calendarRef}>
|
||||
<div className="py-4 px-6">
|
||||
<div className="flex items-center">
|
||||
<div className="w-1/6 relative flex justify-around">
|
||||
@@ -326,4 +326,4 @@ const Calender = ({ onChange, calenderRef, close }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Calender;
|
||||
export default Calendar;
|
||||
@@ -1,11 +1,12 @@
|
||||
import { h } from 'preact';
|
||||
import ActivityIndicator from './ActivityIndicator';
|
||||
import { useApiHost, useConfig } from '../api';
|
||||
import { useApiHost } from '../api';
|
||||
import useSWR from 'swr';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'preact/hooks';
|
||||
import { useResizeObserver } from '../hooks';
|
||||
|
||||
export default function CameraImage({ camera, onload, searchParams = '', stretch = false }) {
|
||||
const { data: config } = useConfig();
|
||||
const { data: config } = useSWR('config');
|
||||
const apiHost = useApiHost();
|
||||
const [hasLoaded, setHasLoaded] = useState(false);
|
||||
const containerRef = useRef(null);
|
||||
|
||||
@@ -66,7 +66,6 @@ export default function DatePicker({
|
||||
onBlur,
|
||||
onChangeText,
|
||||
onFocus,
|
||||
readonly,
|
||||
trailingIcon: TrailingIcon,
|
||||
value: propValue = '',
|
||||
...props
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { h } from 'preact';
|
||||
import Heading from '../Heading';
|
||||
import { TimelineEvent } from '../Timeline/Timeline';
|
||||
import type { TimelineEvent } from '../Timeline/TimelineEvent';
|
||||
|
||||
interface HistoryHeaderProps {
|
||||
event: TimelineEvent;
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
import { Fragment, h } from 'preact';
|
||||
import { useCallback, useEffect, useState } from 'preact/hooks';
|
||||
import { useEvents } from '../../api';
|
||||
import { useSearchString } from '../../hooks/useSearchString';
|
||||
import { getNowYesterdayInLong } from '../../utils/dateUtil';
|
||||
import useSWR from 'swr';
|
||||
import axios from 'axios';
|
||||
import Timeline from '../Timeline/Timeline';
|
||||
import { TimelineChangeEvent } from '../Timeline/TimelineChangeEvent';
|
||||
import { TimelineEvent } from '../Timeline/TimelineEvent';
|
||||
import type { TimelineChangeEvent } from '../Timeline/TimelineChangeEvent';
|
||||
import type { TimelineEvent } from '../Timeline/TimelineEvent';
|
||||
import { HistoryHeader } from './HistoryHeader';
|
||||
import { HistoryVideo } from './HistoryVideo';
|
||||
|
||||
export default function HistoryViewer({ camera }) {
|
||||
const { searchString } = useSearchString(500, `camera=${camera}&after=${getNowYesterdayInLong()}`);
|
||||
const { data: events } = useEvents(searchString);
|
||||
const searchParams = {
|
||||
before: null,
|
||||
after: null,
|
||||
camera,
|
||||
label: 'all',
|
||||
zone: 'all',
|
||||
};
|
||||
|
||||
// TODO: refactor
|
||||
const eventsFetcher = (path, params) => {
|
||||
params = { ...params, include_thumbnails: 0, limit: 500 };
|
||||
return axios.get(path, { params }).then((res) => res.data);
|
||||
};
|
||||
|
||||
const { data: events } = useSWR(['events', searchParams], eventsFetcher);
|
||||
|
||||
const [timelineEvents, setTimelineEvents] = useState<TimelineEvent[]>(undefined);
|
||||
const [currentEvent, setCurrentEvent] = useState<TimelineEvent>(undefined);
|
||||
|
||||
@@ -5,7 +5,7 @@ import JSMpeg from '@cycjimmy/jsmpeg-player';
|
||||
|
||||
export default function JSMpegPlayer({ camera, width, height }) {
|
||||
const playerRef = useRef();
|
||||
const url = `${baseUrl.replace(/^http/, 'ws')}/live/${camera}`
|
||||
const url = `${baseUrl.replace(/^http/, 'ws')}/live/${camera}`;
|
||||
|
||||
useEffect(() => {
|
||||
const video = new JSMpeg.VideoElement(
|
||||
@@ -16,15 +16,15 @@ export default function JSMpegPlayer({ camera, width, height }) {
|
||||
);
|
||||
|
||||
const fullscreen = () => {
|
||||
if(video.els.canvas.webkitRequestFullScreen) {
|
||||
if (video.els.canvas.webkitRequestFullScreen) {
|
||||
video.els.canvas.webkitRequestFullScreen();
|
||||
}
|
||||
else {
|
||||
video.els.canvas.mozRequestFullScreen();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
video.els.canvas.addEventListener('click',fullscreen)
|
||||
video.els.canvas.addEventListener('click',fullscreen);
|
||||
|
||||
return () => {
|
||||
video.destroy();
|
||||
|
||||
@@ -16,18 +16,22 @@ export default function Menu({ className, children, onDismiss, relativeTo, width
|
||||
) : null;
|
||||
}
|
||||
|
||||
export function MenuItem({ focus, icon: Icon, label, onSelect, value }) {
|
||||
export function MenuItem({ focus, icon: Icon, label, href, onSelect, value, ...attrs }) {
|
||||
const handleClick = useCallback(() => {
|
||||
onSelect && onSelect(value, label);
|
||||
}, [onSelect, value, label]);
|
||||
|
||||
const Element = href ? 'a' : 'div';
|
||||
|
||||
return (
|
||||
<div
|
||||
<Element
|
||||
className={`flex space-x-2 p-2 px-5 hover:bg-gray-200 dark:hover:bg-gray-800 dark:hover:text-white cursor-pointer ${
|
||||
focus ? 'bg-gray-200 dark:bg-gray-800 dark:text-white' : ''
|
||||
}`}
|
||||
href={href}
|
||||
onClick={handleClick}
|
||||
role="option"
|
||||
{...attrs}
|
||||
>
|
||||
{Icon ? (
|
||||
<div className="w-6 h-6 self-center mr-4 text-gray-500 flex-shrink-0">
|
||||
@@ -35,7 +39,7 @@ export function MenuItem({ focus, icon: Icon, label, onSelect, value }) {
|
||||
</div>
|
||||
) : null}
|
||||
<div className="whitespace-nowrap">{label}</div>
|
||||
</div>
|
||||
</Element>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ export function Destination({ className = '', href, text, ...other }) {
|
||||
|
||||
const styleProps = {
|
||||
[external
|
||||
? 'className'
|
||||
? className
|
||||
: 'class']: 'block p-2 text-sm font-semibold text-gray-900 rounded hover:bg-blue-500 dark:text-gray-200 hover:text-white dark:hover:text-white focus:outline-none ring-opacity-50 focus:ring-2 ring-blue-300',
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
parseISO,
|
||||
startOfHour,
|
||||
differenceInMinutes,
|
||||
differenceInHours,
|
||||
differenceInHours
|
||||
} from 'date-fns';
|
||||
import ArrowDropdown from '../icons/ArrowDropdown';
|
||||
import ArrowDropup from '../icons/ArrowDropup';
|
||||
@@ -16,7 +16,7 @@ import Menu from '../icons/Menu';
|
||||
import MenuOpen from '../icons/MenuOpen';
|
||||
import { useApiHost } from '../api';
|
||||
|
||||
export default function RecordingPlaylist({ camera, recordings, selectedDate, selectedHour }) {
|
||||
export default function RecordingPlaylist({ camera, recordings, selectedDate }) {
|
||||
const [active, setActive] = useState(true);
|
||||
const toggle = () => setActive(!active);
|
||||
|
||||
@@ -33,7 +33,7 @@ export default function RecordingPlaylist({ camera, recordings, selectedDate, se
|
||||
.slice()
|
||||
.reverse()
|
||||
.map((item, i) => (
|
||||
<div className="mb-2 w-full">
|
||||
<div key={i} className="mb-2 w-full">
|
||||
<div
|
||||
className={`flex w-full text-md text-white px-8 py-2 mb-2 ${
|
||||
i === 0 ? 'border-t border-white border-opacity-50' : ''
|
||||
@@ -50,7 +50,7 @@ export default function RecordingPlaylist({ camera, recordings, selectedDate, se
|
||||
.slice()
|
||||
.reverse()
|
||||
.map((event) => (
|
||||
<EventCard camera={camera} event={event} delay={item.delay} />
|
||||
<EventCard key={event.id} camera={camera} event={event} delay={item.delay} />
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -110,7 +110,7 @@ export default function RelativeModal({
|
||||
|
||||
const menu = (
|
||||
<Fragment>
|
||||
<div data-testid="scrim" key="scrim" className="absolute inset-0 z-10" onClick={handleDismiss} />
|
||||
<div data-testid="scrim" key="scrim" className="fixed inset-0 z-10" onClick={handleDismiss} />
|
||||
<div
|
||||
key="menu"
|
||||
className={`z-10 bg-white dark:bg-gray-700 dark:text-white absolute shadow-lg rounded w-auto h-auto transition-transform transition-opacity duration-75 transform scale-90 opacity-0 overflow-x-hidden overflow-y-auto ${
|
||||
|
||||
@@ -4,7 +4,7 @@ import ArrowDropup from '../icons/ArrowDropup';
|
||||
import Menu, { MenuItem } from './Menu';
|
||||
import TextField from './TextField';
|
||||
import DatePicker from './DatePicker';
|
||||
import Calender from './Calender';
|
||||
import Calendar from './Calendar';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'preact/hooks';
|
||||
|
||||
export default function Select({
|
||||
@@ -71,8 +71,8 @@ export default function Select({
|
||||
}, [type, options, inputOptions, propSelected, setSelected]);
|
||||
|
||||
const [focused, setFocused] = useState(null);
|
||||
const [showCalender, setShowCalender] = useState(false);
|
||||
const calenderRef = useRef(null);
|
||||
const [showCalendar, setShowCalendar] = useState(false);
|
||||
const calendarRef = useRef(null);
|
||||
const ref = useRef(null);
|
||||
|
||||
const handleSelect = useCallback(
|
||||
@@ -80,8 +80,8 @@ export default function Select({
|
||||
setSelected(options.findIndex(({ value }) => Object.values(propSelected).includes(value)));
|
||||
setShowMenu(false);
|
||||
|
||||
//show calender date range picker
|
||||
if (value === 'custom_range') return setShowCalender(true);
|
||||
//show calendar date range picker
|
||||
if (value === 'custom_range') return setShowCalendar(true);
|
||||
onChange && onChange(value);
|
||||
},
|
||||
[onChange, options, propSelected, setSelected]
|
||||
@@ -110,7 +110,7 @@ export default function Select({
|
||||
setSelected(focused);
|
||||
if (options[focused].value === 'custom_range') {
|
||||
setShowMenu(false);
|
||||
return setShowCalender(true);
|
||||
return setShowCalendar(true);
|
||||
}
|
||||
|
||||
onChange && onChange(options[focused].value);
|
||||
@@ -184,8 +184,8 @@ export default function Select({
|
||||
|
||||
useEffect(() => {
|
||||
const addBackDrop = (e) => {
|
||||
if (showCalender && !findDOMNodes(calenderRef.current).contains(e.target)) {
|
||||
setShowCalender(false);
|
||||
if (showCalendar && !findDOMNodes(calendarRef.current).contains(e.target)) {
|
||||
setShowCalendar(false);
|
||||
}
|
||||
};
|
||||
window.addEventListener('click', addBackDrop);
|
||||
@@ -193,7 +193,7 @@ export default function Select({
|
||||
return function cleanup() {
|
||||
window.removeEventListener('click', addBackDrop);
|
||||
};
|
||||
}, [showCalender]);
|
||||
}, [showCalendar]);
|
||||
|
||||
switch (type) {
|
||||
case 'datepicker':
|
||||
@@ -208,9 +208,9 @@ export default function Select({
|
||||
trailingIcon={showMenu ? ArrowDropup : ArrowDropdown}
|
||||
value={datePickerValue}
|
||||
/>
|
||||
{showCalender && (
|
||||
{showCalendar && (
|
||||
<Menu className="rounded-t-none" onDismiss={handleDismiss} relativeTo={ref}>
|
||||
<Calender onChange={handleDateRange} calenderRef={calenderRef} close={() => setShowCalender(false)} />
|
||||
<Calendar onChange={handleDateRange} calendarRef={calendarRef} close={() => setShowCalendar(false)} />
|
||||
</Menu>
|
||||
)}
|
||||
{showMenu ? (
|
||||
@@ -223,7 +223,7 @@ export default function Select({
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
// case 'dropdown':
|
||||
// case 'dropdown':
|
||||
default:
|
||||
return (
|
||||
<Fragment>
|
||||
|
||||
@@ -4,14 +4,11 @@ import { useCallback, useState } from 'preact/hooks';
|
||||
export default function Switch({ checked, id, onChange, label, labelPosition = 'before' }) {
|
||||
const [isFocused, setFocused] = useState(false);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(event) => {
|
||||
if (onChange) {
|
||||
onChange(id, !checked);
|
||||
}
|
||||
},
|
||||
[id, onChange, checked]
|
||||
);
|
||||
const handleChange = useCallback(() => {
|
||||
if (onChange) {
|
||||
onChange(id, !checked);
|
||||
}
|
||||
}, [id, onChange, checked]);
|
||||
|
||||
const handleFocus = useCallback(() => {
|
||||
onChange && setFocused(true);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Fragment, h } from 'preact';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'preact/hooks';
|
||||
import { getTimelineEventBlocksFromTimelineEvents } from '../../utils/Timeline/timelineEventUtils';
|
||||
import { ScrollPermission } from './ScrollPermission';
|
||||
import type { ScrollPermission } from './ScrollPermission';
|
||||
import { TimelineBlocks } from './TimelineBlocks';
|
||||
import { TimelineChangeEvent } from './TimelineChangeEvent';
|
||||
import type { TimelineChangeEvent } from './TimelineChangeEvent';
|
||||
import { DisabledControls, TimelineControls } from './TimelineControls';
|
||||
import { TimelineEvent } from './TimelineEvent';
|
||||
import { TimelineEventBlock } from './TimelineEventBlock';
|
||||
import type { TimelineEvent } from './TimelineEvent';
|
||||
import type { TimelineEventBlock } from './TimelineEventBlock';
|
||||
|
||||
interface TimelineProps {
|
||||
events: TimelineEvent[];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { h } from 'preact';
|
||||
import { useCallback } from 'preact/hooks';
|
||||
import { getColorFromTimelineEvent } from '../../utils/tailwind/twTimelineEventUtil';
|
||||
import { TimelineEventBlock } from './TimelineEventBlock';
|
||||
import type { TimelineEventBlock } from './TimelineEventBlock';
|
||||
|
||||
interface TimelineBlockViewProps {
|
||||
block: TimelineEventBlock;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useMemo } from 'preact/hooks';
|
||||
import { findLargestYOffsetInBlocks, getTimelineWidthFromBlocks } from '../../utils/Timeline/timelineEventUtils';
|
||||
import { convertRemToPixels } from '../../utils/windowUtils';
|
||||
import { TimelineBlockView } from './TimelineBlockView';
|
||||
import { TimelineEventBlock } from './TimelineEventBlock';
|
||||
import type { TimelineEventBlock } from './TimelineEventBlock';
|
||||
|
||||
interface TimelineBlocksProps {
|
||||
timeline: TimelineEventBlock[];
|
||||
@@ -36,7 +36,7 @@ export const TimelineBlocks = ({ timeline, firstBlockOffset, onEventClick }: Tim
|
||||
...block,
|
||||
yOffset: block.yOffset + timelineBlockOffset,
|
||||
};
|
||||
return <TimelineBlockView block={updatedBlock} onClick={onClickHandler} />;
|
||||
return <TimelineBlockView key={block.id} block={updatedBlock} onClick={onClickHandler} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TimelineEvent } from './TimelineEvent';
|
||||
import type { TimelineEvent } from './TimelineEvent';
|
||||
|
||||
export interface TimelineChangeEvent {
|
||||
timelineEvent: TimelineEvent;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TimelineEvent } from './TimelineEvent';
|
||||
import type { TimelineEvent } from './TimelineEvent';
|
||||
|
||||
export interface TimelineEventBlock extends TimelineEvent {
|
||||
index: number;
|
||||
|
||||
@@ -6,14 +6,14 @@ describe('Tooltip', () => {
|
||||
test('renders in a relative position', async () => {
|
||||
jest
|
||||
.spyOn(window.HTMLElement.prototype, 'getBoundingClientRect')
|
||||
// relativeTo
|
||||
// relativeTo
|
||||
.mockReturnValueOnce({
|
||||
x: 100,
|
||||
y: 100,
|
||||
width: 50,
|
||||
height: 10,
|
||||
})
|
||||
// tooltip
|
||||
// tooltip
|
||||
.mockReturnValueOnce({ width: 40, height: 15 });
|
||||
|
||||
const ref = createRef();
|
||||
@@ -34,14 +34,14 @@ describe('Tooltip', () => {
|
||||
window.innerWidth = 1024;
|
||||
jest
|
||||
.spyOn(window.HTMLElement.prototype, 'getBoundingClientRect')
|
||||
// relativeTo
|
||||
// relativeTo
|
||||
.mockReturnValueOnce({
|
||||
x: 1000,
|
||||
y: 100,
|
||||
width: 24,
|
||||
height: 10,
|
||||
})
|
||||
// tooltip
|
||||
// tooltip
|
||||
.mockReturnValueOnce({ width: 50, height: 15 });
|
||||
|
||||
const ref = createRef();
|
||||
@@ -61,14 +61,14 @@ describe('Tooltip', () => {
|
||||
test('if too far left, renders to the right', async () => {
|
||||
jest
|
||||
.spyOn(window.HTMLElement.prototype, 'getBoundingClientRect')
|
||||
// relativeTo
|
||||
// relativeTo
|
||||
.mockReturnValueOnce({
|
||||
x: 0,
|
||||
y: 100,
|
||||
width: 24,
|
||||
height: 10,
|
||||
})
|
||||
// tooltip
|
||||
// tooltip
|
||||
.mockReturnValueOnce({ width: 50, height: 15 });
|
||||
|
||||
const ref = createRef();
|
||||
@@ -89,14 +89,14 @@ describe('Tooltip', () => {
|
||||
window.scrollY = 90;
|
||||
jest
|
||||
.spyOn(window.HTMLElement.prototype, 'getBoundingClientRect')
|
||||
// relativeTo
|
||||
// relativeTo
|
||||
.mockReturnValueOnce({
|
||||
x: 100,
|
||||
y: 100,
|
||||
width: 24,
|
||||
height: 10,
|
||||
})
|
||||
// tooltip
|
||||
// tooltip
|
||||
.mockReturnValueOnce({ width: 50, height: 15 });
|
||||
|
||||
const ref = createRef();
|
||||
|
||||
Reference in New Issue
Block a user