step-2-arrow-controls
This commit is contained in:
parent
996f61fbb4
commit
32ee2c4170
|
|
@ -999,6 +999,7 @@ const handleGroupBorderPosition = (groupElements: NodeListOf<HTMLElement>, conta
|
||||||
|
|
||||||
|
|
||||||
// NEW DIRECTIONAL MOVEMENT HANDLER - START
|
// NEW DIRECTIONAL MOVEMENT HANDLER - START
|
||||||
|
|
||||||
const handleDirectionalMove = (direction: 'up' | 'down' | 'left' | 'right', stepSize: number = 5) => {
|
const handleDirectionalMove = (direction: 'up' | 'down' | 'left' | 'right', stepSize: number = 5) => {
|
||||||
if (!selectedTag) return;
|
if (!selectedTag) return;
|
||||||
|
|
||||||
|
|
@ -1037,11 +1038,44 @@ const handleGroupBorderPosition = (groupElements: NodeListOf<HTMLElement>, conta
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a wrapper that matches DirectionalControls' expected signature
|
|
||||||
const directionalControlsHandler = (direction: 'up' | 'down' | 'left' | 'right') => {
|
const directionalControlsHandler = (direction: 'up' | 'down' | 'left' | 'right') => {
|
||||||
handleDirectionalMove(direction, 5); // Use default stepSize of 5
|
handleDirectionalMove(direction, 5); // Use default stepSize of 5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Add this new handler function to your parent component
|
||||||
|
const handleDirectPositionChange = (newLeft: number, newTop: number) => {
|
||||||
|
console.log("handleDirectPositionChange",newLeft,newTop)
|
||||||
|
if (!selectedTag) return;
|
||||||
|
|
||||||
|
const { key, index } = selectedTag;
|
||||||
|
const currentItem = droppedItems[key]?.[index];
|
||||||
|
|
||||||
|
if (!currentItem) return;
|
||||||
|
|
||||||
|
// Ensure values are not negative
|
||||||
|
const clampedLeft = Math.max(0, newLeft);
|
||||||
|
const clampedTop = Math.max(0, newTop);
|
||||||
|
|
||||||
|
setDroppedItems({
|
||||||
|
...droppedItems,
|
||||||
|
[key]: Array.isArray(droppedItems[key])
|
||||||
|
? droppedItems[key].map((item, i) =>
|
||||||
|
i === index
|
||||||
|
? {
|
||||||
|
...item,
|
||||||
|
dimensions: {
|
||||||
|
...item.dimensions,
|
||||||
|
left: clampedLeft,
|
||||||
|
top: clampedTop
|
||||||
|
},
|
||||||
|
update: true
|
||||||
|
}
|
||||||
|
: item
|
||||||
|
)
|
||||||
|
: [],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Center Doc Container - START */}
|
{/* Center Doc Container - START */}
|
||||||
|
|
@ -1201,6 +1235,7 @@ const handleGroupBorderPosition = (groupElements: NodeListOf<HTMLElement>, conta
|
||||||
|
|
||||||
{selectedTag && <RightSideBar selectedTag={droppedItems[selectedTag.key][selectedTag.index]} setDroppedItems={setDroppedItems} selTagKey={selectedTag.key} selTagIndx={selectedTag.index} DirectionalControlsProps={{
|
{selectedTag && <RightSideBar selectedTag={droppedItems[selectedTag.key][selectedTag.index]} setDroppedItems={setDroppedItems} selTagKey={selectedTag.key} selTagIndx={selectedTag.index} DirectionalControlsProps={{
|
||||||
onMove: directionalControlsHandler,
|
onMove: directionalControlsHandler,
|
||||||
|
onPositionChange: handleDirectPositionChange,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
stepSize: 5,
|
stepSize: 5,
|
||||||
className: ''
|
className: ''
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { FaArrowUp, FaArrowDown, FaArrowLeft, FaArrowRight, FaRegCircle } from 'react-icons/fa';
|
import { FaArrowUp, FaArrowDown, FaArrowLeft, FaArrowRight } from 'react-icons/fa';
|
||||||
|
|
||||||
interface DirectionalControlsProps {
|
interface DirectionalControlsProps {
|
||||||
onMove: (direction: 'up' | 'down' | 'left' | 'right', stepSize?: number) => void;
|
onMove: (direction: 'up' | 'down' | 'left' | 'right', stepSize?: number) => void;
|
||||||
|
onPositionChange?: (left: number, top: number) => void;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
stepSize?: number;
|
stepSize?: number;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|
@ -16,23 +17,67 @@ interface DirectionalControlsProps {
|
||||||
|
|
||||||
const DirectionalControls: React.FC<DirectionalControlsProps> = ({
|
const DirectionalControls: React.FC<DirectionalControlsProps> = ({
|
||||||
onMove,
|
onMove,
|
||||||
|
onPositionChange,
|
||||||
disabled = false,
|
disabled = false,
|
||||||
stepSize = 1,
|
stepSize = 1,
|
||||||
className = '',
|
className = '',
|
||||||
selectedType,
|
selectedType,
|
||||||
}) => {
|
}) => {
|
||||||
const onMoveRef = useRef(onMove);
|
const onMoveRef = useRef(onMove);
|
||||||
|
const [leftValue, setLeftValue] = useState('');
|
||||||
|
const [topValue, setTopValue] = useState('');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
onMoveRef.current = onMove;
|
onMoveRef.current = onMove;
|
||||||
}, [onMove]);
|
}, [onMove]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const { top = 0, left = 0 } = selectedType || {};
|
||||||
|
setLeftValue(Math.round(left).toString());
|
||||||
|
setTopValue(Math.round(top).toString());
|
||||||
|
}, [selectedType]);
|
||||||
|
|
||||||
const handleMove = (direction: 'up' | 'down' | 'left' | 'right') => {
|
const handleMove = (direction: 'up' | 'down' | 'left' | 'right') => {
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
onMoveRef.current(direction, stepSize);
|
onMoveRef.current(direction, stepSize);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handlePositionInputChange = (type: 'left' | 'top', value: string) => {
|
||||||
|
if (type === 'left') {
|
||||||
|
setLeftValue(value);
|
||||||
|
} else {
|
||||||
|
setTopValue(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePositionInputBlur = (type: 'left' | 'top') => {
|
||||||
|
if (!onPositionChange) return;
|
||||||
|
|
||||||
|
const numericValue = parseFloat(type === 'left' ? leftValue : topValue);
|
||||||
|
if (isNaN(numericValue)) {
|
||||||
|
const { top = 0, left = 0 } = selectedType || {};
|
||||||
|
if (type === 'left') {
|
||||||
|
setLeftValue(Math.round(left).toString());
|
||||||
|
} else {
|
||||||
|
setTopValue(Math.round(top).toString());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { top = 0, left = 0 } = selectedType || {};
|
||||||
|
const newLeft = type === 'left' ? numericValue : left;
|
||||||
|
const newTop = type === 'top' ? numericValue : top;
|
||||||
|
|
||||||
|
onPositionChange(newLeft, newTop);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleKeyPress = (e: React.KeyboardEvent, type: 'left' | 'top') => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
handlePositionInputBlur(type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleKeyDown = (event: KeyboardEvent) => {
|
const handleKeyDown = (event: KeyboardEvent) => {
|
||||||
if (disabled) return;
|
if (disabled) return;
|
||||||
|
|
@ -64,57 +109,113 @@ const DirectionalControls: React.FC<DirectionalControlsProps> = ({
|
||||||
const buttonClass = `
|
const buttonClass = `
|
||||||
p-1 rounded-sm transition-all duration-200 border shadow-sm text-[10px]
|
p-1 rounded-sm transition-all duration-200 border shadow-sm text-[10px]
|
||||||
${disabled
|
${disabled
|
||||||
? 'bg-gray-100 text-gray-400 cursor-not-allowed'
|
? 'bg-gray-100 text-gray-400 cursor-not-allowed'
|
||||||
: 'bg-white text-gray-600 hover:bg-blue-100 active:bg-blue-200 cursor-pointer'}
|
: 'bg-white text-gray-600 hover:bg-blue-100 active:bg-blue-200 cursor-pointer'}
|
||||||
flex items-center justify-center w-6 h-6
|
flex items-center justify-center w-6 h-6 `;
|
||||||
`;
|
|
||||||
|
|
||||||
|
const inputClass = `
|
||||||
|
w-12 h-6 text-[10px] text-center border rounded px-1 bg-white
|
||||||
|
${disabled
|
||||||
|
? 'bg-gray-100 text-gray-400 cursor-not-allowed border-gray-300'
|
||||||
|
: 'text-gray-600 border-gray-300 focus:border-blue-400 focus:outline-none'}
|
||||||
|
`;
|
||||||
|
|
||||||
const { top = 0, left = 0, width = 0, height = 0 } = selectedType || {};
|
const { top = 0, left = 0, width = 0, height = 0 } = selectedType || {};
|
||||||
|
|
||||||
const right = left + width;
|
|
||||||
const bottom = top + height;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`grid grid-cols-3 grid-rows-1 text-[10px] text-gray-700 ${className}`}>
|
<div className={`flex flex-col items-center space-y-4 text-[10px] text-gray-700 ${className}`}>
|
||||||
{/* Top Row */}
|
{/* Top Button */}
|
||||||
<div></div>
|
<div className="flex justify-center me-4">
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<button onClick={() => handleMove('up')} disabled={disabled} className={buttonClass} title="Move up" type="button">
|
<button
|
||||||
<FaArrowUp size={12} />
|
onClick={() => handleMove('up')}
|
||||||
</button>
|
disabled={disabled}
|
||||||
<span className="mt-1">Top: {Math.round(top)}px</span>
|
className={buttonClass}
|
||||||
</div>
|
title="Move up"
|
||||||
<div></div>
|
type="button"
|
||||||
|
>
|
||||||
{/* Middle Row */}
|
<FaArrowUp size={12} />
|
||||||
<div className="flex flex-col items-center justify-center">
|
</button>
|
||||||
<button onClick={() => handleMove('left')} disabled={disabled} className={buttonClass} title="Move left" type="button">
|
<span className="mt-1">Top</span>
|
||||||
<FaArrowLeft size={12} />
|
</div>
|
||||||
</button>
|
|
||||||
<span className="mt-1">Left: {Math.round(left)}px</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-8 h-8 flex items-center justify-center text-xs text-gray-400 ps-5"><FaRegCircle/></div>
|
{/* Middle Row: Left - Center (Inputs) - Right */}
|
||||||
|
<div className="flex items-center space-x-1">
|
||||||
|
{/* Left Button */}
|
||||||
|
<div className="flex flex-col items-center">
|
||||||
|
<button
|
||||||
|
onClick={() => handleMove('left')}
|
||||||
|
disabled={disabled}
|
||||||
|
className={buttonClass}
|
||||||
|
title="Move left"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<FaArrowLeft size={12} />
|
||||||
|
</button>
|
||||||
|
<span className="mt-1">Left</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col items-center justify-center">
|
{/* Center Panel */}
|
||||||
<button onClick={() => handleMove('right')} disabled={disabled} className={buttonClass} title="Move right" type="button">
|
<div className="relative flex items-center justify-center bg-white rounded-lg px-1 py-2 w-24">
|
||||||
<FaArrowRight size={12} />
|
{/* Floating dimensions tooltip */}
|
||||||
</button>
|
<div className="absolute -top-2 left-1/2 -translate-x-1/2 px-2 py-[1px] text-[10px] font-mono text-black z-10 rounded-sm flex items-center gap-[2px]">
|
||||||
{/* <span className="mt-1">Right: {Math.round(right)}px</span> */}
|
<input
|
||||||
|
type="number"
|
||||||
|
value={leftValue}
|
||||||
|
onChange={(e) => handlePositionInputChange('left', e.target.value)}
|
||||||
|
onBlur={() => handlePositionInputBlur('left')}
|
||||||
|
onKeyPress={(e) => handleKeyPress(e, 'left')}
|
||||||
|
disabled={disabled}
|
||||||
|
className="w-[40px] h-[16px] text-[10px] text-center border-none focus:outline-none text-black font-mono"
|
||||||
|
/>
|
||||||
|
<span className="mx-[1px]">×</span>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
value={topValue}
|
||||||
|
onChange={(e) => handlePositionInputChange('top', e.target.value)}
|
||||||
|
onBlur={() => handlePositionInputBlur('top')}
|
||||||
|
onKeyPress={(e) => handleKeyPress(e, 'top')}
|
||||||
|
disabled={disabled}
|
||||||
|
className="w-[40px] h-[16px] text-[10px] text-center border-none focus:outline-none text-black font-mono"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{/* Right Button */}
|
||||||
|
<div className="flex flex-col items-center">
|
||||||
|
<button
|
||||||
|
onClick={() => handleMove('right')}
|
||||||
|
disabled={disabled}
|
||||||
|
className={buttonClass}
|
||||||
|
title="Move right"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<FaArrowRight size={12} />
|
||||||
|
</button>
|
||||||
|
<span className="mt-1">Right</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Bottom Row */}
|
{/* Bottom Button */}
|
||||||
<div></div>
|
<div className="flex justify-center me-4">
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<button onClick={() => handleMove('down')} disabled={disabled} className={buttonClass} title="Move down" type="button">
|
<button
|
||||||
<FaArrowDown size={12} />
|
onClick={() => handleMove('down')}
|
||||||
</button>
|
disabled={disabled}
|
||||||
{/* <span className="mt-1">Bottom: {Math.round(bottom)}px</span> */}
|
className={buttonClass}
|
||||||
|
title="Move down"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<FaArrowDown size={12} />
|
||||||
|
</button>
|
||||||
|
<span className="mt-1">Bottom</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div></div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DirectionalControls;
|
export default DirectionalControls;
|
||||||
|
|
@ -180,16 +180,26 @@ const RightSideBar: React.FC<DroppedItemProps> = ({ selectedTag, setDroppedItems
|
||||||
if (!is24Hrs) {
|
if (!is24Hrs) {
|
||||||
val = timeFormats[1].format
|
val = timeFormats[1].format
|
||||||
}
|
}
|
||||||
setDroppedItems((prev) => (
|
console.log("val", val)
|
||||||
{
|
|
||||||
|
setDroppedItems((prev) => {
|
||||||
|
const updatedArray = Array.isArray(prev[selTagKey])
|
||||||
|
? prev[selTagKey].map((item, i) => {
|
||||||
|
if (i === selTagIndx) {
|
||||||
|
const updatedItem = { ...item, [changeTo]: changeWith + " " + val, update: true };
|
||||||
|
console.log('Updating item at index', i, 'with:', updatedItem);
|
||||||
|
return updatedItem;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
})
|
||||||
|
: [];
|
||||||
|
|
||||||
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
[selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array
|
[selTagKey]: updatedArray,
|
||||||
? prev[selTagKey].map((item, i) =>
|
};
|
||||||
i === selTagIndx ? { ...item, [changeTo]: changeWith + " " + val, update: true } : item
|
});
|
||||||
)
|
|
||||||
: [],
|
|
||||||
}// Provide a fallback in case it's undefined or not an array
|
|
||||||
));
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
setDroppedItems((prev) => {
|
setDroppedItems((prev) => {
|
||||||
|
|
@ -397,7 +407,7 @@ const RightSideBar: React.FC<DroppedItemProps> = ({ selectedTag, setDroppedItems
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{(selectedTag.type.toLowerCase() !== TagsTypes.SIGNATURE && selectedTag.type.toLowerCase() !== TagsTypes.INITIALS) &&
|
||||||
<div className="">
|
<div className="">
|
||||||
<div className="flex items-center justify-between mr-2 cursor-pointer"
|
<div className="flex items-center justify-between mr-2 cursor-pointer"
|
||||||
onClick={() => setStyleOpen(!styleOpen)}
|
onClick={() => setStyleOpen(!styleOpen)}
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ const TemporalDateAttr: React.FC<TemporalDateAttrInt> = ({ subType, format, drop
|
||||||
val = val + " " + timeFormats[1].format;
|
val = val + " " + timeFormats[1].format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.log('line 89' , val )
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={indx}
|
key={indx}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue