Skip to content

Commit 1cf7200

Browse files
fix: arrow breaking in AILabel popover (#17982)
* fix: arrow breaking in AILabel popover * fix: removed console * fix: format issue * fix: format issue * fix: format issue * fix: format issue * fix: arrow position vertically in case of ai=label * fix: added test * fix: format issue * fix: format * chore: yarn format
1 parent bdd9f4c commit 1cf7200

File tree

5 files changed

+80
-15
lines changed

5 files changed

+80
-15
lines changed

packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9440,6 +9440,9 @@ Map {
94409440
],
94419441
"type": "oneOf",
94429442
},
9443+
"alignmentAxisOffset": Object {
9444+
"type": "number",
9445+
},
94439446
"as": Object {
94449447
"type": "elementType",
94459448
},

packages/react/src/components/AILabel/index.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ export const AILabel = React.forwardRef<HTMLDivElement, AILabelProps>(
193193
? `${aiText} ${slugLabel || ariaLabel}`
194194
: `${aiText} ${aiTextLabel || textLabel}`;
195195

196+
const isSmallIcon = ['xs', '2xs', 'mini'].includes(size);
197+
196198
return (
197199
<div className={aiLabelClasses} ref={ref} id={id}>
198200
{revertActive ? (
@@ -205,7 +207,11 @@ export const AILabel = React.forwardRef<HTMLDivElement, AILabelProps>(
205207
<Undo />
206208
</IconButton>
207209
) : (
208-
<Toggletip align={align} autoAlign={autoAlign} {...rest}>
210+
<Toggletip
211+
align={align}
212+
autoAlign={autoAlign}
213+
alignmentAxisOffset={isSmallIcon ? -24 : 0}
214+
{...rest}>
209215
<ToggletipButton
210216
className={aiLabelButtonClasses}
211217
label={ariaLabelText}>

packages/react/src/components/Popover/__tests__/Popover-test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { render, screen } from '@testing-library/react';
99
import React from 'react';
1010
import { Popover, PopoverContent } from '../../Popover';
1111
import userEvent from '@testing-library/user-event';
12+
import { waitForPosition } from '../../ListBox/test-helpers';
1213

1314
const prefix = 'cds';
1415

@@ -70,6 +71,44 @@ describe('Popover', () => {
7071
expect(screen.getByTestId('test').firstChild).toHaveClass('test');
7172
});
7273

74+
it('should have default caret height', async () => {
75+
render(
76+
<Popover
77+
open
78+
align="bottom"
79+
data-testid="test"
80+
autoAlign
81+
className="test ai-label">
82+
<button type="button">Settings</button>
83+
<PopoverContent className="test"></PopoverContent>
84+
</Popover>
85+
);
86+
87+
await waitForPosition();
88+
const caretContainer =
89+
screen.getByTestId('test').lastChild.lastChild.firstChild;
90+
expect(caretContainer).toHaveStyle({ left: '0px', top: '-6px' });
91+
});
92+
93+
it('should change caret height in case of ai-label', async () => {
94+
render(
95+
<Popover
96+
open
97+
align="bottom"
98+
data-testid="test"
99+
autoAlign
100+
className="test ai-label">
101+
<button type="button">Settings</button>
102+
<PopoverContent className="test ai-label"></PopoverContent>
103+
</Popover>
104+
);
105+
106+
await waitForPosition();
107+
const caretContainer =
108+
screen.getByTestId('test').lastChild.lastChild.firstChild;
109+
expect(caretContainer).toHaveStyle({ left: '0px', top: '-7px' });
110+
});
111+
73112
it('should forward additional props on the outermost element', () => {
74113
const { container } = render(
75114
<PopoverContent id="test" data-testid="test">

packages/react/src/components/Popover/index.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ export const Popover: PopoverComponent = React.forwardRef(
179179
highContrast = false,
180180
onRequestClose,
181181
open,
182+
alignmentAxisOffset,
182183
...rest
183184
}: PopoverProps<E>,
184185
forwardRef: ForwardedRef<Element>
@@ -209,7 +210,10 @@ export const Popover: PopoverComponent = React.forwardRef(
209210
// needs to be placed 1px further outside the popover content. To do so,
210211
// we look to see if any of the children has a className containing "slug"
211212
const initialCaretHeight = React.Children.toArray(children).some((x) => {
212-
return (x as any)?.props?.className?.includes('slug');
213+
return (
214+
(x as any)?.props?.className?.includes('slug') ||
215+
(x as any)?.props?.className?.includes('ai-label')
216+
);
213217
})
214218
? 7
215219
: 6;
@@ -250,7 +254,6 @@ export const Popover: PopoverComponent = React.forwardRef(
250254
}
251255
}
252256
});
253-
254257
const { refs, floatingStyles, placement, middlewareData } = useFloating(
255258
enableFloatingStyles
256259
? {
@@ -264,7 +267,14 @@ export const Popover: PopoverComponent = React.forwardRef(
264267

265268
// Middleware order matters, arrow should be last
266269
middleware: [
267-
offset(!isTabTip ? popoverDimensions?.current?.offset : 0),
270+
offset(
271+
!isTabTip
272+
? {
273+
alignmentAxis: alignmentAxisOffset,
274+
mainAxis: popoverDimensions?.current?.offset,
275+
}
276+
: 0
277+
),
268278
autoAlign &&
269279
flip({
270280
fallbackPlacements: align.includes('bottom')

packages/react/src/components/Toggletip/index.tsx

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ import { usePrefix } from '../../internal/usePrefix';
2525
import { PolymorphicProps } from '../../types/common';
2626

2727
type ToggletipLabelProps<E extends ElementType> = {
28-
as?: E | undefined;
28+
as?: E;
2929
children?: ReactNode;
30-
className?: string | undefined;
30+
className?: string;
3131
};
3232

3333
/**
@@ -82,12 +82,13 @@ function useToggletip() {
8282
}
8383

8484
interface ToggletipProps<E extends ElementType> {
85-
align?: PopoverAlignment | undefined;
86-
as?: E | undefined;
87-
autoAlign?: boolean | undefined;
88-
className?: string | undefined;
85+
align?: PopoverAlignment;
86+
alignmentAxisOffset?: number;
87+
as?: E;
88+
autoAlign?: boolean;
89+
className?: string;
8990
children?: ReactNode;
90-
defaultOpen?: boolean | undefined;
91+
defaultOpen?: boolean;
9192
}
9293

9394
/**
@@ -223,6 +224,11 @@ Toggletip.propTypes = {
223224
'right-start',
224225
]),
225226

227+
/**
228+
* Provide an offset value for alignment axis.
229+
*/
230+
alignmentAxisOffset: PropTypes.number,
231+
226232
/**
227233
* Provide a custom element or component to render the top-level node for the
228234
* component.
@@ -253,8 +259,8 @@ Toggletip.propTypes = {
253259

254260
interface ToggletipButtonBaseProps {
255261
children?: ReactNode;
256-
className?: string | undefined;
257-
label?: string | undefined;
262+
className?: string;
263+
label?: string;
258264
}
259265

260266
export type ToggleTipButtonProps<T extends React.ElementType> =
@@ -264,6 +270,7 @@ export type ToggleTipButtonProps<T extends React.ElementType> =
264270
* `ToggletipButton` controls the visibility of the Toggletip through mouse
265271
* clicks and keyboard interactions.
266272
*/
273+
267274
export const ToggletipButton = React.forwardRef(function ToggletipButton<
268275
T extends React.ElementType,
269276
>(
@@ -323,7 +330,7 @@ ToggletipButton.displayName = 'ToggletipButton';
323330

324331
interface ToggletipContentProps {
325332
children?: ReactNode;
326-
className?: string | undefined;
333+
className?: string;
327334
}
328335

329336
/**
@@ -365,7 +372,7 @@ export { ToggletipContent };
365372

366373
interface ToggleTipActionsProps {
367374
children?: ReactNode;
368-
className?: string | undefined;
375+
className?: string;
369376
}
370377

371378
/**

0 commit comments

Comments
 (0)