Skip to content

Commit e9474a2

Browse files
committed
add usableStepTarget property
1 parent f637cc8 commit e9474a2

3 files changed

Lines changed: 33 additions & 21 deletions

File tree

src/components/VisualTour/VisualTour.tsx

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ export interface VisualTourProps {
3333
nextLabel?: string;
3434
/** The label for the 'previous' button. */
3535
prevLabel?: string;
36+
/** The step target is usable, e.g. it can be clicked. */
37+
usableStepTarget?: boolean;
3638
}
3739

3840
export interface VisualTourStep {
@@ -48,12 +50,14 @@ export interface VisualTourStep {
4850
image?: string;
4951
/** The size of the tooltip or modal. */
5052
size?: TooltipSize | ModalSize;
53+
/** The step target is usable, e.g. it can be clicked. Overwrites the setting in `<VisualTour/>`. */
54+
usableStepTarget?: boolean;
5155
}
5256

5357
/** This should be used for defining steps in a separate object/file. Use with 'satisfies' after the object definition. */
5458
export type VisualTourStepDefinitions = Record<string, Partial<VisualTourStep>>;
5559

56-
const highlightElementClass = `${eccgui}-visual-tour__highlighted-element`;
60+
const highlightElementBaseClass = `${eccgui}-visual-tour__highlighted-element`;
5761

5862
/** A visual tour multi-step tour of the current view. */
5963
export const VisualTour = ({
@@ -62,6 +66,7 @@ export const VisualTour = ({
6266
closeLabel = "Close",
6367
nextLabel = "Next",
6468
prevLabel = "Back",
69+
usableStepTarget = false,
6570
}: VisualTourProps) => {
6671
const [currentStepIndex, setCurrentStepIndex] = React.useState<number>(0);
6772
const [currentStepComponent, setCurrentStepComponent] = React.useState<React.JSX.Element | null>(null);
@@ -74,6 +79,11 @@ export const VisualTour = ({
7479
onClose();
7580
return;
7681
}
82+
const highlightElementClass = (
83+
typeof step["usableStepTarget"] === "undefined" ? usableStepTarget : step["usableStepTarget"]
84+
)
85+
? `${highlightElementBaseClass}--useable`
86+
: highlightElementBaseClass;
7787
const hasNextStep = currentStepIndex + 1 < steps.length;
7888
const hasPreviousStep = currentStepIndex > 0;
7989
// Configure optional highlighting
@@ -145,7 +155,7 @@ export const VisualTour = ({
145155
<StepModal titleOption={titleOptions} actionButtons={actionButtons} step={step} onClose={onClose} />
146156
);
147157
}
148-
}
158+
};
149159
const addElementHighlighting = () => {
150160
if (step.highlightElementQuery) {
151161
const queries: string[] =
@@ -158,7 +168,7 @@ export const VisualTour = ({
158168
}
159169
});
160170
} else {
161-
elementToHighlight = null
171+
elementToHighlight = null;
162172
}
163173
if (elementToHighlight) {
164174
// Typescript for some reason incorrectly infers the type of elementToHighlight as never
@@ -167,35 +177,35 @@ export const VisualTour = ({
167177
behavior: "smooth",
168178
block: "center",
169179
});
170-
if(lastObserver) {
171-
lastObserver.disconnect()
180+
if (lastObserver) {
181+
lastObserver.disconnect();
172182
}
173183
lastObserver = new MutationObserver(function () {
174184
// Re-new element highlighting
175-
if(step.highlightElementQuery) {
185+
if (step.highlightElementQuery) {
176186
if (!document.body.contains(elementToHighlight)) {
177187
// Element has been removed or replaced
178188
elementToHighlight = null;
179189
addElementHighlighting();
180-
} else if(!elementToHighlight?.classList.contains(highlightElementClass)) {
190+
} else if (!elementToHighlight?.classList.contains(highlightElementClass)) {
181191
// Only the classes have been removed
182192
elementToHighlight?.classList.add(highlightElementClass);
183193
}
184194
}
185195
});
186-
lastObserver.observe(document.body, {childList: true, subtree: true});
196+
lastObserver.observe(document.body, { childList: true, subtree: true });
187197
}
188-
setStepComponent()
189-
}
190-
addElementHighlighting()
198+
setStepComponent();
199+
};
200+
addElementHighlighting();
191201
return () => {
192202
// Remove previous element highlight
193203
document.querySelector(`.${highlightElementClass}`)?.classList.remove(highlightElementClass);
194-
if(lastObserver) {
195-
lastObserver.disconnect()
204+
if (lastObserver) {
205+
lastObserver.disconnect();
196206
}
197207
};
198-
}, [currentStepIndex]);
208+
}, [currentStepIndex, usableStepTarget]);
199209

200210
return currentStepComponent;
201211
};
@@ -216,9 +226,7 @@ const StepContent = ({ step }: { step: VisualTourStep }) => {
216226
<>
217227
{step.image && (
218228
<>
219-
<img
220-
src={step.image}
221-
/>
229+
<img src={step.image} />
222230
<Spacing size="small" />
223231
</>
224232
)}

src/components/VisualTour/stories/defaultTour.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ const definition = {
1414
},
1515
highlightElementA: {
1616
title: "Highlight element A",
17+
usableStepTarget: false,
1718
content:
1819
"It's possible to highlight specific elements on a page. The step content is then displayed in a kind of tooltip instead of a modal.",
1920
},
2021
highlightElementB: {
2122
title: "Highlight element B",
23+
usableStepTarget: true,
2224
content: "Context overlay for another highlighted element.",
2325
},
2426
highlightElementLeft: {

src/components/VisualTour/visualTour.scss

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@
44
--#{$eccgui}-visual-tour-focus-padding: #{0.5 * $eccgui-size-block-whitespace};
55
}
66

7-
.#{$eccgui}-visual-tour__highlighted-element {
8-
position: relative;
9-
z-index: 999999 !important;
10-
7+
[class*="#{$eccgui}-visual-tour__highlighted-element"] {
118
.#{$eccgui}-overviewitem__actions--hiddeninteractions:has(&) {
129
display: inherit;
1310
}
1411
}
1512

13+
.#{$eccgui}-visual-tour__highlighted-element--useable {
14+
position: relative;
15+
z-index: 999999 !important;
16+
}
17+
1618
.#{$eccgui}-visual-tour__focushelper {
1719
position: absolute;
1820
z-index: 8001; // 1 over application header

0 commit comments

Comments
 (0)