Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use PropsWithChildren instead of defining children extra #677

Merged
merged 1 commit into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { TFunction } from "i18next";
import { Component, ErrorInfo, ReactNode } from "react";
import { Component, ErrorInfo, PropsWithChildren } from "react";
import { withTranslation } from "react-i18next";

interface Props {
t: TFunction<[string, string], undefined>;
children: ReactNode;
}

interface State {
Expand All @@ -13,7 +12,7 @@ interface State {
errorInfo?: ErrorInfo;
}

class ErrorBoundary extends Component<Props, State> {
class ErrorBoundary extends Component<PropsWithChildren<Props>, State> {
public state: State = {
hasError: false,
};
Expand Down
4 changes: 2 additions & 2 deletions src/components/ButtonWithSpinner/ButtonWithSpinner.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { ButtonHTMLAttributes, FC } from "react";
import type { ButtonHTMLAttributes, FC, ReactElement } from "react";
import ButtonSpinner from "./ButtonSpinner/ButtonSpinner";

type Props = {
className?: string;
loading?: boolean;
icon?: React.ReactElement;
icon?: ReactElement;
} & ButtonHTMLAttributes<unknown>;

const ButtonWithSpinner: FC<Props> = ({
Expand Down
10 changes: 3 additions & 7 deletions src/components/RequireAuth.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { FC, useContext } from "react";
import { Navigate, useLocation } from "react-router-dom";
import { AppContext } from "@/context/app-context";

type Props = {
children: JSX.Element;
};
import { FC, PropsWithChildren, useContext } from "react";
import { Navigate, useLocation } from "react-router-dom";

//see https://reactrouter.com/docs/en/v6/examples/auth
const RequireAuth: FC<Props> = ({ children }) => {
const RequireAuth: FC<PropsWithChildren> = ({ children }) => {
let { isLoggedIn } = useContext(AppContext);
let location = useLocation();

Expand Down
8 changes: 5 additions & 3 deletions src/components/RequireSetup.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { FC } from "react";
import { FC, PropsWithChildren } from "react";
import { Navigate } from "react-router-dom";

type Props = {
needsSetup: boolean;
children: JSX.Element;
};

//see https://reactrouter.com/docs/en/v6/examples/auth
const RequireSetup: FC<Props> = ({ needsSetup, children }) => {
const RequireSetup: FC<PropsWithChildren<Props>> = ({
needsSetup,
children,
}) => {
if (!needsSetup) {
return <Navigate to={"/home"} replace />;
}
Expand Down
28 changes: 12 additions & 16 deletions src/context/app-context.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import type { FC } from "react";
import {
createContext,
ACCESS_TOKEN,
disableGutter,
parseJwt,
retrieveSettings,
saveSettings,
setWindowAlias,
} from "@/utils";
import type { FC, PropsWithChildren } from "react";
import {
Dispatch,
SetStateAction,
createContext,
useCallback,
useContext,
useEffect,
useState,
} from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import {
ACCESS_TOKEN,
disableGutter,
parseJwt,
retrieveSettings,
saveSettings,
setWindowAlias,
} from "@/utils";
import { SSEContext } from "./sse-context";
import { toast } from "react-toastify";
import { SSEContext } from "./sse-context";

export interface AppContextType {
isLoggedIn: boolean;
Expand Down Expand Up @@ -56,11 +56,7 @@ export const appContextDefault: AppContextType = {

export const AppContext = createContext<AppContextType>(appContextDefault);

type Props = {
children?: React.ReactNode;
};

const AppContextProvider: FC<Props> = ({ children }) => {
const AppContextProvider: FC<PropsWithChildren> = ({ children }) => {
const { i18n } = useTranslation();
const { evtSource, setEvtSource } = useContext(SSEContext);

Expand Down
10 changes: 3 additions & 7 deletions src/context/sse-context.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type { FC } from "react";
import { createContext, Dispatch, SetStateAction, useState } from "react";
import { AppStatus } from "@/models/app-status";
import { App } from "@/models/app.model";
import { BtcInfo } from "@/models/btc-info";
Expand All @@ -9,6 +7,8 @@ import { SystemInfo } from "@/models/system-info";
import { SystemStartupInfo } from "@/models/system-startup-info";
import { Transaction } from "@/models/transaction.model";
import { WalletBalance } from "@/models/wallet-balance";
import type { FC, PropsWithChildren } from "react";
import { Dispatch, SetStateAction, createContext, useState } from "react";

export interface SSEContextType {
evtSource: EventSource | null;
Expand Down Expand Up @@ -65,11 +65,7 @@ export const SSEContext = createContext<SSEContextType>(sseContextDefault);

export const SSE_URL = "/api/sse/subscribe";

type Props = {
children?: React.ReactNode;
};

const SSEContextProvider: FC<Props> = (props) => {
const SSEContextProvider: FC<PropsWithChildren> = (props) => {
const [evtSource, setEvtSource] = useState<EventSource | null>(null);
const [systemInfo, setSystemInfo] = useState<SystemInfo>({
alias: "",
Expand Down
14 changes: 7 additions & 7 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React from "react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import { ToastContainer } from "react-toastify";
import "react-tooltip/dist/react-tooltip.css";
import App from "./App";
import "./i18n/config";
import "./index.css";
import AppContextProvider from "./context/app-context";
import SSEContextProvider from "./context/sse-context";
import "react-tooltip/dist/react-tooltip.css";
import "./i18n/config";
import "./index.css";

import "i18next";
import ErrorBoundary from "@/ErrorBoundary";
import "i18next";

declare module "i18next" {
interface CustomTypeOptions {
Expand All @@ -21,7 +21,7 @@ declare module "i18next" {
const container = document.getElementById("root") as HTMLElement;
const root = createRoot(container);
root.render(
<React.StrictMode>
<StrictMode>
<ErrorBoundary>
<BrowserRouter>
<SSEContextProvider>
Expand All @@ -33,5 +33,5 @@ root.render(
</SSEContextProvider>
</BrowserRouter>
</ErrorBoundary>
</React.StrictMode>,
</StrictMode>,
);
8 changes: 2 additions & 6 deletions src/layouts/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import useSSE from "@/hooks/use-sse";
import type { FC } from "react";
import type { FC, PropsWithChildren } from "react";
import BottomNav from "./BottomNav";
import Header from "./Header";
import SideDrawer from "./SideDrawer";

type Props = {
children?: React.ReactNode;
};

const Layout: FC<Props> = ({ children }) => {
const Layout: FC<PropsWithChildren> = ({ children }) => {
// use SSE for all components after login
useSSE();
return (
Expand Down
8 changes: 2 additions & 6 deletions src/layouts/ModalBackground.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import type { FC } from "react";
import type { FC, PropsWithChildren } from "react";

type Props = {
children?: React.ReactNode;
};

const ModalBackground: FC<Props> = ({ children }) => (
const ModalBackground: FC<PropsWithChildren> = ({ children }) => (
<div className="fixed left-0 top-0 z-50 flex h-full w-full items-center justify-center bg-gray-600 bg-opacity-70">
{children}
</div>
Expand Down
9 changes: 6 additions & 3 deletions src/layouts/ModalDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { XMarkIcon } from "@heroicons/react/24/outline";
import { FC, useCallback, useEffect } from "react";
import { FC, PropsWithChildren, useCallback, useEffect } from "react";
import ModalBackground from "./ModalBackground";

export const disableScroll = {
Expand All @@ -8,12 +8,15 @@ export const disableScroll = {
};

type Props = {
children?: React.ReactNode;
closeable?: boolean;
close: () => void;
};

const ModalDialog: FC<Props> = ({ closeable = true, close, children }) => {
const ModalDialog: FC<PropsWithChildren<Props>> = ({
closeable = true,
close,
children,
}) => {
const closeModal = useCallback(() => {
close();
disableScroll.off();
Expand Down
10 changes: 3 additions & 7 deletions src/layouts/SetupContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { FC, useContext } from "react";
import { MoonIcon } from "@heroicons/react/24/outline";
import I18nDropdown from "@/components/I18nDropdown";
import { AppContext } from "@/context/app-context";
import { MoonIcon } from "@heroicons/react/24/outline";
import { FC, PropsWithChildren, useContext } from "react";

type Props = {
children?: React.ReactNode;
};

const SetupContainer: FC<Props> = ({ children }) => {
const SetupContainer: FC<PropsWithChildren> = ({ children }) => {
const { toggleDarkMode } = useContext(AppContext);
return (
<main className="flex h-screen w-screen flex-col items-center justify-center bg-gray-100 transition-colors dark:bg-gray-700">
Expand Down
5 changes: 2 additions & 3 deletions src/pages/Settings/ActionBox.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import type { FC, ReactElement, ReactNode } from "react";
import type { FC, PropsWithChildren, ReactElement } from "react";

export type Props = {
name: string | ReactElement;
actionName: string;
action: () => void;
showChild: boolean;
children: ReactNode;
};

/**
* displays a box with a title and a button which triggers an action (e.g. reboot)
* has a child component which is displayed if showChild is true
*/
const ActionBox: FC<Props> = ({
const ActionBox: FC<PropsWithChildren<Props>> = ({
name,
action,
actionName,
Expand Down
5 changes: 2 additions & 3 deletions src/pages/Setup/SelectOption.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { FC } from "react";
import { FC, PropsWithChildren } from "react";

type Props = {
id: string;
radioGroup: string;
value: string;
selected: string | null;
children?: React.ReactNode;
// Can be LightningDialog or SetupPhase
// TODO: Move both to something better than enums
onSelectOption: (value: any) => void;
};

const SelectOption: FC<Props> = ({
const SelectOption: FC<PropsWithChildren<Props>> = ({
children,
id,
radioGroup,
Expand Down
17 changes: 11 additions & 6 deletions src/utils/test-utils.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { render, RenderOptions } from "@testing-library/react";
import {
AppContext,
appContextDefault,
Expand All @@ -9,16 +8,22 @@ import {
sseContextDefault,
SSEContextType,
} from "@/context/sse-context";
import React, { FC, ReactElement } from "react";
import i18n from "@/i18n/test_config";
import { render, RenderOptions } from "@testing-library/react";
import { FC, PropsWithChildren, ReactElement } from "react";
import { I18nextProvider } from "react-i18next";
import { BrowserRouter } from "react-router-dom";
import i18n from "@/i18n/test_config";

const AllTheProviders: FC<{
children: React.ReactNode;
type Props = {
sseProps: SSEContextType;
appProps: AppContextType;
}> = ({ children, appProps, sseProps }) => {
};

const AllTheProviders: FC<PropsWithChildren<Props>> = ({
children,
appProps,
sseProps,
}) => {
return (
<BrowserRouter>
<SSEContext.Provider
Expand Down
Loading