Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[@mantine/core] Add arrowRadius support to Tooltip and Popover #2779

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/mantine-core/src/Floating/FloatingArrow/FloatingArrow.tsx
Expand Up @@ -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<HTMLDivElement, FloatingArrowProps>(
({ withBorder, position, arrowSize, arrowOffset, visible, arrowX, arrowY, ...others }, ref) => {
(
{
withBorder,
position,
arrowSize,
arrowOffset,
arrowRadius,
visible,
arrowX,
arrowY,
...others
},
ref
) => {
const theme = useMantineTheme();

if (!visible) {
Expand All @@ -30,6 +44,7 @@ export const FloatingArrow = forwardRef<HTMLDivElement, FloatingArrowProps>(
position,
arrowSize,
arrowOffset,
arrowRadius,
dir: theme.dir,
arrowX,
arrowY,
Expand Down
@@ -1,3 +1,4 @@
import { CSSObject } from '@mantine/styles';
import type { FloatingPosition, FloatingSide, FloatingPlacement } from '../types';

function horizontalSide(
Expand Down Expand Up @@ -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,
Expand All @@ -54,6 +72,7 @@ export function getArrowPositionStyles({
withBorder: boolean;
arrowSize: number;
arrowOffset: number;
arrowRadius: number;
arrowX: number;
arrowY: number;
dir: 'rtl' | 'ltr';
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/mantine-core/src/Popover/Popover.context.ts
Expand Up @@ -22,6 +22,7 @@ interface PopoverContext {
withArrow: boolean;
arrowSize: number;
arrowOffset: number;
arrowRadius: number;
trapFocus: boolean;
placement: FloatingPosition;
withinPortal: boolean;
Expand Down
14 changes: 14 additions & 0 deletions src/mantine-core/src/Popover/Popover.story.tsx
Expand Up @@ -49,6 +49,20 @@ export function WithArrow() {
);
}

export function WithArrowRadius() {
return (
<div style={{ padding: 40 }}>
<Popover withArrow width={400} arrowRadius={4}>
<Popover.Target>
<Button>arrow popover</Button>
</Popover.Target>

<Popover.Dropdown>Dropdown with arrow radius</Popover.Dropdown>
</Popover>
</div>
);
}

export function Controlled() {
const [opened, setState] = useState(false);

Expand Down
6 changes: 6 additions & 0 deletions src/mantine-core/src/Popover/Popover.tsx
Expand Up @@ -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;

Expand Down Expand Up @@ -133,6 +136,7 @@ const defaultProps: Partial<PopoverProps> = {
middlewares: { flip: true, shift: true, inline: false },
arrowSize: 7,
arrowOffset: 5,
arrowRadius: 0,
closeOnClickOutside: true,
withinPortal: false,
closeOnEscape: true,
Expand Down Expand Up @@ -161,6 +165,7 @@ export function Popover(props: PopoverProps) {
withArrow,
arrowSize,
arrowOffset,
arrowRadius,
unstyled,
classNames,
styles,
Expand Down Expand Up @@ -253,6 +258,7 @@ export function Popover(props: PopoverProps) {
withArrow,
arrowSize,
arrowOffset,
arrowRadius,
placement: popover.floating.placement,
trapFocus,
withinPortal,
Expand Down
Expand Up @@ -91,6 +91,7 @@ export function PopoverDropdown({
withBorder
position={ctx.placement}
arrowSize={ctx.arrowSize}
arrowRadius={ctx.arrowRadius}
arrowOffset={ctx.arrowOffset}
className={classes.arrow}
/>
Expand Down
10 changes: 10 additions & 0 deletions src/mantine-core/src/Tooltip/Tooltip.story.tsx
Expand Up @@ -102,6 +102,16 @@ export const WithArrow = () => (
</Tooltip>
);

export const WithArrowRadius = () => (
<Tooltip
withArrow
label="Tooltip button with arrow Tooltip button with arrow Tooltip button with arrow"
arrowRadius={4}
>
<Button type="button">Tooltip button with arrow radius</Button>
</Tooltip>
);

export function Inline() {
return (
<div style={{ padding: 40, maxWidth: 400 }}>
Expand Down
6 changes: 6 additions & 0 deletions src/mantine-core/src/Tooltip/Tooltip.tsx
Expand Up @@ -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;

Expand All @@ -61,6 +64,7 @@ const defaultProps: Partial<TooltipProps> = {
inline: false,
arrowSize: 4,
arrowOffset: 5,
arrowRadius: 0,
offset: 5,
transition: 'fade',
transitionDuration: 100,
Expand Down Expand Up @@ -92,6 +96,7 @@ const _Tooltip = forwardRef<HTMLElement, TooltipProps>((props, ref) => {
withArrow,
arrowSize,
arrowOffset,
arrowRadius,
offset,
transition,
transitionDuration,
Expand Down Expand Up @@ -166,6 +171,7 @@ const _Tooltip = forwardRef<HTMLElement, TooltipProps>((props, ref) => {
position={tooltip.placement}
arrowSize={arrowSize}
arrowOffset={arrowOffset}
arrowRadius={arrowRadius}
className={classes.arrow}
/>
</Box>
Expand Down
Expand Up @@ -23,6 +23,10 @@ function Demo() {
<Tooltip label="Arrow with size" withArrow arrowSize={6}>
<Button variant="outline">With size</Button>
</Tooltip>

<Tooltip label="Arrow with radius" withArrow arrowSize={6} arrowRadius={4}>
<Button variant="outline">With radius</Button>
</Tooltip>
</>
);
}
Expand Down Expand Up @@ -51,6 +55,9 @@ export function Demo() {
<Tooltip label="Arrow with size" withArrow arrowSize={6}>
<Button variant="outline">With size</Button>
</Tooltip>
<Tooltip label="Arrow with radius" withArrow arrowSize={6} arrowRadius={4}>
<Button variant="outline">With radius</Button>
</Tooltip>
</Group>
);
}
Expand Down