|
|
|
|
@@ -46,6 +46,22 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
|
|
|
|
const scrollLeftRef = React.useRef(0);
|
|
|
|
|
const isDraggingRef = React.useRef(false);
|
|
|
|
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
|
|
|
const [paddingX, setPaddingX] = React.useState(24);
|
|
|
|
|
|
|
|
|
|
React.useEffect(() => {
|
|
|
|
|
const updatePadding = () => {
|
|
|
|
|
const containerEl = document.querySelector('#referenzen .container');
|
|
|
|
|
if (containerEl) {
|
|
|
|
|
const rect = containerEl.getBoundingClientRect();
|
|
|
|
|
const computedStyle = window.getComputedStyle(containerEl);
|
|
|
|
|
const pLeft = parseFloat(computedStyle.paddingLeft || '0');
|
|
|
|
|
setPaddingX(rect.left + pLeft);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
updatePadding();
|
|
|
|
|
window.addEventListener('resize', updatePadding);
|
|
|
|
|
return () => window.removeEventListener('resize', updatePadding);
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const badge = props.badge || data?.badge || t('badge');
|
|
|
|
|
const title = props.title || data?.title || t('title');
|
|
|
|
|
@@ -107,17 +123,27 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="relative z-10">
|
|
|
|
|
<div className="container relative z-10">
|
|
|
|
|
<div className="absolute right-0 top-0 bottom-0 w-16 bg-gradient-to-l from-neutral-dark to-transparent z-20 md:hidden pointer-events-none" />
|
|
|
|
|
<div
|
|
|
|
|
ref={containerRef}
|
|
|
|
|
onMouseDown={onMouseDown}
|
|
|
|
|
onMouseLeave={onMouseLeave}
|
|
|
|
|
onMouseUp={onMouseUp}
|
|
|
|
|
onMouseMove={onMouseMove}
|
|
|
|
|
className={`select-none flex gap-6 overflow-x-auto pb-8 pt-4 px-6 md:px-[max(2rem,calc((100vw_-_1280px)_/_2))] lg:px-[max(2.5rem,calc((100vw_-_1280px)_/_2))] [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden ${isDragging ? 'cursor-grabbing snap-none' : 'cursor-grab snap-x snap-mandatory'}`}
|
|
|
|
|
>
|
|
|
|
|
{references.map((ref, i) => {
|
|
|
|
|
|
|
|
|
|
{/* Pure CSS Full-Bleed Alignment Container */}
|
|
|
|
|
<div style={{ '--offset': 'calc(50vw - 50%)' } as React.CSSProperties}>
|
|
|
|
|
<div
|
|
|
|
|
ref={containerRef}
|
|
|
|
|
onMouseDown={onMouseDown}
|
|
|
|
|
onMouseLeave={onMouseLeave}
|
|
|
|
|
onMouseUp={onMouseUp}
|
|
|
|
|
onMouseMove={onMouseMove}
|
|
|
|
|
style={{
|
|
|
|
|
marginLeft: 'calc(-1 * var(--offset))',
|
|
|
|
|
marginRight: 'calc(-1 * var(--offset))',
|
|
|
|
|
paddingLeft: 'var(--offset)',
|
|
|
|
|
paddingRight: 'var(--offset)',
|
|
|
|
|
scrollPaddingLeft: 'var(--offset)',
|
|
|
|
|
}}
|
|
|
|
|
className={`select-none flex overflow-x-auto pb-8 pt-4 [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden ${isDragging ? 'cursor-grabbing snap-none' : 'cursor-grab snap-x snap-mandatory'}`}
|
|
|
|
|
>
|
|
|
|
|
{references.map((ref, i) => {
|
|
|
|
|
const imgSrc = ref.image
|
|
|
|
|
? (typeof ref.image === 'string' ? ref.image : ref.image.url)
|
|
|
|
|
: fallbacks[i % fallbacks.length];
|
|
|
|
|
@@ -129,7 +155,7 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
|
|
|
|
whileInView={{ opacity: 1, x: 0 }}
|
|
|
|
|
viewport={{ once: true, margin: "-50px" }}
|
|
|
|
|
transition={{ delay: i * 0.1, duration: 1.0, ease: [0.16, 1, 0.3, 1] }}
|
|
|
|
|
className="flex-shrink-0 w-[320px] md:w-[480px] snap-start group pointer-events-auto"
|
|
|
|
|
className="flex-shrink-0 w-[320px] md:w-[480px] snap-start group pointer-events-auto mr-6"
|
|
|
|
|
>
|
|
|
|
|
<Link
|
|
|
|
|
href={`/${locale}/referenzen#${ref.slug}`}
|
|
|
|
|
|