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

feat(CoachmarkOverlayElements): Add next/back callbacks and currentStep properties #6548

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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,18 @@ const children = `hello, world (${uuidv4()})`;
const dataTestId = uuidv4();
const className = `class-${uuidv4()}`;

const childrenContent = (
const childrenContent = [
<CoachmarkOverlayElement
key="element1"
title="Hello World"
description="this is a description test"
/>
);
/>,
<CoachmarkOverlayElement
key="element2"
title="Hello World"
description="this is a another description test"
/>,
];

const renderCoachmarkWithOverlayElements = (
{ ...rest } = {},
Expand Down Expand Up @@ -165,4 +171,22 @@ describe(componentName, () => {

expect(screen.getByRole('img')).toBeInTheDocument();
});

it('calls onNext', async () => {
const user = userEvent.setup();
const onNext = jest.fn();
renderCoachmarkWithOverlayElements({
'data-testid': dataTestId,
onNext,
});
const beaconOrButton = screen.getByRole('button', {
name: 'Show information',
});
await act(() => user.click(beaconOrButton));
const nextButton = screen.getByRole('button', {
name: 'Next',
});
await act(() => user.click(nextButton));
await expect(onNext).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@
* The label for the Close button.
*/
closeButtonLabel?: string;
/**
* Callback called when clicking on the Next button.
*/
onNext?: () => void;
/**
* Callback called when clicking on the Previous button.
*/
onBack?: () => void;
/**
* Current step of the coachmarks.
*/
currentStep?: number;
}

// NOTE: the component SCSS is not imported here: it is rolled up separately.
Expand All @@ -96,6 +108,9 @@
nextButtonText: 'Next',
previousButtonLabel: 'Back',
closeButtonLabel: 'Got it',
onNext: undefined,
onBack: undefined,
currentStep: 0,
};
/**
* Composable container to allow for the displaying of CoachmarkOverlayElement
Expand All @@ -112,9 +127,12 @@
isVisible = defaults.isVisible,
media,
renderMedia,
currentStep = defaults.currentStep,
nextButtonText = defaults.nextButtonText,
previousButtonLabel = defaults.previousButtonLabel,
closeButtonLabel = defaults.closeButtonLabel,
onNext = defaults.onNext,
onBack = defaults.onBack,
// Collect any other property values passed in.
...rest
},
Expand All @@ -123,7 +141,7 @@
const buttonFocusRef = useRef<ButtonProps<any> | undefined>(undefined);
const scrollRef = useRef<CarouselProps | undefined>(undefined);
const [scrollPosition, setScrollPosition] = useState(0);
const [currentProgStep, _setCurrentProgStep] = useState(0);
const [currentProgStep, _setCurrentProgStep] = useState(currentStep);
const coachmark = useCoachmark();
const hasMedia = media || renderMedia;

Expand All @@ -145,6 +163,16 @@
[currentProgStep, renderMedia]
);

useEffect(() => {
// When current step is set by props
// scroll to the appropriate view on the carrousel
const targetStep = clamp(currentStep, progStepFloor, progStepCeil);

scrollRef?.current?.scrollToView?.(targetStep);
// Avoid circular call to this hook
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentStep]);

useEffect(() => {
// On mount, one of the two primary buttons ("next" or "close")
// will be rendered and must have focus. (a11y)
Expand Down Expand Up @@ -222,7 +250,6 @@
) : (
<>
<Carousel
disableArrowScroll
ref={scrollRef as RefObject<HTMLDivElement>}
onScroll={(scrollPercent) => {
setScrollPosition(scrollPercent);
Expand All @@ -248,6 +275,7 @@
);
scrollRef?.current?.scrollToView?.(targetStep);
setCurrentProgStep(targetStep);
onBack?.();

Check warning on line 278 in packages/ibm-products/src/components/CoachmarkOverlayElements/CoachmarkOverlayElements.tsx

View check run for this annotation

Codecov / codecov/patch

packages/ibm-products/src/components/CoachmarkOverlayElements/CoachmarkOverlayElements.tsx#L278

Added line #L278 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned on a slack DM, we will have the c4p team add this one in, its a bit more complicated

}}
>
{previousButtonLabel}
Expand All @@ -268,6 +296,7 @@
);
scrollRef?.current?.scrollToView?.(targetStep);
setCurrentProgStep(targetStep);
onNext?.();
}}
>
{nextButtonText}
Expand Down Expand Up @@ -320,6 +349,10 @@
* The label for the Close button.
*/
closeButtonLabel: PropTypes.string,
/**
* Current step of the coachmarks
*/
currentStep: PropTypes.number,
/**
* The visibility of CoachmarkOverlayElements is
* managed in the parent component.
Expand All @@ -344,6 +377,14 @@
* The label for the Next button.
*/
nextButtonText: PropTypes.string,
/**
* Optional callback called when clicking on the Previous button.
*/
onBack: PropTypes.func,
/**
* Optional callback called when clicking on the Next button.
*/
onNext: PropTypes.func,
/**
* The label for the Previous button.
*/
Expand Down
Loading