diff --git a/src/common/ScrollToTop.tsx b/src/common/ScrollToTop.tsx
index aae4a7f5..85fe9766 100644
--- a/src/common/ScrollToTop.tsx
+++ b/src/common/ScrollToTop.tsx
@@ -1,7 +1,7 @@
-import { FC, useEffect } from 'react';
+import { FC, PropsWithChildren, useEffect } from 'react';
import { useLocation } from 'react-router-dom';
-const ScrollToTop = (): FC => ({ children }) => {
+const ScrollToTop = (): FC
> => ({ children }) => {
const location = useLocation();
useEffect(() => {
diff --git a/src/servers/DeleteServerButton.tsx b/src/servers/DeleteServerButton.tsx
index 21d40fc4..a40e6ecc 100644
--- a/src/servers/DeleteServerButton.tsx
+++ b/src/servers/DeleteServerButton.tsx
@@ -1,15 +1,15 @@
-import { FC } from 'react';
+import { FC, PropsWithChildren } from 'react';
import { faMinusCircle as deleteIcon } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { useToggle } from '../utils/helpers/hooks';
import { DeleteServerModalProps } from './DeleteServerModal';
import { ServerWithId } from './data';
-export interface DeleteServerButtonProps {
+export type DeleteServerButtonProps = PropsWithChildren<{
server: ServerWithId;
className?: string;
textClassName?: string;
-}
+}>;
const DeleteServerButton = (DeleteServerModal: FC): FC => (
{ server, className, children, textClassName },
diff --git a/src/servers/Overview.tsx b/src/servers/Overview.tsx
index fc29a675..9127b1ab 100644
--- a/src/servers/Overview.tsx
+++ b/src/servers/Overview.tsx
@@ -8,12 +8,12 @@ import { ShortUrlsTableProps } from '../short-urls/ShortUrlsTable';
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
import { CreateShortUrlProps } from '../short-urls/CreateShortUrl';
import { VisitsOverview } from '../visits/reducers/visitsOverview';
-import { Versions } from '../utils/helpers/version';
import { Topics } from '../mercure/helpers/Topics';
import { ShlinkShortUrlsListParams } from '../api/types';
import { supportsNonOrphanVisits, supportsOrphanVisits } from '../utils/helpers/features';
import { getServerId, SelectedServer } from './data';
import { HighlightCard } from './helpers/HighlightCard';
+import { ForServerVersionProps } from './helpers/ForServerVersion';
interface OverviewConnectProps {
shortUrlsList: ShortUrlsListState;
@@ -28,7 +28,7 @@ interface OverviewConnectProps {
export const Overview = (
ShortUrlsTable: FC,
CreateShortUrl: FC,
- ForServerVersion: FC,
+ ForServerVersion: FC,
) => boundToMercureHub(({
shortUrlsList,
listShortUrls,
diff --git a/src/servers/ServersListGroup.tsx b/src/servers/ServersListGroup.tsx
index ed545b27..a88787a7 100644
--- a/src/servers/ServersListGroup.tsx
+++ b/src/servers/ServersListGroup.tsx
@@ -1,4 +1,4 @@
-import { FC } from 'react';
+import { FC, PropsWithChildren } from 'react';
import { ListGroup, ListGroupItem } from 'reactstrap';
import { Link } from 'react-router-dom';
import classNames from 'classnames';
@@ -7,10 +7,10 @@ import { faChevronRight as chevronIcon } from '@fortawesome/free-solid-svg-icons
import { ServerWithId } from './data';
import './ServersListGroup.scss';
-interface ServersListGroupProps {
+type ServersListGroupProps = PropsWithChildren<{
servers: ServerWithId[];
embedded?: boolean;
-}
+}>;
const ServerListItem = ({ id, name }: { id: string; name: string }) => (
diff --git a/src/servers/helpers/ForServerVersion.tsx b/src/servers/helpers/ForServerVersion.tsx
index 1f871a8e..abda57f2 100644
--- a/src/servers/helpers/ForServerVersion.tsx
+++ b/src/servers/helpers/ForServerVersion.tsx
@@ -1,12 +1,14 @@
-import { FC } from 'react';
+import { FC, PropsWithChildren } from 'react';
import { versionMatch, Versions } from '../../utils/helpers/version';
import { isReachableServer, SelectedServer } from '../data';
-interface ForServerVersionProps extends Versions {
+export type ForServerVersionProps = PropsWithChildren;
+
+interface ForServerVersionConnectProps extends ForServerVersionProps {
selectedServer: SelectedServer;
}
-const ForServerVersion: FC = ({ minVersion, maxVersion, selectedServer, children }) => {
+const ForServerVersion: FC = ({ minVersion, maxVersion, selectedServer, children }) => {
if (!isReachableServer(selectedServer)) {
return null;
}
diff --git a/src/servers/helpers/HighlightCard.tsx b/src/servers/helpers/HighlightCard.tsx
index 5f13edeb..d5a6f1ef 100644
--- a/src/servers/helpers/HighlightCard.tsx
+++ b/src/servers/helpers/HighlightCard.tsx
@@ -1,14 +1,14 @@
-import { FC } from 'react';
+import { FC, PropsWithChildren } from 'react';
import { Card, CardText, CardTitle } from 'reactstrap';
import { Link } from 'react-router-dom';
import { faArrowAltCircleRight as linkIcon } from '@fortawesome/free-regular-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import './HighlightCard.scss';
-export interface HighlightCardProps {
+export type HighlightCardProps = PropsWithChildren<{
title: string;
link?: string | false;
-}
+}>;
const buildExtraProps = (link?: string | false) => (!link ? {} : { tag: Link, to: link });
diff --git a/src/servers/helpers/ImportServersBtn.tsx b/src/servers/helpers/ImportServersBtn.tsx
index abc5be8c..e01500c6 100644
--- a/src/servers/helpers/ImportServersBtn.tsx
+++ b/src/servers/helpers/ImportServersBtn.tsx
@@ -1,4 +1,4 @@
-import { useRef, RefObject, ChangeEvent, MutableRefObject, useState, useEffect, FC } from 'react';
+import { useRef, RefObject, ChangeEvent, MutableRefObject, useState, useEffect, FC, PropsWithChildren } from 'react';
import { Button, UncontrolledTooltip } from 'reactstrap';
import { complement, pipe } from 'ramda';
import { faFileUpload as importIcon } from '@fortawesome/free-solid-svg-icons';
@@ -11,12 +11,12 @@ import './ImportServersBtn.scss';
type Ref = RefObject | MutableRefObject;
-export interface ImportServersBtnProps {
+export type ImportServersBtnProps = PropsWithChildren<{
onImport?: () => void;
onImportError?: (error: Error) => void;
tooltipPlacement?: 'top' | 'bottom';
className?: string;
-}
+}>;
interface ImportServersBtnConnectProps extends ImportServersBtnProps {
createServers: (servers: ServerData[]) => void;
diff --git a/src/servers/helpers/ServerForm.tsx b/src/servers/helpers/ServerForm.tsx
index 2e708e8e..f13b5b4a 100644
--- a/src/servers/helpers/ServerForm.tsx
+++ b/src/servers/helpers/ServerForm.tsx
@@ -1,14 +1,14 @@
-import { FC, ReactNode, useEffect, useState } from 'react';
+import { FC, PropsWithChildren, ReactNode, useEffect, useState } from 'react';
import { InputFormGroup } from '../../utils/forms/InputFormGroup';
import { handleEventPreventingDefault } from '../../utils/utils';
import { ServerData } from '../data';
import { SimpleCard } from '../../utils/SimpleCard';
-interface ServerFormProps {
+type ServerFormProps = PropsWithChildren<{
onSubmit: (server: ServerData) => void;
initialValues?: ServerData;
title?: ReactNode;
-}
+}>;
export const ServerForm: FC = ({ onSubmit, initialValues, children, title }) => {
const [name, setName] = useState('');
diff --git a/src/short-urls/helpers/QrCodeModal.tsx b/src/short-urls/helpers/QrCodeModal.tsx
index d0a7b996..081925e1 100644
--- a/src/short-urls/helpers/QrCodeModal.tsx
+++ b/src/short-urls/helpers/QrCodeModal.tsx
@@ -13,16 +13,16 @@ import {
supportsQrErrorCorrection,
} from '../../utils/helpers/features';
import { ImageDownloader } from '../../common/services/ImageDownloader';
-import { Versions } from '../../utils/helpers/version';
+import { ForServerVersionProps } from '../../servers/helpers/ForServerVersion';
import { QrFormatDropdown } from './qr-codes/QrFormatDropdown';
-import './QrCodeModal.scss';
import { QrErrorCorrectionDropdown } from './qr-codes/QrErrorCorrectionDropdown';
+import './QrCodeModal.scss';
interface QrCodeModalConnectProps extends ShortUrlModalProps {
selectedServer: SelectedServer;
}
-const QrCodeModal = (imageDownloader: ImageDownloader, ForServerVersion: FC) => (
+const QrCodeModal = (imageDownloader: ImageDownloader, ForServerVersion: FC) => (
{ shortUrl: { shortUrl, shortCode }, toggle, isOpen, selectedServer }: QrCodeModalConnectProps,
) => {
const [size, setSize] = useState(300);
diff --git a/src/short-urls/helpers/ShortUrlFormCheckboxGroup.tsx b/src/short-urls/helpers/ShortUrlFormCheckboxGroup.tsx
index 3798f512..85654d24 100644
--- a/src/short-urls/helpers/ShortUrlFormCheckboxGroup.tsx
+++ b/src/short-urls/helpers/ShortUrlFormCheckboxGroup.tsx
@@ -1,12 +1,12 @@
-import { ChangeEvent, FC } from 'react';
+import { ChangeEvent, FC, PropsWithChildren } from 'react';
import Checkbox from '../../utils/Checkbox';
import { InfoTooltip } from '../../utils/InfoTooltip';
-interface ShortUrlFormCheckboxGroupProps {
+type ShortUrlFormCheckboxGroupProps = PropsWithChildren<{
checked?: boolean;
onChange?: (checked: boolean, e: ChangeEvent) => void;
infoTooltip?: string;
-}
+}>;
export const ShortUrlFormCheckboxGroup: FC = (
{ children, infoTooltip, checked, onChange },
diff --git a/src/tags/helpers/Tag.tsx b/src/tags/helpers/Tag.tsx
index 72dd31cd..1bfa2daf 100644
--- a/src/tags/helpers/Tag.tsx
+++ b/src/tags/helpers/Tag.tsx
@@ -1,16 +1,16 @@
-import { FC, MouseEventHandler } from 'react';
+import { FC, MouseEventHandler, PropsWithChildren } from 'react';
import classNames from 'classnames';
import ColorGenerator from '../../utils/services/ColorGenerator';
import './Tag.scss';
-interface TagProps {
+type TagProps = PropsWithChildren<{
colorGenerator: ColorGenerator;
text: string;
className?: string;
clearable?: boolean;
onClick?: MouseEventHandler;
onClose?: MouseEventHandler;
-}
+}>;
const Tag: FC = ({ text, children, clearable, className = '', colorGenerator, onClick, onClose }) => (
) => void;
className?: string;
inline?: boolean;
-}
+}>;
interface BooleanControlWithTypeProps extends BooleanControlProps {
type: 'switch' | 'checkbox';
diff --git a/src/utils/DropdownBtn.tsx b/src/utils/DropdownBtn.tsx
index bbed5ba5..6bfe82cd 100644
--- a/src/utils/DropdownBtn.tsx
+++ b/src/utils/DropdownBtn.tsx
@@ -1,16 +1,16 @@
-import { FC } from 'react';
+import { FC, PropsWithChildren } from 'react';
import { Dropdown, DropdownMenu, DropdownToggle } from 'reactstrap';
import { useToggle } from './helpers/hooks';
import './DropdownBtn.scss';
-export interface DropdownBtnProps {
+export type DropdownBtnProps = PropsWithChildren<{
text: string;
disabled?: boolean;
className?: string;
dropdownClassName?: string;
right?: boolean;
minWidth?: number;
-}
+}>;
export const DropdownBtn: FC = (
{ text, disabled = false, className = '', children, dropdownClassName, right = false, minWidth },
diff --git a/src/utils/DropdownBtnMenu.tsx b/src/utils/DropdownBtnMenu.tsx
index 26d4565e..694ccb89 100644
--- a/src/utils/DropdownBtnMenu.tsx
+++ b/src/utils/DropdownBtnMenu.tsx
@@ -1,14 +1,14 @@
-import { FC } from 'react';
+import { FC, PropsWithChildren } from 'react';
import { ButtonDropdown, DropdownMenu, DropdownToggle } from 'reactstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faEllipsisV as menuIcon } from '@fortawesome/free-solid-svg-icons';
import './DropdownBtnMenu.scss';
-export interface DropdownBtnMenuProps {
+export type DropdownBtnMenuProps = PropsWithChildren<{
isOpen: boolean;
toggle: () => void;
right?: boolean;
-}
+}>;
export const DropdownBtnMenu: FC = ({ isOpen, toggle, children, right = true }) => (
diff --git a/src/utils/InfoTooltip.tsx b/src/utils/InfoTooltip.tsx
index fead3f4b..34cc7239 100644
--- a/src/utils/InfoTooltip.tsx
+++ b/src/utils/InfoTooltip.tsx
@@ -1,13 +1,13 @@
-import { FC, useRef } from 'react';
+import { FC, PropsWithChildren, useRef } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faInfoCircle as infoIcon } from '@fortawesome/free-solid-svg-icons';
import { UncontrolledTooltip } from 'reactstrap';
import { Placement } from '@popperjs/core';
-interface InfoTooltipProps {
+type InfoTooltipProps = PropsWithChildren<{
className?: string;
placement: Placement;
-}
+}>;
export const InfoTooltip: FC = ({ className = '', placement, children }) => {
const ref = useRef();
diff --git a/src/utils/Message.tsx b/src/utils/Message.tsx
index bd1f740b..7d267ca4 100644
--- a/src/utils/Message.tsx
+++ b/src/utils/Message.tsx
@@ -1,4 +1,4 @@
-import { FC } from 'react';
+import { FC, PropsWithChildren } from 'react';
import { Card, Row } from 'reactstrap';
import classNames from 'classnames';
import { faCircleNotch as preloader } from '@fortawesome/free-solid-svg-icons';
@@ -23,12 +23,12 @@ const getTextClassForType = (type: MessageType) => {
return map[type];
};
-export interface MessageProps {
+export type MessageProps = PropsWithChildren<{
className?: string;
loading?: boolean;
fullWidth?: boolean;
type?: MessageType;
-}
+}>;
const Message: FC = ({ className, children, loading = false, type = 'default', fullWidth = false }) => {
const classes = classNames({
diff --git a/src/utils/NavPills.tsx b/src/utils/NavPills.tsx
index f1e9ba67..4eaf3f17 100644
--- a/src/utils/NavPills.tsx
+++ b/src/utils/NavPills.tsx
@@ -1,17 +1,17 @@
-import { FC, Children, isValidElement } from 'react';
+import { FC, Children, isValidElement, PropsWithChildren } from 'react';
import { Card, Nav, NavLink } from 'reactstrap';
import { NavLink as RouterNavLink } from 'react-router-dom';
import './NavPills.scss';
-interface NavPillsProps {
+type NavPillsProps = PropsWithChildren<{
fill?: boolean;
className?: string;
-}
+}>;
-interface NavPillProps {
+type NavPillProps = PropsWithChildren<{
to: string;
replace?: boolean;
-}
+}>;
export const NavPillItem: FC = ({ children, ...rest }) => (
diff --git a/src/utils/Result.tsx b/src/utils/Result.tsx
index 5f49e703..eacf40f0 100644
--- a/src/utils/Result.tsx
+++ b/src/utils/Result.tsx
@@ -1,15 +1,15 @@
-import { FC } from 'react';
+import { FC, PropsWithChildren } from 'react';
import { Row } from 'reactstrap';
import classNames from 'classnames';
import { SimpleCard } from './SimpleCard';
export type ResultType = 'success' | 'error' | 'warning';
-export interface ResultProps {
+export type ResultProps = PropsWithChildren<{
type: ResultType;
className?: string;
small?: boolean;
-}
+}>;
export const Result: FC = ({ children, type, className, small = false }) => (
diff --git a/src/utils/TooltipToggleSwitch.tsx b/src/utils/TooltipToggleSwitch.tsx
index 1fb28f61..35d2889b 100644
--- a/src/utils/TooltipToggleSwitch.tsx
+++ b/src/utils/TooltipToggleSwitch.tsx
@@ -1,9 +1,11 @@
-import { FC, useRef } from 'react';
+import { FC, PropsWithChildren, useRef } from 'react';
import { UncontrolledTooltip, UncontrolledTooltipProps } from 'reactstrap';
import { BooleanControlProps } from './BooleanControl';
import ToggleSwitch from './ToggleSwitch';
-export type TooltipToggleSwitchProps = BooleanControlProps & { tooltip?: Omit };
+export type TooltipToggleSwitchProps = BooleanControlProps & PropsWithChildren<{
+ tooltip?: Omit;
+}>;
export const TooltipToggleSwitch: FC = ({ children, tooltip = {}, ...rest }) => {
const ref = useRef();
diff --git a/src/utils/forms/FormText.tsx b/src/utils/forms/FormText.tsx
index ffe4044b..c3e1a685 100644
--- a/src/utils/forms/FormText.tsx
+++ b/src/utils/forms/FormText.tsx
@@ -1,3 +1,5 @@
-import { FC } from 'react';
+import { FC, PropsWithChildren } from 'react';
-export const FormText: FC = ({ children }) => {children};
+export const FormText: FC> = ({ children }) => (
+ {children}
+);
diff --git a/src/utils/forms/InputFormGroup.tsx b/src/utils/forms/InputFormGroup.tsx
index 016671ad..9e047d3a 100644
--- a/src/utils/forms/InputFormGroup.tsx
+++ b/src/utils/forms/InputFormGroup.tsx
@@ -1,8 +1,8 @@
-import { FC } from 'react';
+import { FC, PropsWithChildren } from 'react';
import { InputType } from 'reactstrap/types/lib/Input';
import { LabeledFormGroup } from './LabeledFormGroup';
-export interface InputFormGroupProps {
+export type InputFormGroupProps = PropsWithChildren<{
value: string;
onChange: (newValue: string) => void;
type?: InputType;
@@ -10,7 +10,7 @@ export interface InputFormGroupProps {
placeholder?: string;
className?: string;
labelClassName?: string;
-}
+}>;
export const InputFormGroup: FC = (
{ children, value, onChange, type, required, placeholder, className, labelClassName },
diff --git a/src/utils/forms/LabeledFormGroup.tsx b/src/utils/forms/LabeledFormGroup.tsx
index cb7fd726..ea11c1ee 100644
--- a/src/utils/forms/LabeledFormGroup.tsx
+++ b/src/utils/forms/LabeledFormGroup.tsx
@@ -1,11 +1,11 @@
-import { FC, ReactNode } from 'react';
+import { FC, PropsWithChildren, ReactNode } from 'react';
-interface LabeledFormGroupProps {
+type LabeledFormGroupProps = PropsWithChildren<{
label: ReactNode;
noMargin?: boolean;
className?: string;
labelClassName?: string;
-}
+}>;
/* eslint-disable jsx-a11y/label-has-associated-control */
export const LabeledFormGroup: FC = (
diff --git a/src/utils/helpers/hooks.ts b/src/utils/helpers/hooks.ts
index 327b55ba..90c232d2 100644
--- a/src/utils/helpers/hooks.ts
+++ b/src/utils/helpers/hooks.ts
@@ -1,8 +1,8 @@
import { useState, useRef, EffectCallback, DependencyList, useEffect } from 'react';
import { useSwipeable as useReactSwipeable } from 'react-swipeable';
import { useNavigate } from 'react-router-dom';
-import { parseQuery, stringifyQuery } from './query';
import { v4 as uuid } from 'uuid';
+import { parseQuery, stringifyQuery } from './query';
const DEFAULT_DELAY = 2000;
diff --git a/src/visits/VisitsHeader.tsx b/src/visits/VisitsHeader.tsx
index 7cd36a77..85398a6b 100644
--- a/src/visits/VisitsHeader.tsx
+++ b/src/visits/VisitsHeader.tsx
@@ -1,17 +1,17 @@
import { Button, Card } from 'reactstrap';
-import { FC, ReactNode } from 'react';
+import { FC, PropsWithChildren, ReactNode } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faArrowLeft } from '@fortawesome/free-solid-svg-icons';
import ShortUrlVisitsCount from '../short-urls/helpers/ShortUrlVisitsCount';
import { ShortUrl } from '../short-urls/data';
import { Visit } from './types';
-interface VisitsHeaderProps {
+type VisitsHeaderProps = PropsWithChildren<{
visits: Visit[];
goBack: () => void;
title: ReactNode;
shortUrl?: ShortUrl;
-}
+}>;
const VisitsHeader: FC = ({ visits, goBack, shortUrl, children, title }) => (
diff --git a/src/visits/VisitsStats.tsx b/src/visits/VisitsStats.tsx
index 90e7fbe7..f0e35b89 100644
--- a/src/visits/VisitsStats.tsx
+++ b/src/visits/VisitsStats.tsx
@@ -1,5 +1,5 @@
import { isEmpty, propEq, values } from 'ramda';
-import { useState, useEffect, useMemo, FC, useRef } from 'react';
+import { useState, useEffect, useMemo, FC, useRef, PropsWithChildren } from 'react';
import { Button, Progress, Row } from 'reactstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCalendarAlt, faMapMarkedAlt, faList, faChartPie } from '@fortawesome/free-solid-svg-icons';
@@ -27,7 +27,7 @@ import { HighlightableProps, highlightedVisitsToStats } from './types/helpers';
import { DoughnutChartCard } from './charts/DoughnutChartCard';
import { SortableBarChartCard } from './charts/SortableBarChartCard';
-export interface VisitsStatsProps {
+export type VisitsStatsProps = PropsWithChildren<{
getVisits: (params: VisitsParams, doIntervalFallback?: boolean) => void;
visitsInfo: VisitsInfo;
settings: Settings;
@@ -36,7 +36,7 @@ export interface VisitsStatsProps {
domain?: string;
exportCsv: (visits: NormalizedVisit[]) => void;
isOrphanVisits?: boolean;
-}
+}>;
interface VisitsNavLinkProps {
title: string;
diff --git a/src/visits/charts/ChartCard.tsx b/src/visits/charts/ChartCard.tsx
index 9c25acc8..c68da31a 100644
--- a/src/visits/charts/ChartCard.tsx
+++ b/src/visits/charts/ChartCard.tsx
@@ -1,11 +1,11 @@
import { Card, CardHeader, CardBody, CardFooter } from 'reactstrap';
-import { FC, ReactNode } from 'react';
+import { FC, PropsWithChildren, ReactNode } from 'react';
import './ChartCard.scss';
-interface ChartCardProps {
+type ChartCardProps = PropsWithChildren<{
title: Function | string;
footer?: ReactNode;
-}
+}>;
export const ChartCard: FC = ({ title, footer, children }) => (