From 1a65d48a1dd996cf835496ac0c9c7e417d0d1b55 Mon Sep 17 00:00:00 2001 From: Lowie Benoot Date: Mon, 30 Oct 2023 15:27:00 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E2=9E=95=20Install=20@radix/react-tooltip?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit st --- package.json | 1 + yarn.lock | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+) diff --git a/package.json b/package.json index fa86dbb2a..d5eb638c6 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "types": "./dist/types/index.d.ts", "dependencies": { "@babel/runtime": "^7.18.3", + "@radix-ui/react-tooltip": "^1.0.7", "@teamleader/ui-animations": "^0.0.3", "@teamleader/ui-colors": "^2.0.0", "@teamleader/ui-icons": "^2.1.0", diff --git a/yarn.lock b/yarn.lock index d270c6965..3d5fc3c8f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2256,6 +2256,13 @@ resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.0.1.tgz#00e64d74e911602c8533957af0cce5af6b2e93c8" integrity sha512-bO37brCPfteXQfFY0DyNDGB3+IMe4j150KFQcgJ5aBP295p9nBGeHEs/p0czrRbtlHq4Px/yoPXO/+dOCcF4uA== +"@floating-ui/core@^1.4.2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.0.tgz#5c05c60d5ae2d05101c3021c1a2a350ddc027f8c" + integrity sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg== + dependencies: + "@floating-ui/utils" "^0.1.3" + "@floating-ui/dom@^1.0.1": version "1.0.4" resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.0.4.tgz#cc0f2a03db7193b1b932b90d09c5c81235682a60" @@ -2263,6 +2270,26 @@ dependencies: "@floating-ui/core" "^1.0.1" +"@floating-ui/dom@^1.5.1": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.3.tgz#54e50efcb432c06c23cd33de2b575102005436fa" + integrity sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA== + dependencies: + "@floating-ui/core" "^1.4.2" + "@floating-ui/utils" "^0.1.3" + +"@floating-ui/react-dom@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.2.tgz#fab244d64db08e6bed7be4b5fcce65315ef44d20" + integrity sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ== + dependencies: + "@floating-ui/dom" "^1.5.1" + +"@floating-ui/utils@^0.1.3": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9" + integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A== + "@humanwhocodes/config-array@^0.11.10": version "0.11.10" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" @@ -2707,6 +2734,185 @@ schema-utils "^3.0.0" source-map "^0.7.3" +"@radix-ui/primitive@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.1.tgz#e46f9958b35d10e9f6dc71c497305c22e3e55dbd" + integrity sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-arrow@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz#c24f7968996ed934d57fe6cde5d6ec7266e1d25d" + integrity sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-primitive" "1.0.3" + +"@radix-ui/react-compose-refs@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz#7ed868b66946aa6030e580b1ffca386dd4d21989" + integrity sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-context@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.1.tgz#fe46e67c96b240de59187dcb7a1a50ce3e2ec00c" + integrity sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-dismissable-layer@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4" + integrity sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-escape-keydown" "1.0.3" + +"@radix-ui/react-id@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0" + integrity sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-layout-effect" "1.0.1" + +"@radix-ui/react-popper@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.1.3.tgz#24c03f527e7ac348fabf18c89795d85d21b00b42" + integrity sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w== + dependencies: + "@babel/runtime" "^7.13.10" + "@floating-ui/react-dom" "^2.0.0" + "@radix-ui/react-arrow" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-layout-effect" "1.0.1" + "@radix-ui/react-use-rect" "1.0.1" + "@radix-ui/react-use-size" "1.0.1" + "@radix-ui/rect" "1.0.1" + +"@radix-ui/react-portal@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15" + integrity sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-primitive" "1.0.3" + +"@radix-ui/react-presence@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba" + integrity sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-use-layout-effect" "1.0.1" + +"@radix-ui/react-primitive@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0" + integrity sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-slot" "1.0.2" + +"@radix-ui/react-slot@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.2.tgz#a9ff4423eade67f501ffb32ec22064bc9d3099ab" + integrity sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + +"@radix-ui/react-tooltip@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz#8f55070f852e7e7450cc1d9210b793d2e5a7686e" + integrity sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-dismissable-layer" "1.0.5" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-popper" "1.1.3" + "@radix-ui/react-portal" "1.0.4" + "@radix-ui/react-presence" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-visually-hidden" "1.0.3" + +"@radix-ui/react-use-callback-ref@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz#f4bb1f27f2023c984e6534317ebc411fc181107a" + integrity sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-use-controllable-state@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz#ecd2ced34e6330caf89a82854aa2f77e07440286" + integrity sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-callback-ref" "1.0.1" + +"@radix-ui/react-use-escape-keydown@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755" + integrity sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-callback-ref" "1.0.1" + +"@radix-ui/react-use-layout-effect@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz#be8c7bc809b0c8934acf6657b577daf948a75399" + integrity sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-use-rect@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz#fde50b3bb9fd08f4a1cd204572e5943c244fcec2" + integrity sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/rect" "1.0.1" + +"@radix-ui/react-use-size@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz#1c5f5fea940a7d7ade77694bb98116fb49f870b2" + integrity sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-layout-effect" "1.0.1" + +"@radix-ui/react-visually-hidden@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz#51aed9dd0fe5abcad7dee2a234ad36106a6984ac" + integrity sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-primitive" "1.0.3" + +"@radix-ui/rect@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.0.1.tgz#bf8e7d947671996da2e30f4904ece343bc4a883f" + integrity sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ== + dependencies: + "@babel/runtime" "^7.13.10" + "@sinclair/typebox@^0.25.16": version "0.25.21" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.21.tgz#763b05a4b472c93a8db29b2c3e359d55b29ce272" From f762ef160edf93403078d24d9691adc033c76129 Mon Sep 17 00:00:00 2001 From: Lowie Benoot Date: Mon, 30 Oct 2023 15:28:54 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E2=9C=A8=20Implement=20the=20tooltip=20wit?= =?UTF-8?q?h=20@radix/react-tooltip=20instead=20of=20doing=20all=20the=20p?= =?UTF-8?q?ositioning=20ourselves?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The positioning is very complicated, and it was bugged. --- src/components/tooltip/Tooltip.tsx | 200 +++++++----------------- src/components/tooltip/theme.css | 240 +++++++++-------------------- 2 files changed, 129 insertions(+), 311 deletions(-) diff --git a/src/components/tooltip/Tooltip.tsx b/src/components/tooltip/Tooltip.tsx index 7940a13df..d4bb877f3 100644 --- a/src/components/tooltip/Tooltip.tsx +++ b/src/components/tooltip/Tooltip.tsx @@ -1,33 +1,23 @@ import uiUtilities from '@teamleader/ui-utilities'; import cx from 'classnames'; +import * as RadixTooltip from '@radix-ui/react-tooltip'; import omit from 'lodash.omit'; -import React, { MouseEventHandler, ReactNode, useEffect, useMemo, useRef, useState } from 'react'; -import { createPortal } from 'react-dom'; -import Transition from 'react-transition-group/Transition'; +import React, { MouseEventHandler, ReactNode, useEffect, useRef, useState } from 'react'; import { GenericComponent } from '../../@types/types'; import { COLORS, SIZES } from '../../constants'; import Box from '../box'; import { BoxProps } from '../box/Box'; -import DocumentObjectProvider, { Context as DocumentObjectContext } from '../hoc/DocumentObjectProvider'; -import { getViewport } from '../utils/utils'; import theme from './theme.css'; -type Position = 'bottom' | 'horizontal' | 'left' | 'right' | 'top' | 'vertical'; +type Position = 'bottom' | 'left' | 'right' | 'top'; export const POSITIONS: Record = { BOTTOM: 'bottom', - HORIZONTAL: 'horizontal', LEFT: 'left', RIGHT: 'right', TOP: 'top', - VERTICAL: 'vertical', }; -interface PositionState { - position: Position; - top: number | string; - left: number | string; -} export type AllowedColor = Exclude<(typeof COLORS)[number], 'teal'> | 'white' | 'inverse'; export type AllowedSize = Exclude<(typeof SIZES)[number], 'tiny' | 'fullscreen' | 'smallest' | 'hero'>; const SIZE_MAP: Record = { @@ -57,19 +47,21 @@ interface TooltippedComponentProps { tooltipPosition?: Position; tooltipShowOnClick?: boolean; tooltipSize?: AllowedSize; - documentObject: Document; tooltipShowDelay?: number; /** The z-index of the Tooltip */ zIndex?: number; tooltipActive?: boolean; ComposedComponent: React.ElementType; } -export interface TooltipProps extends Omit {} +export interface TooltipProps extends Omit {} + +const Arrow = () => { + return
; +}; const TooltippedComponent: GenericComponent = ({ children, className, - documentObject, tooltip, tooltipColor = 'white', onTooltipEntered, @@ -88,75 +80,11 @@ const TooltippedComponent: GenericComponent = ({ ...other }) => { // eslint-disable-next-line react-hooks/exhaustive-deps - const tooltipRoot = useMemo(() => documentObject.createElement('div'), []); const ref = useRef(null); const [active, setActive] = useState(false); - const [position, setPosition] = useState({ position: tooltipPosition, top: 'auto', left: 'auto' }); - - const activate = (position: PositionState) => { - documentObject.body.appendChild(tooltipRoot); - setActive(true); - setPosition({ position: position.position, top: position.top, left: position.left }); - }; - - const getPosition = (element: Element) => { - if (tooltipPosition === POSITIONS.HORIZONTAL) { - const origin = element.getBoundingClientRect(); - const { width: windowWidth } = getViewport(); - const toRight = origin.left < windowWidth / 2 - origin.width / 2; - - return toRight ? POSITIONS.RIGHT : POSITIONS.LEFT; - } else if (tooltipPosition === POSITIONS.VERTICAL) { - const origin = element.getBoundingClientRect(); - const { height: windowHeight } = getViewport(); - const toBottom = origin.top < windowHeight / 2 - origin.height / 2; - - return toBottom ? POSITIONS.BOTTOM : POSITIONS.TOP; - } - - return tooltipPosition; - }; - - const calculatePosition = (element: Element | null) => { - if (typeof element?.getBoundingClientRect !== 'function') { - return { top: 0, left: 0, position: tooltipPosition }; - } - - const { top, left, height, width } = element.getBoundingClientRect(); - const position = getPosition(element); - const xOffset = window.scrollX || window.pageXOffset; - const yOffset = window.scrollY || window.pageYOffset; - - if (position === POSITIONS.BOTTOM) { - return { - top: top + height + yOffset, - left: left + width / 2 + xOffset, - position, - }; - } else if (position === POSITIONS.TOP) { - return { - top: top + yOffset, - left: left + width / 2 + xOffset, - position, - }; - } else if (position === POSITIONS.LEFT) { - return { - top: top + height / 2 + yOffset, - left: left + xOffset, - position, - }; - } else if (position === POSITIONS.RIGHT) { - return { - top: top + height / 2 + yOffset, - left: left + width + xOffset, - position, - }; - } - return { top: 0, left: 0, position: tooltipPosition }; - }; const handleMouseEnter: MouseEventHandler = (event) => { - activate(calculatePosition(event.currentTarget)); + setActive(true); if (onMouseEnter) { onMouseEnter(event); @@ -177,7 +105,7 @@ const TooltippedComponent: GenericComponent = ({ } if (tooltipShowOnClick && !active) { - activate(calculatePosition(event.currentTarget)); + setActive(true); } if (onClick) { @@ -185,17 +113,9 @@ const TooltippedComponent: GenericComponent = ({ } }; - const handleTransitionExited = () => { - documentObject.body.removeChild(tooltipRoot); - }; - - const handleTransitionEntered = () => { - onTooltipEntered && onTooltipEntered(); - }; - useEffect(() => { if (tooltipActive && !active) { - activate(calculatePosition(ref.current)); + setActive(true); } if (!tooltipActive && active) { @@ -210,7 +130,6 @@ const TooltippedComponent: GenericComponent = ({ 'tooltipPosition', 'tooltipShowOnClick', 'tooltipShowDelay', - 'documentObject', ]); let childProps = { @@ -231,47 +150,44 @@ const TooltippedComponent: GenericComponent = ({ }; } - return React.createElement( - ComposedComponent, - childProps, - children, - createPortal( - - {(state) => { - const classNames = cx( - uiUtilities['box-shadow-200'], - theme['tooltip'], - theme[tooltipColor], - theme[tooltipSize], - { - [theme['is-entering']]: state === 'entering', - [theme['is-entered']]: state === 'entered', - [theme['is-exiting']]: state === 'exiting', - [theme[position.position]]: theme[position.position], - }, - ); - - return ( -
- - {tooltipIcon &&
{tooltipIcon}
} -
{tooltip}
-
-
- ); + // Using the radix tooltip component, but we only use it for rendering the tooltip + // we still manually implement the trigger with mouseover/leave/click and keep that in state. + // With a pure radix implementation we couldn't support our `tooltipHideOnClick` prop. + return ( + + { + if (open && onTooltipEntered) { + onTooltipEntered(); + } }} -
, - tooltipRoot, - ), + > + + {children} + + + + + {tooltipIcon &&
{tooltipIcon}
} +
{tooltip}
+
+ + + +
+
+ + ); }; @@ -280,22 +196,14 @@ function Tooltip( ): React.ComponentType; function Tooltip

