Targeting step elements with XPath HTML selector #971
-
Hi Team! We have decided to use this library to integrate Onboarding Tour into our existing system, and did some initial work. But I have questions for targeting elements with XPath selector. And I tried with pass the XPath data to the Tour component, but it did not work... Is it possible for this library to use the XPath selector to target elements? And if it is possible, could you please let me show the approaches? Best Regards. Andry. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 1 reply
-
Hey @codechallenge21 |
Beta Was this translation helpful? Give feedback.
-
Hi @gilbarbara |
Beta Was this translation helpful? Give feedback.
-
Here it goes: import { useEffect, useRef, useState } from 'react';
import Joyride, { Step } from 'react-joyride';
function getElementWithXPath(xp: string) {
return document.evaluate(xp, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)
.singleNodeValue;
}
export default function Demo() {
const [run, setRun] = useState(false);
const [steps, setSteps] = useState<Step[]>([]);
// you could create a ref to store the step element
const step1 = useRef<HTMLDivElement>(null);
// Since you need the DOM to be rendered to get the elements, you need to use useEffect
// that only runs after the first render
useEffect(() => {
// or you query it directly from the DOM
const step2 = document.querySelector('[data-step="2"]');
// or you use a helper function to get the element
const step3 = getElementWithXPath('//div[1]/div[1]/div[4]');
// alternatively you could get the element using data attributes
// const step3 = getElementWithXPath('//*[@data-step="3"]');
if (step1.current && step2 instanceof HTMLElement && step3 instanceof HTMLElement) {
setSteps([
{
content: 'The description of the first step',
placement: 'bottom',
target: step1.current,
},
{
content: 'The description of the second step',
placement: 'bottom',
target: step2,
},
{
content: 'The description of the third step',
placement: 'bottom',
target: step3,
},
]);
setRun(true);
}
}, []);
return (
<div style={{ padding: 32 }}>
<Joyride continuous run={run} steps={steps} />
<h1>Hello</h1>
<div ref={step1} data-step="1">
<p>
Labore officia pariatur nulla veniam dolor ex ipsum voluptate ad sunt ea. Et magna nisi ex
culpa nulla. Officia duis sint pariatur sit officia amet et. Ea qui sint culpa duis.
Laborum aliquip aliqua commodo. Nisi adipisicing officia est consequat amet ex velit
mollit cillum consequat deserunt laboris. Voluptate incididunt nulla consequat cillum
mollit consectetur amet pariatur velit ullamco mollit. Aliqua minim esse pariatur.
</p>
</div>
<div data-step="2">
<p>
Ullamco adipisicing minim officia et ut Lorem. Sint minim amet occaecat sint amet elit
mollit fugiat magna ipsum reprehenderit mollit duis sunt. Laboris est sint amet
exercitation dolore aliquip duis. Tempor ex exercitation occaecat do est in irure deserunt
consequat et. Incididunt et et adipisicing non occaecat enim minim minim officia eu.
Dolore ad minim id enim aliqua ea. Ex sit ex proident cillum ullamco adipisicing culpa.
</p>
</div>
<div data-step="3">
<p>
Ullamco adipisicing minim officia et ut Lorem. Sint minim amet occaecat sint amet elit
mollit fugiat magna ipsum reprehenderit mollit duis sunt. Laboris est sint amet
exercitation dolore aliquip duis. Tempor ex exercitation occaecat do est in irure deserunt
consequat et. Incididunt et et adipisicing non occaecat enim minim minim officia eu.
Dolore ad minim id enim aliqua ea. Ex sit ex proident cillum ullamco adipisicing culpa.
</p>
</div>
</div>
);
} |
Beta Was this translation helpful? Give feedback.
-
Hi @gilbarbara Your code is a very detailed example with various scenarios of targeting HTML elements. Thank you very much for providing the code. |
Beta Was this translation helpful? Give feedback.
Hey @codechallenge21
It's not possible to use a string for XPath. Internally, it uses the document
querySelector
method to find the element.However, the
target
prop also accepts an HTMLElement instead of a selector string, so if you can use another method to evaluate the XPath, it might work.