feat(web): replace react-portal with own implementation (#1862)

* feat(web): replace react-portal with own implementation

* chore: add missing license headers
This commit is contained in:
ze0s 2024-12-07 18:05:56 +01:00 committed by GitHub
parent ab718b8232
commit 172fa651af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 113 additions and 99 deletions

View file

@ -5,54 +5,55 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#18181B">
<meta name="description" content="autobrr" />
<link rel="preload" href="/Inter-Variable.woff2" as="font" type="font/woff2" crossorigin="use-credentials">
<link rel="apple-touch-icon" href="/logo192.png" />
<link rel="apple-touch-icon" href="/apple-touch-icon-iphone-60x60.png" />
<link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-ipad-76x76.png" />
<link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-iphone-retina-120x120.png" />
<link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-ipad-retina-152x152.png" />
<title>autobrr</title>
<base href="{{.BaseUrl}}">
<style>
@font-face {
font-family: "Inter Var";
font-style: normal;
font-weight: 100 900;
font-display: block;
font-feature-settings: "calt" 0;
src:
local("Inter Var"), local("Inter Variable"),
local("Inter var"), local("Inter variable"),
local("InterVar"), local("InterVariable"),
local("Inter"),
url("/Inter-Variable.woff2") format("woff2");
}
:root {
font-family: "Inter Var", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</style>
<script>
<head>
<meta charset="utf-8"/>
<link rel="icon" href="/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="theme-color" content="#18181B">
<meta name="description" content="autobrr"/>
<link rel="preload" href="/Inter-Variable.woff2" as="font" type="font/woff2" crossorigin="use-credentials">
<link rel="apple-touch-icon" href="/logo192.png"/>
<link rel="apple-touch-icon" href="/apple-touch-icon-iphone-60x60.png"/>
<link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-ipad-76x76.png"/>
<link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-iphone-retina-120x120.png"/>
<link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-ipad-retina-152x152.png"/>
<title>autobrr</title>
<base href="{{.BaseUrl}}">
<style>
@font-face {
font-family: "Inter Var";
font-style: normal;
font-weight: 100 900;
font-display: block;
font-feature-settings: "calt" 0;
src: local("Inter Var"), local("Inter Variable"),
local("Inter var"), local("Inter variable"),
local("InterVar"), local("InterVariable"),
local("Inter"),
url("/Inter-Variable.woff2") format("woff2");
}
:root {
font-family: "Inter Var", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</style>
<script>
window.APP = {};
window.APP.baseUrl = "{{.BaseUrl}}";
const browserPrefers = !(window.matchMedia !== undefined && window.matchMedia("(prefers-color-scheme: light)").matches);
const { darkTheme = browserPrefers } = JSON.parse(localStorage.getItem("settings")) || {};
const {darkTheme = browserPrefers} = JSON.parse(localStorage.getItem("settings")) || {};
document.documentElement.classList.toggle("dark", darkTheme);
</script>
</head>
<body class="bg-color">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root" class="pattern h-screen"></div>
<script type="module" src="./src/index.tsx"></script>
</body>
</script>
</head>
<body class="bg-color">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root" class="pattern h-screen"></div>
<div id="portal-root"></div>
<script type="module" src="./src/index.tsx"></script>
</body>
</html>

View file

@ -44,7 +44,6 @@
"@types/node": "^22.10.0",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react-portal": "^4.0.7",
"@types/react-table": "^7.7.20",
"@typescript-eslint/eslint-plugin": "^8.16.0",
"@typescript-eslint/parser": "^8.16.0",
@ -62,7 +61,6 @@
"react-hot-toast": "^2.4.1",
"react-multi-select-component": "^4.3.4",
"react-popper-tooltip": "^4.4.2",
"react-portal": "^4.2.2",
"react-ridge-state": "4.2.9",
"react-select": "^5.8.3",
"react-table": "^7.8.0",
@ -81,7 +79,6 @@
"@types/node": "^22.10.0",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react-portal": "^4.0.7",
"@types/react-table": "^7.7.20",
"@typescript-eslint/eslint-plugin": "^8.16.0",
"@typescript-eslint/parser": "^8.16.0",

85
web/pnpm-lock.yaml generated
View file

@ -46,9 +46,6 @@ importers:
'@types/react-dom':
specifier: ^18.3.1
version: 18.3.1
'@types/react-portal':
specifier: ^4.0.7
version: 4.0.7
'@types/react-table':
specifier: ^7.7.20
version: 7.7.20
@ -100,9 +97,6 @@ importers:
react-popper-tooltip:
specifier: ^4.4.2
version: 4.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-portal:
specifier: ^4.2.2
version: 4.2.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-ridge-state:
specifier: 4.2.9
version: 4.2.9(react@18.3.1)
@ -175,7 +169,7 @@ importers:
version: 0.21.0(vite@6.0.0(@types/node@22.10.0)(jiti@1.21.6)(terser@5.36.0)(yaml@2.6.1))(workbox-build@7.0.0)(workbox-window@7.3.0)
vite-plugin-svgr:
specifier: ^4.3.0
version: 4.3.0(@rollup/wasm-node@4.27.4)(typescript@5.7.2)(vite@6.0.0(@types/node@22.10.0)(jiti@1.21.6)(terser@5.36.0)(yaml@2.6.1))
version: 4.3.0(@rollup/wasm-node@4.28.1)(typescript@5.7.2)(vite@6.0.0(@types/node@22.10.0)(jiti@1.21.6)(terser@5.36.0)(yaml@2.6.1))
packages:
@ -1091,6 +1085,11 @@ packages:
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
'@rollup/wasm-node@4.28.1':
resolution: {integrity: sha512-t4ckEC09V3wbe0r6T4fGjq85lEbvGcGxn7QYYgjHyKNzZaQU5kFqr4FsavXYHRiVNYq8m+dRhdGjpfcC9UzzPg==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
'@rtsao/scc@1.1.0':
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
@ -1345,9 +1344,6 @@ packages:
'@types/react-dom@18.3.1':
resolution: {integrity: sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==}
'@types/react-portal@4.0.7':
resolution: {integrity: sha512-3zQJL6Pqcq7d73+cakVkZDqAYGFBo37XXPfahjhdScr9EdYPlf9evYilL38Fpzs1YGWz7F2SkPtN6+ygTO7ymg==}
'@types/react-table@7.7.20':
resolution: {integrity: sha512-ahMp4pmjVlnExxNwxyaDrFgmKxSbPwU23sGQw2gJK4EhCvnvmib2s/O/+y1dfV57dXOwpr2plfyBol+vEHbi2w==}
@ -2827,12 +2823,6 @@ packages:
react: ^18.3.1
react-dom: ^16.8.0 || ^17 || ^18
react-portal@4.2.2:
resolution: {integrity: sha512-vS18idTmevQxyQpnde0Td6ZcUlv+pD8GTyR42n3CHUQq9OHi1C4jDE4ZWEbEsrbrLRhSECYiao58cvocwMtP7Q==}
peerDependencies:
react: ^18.3.1
react-dom: ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0
react-ridge-state@4.2.9:
resolution: {integrity: sha512-1u2a5l5wl0H//hR1R69ZFbvD9mnvOXK3rit859vy15THQv/M+t7U5VF27Ufzcxb8kbKMwZ1Ni/J5f2chrrTHCQ==}
peerDependencies:
@ -3412,7 +3402,6 @@ packages:
workbox-google-analytics@7.0.0:
resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==}
deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained
workbox-navigation-preload@7.0.0:
resolution: {integrity: sha512-juWCSrxo/fiMz3RsvDspeSLGmbgC0U9tKqcUPZBCf35s64wlaLXyn2KdHHXVQrb2cqF7I0Hc9siQalainmnXJA==}
@ -4493,45 +4482,45 @@ snapshots:
dependencies:
react: 18.3.1
'@rollup/plugin-babel@5.3.1(@babel/core@7.26.0)(@rollup/wasm-node@4.27.4)':
'@rollup/plugin-babel@5.3.1(@babel/core@7.26.0)(@rollup/wasm-node@4.28.1)':
dependencies:
'@babel/core': 7.26.0
'@babel/helper-module-imports': 7.25.9
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.27.4)
rollup: '@rollup/wasm-node@4.27.4'
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.28.1)
rollup: '@rollup/wasm-node@4.28.1'
transitivePeerDependencies:
- supports-color
'@rollup/plugin-node-resolve@11.2.1(@rollup/wasm-node@4.27.4)':
'@rollup/plugin-node-resolve@11.2.1(@rollup/wasm-node@4.28.1)':
dependencies:
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.27.4)
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.28.1)
'@types/resolve': 1.17.1
builtin-modules: 3.3.0
deepmerge: 4.3.1
is-module: 1.0.0
resolve: 1.22.8
rollup: '@rollup/wasm-node@4.27.4'
rollup: '@rollup/wasm-node@4.28.1'
'@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.27.4)':
'@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.28.1)':
dependencies:
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.27.4)
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.28.1)
magic-string: 0.25.9
rollup: '@rollup/wasm-node@4.27.4'
rollup: '@rollup/wasm-node@4.28.1'
'@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.27.4)':
'@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.28.1)':
dependencies:
'@types/estree': 0.0.39
estree-walker: 1.0.1
picomatch: 2.3.1
rollup: '@rollup/wasm-node@4.27.4'
rollup: '@rollup/wasm-node@4.28.1'
'@rollup/pluginutils@5.1.3(@rollup/wasm-node@4.27.4)':
'@rollup/pluginutils@5.1.3(@rollup/wasm-node@4.28.1)':
dependencies:
'@types/estree': 1.0.6
estree-walker: 2.0.2
picomatch: 4.0.2
optionalDependencies:
rollup: '@rollup/wasm-node@4.27.4'
rollup: '@rollup/wasm-node@4.28.1'
'@rollup/wasm-node@4.27.4':
dependencies:
@ -4539,6 +4528,12 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
'@rollup/wasm-node@4.28.1':
dependencies:
'@types/estree': 1.0.6
optionalDependencies:
fsevents: 2.3.3
'@rtsao/scc@1.1.0': {}
'@surma/rollup-plugin-off-main-thread@2.2.3':
@ -4769,10 +4764,6 @@ snapshots:
dependencies:
'@types/react': 18.3.12
'@types/react-portal@4.0.7':
dependencies:
'@types/react': 18.3.12
'@types/react-table@7.7.20':
dependencies:
'@types/react': 18.3.12
@ -6394,12 +6385,6 @@ snapshots:
react-fast-compare: 3.2.2
warning: 4.0.3
react-portal@4.2.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
prop-types: 15.8.1
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
react-ridge-state@4.2.9(react@18.3.1):
dependencies:
react: 18.3.1
@ -6523,11 +6508,11 @@ snapshots:
dependencies:
glob: 7.2.3
rollup-plugin-terser@7.0.2(@rollup/wasm-node@4.27.4):
rollup-plugin-terser@7.0.2(@rollup/wasm-node@4.28.1):
dependencies:
'@babel/code-frame': 7.26.2
jest-worker: 26.6.2
rollup: '@rollup/wasm-node@4.27.4'
rollup: '@rollup/wasm-node@4.28.1'
serialize-javascript: 4.0.0
terser: 5.36.0
@ -6956,9 +6941,9 @@ snapshots:
transitivePeerDependencies:
- supports-color
vite-plugin-svgr@4.3.0(@rollup/wasm-node@4.27.4)(typescript@5.7.2)(vite@6.0.0(@types/node@22.10.0)(jiti@1.21.6)(terser@5.36.0)(yaml@2.6.1)):
vite-plugin-svgr@4.3.0(@rollup/wasm-node@4.28.1)(typescript@5.7.2)(vite@6.0.0(@types/node@22.10.0)(jiti@1.21.6)(terser@5.36.0)(yaml@2.6.1)):
dependencies:
'@rollup/pluginutils': 5.1.3(@rollup/wasm-node@4.27.4)
'@rollup/pluginutils': 5.1.3(@rollup/wasm-node@4.28.1)
'@svgr/core': 8.1.0(typescript@5.7.2)
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.7.2))
vite: 6.0.0(@types/node@22.10.0)(jiti@1.21.6)(terser@5.36.0)(yaml@2.6.1)
@ -6971,7 +6956,7 @@ snapshots:
dependencies:
esbuild: 0.24.0
postcss: 8.4.49
rollup: '@rollup/wasm-node@4.27.4'
rollup: '@rollup/wasm-node@4.28.1'
optionalDependencies:
'@types/node': 22.10.0
fsevents: 2.3.3
@ -7051,9 +7036,9 @@ snapshots:
'@babel/core': 7.26.0
'@babel/preset-env': 7.26.0(@babel/core@7.26.0)
'@babel/runtime': 7.26.0
'@rollup/plugin-babel': 5.3.1(@babel/core@7.26.0)(@rollup/wasm-node@4.27.4)
'@rollup/plugin-node-resolve': 11.2.1(@rollup/wasm-node@4.27.4)
'@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.27.4)
'@rollup/plugin-babel': 5.3.1(@babel/core@7.26.0)(@rollup/wasm-node@4.28.1)
'@rollup/plugin-node-resolve': 11.2.1(@rollup/wasm-node@4.28.1)
'@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.28.1)
'@surma/rollup-plugin-off-main-thread': 2.2.3
ajv: 8.17.1
common-tags: 1.8.2
@ -7062,8 +7047,8 @@ snapshots:
glob: 7.2.3
lodash: 4.17.21
pretty-bytes: 5.6.0
rollup: '@rollup/wasm-node@4.27.4'
rollup-plugin-terser: 7.0.2(@rollup/wasm-node@4.27.4)
rollup: '@rollup/wasm-node@4.28.1'
rollup-plugin-terser: 7.0.2(@rollup/wasm-node@4.28.1)
source-map: 0.8.0-beta.0
stringify-object: 3.3.0
strip-comments: 2.0.1

View file

@ -7,11 +7,11 @@ import { useEffect } from "react";
import { RouterProvider } from "@tanstack/react-router"
import { QueryClientProvider } from "@tanstack/react-query";
import { Toaster } from "react-hot-toast";
import { Portal } from "react-portal";
import { Router } from "@app/routes";
import { routerBasePath } from "@utils";
import { queryClient } from "@api/QueryClient";
import { SettingsContext } from "@utils/Context";
import { Portal } from "@components/portal";
declare module '@tanstack/react-router' {
interface Register {

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2021 - 2024, Ludvig Lundgren and the autobrr contributors.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
import { useEffect, ReactNode } from "react";
import { createPortal } from "react-dom";
interface PortalProps {
children?: ReactNode;
}
export const Portal = ({children }: PortalProps) => {
const mount = document.getElementById("portal-root");
const el = document.createElement("div");
useEffect(() => {
mount?.appendChild(el);
return () => {
mount?.removeChild(el);
}
}, [el, mount]);
return createPortal(children, el)
};

View file

@ -0,0 +1,6 @@
/*
* Copyright (c) 2021 - 2024, Ludvig Lundgren and the autobrr contributors.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
export { Portal } from "./Portal"