From 911ffa735a54ecaa5afd9cecc877f5cd7327b0f3 Mon Sep 17 00:00:00 2001 From: Deniz Date: Sun, 23 Oct 2022 22:29:53 +0300 Subject: [PATCH] [@mantine/core] Add arrowRadius support to Tooltip and Popover --- .../Floating/FloatingArrow/FloatingArrow.tsx | 17 +++++++++++++++- .../get-arrow-position-styles.ts | 20 +++++++++++++++++++ .../src/Popover/Popover.context.ts | 1 + .../src/Popover/Popover.story.tsx | 14 +++++++++++++ src/mantine-core/src/Popover/Popover.tsx | 6 ++++++ .../PopoverDropdown/PopoverDropdown.tsx | 1 + .../src/Tooltip/Tooltip.story.tsx | 10 ++++++++++ src/mantine-core/src/Tooltip/Tooltip.tsx | 6 ++++++ .../demos/core/Tooltip/Tooltip.demo.arrow.tsx | 7 +++++++ 9 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/mantine-core/src/Floating/FloatingArrow/FloatingArrow.tsx b/src/mantine-core/src/Floating/FloatingArrow/FloatingArrow.tsx index 320cf49166d..541e8f0ce28 100644 --- a/src/mantine-core/src/Floating/FloatingArrow/FloatingArrow.tsx +++ b/src/mantine-core/src/Floating/FloatingArrow/FloatingArrow.tsx @@ -8,13 +8,27 @@ interface FloatingArrowProps extends React.ComponentPropsWithoutRef<'div'> { position: FloatingPosition; arrowSize: number; arrowOffset: number; + arrowRadius: number; arrowX: number; arrowY: number; visible: boolean; } export const FloatingArrow = forwardRef( - ({ withBorder, position, arrowSize, arrowOffset, visible, arrowX, arrowY, ...others }, ref) => { + ( + { + withBorder, + position, + arrowSize, + arrowOffset, + arrowRadius, + visible, + arrowX, + arrowY, + ...others + }, + ref + ) => { const theme = useMantineTheme(); if (!visible) { @@ -30,6 +44,7 @@ export const FloatingArrow = forwardRef( position, arrowSize, arrowOffset, + arrowRadius, dir: theme.dir, arrowX, arrowY, diff --git a/src/mantine-core/src/Floating/FloatingArrow/get-arrow-position-styles.ts b/src/mantine-core/src/Floating/FloatingArrow/get-arrow-position-styles.ts index 765c878d5df..39f5cee574d 100644 --- a/src/mantine-core/src/Floating/FloatingArrow/get-arrow-position-styles.ts +++ b/src/mantine-core/src/Floating/FloatingArrow/get-arrow-position-styles.ts @@ -1,3 +1,4 @@ +import { CSSObject } from '@mantine/styles'; import type { FloatingPosition, FloatingSide, FloatingPlacement } from '../types'; function horizontalSide( @@ -41,11 +42,28 @@ function verticalSide( return {}; } +const radiusByFloatingSide: Record< + FloatingSide, + keyof Pick< + CSSObject, + | 'borderBottomLeftRadius' + | 'borderBottomRightRadius' + | 'borderTopLeftRadius' + | 'borderTopRightRadius' + > +> = { + bottom: 'borderTopLeftRadius', + left: 'borderTopRightRadius', + right: 'borderBottomLeftRadius', + top: 'borderBottomRightRadius', +}; + export function getArrowPositionStyles({ position, withBorder, arrowSize, arrowOffset, + arrowRadius, arrowX, arrowY, dir, @@ -54,6 +72,7 @@ export function getArrowPositionStyles({ withBorder: boolean; arrowSize: number; arrowOffset: number; + arrowRadius: number; arrowX: number; arrowY: number; dir: 'rtl' | 'ltr'; @@ -64,6 +83,7 @@ export function getArrowPositionStyles({ height: arrowSize, transform: 'rotate(45deg)', position: 'absolute', + [radiusByFloatingSide[side]]: arrowRadius, }; const arrowPosition = withBorder ? -arrowSize / 2 - 1 : -arrowSize / 2; diff --git a/src/mantine-core/src/Popover/Popover.context.ts b/src/mantine-core/src/Popover/Popover.context.ts index 8a8ffc6d35e..3529d2d5b33 100644 --- a/src/mantine-core/src/Popover/Popover.context.ts +++ b/src/mantine-core/src/Popover/Popover.context.ts @@ -22,6 +22,7 @@ interface PopoverContext { withArrow: boolean; arrowSize: number; arrowOffset: number; + arrowRadius: number; trapFocus: boolean; placement: FloatingPosition; withinPortal: boolean; diff --git a/src/mantine-core/src/Popover/Popover.story.tsx b/src/mantine-core/src/Popover/Popover.story.tsx index df59da94d4d..077dfc6c556 100644 --- a/src/mantine-core/src/Popover/Popover.story.tsx +++ b/src/mantine-core/src/Popover/Popover.story.tsx @@ -49,6 +49,20 @@ export function WithArrow() { ); } +export function WithArrowRadius() { + return ( +
+ + + + + + Dropdown with arrow radius + +
+ ); +} + export function Controlled() { const [opened, setState] = useState(false); diff --git a/src/mantine-core/src/Popover/Popover.tsx b/src/mantine-core/src/Popover/Popover.tsx index fca3bcaae53..2fd238d14c5 100644 --- a/src/mantine-core/src/Popover/Popover.tsx +++ b/src/mantine-core/src/Popover/Popover.tsx @@ -68,6 +68,9 @@ export interface PopoverBaseProps { /** Arrow offset in px */ arrowOffset?: number; + /** Arrow radius in px */ + arrowRadius?: number; + /** Determines whether dropdown should be rendered within Portal, defaults to false */ withinPortal?: boolean; @@ -133,6 +136,7 @@ const defaultProps: Partial = { middlewares: { flip: true, shift: true, inline: false }, arrowSize: 7, arrowOffset: 5, + arrowRadius: 0, closeOnClickOutside: true, withinPortal: false, closeOnEscape: true, @@ -161,6 +165,7 @@ export function Popover(props: PopoverProps) { withArrow, arrowSize, arrowOffset, + arrowRadius, unstyled, classNames, styles, @@ -253,6 +258,7 @@ export function Popover(props: PopoverProps) { withArrow, arrowSize, arrowOffset, + arrowRadius, placement: popover.floating.placement, trapFocus, withinPortal, diff --git a/src/mantine-core/src/Popover/PopoverDropdown/PopoverDropdown.tsx b/src/mantine-core/src/Popover/PopoverDropdown/PopoverDropdown.tsx index 46d2c52467a..1f43b5d52c9 100644 --- a/src/mantine-core/src/Popover/PopoverDropdown/PopoverDropdown.tsx +++ b/src/mantine-core/src/Popover/PopoverDropdown/PopoverDropdown.tsx @@ -91,6 +91,7 @@ export function PopoverDropdown({ withBorder position={ctx.placement} arrowSize={ctx.arrowSize} + arrowRadius={ctx.arrowRadius} arrowOffset={ctx.arrowOffset} className={classes.arrow} /> diff --git a/src/mantine-core/src/Tooltip/Tooltip.story.tsx b/src/mantine-core/src/Tooltip/Tooltip.story.tsx index 312282ba403..3bc04f4ccd5 100644 --- a/src/mantine-core/src/Tooltip/Tooltip.story.tsx +++ b/src/mantine-core/src/Tooltip/Tooltip.story.tsx @@ -102,6 +102,16 @@ export const WithArrow = () => ( ); +export const WithArrowRadius = () => ( + + + +); + export function Inline() { return (
diff --git a/src/mantine-core/src/Tooltip/Tooltip.tsx b/src/mantine-core/src/Tooltip/Tooltip.tsx index 5bf00ea0177..b4b54b4eb1b 100644 --- a/src/mantine-core/src/Tooltip/Tooltip.tsx +++ b/src/mantine-core/src/Tooltip/Tooltip.tsx @@ -38,6 +38,9 @@ export interface TooltipProps extends TooltipBaseProps { /** Arrow offset in px */ arrowOffset?: number; + /** Arrow radius in px */ + arrowRadius?: number; + /** One of premade transitions ot transition object */ transition?: MantineTransition; @@ -61,6 +64,7 @@ const defaultProps: Partial = { inline: false, arrowSize: 4, arrowOffset: 5, + arrowRadius: 0, offset: 5, transition: 'fade', transitionDuration: 100, @@ -92,6 +96,7 @@ const _Tooltip = forwardRef((props, ref) => { withArrow, arrowSize, arrowOffset, + arrowRadius, offset, transition, transitionDuration, @@ -166,6 +171,7 @@ const _Tooltip = forwardRef((props, ref) => { position={tooltip.placement} arrowSize={arrowSize} arrowOffset={arrowOffset} + arrowRadius={arrowRadius} className={classes.arrow} /> diff --git a/src/mantine-demos/src/demos/core/Tooltip/Tooltip.demo.arrow.tsx b/src/mantine-demos/src/demos/core/Tooltip/Tooltip.demo.arrow.tsx index 8b3b2642150..a4614576522 100644 --- a/src/mantine-demos/src/demos/core/Tooltip/Tooltip.demo.arrow.tsx +++ b/src/mantine-demos/src/demos/core/Tooltip/Tooltip.demo.arrow.tsx @@ -23,6 +23,10 @@ function Demo() { + + + + ); } @@ -51,6 +55,9 @@ export function Demo() { + + + ); }