React / React DOM / Types upgrade to version 18 (#2830)

* new react and reactdom packages in wallet

* new react and reactdom packages in root

* new react and reactdom packages in nym connect

* new react and reactdom packages in root

* update react and reactdom for explorer

* react and react-dom upgrade for ts-packages

remove unused import

fix linting error

* use custom FC typing

move typings folder

* fix type error
This commit is contained in:
Fouad
2023-01-12 17:15:31 +00:00
committed by GitHub
parent 3bd4343a39
commit 2eee5195cc
183 changed files with 392 additions and 326 deletions
+4 -4
View File
@@ -18,8 +18,8 @@
"d3-scale": "^4.0.0",
"date-fns": "^2.24.0",
"i18n-iso-countries": "^6.8.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^3.1.4",
"react-google-charts": "^3.0.15",
"react-identicons": "^1.2.5",
@@ -48,8 +48,8 @@
"@types/geojson": "^7946.0.8",
"@types/jest": "^27.0.1",
"@types/node": "^16.7.13",
"@types/react": "^17.0.34",
"@types/react-dom": "^17.0.9",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.10",
"@types/react-simple-maps": "^1.0.6",
"@types/react-tooltip": "^4.2.4",
"@types/topojson-client": "^3.1.0",
+1 -1
View File
@@ -4,7 +4,7 @@ import { MobileNav } from './components/MobileNav';
import { Routes } from './routes/index';
import { useIsMobile } from './hooks/useIsMobile';
export const App: React.FC = () => {
export const App: FCWithChildren = () => {
const isMobile = useIsMobile();
if (isMobile) {
+1 -1
View File
@@ -1,7 +1,7 @@
import { Typography } from '@mui/material';
import * as React from 'react';
export const ComponentError: React.FC<{ text: string }> = ({ text }) => (
export const ComponentError: FCWithChildren<{ text: string }> = ({ text }) => (
<Typography
sx={{ marginTop: 2, color: 'primary.main', fontSize: 10 }}
variant="body1"
+1 -1
View File
@@ -10,7 +10,7 @@ type ContentCardProps = {
onClick?: ReactEventHandler;
};
export const ContentCard: React.FC<ContentCardProps> = ({
export const ContentCard: FCWithChildren<ContentCardProps> = ({
title,
Icon,
Action,
@@ -4,7 +4,7 @@ import { ExpandLess, ExpandMore } from '@mui/icons-material';
import { useTheme } from '@mui/material/styles';
import { Tooltip } from '@nymproject/react/tooltip/Tooltip';
export const CustomColumnHeading: React.FC<{ headingTitle: string; tooltipInfo?: string }> = ({
export const CustomColumnHeading: FCWithChildren<{ headingTitle: string; tooltipInfo?: string }> = ({
headingTitle,
tooltipInfo,
}) => {
+1 -1
View File
@@ -43,7 +43,7 @@ function formatCellValues(val: string | number, field: string) {
return val;
}
export const DetailTable: React.FC<{
export const DetailTable: FCWithChildren<{
tableName: string;
columnsData: ColumnsType[];
rows: MixnodeRowType[] | GatewayEnrichedRowType[];
+1 -1
View File
@@ -4,7 +4,7 @@ import { Typography } from '@mui/material';
import { Socials } from './Socials';
import { useIsMobile } from '../hooks/useIsMobile';
export const Footer: React.FC = () => {
export const Footer: FCWithChildren = () => {
const isMobile = useIsMobile();
return (
@@ -13,7 +13,7 @@ import { currencyToString } from '../../utils/currency';
import { useMixnodeContext } from '../../context/mixnode';
import { useIsMobile } from '../../hooks/useIsMobile';
export const BondBreakdownTable: React.FC = () => {
export const BondBreakdownTable: FCWithChildren = () => {
const { mixNode, delegations, uniqDelegations } = useMixnodeContext();
const [showDelegations, toggleShowDelegations] = React.useState<boolean>(false);
@@ -11,7 +11,7 @@ interface MixNodeDetailProps {
mixnodeDescription: MixNodeDescriptionResponse;
}
export const MixNodeDetailSection: React.FC<MixNodeDetailProps> = ({ mixNodeRow, mixnodeDescription }) => {
export const MixNodeDetailSection: FCWithChildren<MixNodeDetailProps> = ({ mixNodeRow, mixnodeDescription }) => {
const theme = useTheme();
const palette = [theme.palette.text.primary];
const isMobile = useIsMobile();
@@ -6,7 +6,7 @@ import { Box } from '@mui/system';
const parseToNumber = (value: number | undefined | string) =>
typeof value === 'string' ? parseInt(value || '', 10) : value || 0;
export const EconomicsProgress: React.FC<
export const EconomicsProgress: FCWithChildren<
LinearProgressProps & {
threshold?: number;
}
@@ -66,7 +66,7 @@ const formatCellValues = (value: EconomicsRowsType, field: string) => {
);
};
export const DelegatorsInfoTable: React.FC<UniversalTableProps<EconomicsInfoRowWithIndex>> = ({
export const DelegatorsInfoTable: FCWithChildren<UniversalTableProps<EconomicsInfoRowWithIndex>> = ({
tableName,
columnsData,
rows,
+1 -1
View File
@@ -36,7 +36,7 @@ export const getMixNodeStatusText = (status: MixnodeStatus) => {
}
};
export const MixNodeStatus: React.FC<MixNodeStatusProps> = ({ status }) => {
export const MixNodeStatus: FCWithChildren<MixNodeStatusProps> = ({ status }) => {
const theme = useTheme();
const Icon = React.useMemo(() => getMixNodeIcon(status), [status]);
const color = React.useMemo(() => getMixNodeStatusColor(theme, status), [status, theme]);
@@ -1,7 +1,7 @@
import * as React from 'react';
import { MenuItem } from '@mui/material';
import Select from '@mui/material/Select';
import { SelectInputProps } from '@mui/material/Select/SelectInput';
import { SelectChangeEvent } from '@mui/material/Select/SelectInput';
import { SxProps } from '@mui/system';
import { MixNodeStatus } from './Status';
import { MixnodeStatus, MixnodeStatusWithAll } from '../../typeDefs/explorer-api';
@@ -16,14 +16,18 @@ interface MixNodeStatusDropdownProps {
onSelectionChanged?: (status?: MixnodeStatusWithAll) => void;
}
export const MixNodeStatusDropdown: React.FC<MixNodeStatusDropdownProps> = ({ status, onSelectionChanged, sx }) => {
export const MixNodeStatusDropdown: FCWithChildren<MixNodeStatusDropdownProps> = ({
status,
onSelectionChanged,
sx,
}) => {
const isMobile = useIsMobile();
const [statusValue, setStatusValue] = React.useState<MixnodeStatusWithAll>(status || MixnodeStatusWithAll.all);
const onChange: SelectInputProps<MixnodeStatusWithAll>['onChange'] = React.useCallback(
({ target: { value } }) => {
setStatusValue(value);
const onChange = React.useCallback(
(event: SelectChangeEvent) => {
setStatusValue(event.target.value as MixnodeStatusWithAll);
if (onSelectionChanged) {
onSelectionChanged(value);
onSelectionChanged(event.target.value as MixnodeStatusWithAll);
}
},
[onSelectionChanged],
+1 -5
View File
@@ -25,11 +25,7 @@ import { NYM_WEBSITE } from '../api/constants';
import { ExpandableButton } from './Nav';
import { DarkLightSwitchMobile } from './Switch';
type MobileNavProps = {
children: React.ReactNode;
};
export const MobileNav: React.FC<{ children: React.ReactNode }> = ({ children }: MobileNavProps) => {
export const MobileNav: FCWithChildren = ({ children }) => {
const theme = useTheme();
const { navState, updateNavState } = useMainContext();
const [drawerOpen, setDrawerOpen] = React.useState(false);
+2 -2
View File
@@ -87,7 +87,7 @@ type ExpandableButtonType = {
setToActive: (num: number) => void;
};
export const ExpandableButton: React.FC<ExpandableButtonType> = ({
export const ExpandableButton: FCWithChildren<ExpandableButtonType> = ({
id,
url,
setToActive,
@@ -230,7 +230,7 @@ ExpandableButton.defaultProps = {
closeDrawer: undefined,
};
export const Nav: React.FC = ({ children }) => {
export const Nav: FCWithChildren = ({ children }) => {
const { updateNavState, navState } = useMainContext();
const [drawerIsOpen, setDrawerToOpen] = React.useState(false);
const [fixedOpen, setFixedOpen] = React.useState(false);
+1 -1
View File
@@ -12,7 +12,7 @@ export const TWITTER_LINK = 'https://twitter.com/nymproject';
export const GITHUB_LINK = 'https://github.com/nymtech';
export const DISCORD_LINK = 'https://discord.gg/nym';
export const Socials: React.FC<{ isFooter?: boolean }> = ({ isFooter }) => {
export const Socials: FCWithChildren<{ isFooter?: boolean }> = ({ isFooter }) => {
const theme = useTheme();
const color = isFooter
? theme.palette.nym.networkExplorer.footer.socialIcons
+8 -1
View File
@@ -11,7 +11,14 @@ interface StatsCardProps {
onClick?: () => void;
color?: string;
}
export const StatsCard: React.FC<StatsCardProps> = ({ icon, title, count, onClick, errorMsg, color: colorProp }) => {
export const StatsCard: FCWithChildren<StatsCardProps> = ({
icon,
title,
count,
onClick,
errorMsg,
color: colorProp,
}) => {
const theme = useTheme();
const color = colorProp || theme.palette.text.primary;
return (
+2 -2
View File
@@ -51,7 +51,7 @@ export const DarkLightSwitch = styled(Switch)(({ theme }) => ({
},
}));
export const DarkLightSwitchMobile: React.FC = () => {
export const DarkLightSwitchMobile: FCWithChildren = () => {
const { toggleMode } = useMainContext();
return (
<Button onClick={() => toggleMode()} data-testid="switch-button">
@@ -60,7 +60,7 @@ export const DarkLightSwitchMobile: React.FC = () => {
);
};
export const DarkLightSwitchDesktop: React.FC<{ defaultChecked: boolean }> = ({ defaultChecked }) => {
export const DarkLightSwitchDesktop: FCWithChildren<{ defaultChecked: boolean }> = ({ defaultChecked }) => {
const { toggleMode } = useMainContext();
return (
<Button sx={{ paddingLeft: 0 }} onClick={() => toggleMode()} data-testid="switch-button">
+1 -1
View File
@@ -16,7 +16,7 @@ type TableToolBarProps = {
childrenAfter?: React.ReactNode;
};
export const TableToolbar: React.FC<TableToolBarProps> = ({
export const TableToolbar: FCWithChildren<TableToolBarProps> = ({
searchTerm,
onChangeSearch,
onChangePageSize,
+1 -1
View File
@@ -1,7 +1,7 @@
import * as React from 'react';
import { Typography } from '@mui/material';
export const Title: React.FC<{ text: string }> = ({ text }) => (
export const Title: FCWithChildren<{ text: string }> = ({ text }) => (
<Typography
variant="h5"
sx={{
+1 -1
View File
@@ -19,7 +19,7 @@ interface TableProps {
loading: boolean;
}
export const TwoColSmallTable: React.FC<TableProps> = ({
export const TwoColSmallTable: FCWithChildren<TableProps> = ({
loading,
title,
icons,
@@ -50,7 +50,7 @@ type DataGridProps = {
rows: any;
loading?: boolean;
};
export const UniversalDataGrid: React.FC<DataGridProps> = ({ rows, columns, loading, pagination, pageSize }) => {
export const UniversalDataGrid: FCWithChildren<DataGridProps> = ({ rows, columns, loading, pagination, pageSize }) => {
if (loading) return <LinearProgress />;
if (!loading)
return (
+1 -1
View File
@@ -17,7 +17,7 @@ type FormattedDateRecord = [string, number];
type FormattedChartHeadings = string[];
type FormattedChartData = [FormattedChartHeadings | FormattedDateRecord];
export const UptimeChart: React.FC<ChartProps> = ({ title, xLabel, yLabel, uptimeStory, loading }) => {
export const UptimeChart: FCWithChildren<ChartProps> = ({ title, xLabel, yLabel, uptimeStory, loading }) => {
const [formattedChartData, setFormattedChartData] = React.useState<FormattedChartData>();
const theme = useTheme();
const color = theme.palette.text.primary;
+1 -1
View File
@@ -14,7 +14,7 @@ type MapProps = {
loading: boolean;
};
export const WorldMap: React.FC<MapProps> = ({ countryData, userLocation, loading }) => {
export const WorldMap: FCWithChildren<MapProps> = ({ countryData, userLocation, loading }) => {
const { palette } = useTheme();
const colorScale = React.useMemo(() => {
+1 -1
View File
@@ -46,7 +46,7 @@ export const MainContext = React.createContext<State>({
export const useMainContext = (): React.ContextType<typeof MainContext> => React.useContext<State>(MainContext);
export const MainContextProvider: React.FC = ({ children }) => {
export const MainContextProvider: FCWithChildren = ({ children }) => {
// light/dark mode
const [mode, setMode] = React.useState<PaletteMode>('dark');
+2 -1
View File
@@ -37,13 +37,14 @@ export const useMixnodeContext = (): React.ContextType<typeof MixnodeContext> =>
interface MixnodeContextProviderProps {
mixId: string;
children: React.ReactNode;
}
/**
* Provides a state context for a mixnode by identity
* @param mixId The mixID of the mixnode
*/
export const MixnodeContextProvider: React.FC<MixnodeContextProviderProps> = ({ mixId, children }) => {
export const MixnodeContextProvider: FCWithChildren<MixnodeContextProviderProps> = ({ mixId, children }) => {
const [mixNode, fetchMixnodeById, clearMixnodeById] = useApiState<MixNodeResponseItem | undefined>(
mixId,
Api.fetchMixnodeByID,
+1 -1
View File
@@ -4,7 +4,7 @@ import { Alert, AlertTitle, Container } from '@mui/material';
import { NymThemeProvider } from '@nymproject/mui-theme';
import { NymLogo } from '@nymproject/react/logo/NymLogo';
export const ErrorBoundaryContent: React.FC<FallbackProps> = ({ error }) => (
export const ErrorBoundaryContent: FCWithChildren<FallbackProps> = ({ error }) => (
<NymThemeProvider mode="dark">
<Container sx={{ py: 4 }}>
<NymLogo height="75px" width="75px" />
+1 -1
View File
@@ -1,7 +1,7 @@
import * as React from 'react';
import { useTheme } from '@mui/material/styles';
export const GatewaysSVG: React.FC = () => {
export const GatewaysSVG: FCWithChildren = () => {
const theme = useTheme();
const color = theme.palette.text.primary;
return (
+1 -1
View File
@@ -1,7 +1,7 @@
import * as React from 'react';
import { useTheme } from '@mui/material/styles';
export const LightSwitchSVG: React.FC = () => {
export const LightSwitchSVG: FCWithChildren = () => {
const { palette } = useTheme();
return (
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
+1 -1
View File
@@ -1,7 +1,7 @@
import * as React from 'react';
import { useTheme } from '@mui/material/styles';
export const MixnodesSVG: React.FC = () => {
export const MixnodesSVG: FCWithChildren = () => {
const theme = useTheme();
const color = theme.palette.text.primary;
+1 -1
View File
@@ -1,6 +1,6 @@
import * as React from 'react';
export const MobileDrawerClose: React.FC = (props) => (
export const MobileDrawerClose: FCWithChildren = (props) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -5 24 24" width="25" height="25" {...props}>
<path
d="M0 12H13V10H0V12ZM0 7H10V5H0V7ZM0 0V2H13V0H0ZM18 9.59L14.42 6L18 2.41L16.59 1L11.59 6L16.59 11L18 9.59Z"
+1 -1
View File
@@ -1,7 +1,7 @@
import * as React from 'react';
import { useTheme } from '@mui/material/styles';
export const NetworkComponentsSVG: React.FC = () => {
export const NetworkComponentsSVG: FCWithChildren = () => {
const theme = useTheme();
const color = theme.palette.nym.networkExplorer.nav.text;
return (
+1 -1
View File
@@ -1,7 +1,7 @@
import * as React from 'react';
import { useTheme } from '@mui/material/styles';
export const NodemapSVG: React.FC = () => {
export const NodemapSVG: FCWithChildren = () => {
const theme = useTheme();
const color = theme.palette.nym.networkExplorer.nav.text;
return (
+1 -1
View File
@@ -1,7 +1,7 @@
import * as React from 'react';
import { useTheme } from '@mui/material/styles';
export const OverviewSVG: React.FC = () => {
export const OverviewSVG: FCWithChildren = () => {
const theme = useTheme();
const color = theme.palette.nym.networkExplorer.nav.text;
+1 -1
View File
@@ -1,7 +1,7 @@
import * as React from 'react';
import { useTheme } from '@mui/material/styles';
export const ValidatorsSVG: React.FC = () => {
export const ValidatorsSVG: FCWithChildren = () => {
const theme = useTheme();
const color = theme.palette.text.primary;
return (
+1 -1
View File
@@ -6,7 +6,7 @@ interface DiscordIconProps {
color?: string;
}
export const DiscordIcon: React.FC<DiscordIconProps> = ({ size, color: colorProp }) => {
export const DiscordIcon: FCWithChildren<DiscordIconProps> = ({ size, color: colorProp }) => {
const theme = useTheme();
const color = colorProp || theme.palette.text.primary;
return (
+1 -1
View File
@@ -6,7 +6,7 @@ interface GitHubIconProps {
color?: string;
}
export const GitHubIcon: React.FC<GitHubIconProps> = ({ size, color: colorProp }) => {
export const GitHubIcon: FCWithChildren<GitHubIconProps> = ({ size, color: colorProp }) => {
const theme = useTheme();
const color = colorProp || theme.palette.text.primary;
return (
+1 -1
View File
@@ -6,7 +6,7 @@ interface TelegramIconProps {
color?: string;
}
export const TelegramIcon: React.FC<TelegramIconProps> = ({ size, color: colorProp }) => {
export const TelegramIcon: FCWithChildren<TelegramIconProps> = ({ size, color: colorProp }) => {
const theme = useTheme();
const color = colorProp || theme.palette.text.primary;
return (
+1 -1
View File
@@ -6,7 +6,7 @@ interface TwitterIconProps {
color?: string;
}
export const TwitterIcon: React.FC<TwitterIconProps> = ({ size, color: colorProp }) => {
export const TwitterIcon: FCWithChildren<TwitterIconProps> = ({ size, color: colorProp }) => {
const theme = useTheme();
const color = colorProp || theme.palette.text.primary;
return (
+17 -13
View File
@@ -1,5 +1,5 @@
import * as React from 'react';
import ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client';
import { BrowserRouter as Router } from 'react-router-dom';
import { ErrorBoundary } from 'react-error-boundary';
import { App } from './App';
@@ -8,15 +8,19 @@ import './styles.css';
import { NetworkExplorerThemeProvider } from './theme';
import { ErrorBoundaryContent } from './errors/ErrorBoundaryContent';
ReactDOM.render(
<ErrorBoundary FallbackComponent={ErrorBoundaryContent}>
<MainContextProvider>
<NetworkExplorerThemeProvider>
<Router>
<App />
</Router>
</NetworkExplorerThemeProvider>
</MainContextProvider>
</ErrorBoundary>,
document.getElementById('app'),
);
const elem = document.getElementById('app');
if (elem) {
const root = createRoot(elem);
root.render(
<ErrorBoundary FallbackComponent={ErrorBoundaryContent}>
<MainContextProvider>
<NetworkExplorerThemeProvider>
<Router>
<App />
</Router>
</NetworkExplorerThemeProvider>
</MainContextProvider>
</ErrorBoundary>,
);
}
+1 -1
View File
@@ -5,7 +5,7 @@ import { useNavigate } from 'react-router-dom';
import { NymLogo } from '@nymproject/react/logo/NymLogo';
import { useMainContext } from '../../context/main';
export const Page404: React.FC = () => {
export const Page404 = () => {
const navigate = useNavigate();
const { mode } = useMainContext();
const theme = useTheme();
+2 -2
View File
@@ -129,7 +129,7 @@ const PageGatewayDetailsWithState = ({ selectedGateway }: { selectedGateway: Gat
/**
* Guard component to handle loading and not found states
*/
const PageGatewayDetailGuard: React.FC = () => {
const PageGatewayDetailGuard: FCWithChildren = () => {
const [selectedGateway, setSelectedGateway] = React.useState<GatewayResponseItem | undefined>();
const { gateways } = useMainContext();
const { id } = useParams<{ id: string | undefined }>();
@@ -170,7 +170,7 @@ const PageGatewayDetailGuard: React.FC = () => {
/**
* Wrapper component that adds the mixnode content based on the `id` in the address URL
*/
export const PageGatewayDetail: React.FC = () => {
export const PageGatewayDetail: FCWithChildren = () => {
const { id } = useParams<{ id: string | undefined }>();
if (!id) {
+1 -1
View File
@@ -15,7 +15,7 @@ import { Tooltip } from '../../components/Tooltip';
import { BIG_DIPPER } from '../../api/constants';
import { splice } from '../../utils';
export const PageGateways: React.FC = () => {
export const PageGateways: FCWithChildren = () => {
const { gateways } = useMainContext();
const [filteredGateways, setFilteredGateways] = React.useState<GatewayResponse>([]);
const [pageSize, setPageSize] = React.useState<string>('50');
+3 -3
View File
@@ -62,7 +62,7 @@ const columns: ColumnsType[] = [
/**
* Shows mix node details
*/
const PageMixnodeDetailWithState: React.FC = () => {
const PageMixnodeDetailWithState: FCWithChildren = () => {
const { mixNode, mixNodeRow, description, stats, status, uptimeStory, uniqDelegations } = useMixnodeContext();
return (
@@ -181,7 +181,7 @@ const PageMixnodeDetailWithState: React.FC = () => {
/**
* Guard component to handle loading and not found states
*/
const PageMixnodeDetailGuard: React.FC = () => {
const PageMixnodeDetailGuard: FCWithChildren = () => {
const { mixNode } = useMixnodeContext();
const { id } = useParams<{ id: string | undefined }>();
@@ -215,7 +215,7 @@ const PageMixnodeDetailGuard: React.FC = () => {
/**
* Wrapper component that adds the mixnode content based on the `id` in the address URL
*/
export const PageMixnodeDetail: React.FC = () => {
export const PageMixnodeDetail: FCWithChildren = () => {
const { id } = useParams<{ id: string | undefined }>();
if (!id) {
+1 -1
View File
@@ -35,7 +35,7 @@ const getCellStyles = (theme: Theme, row: MixnodeRowType, textColor?: string): S
...getCellFontStyle(theme, row, textColor),
});
export const PageMixnodes: React.FC = () => {
export const PageMixnodes: FCWithChildren = () => {
const { mixnodes, fetchMixnodes } = useMainContext();
const [filteredMixnodes, setFilteredMixnodes] = React.useState<MixNodeResponse>([]);
const [pageSize, setPageSize] = React.useState<string>('10');
+7 -2
View File
@@ -10,7 +10,7 @@ import { WorldMap } from '../../components/WorldMap';
import { useMainContext } from '../../context/main';
import { CountryDataRowType, countryDataToGridRow } from '../../utils';
export const PageMixnodesMap: React.FC = () => {
export const PageMixnodesMap: FCWithChildren = () => {
const { countryData } = useMainContext();
const [pageSize, setPageSize] = React.useState<string>('10');
const [formattedCountries, setFormattedCountries] = React.useState<CountryDataRowType[]>([]);
@@ -115,5 +115,10 @@ export const PageMixnodesMap: React.FC = () => {
</Box>
);
}
return <Alert severity="error">{countryData?.error}</Alert>;
if (countryData?.error) {
return <Alert severity="error">{countryData.error.message}</Alert>;
}
return null;
};
+1 -1
View File
@@ -15,7 +15,7 @@ import { ContentCard } from '../../components/ContentCard';
import { StatsCard } from '../../components/StatsCard';
import { Icons } from '../../components/Icons';
export const PageOverview: React.FC = () => {
export const PageOverview: FCWithChildren = () => {
const theme = useTheme();
const navigate = useNavigate();
const { summaryOverview, gateways, validators, block, countryData } = useMainContext();
+2 -2
View File
@@ -5,11 +5,11 @@ import { PageMixnodesMap } from '../pages/MixnodesMap';
import { Page404 } from '../pages/404';
import { NetworkComponentsRoutes } from './network-components';
export const Routes: React.FC = () => (
export const Routes: FCWithChildren = () => (
<ReactRouterRoutes>
<Route path="/" element={<PageOverview />} />
<Route path="/network-components/*" element={<NetworkComponentsRoutes />} />
<Route path="/nodemap" element={<PageMixnodesMap />} />
<Route path="*" element={Page404} />
<Route path="*" element={<Page404 />} />
</ReactRouterRoutes>
);
+2 -2
View File
@@ -6,14 +6,14 @@ import { PageGatewayDetail } from '../pages/GatewayDetail';
import { PageMixnodeDetail } from '../pages/MixnodeDetail';
import { PageMixnodes } from '../pages/Mixnodes';
const ValidatorRoute: React.FC = () => {
const ValidatorRoute: FCWithChildren = () => {
const navigate = useNavigate();
window.open(`${BIG_DIPPER}/validators`);
navigate(-1);
return null;
};
export const NetworkComponentsRoutes: React.FC = () => (
export const NetworkComponentsRoutes: FCWithChildren = () => (
<ReactRouterRoutes>
<Route path="mixnodes/:status" element={<PageMixnodes />} />
<Route path="mixnodes" element={<PageMixnodes />} />
+1 -1
View File
@@ -2,7 +2,7 @@ import * as React from 'react';
import { NymNetworkExplorerThemeProvider } from '@nymproject/mui-theme';
import { useMainContext } from '../context/main';
export const NetworkExplorerThemeProvider: React.FC = ({ children }) => {
export const NetworkExplorerThemeProvider: FCWithChildren = ({ children }) => {
const { mode } = useMainContext();
return <NymNetworkExplorerThemeProvider mode={mode}>{children}</NymNetworkExplorerThemeProvider>;
};
+1
View File
@@ -0,0 +1 @@
declare type FCWithChildren<P = {}> = React.FC<React.PropsWithChildren<P>>;
+4 -4
View File
@@ -36,8 +36,8 @@
"clsx": "^1.1.1",
"luxon": "^2.3.0",
"pretty-bytes": "^6.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^3.1.3",
"react-hook-form": "^7.14.2",
"react-markdown": "^8.0.4",
@@ -62,8 +62,8 @@
"@types/jest": "^27.0.1",
"@types/luxon": "^2.3.2",
"@types/node": "^16.7.13",
"@types/react": "^17.0.34",
"@types/react-dom": "^17.0.9",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.10",
"@types/semver": "^7.3.8",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.13.0",
+1 -1
View File
@@ -8,7 +8,7 @@ import { ConnectedLayout } from './layouts/ConnectedLayout';
import { HelpGuideLayout } from './layouts/HelpGuideLayout';
import { useTauriEvents } from './utils';
export const App: React.FC = () => {
export const App: FCWithChildren = () => {
const context = useClientContext();
const [busy, setBusy] = React.useState<boolean>();
const [showInfoModal, setShowInfoModal] = React.useState(false);
@@ -3,7 +3,7 @@ import { Box } from '@mui/material';
import { CustomTitleBar } from './CustomTitleBar';
import { AppVersion } from './AppVersion';
export const AppWindowFrame: React.FC = ({ children }) => (
export const AppWindowFrame: FCWithChildren = ({ children }) => (
<Box
sx={{
display: 'grid',
@@ -51,7 +51,7 @@ const getStatusText = (status: ConnectionStatusKind, hover: boolean): string =>
}
};
export const ConnectionButton: React.FC<{
export const ConnectionButton: FCWithChildren<{
status: ConnectionStatusKind;
disabled?: boolean;
busy?: boolean;
@@ -10,7 +10,7 @@ export interface ConnectionStatsItem {
const FONT_SIZE = '14px';
export const ConnectionStats: React.FC<{
export const ConnectionStats: FCWithChildren<{
stats: ConnectionStatsItem[];
}> = ({ stats }) => (
<Box color="rgba(255,255,255,0.6)" width="100%" display="flex" justifyContent="space-between">
@@ -9,7 +9,7 @@ const FONT_SIZE = '10px';
const FONT_WEIGHT = '600';
const FONT_STYLE = 'normal';
const ConnectionStatusContent: React.FC<{
const ConnectionStatusContent: FCWithChildren<{
status: ConnectionStatusKind;
}> = ({ status }) => {
switch (status) {
@@ -56,7 +56,7 @@ const ConnectionStatusContent: React.FC<{
}
};
export const ConnectionStatus: React.FC<{
export const ConnectionStatus: FCWithChildren<{
status: ConnectionStatusKind;
connectedSince?: DateTime;
serviceProvider?: ServiceProvider;
@@ -8,7 +8,7 @@ import { useTestAndEarnContext } from './context/TestAndEarnContext';
import { NymShipyardTheme } from '../../theme';
import { ConnectionStatusKind } from '../../types';
export const Wrapper: React.FC<{ disabled: boolean }> = ({ disabled, children }) => {
export const Wrapper: FCWithChildren<{ disabled: boolean }> = ({ disabled, children }) => {
if (disabled) {
return (
<Badge badgeContent="!" color="warning">
@@ -21,7 +21,7 @@ export const Wrapper: React.FC<{ disabled: boolean }> = ({ disabled, children })
return <>{children}</>;
};
export const TestAndEarnButtonArea: React.FC = () => {
export const TestAndEarnButtonArea: FCWithChildren = () => {
const clientContext = useClientContext();
const context = useTestAndEarnContext();
const disabled = clientContext.connectionStatus !== ConnectionStatusKind.connected;
@@ -10,7 +10,7 @@ import { useTestAndEarnContext } from './context/TestAndEarnContext';
import { DrawEntryStatus, DrawWithWordOfTheDay } from './context/types';
import Content from './content/en.yaml';
export const TestAndEarnCurrentDrawFuture: React.FC<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => {
export const TestAndEarnCurrentDrawFuture: FCWithChildren<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => {
const startsUtc = React.useMemo(() => draw && DateTime.fromISO(draw.start_utc), [draw?.start_utc]);
const startsIn = React.useMemo(() => {
if (draw && startsUtc) {
@@ -34,7 +34,7 @@ export const TestAndEarnCurrentDrawFuture: React.FC<{ draw?: DrawWithWordOfTheDa
);
};
export const TestAndEarnCurrentDrawEnter: React.FC<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => {
export const TestAndEarnCurrentDrawEnter: FCWithChildren<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => {
const context = useTestAndEarnContext();
const [busy, setBusy] = React.useState(false);
const [error, setError] = React.useState<string>();
@@ -72,7 +72,7 @@ export const TestAndEarnCurrentDrawEnter: React.FC<{ draw?: DrawWithWordOfTheDay
);
};
export const TestAndEarnCurrentDrawEntered: React.FC<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => {
export const TestAndEarnCurrentDrawEntered: FCWithChildren<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => {
if (!draw || !draw.entry) {
return null;
}
@@ -131,7 +131,7 @@ export const TestAndEarnCurrentDrawEntered: React.FC<{ draw?: DrawWithWordOfTheD
);
};
export const TestAndEarnCurrentDraw: React.FC<{
export const TestAndEarnCurrentDraw: FCWithChildren<{
draw?: DrawWithWordOfTheDay;
sx?: SxProps;
}> = ({ draw, sx }) => {
@@ -171,7 +171,7 @@ export const TestAndEarnCurrentDraw: React.FC<{
return null;
};
export const TestAndEarnCurrentDrawWithState: React.FC<{
export const TestAndEarnCurrentDrawWithState: FCWithChildren<{
sx?: SxProps;
}> = ({ sx }) => {
const context = useTestAndEarnContext();
@@ -39,7 +39,7 @@ const statusToColor = (status: string): 'info' | 'success' | 'warning' | undefin
}
};
const StatusText: React.FC<{ entry: DrawEntry }> = ({ entry }) => {
const StatusText: FCWithChildren<{ entry: DrawEntry }> = ({ entry }) => {
const context = useTestAndEarnContext();
const [busy, setBusy] = React.useState(false);
const [error, setError] = React.useState<string>();
@@ -132,7 +132,7 @@ const StatusText: React.FC<{ entry: DrawEntry }> = ({ entry }) => {
}
};
export const TestAndEarnDraws: React.FC<{
export const TestAndEarnDraws: FCWithChildren<{
sx?: SxProps;
}> = ({ sx }) => {
const context = useTestAndEarnContext();
@@ -181,7 +181,7 @@ export const TestAndEarnDraws: React.FC<{
);
};
export const TestAndEarnDrawsWithState: React.FC<{
export const TestAndEarnDrawsWithState: FCWithChildren<{
sx?: SxProps;
}> = ({ sx }) => {
const context = useTestAndEarnContext();
@@ -5,7 +5,7 @@ import { Paper, Stack, Button, Box } from '@mui/material';
import ArrowCircleRightIcon from '@mui/icons-material/ArrowCircleRight';
import { useTestAndEarnContext } from './context/TestAndEarnContext';
export const TestAndEarnEnterWalletAddress: React.FC<{
export const TestAndEarnEnterWalletAddress: FCWithChildren<{
initialValue?: string;
placeholder?: string;
onSubmit?: () => Promise<void> | void;
@@ -1,7 +1,7 @@
import React from 'react';
import { Box, Button } from '@mui/material';
export const TestAndEarnError: React.FC<{ error?: string }> = ({ error = 'An error has occurred' }) => (
export const TestAndEarnError: FCWithChildren<{ error?: string }> = ({ error = 'An error has occurred' }) => (
<Box>
<Box mb={4} fontWeight="bold">
{error}
@@ -29,12 +29,12 @@ export default {
component: TestAndEarnPopupContent,
} as ComponentMeta<typeof TestAndEarnPopupContent>;
const MacOSWindow: React.FC<{ width?: string | number; height?: string | number; title?: string }> = ({
title,
width,
height,
children,
}) => (
const MacOSWindow: FCWithChildren<{
width?: string | number;
height?: string | number;
title?: string;
children: React.ReactNode;
}> = ({ title, width, height, children }) => (
<Box sx={{ border: '1px solid #EEEEEE', width, height }}>
<Box sx={{ background: '#EEEEEE', display: 'grid', gridTemplateColumns: 'auto auto', gridTemplateRows: 'auto' }}>
<Box ml={1}>
@@ -67,7 +67,7 @@ const MacOSWindow: React.FC<{ width?: string | number; height?: string | number;
</Box>
);
const Wrapper: React.FC<{ text: React.ReactNode }> = ({ text }) => (
const Wrapper: FCWithChildren<{ text: React.ReactNode }> = ({ text }) => (
<NymShipyardTheme>
<Alert severity="info" sx={{ mb: 4 }}>
{text}
@@ -15,7 +15,7 @@ enum Stages {
registered = 'registered',
}
export const TestAndEarnPopupContent: React.FC<{
export const TestAndEarnPopupContent: FCWithChildren<{
stage?: string;
connectionStatus?: ConnectionStatusKind;
error?: string;
@@ -72,7 +72,7 @@ export const TestAndEarnPopupContent: React.FC<{
}
};
export const TestAndEarnPopup: React.FC = () => {
export const TestAndEarnPopup: FCWithChildren = () => {
const clientContext = useClientContext();
const context = useTestAndEarnContext();
@@ -7,7 +7,7 @@ import { invoke } from '@tauri-apps/api';
import { useTestAndEarnContext } from './context/TestAndEarnContext';
import { ClientId, Registration } from './context/types';
export const TestAndEarnTakePart: React.FC<{
export const TestAndEarnTakePart: FCWithChildren<{
websiteLinkUrl: string;
websiteLinkText: string;
content: string;
@@ -8,7 +8,7 @@ import { DrawEntry, DrawEntryStatus } from './context/types';
import { TestAndEarnEnterWalletAddress } from './TestAndEarnEnterWalletAddress';
import Content from './content/en.yaml';
export const TestAndEarnWinner: React.FC<{
export const TestAndEarnWinner: FCWithChildren<{
sx?: SxProps;
entry?: DrawEntry;
}> = ({ sx, entry }) => {
@@ -100,7 +100,7 @@ export const TestAndEarnWinner: React.FC<{
);
};
export const TestAndEarnWinnerWithState: React.FC<{
export const TestAndEarnWinnerWithState: FCWithChildren<{
sx?: SxProps;
}> = ({ sx }) => {
const context = useTestAndEarnContext();
@@ -3,7 +3,7 @@ import { Box, Button, Card, CardContent, CardMedia, Typography } from '@mui/mate
import { SxProps } from '@mui/system';
import Content from './content/TestAndEarn/WinnerEntersWalletAddress.mdx';
export const TestAndEarnWinnerWalletAddress: React.FC<{
export const TestAndEarnWinnerWalletAddress: FCWithChildren<{
sx?: SxProps;
}> = ({ sx }) => (
<Box>
@@ -44,7 +44,7 @@ export const TestAndEarnContext = createContext(defaultValue);
const CLIENT_ID_KEY = 'tne_client_id';
const REGISTRATION_KEY = 'tne_registration';
export const TestAndEarnContextProvider = ({ children }: { children: React.ReactNode }) => {
export const TestAndEarnContextProvider: FCWithChildren = ({ children }) => {
const clientContext = useClientContext();
const [loadedOnce, setLoadedOnce] = useState(false);
const [loading, setLoading] = useState(true);
@@ -21,7 +21,7 @@ const mockValues_NotRegistered: TTestAndEarnContext = {
...methodDefaults,
};
export const MockTestAndEarnProvider_NotRegistered = ({ children }: { children: React.ReactNode }) => (
export const MockTestAndEarnProvider_NotRegistered: FCWithChildren = ({ children }) => (
<TestAndEarnContext.Provider value={mockValues_NotRegistered}>{children}</TestAndEarnContext.Provider>
);
@@ -43,7 +43,7 @@ const mockValues_Registered: TTestAndEarnContext = {
},
};
export const MockTestAndEarnProvider_Registered = ({ children }: { children: React.ReactNode }) => (
export const MockTestAndEarnProvider_Registered: FCWithChildren = ({ children }) => (
<TestAndEarnContext.Provider value={mockValues_Registered}>{children}</TestAndEarnContext.Provider>
);
@@ -137,7 +137,7 @@ const mockValues_RegisteredWithAllDrawsAndEntry: TTestAndEarnContext = {
},
};
export const MockTestAndEarnProvider_RegisteredWithAllDraws = ({ children }: { children: React.ReactNode }) => (
export const MockTestAndEarnProvider_RegisteredWithAllDraws: FCWithChildren = ({ children }) => (
<TestAndEarnContext.Provider value={mockValues_RegisteredWithAllDrawsAndEntry}>
{children}
</TestAndEarnContext.Provider>
@@ -150,7 +150,7 @@ const mockValues_RegisteredWithDrawsNoCurrent: TTestAndEarnContext = {
},
};
export const MockTestAndEarnProvider_RegisteredWithDrawsNoCurrent = ({ children }: { children: React.ReactNode }) => (
export const MockTestAndEarnProvider_RegisteredWithDrawsNoCurrent: FCWithChildren = ({ children }) => (
<TestAndEarnContext.Provider value={mockValues_RegisteredWithDrawsNoCurrent}>{children}</TestAndEarnContext.Provider>
);
@@ -162,7 +162,7 @@ const mockValues_RegisteredWithDraws: TTestAndEarnContext = {
},
};
export const MockTestAndEarnProvider_RegisteredWithDraws = ({ children }: { children: React.ReactNode }) => (
export const MockTestAndEarnProvider_RegisteredWithDraws: FCWithChildren = ({ children }) => (
<TestAndEarnContext.Provider value={mockValues_RegisteredWithDraws}>{children}</TestAndEarnContext.Provider>
);
@@ -177,7 +177,7 @@ const mockValues_RegisteredWithDrawsAndEntry: TTestAndEarnContext = {
},
};
export const MockTestAndEarnProvider_RegisteredWithDrawsAndEntry = ({ children }: { children: React.ReactNode }) => (
export const MockTestAndEarnProvider_RegisteredWithDrawsAndEntry: FCWithChildren = ({ children }) => (
<TestAndEarnContext.Provider value={mockValues_RegisteredWithDrawsAndEntry}>{children}</TestAndEarnContext.Provider>
);
@@ -257,6 +257,6 @@ const mockValues_RegisteredAndError: TTestAndEarnContext = {
error: 'Error message text will go here',
};
export const MockTestAndEarnProvider_RegisteredAndError = ({ children }: { children: React.ReactNode }) => (
export const MockTestAndEarnProvider_RegisteredAndError: FCWithChildren = ({ children }) => (
<TestAndEarnContext.Provider value={mockValues_RegisteredAndError}>{children}</TestAndEarnContext.Provider>
);
@@ -14,7 +14,7 @@ const IpAddressAndPortContainer = styled('div')({
},
});
export const IpAddressAndPort: React.FC<{
export const IpAddressAndPort: FCWithChildren<{
label: string;
ipAddress: string;
port: number;
+1 -1
View File
@@ -4,7 +4,7 @@ import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
const HELP_URL = 'https://docs.nymtech.net';
export const NeedHelp: React.FC = () => (
export const NeedHelp: FCWithChildren = () => (
<Box sx={{ display: 'grid', placeItems: 'center' }}>
<Button component="a" href={HELP_URL} target="_blank" sx={{ fontSize: '12px', fontWeight: '600' }} color="info">
<HelpOutlineIcon color="inherit" fontSize="inherit" fontWeight="inherit" />
@@ -2,7 +2,7 @@ import React from 'react';
import { Autocomplete, Box, Chip, Dialog, DialogProps, TextField, Typography } from '@mui/material';
import { ServiceProvider, Service, Services } from '../types/directory';
export const ServiceProviderPopup: React.FC<
export const ServiceProviderPopup: FCWithChildren<
DialogProps & { services: Services; onServiceProviderChanged: (sp?: ServiceProvider, s?: Service) => void }
> = ({ services, onServiceProviderChanged, ...dialogProps }) => {
const options = services.flatMap((s) =>
@@ -11,7 +11,7 @@ type ServiceWithRandomSp = {
const defaultServiceValue = { id: '', description: '', items: [] };
export const ServiceProviderSelector: React.FC<{
export const ServiceProviderSelector: FCWithChildren<{
onChange?: (serviceProvider?: ServiceProvider) => void;
services?: Services;
currentSp?: ServiceProvider;
@@ -14,7 +14,7 @@ import { Service, ServiceProvider, Services } from '../types/directory';
import { useTauriEvents } from '../utils';
import { ServiceProviderPopup } from './ServiceProviderPopup';
export const ServiceSelector: React.FC<{
export const ServiceSelector: FCWithChildren<{
onChange?: (serviceProvider?: ServiceProvider) => void;
services?: Services;
currentSp?: ServiceProvider;
+1 -1
View File
@@ -40,7 +40,7 @@ export type TClientContext = {
export const ClientContext = createContext({} as TClientContext);
export const ClientContextProvider = ({ children }: { children: React.ReactNode }) => {
export const ClientContextProvider: FCWithChildren = ({ children }) => {
const [mode, setMode] = useState<ModeType>('dark');
const [connectionStatus, setConnectionStatus] = useState<ConnectionStatusKind>(ConnectionStatusKind.disconnected);
const [connectionStats, setConnectionStats] = useState<ConnectionStatsItem[]>();
+1 -1
View File
@@ -20,7 +20,7 @@ const mockValues: TClientContext = {
startDisconnecting: async () => {},
};
export const MockProvider: React.FC<{
export const MockProvider: FCWithChildren<{
children?: React.ReactNode;
connectionStatus?: ConnectionStatusKind;
}> = ({ connectionStatus = ConnectionStatusKind.disconnected, children }) => (
+18 -16
View File
@@ -1,5 +1,5 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client';
import { ErrorBoundary } from 'react-error-boundary';
import { ClientContextProvider } from './context/main';
import { ErrorFallback } from './components/Error';
@@ -8,19 +8,21 @@ import { App } from './App';
import { AppWindowFrame } from './components/AppWindowFrame';
import { TestAndEarnContextProvider } from './components/Growth/context/TestAndEarnContext';
const root = document.getElementById('root');
const elem = document.getElementById('root');
ReactDOM.render(
<ErrorBoundary FallbackComponent={ErrorFallback}>
<ClientContextProvider>
<TestAndEarnContextProvider>
<NymMixnetTheme mode="dark">
<AppWindowFrame>
<App />
</AppWindowFrame>
</NymMixnetTheme>
</TestAndEarnContextProvider>
</ClientContextProvider>
</ErrorBoundary>,
root,
);
if (elem) {
const root = createRoot(elem);
root.render(
<ErrorBoundary FallbackComponent={ErrorFallback}>
<ClientContextProvider>
<TestAndEarnContextProvider>
<NymMixnetTheme mode="dark">
<AppWindowFrame>
<App />
</AppWindowFrame>
</NymMixnetTheme>
</TestAndEarnContextProvider>
</ClientContextProvider>
</ErrorBoundary>,
);
}
+1 -1
View File
@@ -11,7 +11,7 @@ import { IpAddressAndPort } from '../components/IpAddressAndPort';
import { ServiceProvider } from '../types/directory';
import { TestAndEarnButtonArea } from '../components/Growth/TestAndEarnButtonArea';
export const ConnectedLayout: React.FC<{
export const ConnectedLayout: FCWithChildren<{
status: ConnectionStatusKind;
stats: ConnectionStatsItem[];
ipAddress: string;
+1 -1
View File
@@ -12,7 +12,7 @@ import { Services } from '../types/directory';
import { TestAndEarnButtonArea } from '../components/Growth/TestAndEarnButtonArea';
import { AppVersion } from '../components/AppVersion';
export const DefaultLayout: React.FC<{
export const DefaultLayout: FCWithChildren<{
error?: Error;
status: ConnectionStatusKind;
services?: Services;
+2 -2
View File
@@ -7,7 +7,7 @@ import '../../../assets/fonts/non-variable/fonts.css';
/**
* Provides the theme for Nym Connect by reacting to the light/dark mode choice stored in the app context.
*/
export const NymMixnetTheme: React.FC<{ mode: 'light' | 'dark' }> = ({ children, mode }) => {
export const NymMixnetTheme: FCWithChildren<{ mode: 'light' | 'dark' }> = ({ children, mode }) => {
const theme = React.useMemo(() => createTheme(getDesignTokens(mode)), [mode]);
return (
<ThemeProvider theme={theme}>
@@ -17,7 +17,7 @@ export const NymMixnetTheme: React.FC<{ mode: 'light' | 'dark' }> = ({ children,
);
};
export const NymShipyardTheme: React.FC<{ mode?: 'light' | 'dark' }> = ({ children, mode = 'dark' }) => {
export const NymShipyardTheme: FCWithChildren<{ mode?: 'light' | 'dark' }> = ({ children, mode = 'dark' }) => {
const theme = React.useMemo(() => createTheme(getDesignTokens(mode, true)), [mode]);
return (
<ThemeProvider theme={theme}>
+1
View File
@@ -0,0 +1 @@
declare type FCWithChildren<P = {}> = React.FC<React.PropsWithChildren<P>>;
+4 -4
View File
@@ -42,8 +42,8 @@
"notistack": "^2.0.3",
"npm-run-all": "^4.1.5",
"qrcode.react": "^1.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^3.1.3",
"react-hook-form": "^7.14.2",
"react-router-dom": "6",
@@ -72,8 +72,8 @@
"@types/jest": "^27.0.1",
"@types/node": "^16.7.13",
"@types/qrcode.react": "^1.0.2",
"@types/react": "^17.0.34",
"@types/react-dom": "^17.0.9",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.10",
"@types/semver": "^7.3.8",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.13.0",
+6 -6
View File
@@ -2,12 +2,12 @@ import React, { useRef } from 'react';
import { MoreVertSharp } from '@mui/icons-material';
import { IconButton, ListItemIcon, ListItemText, Menu, MenuItem } from '@mui/material';
export const ActionsMenu: React.FC<{ open: boolean; onOpen: () => void; onClose: () => void }> = ({
children,
open,
onOpen,
onClose,
}) => {
export const ActionsMenu: FCWithChildren<{
open: boolean;
children: React.ReactNode;
onOpen: () => void;
onClose: () => void;
}> = ({ children, open, onOpen, onClose }) => {
const anchorEl: any = useRef<HTMLElement>();
return (
@@ -2,7 +2,7 @@ import React from 'react';
import { Stack, Typography } from '@mui/material';
import { SimpleModal } from 'src/components/Modals/SimpleModal';
export const BondOversaturatedModal: React.FC<{
export const BondOversaturatedModal: FCWithChildren<{
open: boolean;
saturationPercentage: string;
onClose?: () => void;
+5 -11
View File
@@ -4,20 +4,14 @@ import { AppContext } from '../context/main';
import { CopyToClipboard } from './CopyToClipboard';
import { splice } from '../utils';
const AddressTooltip: FC<{ visible?: boolean; address?: string; children: React.ReactElement<any, any> }> = ({
visible,
address,
children,
}) => {
if (!visible) {
return children;
}
if (!address) {
return children;
const AddressTooltip: FCWithChildren<{ visible?: boolean; address?: string }> = ({ visible, address, children }) => {
if (!visible || !address) {
return <>{children}</>;
}
return (
<Tooltip title={address} arrow>
{children}
<>{children}</>
</Tooltip>
);
};
+2 -1
View File
@@ -15,7 +15,7 @@ const storybookStyles = (theme: Theme, isStorybook?: boolean, backdropProps?: ob
}
: {};
export const ConfirmTx: React.FC<{
export const ConfirmTx: FCWithChildren<{
open: boolean;
header: string;
subheader?: string;
@@ -24,6 +24,7 @@ export const ConfirmTx: React.FC<{
onClose?: () => void;
onPrev: () => void;
isStorybook?: boolean;
children?: React.ReactNode;
}> = ({ open, fee, onConfirm, onClose, header, subheader, onPrev, children, isStorybook }) => {
const theme = useTheme();
return (
@@ -2,7 +2,7 @@ import React from 'react';
import { SxProps } from '@mui/material';
import { SimpleModal } from '../Modals/SimpleModal';
export const OverSaturatedBlockerModal: React.FC<{
export const OverSaturatedBlockerModal: FCWithChildren<{
open: boolean;
onClose?: () => void;
header?: string;
@@ -18,7 +18,7 @@ import { ErrorModal } from '../Modals/ErrorModal';
const MIN_AMOUNT_TO_DELEGATE = 10;
export const DelegateModal: React.FC<{
export const DelegateModal: FCWithChildren<{
open: boolean;
onClose: () => void;
onOk?: (
@@ -10,7 +10,7 @@ export type DelegationListItemActions = 'delegate' | 'undelegate' | 'redeem' | '
const BUTTON_SIZE = '32px';
const MIN_WIDTH = '150px';
export const DelegationActions: React.FC<{
export const DelegationActions: FCWithChildren<{
onActionClick?: (action: DelegationListItemActions) => void;
isPending?: DelegateListItemPending;
disableRedeemingRewards?: boolean;
@@ -64,7 +64,7 @@ export const DelegationActions: React.FC<{
);
};
export const DelegationsActionsMenu: React.FC<{
export const DelegationsActionsMenu: FCWithChildren<{
onActionClick?: (action: DelegationListItemActions) => void;
disableRedeemingRewards?: boolean;
disableDelegateMore?: boolean | null;
@@ -45,7 +45,7 @@ const headCells: HeadCell[] = [
{ id: 'unclaimed_rewards', label: 'Reward', sortable: true, align: 'left' },
];
const EnhancedTableHead: React.FC<EnhancedTableProps> = ({ order, orderBy, onRequestSort }) => {
const EnhancedTableHead: FCWithChildren<EnhancedTableProps> = ({ order, orderBy, onRequestSort }) => {
const createSortHandler = (property: string) => (event: React.MouseEvent<unknown>) => {
onRequestSort(event, property);
};
@@ -87,7 +87,7 @@ const sortByUnbondedMixnodeFirst = (a: DelegationWithEvent) => {
return 1;
};
export const DelegationList: React.FC<{
export const DelegationList: FCWithChildren<{
isLoading?: boolean;
items: TDelegations;
onItemActionClick?: (item: DelegationWithEverything, action: DelegationListItemActions) => void;
@@ -30,7 +30,7 @@ const transactionForDarkTheme = {
hash: '11ED7B9E21534A9421834F52FED5103DC6E982949C06335F5E12EFC71DAF0CF0',
};
const Content: React.FC<{ children: React.ReactElement<any, any>; handleClick: () => void }> = ({
const Content: FCWithChildren<{ children: React.ReactElement<any, any>; handleClick: () => void }> = ({
children,
handleClick,
}) => (
@@ -36,12 +36,13 @@ export type DelegationModalProps = {
}[];
};
export const DelegationModal: React.FC<
export const DelegationModal: FCWithChildren<
DelegationModalProps & {
open: boolean;
onClose: () => void;
sx?: SxProps;
backdropProps?: object;
children?: React.ReactNode;
}
> = ({ status, action, message, transactions, open, onClose, children, sx, backdropProps }) => {
if (status === 'loading') return <LoadingModal sx={sx} backdropProps={backdropProps} />;
@@ -5,7 +5,7 @@ import { Link } from '@nymproject/react/link/Link';
import { DelegationList } from './DelegationList';
import { DelegationListItemActions } from './DelegationActions';
export const Delegations: React.FC<{
export const Delegations: FCWithChildren<{
isLoading?: boolean;
items: DelegationWithEverything[];
explorerUrl: string;
@@ -15,7 +15,7 @@ export default {
title: 'Delegation/Components/Action Modals',
};
const Background: React.FC<{ onOpen: () => void }> = ({ onOpen }) => {
const Background: FCWithChildren<{ onOpen: () => void }> = ({ onOpen }) => {
const theme = useTheme();
return (
<Paper elevation={0} sx={{ px: 4, pt: 2, pb: 4 }}>
@@ -8,7 +8,7 @@ import { ModalFee } from '../Modals/ModalFee';
import { ModalListItem } from '../Modals/ModalListItem';
import { SimpleModal } from '../Modals/SimpleModal';
export const UndelegateModal: React.FC<{
export const UndelegateModal: FCWithChildren<{
open: boolean;
onClose?: () => void;
onOk?: (mixId: number, identityKey: string, usesVestingContractTokens: boolean, fee?: FeeDetails) => void;
@@ -2,13 +2,14 @@ import React from 'react';
import { Box, Button, Modal, SxProps, Typography } from '@mui/material';
import { modalStyle } from './styles';
export const ErrorModal: React.FC<{
export const ErrorModal: FCWithChildren<{
open: boolean;
title?: string;
message?: string;
sx?: SxProps;
backdropProps?: object;
onClose: () => void;
children?: React.ReactNode;
}> = ({ children, open, title, message, sx, backdropProps, onClose }) => (
<Modal open={open} onClose={onClose} BackdropProps={backdropProps}>
<Box
@@ -13,7 +13,7 @@ const modalStyle: SxProps = {
p: 4,
};
export const LoadingModal: React.FC<{
export const LoadingModal: FCWithChildren<{
sx?: SxProps;
backdropProps?: object;
}> = ({ sx, backdropProps }) => (
@@ -1,6 +1,6 @@
import React from 'react';
import { Box, SxProps } from '@mui/material';
export const ModalDivider: React.FC<{
export const ModalDivider: FCWithChildren<{
sx?: SxProps;
}> = ({ sx }) => <Box borderTop="1px solid" borderColor="rgba(141, 147, 153, 0.2)" my={1} sx={sx} />;
@@ -2,7 +2,7 @@ import React from 'react';
import { Box, Stack, Typography, TypographyProps } from '@mui/material';
import { ModalDivider } from './ModalDivider';
export const ModalListItem: React.FC<{
export const ModalListItem: FCWithChildren<{
label: string;
divider?: boolean;
hidden?: boolean;
@@ -16,7 +16,7 @@ export default {
component: SimpleModal,
} as ComponentMeta<typeof SimpleModal>;
const BasePage: React.FC<{ children: React.ReactElement<any, any>; handleClick: () => void }> = ({
const BasePage: FCWithChildren<{ children: React.ReactElement<any, any>; handleClick: () => void }> = ({
children,
handleClick,
}) => (

Some files were not shown because too many files have changed in this diff Show More