@aladinbs/react-guided-tour 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,6 +12,8 @@ A modern, flexible React TypeScript tour guide library with advanced highlightin
12
12
  - 💾 **State Persistence** - localStorage integration to remember tour completion and progress
13
13
  - ⚡ **Performance Optimized** - Framework-agnostic core with efficient React integration
14
14
  - 🎪 **Action System** - Automated interactions (clicks, navigation, tab switching)
15
+ - 🔒 **Interaction Blocking** - Prevent user interactions outside the tour target for focused guidance
16
+ - 👆 **Click-to-Advance** - Allow users to click target elements directly to advance tour steps
15
17
  - 🔄 **Event System** - Rich event hooks for tour lifecycle management
16
18
  - 🎯 **TypeScript First** - Full type safety with comprehensive type definitions
17
19
 
@@ -141,6 +143,8 @@ interface TourConfig {
141
143
  onStepChange?: (step: TourStep, index: number) => void;
142
144
  allowKeyboardNavigation?: boolean; // Enable keyboard controls
143
145
  allowClickOutside?: boolean; // Allow clicking outside to close
146
+ blockInteractions?: boolean; // Block interactions outside tour target
147
+ clickToAdvance?: boolean; // Enable click-to-advance globally
144
148
  showProgress?: boolean; // Show step progress indicator
145
149
  storage?: {
146
150
  key?: string; // localStorage key (default: 'tour-{id}')
@@ -168,6 +172,8 @@ interface TourStep {
168
172
  canSkip?: boolean; // Allow skipping this step
169
173
  waitForElement?: boolean; // Wait for target element to appear
170
174
  waitTimeout?: number; // Timeout for element waiting (ms)
175
+ blockInteractions?: boolean; // Override global interaction blocking for this step
176
+ clickToAdvance?: boolean; // Override global click-to-advance for this step
171
177
  }
172
178
  ```
173
179
 
@@ -279,6 +285,92 @@ Navigate through multi-step wizards:
279
285
  }
280
286
  ```
281
287
 
288
+ ### Interaction Blocking
289
+
290
+ Control user interactions during the tour to create focused guidance experiences:
291
+
292
+ ```tsx
293
+ const tourConfig: TourConfig = {
294
+ id: 'focused-tour',
295
+ blockInteractions: true, // Block interactions globally
296
+ steps: [
297
+ {
298
+ id: 'step1',
299
+ title: 'Focused Step',
300
+ content: 'Users can only interact with the highlighted element.',
301
+ target: '#important-button',
302
+ blockInteractions: true, // Enforce blocking for this step
303
+ },
304
+ {
305
+ id: 'step2',
306
+ title: 'Free Interaction',
307
+ content: 'Users can click anywhere during this step.',
308
+ target: '#another-element',
309
+ blockInteractions: false, // Override global setting for this step
310
+ },
311
+ ],
312
+ };
313
+ ```
314
+
315
+ **Features:**
316
+ - **Global Control**: Set `blockInteractions: true` in tour config to block interactions for all steps
317
+ - **Per-Step Override**: Use `blockInteractions` in individual steps to override the global setting
318
+ - **Visual Feedback**: Shows a "🔒 Interactions blocked" indicator when active
319
+ - **Smart Targeting**: Only the highlighted element and tour UI remain interactive
320
+ - **Keyboard Blocking**: Prevents keyboard interactions except tour navigation keys
321
+
322
+ **When to use:**
323
+ - Complex interfaces where users might get distracted
324
+ - Critical onboarding flows that must be completed in order
325
+ - Preventing accidental clicks that could break the tour flow
326
+ - Ensuring users focus on specific elements
327
+
328
+ ### Click-to-Advance
329
+
330
+ Enable users to interact directly with tour target elements to advance to the next step:
331
+
332
+ ```tsx
333
+ const tourConfig: TourConfig = {
334
+ id: "interactive-tour",
335
+ clickToAdvance: true, // Enable globally
336
+ steps: [
337
+ {
338
+ id: "button-interaction",
339
+ title: "Try the Button",
340
+ content: "Click the button below to continue the tour!",
341
+ target: "#my-button",
342
+ clickToAdvance: true, // Enable for this step
343
+ },
344
+ {
345
+ id: "form-interaction",
346
+ title: "Fill the Form",
347
+ content: "Complete this form field to proceed.",
348
+ target: "#email-input",
349
+ clickToAdvance: false, // Disable for this step (use Next button)
350
+ },
351
+ ],
352
+ };
353
+ ```
354
+
355
+ **Features:**
356
+ - **Global Control**: Set `clickToAdvance: true` in tour config to enable for all steps
357
+ - **Per-Step Override**: Use `clickToAdvance` in individual steps to override the global setting
358
+ - **Smart UI**: Next button is automatically hidden when click-to-advance is active
359
+ - **Visual Guidance**: Shows "👆 Click the highlighted element to continue" instruction
360
+ - **Event Handling**: Automatically captures clicks on target elements and advances tour
361
+
362
+ **When to use:**
363
+ - Interactive tutorials where users need to practice using actual UI elements
364
+ - Onboarding flows for buttons, forms, and interactive components
365
+ - Training scenarios where clicking the real element is part of the learning
366
+ - Reducing cognitive load by eliminating the need to find the Next button
367
+
368
+ **Best practices:**
369
+ - Use for clickable elements like buttons, links, and form controls
370
+ - Combine with `blockInteractions: true` to ensure users click the right element
371
+ - Provide clear instructions in the step content about what to click
372
+ - Consider accessibility - ensure target elements are keyboard accessible
373
+
282
374
  ### Custom Integrations
283
375
 
284
376
  Extend the tour system with custom integrations:
@@ -1 +1 @@
1
- {"version":3,"file":"TourOverlay.d.ts","sourceRoot":"","sources":["../../src/components/TourOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+B,MAAM,OAAO,CAAC;AAIpD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,8CA4EtB,CAAC"}
1
+ {"version":3,"file":"TourOverlay.d.ts","sourceRoot":"","sources":["../../src/components/TourOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAIzE,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,8CAwQtB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"TourPopover.d.ts","sourceRoot":"","sources":["../../src/components/TourPopover.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAOjF,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,8CAgTtB,CAAC"}
1
+ {"version":3,"file":"TourPopover.d.ts","sourceRoot":"","sources":["../../src/components/TourPopover.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAOjF,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,8CAsWtB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -15,6 +15,8 @@ interface TourStep {
15
15
  canSkip?: boolean;
16
16
  waitForElement?: boolean;
17
17
  waitTimeout?: number;
18
+ blockInteractions?: boolean;
19
+ clickToAdvance?: boolean;
18
20
  }
19
21
  interface TourAction {
20
22
  type: 'click' | 'navigate' | 'highlight' | 'tab-switch' | 'wizard-step' | 'custom';
@@ -52,6 +54,8 @@ interface TourConfig {
52
54
  onStepChange?: (step: TourStep, index: number) => void;
53
55
  allowKeyboardNavigation?: boolean;
54
56
  allowClickOutside?: boolean;
57
+ blockInteractions?: boolean;
58
+ clickToAdvance?: boolean;
55
59
  showProgress?: boolean;
56
60
  storage?: {
57
61
  key?: string;
package/dist/index.esm.js CHANGED
@@ -1414,8 +1414,21 @@ function useTourHighlight(step) {
1414
1414
  }
1415
1415
 
1416
1416
  const TourOverlay = React.memo(function TourOverlay({ className }) {
1417
- const { state, theme, stop } = useTour();
1417
+ const { state, theme, stop, config, next } = useTour();
1418
1418
  const { targetElement, highlightStyle, isVisible } = useTourHighlight(state.currentStep);
1419
+ const [scrollTrigger, setScrollTrigger] = useState(0);
1420
+ // Determine if interactions should be blocked
1421
+ const shouldBlockInteractions = useMemo(() => {
1422
+ const stepBlocking = state.currentStep?.blockInteractions;
1423
+ const globalBlocking = config.blockInteractions;
1424
+ return stepBlocking !== undefined ? stepBlocking : globalBlocking;
1425
+ }, [state.currentStep?.blockInteractions, config.blockInteractions]);
1426
+ // Determine if click-to-advance is enabled
1427
+ const shouldClickToAdvance = useMemo(() => {
1428
+ const stepClickToAdvance = state.currentStep?.clickToAdvance;
1429
+ const globalClickToAdvance = config.clickToAdvance;
1430
+ return stepClickToAdvance !== undefined ? stepClickToAdvance : globalClickToAdvance;
1431
+ }, [state.currentStep?.clickToAdvance, config.clickToAdvance]);
1419
1432
  const overlayStyle = useMemo(() => ({
1420
1433
  position: 'fixed',
1421
1434
  top: 0,
@@ -1427,15 +1440,150 @@ const TourOverlay = React.memo(function TourOverlay({ className }) {
1427
1440
  zIndex: (theme.zIndex || 9999) - 1,
1428
1441
  pointerEvents: 'auto',
1429
1442
  }), [theme.overlay?.backgroundColor, theme.overlay?.opacity, theme.zIndex]);
1430
- const handleOverlayClick = useCallback(() => {
1431
- if (state.currentStep?.canSkip !== false) {
1443
+ // Create cutout style for the highlighted element
1444
+ const cutoutOverlayStyle = useMemo(() => {
1445
+ if ((!shouldBlockInteractions && !shouldClickToAdvance) || !targetElement || !isVisible) {
1446
+ return overlayStyle;
1447
+ }
1448
+ // Use getBoundingClientRect for viewport-relative coordinates (perfect for fixed overlay)
1449
+ const rect = targetElement.getBoundingClientRect();
1450
+ const padding = state.currentStep?.highlight?.padding || 8;
1451
+ // Ensure coordinates are within viewport bounds
1452
+ const left = Math.max(0, rect.left - padding);
1453
+ const top = Math.max(0, rect.top - padding);
1454
+ const right = Math.min(window.innerWidth, rect.right + padding);
1455
+ const bottom = Math.min(window.innerHeight, rect.bottom + padding);
1456
+ return {
1457
+ ...overlayStyle,
1458
+ clipPath: `polygon(
1459
+ 0% 0%,
1460
+ 0% 100%,
1461
+ ${left}px 100%,
1462
+ ${left}px ${top}px,
1463
+ ${right}px ${top}px,
1464
+ ${right}px ${bottom}px,
1465
+ ${left}px ${bottom}px,
1466
+ ${left}px 100%,
1467
+ 100% 100%,
1468
+ 100% 0%
1469
+ )`,
1470
+ };
1471
+ }, [overlayStyle, shouldBlockInteractions, shouldClickToAdvance, targetElement, isVisible, state.currentStep?.highlight?.padding, scrollTrigger]); // eslint-disable-line react-hooks/exhaustive-deps
1472
+ // Force re-render of cutout overlay on scroll to maintain proper positioning
1473
+ useEffect(() => {
1474
+ if (!shouldBlockInteractions && !shouldClickToAdvance) {
1475
+ return;
1476
+ }
1477
+ const handleScroll = () => {
1478
+ // Force recalculation by updating scroll trigger
1479
+ setScrollTrigger(prev => prev + 1);
1480
+ };
1481
+ window.addEventListener('scroll', handleScroll, { passive: true });
1482
+ window.addEventListener('resize', handleScroll, { passive: true });
1483
+ return () => {
1484
+ window.removeEventListener('scroll', handleScroll);
1485
+ window.removeEventListener('resize', handleScroll);
1486
+ };
1487
+ }, [shouldBlockInteractions, shouldClickToAdvance]);
1488
+ const handleOverlayClick = useCallback((e) => {
1489
+ // If interactions are blocked, prevent the click from propagating
1490
+ if (shouldBlockInteractions) {
1491
+ e.preventDefault();
1492
+ e.stopPropagation();
1493
+ return;
1494
+ }
1495
+ // Allow clicking outside to close tour if not blocking interactions
1496
+ if (config.allowClickOutside !== false && state.currentStep?.canSkip !== false) {
1432
1497
  stop();
1433
1498
  }
1434
- }, [state.currentStep?.canSkip, stop]);
1499
+ }, [shouldBlockInteractions, config.allowClickOutside, state.currentStep?.canSkip, stop]);
1500
+ // Handle click-to-advance functionality
1501
+ useEffect(() => {
1502
+ if (!shouldClickToAdvance || !targetElement || !state.isRunning) {
1503
+ return;
1504
+ }
1505
+ // Ensure target element is above the overlay when click-to-advance is enabled
1506
+ const originalZIndex = targetElement.style.zIndex;
1507
+ const originalPosition = targetElement.style.position;
1508
+ targetElement.style.position = targetElement.style.position || 'relative';
1509
+ targetElement.style.zIndex = String((theme.zIndex || 9999) + 1);
1510
+ const handleTargetClick = (_e) => {
1511
+ // Don't prevent default or stop propagation - let the element's normal behavior work
1512
+ // Just advance the tour after a small delay to allow the click to be processed
1513
+ setTimeout(() => {
1514
+ next();
1515
+ }, 100);
1516
+ };
1517
+ targetElement.addEventListener('click', handleTargetClick, true);
1518
+ return () => {
1519
+ targetElement.removeEventListener('click', handleTargetClick, true);
1520
+ // Restore original styles
1521
+ targetElement.style.zIndex = originalZIndex;
1522
+ targetElement.style.position = originalPosition;
1523
+ };
1524
+ }, [shouldClickToAdvance, targetElement, state.isRunning, next, theme.zIndex]);
1525
+ // Block interactions on the entire page when blocking is enabled
1526
+ useEffect(() => {
1527
+ if (!shouldBlockInteractions || !state.isRunning) {
1528
+ return;
1529
+ }
1530
+ const handleGlobalClick = (e) => {
1531
+ const target = e.target;
1532
+ // Allow clicks on the tour target element and its children
1533
+ if (targetElement && (targetElement.contains(target) || targetElement === target)) {
1534
+ // If click-to-advance is enabled, let the target click handler deal with it
1535
+ if (shouldClickToAdvance) {
1536
+ return;
1537
+ }
1538
+ return;
1539
+ }
1540
+ // Allow clicks on tour UI elements (popover, buttons, etc.)
1541
+ if (target.closest('[data-tour-popover]') ||
1542
+ target.closest('[data-tour-highlight]') ||
1543
+ target.closest('[data-tour-overlay]')) {
1544
+ return;
1545
+ }
1546
+ // Block all other clicks
1547
+ e.preventDefault();
1548
+ e.stopPropagation();
1549
+ };
1550
+ const handleGlobalKeydown = (e) => {
1551
+ // Allow tour navigation keys
1552
+ if (['Escape', 'ArrowLeft', 'ArrowRight', 'Enter', 'Space'].includes(e.key)) {
1553
+ return;
1554
+ }
1555
+ // Block other keyboard interactions
1556
+ e.preventDefault();
1557
+ e.stopPropagation();
1558
+ };
1559
+ // Add event listeners to capture phase to block interactions early
1560
+ document.addEventListener('click', handleGlobalClick, true);
1561
+ document.addEventListener('keydown', handleGlobalKeydown, true);
1562
+ document.addEventListener('mousedown', handleGlobalClick, true);
1563
+ document.addEventListener('touchstart', handleGlobalClick, true);
1564
+ return () => {
1565
+ document.removeEventListener('click', handleGlobalClick, true);
1566
+ document.removeEventListener('keydown', handleGlobalKeydown, true);
1567
+ document.removeEventListener('mousedown', handleGlobalClick, true);
1568
+ document.removeEventListener('touchstart', handleGlobalClick, true);
1569
+ };
1570
+ }, [shouldBlockInteractions, state.isRunning, targetElement, shouldClickToAdvance]);
1435
1571
  if (!state.isRunning || !state.currentStep) {
1436
1572
  return null;
1437
1573
  }
1438
- return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("div", { style: overlayStyle, onClick: handleOverlayClick, className: className, "data-tour-overlay": true }), isVisible && targetElement && (jsxRuntimeExports.jsx("div", { style: highlightStyle, "data-tour-highlight": true })), jsxRuntimeExports.jsx("style", { children: `
1574
+ return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("div", { style: (shouldBlockInteractions || shouldClickToAdvance) ? cutoutOverlayStyle : overlayStyle, onClick: handleOverlayClick, className: className, "data-tour-overlay": true }), isVisible && targetElement && (jsxRuntimeExports.jsx("div", { style: highlightStyle, "data-tour-highlight": true })), shouldBlockInteractions && (jsxRuntimeExports.jsx("div", { style: {
1575
+ position: 'fixed',
1576
+ top: '20px',
1577
+ right: '20px',
1578
+ backgroundColor: 'rgba(0, 0, 0, 0.8)',
1579
+ color: 'white',
1580
+ padding: '8px 12px',
1581
+ borderRadius: '4px',
1582
+ fontSize: '12px',
1583
+ zIndex: (theme.zIndex || 9999) + 1,
1584
+ pointerEvents: 'none',
1585
+ animation: 'tour-fade-in 0.3s ease-out',
1586
+ }, "data-tour-blocking-indicator": true, children: "\uD83D\uDD12 Interactions blocked" })), jsxRuntimeExports.jsx("style", { children: `
1439
1587
  @keyframes tour-highlight-pulse {
1440
1588
  0%, 100% {
1441
1589
  box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.2), 0 0 20px rgba(59, 130, 246, 0.3);
@@ -1463,24 +1611,53 @@ const TourOverlay = React.memo(function TourOverlay({ className }) {
1463
1611
  [data-tour-highlight] {
1464
1612
  animation: tour-fade-in 0.3s ease-out;
1465
1613
  }
1614
+
1615
+ [data-tour-blocking-indicator] {
1616
+ animation: tour-fade-in 0.3s ease-out;
1617
+ }
1466
1618
  ` })] }));
1467
1619
  });
1468
1620
 
1469
1621
  function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
1470
1622
 
1471
1623
  const TourPopover = React.memo(function TourPopover({ className }) {
1472
- const { state, theme, next, previous, skip, stop, isFirstStep, isLastStep, canGoNext, canGoPrevious } = useTour();
1624
+ const { state, theme, next, previous, skip, stop, isFirstStep, isLastStep, canGoNext, canGoPrevious, config } = useTour();
1473
1625
  const { targetElement } = useTourHighlight(state.currentStep);
1474
1626
  const popoverRef = useRef(null);
1475
1627
  const [position, setPosition] = useState({ top: 0, left: 0, placement: 'top' });
1476
1628
  const updatePosition = useCallback(() => {
1477
- if (!popoverRef.current || !targetElement || !state.currentStep)
1629
+ if (!popoverRef.current || !state.currentStep)
1630
+ return;
1631
+ // For center placement without target element, calculate center position directly
1632
+ if (state.currentStep.placement === 'center' && !targetElement) {
1633
+ const popoverRect = popoverRef.current.getBoundingClientRect();
1634
+ const viewport = {
1635
+ width: window.innerWidth,
1636
+ height: window.innerHeight,
1637
+ scrollTop: window.pageYOffset || document.documentElement.scrollTop,
1638
+ scrollLeft: window.pageXOffset || document.documentElement.scrollLeft,
1639
+ };
1640
+ setPosition({
1641
+ top: viewport.scrollTop + (viewport.height - popoverRect.height) / 2,
1642
+ left: viewport.scrollLeft + (viewport.width - popoverRect.width) / 2,
1643
+ placement: 'center',
1644
+ });
1645
+ return;
1646
+ }
1647
+ // For other placements, require target element
1648
+ if (!targetElement)
1478
1649
  return;
1479
1650
  const newPosition = calculatePopoverPosition(targetElement, popoverRef.current, state.currentStep.placement || 'top');
1480
1651
  setPosition(newPosition);
1481
1652
  }, [targetElement, state.currentStep]);
1482
1653
  const step = state.currentStep;
1483
1654
  const popoverConfig = useMemo(() => step?.popover || {}, [step?.popover]);
1655
+ // Determine if click-to-advance is enabled for this step
1656
+ const shouldClickToAdvance = useMemo(() => {
1657
+ const stepClickToAdvance = step?.clickToAdvance;
1658
+ const globalClickToAdvance = config.clickToAdvance;
1659
+ return stepClickToAdvance !== undefined ? stepClickToAdvance : globalClickToAdvance;
1660
+ }, [step?.clickToAdvance, config.clickToAdvance]);
1484
1661
  const popoverStyle = useMemo(() => ({
1485
1662
  position: 'absolute',
1486
1663
  top: position.top,
@@ -1524,12 +1701,16 @@ const TourPopover = React.memo(function TourPopover({ className }) {
1524
1701
  await stop();
1525
1702
  }, [stop]);
1526
1703
  useEffect(() => {
1527
- updatePosition();
1704
+ // Small delay to ensure popover is rendered and has dimensions
1705
+ const timeoutId = setTimeout(() => {
1706
+ updatePosition();
1707
+ }, 10);
1528
1708
  const handleResize = () => updatePosition();
1529
1709
  const handleScroll = () => updatePosition();
1530
1710
  window.addEventListener('resize', handleResize);
1531
1711
  window.addEventListener('scroll', handleScroll, { passive: true });
1532
1712
  return () => {
1713
+ clearTimeout(timeoutId);
1533
1714
  window.removeEventListener('resize', handleResize);
1534
1715
  window.removeEventListener('scroll', handleScroll);
1535
1716
  };
@@ -1626,7 +1807,7 @@ const TourPopover = React.memo(function TourPopover({ className }) {
1626
1807
  fontWeight: '500',
1627
1808
  opacity: canGoPrevious ? 1 : 0.5,
1628
1809
  transition: 'all 0.2s ease',
1629
- }, children: "Previous" })), jsxRuntimeExports.jsx("button", { onClick: (e) => {
1810
+ }, children: "Previous" })), !shouldClickToAdvance && (jsxRuntimeExports.jsx("button", { onClick: (e) => {
1630
1811
  e.preventDefault();
1631
1812
  e.stopPropagation();
1632
1813
  handleNext();
@@ -1649,7 +1830,18 @@ const TourPopover = React.memo(function TourPopover({ className }) {
1649
1830
  zIndex: 99999,
1650
1831
  }, children: isLastStep
1651
1832
  ? (popoverConfig.finishLabel || 'Finish')
1652
- : (popoverConfig.nextLabel || 'Next') })] })] }), position.placement !== 'center' && (jsxRuntimeExports.jsx("div", { style: {
1833
+ : (popoverConfig.nextLabel || 'Next') })), shouldClickToAdvance && (jsxRuntimeExports.jsx("div", { style: {
1834
+ backgroundColor: 'rgba(59, 130, 246, 0.1)',
1835
+ border: '1px solid rgba(59, 130, 246, 0.3)',
1836
+ color: theme.primaryColor || '#3b82f6',
1837
+ padding: '8px 16px',
1838
+ borderRadius: '8px',
1839
+ fontSize: '14px',
1840
+ fontWeight: '500',
1841
+ display: 'flex',
1842
+ alignItems: 'center',
1843
+ gap: '6px',
1844
+ }, children: "\uD83D\uDC46 Click the highlighted element to continue" }))] })] }), position.placement !== 'center' && (jsxRuntimeExports.jsx("div", { style: {
1653
1845
  position: 'absolute',
1654
1846
  width: '12px',
1655
1847
  height: '12px',