1
1
mirror of https://github.com/pterodactyl/panel.git synced 2024-11-22 09:02:28 +01:00

Add support for tooltips

This commit is contained in:
DaneEveritt 2022-06-05 18:27:54 -04:00
parent 1a5465dc34
commit 2a2fc42e37
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
5 changed files with 201 additions and 1 deletions

View File

@ -44,6 +44,10 @@ rules:
array-bracket-spacing:
- warn
- always
"@typescript-eslint/no-unused-vars":
- warn
- argsIgnorePattern: '^_'
varsIgnorePattern: '^_'
# Remove errors for not having newlines between operands of ternary expressions https://eslint.org/docs/rules/multiline-ternary
multiline-ternary: 0
"react-hooks/rules-of-hooks":

View File

@ -1,6 +1,7 @@
{
"name": "pterodactyl-panel",
"dependencies": {
"@floating-ui/react-dom-interactions": "^0.6.3",
"@fortawesome/fontawesome-svg-core": "^1.2.32",
"@fortawesome/free-solid-svg-icons": "^5.15.1",
"@fortawesome/react-fontawesome": "^0.1.11",
@ -18,6 +19,7 @@
"easy-peasy": "^4.0.1",
"events": "^3.0.0",
"formik": "^2.2.6",
"framer-motion": "^6.3.10",
"i18next": "^19.0.0",
"i18next-chained-backend": "^2.0.0",
"i18next-localstorage-backend": "^3.0.0",

View File

@ -0,0 +1,95 @@
import React, { cloneElement, useRef, useState } from 'react';
import {
arrow,
autoUpdate,
flip,
offset,
Placement,
shift,
Side,
Strategy,
useDismiss,
useFloating,
useFocus,
useHover,
useInteractions,
useRole,
} from '@floating-ui/react-dom-interactions';
import { AnimatePresence, motion } from 'framer-motion';
interface Props {
content: string | React.ReactChild;
arrow?: boolean;
placement?: Placement;
strategy?: Strategy;
className?: string;
children: React.ReactElement;
}
const arrowSides: Record<Side, Side> = {
top: 'bottom',
bottom: 'top',
left: 'right',
right: 'left',
};
export default ({ content, children, ...props }: Props) => {
const arrowEl = useRef<HTMLSpanElement>(null);
const [ open, setOpen ] = useState(false);
const { x, y, reference, floating, middlewareData, strategy, context } = useFloating({
open,
placement: props.placement || 'top',
strategy: props.strategy || 'absolute',
middleware: [ offset(6), flip(), shift({ padding: 6 }), arrow({ element: arrowEl, padding: 6 }) ],
onOpenChange: setOpen,
whileElementsMounted: autoUpdate,
});
const { getReferenceProps, getFloatingProps } = useInteractions([
useFocus(context),
useHover(context, { restMs: 30 }),
useRole(context, { role: 'tooltip' }),
useDismiss(context),
]);
const side = arrowSides[(props.placement || 'top').split('-')[0] as Side];
const { x: ax, y: ay } = middlewareData.arrow || {};
return (
<>
{cloneElement(children, getReferenceProps({ ref: reference, ...children.props }))}
<AnimatePresence>
{open &&
<motion.span
initial={{ opacity: 0, scale: 0.85 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0 }}
transition={{ type: 'easeIn', damping: 20, stiffness: 300, duration: 0.1 }}
{...getFloatingProps({
ref: floating,
className: 'absolute top-0 left-0 bg-gray-900 text-sm text-gray-200 px-3 py-2 rounded pointer-events-none',
style: {
position: strategy,
top: `${y || 0}px`,
left: `${x || 0}px`,
},
})}
>
{content}
{props.arrow &&
<span
ref={arrowEl}
style={{
transform: `translate(${Math.round(ax || 0)}px, ${Math.round(ay || 0)}px)`,
[side]: '-6px',
}}
className={'absolute top-0 left-0 bg-gray-900 w-3 h-3 rotate-45'}
/>
}
</motion.span>
}
</AnimatePresence>
</>
);
};

View File

@ -29,6 +29,11 @@ module.exports = {
exclude: /node_modules|\.spec\.tsx?$/,
loader: 'babel-loader',
},
{
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto',
},
{
test: /\.css$/,
use: [

View File

@ -1204,7 +1204,7 @@
resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.0.tgz#65b12f12db55188422070e34687bf3af09870922"
integrity sha512-rZ6vufeY/UjAgtyiJ4WvfF6XP6HizIyOfbZOg0RnecIwjrvH8Am3nN1BpKnnPZunYAkUcPPXDhwbxOtGop8cfQ==
"@emotion/is-prop-valid@^0.8.8":
"@emotion/is-prop-valid@^0.8.2", "@emotion/is-prop-valid@^0.8.8":
version "0.8.8"
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
@ -1241,6 +1241,35 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
"@floating-ui/core@^0.7.2":
version "0.7.2"
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-0.7.2.tgz#f7af9613d080dc29360e77c970965b79b524d45a"
integrity sha512-FRVAkSNU/vGXLIsgbggcs70GkXKEOXgBBbNpYPNHSaKsCAMMd00NrjbtKTesxkdv9xm9N3+XiDlcFGY6WnatBg==
"@floating-ui/dom@^0.5.1":
version "0.5.2"
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-0.5.2.tgz#908f3febbfc0d6696d70921616ec194fe07af183"
integrity sha512-z1DnEa7F3d8Fm/eXSbii8UEGpcjZGkQaYYUI0WpEVgD3vBfebDW8j/3ysusxonuMexoigA+A3b/fYH7sEqiwyg==
dependencies:
"@floating-ui/core" "^0.7.2"
"@floating-ui/react-dom-interactions@^0.6.3":
version "0.6.3"
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom-interactions/-/react-dom-interactions-0.6.3.tgz#895c52cb06bf5ea73c00f1074c75b0535e0046bc"
integrity sha512-xvbGEtBtA7JaEngnHQjROArv2onRp3oJIpb4+bEN5EGJf0hBYDY0vD8vFGPz/5TQwN++hb6icOB1QwdOnffMzw==
dependencies:
"@floating-ui/react-dom" "^0.7.1"
aria-hidden "^1.1.3"
use-isomorphic-layout-effect "^1.1.1"
"@floating-ui/react-dom@^0.7.1":
version "0.7.1"
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-0.7.1.tgz#e0eb57cb05c7762d4c904bfbae73148684578d66"
integrity sha512-Dd7e8AupUjzcjeGf1g3EItf/QRtEWKF5GGyEs5WA5n3zlHvEgZ4XrZM6ANhUnzgE3pUQAaXkcXLnibgFp1YBRw==
dependencies:
"@floating-ui/dom" "^0.5.1"
use-isomorphic-layout-effect "^1.1.1"
"@fortawesome/fontawesome-common-types@^0.2.32":
version "0.2.32"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.32.tgz#3436795d5684f22742989bfa08f46f50f516f259"
@ -2027,6 +2056,13 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
aria-hidden@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.1.3.tgz#bb48de18dc84787a3c6eee113709c473c64ec254"
integrity sha512-RhVWFtKH5BiGMycI72q2RAFMLQi8JP9bLuQXgR5a8Znp7P5KOIADSJeyfI8PCVxLEp067B2HbP5JIiI/PXIZeA==
dependencies:
tslib "^1.0.0"
arr-diff@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
@ -4120,6 +4156,26 @@ fragment-cache@^0.2.1:
dependencies:
map-cache "^0.2.2"
framer-motion@^6.3.10:
version "6.3.10"
resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-6.3.10.tgz#e71f8c4ee09612de8328725c4fb1a1c204ae451f"
integrity sha512-modFplFb1Fznsm0MrmRAJUC32UDA5jbGU9rDvkGzhAHksru2tnoKbU/Pa3orzdsJI0CJviG4NGBrmwGveU98Cg==
dependencies:
framesync "6.0.1"
hey-listen "^1.0.8"
popmotion "11.0.3"
style-value-types "5.0.0"
tslib "^2.1.0"
optionalDependencies:
"@emotion/is-prop-valid" "^0.8.2"
framesync@6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.0.1.tgz#5e32fc01f1c42b39c654c35b16440e07a25d6f20"
integrity sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==
dependencies:
tslib "^2.1.0"
fresh@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
@ -4499,6 +4555,11 @@ hex-color-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
hey-listen@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68"
integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==
history@^4.9.0:
version "4.9.0"
resolved "https://registry.yarnpkg.com/history/-/history-4.9.0.tgz#84587c2068039ead8af769e9d6a6860a14fa1bca"
@ -6334,6 +6395,16 @@ pkg-up@^2.0.0:
dependencies:
find-up "^2.1.0"
popmotion@11.0.3:
version "11.0.3"
resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-11.0.3.tgz#565c5f6590bbcddab7a33a074bb2ba97e24b0cc9"
integrity sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==
dependencies:
framesync "6.0.1"
hey-listen "^1.0.8"
style-value-types "5.0.0"
tslib "^2.1.0"
portfinder@^1.0.26:
version "1.0.26"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70"
@ -7993,6 +8064,14 @@ style-loader@^2.0.0:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
style-value-types@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-5.0.0.tgz#76c35f0e579843d523187989da866729411fc8ad"
integrity sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==
dependencies:
hey-listen "^1.0.8"
tslib "^2.1.0"
styled-components-breakpoint@^3.0.0-preview.20:
version "3.0.0-preview.20"
resolved "https://registry.yarnpkg.com/styled-components-breakpoint/-/styled-components-breakpoint-3.0.0-preview.20.tgz#877e88a00c0cf66976f610a1d347839a1a0b6d70"
@ -8340,6 +8419,11 @@ tsconfig-paths@^3.9.0:
minimist "^1.2.0"
strip-bom "^3.0.0"
tslib@^1.0.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^1.10.0:
version "1.11.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
@ -8349,6 +8433,11 @@ tslib@^1.8.1, tslib@^1.9.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
tslib@^2.1.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
tsutils@^3.17.1:
version "3.17.1"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
@ -8517,6 +8606,11 @@ url@^0.11.0:
punycode "1.3.2"
querystring "0.2.0"
use-isomorphic-layout-effect@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb"
integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==
use-memo-one@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.1.tgz#39e6f08fe27e422a7d7b234b5f9056af313bd22c"