nfsfu234-tour-guide
Version:
A plug-and-play React component for creating customizable onboarding tours with tooltips, modals, and smooth user guidance. Built with Tailwind CSS and supports dark mode, Framer Motion animations, and full control over step logic.
1 lines • 44.9 kB
Source Map (JSON)
{"version":3,"sources":["../src/Branding.tsx","../src/Tour.tsx"],"names":["jsx","useState","useRef","useEffect","createPortal","jsxs","useMemo","Fragment"],"mappings":"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","file":"index.cjs","sourcesContent":["// src/Branding.tsx\n\ninterface BrandingProps {\n color?: string;\n}\n\n/**\n * Subtle \"Built with NFSFU234TourGuide\" badge.\n * Rendered inside the welcome screen when showBranding={true} (default).\n * Never appears on individual step tooltips.\n */\nexport default function Branding({ color = '#ffffff' }: BrandingProps) {\n return (\n <a\n href=\"https://tour-guide.nforshifu234dev.com\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{\n display: 'block',\n textAlign: 'center',\n marginTop: '16px',\n fontSize: '11px',\n color,\n opacity: 0.35,\n textDecoration: 'none',\n letterSpacing: '0.02em',\n transition: 'opacity 0.2s',\n }}\n onMouseEnter={(e) => (e.currentTarget.style.opacity = '0.65')}\n onMouseLeave={(e) => (e.currentTarget.style.opacity = '0.35')}\n >\n Built with NFSFU234TourGuide\n </a>\n );\n}","'use client';\n\nimport { useState, useEffect, useRef, useMemo } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport Branding from './Branding';\n\nimport type {\n ThemeConfig,\n ButtonLabels,\n WelcomeScreenConfig,\n TourStep,\n TourProps,\n} from './types';\n\n// ────────────────────────────────────────────────────────────────────────────────\n// DEFAULT CONFIGURATIONS\n// ────────────────────────────────────────────────────────────────────────────────\n\nconst THEME_PRESETS: Record<'light' | 'dark', ThemeConfig> = {\n dark: {\n backdrop: 'rgba(0, 0, 0, 0.75)',\n tooltipBg: '#18181b',\n tooltipText: '#ffffff',\n tooltipBorder: '#3f3f46',\n buttonBg: '#27272a',\n buttonText: '#ffffff',\n progressBar: '#3f3f46',\n highlightRing: 'rgba(16, 185, 129, 0.5)',\n },\n light: {\n backdrop: 'rgba(0, 0, 0, 0.5)',\n tooltipBg: '#ffffff',\n tooltipText: '#18181b',\n tooltipBorder: '#e4e4e7',\n buttonBg: '#f4f4f5',\n buttonText: '#18181b',\n progressBar: '#e4e4e7',\n highlightRing: 'rgba(59, 130, 246, 0.5)',\n },\n};\n\nconst DEFAULT_BUTTON_LABELS: Required<ButtonLabels> = {\n next: 'Next',\n previous: 'Back',\n skip: 'Skip',\n finish: 'Finish',\n start: 'Start Tour',\n};\n\nconst DEFAULT_WELCOME_SCREEN: Required<WelcomeScreenConfig> = {\n enabled: false,\n title: 'Welcome',\n message: \"Let's guide you through the key features.\",\n startButtonText: 'Start Tour',\n};\n\n/**\n * Detects if the current viewport width qualifies as mobile (< 768px).\n */\nfunction isMobile(): boolean {\n return typeof window !== 'undefined' && window.innerWidth < 768;\n}\n\n/**\n * Checks whether a given tour step should be displayed based on its device targeting\n * and the currently detected device type.\n */\nfunction shouldShowStep(step: TourStep, currentDevice: 'mobile' | 'desktop'): boolean {\n if (!step.device || step.device === 'both') return true;\n return currentDevice === 'mobile' ? step.device === 'mobile' : step.device === 'desktop';\n}\n\n/**\n * Returns the CSS object for a tooltip arrow pointing in the specified direction.\n */\nfunction getArrowStyle(position?: string, color?: string) {\n const borderColor = color || '#18181b';\n\n switch (position) {\n case 'top':\n return {\n content: '',\n position: 'absolute' as const,\n bottom: '-8px',\n left: '50%',\n transform: 'translateX(-50%)',\n width: 0,\n height: 0,\n borderLeft: '8px solid transparent',\n borderRight: '8px solid transparent',\n borderTop: `8px solid ${borderColor}`,\n };\n case 'bottom':\n return {\n content: '',\n position: 'absolute' as const,\n top: '-8px',\n left: '50%',\n transform: 'translateX(-50%)',\n width: 0,\n height: 0,\n borderLeft: '8px solid transparent',\n borderRight: '8px solid transparent',\n borderBottom: `8px solid ${borderColor}`,\n };\n case 'left':\n return {\n content: '',\n position: 'absolute' as const,\n right: '-8px',\n top: '50%',\n transform: 'translateY(-50%)',\n width: 0,\n height: 0,\n borderTop: '8px solid transparent',\n borderBottom: '8px solid transparent',\n borderLeft: `8px solid ${borderColor}`,\n };\n case 'right':\n return {\n content: '',\n position: 'absolute' as const,\n left: '-8px',\n top: '50%',\n transform: 'translateY(-50%)',\n width: 0,\n height: 0,\n borderTop: '8px solid transparent',\n borderBottom: '8px solid transparent',\n borderRight: `8px solid ${borderColor}`,\n };\n default:\n return { display: 'none' };\n }\n}\n\n// ────────────────────────────────────────────────────────────────────────────────\n// TOOLTIP SUB-COMPONENT\n// ────────────────────────────────────────────────────────────────────────────────\n\ninterface TooltipProps {\n step: TourStep;\n stepIndex: number;\n totalSteps: number;\n themeConfig: ThemeConfig;\n accentColor: string;\n showProgress: boolean;\n buttonLabels: Required<ButtonLabels>;\n tooltipClassName?: string;\n onNext: () => void;\n onPrevious: () => void;\n onSkip: () => void;\n}\n\n/**\n * Displays a single tour step tooltip anchored to a DOM target.\n * Handles:\n * - Dynamic positioning with automatic side flipping when space is insufficient\n * - Viewport edge clamping\n * - Target highlighting and scroll-into-view behavior\n * - Device-specific content selection\n */\nfunction Tooltip({\n step,\n stepIndex,\n totalSteps,\n themeConfig,\n accentColor,\n showProgress,\n buttonLabels,\n tooltipClassName,\n onNext,\n onPrevious,\n onSkip,\n}: TooltipProps) {\n const [targetElement, setTargetElement] = useState<HTMLElement | null>(null);\n const [tooltipStyle, setTooltipStyle] = useState<React.CSSProperties>({});\n const tooltipRef = useRef<HTMLDivElement>(null);\n\n const content = isMobile() && step.contentMobile ? step.contentMobile : step.content;\n\n // ── Target attachment, highlighting & visibility observer ───────────────────\n useEffect(() => {\n const target = document.querySelector(step.target) as HTMLElement | null;\n if (!target) {\n console.warn(`[NFSFU234TourGuide] Target \"${step.target}\" not found`);\n return;\n }\n\n setTargetElement(target);\n\n target.scrollIntoView({ behavior: 'smooth', block: 'center' });\n\n target.style.position = 'relative';\n target.style.zIndex = '9999';\n target.classList.add('nfsfu234-tour-active-target');\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (!entries[0].isIntersecting) {\n target.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n },\n { threshold: 0.3 }\n );\n observer.observe(target);\n\n return () => {\n observer.disconnect();\n target.classList.remove('nfsfu234-tour-active-target');\n target.style.zIndex = '';\n };\n }, [step.target]);\n\n // ── Adaptive positioning with smart flipping & resize handling ──────────────\n useEffect(() => {\n if (!targetElement || !tooltipRef.current) return;\n\n let rafId: number;\n\n const updatePosition = () => {\n const targetRect = targetElement.getBoundingClientRect();\n const tooltipRect = tooltipRef.current!.getBoundingClientRect();\n\n let position = step.position || 'bottom';\n\n const space = {\n top: targetRect.top,\n bottom: window.innerHeight - targetRect.bottom,\n left: targetRect.left,\n right: window.innerWidth - targetRect.right,\n };\n\n const MIN_SPACE = 40;\n\n // Flip if preferred side lacks space\n if (position === 'top' && tooltipRect.height + MIN_SPACE > space.top) position = 'bottom';\n else if (position === 'bottom' && tooltipRect.height + MIN_SPACE > space.bottom) position = 'top';\n else if (position === 'left' && tooltipRect.width + MIN_SPACE > space.left) position = 'right';\n else if (position === 'right' && tooltipRect.width + MIN_SPACE > space.right) position = 'left';\n\n // Final fallback to safer defaults\n if ((position === 'top' && space.top < MIN_SPACE) || (position === 'left' && space.left < MIN_SPACE)) {\n position = position === 'top' ? 'bottom' : 'right';\n }\n\n let top = 0;\n let left = 0;\n\n const offsetX = step.offset?.x ?? 0;\n const offsetY = step.offset?.y ?? (isMobile() ? 12 : 16);\n\n switch (position) {\n case 'top':\n top = targetRect.top - tooltipRect.height - offsetY;\n left = targetRect.left + targetRect.width / 2 - tooltipRect.width / 2 + offsetX;\n break;\n case 'bottom':\n top = targetRect.bottom + offsetY;\n left = targetRect.left + targetRect.width / 2 - tooltipRect.width / 2 + offsetX;\n break;\n case 'left':\n top = targetRect.top + targetRect.height / 2 - tooltipRect.height / 2 + offsetY;\n left = targetRect.left - tooltipRect.width - offsetY;\n break;\n case 'right':\n top = targetRect.top + targetRect.height / 2 - tooltipRect.height / 2 + offsetY;\n left = targetRect.right + offsetY;\n break;\n }\n\n // Clamp to viewport edges\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n top = Math.max(16, Math.min(top, vh - tooltipRect.height - 16));\n left = Math.max(16, Math.min(left, vw - tooltipRect.width - 16));\n\n setTooltipStyle({\n position: 'fixed',\n top: `${top}px`,\n left: `${left}px`,\n zIndex: 10000,\n });\n };\n\n const debouncedUpdate = () => {\n cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(updatePosition);\n };\n\n debouncedUpdate();\n\n window.addEventListener('scroll', debouncedUpdate, true);\n window.addEventListener('resize', debouncedUpdate);\n\n return () => {\n cancelAnimationFrame(rafId);\n window.removeEventListener('scroll', debouncedUpdate, true);\n window.removeEventListener('resize', debouncedUpdate);\n };\n }, [targetElement, step.position, step.offset, step.target]);\n\n if (!targetElement) return null;\n\n return createPortal(\n <div\n ref={tooltipRef}\n className={tooltipClassName}\n style={{\n ...tooltipStyle,\n backgroundColor: themeConfig.tooltipBg,\n color: themeConfig.tooltipText,\n border: `1px solid ${themeConfig.tooltipBorder}`,\n borderRadius: '12px',\n padding: '20px 24px',\n maxWidth: '400px',\n width: isMobile() ? '90%' : 'auto',\n boxShadow: '0 20px 60px rgba(0, 0, 0, 0.3)',\n }}\n >\n <p style={{ marginBottom: '16px', fontSize: '15px', lineHeight: '1.6' }}>\n {content}\n </p>\n\n {showProgress && (\n <div\n style={{\n height: '4px',\n backgroundColor: themeConfig.progressBar,\n borderRadius: '4px',\n overflow: 'hidden',\n marginBottom: '20px',\n }}\n >\n <div\n style={{\n height: '100%',\n width: `${((stepIndex + 1) / totalSteps) * 100}%`,\n backgroundColor: accentColor,\n transition: 'width 0.3s ease',\n }}\n />\n </div>\n )}\n\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\n <button\n onClick={onSkip}\n style={{\n background: 'none',\n border: 'none',\n color: themeConfig.tooltipText,\n opacity: 0.7,\n cursor: 'pointer',\n fontSize: '14px',\n padding: '8px 0',\n }}\n onMouseEnter={(e) => (e.currentTarget.style.opacity = '1')}\n onMouseLeave={(e) => (e.currentTarget.style.opacity = '0.7')}\n >\n {buttonLabels.skip}\n </button>\n\n <div style={{ display: 'flex', gap: '12px' }}>\n <button\n onClick={onPrevious}\n disabled={stepIndex === 0}\n style={{\n padding: '8px 16px',\n borderRadius: '8px',\n border: 'none',\n backgroundColor: themeConfig.buttonBg,\n color: themeConfig.buttonText,\n cursor: stepIndex === 0 ? 'not-allowed' : 'pointer',\n opacity: stepIndex === 0 ? 0.5 : 1,\n fontSize: '14px',\n }}\n >\n {buttonLabels.previous}\n </button>\n\n <button\n onClick={onNext}\n style={{\n padding: '8px 20px',\n borderRadius: '8px',\n border: 'none',\n backgroundColor: accentColor,\n color: '#ffffff',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: '500',\n }}\n >\n {stepIndex < totalSteps - 1 ? buttonLabels.next : buttonLabels.finish}\n </button>\n </div>\n </div>\n\n <div style={getArrowStyle(step.position, themeConfig.tooltipBg)} />\n </div>,\n document.body\n );\n}\n\n// ────────────────────────────────────────────────────────────────────────────────\n// MAIN TOUR COMPONENT\n// ────────────────────────────────────────────────────────────────────────────────\n\n/**\n * Lightweight, zero-dependency React product tour / onboarding component.\n *\n * Features:\n * - Optional welcome screen with scroll lock\n * - Step-by-step tooltips with target highlighting & progress bar\n * - Device-specific steps (mobile / desktop / both)\n * - Smart adaptive tooltip positioning (auto-flips when space is limited)\n * - Reactive to browser resize and orientation changes\n * - Clean unmount: removes backdrop & unlocks body scroll when finished\n * - Optional \"Built with NFSFU234TourGuide\" branding badge (showBranding prop)\n *\n * @example\n * <Tour\n * steps={[{ target: '#hero', content: 'Welcome!' }]}\n * isActive={true}\n * welcomeScreen={{ enabled: true, title: 'Hello!' }}\n * showBranding={false} // opt out of the badge\n * />\n */\nexport default function Tour({\n tourId = 'nfsfu234-tour-guide',\n steps,\n isActive = true,\n theme = 'dark',\n customTheme,\n accentColor = '#10b981',\n onComplete,\n onSkip,\n onStart,\n onStepChange,\n welcomeScreen,\n buttonLabels,\n showProgress = true,\n showBranding = true,\n className = '',\n overlayClassName = '',\n tooltipClassName = '',\n highlightClassName = 'nfsfu234-tour-highlight',\n}: TourProps) {\n // ── Configuration ────────────────────────────────────────────────────────────\n\n const welcomeConfig = useMemo(() => ({ ...DEFAULT_WELCOME_SCREEN, ...welcomeScreen }), [welcomeScreen]);\n const labels = { ...DEFAULT_BUTTON_LABELS, ...buttonLabels };\n const themeConfig = customTheme || (theme !== 'custom' ? THEME_PRESETS[theme] : THEME_PRESETS.dark);\n\n // ── Reactive device detection ───────────────────────────────────────────────\n\n const [currentDevice, setCurrentDevice] = useState<'mobile' | 'desktop'>(isMobile() ? 'mobile' : 'desktop');\n\n useEffect(() => {\n const checkDevice = () => {\n setCurrentDevice(isMobile() ? 'mobile' : 'desktop');\n };\n\n window.addEventListener('resize', checkDevice);\n checkDevice();\n\n return () => window.removeEventListener('resize', checkDevice);\n }, []);\n\n // ── Filtered steps (updates when device changes) ─────────────────────────────\n\n const filteredSteps = useMemo(\n () => steps.filter((step) => shouldShowStep(step, currentDevice)),\n [steps, currentDevice]\n );\n\n // ── Phase & step state ───────────────────────────────────────────────────────\n\n const [phase, setPhase] = useState<'welcome' | 'active' | 'done'>(\n welcomeConfig.enabled ? 'welcome' : filteredSteps.length > 0 ? 'active' : 'done'\n );\n\n const [currentStep, setCurrentStep] = useState(0);\n const [mounted, setMounted] = useState(false);\n\n const welcomeContainerRef = useRef<HTMLDivElement>(null);\n\n // ── Lifecycle & reset ────────────────────────────────────────────────────────\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n useEffect(() => {\n if (isActive) {\n setPhase(welcomeConfig.enabled ? 'welcome' : filteredSteps.length > 0 ? 'active' : 'done');\n setCurrentStep(0);\n }\n }, [isActive, welcomeConfig.enabled, filteredSteps.length]);\n\n // ── Auto-skip to next valid step if current becomes invalid after resize ─────\n\n useEffect(() => {\n if (phase !== 'active') return;\n\n const current = filteredSteps[currentStep];\n if (!current || !shouldShowStep(current, currentDevice)) {\n const nextValidIndex = filteredSteps.findIndex(\n (s, i) => i > currentStep && shouldShowStep(s, currentDevice)\n );\n\n if (nextValidIndex !== -1) {\n setCurrentStep(nextValidIndex);\n onStepChange?.(nextValidIndex);\n } else {\n setPhase('done');\n onComplete?.();\n }\n }\n }, [currentDevice, filteredSteps, currentStep, phase, onStepChange, onComplete]);\n\n // ── Scroll lock when welcome screen is active ────────────────────────────────\n useEffect(() => {\n if (!mounted || !isActive || phase !== 'welcome') return;\n\n const scrollY = window.scrollY;\n\n document.body.style.position = 'fixed';\n document.body.style.top = `-${scrollY}px`;\n document.body.style.width = '100%';\n document.body.style.overflow = 'hidden';\n\n return () => {\n document.body.style.position = '';\n document.body.style.top = '';\n document.body.style.width = '';\n document.body.style.overflow = '';\n window.scrollTo({ top: scrollY, behavior: 'instant' });\n };\n }, [mounted, isActive, phase]);\n\n // ── Navigation handlers ──────────────────────────────────────────────────────\n\n const handleStart = () => {\n setPhase('active');\n setCurrentStep(0);\n onStart?.();\n onStepChange?.(0);\n };\n\n const handleNext = () => {\n if (currentStep < filteredSteps.length - 1) {\n const next = currentStep + 1;\n setCurrentStep(next);\n onStepChange?.(next);\n } else {\n setPhase('done');\n onComplete?.();\n }\n };\n\n const handlePrevious = () => {\n if (currentStep > 0) {\n const prev = currentStep - 1;\n setCurrentStep(prev);\n onStepChange?.(prev);\n }\n };\n\n const handleSkip = () => {\n setPhase('done');\n onSkip?.();\n };\n\n if (!mounted) return null;\n\n return (\n <>\n {/* Backdrop: hidden during welcome (welcome has its own overlay effect) */}\n {isActive && phase === 'active' && (\n <div\n className={overlayClassName}\n onClick={handleSkip}\n style={{\n position: 'fixed',\n inset: 0,\n width: '100vw',\n height: '100vh',\n backgroundColor: themeConfig.backdrop,\n zIndex: 9998,\n }}\n aria-hidden=\"true\"\n />\n )}\n\n {/* Welcome Screen */}\n {isActive && phase === 'welcome' && welcomeConfig.enabled && (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n width: '100vw',\n height: '100vh',\n backgroundColor: themeConfig.backdrop,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 9999,\n }}\n >\n <div\n className={tooltipClassName}\n style={{\n backgroundColor: themeConfig.tooltipBg,\n color: themeConfig.tooltipText,\n border: `1px solid ${themeConfig.tooltipBorder}`,\n borderRadius: '16px',\n padding: isMobile() ? '24px' : '32px',\n maxWidth: '500px',\n width: '90%',\n boxShadow: '0 20px 60px rgba(0, 0, 0, 0.3)',\n }}\n >\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '20px' }}>\n <h2 style={{ fontSize: '24px', fontWeight: 'bold', margin: 0 }}>\n {welcomeConfig.title}\n </h2>\n <button\n onClick={handleSkip}\n aria-label=\"Close welcome screen\"\n style={{\n background: 'none', border: 'none', fontSize: '28px',\n lineHeight: 1, cursor: 'pointer',\n color: themeConfig.tooltipText, opacity: 0.7, padding: '4px 8px',\n }}\n onMouseEnter={(e) => (e.currentTarget.style.opacity = '1')}\n onMouseLeave={(e) => (e.currentTarget.style.opacity = '0.7')}\n >\n ×\n </button>\n </div>\n\n <p style={{ marginBottom: '24px', fontSize: '15px', lineHeight: '1.6', whiteSpace: 'pre-line' }}>\n {welcomeConfig.message}\n </p>\n\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '16px' }}>\n <button\n onClick={handleSkip}\n style={{\n background: 'none', border: 'none',\n color: themeConfig.tooltipText, opacity: 0.8,\n cursor: 'pointer', fontSize: '14px', padding: '12px 0',\n }}\n onMouseEnter={(e) => (e.currentTarget.style.opacity = '1')}\n onMouseLeave={(e) => (e.currentTarget.style.opacity = '0.8')}\n >\n {labels.skip}\n </button>\n <button\n onClick={handleStart}\n style={{\n padding: '12px 24px', borderRadius: '12px', border: 'none',\n backgroundColor: accentColor, color: '#ffffff',\n cursor: 'pointer', fontSize: '14px', fontWeight: '500',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',\n }}\n >\n {welcomeConfig.startButtonText || labels.start}\n </button>\n </div>\n\n {/* ── Branding badge — opt out with showBranding={false} ── */}\n {showBranding && (\n <Branding color={themeConfig.tooltipText} />\n )}\n </div>\n </div>\n )}\n\n {/* Active tour tooltip */}\n {isActive && phase === 'active' && filteredSteps[currentStep] && (\n <Tooltip\n key={currentStep}\n step={filteredSteps[currentStep]}\n stepIndex={currentStep}\n totalSteps={filteredSteps.length}\n themeConfig={themeConfig}\n accentColor={accentColor}\n showProgress={showProgress}\n buttonLabels={labels}\n tooltipClassName={tooltipClassName}\n onNext={handleNext}\n onPrevious={handlePrevious}\n onSkip={handleSkip}\n />\n )}\n\n {/* Styles — only injected while tour is active */}\n {isActive && phase !== 'done' && (\n <style>{`\n .nfsfu234-tour-active-target {\n position: relative !important;\n z-index: 9999 !important;\n box-shadow: 0 0 0 4px ${themeConfig.highlightRing || 'rgba(16, 185, 129, 0.5)'},\n 0 0 0 8px ${themeConfig.highlightRing ? themeConfig.highlightRing.replace('0.5', '0.2') : 'rgba(16, 185, 129, 0.2)'},\n 0 20px 40px rgba(0, 0, 0, 0.4) !important;\n border-radius: 12px;\n transition: box-shadow 0.3s ease;\n animation: nfsfu234-tour-pulse 2s ease-in-out infinite;\n }\n @keyframes nfsfu234-tour-pulse {\n 0%, 100% {\n box-shadow: 0 0 0 4px ${themeConfig.highlightRing || 'rgba(16, 185, 129, 0.5)'},\n 0 0 0 8px ${themeConfig.highlightRing ? themeConfig.highlightRing.replace('0.5', '0.2') : 'rgba(16, 185, 129, 0.2)'},\n 0 20px 40px rgba(0, 0, 0, 0.4);\n }\n 50% {\n box-shadow: 0 0 0 4px ${themeConfig.highlightRing || 'rgba(16, 185, 129, 0.7)'},\n 0 0 0 12px ${themeConfig.highlightRing ? themeConfig.highlightRing.replace('0.5', '0.3') : 'rgba(16, 185, 129, 0.3)'},\n 0 20px 40px rgba(0, 0, 0, 0.4);\n }\n }\n `}</style>\n )}\n </>\n );\n}"]}