;
-
-export const Base = {
- render: () => (
-
-
- An infinite amount of content to place correctly the tooltip. Lorem ipsum dolor sit amet, consectetur adipiscing
- elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
- exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
- voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,
- sunt in culpa qui officia deserunt mollit anim id est laborum.
-
-
- Show tooltip
-
-
- An infinite amount of content to place correctly the tooltip. Lorem ipsum dolor sit amet, consectetur adipiscing
- elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
- exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
- voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,
- sunt in culpa qui officia deserunt mollit anim id est laborum.
-
-
- ),
-
- name: 'base',
-} satisfies Story;
-
-export const WithTextInside = {
- render: () => (
-
-
- Show tooltip
-
-
- ),
-
- name: 'with text inside',
-} satisfies Story;
-
-export const Grid = {
- render: () => (
-
-
-
-
- Default tooltip
-
-
-
-
-
-
- Bottom
-
-
-
-
-
-
- Right
-
-
-
-
-
-
- Left
-
-
-
-
- ),
-
- name: 'grid',
-} satisfies Story;
diff --git a/packages/design-system/package.json b/packages/design-system/package.json
index 94976791f..7afbcc942 100644
--- a/packages/design-system/package.json
+++ b/packages/design-system/package.json
@@ -19,6 +19,7 @@
"@radix-ui/react-dismissable-layer": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-focus-scope": "1.0.4",
+ "@radix-ui/react-tooltip": "1.0.7",
"@radix-ui/react-use-controllable-state": "^1.0.1",
"@strapi/ui-primitives": "^2.0.0-beta.3",
"@uiw/react-codemirror": "^4.21.25",
diff --git a/packages/design-system/src/components/CarouselInput/CarouselImage.tsx b/packages/design-system/src/components/CarouselInput/CarouselImage.tsx
index dd2e02fe1..4d6f396cc 100644
--- a/packages/design-system/src/components/CarouselInput/CarouselImage.tsx
+++ b/packages/design-system/src/components/CarouselInput/CarouselImage.tsx
@@ -24,7 +24,7 @@ export const CarouselImage = (props: CarouselImageProps) => {
if (isError) {
return (
-
+
);
diff --git a/packages/design-system/src/components/IconButton/IconButton.tsx b/packages/design-system/src/components/IconButton/IconButton.tsx
index f7bd874fd..083d99690 100644
--- a/packages/design-system/src/components/IconButton/IconButton.tsx
+++ b/packages/design-system/src/components/IconButton/IconButton.tsx
@@ -3,8 +3,8 @@ import * as React from 'react';
import { styled } from 'styled-components';
import { PolymorphicRef, PropsToTransientProps } from '../../types';
+import { AccessibleIcon } from '../../utilities/AccessibleIcon';
import { forwardRef } from '../../utilities/forwardRef';
-import { VisuallyHidden } from '../../utilities/VisuallyHidden';
import { BaseButton, BaseButtonComponent, BaseButtonProps } from '../BaseButton';
import { Flex, FlexComponent } from '../Flex';
import { Tooltip } from '../Tooltip';
@@ -20,55 +20,38 @@ const VARIANTS = [VARIANT_DEFAULT, VARIANT_SECONDARY] as const;
type IconButtonSize = (typeof SIZES)[number];
type IconButtonVariant = (typeof VARIANTS)[number];
-type SharedIconButtonProps = BaseButtonProps & {
+type IconButtonProps = BaseButtonProps & {
+ children: React.ReactNode;
+ /**
+ * This isn't visually rendererd, but required for accessibility.
+ */
+ label: string;
onClick?: React.MouseEventHandler;
+ /**
+ * @default 'S'
+ */
size?: IconButtonSize;
+ /**
+ * @default 'tertiary'
+ */
variant?: IconButtonVariant;
+ /**
+ * @default true
+ */
+ withTooltip?: boolean;
};
-type LabelOnlyProps = SharedIconButtonProps & {
- label: string;
- ['aria-label']?: never;
-};
-
-type AriaLabelOnlyProps = SharedIconButtonProps & {
- label?: never;
- ['aria-label']: string;
-};
-
-interface IconOnlyProps {
- icon: React.ReactNode;
- children?: never;
-}
-
-interface ChildrenOnlyProps {
- icon?: never;
- children: React.ReactNode;
-}
-
-type ChildrenWithLabel = LabelOnlyProps & ChildrenOnlyProps;
-type ChildrenWithAriaLabel = AriaLabelOnlyProps & ChildrenOnlyProps;
-type IconWithLabel = LabelOnlyProps & IconOnlyProps;
-type IconWithAriaLabel = AriaLabelOnlyProps & IconOnlyProps;
-
-type IconButtonProps =
- | ChildrenWithLabel
- | ChildrenWithAriaLabel
- | IconWithLabel
- | IconWithAriaLabel;
-
const IconButton = forwardRef(
(
{
label,
background,
children,
- icon,
disabled = false,
onClick,
size = SIZES[0],
- 'aria-label': ariaLabel,
variant = VARIANTS[0],
+ withTooltip = true,
...restProps
}: IconButtonProps,
ref: PolymorphicRef,
@@ -90,16 +73,11 @@ const IconButton = forwardRef(
onClick={handleClick}
$variant={variant}
>
- {label ?? ariaLabel}
-
- {React.cloneElement((icon || children) as React.ReactElement, {
- 'aria-hidden': true,
- focusable: false, // See: https://allyjs.io/tutorials/focusing-in-svg.html#making-svg-elements-focusable
- })}
+ {children}
);
- return label ? {component} : component;
+ return withTooltip ? {component} : component;
},
);
@@ -180,15 +158,4 @@ const IconButtonGroup = styled(Flex)`
`;
export { IconButton, IconButtonGroup };
-export type {
- IconButtonProps,
- IconButtonComponent,
- IconButtonSize,
- IconButtonVariant,
- ChildrenOnlyProps,
- ChildrenWithAriaLabel,
- ChildrenWithLabel,
- IconOnlyProps,
- IconWithAriaLabel,
- IconWithLabel,
-};
+export type { IconButtonProps, IconButtonComponent, IconButtonSize, IconButtonVariant };
diff --git a/packages/design-system/src/components/ModalLayout/ModalHeader.tsx b/packages/design-system/src/components/ModalLayout/ModalHeader.tsx
index a4e038eb5..586daf810 100644
--- a/packages/design-system/src/components/ModalLayout/ModalHeader.tsx
+++ b/packages/design-system/src/components/ModalLayout/ModalHeader.tsx
@@ -24,7 +24,9 @@ export const ModalHeader = ({ children, closeLabel = 'Close the modal' }: ModalH
{children}
- } />
+
+
+
);
diff --git a/packages/design-system/src/components/ModalLayout/__tests__/__snapshots__/ModalLayout.test.tsx.snap b/packages/design-system/src/components/ModalLayout/__tests__/__snapshots__/ModalLayout.test.tsx.snap
index 1daf4b1f8..6a8bbed37 100644
--- a/packages/design-system/src/components/ModalLayout/__tests__/__snapshots__/ModalLayout.test.tsx.snap
+++ b/packages/design-system/src/components/ModalLayout/__tests__/__snapshots__/ModalLayout.test.tsx.snap
@@ -310,11 +310,6 @@ exports[`ModalLayout should render component and match snapshot 1`] = `
class="c8 c2 c9 c10"
type="button"
>
-
- Close the modal
-
+
+ Close the modal
+
diff --git a/packages/design-system/src/components/SubNav/SubNavHeader.tsx b/packages/design-system/src/components/SubNav/SubNavHeader.tsx
index 7ec2645e2..4838a06b0 100644
--- a/packages/design-system/src/components/SubNav/SubNavHeader.tsx
+++ b/packages/design-system/src/components/SubNav/SubNavHeader.tsx
@@ -108,7 +108,9 @@ export const SubNavHeader = ({
{label}
{searchable && (
- } />
+
+
+
)}
diff --git a/packages/design-system/src/components/Tooltip/Tooltip.tsx b/packages/design-system/src/components/Tooltip/Tooltip.tsx
index 1e320f86e..84fb9998c 100644
--- a/packages/design-system/src/components/Tooltip/Tooltip.tsx
+++ b/packages/design-system/src/components/Tooltip/Tooltip.tsx
@@ -1,69 +1,93 @@
import * as React from 'react';
-import { styled } from 'styled-components';
+import * as Tooltip from '@radix-ui/react-tooltip';
+import { keyframes, styled } from 'styled-components';
-import { useId } from '../../hooks/useId';
-import { VisuallyHidden } from '../../utilities/VisuallyHidden';
-import { Box, BoxComponent, BoxProps } from '../Box';
-import { Portal } from '../Portal';
import { Typography } from '../Typography';
-import { useTooltipHandlers } from './hooks/useTooltipHandlers';
-import { useTooltipLayout } from './hooks/useTooltipLayout';
-import { TooltipPosition } from './utils/positionTooltip';
+type TooltipElement = HTMLDivElement;
-interface TooltipProps extends Omit, 'position'> {
+interface TooltipProps extends Tooltip.TooltipContentProps {
+ children?: React.ReactNode;
+ defaultOpen?: boolean;
+ /**
+ * The duration from when the pointer enters the trigger until the tooltip gets opened. This will
+ * override the prop with the same name passed to Provider.
+ * @default 500
+ */
+ delayDuration?: number;
+ /**
+ * @deprecated Use `label` instead.
+ */
description?: string;
- delay?: number;
- id?: string;
+ /**
+ * When `true`, trying to hover the content will result in the tooltip closing as the pointer leaves the trigger.
+ * @default false
+ */
+ disableHoverableContent?: boolean;
label?: React.ReactNode;
- position?: TooltipPosition;
+ onOpenChange?: (open: boolean) => void;
+ open?: boolean;
}
-const Tooltip = ({ children, label, description, delay = 500, position = 'top', id, ...props }: TooltipProps) => {
- const tooltipId = useId(id);
- const descriptionId = useId();
- const { visible, ...tooltipHandlers } = useTooltipHandlers(delay);
- const { tooltipWrapperRef, toggleSourceRef } = useTooltipLayout(visible, position);
+const TooltipImpl = React.forwardRef(
+ (
+ {
+ children,
+ description,
+ label,
+ defaultOpen,
+ open,
+ onOpenChange,
+ delayDuration = 500,
+ disableHoverableContent,
+ ...restProps
+ },
+ forwardedRef,
+ ) => {
+ return (
+
+ {children}
+
+
+
+ {label || description}
+
+
+
+
+ );
+ },
+);
- const childrenClone = React.cloneElement(children as React.ReactElement, {
- tabIndex: 0,
- 'aria-labelledby': label ? tooltipId : undefined,
- 'aria-describedby': description ? tooltipId : undefined,
- ...tooltipHandlers,
- });
-
- return (
- <>
-
-
- {visible && {description} }
-
- {label || description}
-
-
-
+const fadeIn = keyframes`
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+`;
- {childrenClone}
- >
- );
-};
+const TooltipContent = styled(Tooltip.Content)`
+ background-color: ${(props) => props.theme.colors.neutral900};
+ color: ${(props) => props.theme.colors.neutral0};
+ padding-inline: ${(props) => props.theme.spaces[2]};
+ padding-block: ${(props) => props.theme.spaces[2]};
+ border-radius: ${(props) => props.theme.borderRadius};
+ will-change: opacity;
+ transform-origin: var(--radix-tooltip-content-transform-origin);
-const TooltipWrapper = styled(Box)<{ $visible: boolean }>`
- /* z-index exist because of its position inside Modals */
- z-index: 4;
- display: ${({ $visible }) => ($visible ? 'revert' : 'none')};
+ @media (prefers-reduced-motion: no-preference) {
+ animation: ${fadeIn} 200ms ${(props) => props.theme.easings.authenticMotion};
+ }
`;
-export { Tooltip };
-export type { TooltipProps };
+export { TooltipImpl as Tooltip };
+export type { TooltipProps, TooltipElement };
diff --git a/packages/design-system/src/components/Tooltip/__tests__/Tooltip.test.tsx b/packages/design-system/src/components/Tooltip/__tests__/Tooltip.test.tsx
deleted file mode 100644
index d8526b14b..000000000
--- a/packages/design-system/src/components/Tooltip/__tests__/Tooltip.test.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { render, fireEvent, screen } from '@test/utils';
-
-import { Tooltip } from '../Tooltip';
-
-describe('Tooltip', () => {
- it('snapshots document.body when the tooltip is not visible but exists in the DOM', () => {
- render(
-
- Show tooltip
- ,
- );
-
- expect(document.body).toMatchSnapshot();
- });
-
- it('snapshots document.body when the button is focused (aria-describedby exists)', () => {
- render(
-
- Show tooltip
- ,
- );
-
- fireEvent.focus(screen.getByText('Show tooltip'));
-
- expect(document.body).toMatchSnapshot();
- });
-
- it('snapshots document.body with a label', () => {
- render(
-
- +
- ,
- );
-
- fireEvent.focus(screen.getByText('+'));
-
- expect(document.body).toMatchSnapshot();
- });
-});
diff --git a/packages/design-system/src/components/Tooltip/__tests__/__snapshots__/Tooltip.test.tsx.snap b/packages/design-system/src/components/Tooltip/__tests__/__snapshots__/Tooltip.test.tsx.snap
deleted file mode 100644
index 1b77ab334..000000000
--- a/packages/design-system/src/components/Tooltip/__tests__/__snapshots__/Tooltip.test.tsx.snap
+++ /dev/null
@@ -1,265 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Tooltip snapshots document.body when the button is focused (aria-describedby exists) 1`] = `
-.c0 {
- border: 0;
- clip: rect(0 0 0 0);
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- width: 1px;
-}
-
-.c1 {
- background: #212134;
- padding-block: 8px;
- padding-inline: 8px;
- border-radius: 4px;
- position: absolute;
-}
-
-.c3 {
- font-size: 1.2rem;
- line-height: 1.33;
- font-weight: 600;
- color: #ffffff;
-}
-
-.c2 {
- z-index: 4;
- display: revert;
-}
-
-
-
-
-
- Show tooltip
-
-
-
-
-
-
-
-
-
-
-
- Content of the tooltip fefe
-
-
- Content of the tooltip fefe
-
-
-
-
-`;
-
-exports[`Tooltip snapshots document.body when the tooltip is not visible but exists in the DOM 1`] = `
-.c0 {
- border: 0;
- clip: rect(0 0 0 0);
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- width: 1px;
-}
-
-.c1 {
- background: #212134;
- padding-block: 8px;
- padding-inline: 8px;
- border-radius: 4px;
- position: absolute;
-}
-
-.c3 {
- font-size: 1.2rem;
- line-height: 1.33;
- font-weight: 600;
- color: #ffffff;
-}
-
-.c2 {
- z-index: 4;
- display: none;
-}
-
-
-
-
-
- Show tooltip
-
-
-
-
-
-
-
-
-
-
-
- Content of the tooltip fefe
-
-
-
-
-`;
-
-exports[`Tooltip snapshots document.body with a label 1`] = `
-.c0 {
- border: 0;
- clip: rect(0 0 0 0);
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- width: 1px;
-}
-
-.c1 {
- background: #212134;
- padding-block: 8px;
- padding-inline: 8px;
- border-radius: 4px;
- position: absolute;
-}
-
-.c3 {
- font-size: 1.2rem;
- line-height: 1.33;
- font-weight: 600;
- color: #ffffff;
-}
-
-.c2 {
- z-index: 4;
- display: revert;
-}
-
-
-
-
-
-
-
- Content of the tooltip fefe
-
-
-
-
-`;
diff --git a/packages/design-system/src/components/Tooltip/hooks/useTooltipHandlers.ts b/packages/design-system/src/components/Tooltip/hooks/useTooltipHandlers.ts
deleted file mode 100644
index 658d51ac1..000000000
--- a/packages/design-system/src/components/Tooltip/hooks/useTooltipHandlers.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import * as React from 'react';
-
-export const useTooltipHandlers = (delay: number) => {
- const [visible, setVisible] = React.useState(false);
- const timerRef = React.useRef(null);
-
- const clearTimer = () => {
- if (typeof timerRef.current === 'number') {
- clearTimeout(timerRef.current);
- timerRef.current = null;
- }
- };
-
- React.useEffect(() => {
- return () => {
- clearTimer();
- };
- }, []);
-
- const onFocus = () => {
- setVisible(true);
- };
-
- const onBlur = () => {
- setVisible(false);
- };
-
- const onMouseEnter = () => {
- timerRef.current = setTimeout(() => {
- setVisible(true);
- }, delay);
- };
-
- const onMouseLeave = () => {
- clearTimer();
- setVisible(false);
- };
-
- return { visible, onFocus, onBlur, onMouseEnter, onMouseLeave };
-};
diff --git a/packages/design-system/src/components/Tooltip/hooks/useTooltipLayout.ts b/packages/design-system/src/components/Tooltip/hooks/useTooltipLayout.ts
deleted file mode 100644
index 1066d91d5..000000000
--- a/packages/design-system/src/components/Tooltip/hooks/useTooltipLayout.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import * as React from 'react';
-
-import { positionTooltip, TooltipPosition } from '../utils/positionTooltip';
-
-export const useTooltipLayout = (visible: boolean, position: TooltipPosition) => {
- const tooltipWrapperRef = React.useRef(null);
- const toggleSourceRef = React.useRef(null);
-
- React.useLayoutEffect(() => {
- if (visible) {
- const tooltip = tooltipWrapperRef.current;
- const toggleSource = toggleSourceRef.current;
-
- if (tooltip && toggleSource) {
- const tooltipPosition = positionTooltip(tooltip, toggleSource, position);
-
- tooltip.style.left = `${tooltipPosition.left}px`;
- tooltip.style.top = `${tooltipPosition.top}px`;
- }
- }
- }, [position, visible]);
-
- return { tooltipWrapperRef, toggleSourceRef };
-};
diff --git a/packages/design-system/src/components/Tooltip/utils/__tests__/positionTooltip.spec.ts b/packages/design-system/src/components/Tooltip/utils/__tests__/positionTooltip.spec.ts
deleted file mode 100644
index f2a4f97e4..000000000
--- a/packages/design-system/src/components/Tooltip/utils/__tests__/positionTooltip.spec.ts
+++ /dev/null
@@ -1,114 +0,0 @@
-import { positionTooltip } from '../positionTooltip';
-
-describe('positionTooltip', () => {
- let tooltipNode;
- let toggleSourceNode;
-
- beforeEach(() => {
- tooltipNode = {
- getBoundingClientRect: () => ({ width: 160, height: 40 }),
- };
- toggleSourceNode = {
- getBoundingClientRect: () => ({ left: 500, top: 300, width: 100, height: 30 }),
- };
-
- window.pageYOffset = 800;
- });
-
- it('positions the tooltip at the top of the toggle source', () => {
- const position = positionTooltip(tooltipNode, toggleSourceNode);
-
- expect(position).toEqual({ left: 470, top: 1052 });
- });
-
- it('positions the tooltip at the bottom of the toggle source', () => {
- const position = positionTooltip(tooltipNode, toggleSourceNode, 'bottom');
-
- expect(position).toEqual({ left: 470, top: 1138 });
- });
-
- it('positions the tooltip on the left of the toggle source', () => {
- const position = positionTooltip(tooltipNode, toggleSourceNode, 'left');
-
- expect(position).toEqual({ left: 332, top: 1095 });
- });
-
- it('positions the tooltip on the right of the toggle source', () => {
- const position = positionTooltip(tooltipNode, toggleSourceNode, 'right');
-
- expect(position).toEqual({ left: 608, top: 1095 });
- });
-
- it('positions the tooltip on the right of the toggle source when toggle source pos is top-left', () => {
- toggleSourceNode = {
- getBoundingClientRect: () => ({ left: 15, top: 15, width: 50, height: 20 }),
- };
- window.pageYOffset = 0;
-
- const position = positionTooltip(tooltipNode, toggleSourceNode);
-
- expect(position).toEqual({ left: 73, top: 3 });
- });
-
- it('positions the tooltip on the right of the toggle source when toggle source pos is bottom-left', () => {
- toggleSourceNode = {
- getBoundingClientRect: () => ({ left: 15, top: 760, width: 50, height: 20 }),
- };
-
- window.pageYOffset = 0;
- window.innerHeight = 800;
-
- const position = positionTooltip(tooltipNode, toggleSourceNode);
-
- expect(position).toEqual({ left: 73, top: 748 });
- });
-
- it('positions the tooltip below the toggle source when toggle source pos is top-center', () => {
- toggleSourceNode = {
- getBoundingClientRect: () => ({ left: 400, top: 15, width: 50, height: 20 }),
- };
- window.pageYOffset = 0;
- window.innerWidth = 800;
-
- const position = positionTooltip(tooltipNode, toggleSourceNode);
-
- expect(position).toEqual({ left: 345, top: 43 });
- });
-
- it('positions the tooltip above the toggle source when toggle source pos is bottom-center', () => {
- toggleSourceNode = {
- getBoundingClientRect: () => ({ left: 400, top: 760, width: 50, height: 20 }),
- };
- window.pageYOffset = 0;
- window.innerWidth = 800;
-
- const position = positionTooltip(tooltipNode, toggleSourceNode);
-
- expect(position).toEqual({ left: 345, top: 712 });
- });
-
- it('positions the tooltip on the left of the toggle source when toggle source pos is top-right', () => {
- toggleSourceNode = {
- getBoundingClientRect: () => ({ left: 750, right: 800, top: 15, width: 50, height: 20 }),
- };
- window.innerWidth = 800;
- window.pageYOffset = 0;
-
- const position = positionTooltip(tooltipNode, toggleSourceNode);
-
- expect(position).toEqual({ left: 582, top: 5 });
- });
-
- it('positions the tooltip on the left of the toggle source when toggle source pos is bottom-right', () => {
- toggleSourceNode = {
- getBoundingClientRect: () => ({ left: 750, right: 800, top: 760, width: 50, height: 20 }),
- };
- window.innerWidth = 800;
- window.innerHeight = 800;
- window.pageYOffset = 0;
-
- const position = positionTooltip(tooltipNode, toggleSourceNode);
-
- expect(position).toEqual({ left: 582, top: 750 });
- });
-});
diff --git a/packages/design-system/src/components/Tooltip/utils/positionTooltip.ts b/packages/design-system/src/components/Tooltip/utils/positionTooltip.ts
deleted file mode 100644
index 8b258e6f4..000000000
--- a/packages/design-system/src/components/Tooltip/utils/positionTooltip.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-export type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';
-
-const SPACE_BETWEEN = 8;
-
-const positionBottom = (tooltipRect: DOMRect, toggleSourceRect: DOMRect) => {
- const widthDifference = (tooltipRect.width - toggleSourceRect.width) / 2;
- const left = toggleSourceRect.left - widthDifference;
- const top = toggleSourceRect.top + toggleSourceRect.height + SPACE_BETWEEN + window.pageYOffset;
-
- return {
- left,
- top,
- };
-};
-
-const positionRight = (tooltipRect: DOMRect, toggleSourceRect: DOMRect) => {
- const heightDifference = (tooltipRect.height - toggleSourceRect.height) / 2;
- const left = toggleSourceRect.left + toggleSourceRect.width + SPACE_BETWEEN;
- const top = toggleSourceRect.top - heightDifference + window.pageYOffset;
-
- return { left, top };
-};
-
-const positionLeft = (tooltipRect: DOMRect, toggleSourceRect: DOMRect) => {
- const heightDifference = (tooltipRect.height - toggleSourceRect.height) / 2;
- const left = toggleSourceRect.left - tooltipRect.width - SPACE_BETWEEN;
- const top = toggleSourceRect.top - heightDifference + window.pageYOffset;
-
- return { left, top };
-};
-
-const positionTop = (tooltipRect: DOMRect, toggleSourceRect: DOMRect) => {
- const widthDifference = (tooltipRect.width - toggleSourceRect.width) / 2;
- let left = toggleSourceRect.left - widthDifference;
- let top = toggleSourceRect.top - tooltipRect.height - SPACE_BETWEEN + window.pageYOffset;
-
- // CONDITIONS TO HANDLE TOOLTIP OVERFLOW OUT OF VIEWPORT
-
- // calculate the space between rightside viewport to rightside source element
- // knowing this space will help calculate if tooltip will overflow right side
- const rightSpaceDifference = window.innerWidth - toggleSourceRect.right;
-
- // calculate rightside pos of tooltip to compare later to window.innerWidth
- const overflowRight = toggleSourceRect.left + tooltipRect.width - rightSpaceDifference;
-
- if (overflowRight > window.innerWidth) {
- // if tooltip overflow right side of viewport
- // place tooltip left side from source element
- left = toggleSourceRect.left - tooltipRect.width - SPACE_BETWEEN;
- top = toggleSourceRect.top + window.scrollY - toggleSourceRect.height / 2;
- } else if (left < 0) {
- // if overflow left
- // place tooltip right side from source element
- left = toggleSourceRect.width + toggleSourceRect.left + SPACE_BETWEEN;
- top = toggleSourceRect.top + window.scrollY - tooltipRect.height / 2 + SPACE_BETWEEN;
- } else if (top < 0 && left > 0) {
- // if overflow top but not left
- // place tooltip below source element
- top = toggleSourceRect.top + toggleSourceRect.height + SPACE_BETWEEN;
- }
-
- return {
- left,
- top,
- };
-};
-
-export const positionTooltip = (
- tooltipNode: HTMLDivElement,
- toggleSourceNode: HTMLSpanElement,
- position?: TooltipPosition,
-) => {
- const tooltipRect = tooltipNode.getBoundingClientRect();
- const toggleSourceRect = toggleSourceNode.getBoundingClientRect();
-
- if (position === 'bottom') {
- return positionBottom(tooltipRect, toggleSourceRect);
- }
-
- if (position === 'right') {
- return positionRight(tooltipRect, toggleSourceRect);
- }
-
- if (position === 'left') {
- return positionLeft(tooltipRect, toggleSourceRect);
- }
-
- return positionTop(tooltipRect, toggleSourceRect);
-};
diff --git a/packages/design-system/src/utilities/DesignSystemProvider.tsx b/packages/design-system/src/utilities/DesignSystemProvider.tsx
index bab00ed48..bccb0b8c0 100644
--- a/packages/design-system/src/utilities/DesignSystemProvider.tsx
+++ b/packages/design-system/src/utilities/DesignSystemProvider.tsx
@@ -1,3 +1,4 @@
+import { Provider as TooltipProvider, TooltipProviderProps } from '@radix-ui/react-tooltip';
import { DefaultTheme, ThemeProvider } from 'styled-components';
import { LiveRegions } from '../components/LiveRegions';
@@ -30,17 +31,19 @@ const [Provider, useDesignSystem] = createContext('Str
interface DesignSystemProviderProps extends Partial {
children?: React.ReactNode;
theme?: DefaultTheme;
+ tooltipConfig?: Omit;
}
const DesignSystemProvider = ({
+ children,
locale = getDefaultLocale(),
theme = lightTheme,
- children,
+ tooltipConfig,
}: DesignSystemProviderProps) => {
return (
- {children}
+ {children}
diff --git a/turbo.json b/turbo.json
index f20ae5bbf..98db104bc 100644
--- a/turbo.json
+++ b/turbo.json
@@ -15,7 +15,6 @@
"persistent": true
},
"develop": {
- "dependsOn": ["^build"],
"cache": false,
"persistent": true
},
diff --git a/yarn.lock b/yarn.lock
index eab687acc..ed90c4f1b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4113,6 +4113,37 @@ __metadata:
languageName: node
linkType: hard
+"@radix-ui/react-tooltip@npm:1.0.7":
+ version: 1.0.7
+ resolution: "@radix-ui/react-tooltip@npm:1.0.7"
+ 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
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 894d448c69a3e4d7626759f9f6c7997018fe8ef9cde098393bd83e10743d493dfd284eef041e46accc45486d5a5cd5f76d97f56afbdace7aed6e0cb14007bf15
+ languageName: node
+ linkType: hard
+
"@radix-ui/react-use-callback-ref@npm:1.0.1, @radix-ui/react-use-callback-ref@npm:^1.0.1":
version: 1.0.1
resolution: "@radix-ui/react-use-callback-ref@npm:1.0.1"
@@ -5301,6 +5332,7 @@ __metadata:
"@radix-ui/react-dismissable-layer": ^1.0.5
"@radix-ui/react-dropdown-menu": ^2.0.6
"@radix-ui/react-focus-scope": 1.0.4
+ "@radix-ui/react-tooltip": 1.0.7
"@radix-ui/react-use-controllable-state": ^1.0.1
"@strapi/icons": ^2.0.0-beta.3
"@strapi/pack-up": ^5.0.0