(ComposedComponent: React.ElementType

): React.ComponentType

; function Tooltip(ComposedComponent: TooltippedComponentProps['ComposedComponent']) { - return DocumentObjectProvider((props) => { + const WrappedComponent = (props: TooltipProps) => { return ( - - {(documentObject) => ( - - {props.children} - - )} - + + {props.children} + ); - }); + }; + return WrappedComponent; } export default Tooltip; diff --git a/src/components/tooltip/theme.css b/src/components/tooltip/theme.css index d9c9b597f..aadfbf3ee 100644 --- a/src/components/tooltip/theme.css +++ b/src/components/tooltip/theme.css @@ -4,210 +4,120 @@ --tooltip-margin: calc(0.8 * var(--unit)); --tooltip-border-radius: calc(0.4 * var(--unit)); --tooltip-border-width: 1px; - --tooltip-small-max-width: calc(18 * var(--unit)); - --tooltip-medium-max-width: calc(24 * var(--unit)); - --tooltip-large-max-width: calc(36 * var(--unit)); --tooltip-animation-duration: 200ms; } -.tooltip { - svg { - -ms-transform: translateY(-1px); - } -} - -.tooltip { +.tooltip-content { + border-radius: var(--tooltip-border-radius); display: block; + will-change: transform, opacity; pointer-events: none; - position: absolute; - text-align: left; - transform-origin: top left; - transition: cubic-bezier(0.4, 0, 0.2, 1) var(--tooltip-animation-duration) transform; - - &::after { - content: ''; - border-color: hsl(var(--color-teal-dark-hsl) / 20%); - border-style: solid; - height: var(--tooltip-arrow-size); - position: absolute; - width: var(--tooltip-arrow-size); - transform: rotate(45deg); - } - - &.bottom { - margin-top: var(--tooltip-arrow-size); + color: var(--tooltip-text-color); + animation-duration: var(--tooltip-animation-duration); + animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + animation-name: animateTooltip; + will-change: transform, opacity; + transform-origin: var(--radix-tooltip-content-transform-origin); - &.is-exiting, - &.is-entering { - transform: scale(0) translateX(-50%); - } - - &.is-entered { - transform: scale(1) translateX(-50%); - } - - &::after { - border-width: var(--tooltip-border-width) 0 0 var(--tooltip-border-width); - bottom: calc(100% - var(--tooltip-arrow-position-correction)); - left: calc(50% - (var(--tooltip-arrow-size) + var(--tooltip-border-width) * 2) / 2); - } - } - - &.top { - margin-top: calc(-1 * var(--tooltip-arrow-size)); - - &.is-exiting, - &.is-entering { - transform: scale(0) translateX(-50%) translateY(-100%); - } - - &.is-entered { - transform: scale(1) translateX(-50%) translateY(-100%); - } - - &::after { - border-width: 0 var(--tooltip-border-width) var(--tooltip-border-width) 0; - left: calc(50% - (var(--tooltip-arrow-size) + var(--tooltip-border-width) * 2) / 2); - top: calc(100% - var(--tooltip-arrow-position-correction)); - } + .inner { + border: var(--tooltip-border-width) solid hsl(var(--color-teal-dark-hsl) / 20%); + border-radius: var(--tooltip-border-radius); + background: var(--tooltip-background-color); + display: flex; + align-items: center; } - &.left { - margin-left: calc(-1 * var(--tooltip-arrow-size)); - - &.is-exiting, - &.is-entering { - transform: scale(0) translateX(-100%) translateY(-50%); - } - - &.is-entered { - transform: scale(1) translateX(-100%) translateY(-50%); - } - - &::after { - border-width: var(--tooltip-border-width) var(--tooltip-border-width) 0 0; - left: calc(100% - var(--tooltip-arrow-position-correction)); - top: calc(50% - (var(--tooltip-arrow-size) + var(--tooltip-border-width) * 2) / 2); - } + .text { + flex: 1; + max-width: var(--tooltip-max-width); } - &.right { - margin-left: var(--tooltip-arrow-size); - - &.is-exiting, - &.is-entering { - transform: scale(0) translateX(0) translateY(-50%); - } - - &.is-entered { - transform: scale(1) translateX(0) translateY(-50%); - } - - &::after { - border-width: 0 0 var(--tooltip-border-width) var(--tooltip-border-width); - right: calc(100% - var(--tooltip-arrow-position-correction)); - top: calc(50% - (var(--tooltip-arrow-size) + var(--tooltip-border-width) * 2) / 2); - } + .icon { + display: inline-block; + margin-right: var(--spacer-smaller); + vertical-align: middle; } } -.inner { - border: var(--tooltip-border-width) solid hsl(var(--color-teal-dark-hsl) / 20%); - border-radius: var(--tooltip-border-radius); - display: block; -} - -.icon { - display: inline-block; - margin-right: var(--spacer-smaller); - vertical-align: middle; -} - -.text { - display: inline-block; - vertical-align: middle; -} - -.small .text { - max-width: var(--tooltip-small-max-width); -} - -.medium .text { - max-width: var(--tooltip-medium-max-width); +.arrow { + border-color: hsl(var(--color-teal-dark-hsl) / 20%); + border-style: solid; + height: var(--tooltip-arrow-size); + position: absolute; + width: var(--tooltip-arrow-size); + transform: rotate(45deg); + background-color: var(--tooltip-background-color); + border-width: 0 var(--tooltip-border-width) var(--tooltip-border-width) 0; + left: calc(50% - (var(--tooltip-arrow-size) + var(--tooltip-border-width) * 2) / 2); + top: calc(100% - var(--tooltip-arrow-position-correction)); } -.large .text { - max-width: var(--tooltip-large-max-width); +.tooltip-content { + svg { + -ms-transform: translateY(-1px); + } } .aqua { - color: var(--color-aqua-darkest); - - &::after, - .inner { - background: var(--color-aqua-light); - } + --tooltip-text-color: var(--color-aqua-darkest); + --tooltip-background-color: var(--color-aqua-light); } .gold { - color: var(--color-gold-darkest); - - &::after, - .inner { - background: var(--color-gold-light); - } + --tooltip-text-color: var(--color-gold-darkest); + --tooltip-background-color: var(--color-gold-light); } .inverse { - color: var(--color-teal-light); - - &::after, - .inner { - background: var(--color-teal-darkest); - } + --tooltip-text-color: var(--color-teal-light); + --tooltip-background-color: var(--color-teal-darkest); } .neutral { - color: var(--color-teal-darkest); - - &::after, - .inner { - background: var(--color-neutral-light); - } + --tooltip-text-color: var(--color-teal-darkest); + --tooltip-background-color: var(--color-neutral-light); } .mint { - color: var(--color-mint-darkest); - - &::after, - .inner { - background: var(--color-mint-light); - } + --tooltip-text-color: var(--color-mint-darkest); + --tooltip-background-color: var(--color-mint-light); } .ruby { - color: var(--color-ruby-darkest); - - &::after, - .inner { - background: var(--color-ruby-light); - } + --tooltip-text-color: var(--color-ruby-darkest); + --tooltip-background-color: var(--color-ruby-light); } .violet { - color: var(--color-violet-darkest); - - &::after, - .inner { - background: var(--color-violet-light); - } + --tooltip-text-color: var(--color-violet-darkest); + --tooltip-background-color: var(--color-violet-light); } .white { - color: var(--color-teal-darkest); + --tooltip-text-color: var(--color-teal-darkest); + --tooltip-background-color: var(--color-white); +} - &::after, - .inner { - background: var(--color-white); +.small { + --tooltip-max-width: calc(18 * var(--unit)); +} + +.medium { + --tooltip-max-width: calc(24 * var(--unit)); +} + +.large { + --tooltip-max-width: calc(36 * var(--unit)); +} + +@keyframes animateTooltip { + from { + opacity: 0; + transform: scale(0); + } + to { + opacity: 1; + transform: scale(1); } } + From 5b86813f43bf8c065a878dddeff9b21e48c95eb1 Mon Sep 17 00:00:00 2001 From: Lowie Benoot Date: Mon, 30 Oct 2023 15:30:24 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=F0=9F=93=9D=20Change=20tooltip=20position?= =?UTF-8?q?=20in=20the=20stories?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Horizontal and vertical don't exist anymore --- src/components/tooltip/tooltip.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/tooltip/tooltip.stories.tsx b/src/components/tooltip/tooltip.stories.tsx index b7cb1cc71..2f00e5f10 100644 --- a/src/components/tooltip/tooltip.stories.tsx +++ b/src/components/tooltip/tooltip.stories.tsx @@ -26,7 +26,7 @@ const textSmallTooltipContent = ( const defaultTooltipProps = { tooltipColor: 'white', - tooltipPosition: 'horizontal', + tooltipPosition: 'bottom', tooltipSize: 'medium', }; const tooltipArgTypes = { From 99a21d712db87be0bbdf8d67db210e1f75aeceef Mon Sep 17 00:00:00 2001 From: Lowie Benoot Date: Mon, 30 Oct 2023 15:41:09 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E2=9C=85=20Update=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Radix renders the tooltip content 2 times, one is just for accessibility. --- src/components/tooltip/__tests__/Tooltip.spec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/tooltip/__tests__/Tooltip.spec.tsx b/src/components/tooltip/__tests__/Tooltip.spec.tsx index 1caad4334..648be9049 100644 --- a/src/components/tooltip/__tests__/Tooltip.spec.tsx +++ b/src/components/tooltip/__tests__/Tooltip.spec.tsx @@ -16,6 +16,6 @@ describe('Component - Tooltip', () => { const screen = render(Hover me); await user.hover(screen.getByText('Hover me')); - expect(screen.getByText('This is the tooltip')).toBeVisible(); + expect(screen.getAllByText('This is the tooltip')[0]).toBeVisible(); }); }); From 289ebc71855980125ed5af8621429ffac05b410d Mon Sep 17 00:00:00 2001 From: Lowie Benoot Date: Mon, 30 Oct 2023 15:44:44 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=F0=9F=93=9D=20Update=20changelog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af0796459..5527c84cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,11 @@ ### Removed -### Fixed +## [23.0.0] - 2023-10-30 -### Dependency updates +### Removed + +- `Tooltip`: removed `horizontal` and `vertical` positions from the `tooltipPosition` options. Tooltips will still render to the opposite side in case there is not enough space on the chosen position. ([@lowiebenoot](https://github.com/lowiebenoot)) in [#2796](https://github.com/teamleadercrm/ui/pull/2796)` ## [22.3.5] - 2023-10-18 From f06cb457d95e85a60c77f93805ded756ca257202 Mon Sep 17 00:00:00 2001 From: Lowie Benoot Date: Mon, 30 Oct 2023 15:45:09 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=F0=9F=94=96=20Bump=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d5eb638c6..186eb79e9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@teamleader/ui", "description": "Teamleader UI library", - "version": "22.3.5", + "version": "23.0.0", "author": "Teamleader ", "bugs": { "url": "https://github.com/teamleadercrm/ui/issues" From 300014d7dbb316c6e85d58396a1853f377480587 Mon Sep 17 00:00:00 2001 From: Lowie Benoot Date: Tue, 31 Oct 2023 12:30:13 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Don't=20use=20inline?= =?UTF-8?q?=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/tooltip/Tooltip.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/tooltip/Tooltip.tsx b/src/components/tooltip/Tooltip.tsx index d4bb877f3..4712c6ad2 100644 --- a/src/components/tooltip/Tooltip.tsx +++ b/src/components/tooltip/Tooltip.tsx @@ -113,6 +113,12 @@ const TooltippedComponent: GenericComponent = ({ } }; + const handleOpenChange: RadixTooltip.TooltipProps['onOpenChange'] = (open) => { + if (open && onTooltipEntered) { + onTooltipEntered(); + } + }; + useEffect(() => { if (tooltipActive && !active) { setActive(true); @@ -155,13 +161,7 @@ const TooltippedComponent: GenericComponent = ({ // With a pure radix implementation we couldn't support our `tooltipHideOnClick` prop. return ( - { - if (open && onTooltipEntered) { - onTooltipEntered(); - } - }} - > + {children} From a038c63b3c4f2df4f95e0fcea2f96e8e10c3d020 Mon Sep 17 00:00:00 2001 From: Lowie Benoot Date: Tue, 31 Oct 2023 12:32:05 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=F0=9F=94=A5=20Remove=20unnecessary=20eslin?= =?UTF-8?q?t-disable-next-line?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/tooltip/Tooltip.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/tooltip/Tooltip.tsx b/src/components/tooltip/Tooltip.tsx index 4712c6ad2..e4e9bbeb5 100644 --- a/src/components/tooltip/Tooltip.tsx +++ b/src/components/tooltip/Tooltip.tsx @@ -79,7 +79,6 @@ const TooltippedComponent: GenericComponent = ({ ComposedComponent, ...other }) => { - // eslint-disable-next-line react-hooks/exhaustive-deps const ref = useRef(null); const [active, setActive] = useState(false);