"use client" import type React from "react" import { useState, useEffect, useRef } from "react" import { cn } from "@/lib/utils" import { iconSvgPaths } from "@/lib/icons" interface PreviewWidgetProps { removeImages: boolean grayscale: boolean // colorblindMode wurde entfernt fontSize: number disableAnimations: boolean largeCursor: boolean dyslexiaFont: boolean highlightLinks: boolean invertColors: boolean highlightHeadings: boolean // readingMode wurde entfernt contrastMode: "normal" | "dark" | "light" saturationMode: "normal" | "low" | "high" contentScaling: number // lineHeight wurde entfernt letterSpacing: number widgetPosition: "bottom-right" | "bottom-left" buttonColor: string accentColor: string widgetIcon: string // New props blueFilter: boolean muteSounds: boolean } export function PreviewWidget({ removeImages, grayscale, // colorblindMode wurde entfernt fontSize, disableAnimations, largeCursor, dyslexiaFont, highlightLinks, invertColors, highlightHeadings, // readingMode wurde entfernt contrastMode, saturationMode, contentScaling, // lineHeight wurde entfernt letterSpacing, widgetPosition, buttonColor, accentColor, widgetIcon, // New props blueFilter, muteSounds, }: PreviewWidgetProps) { const [isOpen, setIsOpen] = useState(false) const widgetContainerRef = useRef(null) const SelectedIconClass = iconSvgPaths[widgetIcon] || iconSvgPaths.accessibility const resetIconClass = iconSvgPaths.rotateRight const closeIconClass = iconSvgPaths.xmark const activeFeaturesCount = [ invertColors, grayscale, contrastMode !== "normal", saturationMode !== "normal", highlightLinks, highlightHeadings, removeImages, // colorblindMode wurde entfernt fontSize !== 100, contentScaling !== 100, // lineHeight !== 100, // lineHeight wurde entfernt letterSpacing !== 0, disableAnimations, largeCursor, dyslexiaFont, // New features blueFilter, muteSounds, ].filter(Boolean).length // Effect to load CSS and JS and initialize the widget useEffect(() => { const baseUrl = "https://v0-next-js-widget-configurator.vercel.app" // Replace with your actual deployed URL // Load CSS (only once) let cssLink = document.querySelector(`link[href="${baseUrl}/widget.css"]`) as HTMLLinkElement if (!cssLink) { cssLink = document.createElement("link") cssLink.rel = "stylesheet" cssLink.href = `${baseUrl}/widget.css` document.head.appendChild(cssLink) } // Load JS (and re-initialize on settings change) // We need to ensure the script is loaded before calling initializeAccessibilityWidget const loadScript = () => { let jsScript = document.querySelector(`script[src="${baseUrl}/widget.js"]`) as HTMLScriptElement if (!jsScript) { jsScript = document.createElement("script") jsScript.src = `${baseUrl}/widget.js` jsScript.onload = () => { // Ensure the global function is available after script loads if (window.initializeAccessibilityWidget) { window.initializeAccessibilityWidget() } } document.body.appendChild(jsScript) } else { // If script is already loaded, just re-initialize if (window.initializeAccessibilityWidget) { window.initializeAccessibilityWidget() } } } loadScript() // Cleanup function for when the component unmounts or dialog closes return () => { // The widget.js cleanup logic is now handled internally by initializeAccessibilityWidget() // when it's called again. For a full unmount, we might want to remove the CSS/JS, // but for a dialog close, it's usually fine to leave them. // For this specific case, since the widget.js is designed to be persistent on the page, // we rely on its internal cleanup when re-initialized. } }, []) // Empty dependency array means this runs once on mount // Effect to re-initialize widget when props change useEffect(() => { if (window.initializeAccessibilityWidget) { // This will trigger the widget.js to re-read data attributes and apply settings window.initializeAccessibilityWidget() } }, [ removeImages, grayscale, // colorblindMode wurde entfernt fontSize, disableAnimations, largeCursor, dyslexiaFont, highlightLinks, invertColors, highlightHeadings, // readingMode wurde entfernt contrastMode, saturationMode, contentScaling, // lineHeight wurde entfernt letterSpacing, buttonColor, accentColor, widgetIcon, // New props blueFilter, muteSounds, ]) // This local state `isOpen` is only for the preview's toggle button // The actual widget.js will manage its own open/close state based on its toggle button // We need to ensure the preview's toggle button interacts with the actual widget.js const handlePreviewToggleClick = () => { setIsOpen(!isOpen) // Trigger the actual widget's toggle button click const actualToggleButton = widgetContainerRef.current?.querySelector( "#accessibility-widget-toggle", ) as HTMLButtonElement if (actualToggleButton) { actualToggleButton.click() } } // This local state `isOpen` is only for the preview's close button const handlePreviewCloseClick = () => { setIsOpen(false) // Trigger the actual widget's close button click const actualCloseButton = widgetContainerRef.current?.querySelector(".a11y-close-button") as HTMLButtonElement if (actualCloseButton) { actualCloseButton.click() } } // This local state `isOpen` is only for the preview's reset button const handlePreviewResetClick = () => { // Trigger the actual widget's reset button click const actualResetButton = widgetContainerRef.current?.querySelector(".a11y-reset-button") as HTMLButtonElement if (actualResetButton) { actualResetButton.click() } } return (
{/* The actual widget HTML structure, which widget.js will manipulate */}

Barrierefreiheits-Menü

{/* New scrollable container for sliders and tiles */}
{/* Sliders as individual rows */}
Inhaltsskalierung
{contentScaling}%
Schriftgröße
{fontSize}%
Buchstabenabstand
{letterSpacing / 100}em
{/* Toggle Tiles - Bilder ausblenden first */}
Bilder aus
Farben umkehren
Monochrom
Blaufilter
Dunkler Kontrast
Heller Kontrast
Niedrige Sättigung
Hohe Sättigung
Links hervorheben
Überschriften hervorheben
{/* Existing features not in screenshot, but kept */}
Bewegung reduzieren
Großer Cursor
Dyslexie Schrift
Töne aus
) }