mirror of
https://github.com/kremalicious/umami.git
synced 2024-12-18 15:23:38 +01:00
Merge pull request #481 from gnarlex/proptyping-common
Add prop-types for "common" components
This commit is contained in:
commit
826facf56a
@ -1,10 +1,11 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
import classNames from 'classnames';
|
||||
import Icon from './Icon';
|
||||
import styles from './Button.module.css';
|
||||
|
||||
export default function Button({
|
||||
function Button({
|
||||
type = 'button',
|
||||
icon,
|
||||
size,
|
||||
@ -43,3 +44,19 @@ export default function Button({
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
Button.propTypes = {
|
||||
type: PropTypes.oneOf(['button', 'submit', 'reset']),
|
||||
icon: PropTypes.node,
|
||||
size: PropTypes.oneOf(['xlarge', 'large', 'medium', 'small', 'xsmall']),
|
||||
variant: PropTypes.oneOf(['action', 'danger', 'light']),
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
tooltip: PropTypes.node,
|
||||
tooltipId: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
iconRight: PropTypes.bool,
|
||||
onClick: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Button;
|
||||
|
@ -1,16 +1,10 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import Button from './Button';
|
||||
import styles from './ButtonGroup.module.css';
|
||||
|
||||
export default function ButtonGroup({
|
||||
items = [],
|
||||
selectedItem,
|
||||
className,
|
||||
size,
|
||||
icon,
|
||||
onClick = () => {},
|
||||
}) {
|
||||
function ButtonGroup({ items = [], selectedItem, className, size, icon, onClick = () => {} }) {
|
||||
return (
|
||||
<div className={classNames(styles.group, className)}>
|
||||
{items.map(item => {
|
||||
@ -30,3 +24,19 @@ export default function ButtonGroup({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
ButtonGroup.propTypes = {
|
||||
items: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
label: PropTypes.node,
|
||||
value: PropTypes.any.isRequired,
|
||||
}),
|
||||
),
|
||||
selectedItem: PropTypes.any,
|
||||
className: PropTypes.string,
|
||||
size: PropTypes.oneOf(['xlarge', 'large', 'medium', 'small', 'xsmall']),
|
||||
icon: PropTypes.node,
|
||||
onClick: PropTypes.func,
|
||||
};
|
||||
|
||||
export default ButtonGroup;
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React, { useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Icon from 'components/common/Icon';
|
||||
import Check from 'assets/check.svg';
|
||||
import styles from './Checkbox.module.css';
|
||||
|
||||
export default function Checkbox({ name, value, label, onChange }) {
|
||||
function Checkbox({ name, value, label, onChange }) {
|
||||
const ref = useRef();
|
||||
|
||||
return (
|
||||
@ -25,3 +26,12 @@ export default function Checkbox({ name, value, label, onChange }) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Checkbox.propTypes = {
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.any,
|
||||
label: PropTypes.node,
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Checkbox;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Button from './Button';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
@ -6,7 +7,7 @@ const defaultText = (
|
||||
<FormattedMessage id="label.copy-to-clipboard" defaultMessage="Copy to clipboard" />
|
||||
);
|
||||
|
||||
export default function CopyButton({ element, ...props }) {
|
||||
function CopyButton({ element, ...props }) {
|
||||
const [text, setText] = useState(defaultText);
|
||||
|
||||
function handleClick() {
|
||||
@ -24,3 +25,13 @@ export default function CopyButton({ element, ...props }) {
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
CopyButton.propTypes = {
|
||||
element: PropTypes.shape({
|
||||
current: PropTypes.shape({
|
||||
select: PropTypes.func.isRequired,
|
||||
}),
|
||||
}),
|
||||
};
|
||||
|
||||
export default CopyButton;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { endOfYear, isSameDay } from 'date-fns';
|
||||
import Modal from './Modal';
|
||||
@ -54,7 +55,7 @@ const filterOptions = [
|
||||
},
|
||||
];
|
||||
|
||||
export default function DateFilter({ value, startDate, endDate, onChange, className }) {
|
||||
function DateFilter({ value, startDate, endDate, onChange, className }) {
|
||||
const [showPicker, setShowPicker] = useState(false);
|
||||
const displayValue =
|
||||
value === 'custom' ? (
|
||||
@ -117,3 +118,13 @@ const CustomRange = ({ startDate, endDate, onClick }) => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
DateFilter.propTypes = {
|
||||
value: PropTypes.string,
|
||||
startDate: PropTypes.instanceOf(Date),
|
||||
endDate: PropTypes.instanceOf(Date),
|
||||
onChange: PropTypes.func,
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default DateFilter;
|
||||
|
@ -1,8 +1,9 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import styles from './Dot.module.css';
|
||||
|
||||
export default function Dot({ color, size, className }) {
|
||||
function Dot({ color, size, className }) {
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<div
|
||||
@ -15,3 +16,11 @@ export default function Dot({ color, size, className }) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Dot.propTypes = {
|
||||
color: PropTypes.string,
|
||||
size: PropTypes.oneOf(['small', 'large']),
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Dot;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { useState, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import Menu from './Menu';
|
||||
import useDocumentClick from 'hooks/useDocumentClick';
|
||||
@ -6,13 +7,7 @@ import Chevron from 'assets/chevron-down.svg';
|
||||
import styles from './Dropdown.module.css';
|
||||
import Icon from './Icon';
|
||||
|
||||
export default function DropDown({
|
||||
value,
|
||||
className,
|
||||
menuClassName,
|
||||
options = [],
|
||||
onChange = () => {},
|
||||
}) {
|
||||
function DropDown({ value, className, menuClassName, options = [], onChange = () => {} }) {
|
||||
const [showMenu, setShowMenu] = useState(false);
|
||||
const ref = useRef();
|
||||
const selectedOption = options.find(e => e.value === value);
|
||||
@ -52,3 +47,18 @@ export default function DropDown({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
DropDown.propTypes = {
|
||||
value: PropTypes.any,
|
||||
className: PropTypes.string,
|
||||
menuClassName: PropTypes.string,
|
||||
options: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
value: PropTypes.any.isRequired,
|
||||
label: PropTypes.node,
|
||||
}),
|
||||
),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
export default DropDown;
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Icon from 'components/common/Icon';
|
||||
import Logo from 'assets/logo.svg';
|
||||
import styles from './EmptyPlaceholder.module.css';
|
||||
|
||||
export default function EmptyPlaceholder({ msg, children }) {
|
||||
function EmptyPlaceholder({ msg, children }) {
|
||||
return (
|
||||
<div className={styles.placeholder}>
|
||||
<Icon className={styles.icon} icon={<Logo />} size="xlarge" />
|
||||
@ -12,3 +13,10 @@ export default function EmptyPlaceholder({ msg, children }) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
EmptyPlaceholder.propTypes = {
|
||||
msg: PropTypes.node,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
export default EmptyPlaceholder;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Favicon.module.css';
|
||||
|
||||
function getHostName(url) {
|
||||
@ -6,7 +7,7 @@ function getHostName(url) {
|
||||
return match && match.length > 1 ? match[1] : null;
|
||||
}
|
||||
|
||||
export default function Favicon({ domain, ...props }) {
|
||||
function Favicon({ domain, ...props }) {
|
||||
const hostName = domain ? getHostName(domain) : null;
|
||||
|
||||
return hostName ? (
|
||||
@ -19,3 +20,9 @@ export default function Favicon({ domain, ...props }) {
|
||||
/>
|
||||
) : null;
|
||||
}
|
||||
|
||||
Favicon.propTypes = {
|
||||
domain: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Favicon;
|
||||
|
@ -1,11 +1,25 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ButtonLayout from 'components/layout/ButtonLayout';
|
||||
import ButtonGroup from './ButtonGroup';
|
||||
|
||||
export default function FilterButtons({ buttons, selected, onClick }) {
|
||||
function FilterButtons({ buttons, selected, onClick }) {
|
||||
return (
|
||||
<ButtonLayout>
|
||||
<ButtonGroup size="xsmall" items={buttons} selectedItem={selected} onClick={onClick} />
|
||||
</ButtonLayout>
|
||||
);
|
||||
}
|
||||
|
||||
FilterButtons.propTypes = {
|
||||
buttons: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
label: PropTypes.node,
|
||||
value: PropTypes.any.isRequired,
|
||||
}),
|
||||
),
|
||||
selected: PropTypes.any,
|
||||
onClick: PropTypes.func,
|
||||
};
|
||||
|
||||
export default FilterButtons;
|
||||
|
@ -1,8 +1,9 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import styles from './Icon.module.css';
|
||||
|
||||
export default function Icon({ icon, className, size = 'medium', ...props }) {
|
||||
function Icon({ icon, className, size = 'medium', ...props }) {
|
||||
return (
|
||||
<div
|
||||
className={classNames(styles.icon, className, {
|
||||
@ -18,3 +19,11 @@ export default function Icon({ icon, className, size = 'medium', ...props }) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Icon.propTypes = {
|
||||
className: PropTypes.string,
|
||||
icon: PropTypes.node.isRequired,
|
||||
size: PropTypes.oneOf(['xlarge', 'large', 'medium', 'small', 'xsmall']),
|
||||
};
|
||||
|
||||
export default Icon;
|
||||
|
@ -1,10 +1,11 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import NextLink from 'next/link';
|
||||
import Icon from './Icon';
|
||||
import styles from './Link.module.css';
|
||||
|
||||
export default function Link({ className, icon, children, size, iconRight, ...props }) {
|
||||
function Link({ className, icon, children, size, iconRight, ...props }) {
|
||||
return (
|
||||
<NextLink {...props}>
|
||||
<a
|
||||
@ -21,3 +22,13 @@ export default function Link({ className, icon, children, size, iconRight, ...pr
|
||||
</NextLink>
|
||||
);
|
||||
}
|
||||
|
||||
Link.propTypes = {
|
||||
className: PropTypes.string,
|
||||
icon: PropTypes.node,
|
||||
children: PropTypes.node,
|
||||
size: PropTypes.oneOf(['large', 'small', 'xsmall']),
|
||||
iconRight: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Link;
|
||||
|
@ -1,8 +1,9 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import styles from './Loading.module.css';
|
||||
|
||||
export default function Loading({ className }) {
|
||||
function Loading({ className }) {
|
||||
return (
|
||||
<div className={classNames(styles.loading, className)}>
|
||||
<div />
|
||||
@ -11,3 +12,9 @@ export default function Loading({ className }) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Loading.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Loading;
|
||||
|
@ -1,8 +1,9 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import styles from './Menu.module.css';
|
||||
|
||||
export default function Menu({
|
||||
function Menu({
|
||||
options = [],
|
||||
selectedOption,
|
||||
className,
|
||||
@ -46,3 +47,24 @@ export default function Menu({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Menu.propTypes = {
|
||||
options: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
label: PropTypes.node,
|
||||
value: PropTypes.any,
|
||||
className: PropTypes.string,
|
||||
render: PropTypes.func,
|
||||
divider: PropTypes.bool,
|
||||
}),
|
||||
),
|
||||
selectedOption: PropTypes.any,
|
||||
className: PropTypes.string,
|
||||
float: PropTypes.oneOf(['top', 'bottom']),
|
||||
align: PropTypes.oneOf(['left', 'right']),
|
||||
optionClassName: PropTypes.string,
|
||||
selectedClassName: PropTypes.string,
|
||||
onSelect: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Menu;
|
||||
|
@ -1,11 +1,12 @@
|
||||
import React, { useState, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import Menu from 'components/common/Menu';
|
||||
import Button from 'components/common/Button';
|
||||
import useDocumentClick from 'hooks/useDocumentClick';
|
||||
import styles from './MenuButton.module.css';
|
||||
|
||||
export default function MenuButton({
|
||||
function MenuButton({
|
||||
icon,
|
||||
value,
|
||||
options,
|
||||
@ -58,3 +59,25 @@ export default function MenuButton({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
MenuButton.propTypes = {
|
||||
icon: PropTypes.node,
|
||||
value: PropTypes.any,
|
||||
options: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
label: PropTypes.node,
|
||||
value: PropTypes.any,
|
||||
className: PropTypes.string,
|
||||
render: PropTypes.func,
|
||||
divider: PropTypes.bool,
|
||||
}),
|
||||
),
|
||||
buttonClassName: PropTypes.string,
|
||||
menuClassName: PropTypes.string,
|
||||
menuPosition: PropTypes.oneOf(['top', 'bottom']),
|
||||
menuAlign: PropTypes.oneOf(['left', 'right']),
|
||||
onSelect: PropTypes.func,
|
||||
renderValue: PropTypes.func,
|
||||
};
|
||||
|
||||
export default MenuButton;
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { useSpring, animated } from 'react-spring';
|
||||
import styles from './Modal.module.css';
|
||||
|
||||
export default function Modal({ title, children }) {
|
||||
function Modal({ title, children }) {
|
||||
const props = useSpring({ opacity: 1, from: { opacity: 0 } });
|
||||
|
||||
return ReactDOM.createPortal(
|
||||
@ -16,3 +17,10 @@ export default function Modal({ title, children }) {
|
||||
document.getElementById('__modals'),
|
||||
);
|
||||
}
|
||||
|
||||
Modal.propTypes = {
|
||||
title: PropTypes.node,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
export default Modal;
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useRouter } from 'next/router';
|
||||
import classNames from 'classnames';
|
||||
import styles from './NavMenu.module.css';
|
||||
|
||||
export default function NavMenu({ options = [], className, onSelect = () => {} }) {
|
||||
function NavMenu({ options = [], className, onSelect = () => {} }) {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
@ -30,3 +31,17 @@ export default function NavMenu({ options = [], className, onSelect = () => {} }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
NavMenu.propTypes = {
|
||||
options: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
label: PropTypes.node,
|
||||
value: PropTypes.any,
|
||||
className: PropTypes.string,
|
||||
render: PropTypes.func,
|
||||
}),
|
||||
),
|
||||
className: PropTypes.string,
|
||||
onSelect: PropTypes.func,
|
||||
};
|
||||
export default NavMenu;
|
||||
|
@ -1,12 +1,19 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import styles from './NoData.module.css';
|
||||
|
||||
export default function NoData({ className }) {
|
||||
function NoData({ className }) {
|
||||
return (
|
||||
<div className={classNames(styles.container, className)}>
|
||||
<FormattedMessage id="message.no-data-available" defaultMessage="No data available." />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
NoData.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default NoData;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { setDateRange } from 'redux/actions/websites';
|
||||
@ -8,7 +9,7 @@ import Dots from 'assets/ellipsis-h.svg';
|
||||
import useDateRange from 'hooks/useDateRange';
|
||||
import { getDateRange } from '../../lib/date';
|
||||
|
||||
export default function RefreshButton({ websiteId }) {
|
||||
function RefreshButton({ websiteId }) {
|
||||
const dispatch = useDispatch();
|
||||
const [dateRange] = useDateRange(websiteId);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@ -35,3 +36,9 @@ export default function RefreshButton({ websiteId }) {
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
RefreshButton.propTypes = {
|
||||
websiteId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
};
|
||||
|
||||
export default RefreshButton;
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import NoData from 'components/common/NoData';
|
||||
import styles from './Table.module.css';
|
||||
|
||||
export default function Table({
|
||||
function Table({
|
||||
columns,
|
||||
rows,
|
||||
empty,
|
||||
@ -45,6 +46,34 @@ export default function Table({
|
||||
);
|
||||
}
|
||||
|
||||
const styledObject = PropTypes.shape({
|
||||
className: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
});
|
||||
|
||||
Table.propTypes = {
|
||||
columns: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
cell: styledObject,
|
||||
className: PropTypes.string,
|
||||
header: styledObject,
|
||||
key: PropTypes.string,
|
||||
label: PropTypes.node,
|
||||
render: PropTypes.func,
|
||||
style: PropTypes.object,
|
||||
}),
|
||||
),
|
||||
rows: PropTypes.arrayOf(PropTypes.object),
|
||||
empty: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
bodyClassName: PropTypes.string,
|
||||
rowKey: PropTypes.func,
|
||||
showHeader: PropTypes.bool,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
export default Table;
|
||||
|
||||
export const TableRow = ({ columns, row }) => (
|
||||
<div className={classNames(styles.row, 'row')}>
|
||||
{columns.map(({ key, render, className, style, cell }, index) => (
|
||||
|
@ -1,7 +1,15 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import styles from './Tag.module.css';
|
||||
|
||||
export default function Tag({ className, children }) {
|
||||
function Tag({ className, children }) {
|
||||
return <span className={classNames(styles.tag, className)}>{children}</span>;
|
||||
}
|
||||
|
||||
Tag.propTypes = {
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
export default Tag;
|
||||
|
@ -1,11 +1,12 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { useSpring, animated } from 'react-spring';
|
||||
import styles from './Toast.module.css';
|
||||
import Icon from 'components/common/Icon';
|
||||
import Close from 'assets/times.svg';
|
||||
|
||||
export default function Toast({ message, timeout = 3000, onClose }) {
|
||||
function Toast({ message, timeout = 3000, onClose }) {
|
||||
const props = useSpring({
|
||||
opacity: 1,
|
||||
transform: 'translate3d(0,0px,0)',
|
||||
@ -24,3 +25,11 @@ export default function Toast({ message, timeout = 3000, onClose }) {
|
||||
document.getElementById('__modals'),
|
||||
);
|
||||
}
|
||||
|
||||
Toast.propTypes = {
|
||||
message: PropTypes.node,
|
||||
timeout: PropTypes.number,
|
||||
onClose: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Toast;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
import { ComposableMap, Geographies, Geography, ZoomableGroup } from 'react-simple-maps';
|
||||
import classNames from 'classnames';
|
||||
@ -12,7 +13,7 @@ import { useRouter } from 'next/router';
|
||||
|
||||
const geoUrl = '/world-110m.json';
|
||||
|
||||
export default function WorldMap({ data, className }) {
|
||||
function WorldMap({ data, className }) {
|
||||
const { basePath } = useRouter();
|
||||
const [tooltip, setTooltip] = useState();
|
||||
const [theme] = useTheme();
|
||||
@ -89,3 +90,16 @@ export default function WorldMap({ data, className }) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
WorldMap.propTypes = {
|
||||
data: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
x: PropTypes.string,
|
||||
y: PropTypes.number,
|
||||
z: PropTypes.number,
|
||||
}),
|
||||
),
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default WorldMap;
|
||||
|
Loading…
Reference in New Issue
Block a user