From 7f70d2d9a46420188761276d38b36feafa1141ea Mon Sep 17 00:00:00 2001 From: sook Date: Sat, 24 Feb 2024 19:51:16 +0900 Subject: [PATCH 1/4] add props.offset to OverlayArrow --- .../overlays/src/calculatePosition.ts | 5 +- .../overlays/src/useOverlayPosition.ts | 2 +- .../overlays/test/calculatePosition.test.ts | 56 ++++- .../react-aria-components/docs/Popover.mdx | 3 +- .../react-aria-components/docs/Tooltip.mdx | 3 +- .../src/OverlayArrow.tsx | 18 +- .../stories/Tooltip.stories.tsx | 193 ++++++++++++++++++ 7 files changed, 274 insertions(+), 6 deletions(-) diff --git a/packages/@react-aria/overlays/src/calculatePosition.ts b/packages/@react-aria/overlays/src/calculatePosition.ts index 13010b09e7f..251dd07b59d 100644 --- a/packages/@react-aria/overlays/src/calculatePosition.ts +++ b/packages/@react-aria/overlays/src/calculatePosition.ts @@ -10,9 +10,12 @@ * governing permissions and limitations under the License. */ -import {Axis, Placement, PlacementAxis, SizeAxis} from '@react-types/overlays'; +import {Axis, PlacementAxis, Placement as PlacementSuperset, SizeAxis} from '@react-types/overlays'; import {clamp, isWebKit} from '@react-aria/utils'; +type Placement = Exclude +export type PlacementSubset = Placement; + interface Position { top?: number, left?: number, diff --git a/packages/@react-aria/overlays/src/useOverlayPosition.ts b/packages/@react-aria/overlays/src/useOverlayPosition.ts index ca6dd4c8d0a..73f51058c3b 100644 --- a/packages/@react-aria/overlays/src/useOverlayPosition.ts +++ b/packages/@react-aria/overlays/src/useOverlayPosition.ts @@ -264,7 +264,7 @@ function useResize(onResize) { }, [onResize]); } -function translateRTL(position, direction) { +export function translateRTL(position, direction) { if (direction === 'rtl') { return position.replace('start', 'right').replace('end', 'left'); } diff --git a/packages/@react-aria/overlays/test/calculatePosition.test.ts b/packages/@react-aria/overlays/test/calculatePosition.test.ts index db8a84d3e2f..9fa9ef669dc 100644 --- a/packages/@react-aria/overlays/test/calculatePosition.test.ts +++ b/packages/@react-aria/overlays/test/calculatePosition.test.ts @@ -10,7 +10,8 @@ * governing permissions and limitations under the License. */ -import {calculatePosition} from '../src/calculatePosition'; +import {calculatePosition, PlacementSubset} from '../src/calculatePosition'; +import {translateRTL} from '../src/useOverlayPosition'; const FLIPPED_DIRECTION = { left: 'right' @@ -418,4 +419,57 @@ describe('calculatePosition', function () { document.body.removeChild(target); }); }); + + describe('arrow offsets', () => { + it('Only one of either `arrowOffsetLeft` or `arrowOffsetTop` should have a value', () => { + const target = document.createElement('div'); + const overlayNode = document.createElement('div'); + const container = document.createElement('div'); + document.body.appendChild(target); + + for (let placement of [ + 'bottom', 'bottom left', 'bottom right', 'bottom start', 'bottom end', + 'top', 'top left', 'top right', 'top start', 'top end', + 'left', 'left top', 'left bottom', + 'right', 'right top', 'right bottom' + ] as PlacementSubset[]) { + let {arrowOffsetLeft, arrowOffsetTop} = calculatePosition({ + placement, + overlayNode, + targetNode: target, + scrollNode: overlayNode, + padding: 0, + shouldFlip: false, + boundaryElement: container, + offset: 0, + crossOffset: 0, + arrowSize: 0 + }); + + expect(['undefined-0', '0-undefined']).toContain(`${arrowOffsetLeft}-${arrowOffsetTop}`); + } + + for (let direction of ['ltr', 'rtl']) { + for (let placement of [ + 'start', 'start top', 'start bottom', + 'end', 'end top', 'end bottom' + ]) { + let {arrowOffsetLeft, arrowOffsetTop} = calculatePosition({ + placement: translateRTL(placement, direction), + overlayNode, + targetNode: target, + scrollNode: overlayNode, + padding: 0, + shouldFlip: false, + boundaryElement: container, + offset: 0, + crossOffset: 0, + arrowSize: 0 + }); + + expect(['undefined-0', '0-undefined']).toContain(`${arrowOffsetLeft}-${arrowOffsetTop}`); + } + } + }); + }); }); diff --git a/packages/react-aria-components/docs/Popover.mdx b/packages/react-aria-components/docs/Popover.mdx index c3bbf7eed35..7e52eee320f 100644 --- a/packages/react-aria-components/docs/Popover.mdx +++ b/packages/react-aria-components/docs/Popover.mdx @@ -386,7 +386,8 @@ function Example() { ### OverlayArrow -`OverlayArrow` accepts all HTML attributes. + +`*` `OverlayArrow` accepts all HTML attributes as well. ## Styling diff --git a/packages/react-aria-components/docs/Tooltip.mdx b/packages/react-aria-components/docs/Tooltip.mdx index dc7c8900279..0b0f3fc1ca7 100644 --- a/packages/react-aria-components/docs/Tooltip.mdx +++ b/packages/react-aria-components/docs/Tooltip.mdx @@ -340,7 +340,8 @@ The `isDisabled` prop can be provided to a TooltipTrigger to disable the tooltip ### OverlayArrow -`OverlayArrow` accepts all HTML attributes. + +`*` `OverlayArrow` accepts all HTML attributes as well. ## Styling diff --git a/packages/react-aria-components/src/OverlayArrow.tsx b/packages/react-aria-components/src/OverlayArrow.tsx index 0d787fc409f..e34c25bca41 100644 --- a/packages/react-aria-components/src/OverlayArrow.tsx +++ b/packages/react-aria-components/src/OverlayArrow.tsx @@ -22,7 +22,12 @@ export const OverlayArrowContext = createContext, 'className' | 'style' | 'children'>, RenderProps {} +export interface OverlayArrowProps extends Omit, 'className' | 'style' | 'children'>, RenderProps { + /** + * The adjustment of the arrow position (in CSS pixel) with respect to the default position on its main axis. + */ + offset?: number +} export interface OverlayArrowRenderProps { /** @@ -54,6 +59,17 @@ function OverlayArrow(props: OverlayArrowProps, ref: ForwardedRef renderProps.style![key] === undefined && delete renderProps.style![key]); } + if (props.offset && renderProps.style) { + if (typeof renderProps.style.top === 'number') { + // direct assignment like `renderProps.style.top += props.offset;` would produce different results, + // depending on whether `props.style` exists or not. (possibly related to `props.style` not being copied in `useRenderProps` but not entirely sure why) + // (e.g.) v.s. would produce different `top` values. + renderProps.style = {...renderProps.style, top: renderProps.style.top + props.offset}; + } else if (typeof renderProps.style.left === 'number') { + renderProps.style = {...renderProps.style, left: renderProps.style.left + props.offset}; + } + } + return (
( ); + +export const TooltipArrowOffestExample = { + render: () => { + return ( +
+
+
+ + + + + + + + + Top left + + +
+
+ + + + + + + + + Top right + + +
+
+
+
+ + + + + + + + + Left top + + +
+
+ + + + + + + + + Left bottom + + +
+
+
+
+ + + + + + + + + Right top + + +
+
+ + + + + + + + + Right bottom + + +
+
+
+
+ + + + + + + + + Bottom left + + +
+
+ + + + + + + + + Bottom right + + +
+
+
+ ); + } +}; From f6f9ae42464fbe1a3c475cf557fdb2e316ea4c27 Mon Sep 17 00:00:00 2001 From: sook Date: Thu, 7 Mar 2024 23:14:20 +0900 Subject: [PATCH 2/4] Revert "add props.offset to OverlayArrow" This reverts commit 7f70d2d9a46420188761276d38b36feafa1141ea. --- .../overlays/src/calculatePosition.ts | 5 +- .../overlays/src/useOverlayPosition.ts | 2 +- .../overlays/test/calculatePosition.test.ts | 56 +---- .../react-aria-components/docs/Popover.mdx | 3 +- .../react-aria-components/docs/Tooltip.mdx | 3 +- .../src/OverlayArrow.tsx | 18 +- .../stories/Tooltip.stories.tsx | 193 ------------------ 7 files changed, 6 insertions(+), 274 deletions(-) diff --git a/packages/@react-aria/overlays/src/calculatePosition.ts b/packages/@react-aria/overlays/src/calculatePosition.ts index 251dd07b59d..13010b09e7f 100644 --- a/packages/@react-aria/overlays/src/calculatePosition.ts +++ b/packages/@react-aria/overlays/src/calculatePosition.ts @@ -10,12 +10,9 @@ * governing permissions and limitations under the License. */ -import {Axis, PlacementAxis, Placement as PlacementSuperset, SizeAxis} from '@react-types/overlays'; +import {Axis, Placement, PlacementAxis, SizeAxis} from '@react-types/overlays'; import {clamp, isWebKit} from '@react-aria/utils'; -type Placement = Exclude -export type PlacementSubset = Placement; - interface Position { top?: number, left?: number, diff --git a/packages/@react-aria/overlays/src/useOverlayPosition.ts b/packages/@react-aria/overlays/src/useOverlayPosition.ts index 73f51058c3b..ca6dd4c8d0a 100644 --- a/packages/@react-aria/overlays/src/useOverlayPosition.ts +++ b/packages/@react-aria/overlays/src/useOverlayPosition.ts @@ -264,7 +264,7 @@ function useResize(onResize) { }, [onResize]); } -export function translateRTL(position, direction) { +function translateRTL(position, direction) { if (direction === 'rtl') { return position.replace('start', 'right').replace('end', 'left'); } diff --git a/packages/@react-aria/overlays/test/calculatePosition.test.ts b/packages/@react-aria/overlays/test/calculatePosition.test.ts index 9fa9ef669dc..db8a84d3e2f 100644 --- a/packages/@react-aria/overlays/test/calculatePosition.test.ts +++ b/packages/@react-aria/overlays/test/calculatePosition.test.ts @@ -10,8 +10,7 @@ * governing permissions and limitations under the License. */ -import {calculatePosition, PlacementSubset} from '../src/calculatePosition'; -import {translateRTL} from '../src/useOverlayPosition'; +import {calculatePosition} from '../src/calculatePosition'; const FLIPPED_DIRECTION = { left: 'right' @@ -419,57 +418,4 @@ describe('calculatePosition', function () { document.body.removeChild(target); }); }); - - describe('arrow offsets', () => { - it('Only one of either `arrowOffsetLeft` or `arrowOffsetTop` should have a value', () => { - const target = document.createElement('div'); - const overlayNode = document.createElement('div'); - const container = document.createElement('div'); - document.body.appendChild(target); - - for (let placement of [ - 'bottom', 'bottom left', 'bottom right', 'bottom start', 'bottom end', - 'top', 'top left', 'top right', 'top start', 'top end', - 'left', 'left top', 'left bottom', - 'right', 'right top', 'right bottom' - ] as PlacementSubset[]) { - let {arrowOffsetLeft, arrowOffsetTop} = calculatePosition({ - placement, - overlayNode, - targetNode: target, - scrollNode: overlayNode, - padding: 0, - shouldFlip: false, - boundaryElement: container, - offset: 0, - crossOffset: 0, - arrowSize: 0 - }); - - expect(['undefined-0', '0-undefined']).toContain(`${arrowOffsetLeft}-${arrowOffsetTop}`); - } - - for (let direction of ['ltr', 'rtl']) { - for (let placement of [ - 'start', 'start top', 'start bottom', - 'end', 'end top', 'end bottom' - ]) { - let {arrowOffsetLeft, arrowOffsetTop} = calculatePosition({ - placement: translateRTL(placement, direction), - overlayNode, - targetNode: target, - scrollNode: overlayNode, - padding: 0, - shouldFlip: false, - boundaryElement: container, - offset: 0, - crossOffset: 0, - arrowSize: 0 - }); - - expect(['undefined-0', '0-undefined']).toContain(`${arrowOffsetLeft}-${arrowOffsetTop}`); - } - } - }); - }); }); diff --git a/packages/react-aria-components/docs/Popover.mdx b/packages/react-aria-components/docs/Popover.mdx index 7e52eee320f..c3bbf7eed35 100644 --- a/packages/react-aria-components/docs/Popover.mdx +++ b/packages/react-aria-components/docs/Popover.mdx @@ -386,8 +386,7 @@ function Example() { ### OverlayArrow - -`*` `OverlayArrow` accepts all HTML attributes as well. +`OverlayArrow` accepts all HTML attributes. ## Styling diff --git a/packages/react-aria-components/docs/Tooltip.mdx b/packages/react-aria-components/docs/Tooltip.mdx index 0b0f3fc1ca7..dc7c8900279 100644 --- a/packages/react-aria-components/docs/Tooltip.mdx +++ b/packages/react-aria-components/docs/Tooltip.mdx @@ -340,8 +340,7 @@ The `isDisabled` prop can be provided to a TooltipTrigger to disable the tooltip ### OverlayArrow - -`*` `OverlayArrow` accepts all HTML attributes as well. +`OverlayArrow` accepts all HTML attributes. ## Styling diff --git a/packages/react-aria-components/src/OverlayArrow.tsx b/packages/react-aria-components/src/OverlayArrow.tsx index e34c25bca41..0d787fc409f 100644 --- a/packages/react-aria-components/src/OverlayArrow.tsx +++ b/packages/react-aria-components/src/OverlayArrow.tsx @@ -22,12 +22,7 @@ export const OverlayArrowContext = createContext, 'className' | 'style' | 'children'>, RenderProps { - /** - * The adjustment of the arrow position (in CSS pixel) with respect to the default position on its main axis. - */ - offset?: number -} +export interface OverlayArrowProps extends Omit, 'className' | 'style' | 'children'>, RenderProps {} export interface OverlayArrowRenderProps { /** @@ -59,17 +54,6 @@ function OverlayArrow(props: OverlayArrowProps, ref: ForwardedRef renderProps.style![key] === undefined && delete renderProps.style![key]); } - if (props.offset && renderProps.style) { - if (typeof renderProps.style.top === 'number') { - // direct assignment like `renderProps.style.top += props.offset;` would produce different results, - // depending on whether `props.style` exists or not. (possibly related to `props.style` not being copied in `useRenderProps` but not entirely sure why) - // (e.g.) v.s. would produce different `top` values. - renderProps.style = {...renderProps.style, top: renderProps.style.top + props.offset}; - } else if (typeof renderProps.style.left === 'number') { - renderProps.style = {...renderProps.style, left: renderProps.style.left + props.offset}; - } - } - return (
( ); - -export const TooltipArrowOffestExample = { - render: () => { - return ( -
-
-
- - - - - - - - - Top left - - -
-
- - - - - - - - - Top right - - -
-
-
-
- - - - - - - - - Left top - - -
-
- - - - - - - - - Left bottom - - -
-
-
-
- - - - - - - - - Right top - - -
-
- - - - - - - - - Right bottom - - -
-
-
-
- - - - - - - - - Bottom left - - -
-
- - - - - - - - - Bottom right - - -
-
-
- ); - } -}; From b2c84ab222b49eb5d01506944323b060551bb6fc Mon Sep 17 00:00:00 2001 From: sook Date: Thu, 7 Mar 2024 23:57:11 +0900 Subject: [PATCH 3/4] fix revised --- .../react-aria-components/src/Popover.tsx | 21 +- .../react-aria-components/src/Tooltip.tsx | 23 +- .../stories/Popover.stories.tsx | 217 +++++++++++++++++- .../stories/Tooltip.stories.tsx | 201 ++++++++++++++++ 4 files changed, 451 insertions(+), 11 deletions(-) diff --git a/packages/react-aria-components/src/Popover.tsx b/packages/react-aria-components/src/Popover.tsx index 058ae05b4a9..cceb6bd1117 100644 --- a/packages/react-aria-components/src/Popover.tsx +++ b/packages/react-aria-components/src/Popover.tsx @@ -12,13 +12,13 @@ import {AriaPopoverProps, DismissButton, Overlay, PlacementAxis, PositionProps, usePopover} from 'react-aria'; import {ContextValue, forwardRefType, HiddenContext, RenderProps, SlotProps, useContextProps, useEnterAnimation, useExitAnimation, useRenderProps} from './utils'; -import {filterDOMProps, mergeProps} from '@react-aria/utils'; +import {filterDOMProps, mergeProps, useLayoutEffect} from '@react-aria/utils'; import {OverlayArrowContext} from './OverlayArrow'; import {OverlayTriggerProps, OverlayTriggerState, useOverlayTriggerState} from 'react-stately'; import {OverlayTriggerStateContext} from './Dialog'; -import React, {createContext, ForwardedRef, forwardRef, RefObject, useContext} from 'react'; +import React, {createContext, ForwardedRef, forwardRef, RefObject, useContext, useRef, useState} from 'react'; -export interface PopoverProps extends Omit, Omit, OverlayTriggerProps, RenderProps, SlotProps { +export interface PopoverProps extends Omit, Omit, OverlayTriggerProps, RenderProps, SlotProps { /** * The name of the component that triggered the popover. This is reflected on the element * as the `data-trigger` attribute, and can be used to provide specific @@ -130,9 +130,20 @@ interface PopoverInnerProps extends AriaPopoverProps, RenderProps(null); + let [arrowWidth, setArrowWidth] = useState(0); + useLayoutEffect(() => { + if (arrowRef.current && state.isOpen) { + setArrowWidth(arrowRef.current.getBoundingClientRect().width); + } + }, [state.isOpen, arrowRef]); + let {popoverProps, underlayProps, arrowProps, placement} = usePopover({ ...props, - offset: props.offset ?? 8 + offset: props.offset ?? 8, + arrowSize: arrowWidth }, state); let ref = props.popoverRef as RefObject; @@ -164,7 +175,7 @@ function PopoverInner({state, isExiting, UNSTABLE_portalContainer, ...props}: Po data-entering={isEntering || undefined} data-exiting={isExiting || undefined}> {!props.isNonModal && } - + {renderProps.children} diff --git a/packages/react-aria-components/src/Tooltip.tsx b/packages/react-aria-components/src/Tooltip.tsx index 31a9895df9d..b3e77c29f85 100644 --- a/packages/react-aria-components/src/Tooltip.tsx +++ b/packages/react-aria-components/src/Tooltip.tsx @@ -11,18 +11,19 @@ */ import {AriaLabelingProps, FocusableElement} from '@react-types/shared'; +import {AriaPositionProps, mergeProps, OverlayContainer, PlacementAxis, PositionProps, useOverlayPosition, useTooltip, useTooltipTrigger} from 'react-aria'; import {ContextValue, forwardRefType, Provider, RenderProps, useContextProps, useEnterAnimation, useExitAnimation, useRenderProps} from './utils'; import {FocusableProvider} from '@react-aria/focus'; -import {mergeProps, OverlayContainer, PlacementAxis, PositionProps, useOverlayPosition, useTooltip, useTooltipTrigger} from 'react-aria'; import {OverlayArrowContext} from './OverlayArrow'; import {OverlayTriggerProps, TooltipTriggerProps, TooltipTriggerState, useTooltipTriggerState} from 'react-stately'; -import React, {createContext, ForwardedRef, forwardRef, ReactNode, RefObject, useContext, useRef} from 'react'; +import React, {createContext, ForwardedRef, forwardRef, ReactNode, RefObject, useContext, useRef, useState} from 'react'; +import {useLayoutEffect} from '@react-aria/utils'; export interface TooltipTriggerComponentProps extends TooltipTriggerProps { children: ReactNode } -export interface TooltipProps extends PositionProps, OverlayTriggerProps, AriaLabelingProps, RenderProps { +export interface TooltipProps extends PositionProps, Pick, OverlayTriggerProps, AriaLabelingProps, RenderProps { /** * The ref for the element which the tooltip positions itself with respect to. * @@ -118,13 +119,25 @@ export {_Tooltip as Tooltip}; function TooltipInner(props: TooltipProps & {isExiting: boolean, tooltipRef: RefObject}) { let state = useContext(TooltipTriggerStateContext)!; + // Calculate the arrow size internally + // Referenced from: packages/@react-spectrum/tooltip/src/TooltipTrigger.tsx + let arrowRef = useRef(null); + let [arrowWidth, setArrowWidth] = useState(0); + useLayoutEffect(() => { + if (arrowRef.current && state.isOpen) { + setArrowWidth(arrowRef.current.getBoundingClientRect().width); + } + }, [state.isOpen, arrowRef]); + let {overlayProps, arrowProps, placement} = useOverlayPosition({ placement: props.placement || 'top', targetRef: props.triggerRef!, overlayRef: props.tooltipRef, offset: props.offset, crossOffset: props.crossOffset, - isOpen: state.isOpen + isOpen: state.isOpen, + arrowSize: arrowWidth, + arrowBoundaryOffset: props.arrowBoundaryOffset }); let isEntering = useEnterAnimation(props.tooltipRef, !!placement) || props.isEntering || false; @@ -151,7 +164,7 @@ function TooltipInner(props: TooltipProps & {isExiting: boolean, tooltipRef: Ref data-placement={placement} data-entering={isEntering || undefined} data-exiting={props.isExiting || undefined}> - + {renderProps.children}
diff --git a/packages/react-aria-components/stories/Popover.stories.tsx b/packages/react-aria-components/stories/Popover.stories.tsx index 343de0f34a7..c98bae7fbde 100644 --- a/packages/react-aria-components/stories/Popover.stories.tsx +++ b/packages/react-aria-components/stories/Popover.stories.tsx @@ -10,7 +10,7 @@ * governing permissions and limitations under the License. */ -import {Button, Dialog, DialogTrigger, Heading, Popover} from 'react-aria-components'; +import {Button, Dialog, DialogTrigger, Heading, OverlayArrow, Popover} from 'react-aria-components'; import React from 'react'; export default { @@ -48,3 +48,218 @@ export const PopoverExample = () => ( ); + +export const PopoverArrowBoundaryOffsetExample = () => { + return ( +
+
+
+ + + + + + + + + +
Top left
+
+
+
+
+
+ + + + + + + + + +
Top right
+
+
+
+
+
+
+
+ + + + + + + + + +
Left top
+
+
+
+
+
+ + + + + + + + + +
Left bottom
+
+
+
+
+
+
+
+ + + + + + + + + +
Right top
+
+
+
+
+
+ + + + + + + + + +
Right bottom
+
+
+
+
+
+
+
+ + + + + + + + + +
Bottom left
+
+
+
+
+
+ + + + + + + + + +
Bottom right
+
+
+
+
+
+
+ ); +}; diff --git a/packages/react-aria-components/stories/Tooltip.stories.tsx b/packages/react-aria-components/stories/Tooltip.stories.tsx index 0392c09dd5e..9f20da05878 100644 --- a/packages/react-aria-components/stories/Tooltip.stories.tsx +++ b/packages/react-aria-components/stories/Tooltip.stories.tsx @@ -38,3 +38,204 @@ export const TooltipExample = () => ( ); + +export const TooltipArrowBoundaryOffsetExample = { + render: () => { + return ( +
+
+
+ + + + + + + + + Top left + + +
+
+ + + + + + + + + Top right + + +
+
+
+
+ + + + + + + + + Left top + + +
+
+ + + + + + + + + Left bottom + + +
+
+
+
+ + + + + + + + + Right top + + +
+
+ + + + + + + + + Right bottom + + +
+
+
+
+ + + + + + + + + Bottom left + + +
+
+ + + + + + + + + Bottom right + + +
+
+
+ ); + } +}; From 893afdb7c065acf29d090f56ae3989eaa85feb32 Mon Sep 17 00:00:00 2001 From: sook Date: Sat, 9 Mar 2024 18:58:44 +0900 Subject: [PATCH 4/4] add offset controllers to the stories --- .../stories/Popover.stories.tsx | 484 ++++++++++-------- .../stories/Tooltip.stories.tsx | 100 +++- 2 files changed, 359 insertions(+), 225 deletions(-) diff --git a/packages/react-aria-components/stories/Popover.stories.tsx b/packages/react-aria-components/stories/Popover.stories.tsx index c98bae7fbde..327a334b358 100644 --- a/packages/react-aria-components/stories/Popover.stories.tsx +++ b/packages/react-aria-components/stories/Popover.stories.tsx @@ -49,217 +49,285 @@ export const PopoverExample = () => ( ); -export const PopoverArrowBoundaryOffsetExample = () => { - return ( -
-
-
- - - - - - - - - -
Top left
-
-
-
+export const PopoverArrowBoundaryOffsetExample = { + argTypes: { + topLeft: { + defaultValue: 25, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + topRight: { + defaultValue: 25, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + leftTop: { + defaultValue: 15, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + leftBotton: { + defaultValue: 15, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + rightTop: { + defaultValue: 15, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + rightBottom: { + defaultValue: 15, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + bottomLeft: { + defaultValue: 25, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + bottomRight: { + defaultValue: 25, + control: { + type: 'range', + min: -100, + max: 100 + } + } + }, + render: ({topLeft, topRight, leftTop, leftBotton, rightTop, rightBottom, bottomLeft, bottomRight}: any) => { + return ( +
+
+
+ + + + + + + + + +
Top left
+
+
+
+
+
+ + + + + + + + + +
Top right
+
+
+
+
-
- - - - - - - - - -
Top right
-
-
-
+
+
+ + + + + + + + + +
Left top
+
+
+
+
+
+ + + + + + + + + +
Left bottom
+
+
+
+
-
-
-
- - - - - - - - - -
Left top
-
-
-
-
-
- - - - - - - - - -
Left bottom
-
-
-
-
-
-
-
- - - - - - - - - -
Right top
-
-
-
-
-
- - - - - - - - - -
Right bottom
-
-
-
-
-
-
-
- - - - - - - - - -
Bottom left
-
-
-
+
+
+ + + + + + + + + +
Right top
+
+
+
+
+
+ + + + + + + + + +
Right bottom
+
+
+
+
-
- - - - - - - - - -
Bottom right
-
-
-
+
+
+ + + + + + + + + +
Bottom left
+
+
+
+
+
+ + + + + + + + + +
Bottom right
+
+
+
+
-
- ); + ); + } }; diff --git a/packages/react-aria-components/stories/Tooltip.stories.tsx b/packages/react-aria-components/stories/Tooltip.stories.tsx index 9f20da05878..f0c5415e4a2 100644 --- a/packages/react-aria-components/stories/Tooltip.stories.tsx +++ b/packages/react-aria-components/stories/Tooltip.stories.tsx @@ -40,17 +40,83 @@ export const TooltipExample = () => ( ); export const TooltipArrowBoundaryOffsetExample = { - render: () => { + argTypes: { + topLeft: { + defaultValue: 25, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + topRight: { + defaultValue: 25, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + leftTop: { + defaultValue: 15, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + leftBotton: { + defaultValue: 15, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + rightTop: { + defaultValue: 15, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + rightBottom: { + defaultValue: 15, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + bottomLeft: { + defaultValue: 25, + control: { + type: 'range', + min: -100, + max: 100 + } + }, + bottomRight: { + defaultValue: 25, + control: { + type: 'range', + min: -100, + max: 100 + } + } + }, + render: ({topLeft, topRight, leftTop, leftBotton, rightTop, rightBottom, bottomLeft, bottomRight}: any) => { return (
- +
- +
- +
- +
- +
- +
- +
- +