diff options
| author | Larvan2 <[email protected]> | 2026-06-21 12:50:01 +0800 |
|---|---|---|
| committer | Larvan2 <[email protected]> | 2026-06-21 12:50:01 +0800 |
| commit | 2de67ed7e2ca5bbf8c59dcad5a5e4c0d69462e86 (patch) | |
| tree | 468a81061a53ffb01d3e90be870776b973a3cc6f | |
| parent | 5ed61163bf6f621a16fe109119ebf4f261c26830 (diff) | |
refactor: replace unmaintained @reach/tooltip with Radix UI
- add a shared Tooltip wrapper around @radix-ui/react-tooltip that keeps
the @reach-style `label` API, so call sites barely change
- add a global RadixTooltip.Provider in AppProviders
- replace the custom useTooltip/TooltipPopup positioning in Proxy.tsx with
Radix auto-positioning
- migrate reach tooltip CSS to a .tooltip-content class
- drop @reach/visually-hidden (was unused; the visually-hidden CSS class
is unrelated)
Co-Authored-By: Claude Opus 4.8 <[email protected]>
| -rw-r--r-- | package.json | 3 | ||||
| -rw-r--r-- | pnpm-lock.yaml | 430 | ||||
| -rw-r--r-- | src/app/providers.tsx | 5 | ||||
| -rw-r--r-- | src/components/SideBar.tsx | 2 | ||||
| -rw-r--r-- | src/components/proxies/Proxies.tsx | 2 | ||||
| -rw-r--r-- | src/components/proxies/Proxy.tsx | 28 | ||||
| -rw-r--r-- | src/components/shared/ThemeSwitcher.tsx | 2 | ||||
| -rw-r--r-- | src/components/shared/Tooltip.tsx | 29 | ||||
| -rw-r--r-- | src/styles/main.scss | 9 |
9 files changed, 418 insertions, 92 deletions
diff --git a/package.json b/package.json index ca5148f..977a5ff 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,7 @@ }, "dependencies": { "@hello-pangea/dnd": "^18.0.1", - "@reach/tooltip": "0.18.0", - "@reach/visually-hidden": "0.18.0", + "@radix-ui/react-tooltip": "^1.2.10", "@tanstack/react-query": "^5.101.0", "@tanstack/react-table": "^8.21.3", "chartjs-adapter-date-fns": "^3.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 42ed1f0..75f4d27 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,12 +15,9 @@ importers: '@hello-pangea/dnd': specifier: ^18.0.1 - '@reach/tooltip': - specifier: 0.18.0 - '@reach/visually-hidden': - specifier: 0.18.0 + '@radix-ui/react-tooltip': + specifier: ^1.2.10 + version: 1.2.10(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) '@tanstack/react-query': specifier: ^5.101.0 version: 5.101.0([email protected]) @@ -1269,6 +1266,21 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@floating-ui/[email protected]': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + + '@floating-ui/[email protected]': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + + '@floating-ui/[email protected]': + resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/[email protected]': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + '@fontsource/[email protected]': resolution: {integrity: sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg==} @@ -1439,49 +1451,214 @@ packages: resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} engines: {node: '>= 10.0.0'} - '@reach/[email protected]': - resolution: {integrity: sha512-XwY1IwhM7mkHZFghhjiqjQ6dstbOdpbFLdggeke75u8/8icT8uEHLbovFUgzKjy9qPvYwZIB87rLiR8WdtOXCg==} + '@radix-ui/[email protected]': + resolution: {integrity: sha512-7AdCK9PQyiljKoBDbN8OuctCbd/esdwZPQ8RtOE3SsyQtUpiPb+ND75q0jEhC1m1ecBI0MFNeLJvwIh9iKHRcQ==} + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-j2VTDz1vgCsmuG0k5lBfOcM8n5JPFqZBcMryasFjHYMhwxYL5SRUV5lMSUpRdNtw3D/Sv8pzJtrlAgkssYSsQQ==} + peerDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA==} + peerDependencies: + '@types/react': 18.3.28 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-QwH4PO5urrbO+FaGd5Aglg+YJgWTyyuZ3g/6mKvsqraLkglDdckw9JafgL5McL5VEJ6EPNduPaT3ZE9BttDAqg==} + peerDependencies: + '@types/react': 18.3.28 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-2v+zNAWWe0ySxgC0D0yeXMPQ23xZVgXZTerTz+JKlmdRj6gfTqmCcR29jb6d290DezXPGgruHWDX/vYUebtErg==} + peerDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA==} + peerDependencies: + '@types/react': 18.3.28 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-bhnq/0DEPTi2lsOD3J5rTL65qUKHbKbhqHsmN9TMiclSXpipi651ooUKPPp6G5lF/WiHBdn1s0Wuqsn+myVAvw==} + peerDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-m309havGzsjLHHaIX50G5PlvRs3xkgPCsGk/5PTvYm8D5q33yG0J7w/712PTOhid7NTaFETtnSXjngHQavvhVw==} + peerDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-zdTk4PlUO0E18HnZ3wYbW0KkJJxWCdiNYp6g6X1PtONFhxVkg01vliTJAmwIszU6mHiyBOoW9P0rAugl5/hULQ==} + peerDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-wetd0QI77DbvrPpTAvH1SqOxsYF2wZe5TNxqwOd5Ty4XDpV3dpV0s8K/1MGMJBeY5o7lg8ub5VIt1Ub+yVen6g==} + peerDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA==} + peerDependencies: + '@types/react': 18.3.28 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-NlNe8D0dWEpVfXFli90IO6X07Josx/b1iu98tDnx9Xv0HT4wLIL+m2VOheMHhK7qbp2HoTBqALEFzGyZs/levw==} peerDependencies: - react: ^16.8.0 || 17.x - react-dom: ^16.8.0 || 17.x + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@reach/[email protected]': - resolution: {integrity: sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ==} + '@radix-ui/[email protected]': + resolution: {integrity: sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw==} + peerDependencies: + '@types/react': 18.3.28 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-PLzC90MS+ReootmjC597dvopoelpZ8Q61HJkDXZSExitIq7PL55vHNnesAHwguHK0aPfBnpdNzQtv1uliaqQrA==} + peerDependencies: + '@types/react': 18.3.28 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@reach/[email protected]': - resolution: {integrity: sha512-N9iAjdMbE//6rryZZxAPLRorzDcGBnluf7YQij6XDLiMtfCj1noa7KyLpEc/5XCIB/EwhX3zCluFAwloBKdblA==} + '@radix-ui/[email protected]': + resolution: {integrity: sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA==} peerDependencies: - react: ^16.8.0 || 17.x + '@types/react': 18.3.28 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@reach/[email protected]': - resolution: {integrity: sha512-TImozRapd576ofRk30Le2L3lRTFXF1p47B182wnp5eMTdZa74JX138BtNGEPJFOyrMaVmguVF8SSwZ6a0fon1Q==} + '@radix-ui/[email protected]': + resolution: {integrity: sha512-2uVLvLjgO7NZCWw01/FdqRwmA42J0BcjPMUCA+koFEOAb+zjqIP7SiFz/7zWPrKnVmSqr76Omq2ALyCuX4dhLw==} peerDependencies: - react: ^16.8.0 || 17.x - react-dom: ^16.8.0 || 17.x + '@types/react': 18.3.28 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@reach/[email protected]': - resolution: {integrity: sha512-Xk8urN4NLn3F70da/DtByMow83qO6DF6vOxpLjuDBqud+kjKgxAU9vZMBSZJyH37+F8mZinRnHyXtlLn5njQOg==} + '@radix-ui/[email protected]': + resolution: {integrity: sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA==} peerDependencies: - react: ^16.8.0 || 17.x - react-dom: ^16.8.0 || 17.x + '@types/react': 18.3.28 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@reach/[email protected]': - resolution: {integrity: sha512-yugoTmTjB3qoMk/nUvcnw99MqpyE2TQMOXE29qnQhSqHriRwQhfftjXlTAGTSzsUJmbyms3A/1gQW0X61kjFZw==} + '@radix-ui/[email protected]': + resolution: {integrity: sha512-d8a+bBY/FxikNPlgJJoaBHZX+zKVbWHYJGTLnLvveQgFSTntkGdEKv3JDtHrMS0DNYpllz2nRsTLGLKYttbpmw==} peerDependencies: - react: ^16.8.0 || 17.x - react-dom: ^16.8.0 || 17.x + '@types/react': 18.3.28 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@reach/[email protected]': - resolution: {integrity: sha512-KdVMdpTgDyK8FzdKO9SCpiibuy/kbv3pwgfXshTI6tEcQT1OOwj7BAksnzGC0rPz0UholwC+AgkqEl3EJX3M1A==} + '@radix-ui/[email protected]': + resolution: {integrity: sha512-giWQp+4mxjBPt4KZ0MmyuykFNWfbDxKt4x+fPkRYmgRFJSbCZFzUglvMb/Kjn38tm10YP4ufiQZDx3zna4LU6w==} peerDependencies: - react: ^16.8.0 || 17.x - react-dom: ^16.8.0 || 17.x + '@types/react': 18.3.28 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@reach/[email protected]': - resolution: {integrity: sha512-NsJ3oeHJtPc6UOeV6MHMuzQ5sl1ouKhW85i3C0S7VM+klxVlYScBZ2J4UVnWB50A2c+evdVpCnld2YeuyYYwBw==} + '@radix-ui/[email protected]': + resolution: {integrity: sha512-jCE0WljWifTI4niIMCll06kGpsJTAPiZVU9H4WR1N6qW7At9ystHbN7dDB+we2xH535roFHj7qKS+RGj0FMDWQ==} peerDependencies: - react: ^16.8.0 || 17.x || 18.x - react-dom: ^16.8.0 || 17.x || 18.x + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/[email protected]': + resolution: {integrity: sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA==} '@rolldown/[email protected]': resolution: {integrity: sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==} @@ -5330,6 +5507,23 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@floating-ui/[email protected]': + dependencies: + '@floating-ui/utils': 0.2.11 + + '@floating-ui/[email protected]': + dependencies: + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 + + dependencies: + '@floating-ui/dom': 1.7.6 + react: 18.3.1 + react-dom: 18.3.1([email protected]) + + '@floating-ui/[email protected]': {} + '@fontsource/[email protected]': {} '@fontsource/[email protected]': {} @@ -5478,52 +5672,180 @@ snapshots: '@parcel/watcher-win32-x64': 2.5.6 optional: true + '@radix-ui/[email protected]': {} + + '@radix-ui/[email protected](@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])': + dependencies: + '@radix-ui/react-primitive': 2.1.6(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) + react: 18.3.1 + react-dom: 18.3.1([email protected]) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/[email protected]) + + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/[email protected](@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])': + dependencies: + '@radix-ui/primitive': 1.1.4 + '@radix-ui/react-compose-refs': 1.1.3(@types/[email protected])([email protected]) + '@radix-ui/react-primitive': 2.1.6(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/[email protected])([email protected]) + '@radix-ui/react-use-escape-keydown': 1.1.2(@types/[email protected])([email protected]) react: 18.3.1 react-dom: 18.3.1([email protected]) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/[email protected]) - '@reach/[email protected]': {} + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.2(@types/[email protected])([email protected]) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 - '@reach/[email protected]([email protected])': + '@radix-ui/[email protected](@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])': dependencies: + '@radix-ui/react-arrow': 1.1.10(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) + '@radix-ui/react-compose-refs': 1.1.3(@types/[email protected])([email protected]) + '@radix-ui/react-context': 1.1.4(@types/[email protected])([email protected]) + '@radix-ui/react-primitive': 2.1.6(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/[email protected])([email protected]) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/[email protected])([email protected]) + '@radix-ui/react-use-rect': 1.1.2(@types/[email protected])([email protected]) + '@radix-ui/react-use-size': 1.1.2(@types/[email protected])([email protected]) + '@radix-ui/rect': 1.1.2 react: 18.3.1 + react-dom: 18.3.1([email protected]) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/[email protected]) + '@radix-ui/[email protected](@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])': dependencies: + '@radix-ui/react-primitive': 2.1.6(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/[email protected])([email protected]) react: 18.3.1 react-dom: 18.3.1([email protected]) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/[email protected]) + '@radix-ui/[email protected](@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])': dependencies: - '@reach/observe-rect': 1.2.0 + '@radix-ui/react-use-layout-effect': 1.1.2(@types/[email protected])([email protected]) react: 18.3.1 react-dom: 18.3.1([email protected]) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/[email protected]) + '@radix-ui/[email protected](@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])': dependencies: - '@reach/polymorphic': 0.18.0([email protected]) + '@radix-ui/react-slot': 1.3.0(@types/[email protected])([email protected]) react: 18.3.1 react-dom: 18.3.1([email protected]) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/[email protected]) dependencies: + '@radix-ui/react-compose-refs': 1.1.3(@types/[email protected])([email protected]) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/[email protected](@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])': + dependencies: + '@radix-ui/primitive': 1.1.4 + '@radix-ui/react-compose-refs': 1.1.3(@types/[email protected])([email protected]) + '@radix-ui/react-context': 1.1.4(@types/[email protected])([email protected]) + '@radix-ui/react-dismissable-layer': 1.1.13(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) + '@radix-ui/react-id': 1.1.2(@types/[email protected])([email protected]) + '@radix-ui/react-popper': 1.3.1(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) + '@radix-ui/react-portal': 1.1.12(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) + '@radix-ui/react-presence': 1.1.6(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) + '@radix-ui/react-primitive': 2.1.6(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) + '@radix-ui/react-slot': 1.3.0(@types/[email protected])([email protected]) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/[email protected])([email protected]) + '@radix-ui/react-visually-hidden': 1.2.6(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) react: 18.3.1 react-dom: 18.3.1([email protected]) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/[email protected]) + + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + dependencies: + '@radix-ui/react-use-effect-event': 0.0.3(@types/[email protected])([email protected]) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/[email protected])([email protected]) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.2(@types/[email protected])([email protected]) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.2(@types/[email protected])([email protected]) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 dependencies: - '@reach/polymorphic': 0.18.0([email protected]) + '@radix-ui/rect': 1.1.2 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.2(@types/[email protected])([email protected]) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/[email protected](@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])': + dependencies: + '@radix-ui/react-primitive': 2.1.6(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]) react: 18.3.1 react-dom: 18.3.1([email protected]) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/[email protected]) + + '@radix-ui/[email protected]': {} '@rolldown/[email protected]': {} diff --git a/src/app/providers.tsx b/src/app/providers.tsx index 709df3b..2ad83e2 100644 --- a/src/app/providers.tsx +++ b/src/app/providers.tsx @@ -1,3 +1,4 @@ +import * as RadixTooltip from '@radix-ui/react-tooltip'; import { QueryClientProvider } from '@tanstack/react-query'; import * as React from 'react'; @@ -14,7 +15,9 @@ export function AppProviders({ children }: Props) { return ( <ErrorBoundary> <StateProvider initialState={initialState} actions={actions}> - <QueryClientProvider client={queryClient}>{children}</QueryClientProvider> + <QueryClientProvider client={queryClient}> + <RadixTooltip.Provider delayDuration={0}>{children}</RadixTooltip.Provider> + </QueryClientProvider> </StateProvider> </ErrorBoundary> ); diff --git a/src/components/SideBar.tsx b/src/components/SideBar.tsx index ffd2679..15db264 100644 --- a/src/components/SideBar.tsx +++ b/src/components/SideBar.tsx @@ -1,4 +1,3 @@ -import { Tooltip } from '@reach/tooltip'; import { useSuspenseQuery } from '@tanstack/react-query'; import cx from 'clsx'; import * as React from 'react'; @@ -9,6 +8,7 @@ import { Link, useLocation } from 'react-router-dom'; import { fetchVersion } from '~/api/version'; import { Info } from '~/components/shared/FeatherIcons'; import { ThemeSwitcher } from '~/components/shared/ThemeSwitcher'; +import { Tooltip } from '~/components/shared/Tooltip'; import { connect } from '~/components/StateProvider'; import { getClashAPIConfig } from '~/store/app'; import { ClashAPIConfig } from '~/types'; diff --git a/src/components/proxies/Proxies.tsx b/src/components/proxies/Proxies.tsx index 667c990..8bd37f4 100644 --- a/src/components/proxies/Proxies.tsx +++ b/src/components/proxies/Proxies.tsx @@ -1,4 +1,3 @@ -import { Tooltip } from '@reach/tooltip'; import cx from 'clsx'; import * as React from 'react'; import { useTranslation } from 'react-i18next'; @@ -12,6 +11,7 @@ import { ProxyProvider } from '~/components/proxies/ProxyProvider'; import Settings from '~/components/proxies/Settings'; import BaseModal from '~/components/shared/BaseModal'; import { TextFilter } from '~/components/shared/TextFitler'; +import { Tooltip } from '~/components/shared/Tooltip'; import { useStoreActions } from '~/components/StateProvider'; import Equalizer from '~/components/svg/Equalizer'; import { useProxiesPage } from '~/modules/proxies/hooks'; diff --git a/src/components/proxies/Proxy.tsx b/src/components/proxies/Proxy.tsx index f2de17f..dd5a38c 100644 --- a/src/components/proxies/Proxy.tsx +++ b/src/components/proxies/Proxy.tsx @@ -1,7 +1,7 @@ -import { TooltipPopup, useTooltip } from '@reach/tooltip'; import cx from 'clsx'; import * as React from 'react'; +import { Tooltip } from '~/components/shared/Tooltip'; import { keyCodes } from '~/misc/keycode'; import { DispatchFn, ProxyItem } from '~/store/types'; import { ClashAPIConfig } from '~/types'; @@ -131,28 +131,6 @@ function formatProxyType(t: string) { return t; } -const positionProxyNameTooltip = (triggerRect: { left: number; top: number }) => { - return { - left: triggerRect.left + window.scrollX - 5, - top: triggerRect.top + window.scrollY - 38, - }; -}; - -function ProxyNameTooltip({ children, label, 'aria-label': ariaLabel }) { - const [trigger, tooltip] = useTooltip(); - return ( - <> - {React.cloneElement(children, trigger)} - <TooltipPopup - {...tooltip} - label={label} - aria-label={ariaLabel} - position={positionProxyNameTooltip} - /> - </> - ); -} - export const Proxy = memo(function Proxy({ now, name, @@ -233,9 +211,9 @@ export const Proxy = memo(function Proxy({ role={isSelectable ? 'menuitem' : ''} > <div className={cx(s0.proxyName, s0.row)}> - <ProxyNameTooltip label={name} aria-label={`proxy name: ${name}`}> + <Tooltip label={name} aria-label={`proxy name: ${name}`}> <span>{name}</span> - </ProxyNameTooltip> + </Tooltip> <span className={s0.udpType} style={{ paddingLeft: 4 }}> {formatUdpType(proxy.udp, proxy.xudp)} </span> diff --git a/src/components/shared/ThemeSwitcher.tsx b/src/components/shared/ThemeSwitcher.tsx index 9a67459..59c4c3a 100644 --- a/src/components/shared/ThemeSwitcher.tsx +++ b/src/components/shared/ThemeSwitcher.tsx @@ -1,8 +1,8 @@ -import { Tooltip } from '@reach/tooltip'; import { LazyMotion, domAnimation, m } from 'framer-motion'; import * as React from 'react'; import { useTranslation } from 'react-i18next'; +import { Tooltip } from '~/components/shared/Tooltip'; import { connect } from '~/components/StateProvider'; import { getTheme, switchTheme } from '~/store/app'; import { State } from '~/store/types'; diff --git a/src/components/shared/Tooltip.tsx b/src/components/shared/Tooltip.tsx new file mode 100644 index 0000000..070dd52 --- /dev/null +++ b/src/components/shared/Tooltip.tsx @@ -0,0 +1,29 @@ +import * as RadixTooltip from '@radix-ui/react-tooltip'; +import * as React from 'react'; + +// 对外保持与原 @reach/tooltip 相近的 `label` API,封装 Radix Tooltip。 +// 全局的 RadixTooltip.Provider 在 app/providers.tsx 中提供。 +export function Tooltip({ + label, + children, + 'aria-label': ariaLabel, +}: { + label: React.ReactNode; + children: React.ReactElement; + 'aria-label'?: string; +}) { + return ( + <RadixTooltip.Root> + <RadixTooltip.Trigger asChild>{children}</RadixTooltip.Trigger> + <RadixTooltip.Portal> + <RadixTooltip.Content + className="tooltip-content" + sideOffset={5} + aria-label={ariaLabel} + > + {label} + </RadixTooltip.Content> + </RadixTooltip.Portal> + </RadixTooltip.Root> + ); +} diff --git a/src/styles/main.scss b/src/styles/main.scss index cf04c9e..3932141 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -222,15 +222,10 @@ body { padding: 0; } -/**** @reach/tooltip/styles.css ****/ -:root { - --reach-tooltip: 1; -} - -[data-reach-tooltip] { +/**** Radix Tooltip content ****/ +.tooltip-content { z-index: 1; pointer-events: none; - position: absolute; padding: 0.25em 0.5em; box-shadow: 2px 2px 10px hsla(0, 0%, 0%, 0.1); white-space: nowrap; |
