import * as React from "react"; import { get, has } from "lodash"; import { DndProvider, useDragLayer } from "react-dnd"; import Backend from "react-dnd-html5-backend"; import { useDrag } from "react-dnd"; import { useKeyPress } from "@sc/plugins/utilities"; import { useState, useEffect } from "react"; import { generateStyles, getObjectFromStyle, containerStyle, innerContainerStyle, Trapezoid, } from "./style"; import { SpacingProps, commandType, SquareBlockProps, styleTypes, SquareBlockStyles, IKeysPressed, ICompass, } from "./types"; const getShouldBeActivated = ( action: commandType, isKeyPressed: IKeysPressed ): ICompass => { if (isKeyPressed.shiftKey) { return { top: true, right: true, bottom: true, left: true, }; } if (isKeyPressed.commandKey || isKeyPressed.controlKey) { if (action === commandType.TOP || action === commandType.BOTTOM) { return { top: true, right: false, bottom: true, left: false, }; } if (action === commandType.LEFT || action === commandType.RIGHT) { return { top: false, right: true, bottom: false, left: true, }; } } return { top: action === commandType.TOP, right: action === commandType.RIGHT, bottom: action === commandType.BOTTOM, left: action === commandType.LEFT, }; }; const SqueryBlock: React.FC = ({ style, onChange }) => { const [isMarginHovered, setIsMarginHovered] = React.useState([ false, null, ]); const [isPaddingHovered, setIsPaddingHovered] = React.useState([ false, null, ]); const [originalStyle, setOriginalStyle] = React.useState(style); const marginStyles: SquareBlockStyles = generateStyles({ clipSmallPercentage: 20, clipBigPercentage: 80, }); const paddingStyles: SquareBlockStyles = generateStyles({ clipSmallPercentage: 34, clipBigPercentage: 66, }); const isKeyPressed: IKeysPressed = { shiftKey: useKeyPress("Shift"), commandKey: useKeyPress("Meta"), altKey: useKeyPress("Alt"), controlKey: useKeyPress("Control"), }; const [mT, dragRefMarginTop, previewRefMarginTop] = useDrag({ item: { type: styleTypes.MARGIN, command: commandType.TOP }, end: () => setOriginalStyle(style), }); const [mR, dragRefMarginRight, previewRefMarginRight] = useDrag({ item: { type: styleTypes.MARGIN, command: commandType.RIGHT }, end: () => setOriginalStyle(style), }); const [mB, dragRefMarginBottom, previewRefMarginBottom] = useDrag({ item: { type: styleTypes.MARGIN, command: commandType.BOTTOM }, end: () => setOriginalStyle(style), }); const [mL, dragRefMarginLeft, previewRefMarginLeft] = useDrag({ item: { type: styleTypes.MARGIN, command: commandType.LEFT }, end: () => setOriginalStyle(style), }); const [mp, dragRefPaddingTop, previewRefPaddingTop] = useDrag({ item: { type: styleTypes.PADDING, command: commandType.TOP }, end: () => setOriginalStyle(style), }); const [pR, dragRefPaddingRight, previewRefPaddingRight] = useDrag({ item: { type: styleTypes.PADDING, command: commandType.RIGHT }, end: () => setOriginalStyle(style), }); const [pB, dragRefPaddingBottom, previewRefPaddingBottom] = useDrag({ item: { type: styleTypes.PADDING, command: commandType.BOTTOM }, end: () => setOriginalStyle(style), }); const [pL, dragRefPaddingLeft, previewRefPaddingLeft] = useDrag({ item: { type: styleTypes.PADDING, command: commandType.LEFT }, end: () => setOriginalStyle(style), }); const { currentOffset } = useDragLayer((monitor) => { const currentOffset = monitor.getDifferenceFromInitialOffset(); const item = monitor.getItem(); if ( has(currentOffset, "y") && has(currentOffset, "x") && has(item, "command") && has(item, "type") ) { if (item.command === commandType.TOP) { onChange( item.type, commandType.TOP, { ...originalStyle, top: Number(get(originalStyle, "marginTop", 0)) + Number(currentOffset.y), }, isKeyPressed ); } if (item.command === commandType.RIGHT) { onChange( item.type, commandType.RIGHT, { ...originalStyle, right: Number(get(originalStyle, "marginRight", 0)) + Number(currentOffset.x), }, isKeyPressed ); } if (item.command === commandType.BOTTOM) { onChange( item.type, commandType.BOTTOM, { ...originalStyle, bottom: Number(get(originalStyle, "marginBottom", 0)) + Number(currentOffset.y), }, isKeyPressed ); } if (item.command === commandType.LEFT) { onChange( item.type, commandType.LEFT, { ...originalStyle, left: Number(get(originalStyle, "marginLeft", 0)) + Number(currentOffset.x), }, isKeyPressed ); } } return { currentOffset }; }); const marginIncomingStyle = getObjectFromStyle(styleTypes.MARGIN, style); const paddingIncomingStyle = getObjectFromStyle(styleTypes.PADDING, style); const highlightMarginTop = getShouldBeActivated( isMarginHovered[1], isKeyPressed ).top; const highlightMarginRight = getShouldBeActivated( isMarginHovered[1], isKeyPressed ).right; const highlightMarginBottom = getShouldBeActivated( isMarginHovered[1], isKeyPressed ).bottom; const highlightMarginLeft = getShouldBeActivated( isMarginHovered[1], isKeyPressed ).left; const highlightPaddingTop = getShouldBeActivated( isPaddingHovered[1], isKeyPressed ).top; const highlightPaddingRight = getShouldBeActivated( isPaddingHovered[1], isKeyPressed ).right; const highlightPaddingBottom = getShouldBeActivated( isPaddingHovered[1], isKeyPressed ).bottom; const highlightPaddingLeft = getShouldBeActivated( isPaddingHovered[1], isKeyPressed ).left; const marginTopLayer = { ...marginStyles.topLayer, padding: "10px 22px", ...(isMarginHovered[0] && highlightMarginTop && { opacity: 0.35, backgroundColor: "#1c2b3a" }), }; const marginRightLayer = { ...marginStyles.rightLayer, padding: "10px 22px", ...(isMarginHovered[0] && highlightMarginRight && { opacity: 0.35, backgroundColor: "#1c2b3a" }), }; const marginBottomLayer = { ...marginStyles.bottomLayer, padding: "10px 22px", ...(isMarginHovered[0] && highlightMarginBottom && { opacity: 0.35, backgroundColor: "#1c2b3a" }), }; const marginLeftLayer = { ...marginStyles.leftLayer, padding: "10px 22px", ...(isMarginHovered[0] && highlightMarginLeft && { opacity: 0.35, backgroundColor: "#1c2b3a" }), }; const paddingTopLayer = { ...paddingStyles.topLayer, padding: "7px 0", ...(isPaddingHovered[0] && highlightPaddingTop && { opacity: 0.35, backgroundColor: "#1c2b3a" }), }; const paddingRightLayer = { ...paddingStyles.rightLayer, padding: "7px 0", ...(isPaddingHovered[0] && highlightPaddingRight && { opacity: 0.35, backgroundColor: "#1c2b3a" }), }; const paddingBottomLayer = { ...paddingStyles.bottomLayer, padding: "7px 0", ...(isPaddingHovered[0] && highlightPaddingBottom && { opacity: 0.35, backgroundColor: "#1c2b3a" }), }; const paddingLeftLayer = { ...paddingStyles.leftLayer, padding: "7px 0", ...(isPaddingHovered[0] && highlightPaddingLeft && { opacity: 0.35, backgroundColor: "#1c2b3a" }), }; // const useThisRef = { [styleType]: dragRefMarginTop }; return (
Margin {[ previewRefMarginTop, previewRefMarginRight, previewRefMarginBottom, previewRefMarginLeft, ].map((itm, k) => ( ))} {[ previewRefPaddingTop, previewRefPaddingRight, previewRefPaddingBottom, previewRefPaddingLeft, ].map((itm, k) => ( ))} setIsMarginHovered([true, commandType.RIGHT])} onMouseLeave={() => setIsMarginHovered([false, commandType.RIGHT])} style={marginRightLayer} ref={dragRefMarginRight} > {marginIncomingStyle.right} setIsMarginHovered([true, commandType.LEFT])} onMouseLeave={() => setIsMarginHovered([false, commandType.LEFT])} style={marginLeftLayer} ref={dragRefMarginLeft} > {marginIncomingStyle.left}
Padding setIsPaddingHovered([true, commandType.RIGHT])} onMouseLeave={() => setIsPaddingHovered([false, commandType.RIGHT])} style={paddingRightLayer} ref={dragRefPaddingRight} > {paddingIncomingStyle.right} setIsPaddingHovered([true, commandType.LEFT])} onMouseLeave={() => setIsPaddingHovered([false, commandType.LEFT])} style={paddingLeftLayer} ref={dragRefPaddingLeft} > {paddingIncomingStyle.left} setIsPaddingHovered([true, commandType.TOP])} onMouseLeave={() => setIsPaddingHovered([false, commandType.TOP])} style={paddingTopLayer} ref={dragRefPaddingTop} > {paddingIncomingStyle.top} setIsPaddingHovered([true, commandType.BOTTOM])} onMouseLeave={() => setIsPaddingHovered([false, commandType.BOTTOM])} style={paddingBottomLayer} ref={dragRefPaddingBottom} > {paddingIncomingStyle.bottom}
setIsMarginHovered([true, commandType.TOP])} onMouseLeave={() => setIsMarginHovered([false, commandType.TOP])} style={marginTopLayer} ref={dragRefMarginTop} > {marginIncomingStyle.top} setIsMarginHovered([true, commandType.BOTTOM])} onMouseLeave={() => setIsMarginHovered([false, commandType.BOTTOM])} style={marginBottomLayer} ref={dragRefMarginBottom} > {marginIncomingStyle.bottom}
); }; /** * A property component that let's the user define the spacing (margin and padding) for an object * * Returns a modified version of the provided style object based on how the user clicks and drags the padding or margin controls * * User can apply their changes to all sides by holding down the [shift] key as they drag, or apply to the opposite side when the [ctrl] or [cmd] key is held * */ export const Spacing: React.FC = ({ style, onChange }) => { const handleChange = ( type: styleTypes, action: commandType, newStyle: React.CSSProperties, isKeyPressed: IKeysPressed ) => { if (newStyle) { let value = get(newStyle, `${action.toLowerCase()}`, 0); if (type === styleTypes.PADDING && value < 0) value = 0; let modifiedStyle = {}; const shouldBeActivated = getShouldBeActivated(action, isKeyPressed); if (shouldBeActivated.top) modifiedStyle[`${type}Top`] = value; if (shouldBeActivated.right) modifiedStyle[`${type}Right`] = value; if (shouldBeActivated.bottom) modifiedStyle[`${type}Bottom`] = value; if (shouldBeActivated.left) modifiedStyle[`${type}Left`] = value; // console.log(style, modifiedStyle); onChange({ ...style, ...modifiedStyle, }); } }; return (
); }; export default Spacing;