5180 fichiers 38.5 Mo 0 téléchargements 236 vues mis à jour il y a 5 heures ui
nitro-v36-with-renderer-v36 / src / common / card / CardResizeHandle.tsx
CardResizeHandle.tsx 2.9 Ko Télécharger le fichier
import { Key, PointerEvent, RefObject, useEffect, useRef } from 'react';

const windowSizes = new Map<Key, Partial<Record<'width' | 'height', number>>>();

export const CardResizeHandle = ({
    elementRef,
    uniqueKey = null,
    resizeAxis = 'both'
}: {
    elementRef: RefObject<HTMLDivElement | null>;
    resizeAxis?: 'both' | 'vertical' | 'horizontal';
    uniqueKey?: Key;
}) => {
    useEffect(() => {
        const dimensions = uniqueKey !== null ? windowSizes.get(uniqueKey) : null;
        if (!dimensions || !elementRef.current) return;
        for (const [dimension, value] of Object.entries(dimensions)) {
            elementRef.current.style.setProperty(dimension, `${value}px`, 'important');
        }
    }, [elementRef, uniqueKey]);

    const resizeStart = useRef<{ pointerId: number; x: number; y: number; width: number; height: number; scaleX: number; scaleY: number } | null>(null);

    const onResizeStart = (event: PointerEvent<HTMLDivElement>) => {
        if (event.button !== 0 || !elementRef.current) return;

        event.preventDefault();
        event.stopPropagation();
        const element = elementRef.current;
        const bounds = element.getBoundingClientRect();
        resizeStart.current = {
            pointerId: event.pointerId,
            x: event.clientX,
            y: event.clientY,
            width: element.offsetWidth,
            height: element.offsetHeight,
            scaleX: bounds.width / element.offsetWidth,
            scaleY: bounds.height / element.offsetHeight
        };
        event.currentTarget.setPointerCapture(event.pointerId);
    };

    const onResizeMove = (event: PointerEvent<HTMLDivElement>) => {
        const start = resizeStart.current;
        const element = elementRef.current;
        if (!start || !element || start.pointerId !== event.pointerId) return;

        // CSS resolves percentage/viewport min/max sizes against the actual containing block.
        const resizeDimension = (dimension: 'width' | 'height', value: number) => {
            element.style.setProperty(dimension, `${Math.max(0, value)}px`, 'important');
            if (uniqueKey !== null) windowSizes.set(uniqueKey, { ...windowSizes.get(uniqueKey), [dimension]: Math.max(0, value) });
        };

        if (resizeAxis !== 'vertical') resizeDimension('width', start.width + (event.clientX - start.x) / start.scaleX);
        if (resizeAxis !== 'horizontal') resizeDimension('height', start.height + (event.clientY - start.y) / start.scaleY);
    };

    const onResizeEnd = () => {
        resizeStart.current = null;
    };

    return (
        <div
            aria-hidden="true"
            className={`octane-card-resize-handle is-${resizeAxis}`}
            onLostPointerCapture={onResizeEnd}
            onPointerCancel={onResizeEnd}
            onPointerDown={onResizeStart}
            onPointerMove={onResizeMove}
            onPointerUp={onResizeEnd}
        />
    );
};
15Sujets
1Dépôts
20Membres
2En ligne
Profile
Inscrit
Dernière visite
Messages
0
Votes positifs
0
Votes négatifs
0

Nous utilisons des cookies pour assurer le bon fonctionnement du site et améliorer votre expérience. en savoir plus

Autoriser