feat(ui): enhance component share UX and add new interactive simulations
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 6s
Build & Deploy / 🏗️ Build (push) Failing after 26s
Build & Deploy / 🧪 QA (push) Failing after 1m14s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s

This commit is contained in:
2026-02-22 16:58:42 +01:00
parent d9ddce412a
commit 38f2cc8b85
22 changed files with 918 additions and 163 deletions

View File

@@ -1,6 +1,7 @@
'use client';
import React, { useEffect, useRef, useState } from 'react';
import React, { useEffect, useRef, useState, useId } from 'react';
import { ComponentShareButton } from './ComponentShareButton';
interface BoldNumberProps {
/** The number to display, e.g. "53%" or "2.5M€" or "-20%" */
@@ -28,6 +29,7 @@ export const BoldNumber: React.FC<BoldNumberProps> = ({
const ref = useRef<HTMLDivElement>(null);
const [isVisible, setIsVisible] = useState(false);
const [displayValue, setDisplayValue] = useState('');
const shareId = `boldnum-${useId().replace(/:/g, '')}`;
// Extract numeric part for animation
const numericMatch = value.match(/^([+-]?)(\d+(?:[.,]\d+)?)(.*)/);
@@ -84,22 +86,16 @@ export const BoldNumber: React.FC<BoldNumberProps> = ({
return () => clearInterval(timer);
}, [isVisible, value, prefix, suffix, targetNum, hasDecimals, numStr]);
const handleShare = async () => {
const shareText = `${value}${label}${source ? ` (${source})` : ''}`;
try {
if (navigator.share) {
await navigator.share({ text: shareText });
} else {
await navigator.clipboard.writeText(shareText);
}
} catch { /* user cancelled */ }
};
return (
<div
ref={ref}
className={`not-prose relative overflow-hidden rounded-2xl my-16 border border-slate-100 bg-slate-50/50 p-10 md:p-14 text-center ${className}`}
id={shareId}
className={`not-prose relative overflow-hidden rounded-2xl my-16 border border-slate-100 bg-slate-50/50 p-10 md:p-14 text-center group ${className}`}
>
<div className="absolute top-4 right-4 z-50 md:opacity-0 group-hover:opacity-100 transition-opacity duration-500">
<ComponentShareButton targetId={shareId} title={`Statistik: ${label}`} />
</div>
<div className="relative z-10">
<span className="block text-6xl md:text-8xl font-black tracking-tighter tabular-nums leading-none text-slate-900 pb-2">
{displayValue || value}
@@ -119,19 +115,6 @@ export const BoldNumber: React.FC<BoldNumberProps> = ({
</span>
)}
</div>
{/* Share button - subtle now */}
<button
onClick={handleShare}
className="absolute top-4 right-4 z-20 p-2 rounded-lg text-slate-300 hover:text-blue-600 hover:bg-blue-50 transition-all cursor-pointer"
title="Teilen"
>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8" />
<polyline points="16 6 12 2 8 6" />
<line x1="12" y1="2" x2="12" y2="15" />
</svg>
</button>
</div>
);
};