Skip to content

Commit 8029def

Browse files
authored
feat(coachmarkStacked): implemented as patterns (#8317)
* feat(coachmarkStacked): implemented as patterns * feat(coachmarkStacked): implemented as patterns * feat(coachmarkStacked): add pkg.prefix * feat: add documentation for carousel in mdx
1 parent e898e58 commit 8029def

File tree

7 files changed

+803
-16
lines changed

7 files changed

+803
-16
lines changed

packages/ibm-products/src/components/Coachmark/next/Coachmark/Coachmark.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import React, {
1111
ReactNode,
1212
RefAttributes,
1313
RefObject,
14-
createContext,
1514
forwardRef,
1615
useEffect,
1716
useRef,

packages/ibm-products/src/components/Coachmark/next/Coachmark/CoachmarkContent.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ const CoachmarkContent = forwardRef<HTMLDivElement, CoachmarkContentProps>(
6868
const targetId = open ? triggerRef?.current?.id : null;
6969

7070
const handleRef = useRef<HTMLDivElement | null>(null);
71-
const bubbleRef = ref && typeof ref !== 'function' ? ref : handleRef;
71+
const bubbleRef = ref || handleRef;
7272

7373
useEffect(() => {
74-
if (open && bubbleRef.current) {
74+
if (open && 'current' in bubbleRef && bubbleRef.current) {
7575
requestAnimationFrame(() => {
7676
const contentBody = bubbleRef.current?.querySelector(
7777
`.${contentBodyClass}`
@@ -91,7 +91,8 @@ const CoachmarkContent = forwardRef<HTMLDivElement, CoachmarkContentProps>(
9191
useEffect(() => {
9292
const handleOutsideClick = (event: MouseEvent) => {
9393
const targetElement = document.getElementById(targetId || '');
94-
const bubbleElement = bubbleRef.current;
94+
const bubbleElement =
95+
bubbleRef && 'current' in bubbleRef ? bubbleRef.current : null;
9596

9697
if (
9798
bubbleElement &&
@@ -122,7 +123,7 @@ const CoachmarkContent = forwardRef<HTMLDivElement, CoachmarkContentProps>(
122123
}, [open, targetId, setOpen]);
123124

124125
useEffect(() => {
125-
if (open && bubbleRef.current) {
126+
if (open && 'current' in bubbleRef && bubbleRef.current) {
126127
const dragContainer = bubbleRef.current.querySelector(
127128
`.${pkg.prefix}__bubble`
128129
);
@@ -131,7 +132,8 @@ const CoachmarkContent = forwardRef<HTMLDivElement, CoachmarkContentProps>(
131132
}
132133
}
133134
// eslint-disable-next-line react-hooks/exhaustive-deps
134-
}, [open, bubbleRef.current]);
135+
}, [open, bubbleRef]);
136+
135137
return (
136138
open && (
137139
<div ref={bubbleRef}>

packages/ibm-products/src/global/js/utils/carousel/carousel.ts

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,12 @@ export const initCarousel = (
3030

3131
const minHeight = 4; // 10 rem
3232

33-
const { onViewChangeStart, onViewChangeEnd, excludeSwipeSupport } =
34-
config || {};
33+
const {
34+
onViewChangeStart,
35+
onViewChangeEnd,
36+
excludeSwipeSupport,
37+
useMaxHeight,
38+
} = config || {};
3539

3640
/**
3741
* Registers an HTMLElement at a specific index in the refs array.
@@ -238,6 +242,8 @@ export const initCarousel = (
238242
*/
239243
const performAnimation = (isInitial: boolean) => {
240244
let itemHeightSmallest = 0;
245+
let itemHeightMaximum = 0;
246+
241247
Array.from(viewItems).forEach((viewItem: HTMLElement, index) => {
242248
const stackIndex = viewIndexStack.findIndex((idx) => idx === index);
243249
const stackIndexInstanceCount = previousViewIndexStack.filter(
@@ -269,15 +275,25 @@ export const initCarousel = (
269275
registerRef(index, viewItem);
270276

271277
setTimeout(() => {
272-
if (
273-
!itemHeightSmallest ||
274-
(viewItem.offsetHeight < itemHeightSmallest &&
275-
itemHeightSmallest > remToPx(minHeight))
276-
) {
277-
itemHeightSmallest = viewItem.offsetHeight;
278+
if (useMaxHeight) {
279+
const heights: number[] = Array.from(viewItems).map(
280+
(viewItem) => viewItem.scrollHeight
281+
);
282+
itemHeightMaximum = Math.max(...heights);
283+
284+
viewItem.style.position = 'absolute';
285+
updateHeightForWrapper(itemHeightMaximum);
286+
} else {
287+
if (
288+
!itemHeightSmallest ||
289+
(viewItem.offsetHeight < itemHeightSmallest &&
290+
itemHeightSmallest > remToPx(minHeight))
291+
) {
292+
itemHeightSmallest = viewItem.offsetHeight;
293+
}
294+
viewItem.style.position = 'absolute';
295+
updateHeightForWrapper(itemHeightSmallest);
278296
}
279-
viewItem.style.position = 'absolute';
280-
updateHeightForWrapper(itemHeightSmallest);
281297
});
282298

283299
const listener = (e: Event) => {

packages/ibm-products/src/global/js/utils/carousel/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export type Config = {
2828
onViewChangeStart?: (args: CarouselResponse) => void;
2929
onViewChangeEnd?: (args: CarouselResponse) => void;
3030
excludeSwipeSupport?: boolean;
31+
useMaxHeight?: boolean;
3132
};
3233

3334
interface InitCarousel {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Story, Controls, Source, Canvas } from '@storybook/addon-docs/blocks';
2+
import { CodesandboxLink } from '../../global/js/utils/story-helper';
3+
import * as CoachmarkStackedStories from './CoachmarkStacked.stories';
4+
import { stackblitzPrefillConfig } from '../../../previewer/codePreviewer';
5+
6+
# CoachmarkStacked
7+
8+
## Table of Contents
9+
10+
- [Overview](#overview)
11+
- [Example usage](#example-usage)
12+
13+
## Overview
14+
15+
The CoachmarkStacked pattern acts as a container element for onboarding and
16+
should only be used within the scope of a Coachmark.
17+
18+
To build this pattern, we recommend including the following components:
19+
20+
- [Coachmark](https://carbon-for-ibm-products.netlify.app/?path=/docs/experimental-onboarding-coachmark-next--overview)
21+
- [cds-button](https://web-components.carbondesignsystem.com/?path=/docs/components-button)
22+
- [Carousel utility](https://github.com/carbon-design-system/carbon/blob/main/packages/utilities/src/carousel/README.md)
23+
24+
## About Onboarding
25+
26+
[Onboarding](https://pages.github.ibm.com/security/security-design/department/end-to-end-experiences/onboarding/overview/)
27+
is a continuous learning methodology and framework that aims to orient, onboard,
28+
explain, educate, and cultivate novice users into high-functioning power users.
29+
30+
## Example usage
31+
32+
{/* TODO: One example per designed use case. */}
33+
34+
<Canvas className="coachmarkExample" withSource="none">
35+
<div className="CoachmarkBaseExampleUsage">
36+
<Story of={CoachmarkStackedStories.CoachmarkStacked} />
37+
</div>
38+
</Canvas>

0 commit comments

Comments
 (0)