From 70b9aa5e2e699da74907a0f0fab2756347990754 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Wed, 6 Mar 2024 14:44:10 +0100 Subject: [PATCH 01/25] Minimal functional version - selected portion of the title is now movable via the visible interaction boxes - commiting before I rewrite this system with different approach --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 91 ++++++++++++++++ .../SelectionBox/styles.module.css | 30 ++++++ .../components/Hero/SelectedLabel/index.tsx | 102 +++++++++++++----- .../Hero/SelectedLabel/styles.module.css | 28 +---- 4 files changed, 198 insertions(+), 53 deletions(-) create mode 100644 docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx create mode 100644 docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx new file mode 100644 index 000000000000..ccd26ca29f3a --- /dev/null +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -0,0 +1,91 @@ +import clsx from 'clsx'; +import React, { useEffect, useState } from 'react'; +import styles from './styles.module.css'; +import Draggable from 'react-draggable'; + +export enum CornerIdEnum { + TOP_LEFT, + TOP_RIGHT, + BOTTOM_LEFT, + BOTTOM_RIGHT, +} + +const SelectionBox: React.FC<{ + propagationFunction: ( + position: { deltaX: number; deltaY: number }, + cornerIdentifier: CornerIdEnum + ) => void; + cornerIdentifier: CornerIdEnum; +}> = ({ propagationFunction, cornerIdentifier }) => { + const returnToOrigin = false; + + // set personal css + const cssSelector = clsx( + styles.selectionBox, + cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || + cornerIdentifier == CornerIdEnum.BOTTOM_RIGHT + ? styles.boxLower + : styles.boxUpper, + cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || + cornerIdentifier == CornerIdEnum.TOP_LEFT + ? styles.boxLeft + : styles.boxRight + ); + + enum PositionEnum { + ABSOLUTE = 'absolute', + FIXED = 'fixed', + } + + enum AxisEnum { + NONE = 'none', + BOTH = 'both', + } + + const [draggabilityOptions, setDraggabilityOptions] = useState({ + position: PositionEnum.ABSOLUTE, + axis: AxisEnum.NONE, + }); + const [positionStyles, setPositionsStyles] = useState({ + top: null, + left: null, + }); + + // for the period of being moved, boxes will be completely detached from their surrounding layout + const detachBox = () => { + setDraggabilityOptions({ + position: PositionEnum.FIXED, + axis: AxisEnum.BOTH, + }); + }; + + // after being dropped by the user, boxes are reattached to their surrounding layout + const attachBox = () => { + setDraggabilityOptions({ + position: PositionEnum.ABSOLUTE, + axis: AxisEnum.NONE, + }); + setPositionsStyles({ top: null, left: null }); + }; + + const moveToCursor = (position: { x: number; y: number }) => { + //setPositionsStyles({top: position.y, left: position.x}); + }; + + // use animation with the destination being cursor position + // todo: detach the grabbed box from website layout, it hinders it's free flow + return ( + { + propagationFunction(position, cornerIdentifier); + }} + allowAnyClick={false} + axis={draggabilityOptions.axis}> +
+
+ ); +}; + +export default SelectionBox; diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css new file mode 100644 index 000000000000..e2ffdd9c1c33 --- /dev/null +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css @@ -0,0 +1,30 @@ +.selectionBox { + position: absolute; + width: 12px; + height: 12px; + + background: var(--swm-white); + border: 2px solid var(--swm-landing-heading-selected-border); + + cursor: grab; +} + +.selectionBox:active { + cursor: grabbing; +} + +.boxUpper { + top: -6px; +} + +.boxLower { + bottom: -14px; +} + +.boxLeft { + left: -14px; +} + +.boxRight { + right: -14px; +} diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index eac983ba2a31..87753ef08039 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -1,37 +1,85 @@ import clsx from 'clsx'; -import React from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import styles from './styles.module.css'; +import SelectionBox, { CornerIdEnum } from './SelectionBox'; const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ children, }) => { + const selectionContainerRef = useRef(null); + const [sizeStyles, setSizeStyles] = useState({ width: null, height: null }); + const [positionStyles, setPositionStyles] = useState({ top: 0, left: 0 }); + const [minSizeStyles, setMinSizeStyles] = useState({ + minWidth: 0, + minHeight: 0, + }); + + useEffect(() => { + const currentWidth = selectionContainerRef.current.clientWidth; + const currentHeight = selectionContainerRef.current.clientHeight; + + setMinSizeStyles({ + minWidth: currentWidth, + minHeight: currentHeight, + }); + setSizeStyles({ + width: currentWidth, + height: currentHeight, + }); + }, []); + + let positionPropagator = ( + position: { deltaX: number; deltaY: number }, + cornerIdentifier: CornerIdEnum + ) => { + // changing selectionContainer will automatically adjust position of selectionBoxes as well + // all changes are done through css + const dirHorizontal = + cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || + cornerIdentifier == CornerIdEnum.TOP_LEFT; + const dirVertical = + cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || + cornerIdentifier == CornerIdEnum.BOTTOM_RIGHT; + + const positionAdjustment = { + x: dirHorizontal ? position.deltaX : 0, + y: dirVertical ? 0 : position.deltaY, + }; + const resizingDirection = { + x: dirHorizontal ? -1 : 1, + y: dirVertical ? 1 : -1, + }; + + setPositionStyles({ + left: positionStyles.left + positionAdjustment.x, + top: positionStyles.top + positionAdjustment.y, + }); + setSizeStyles({ + width: sizeStyles.width + position.deltaX * resizingDirection.x, + height: sizeStyles.height + position.deltaY * resizingDirection.y, + }); + }; + return ( - -
-
-
-
-
+ +
+ + + + {children}
diff --git a/docs/src/components/Hero/SelectedLabel/styles.module.css b/docs/src/components/Hero/SelectedLabel/styles.module.css index e699321122b8..c32aafde5cc2 100644 --- a/docs/src/components/Hero/SelectedLabel/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/styles.module.css @@ -5,6 +5,7 @@ .selection { display: inline-block; + position: relative; padding: 2px 10px 8px; color: var(--swm-landing-heading-selected); line-height: 1; @@ -20,29 +21,4 @@ .selectionContainer { position: relative; -} - -.selectionBox { - position: absolute; - width: 12px; - height: 12px; - - background: var(--swm-white); - border: 2px solid var(--swm-landing-heading-selected-border); -} - -.boxUpper { - top: -6px; -} - -.boxLower { - bottom: -14px; -} - -.boxLeft { - left: -14px; -} - -.boxRight { - right: -14px; -} +} \ No newline at end of file From 46f5eb0b5048e37c2caa3feecd0364aaa84e695c Mon Sep 17 00:00:00 2001 From: LatekVo Date: Wed, 6 Mar 2024 17:40:53 +0100 Subject: [PATCH 02/25] Reworked movement so that jittering is insignificant and layout is not affected. Committing before reworking dragging mechanism and adding visual improvements. --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 46 +------------ .../components/Hero/SelectedLabel/index.tsx | 69 +++++++++++++------ .../Hero/SelectedLabel/styles.module.css | 8 +++ .../src/components/Hero/StartScreen/index.tsx | 8 ++- .../Hero/StartScreen/styles.module.css | 10 ++- 5 files changed, 73 insertions(+), 68 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx index ccd26ca29f3a..66829874067c 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -32,46 +32,6 @@ const SelectionBox: React.FC<{ : styles.boxRight ); - enum PositionEnum { - ABSOLUTE = 'absolute', - FIXED = 'fixed', - } - - enum AxisEnum { - NONE = 'none', - BOTH = 'both', - } - - const [draggabilityOptions, setDraggabilityOptions] = useState({ - position: PositionEnum.ABSOLUTE, - axis: AxisEnum.NONE, - }); - const [positionStyles, setPositionsStyles] = useState({ - top: null, - left: null, - }); - - // for the period of being moved, boxes will be completely detached from their surrounding layout - const detachBox = () => { - setDraggabilityOptions({ - position: PositionEnum.FIXED, - axis: AxisEnum.BOTH, - }); - }; - - // after being dropped by the user, boxes are reattached to their surrounding layout - const attachBox = () => { - setDraggabilityOptions({ - position: PositionEnum.ABSOLUTE, - axis: AxisEnum.NONE, - }); - setPositionsStyles({ top: null, left: null }); - }; - - const moveToCursor = (position: { x: number; y: number }) => { - //setPositionsStyles({top: position.y, left: position.x}); - }; - // use animation with the destination being cursor position // todo: detach the grabbed box from website layout, it hinders it's free flow return ( @@ -80,10 +40,8 @@ const SelectionBox: React.FC<{ propagationFunction(position, cornerIdentifier); }} allowAnyClick={false} - axis={draggabilityOptions.axis}> -
+ axis={'none'}> +
); }; diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 87753ef08039..4186cb5c860d 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -7,24 +7,31 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ children, }) => { const selectionContainerRef = useRef(null); - const [sizeStyles, setSizeStyles] = useState({ width: null, height: null }); - const [positionStyles, setPositionStyles] = useState({ top: 0, left: 0 }); - const [minSizeStyles, setMinSizeStyles] = useState({ - minWidth: 0, - minHeight: 0, + const [positionStyles, setPositionStyles] = useState({ + top: 0, + left: 0, + width: null, + height: null, + }); + const [constantStyles, setConstantStyles] = useState({ + minWidth: null, + minHeight: null, + setAbsolute: false, }); useEffect(() => { - const currentWidth = selectionContainerRef.current.clientWidth; - const currentHeight = selectionContainerRef.current.clientHeight; - - setMinSizeStyles({ - minWidth: currentWidth, - minHeight: currentHeight, + const rect = selectionContainerRef.current.getBoundingClientRect(); + console.log(rect); + setPositionStyles({ + top: 0, // rect.top, + left: 0, // rect.left, + width: rect.width, + height: rect.height, }); - setSizeStyles({ - width: currentWidth, - height: currentHeight, + setConstantStyles({ + minWidth: rect.width, + minHeight: rect.height, + setAbsolute: true, }); }, []); @@ -53,21 +60,34 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ setPositionStyles({ left: positionStyles.left + positionAdjustment.x, top: positionStyles.top + positionAdjustment.y, - }); - setSizeStyles({ - width: sizeStyles.width + position.deltaX * resizingDirection.x, - height: sizeStyles.height + position.deltaY * resizingDirection.y, + width: positionStyles.width + position.deltaX * resizingDirection.x, + height: positionStyles.height + position.deltaY * resizingDirection.y, }); }; + const textScale = { + x: positionStyles.width / constantStyles.minWidth, + y: positionStyles.height / constantStyles.minHeight, + }; + + let smallerScale = textScale.x < textScale.y ? textScale.x : textScale.y; + if (smallerScale < 1) smallerScale = 1; + return ( + style={{ + transform: `translate(${positionStyles.left}px, ${positionStyles.top}px)`, + position: constantStyles.setAbsolute ? 'absolute' : 'relative', + }}>
+ style={{ + width: positionStyles.width, + height: positionStyles.height, + ...constantStyles, + }}> @@ -80,7 +100,14 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ - {children} + + {children} +
); diff --git a/docs/src/components/Hero/SelectedLabel/styles.module.css b/docs/src/components/Hero/SelectedLabel/styles.module.css index c32aafde5cc2..f97822966845 100644 --- a/docs/src/components/Hero/SelectedLabel/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/styles.module.css @@ -9,6 +9,7 @@ padding: 2px 10px 8px; color: var(--swm-landing-heading-selected); line-height: 1; + z-index: 1; /* normally one would do this with border dashed but that doesn't allow for modifying spacing between dashes */ /* prettier-ignore */ @@ -21,4 +22,11 @@ .selectionContainer { position: relative; + text-align: center; +} + +.movableHeader { + left: 50%; + top: 50%; + transform: translate(-50%, -50%); } \ No newline at end of file diff --git a/docs/src/components/Hero/StartScreen/index.tsx b/docs/src/components/Hero/StartScreen/index.tsx index f3e01cf9ef4a..0e7ef8f7af15 100644 --- a/docs/src/components/Hero/StartScreen/index.tsx +++ b/docs/src/components/Hero/StartScreen/index.tsx @@ -13,10 +13,14 @@ const StartScreen = () => {

- React Native +
+ React Native +

+ Beyond the limitations +

+
Reanimated

-

Beyond the limitations

diff --git a/docs/src/components/Hero/StartScreen/styles.module.css b/docs/src/components/Hero/StartScreen/styles.module.css index 5ee38fa5e4df..6e9790a59d28 100644 --- a/docs/src/components/Hero/StartScreen/styles.module.css +++ b/docs/src/components/Hero/StartScreen/styles.module.css @@ -16,6 +16,14 @@ height: fit-content; } +.headingColumn { + display: inline-flex; + flex-direction: column; + padding: 0; + margin: 0; + width: max-content; +} + .headingLabel { font-family: var(--swm-title-landing-font); font-size: 64px; @@ -39,7 +47,7 @@ margin-top: 32px; margin-bottom: 56px; - width: 600px; + width: fit-content; color: var(--swm-landing-heading); } From a4ef1bc27777007ac867178bd8ce4236fd025ee8 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Thu, 7 Mar 2024 10:38:25 +0100 Subject: [PATCH 03/25] last functional version, added mouse capture --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 80 +++++++++++++++---- .../components/Hero/SelectedLabel/index.tsx | 16 ++-- .../Hero/StartScreen/styles.module.css | 1 + 3 files changed, 73 insertions(+), 24 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx index 66829874067c..489d7bdd95bd 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -12,36 +12,84 @@ export enum CornerIdEnum { const SelectionBox: React.FC<{ propagationFunction: ( - position: { deltaX: number; deltaY: number }, + position: { x: number; y: number }, cornerIdentifier: CornerIdEnum ) => void; cornerIdentifier: CornerIdEnum; }> = ({ propagationFunction, cornerIdentifier }) => { const returnToOrigin = false; + const [classList, setClassList] = useState(''); - // set personal css - const cssSelector = clsx( - styles.selectionBox, - cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || - cornerIdentifier == CornerIdEnum.BOTTOM_RIGHT - ? styles.boxLower - : styles.boxUpper, - cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || - cornerIdentifier == CornerIdEnum.TOP_LEFT - ? styles.boxLeft - : styles.boxRight - ); + useEffect(() => { + console.log('running useEffect 1'); + setClassList( + clsx( + styles.selectionBox, + cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || + cornerIdentifier == CornerIdEnum.BOTTOM_RIGHT + ? styles.boxLower + : styles.boxUpper, + cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || + cornerIdentifier == CornerIdEnum.TOP_LEFT + ? styles.boxLeft + : styles.boxRight + ) + ); + }, []); + + const [uploadPosition, setUploadPosition] = useState(false); + + const startMouseTracker = () => { + console.log('starting mouse tracking'); + setUploadPosition(true); + }; + + const stopMouseTracker = () => { + console.log('stopping mouse tracking'); + setUploadPosition(false); + }; + + useEffect(() => { + const extractCoords = (event) => { + return; + // note for tommorrow: this is running only when it's supposed to as of latest. + console.log(event.offsetX, event.offsetY); + console.log(event); + propagationFunction( + { + x: event.offsetX, + y: event.offsetY, + }, + cornerIdentifier + ); + }; + + if (uploadPosition) { + window.addEventListener('mousemove', extractCoords); + } else { + window.removeEventListener('mousemove', extractCoords); + } + + return () => { + window.removeEventListener('mousemove', extractCoords); + }; + }, [uploadPosition]); // use animation with the destination being cursor position // todo: detach the grabbed box from website layout, it hinders it's free flow return ( { - propagationFunction(position, cornerIdentifier); + onStart={startMouseTracker} + onStop={stopMouseTracker} + onDrag={(event, dragEvent) => { + propagationFunction( + { x: dragEvent.deltaX, y: dragEvent.deltaY }, + cornerIdentifier + ); }} allowAnyClick={false} axis={'none'}> -
+
); }; diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 4186cb5c860d..48767860d3e6 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -36,7 +36,7 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ }, []); let positionPropagator = ( - position: { deltaX: number; deltaY: number }, + position: { x: number; y: number }, cornerIdentifier: CornerIdEnum ) => { // changing selectionContainer will automatically adjust position of selectionBoxes as well @@ -45,23 +45,23 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || cornerIdentifier == CornerIdEnum.TOP_LEFT; const dirVertical = - cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || - cornerIdentifier == CornerIdEnum.BOTTOM_RIGHT; + cornerIdentifier == CornerIdEnum.TOP_LEFT || + cornerIdentifier == CornerIdEnum.TOP_RIGHT; const positionAdjustment = { - x: dirHorizontal ? position.deltaX : 0, - y: dirVertical ? 0 : position.deltaY, + x: dirHorizontal ? position.x : 0, + y: dirVertical ? position.y : 0, }; const resizingDirection = { x: dirHorizontal ? -1 : 1, - y: dirVertical ? 1 : -1, + y: dirVertical ? -1 : 1, }; setPositionStyles({ left: positionStyles.left + positionAdjustment.x, top: positionStyles.top + positionAdjustment.y, - width: positionStyles.width + position.deltaX * resizingDirection.x, - height: positionStyles.height + position.deltaY * resizingDirection.y, + width: positionStyles.width + position.x * resizingDirection.x, + height: positionStyles.height + position.y * resizingDirection.y, }); }; diff --git a/docs/src/components/Hero/StartScreen/styles.module.css b/docs/src/components/Hero/StartScreen/styles.module.css index 6e9790a59d28..eff99c9196a8 100644 --- a/docs/src/components/Hero/StartScreen/styles.module.css +++ b/docs/src/components/Hero/StartScreen/styles.module.css @@ -22,6 +22,7 @@ padding: 0; margin: 0; width: max-content; + margin-right: 8px; } .headingLabel { From f7f65db983823e70077971740ee64f342abeee4c Mon Sep 17 00:00:00 2001 From: LatekVo Date: Thu, 7 Mar 2024 14:05:26 +0100 Subject: [PATCH 04/25] added panning, visual changes --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 76 +++++-------------- .../SelectionBox/styles.module.css | 24 +++++- .../components/Hero/SelectedLabel/index.tsx | 66 +++++++++++----- .../Hero/SelectedLabel/styles.module.css | 1 + 4 files changed, 88 insertions(+), 79 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx index 489d7bdd95bd..d92a43c17bb3 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -8,6 +8,7 @@ export enum CornerIdEnum { TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, + CENTER, } const SelectionBox: React.FC<{ @@ -16,80 +17,41 @@ const SelectionBox: React.FC<{ cornerIdentifier: CornerIdEnum ) => void; cornerIdentifier: CornerIdEnum; -}> = ({ propagationFunction, cornerIdentifier }) => { - const returnToOrigin = false; + children?: React.ReactNode; +}> = ({ propagationFunction, cornerIdentifier, children }) => { const [classList, setClassList] = useState(''); useEffect(() => { - console.log('running useEffect 1'); setClassList( - clsx( - styles.selectionBox, - cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || - cornerIdentifier == CornerIdEnum.BOTTOM_RIGHT - ? styles.boxLower - : styles.boxUpper, - cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || - cornerIdentifier == CornerIdEnum.TOP_LEFT - ? styles.boxLeft - : styles.boxRight - ) + cornerIdentifier == CornerIdEnum.CENTER + ? clsx(styles.movableHeader) + : clsx( + styles.selectionBox, + cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || + cornerIdentifier == CornerIdEnum.BOTTOM_RIGHT + ? styles.boxLower + : styles.boxUpper, + cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || + cornerIdentifier == CornerIdEnum.TOP_LEFT + ? styles.boxLeft + : styles.boxRight + ) ); }, []); - const [uploadPosition, setUploadPosition] = useState(false); - - const startMouseTracker = () => { - console.log('starting mouse tracking'); - setUploadPosition(true); - }; - - const stopMouseTracker = () => { - console.log('stopping mouse tracking'); - setUploadPosition(false); - }; - - useEffect(() => { - const extractCoords = (event) => { - return; - // note for tommorrow: this is running only when it's supposed to as of latest. - console.log(event.offsetX, event.offsetY); - console.log(event); - propagationFunction( - { - x: event.offsetX, - y: event.offsetY, - }, - cornerIdentifier - ); - }; - - if (uploadPosition) { - window.addEventListener('mousemove', extractCoords); - } else { - window.removeEventListener('mousemove', extractCoords); - } - - return () => { - window.removeEventListener('mousemove', extractCoords); - }; - }, [uploadPosition]); - // use animation with the destination being cursor position // todo: detach the grabbed box from website layout, it hinders it's free flow return ( { + onDrag={(event: any) => { propagationFunction( - { x: dragEvent.deltaX, y: dragEvent.deltaY }, + { x: event.movementX, y: event.movementY }, cornerIdentifier ); }} allowAnyClick={false} axis={'none'}> -
+
{children}
); }; diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css index e2ffdd9c1c33..95068d569ec0 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css @@ -2,15 +2,35 @@ position: absolute; width: 12px; height: 12px; + z-index: 2; background: var(--swm-white); border: 2px solid var(--swm-landing-heading-selected-border); cursor: grab; + transition: scale 50ms ease-in-out; } .selectionBox:active { cursor: grabbing; + scale: 1.35; +} + +.selectionBox:hover { + scale: 1.35; +} + +.selectionContainer { + position: relative; + text-align: center; + margin: 0 10px; +} + +.movableHeader { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); } .boxUpper { @@ -22,9 +42,9 @@ } .boxLeft { - left: -14px; + left: -25px; } .boxRight { - right: -14px; + right: -25px; } diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 48767860d3e6..df5efddd610f 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -14,14 +14,13 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ height: null, }); const [constantStyles, setConstantStyles] = useState({ - minWidth: null, - minHeight: null, + initialWidth: null, + initialHeight: null, setAbsolute: false, }); useEffect(() => { const rect = selectionContainerRef.current.getBoundingClientRect(); - console.log(rect); setPositionStyles({ top: 0, // rect.top, left: 0, // rect.left, @@ -29,8 +28,8 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ height: rect.height, }); setConstantStyles({ - minWidth: rect.width, - minHeight: rect.height, + initialWidth: rect.width, + initialHeight: rect.height, setAbsolute: true, }); }, []); @@ -56,22 +55,46 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ x: dirHorizontal ? -1 : 1, y: dirVertical ? -1 : 1, }; + const sizeChange = { + x: position.x * resizingDirection.x, + y: position.y * resizingDirection.y, + }; + + // adjust variables when dragging the center + if (cornerIdentifier == CornerIdEnum.CENTER) { + positionAdjustment.x = sizeChange.x; + positionAdjustment.y = sizeChange.y; + sizeChange.x = 0; + sizeChange.y = 0; + } + + // stop overreduction in size + if (positionStyles.width + sizeChange.x < 0) + sizeChange.x = -positionStyles.width; + if (positionStyles.height + sizeChange.y < 0) + sizeChange.y = -positionStyles.height; + + // stop dragging a minimized object + if (positionStyles.width - positionAdjustment.x < 0) + positionAdjustment.x = 0; + if (positionStyles.height - positionAdjustment.y < 0) + positionAdjustment.y = 0; setPositionStyles({ left: positionStyles.left + positionAdjustment.x, top: positionStyles.top + positionAdjustment.y, - width: positionStyles.width + position.x * resizingDirection.x, - height: positionStyles.height + position.y * resizingDirection.y, + width: positionStyles.width + sizeChange.x, + height: positionStyles.height + sizeChange.y, }); }; const textScale = { - x: positionStyles.width / constantStyles.minWidth, - y: positionStyles.height / constantStyles.minHeight, + x: (positionStyles.width / constantStyles.initialWidth) * 0.94 + 0.06, + y: (positionStyles.height / constantStyles.initialHeight) * 1.1 - 0.1, }; - let smallerScale = textScale.x < textScale.y ? textScale.x : textScale.y; - if (smallerScale < 1) smallerScale = 1; + if (textScale.x < 0) textScale.x = 0; + if (textScale.y < 0) textScale.y = 0; return ( = ({ style={{ width: positionStyles.width, height: positionStyles.height, - ...constantStyles, }}> = ({ - - {children} - + + + {children} + +
); diff --git a/docs/src/components/Hero/SelectedLabel/styles.module.css b/docs/src/components/Hero/SelectedLabel/styles.module.css index f97822966845..7f6ccb61ff0a 100644 --- a/docs/src/components/Hero/SelectedLabel/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/styles.module.css @@ -23,6 +23,7 @@ .selectionContainer { position: relative; text-align: center; + margin: 0 10px; } .movableHeader { From da5e289dd3ace5135e3a5491295310b4086aba3d Mon Sep 17 00:00:00 2001 From: LatekVo Date: Thu, 7 Mar 2024 15:32:00 +0100 Subject: [PATCH 05/25] converted rendering system to use references instead of rerenders --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 5 +- .../SelectionBox/styles.module.css | 10 ++- .../components/Hero/SelectedLabel/index.tsx | 70 +++++++++++++++---- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx index d92a43c17bb3..fd9552903fa2 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -24,9 +24,10 @@ const SelectionBox: React.FC<{ useEffect(() => { setClassList( cornerIdentifier == CornerIdEnum.CENTER - ? clsx(styles.movableHeader) + ? clsx(styles.movableHeader, styles.movable) : clsx( styles.selectionBox, + styles.movable, cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || cornerIdentifier == CornerIdEnum.BOTTOM_RIGHT ? styles.boxLower @@ -39,6 +40,8 @@ const SelectionBox: React.FC<{ ); }, []); + console.log('Rendering SelectionBox'); + // use animation with the destination being cursor position // todo: detach the grabbed box from website layout, it hinders it's free flow return ( diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css index 95068d569ec0..022fac921aa4 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css @@ -1,3 +1,11 @@ +.movable { + cursor: grab; +} + +.movable:active { + cursor: grabbing; +} + .selectionBox { position: absolute; width: 12px; @@ -7,12 +15,10 @@ background: var(--swm-white); border: 2px solid var(--swm-landing-heading-selected-border); - cursor: grab; transition: scale 50ms ease-in-out; } .selectionBox:active { - cursor: grabbing; scale: 1.35; } diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index df5efddd610f..cb719263e89b 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -6,13 +6,42 @@ import SelectionBox, { CornerIdEnum } from './SelectionBox'; const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ children, }) => { + const selectionRef = useRef(null); const selectionContainerRef = useRef(null); - const [positionStyles, setPositionStyles] = useState({ + const textLabelRef = useRef(null); + + const positionStyles = { top: 0, left: 0, width: null, height: null, - }); + }; + const setPositionStyles = (newPositionStyles: { + top: number; + left: number; + width: number; + height: number; + }) => { + // save changes + positionStyles.top = newPositionStyles.top; + positionStyles.left = newPositionStyles.left; + positionStyles.width = newPositionStyles.width; + positionStyles.height = newPositionStyles.height; + + // apply changes to refs + selectionRef.current.style.transform = `translate(${positionStyles.left}px, ${positionStyles.top}px)`; + selectionContainerRef.current.style.width = `${positionStyles.width}px`; + selectionContainerRef.current.style.height = `${positionStyles.height}px`; + }; + + const textScale = { + x: 1, + y: 1, + }; + const applyTextScale = () => { + textLabelRef.current.style.transform = `translate(-50%, -50%) scale(${textScale.x}, ${textScale.y})`; + }; + const [constantStyles, setConstantStyles] = useState({ initialWidth: null, initialHeight: null, @@ -21,12 +50,6 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ useEffect(() => { const rect = selectionContainerRef.current.getBoundingClientRect(); - setPositionStyles({ - top: 0, // rect.top, - left: 0, // rect.left, - width: rect.width, - height: rect.height, - }); setConstantStyles({ initialWidth: rect.width, initialHeight: rect.height, @@ -34,6 +57,16 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ }); }, []); + useEffect(() => { + const rect = selectionContainerRef.current.getBoundingClientRect(); + setPositionStyles({ + top: 0, // rect.top, + left: 0, // rect.left, + width: rect.width, + height: rect.height, + }); + }, [constantStyles]); + let positionPropagator = ( position: { x: number; y: number }, cornerIdentifier: CornerIdEnum @@ -86,26 +119,32 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ width: positionStyles.width + sizeChange.x, height: positionStyles.height + sizeChange.y, }); - }; - const textScale = { - x: (positionStyles.width / constantStyles.initialWidth) * 0.94 + 0.06, - y: (positionStyles.height / constantStyles.initialHeight) * 1.1 - 0.1, + // these magic numbers are a result of disparity between font's apparent and actual size + textScale.x = + (positionStyles.width / constantStyles.initialWidth) * 0.96 + 0.04; + textScale.y = + (positionStyles.height / constantStyles.initialHeight) * 1.255 - 0.255; + + if (textScale.x < 0) textScale.x = 0; + if (textScale.y < 0) textScale.y = 0; + + applyTextScale(); }; - if (textScale.x < 0) textScale.x = 0; - if (textScale.y < 0) textScale.y = 0; + console.log('Rendering SelectedLabel'); return (
= ({ propagationFunction={positionPropagator} cornerIdentifier={CornerIdEnum.CENTER}> Date: Thu, 7 Mar 2024 19:59:21 +0100 Subject: [PATCH 06/25] prettier - fixed file formatting for PR --- docs/src/components/Hero/SelectedLabel/styles.module.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/components/Hero/SelectedLabel/styles.module.css b/docs/src/components/Hero/SelectedLabel/styles.module.css index 7f6ccb61ff0a..4acecf567285 100644 --- a/docs/src/components/Hero/SelectedLabel/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/styles.module.css @@ -30,4 +30,4 @@ left: 50%; top: 50%; transform: translate(-50%, -50%); -} \ No newline at end of file +} From 18e9440b8ad4ddff2a3bc5de10c050b56665524b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ignacy=20=C5=81=C4=85tka?= <74246391+LatekVo@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:07:47 +0100 Subject: [PATCH 07/25] Apply css suggestion. Co-authored-by: Krzysztof Piaskowy --- .../Hero/SelectedLabel/SelectionBox/styles.module.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css index 022fac921aa4..f6cbd9d3520d 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css @@ -11,10 +11,8 @@ width: 12px; height: 12px; z-index: 2; - background: var(--swm-white); border: 2px solid var(--swm-landing-heading-selected-border); - transition: scale 50ms ease-in-out; } From 7efee6d4ed9f9d77b5ba80f08a1772728a7ddb50 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Tue, 12 Mar 2024 14:41:09 +0100 Subject: [PATCH 08/25] Applied review suggestion. Code cleanup. --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 27 +++++----- .../components/Hero/SelectedLabel/index.tsx | 51 ++++++++----------- 2 files changed, 33 insertions(+), 45 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx index fd9552903fa2..ddd00b410ef3 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -1,9 +1,9 @@ import clsx from 'clsx'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import styles from './styles.module.css'; import Draggable from 'react-draggable'; -export enum CornerIdEnum { +export enum DraggableId { TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, @@ -14,42 +14,39 @@ export enum CornerIdEnum { const SelectionBox: React.FC<{ propagationFunction: ( position: { x: number; y: number }, - cornerIdentifier: CornerIdEnum + draggableIdentifier: DraggableId ) => void; - cornerIdentifier: CornerIdEnum; + draggableIdentifier: DraggableId; children?: React.ReactNode; -}> = ({ propagationFunction, cornerIdentifier, children }) => { +}> = ({ propagationFunction, draggableIdentifier, children }) => { const [classList, setClassList] = useState(''); useEffect(() => { setClassList( - cornerIdentifier == CornerIdEnum.CENTER + draggableIdentifier == DraggableId.CENTER ? clsx(styles.movableHeader, styles.movable) : clsx( styles.selectionBox, styles.movable, - cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || - cornerIdentifier == CornerIdEnum.BOTTOM_RIGHT + draggableIdentifier == DraggableId.BOTTOM_LEFT || + draggableIdentifier == DraggableId.BOTTOM_RIGHT ? styles.boxLower : styles.boxUpper, - cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || - cornerIdentifier == CornerIdEnum.TOP_LEFT + draggableIdentifier == DraggableId.BOTTOM_LEFT || + draggableIdentifier == DraggableId.TOP_LEFT ? styles.boxLeft : styles.boxRight ) ); - }, []); - - console.log('Rendering SelectionBox'); + }, [draggableIdentifier]); // use animation with the destination being cursor position - // todo: detach the grabbed box from website layout, it hinders it's free flow return ( { propagationFunction( { x: event.movementX, y: event.movementY }, - cornerIdentifier + draggableIdentifier ); }} allowAnyClick={false} diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index cb719263e89b..4c41b142f8e4 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -1,7 +1,7 @@ import clsx from 'clsx'; import React, { useEffect, useRef, useState } from 'react'; import styles from './styles.module.css'; -import SelectionBox, { CornerIdEnum } from './SelectionBox'; +import SelectionBox, { DraggableId } from './SelectionBox'; const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ children, @@ -67,26 +67,26 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ }); }, [constantStyles]); - let positionPropagator = ( + const positionPropagator = ( position: { x: number; y: number }, - cornerIdentifier: CornerIdEnum + draggableIdentifier: DraggableId ) => { // changing selectionContainer will automatically adjust position of selectionBoxes as well // all changes are done through css - const dirHorizontal = - cornerIdentifier == CornerIdEnum.BOTTOM_LEFT || - cornerIdentifier == CornerIdEnum.TOP_LEFT; - const dirVertical = - cornerIdentifier == CornerIdEnum.TOP_LEFT || - cornerIdentifier == CornerIdEnum.TOP_RIGHT; + const isHorizontal = + draggableIdentifier == DraggableId.BOTTOM_LEFT || + draggableIdentifier == DraggableId.TOP_LEFT; + const isVertical = + draggableIdentifier == DraggableId.TOP_LEFT || + draggableIdentifier == DraggableId.TOP_RIGHT; const positionAdjustment = { - x: dirHorizontal ? position.x : 0, - y: dirVertical ? position.y : 0, + x: isHorizontal ? position.x : 0, + y: isVertical ? position.y : 0, }; const resizingDirection = { - x: dirHorizontal ? -1 : 1, - y: dirVertical ? -1 : 1, + x: isHorizontal ? -1 : 1, + y: isVertical ? -1 : 1, }; const sizeChange = { x: position.x * resizingDirection.x, @@ -94,7 +94,7 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ }; // adjust variables when dragging the center - if (cornerIdentifier == CornerIdEnum.CENTER) { + if (draggableIdentifier == DraggableId.CENTER) { positionAdjustment.x = sizeChange.x; positionAdjustment.y = sizeChange.y; sizeChange.x = 0; @@ -132,43 +132,34 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ applyTextScale(); }; - console.log('Rendering SelectedLabel'); - return ( -
+
+ draggableIdentifier={DraggableId.TOP_LEFT}> + draggableIdentifier={DraggableId.TOP_RIGHT}> + draggableIdentifier={DraggableId.BOTTOM_LEFT}> + draggableIdentifier={DraggableId.BOTTOM_RIGHT}> + draggableIdentifier={DraggableId.CENTER}> {children} From c752c644c5a789567db3590fa95c0617ecddcf03 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Wed, 13 Mar 2024 14:12:52 +0100 Subject: [PATCH 09/25] Fixed sudden moves being stopped. Code cleanup. --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 2 +- .../components/Hero/SelectedLabel/index.tsx | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx index ddd00b410ef3..9f4df1633424 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -38,7 +38,7 @@ const SelectionBox: React.FC<{ : styles.boxRight ) ); - }, [draggableIdentifier]); + }, []); // use animation with the destination being cursor position return ( diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 4c41b142f8e4..5ddf08cfc0bc 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -108,11 +108,12 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ sizeChange.y = -positionStyles.height; // stop dragging a minimized object - if (positionStyles.width - positionAdjustment.x < 0) - positionAdjustment.x = 0; - if (positionStyles.height - positionAdjustment.y < 0) - positionAdjustment.y = 0; - + if (draggableIdentifier !== DraggableId.CENTER) { + if (positionStyles.width - positionAdjustment.x < 0) + positionAdjustment.x = 0; + if (positionStyles.height - positionAdjustment.y < 0) + positionAdjustment.y = 0; + } setPositionStyles({ left: positionStyles.left + positionAdjustment.x, top: positionStyles.top + positionAdjustment.y, @@ -121,10 +122,16 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ }); // these magic numbers are a result of disparity between font's apparent and actual size + const scaleOffsetX = 0.96; + const scaleOffsetY = 1.255; + + // this is a limit with offset function, initial scale is 1.0, but it converges into x=0.96 and y=1.255 textScale.x = - (positionStyles.width / constantStyles.initialWidth) * 0.96 + 0.04; + positionStyles.width / constantStyles.initialWidth + * scaleOffsetX - scaleOffsetX + 1.0; textScale.y = - (positionStyles.height / constantStyles.initialHeight) * 1.255 - 0.255; + positionStyles.height / constantStyles.initialHeight + * scaleOffsetY - scaleOffsetY + 1.0; if (textScale.x < 0) textScale.x = 0; if (textScale.y < 0) textScale.y = 0; From db00f7235f55d4b86069d32125ec1926afb7cf27 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Wed, 13 Mar 2024 15:04:09 +0100 Subject: [PATCH 10/25] Added unstaged changes from previous commit. --- .../src/components/Hero/SelectedLabel/index.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 4c41b142f8e4..1bd6dc2cce26 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -108,11 +108,12 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ sizeChange.y = -positionStyles.height; // stop dragging a minimized object - if (positionStyles.width - positionAdjustment.x < 0) - positionAdjustment.x = 0; - if (positionStyles.height - positionAdjustment.y < 0) - positionAdjustment.y = 0; - + if (draggableIdentifier !== DraggableId.CENTER) { + if (positionStyles.width - positionAdjustment.x < 0) + positionAdjustment.x = 0; + if (positionStyles.height - positionAdjustment.y < 0) + positionAdjustment.y = 0; + } setPositionStyles({ left: positionStyles.left + positionAdjustment.x, top: positionStyles.top + positionAdjustment.y, @@ -121,10 +122,12 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ }); // these magic numbers are a result of disparity between font's apparent and actual size + const sizeOffsetX = 0.96; + const sizeOffsetY = 1.255; textScale.x = - (positionStyles.width / constantStyles.initialWidth) * 0.96 + 0.04; + (positionStyles.width / constantStyles.initialWidth) * sizeOffsetX - sizeOffsetX + 1; textScale.y = - (positionStyles.height / constantStyles.initialHeight) * 1.255 - 0.255; + (positionStyles.height / constantStyles.initialHeight) * sizeOffsetY - sizeOffsetY + 1; if (textScale.x < 0) textScale.x = 0; if (textScale.y < 0) textScale.y = 0; From e44b0d0e5919cc5a0d183c2610130679817bb7d4 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Wed, 13 Mar 2024 16:11:38 +0100 Subject: [PATCH 11/25] By default, title is not interactive, and looks exactly how it used to look before this PR. After turning on isInteractive flag, it becomes interactive. --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 47 +++++++++++-------- .../SelectionBox/styles.module.css | 4 +- .../components/Hero/SelectedLabel/index.tsx | 28 ++++++++--- .../src/components/Hero/StartScreen/index.tsx | 2 +- .../Hero/StartScreen/styles.module.css | 4 -- 5 files changed, 52 insertions(+), 33 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx index ddd00b410ef3..442178b4558f 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -14,30 +14,37 @@ export enum DraggableId { const SelectionBox: React.FC<{ propagationFunction: ( position: { x: number; y: number }, - draggableIdentifier: DraggableId + draggableIdentifier: DraggableId, ) => void; draggableIdentifier: DraggableId; children?: React.ReactNode; -}> = ({ propagationFunction, draggableIdentifier, children }) => { - const [classList, setClassList] = useState(''); + isInteractive: Boolean; +}> = ({ propagationFunction, draggableIdentifier, children, isInteractive }) => { + let defaultState: string; - useEffect(() => { - setClassList( - draggableIdentifier == DraggableId.CENTER - ? clsx(styles.movableHeader, styles.movable) - : clsx( - styles.selectionBox, - styles.movable, - draggableIdentifier == DraggableId.BOTTOM_LEFT || - draggableIdentifier == DraggableId.BOTTOM_RIGHT - ? styles.boxLower - : styles.boxUpper, - draggableIdentifier == DraggableId.BOTTOM_LEFT || - draggableIdentifier == DraggableId.TOP_LEFT - ? styles.boxLeft - : styles.boxRight - ) + if (draggableIdentifier !== DraggableId.CENTER) { + defaultState = clsx( + styles.selectionBox, + draggableIdentifier == DraggableId.BOTTOM_LEFT || + draggableIdentifier == DraggableId.BOTTOM_RIGHT + ? styles.boxLower + : styles.boxUpper, + draggableIdentifier == DraggableId.BOTTOM_LEFT || + draggableIdentifier == DraggableId.TOP_LEFT + ? styles.boxLeft + : styles.boxRight ); + } + + const [classList, setClassList] = useState(defaultState); + + useEffect(() => { + // if interactivity is enabled, center CENTER after re-render + if (draggableIdentifier === DraggableId.CENTER && isInteractive) { + setClassList(clsx( + styles.movableHeader, styles.movable + )); + } }, [draggableIdentifier]); // use animation with the destination being cursor position @@ -51,7 +58,7 @@ const SelectionBox: React.FC<{ }} allowAnyClick={false} axis={'none'}> -
{children}
+
{children}
); }; diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css index f6cbd9d3520d..557b0926391b 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css @@ -16,11 +16,11 @@ transition: scale 50ms ease-in-out; } -.selectionBox:active { +.movable.selectionBox:active { scale: 1.35; } -.selectionBox:hover { +.movable.selectionBox:hover { scale: 1.35; } diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 1bd6dc2cce26..96c642c3c51d 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -3,8 +3,9 @@ import React, { useEffect, useRef, useState } from 'react'; import styles from './styles.module.css'; import SelectionBox, { DraggableId } from './SelectionBox'; -const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ +const SelectedLabel: React.FC<{ children: React.ReactNode, isInteractive: Boolean }> = ({ children, + isInteractive = false }) => { const selectionRef = useRef(null); const selectionContainerRef = useRef(null); @@ -50,6 +51,10 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ useEffect(() => { const rect = selectionContainerRef.current.getBoundingClientRect(); + + if (!isInteractive) + return; + setConstantStyles({ initialWidth: rect.width, initialHeight: rect.height, @@ -59,6 +64,10 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ useEffect(() => { const rect = selectionContainerRef.current.getBoundingClientRect(); + + if (!isInteractive) + return; + setPositionStyles({ top: 0, // rect.top, left: 0, // rect.left, @@ -71,6 +80,8 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({ position: { x: number; y: number }, draggableIdentifier: DraggableId ) => { + if (!isInteractive) + return; // changing selectionContainer will automatically adjust position of selectionBoxes as well // all changes are done through css const isHorizontal = @@ -145,19 +156,24 @@ const SelectedLabel: React.FC<{ children: React.ReactNode }> = ({
+ draggableIdentifier={DraggableId.TOP_LEFT} + isInteractive={isInteractive}> + draggableIdentifier={DraggableId.TOP_RIGHT} + isInteractive={isInteractive}> + draggableIdentifier={DraggableId.BOTTOM_LEFT} + isInteractive={isInteractive}> + draggableIdentifier={DraggableId.BOTTOM_RIGHT} + isInteractive={isInteractive}> + draggableIdentifier={DraggableId.CENTER} + isInteractive={isInteractive}> { Beyond the limitations
- Reanimated + Reanimated
diff --git a/docs/src/components/Hero/StartScreen/styles.module.css b/docs/src/components/Hero/StartScreen/styles.module.css index eff99c9196a8..e2d996ebf997 100644 --- a/docs/src/components/Hero/StartScreen/styles.module.css +++ b/docs/src/components/Hero/StartScreen/styles.module.css @@ -35,10 +35,6 @@ color: var(--swm-landing-heading); } -.headingLabel span { - margin-right: 8px; -} - .subheadingLabel { font-family: var(--swm-title-landing-font); font-size: 32px; From bc9b9cc247d0fc9ead04ba13c85dd157ff2869ef Mon Sep 17 00:00:00 2001 From: LatekVo Date: Thu, 14 Mar 2024 01:04:13 +0100 Subject: [PATCH 12/25] Removed unnecessary useEffects. Fixed structure and styling. --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 19 ++++------- .../SelectionBox/styles.module.css | 14 ++------ .../components/Hero/SelectedLabel/index.tsx | 33 +++++++++---------- .../Hero/SelectedLabel/styles.module.css | 11 +++++++ 4 files changed, 35 insertions(+), 42 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx index 442178b4558f..3b394e6ff7e1 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -20,10 +20,10 @@ const SelectionBox: React.FC<{ children?: React.ReactNode; isInteractive: Boolean; }> = ({ propagationFunction, draggableIdentifier, children, isInteractive }) => { - let defaultState: string; + let classList: string; if (draggableIdentifier !== DraggableId.CENTER) { - defaultState = clsx( + classList = clsx( styles.selectionBox, draggableIdentifier == DraggableId.BOTTOM_LEFT || draggableIdentifier == DraggableId.BOTTOM_RIGHT @@ -34,19 +34,12 @@ const SelectionBox: React.FC<{ ? styles.boxLeft : styles.boxRight ); + } else { + classList = clsx( + styles.centerDraggable + ); } - const [classList, setClassList] = useState(defaultState); - - useEffect(() => { - // if interactivity is enabled, center CENTER after re-render - if (draggableIdentifier === DraggableId.CENTER && isInteractive) { - setClassList(clsx( - styles.movableHeader, styles.movable - )); - } - }, [draggableIdentifier]); - // use animation with the destination being cursor position return ( { - const rect = selectionContainerRef.current.getBoundingClientRect(); - + useEffect(() => { if (!isInteractive) return; + const rect = selectionContainerRef.current.getBoundingClientRect(); setConstantStyles({ initialWidth: rect.width, initialHeight: rect.height, - setAbsolute: true, + isTextInteractive: true, }); }, []); useEffect(() => { - const rect = selectionContainerRef.current.getBoundingClientRect(); - if (!isInteractive) return; + const rect = selectionContainerRef.current.getBoundingClientRect(); setPositionStyles({ - top: 0, // rect.top, - left: 0, // rect.left, + top: 0, + left: 0, width: rect.width, height: rect.height, }); @@ -82,8 +80,7 @@ const SelectedLabel: React.FC<{ children: React.ReactNode, isInteractive: Boolea ) => { if (!isInteractive) return; - // changing selectionContainer will automatically adjust position of selectionBoxes as well - // all changes are done through css + const isHorizontal = draggableIdentifier == DraggableId.BOTTOM_LEFT || draggableIdentifier == DraggableId.TOP_LEFT; @@ -125,6 +122,7 @@ const SelectedLabel: React.FC<{ children: React.ReactNode, isInteractive: Boolea if (positionStyles.height - positionAdjustment.y < 0) positionAdjustment.y = 0; } + setPositionStyles({ left: positionStyles.left + positionAdjustment.x, top: positionStyles.top + positionAdjustment.y, @@ -133,8 +131,9 @@ const SelectedLabel: React.FC<{ children: React.ReactNode, isInteractive: Boolea }); // these magic numbers are a result of disparity between font's apparent and actual size - const sizeOffsetX = 0.96; + const sizeOffsetX = 0.93; const sizeOffsetY = 1.255; + // scale starts at 1 and as it gets larger approaches sizeOffset textScale.x = (positionStyles.width / constantStyles.initialWidth) * sizeOffsetX - sizeOffsetX + 1; textScale.y = @@ -151,7 +150,7 @@ const SelectedLabel: React.FC<{ children: React.ReactNode, isInteractive: Boolea ref={selectionRef} className={clsx(styles.headingLabel, styles.selection)} style={{ - position: constantStyles.setAbsolute ? 'absolute' : 'relative', + position: constantStyles.isTextInteractive ? 'absolute' : 'relative', }}>
+ className={clsx( + constantStyles.isTextInteractive ? styles.interactiveHeaderText : styles.headerText + )}> {children} diff --git a/docs/src/components/Hero/SelectedLabel/styles.module.css b/docs/src/components/Hero/SelectedLabel/styles.module.css index 4acecf567285..e854b9bcd8d6 100644 --- a/docs/src/components/Hero/SelectedLabel/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/styles.module.css @@ -29,5 +29,16 @@ .movableHeader { left: 50%; top: 50%; +} + +.headerText { + position: relative; +} + +.interactiveHeaderText { + position: absolute; transform: translate(-50%, -50%); + left: 50%; + top: 50%; + user-select: none; } From 0207edc8b39775a7b99635df58ec83856875a0fe Mon Sep 17 00:00:00 2001 From: LatekVo Date: Thu, 14 Mar 2024 01:21:35 +0100 Subject: [PATCH 13/25] Simplified code. Ran prettier. --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 43 ++++++++++--------- .../components/Hero/SelectedLabel/index.tsx | 42 +++++++++--------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx index 3b394e6ff7e1..9f25e6086694 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -14,30 +14,31 @@ export enum DraggableId { const SelectionBox: React.FC<{ propagationFunction: ( position: { x: number; y: number }, - draggableIdentifier: DraggableId, + draggableIdentifier: DraggableId ) => void; draggableIdentifier: DraggableId; children?: React.ReactNode; isInteractive: Boolean; -}> = ({ propagationFunction, draggableIdentifier, children, isInteractive }) => { - let classList: string; +}> = ({ + propagationFunction, + draggableIdentifier, + children, + isInteractive, +}) => { + let classList = clsx( + styles.selectionBox, + draggableIdentifier == DraggableId.BOTTOM_LEFT || + draggableIdentifier == DraggableId.BOTTOM_RIGHT + ? styles.boxLower + : styles.boxUpper, + draggableIdentifier == DraggableId.BOTTOM_LEFT || + draggableIdentifier == DraggableId.TOP_LEFT + ? styles.boxLeft + : styles.boxRight + ); - if (draggableIdentifier !== DraggableId.CENTER) { - classList = clsx( - styles.selectionBox, - draggableIdentifier == DraggableId.BOTTOM_LEFT || - draggableIdentifier == DraggableId.BOTTOM_RIGHT - ? styles.boxLower - : styles.boxUpper, - draggableIdentifier == DraggableId.BOTTOM_LEFT || - draggableIdentifier == DraggableId.TOP_LEFT - ? styles.boxLeft - : styles.boxRight - ); - } else { - classList = clsx( - styles.centerDraggable - ); + if (draggableIdentifier === DraggableId.CENTER) { + classList = clsx(styles.centerDraggable); } // use animation with the destination being cursor position @@ -51,7 +52,9 @@ const SelectionBox: React.FC<{ }} allowAnyClick={false} axis={'none'}> -
{children}
+
+ {children} +
); }; diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 686d68926306..37a903622a8e 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -3,10 +3,10 @@ import React, { useEffect, useRef, useState } from 'react'; import styles from './styles.module.css'; import SelectionBox, { DraggableId } from './SelectionBox'; -const SelectedLabel: React.FC<{ children: React.ReactNode, isInteractive: Boolean }> = ({ - children, - isInteractive = false -}) => { +const SelectedLabel: React.FC<{ + children: React.ReactNode; + isInteractive: Boolean; +}> = ({ children, isInteractive = false }) => { const selectionRef = useRef(null); const selectionContainerRef = useRef(null); const textLabelRef = useRef(null); @@ -49,9 +49,8 @@ const SelectedLabel: React.FC<{ children: React.ReactNode, isInteractive: Boolea isTextInteractive: false, }); - useEffect(() => { - if (!isInteractive) - return; + useEffect(() => { + if (!isInteractive) return; const rect = selectionContainerRef.current.getBoundingClientRect(); setConstantStyles({ @@ -62,8 +61,7 @@ const SelectedLabel: React.FC<{ children: React.ReactNode, isInteractive: Boolea }, []); useEffect(() => { - if (!isInteractive) - return; + if (!isInteractive) return; const rect = selectionContainerRef.current.getBoundingClientRect(); setPositionStyles({ @@ -78,23 +76,22 @@ const SelectedLabel: React.FC<{ children: React.ReactNode, isInteractive: Boolea position: { x: number; y: number }, draggableIdentifier: DraggableId ) => { - if (!isInteractive) - return; + if (!isInteractive) return; - const isHorizontal = + const horizontalSide = draggableIdentifier == DraggableId.BOTTOM_LEFT || draggableIdentifier == DraggableId.TOP_LEFT; - const isVertical = + const verticalSide = draggableIdentifier == DraggableId.TOP_LEFT || draggableIdentifier == DraggableId.TOP_RIGHT; const positionAdjustment = { - x: isHorizontal ? position.x : 0, - y: isVertical ? position.y : 0, + x: horizontalSide ? position.x : 0, + y: verticalSide ? position.y : 0, }; const resizingDirection = { - x: isHorizontal ? -1 : 1, - y: isVertical ? -1 : 1, + x: horizontalSide ? -1 : 1, + y: verticalSide ? -1 : 1, }; const sizeChange = { x: position.x * resizingDirection.x, @@ -133,11 +130,14 @@ const SelectedLabel: React.FC<{ children: React.ReactNode, isInteractive: Boolea // these magic numbers are a result of disparity between font's apparent and actual size const sizeOffsetX = 0.93; const sizeOffsetY = 1.255; + // scale starts at 1 and as it gets larger approaches sizeOffset textScale.x = - (positionStyles.width / constantStyles.initialWidth) * sizeOffsetX - sizeOffsetX + 1; + (positionStyles.width / constantStyles.initialWidth) + * sizeOffsetX - sizeOffsetX + 1; textScale.y = - (positionStyles.height / constantStyles.initialHeight) * sizeOffsetY - sizeOffsetY + 1; + (positionStyles.height / constantStyles.initialHeight) + * sizeOffsetY - sizeOffsetY + 1; if (textScale.x < 0) textScale.x = 0; if (textScale.y < 0) textScale.y = 0; @@ -176,7 +176,9 @@ const SelectedLabel: React.FC<{ children: React.ReactNode, isInteractive: Boolea {children} From 97919899efa02b7370367a7f40600ad8502fea61 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Thu, 14 Mar 2024 09:55:11 +0100 Subject: [PATCH 14/25] Unify styling for interactive and non-interactive components. --- .../SelectedLabel/SelectionBox/styles.module.css | 4 ++-- docs/src/components/Hero/SelectedLabel/index.tsx | 12 ++++++++---- .../components/Hero/SelectedLabel/styles.module.css | 1 - 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css index 039f18adcade..693a9a12666e 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css @@ -38,9 +38,9 @@ } .boxLeft { - left: -25px; + left: -15px; } .boxRight { - right: -25px; + right: -15px; } diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 37a903622a8e..18cd11585520 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -128,8 +128,8 @@ const SelectedLabel: React.FC<{ }); // these magic numbers are a result of disparity between font's apparent and actual size - const sizeOffsetX = 0.93; - const sizeOffsetY = 1.255; + const sizeOffsetX = 0.98; + const sizeOffsetY = 1.250; // scale starts at 1 and as it gets larger approaches sizeOffset textScale.x = @@ -152,7 +152,8 @@ const SelectedLabel: React.FC<{ style={{ position: constantStyles.isTextInteractive ? 'absolute' : 'relative', }}> -
+
+ )} + style={{ + marginRight: isInteractive ? 30 : null, + }}> {children} diff --git a/docs/src/components/Hero/SelectedLabel/styles.module.css b/docs/src/components/Hero/SelectedLabel/styles.module.css index e854b9bcd8d6..f8b36be7815b 100644 --- a/docs/src/components/Hero/SelectedLabel/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/styles.module.css @@ -23,7 +23,6 @@ .selectionContainer { position: relative; text-align: center; - margin: 0 10px; } .movableHeader { From e5af1160be9c96f48f06e07865815aa83705148f Mon Sep 17 00:00:00 2001 From: LatekVo Date: Thu, 14 Mar 2024 10:21:24 +0100 Subject: [PATCH 15/25] Fix styling for mobile devices, this may require more work. --- docs/src/components/Hero/SelectedLabel/index.tsx | 10 +++++----- .../Hero/SelectedLabel/styles.module.css | 15 ++++++++++----- .../components/Hero/StartScreen/styles.module.css | 5 +++++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 18cd11585520..b77a22da2feb 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -179,11 +179,11 @@ const SelectedLabel: React.FC<{ className={clsx( constantStyles.isTextInteractive ? styles.interactiveHeaderText - : styles.headerText - )} - style={{ - marginRight: isInteractive ? 30 : null, - }}> + : styles.headerText, + isInteractive + ? styles.preInteractiveHeaderText + : null + )}> {children} diff --git a/docs/src/components/Hero/SelectedLabel/styles.module.css b/docs/src/components/Hero/SelectedLabel/styles.module.css index f8b36be7815b..72295c34e2f5 100644 --- a/docs/src/components/Hero/SelectedLabel/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/styles.module.css @@ -25,11 +25,6 @@ text-align: center; } -.movableHeader { - left: 50%; - top: 50%; -} - .headerText { position: relative; } @@ -41,3 +36,13 @@ top: 50%; user-select: none; } + +.preInteractiveHeaderText { + margin-right: 30px; +} + +@media (max-width: 768px) { + .preInteractiveHeaderText { + margin-right: 8px; + } +} diff --git a/docs/src/components/Hero/StartScreen/styles.module.css b/docs/src/components/Hero/StartScreen/styles.module.css index e2d996ebf997..8a0d11a3cec0 100644 --- a/docs/src/components/Hero/StartScreen/styles.module.css +++ b/docs/src/components/Hero/StartScreen/styles.module.css @@ -58,6 +58,11 @@ font-size: 26px; } + .headingColumn { + flex-direction: column-reverse; + width: 100%; + } + .subheadingLabel { font-size: 20px; width: 90%; From 960642f0a3f0c781136585b8233c89cc11f4ab77 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Thu, 14 Mar 2024 10:30:43 +0100 Subject: [PATCH 16/25] Fix failing git checks. Ran prettier. --- docs/src/components/Hero/SelectedLabel/index.tsx | 13 ++++++------- .../components/Hero/SelectedLabel/styles.module.css | 2 +- .../components/Hero/StartScreen/styles.module.css | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index b77a22da2feb..4453b1b1700f 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -129,12 +129,14 @@ const SelectedLabel: React.FC<{ // these magic numbers are a result of disparity between font's apparent and actual size const sizeOffsetX = 0.98; - const sizeOffsetY = 1.250; + const sizeOffsetY = 1.25; // scale starts at 1 and as it gets larger approaches sizeOffset + // prettier-ignore textScale.x = (positionStyles.width / constantStyles.initialWidth) * sizeOffsetX - sizeOffsetX + 1; + // prettier-ignore textScale.y = (positionStyles.height / constantStyles.initialHeight) * sizeOffsetY - sizeOffsetY + 1; @@ -152,8 +154,7 @@ const SelectedLabel: React.FC<{ style={{ position: constantStyles.isTextInteractive ? 'absolute' : 'relative', }}> -
+
{children} diff --git a/docs/src/components/Hero/SelectedLabel/styles.module.css b/docs/src/components/Hero/SelectedLabel/styles.module.css index 72295c34e2f5..02dbcb6a6a2f 100644 --- a/docs/src/components/Hero/SelectedLabel/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/styles.module.css @@ -44,5 +44,5 @@ @media (max-width: 768px) { .preInteractiveHeaderText { margin-right: 8px; - } + } } diff --git a/docs/src/components/Hero/StartScreen/styles.module.css b/docs/src/components/Hero/StartScreen/styles.module.css index 8a0d11a3cec0..c59a0caf62f6 100644 --- a/docs/src/components/Hero/StartScreen/styles.module.css +++ b/docs/src/components/Hero/StartScreen/styles.module.css @@ -61,7 +61,7 @@ .headingColumn { flex-direction: column-reverse; width: 100%; - } + } .subheadingLabel { font-size: 20px; From 7bb1cebb381530361e49498c3325553ab2ed84dc Mon Sep 17 00:00:00 2001 From: LatekVo Date: Thu, 14 Mar 2024 10:59:17 +0100 Subject: [PATCH 17/25] Fixed website layout so it appears on mobile exactly how it used to before this PR. --- docs/src/components/Hero/StartScreen/index.tsx | 12 +++++------- .../components/Hero/StartScreen/styles.module.css | 4 ++++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/src/components/Hero/StartScreen/index.tsx b/docs/src/components/Hero/StartScreen/index.tsx index 22f102e58e7c..16e269f4721b 100644 --- a/docs/src/components/Hero/StartScreen/index.tsx +++ b/docs/src/components/Hero/StartScreen/index.tsx @@ -13,14 +13,12 @@ const StartScreen = () => {

-
- React Native -

- Beyond the limitations -

-
- Reanimated + React Native + Reanimated

+

+ Beyond the limitations +

diff --git a/docs/src/components/Hero/StartScreen/styles.module.css b/docs/src/components/Hero/StartScreen/styles.module.css index c59a0caf62f6..fd7f89eff171 100644 --- a/docs/src/components/Hero/StartScreen/styles.module.css +++ b/docs/src/components/Hero/StartScreen/styles.module.css @@ -35,6 +35,10 @@ color: var(--swm-landing-heading); } +.rnLabel { + margin-right: 10px; +} + .subheadingLabel { font-family: var(--swm-title-landing-font); font-size: 32px; From 69287e61aacccd2a0010b7393766308bb7b5ce5b Mon Sep 17 00:00:00 2001 From: LatekVo Date: Thu, 14 Mar 2024 11:01:54 +0100 Subject: [PATCH 18/25] Fix git CI errors. --- docs/src/components/Hero/StartScreen/index.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/src/components/Hero/StartScreen/index.tsx b/docs/src/components/Hero/StartScreen/index.tsx index 16e269f4721b..09f2960a3816 100644 --- a/docs/src/components/Hero/StartScreen/index.tsx +++ b/docs/src/components/Hero/StartScreen/index.tsx @@ -13,12 +13,10 @@ const StartScreen = () => {

- React Native - Reanimated + React Native + Reanimated

-

- Beyond the limitations -

+

Beyond the limitations

From 13bcce4b518cf7c388b44cdcc2d5e5bc90912631 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Thu, 14 Mar 2024 17:07:45 +0100 Subject: [PATCH 19/25] Cleaned up code. Removed unnecessary useEffect. Fixed styles. --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 63 ++++---- .../SelectionBox/styles.module.css | 6 +- .../components/Hero/SelectedLabel/index.tsx | 144 ++++++++++-------- 3 files changed, 114 insertions(+), 99 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx index 9f25e6086694..1cb84f1499e3 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -25,38 +25,39 @@ const SelectionBox: React.FC<{ children, isInteractive, }) => { - let classList = clsx( - styles.selectionBox, - draggableIdentifier == DraggableId.BOTTOM_LEFT || - draggableIdentifier == DraggableId.BOTTOM_RIGHT - ? styles.boxLower - : styles.boxUpper, - draggableIdentifier == DraggableId.BOTTOM_LEFT || - draggableIdentifier == DraggableId.TOP_LEFT - ? styles.boxLeft - : styles.boxRight - ); + const isBottom = draggableIdentifier == DraggableId.BOTTOM_LEFT || + draggableIdentifier == DraggableId.BOTTOM_RIGHT; + const isLeft = draggableIdentifier == DraggableId.BOTTOM_LEFT || + draggableIdentifier == DraggableId.TOP_LEFT; + const isCenter = draggableIdentifier === DraggableId.CENTER; - if (draggableIdentifier === DraggableId.CENTER) { - classList = clsx(styles.centerDraggable); - } + let classList = clsx( + styles.selectionBox, + isBottom + ? styles.boxLower + : styles.boxUpper, + isLeft + ? styles.boxLeft + : styles.boxRight + ); - // use animation with the destination being cursor position - return ( - { - propagationFunction( - { x: event.movementX, y: event.movementY }, - draggableIdentifier - ); - }} - allowAnyClick={false} - axis={'none'}> -
- {children} -
-
- ); -}; + classList = isCenter ? clsx(styles.centerDraggable) : classList; + + return ( + { + propagationFunction( + { x: event.movementX, y: event.movementY }, + draggableIdentifier + ); + }} + allowAnyClick={false} + axis={'none'}> +
+ {children} +
+
+ ); + }; export default SelectionBox; diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css index 693a9a12666e..9f08c11df4a5 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css @@ -30,11 +30,11 @@ } .boxUpper { - top: -6px; + top: -7px; } .boxLower { - bottom: -14px; + bottom: -13px; } .boxLeft { @@ -43,4 +43,4 @@ .boxRight { right: -15px; -} +} \ No newline at end of file diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 4453b1b1700f..684e2622ca1d 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -7,43 +7,45 @@ const SelectedLabel: React.FC<{ children: React.ReactNode; isInteractive: Boolean; }> = ({ children, isInteractive = false }) => { + type PositionStyles = { + top: number; + left: number; + width: number; + height: number; + } + + // DOM refs const selectionRef = useRef(null); const selectionContainerRef = useRef(null); const textLabelRef = useRef(null); - const positionStyles = { + // Render-persistent label positioning styles + const positionStyles = useRef({ top: 0, left: 0, width: null, height: null, - }; - const setPositionStyles = (newPositionStyles: { - top: number; - left: number; - width: number; - height: number; - }) => { + }); + const setPositionStyles = (newPositionStyles: PositionStyles) => { + const currentPositionStyles = positionStyles.current; + // save changes - positionStyles.top = newPositionStyles.top; - positionStyles.left = newPositionStyles.left; - positionStyles.width = newPositionStyles.width; - positionStyles.height = newPositionStyles.height; + currentPositionStyles.top = newPositionStyles.top; + currentPositionStyles.left = newPositionStyles.left; + currentPositionStyles.width = newPositionStyles.width; + currentPositionStyles.height = newPositionStyles.height; // apply changes to refs - selectionRef.current.style.transform = `translate(${positionStyles.left}px, ${positionStyles.top}px)`; - selectionContainerRef.current.style.width = `${positionStyles.width}px`; - selectionContainerRef.current.style.height = `${positionStyles.height}px`; + selectionRef.current.style.transform = `translate(${currentPositionStyles.left}px, ${currentPositionStyles.top}px)`; + selectionContainerRef.current.style.width = `${currentPositionStyles.width}px`; + selectionContainerRef.current.style.height = `${currentPositionStyles.height}px`; }; - const textScale = { - x: 1, - y: 1, - }; - const applyTextScale = () => { - textLabelRef.current.style.transform = `translate(-50%, -50%) scale(${textScale.x}, ${textScale.y})`; + const applyTextScale = (scaleX: number, scaleY: number) => { + textLabelRef.current.style.transform = `translate(-50%, -50%) scale(${scaleX}, ${scaleY})`; }; - const [constantStyles, setConstantStyles] = useState({ + const constantStyles = useRef({ initialWidth: null, initialHeight: null, isTextInteractive: false, @@ -52,99 +54,111 @@ const SelectedLabel: React.FC<{ useEffect(() => { if (!isInteractive) return; - const rect = selectionContainerRef.current.getBoundingClientRect(); - setConstantStyles({ + let rect = selectionContainerRef.current.getBoundingClientRect(); + constantStyles.current = { initialWidth: rect.width, initialHeight: rect.height, isTextInteractive: true, - }); - }, []); - - useEffect(() => { - if (!isInteractive) return; + }; - const rect = selectionContainerRef.current.getBoundingClientRect(); setPositionStyles({ top: 0, left: 0, width: rect.width, height: rect.height, }); - }, [constantStyles]); + }, []); - const positionPropagator = ( + const adjustSelectionStyles = ( position: { x: number; y: number }, draggableIdentifier: DraggableId ) => { - if (!isInteractive) return; - - const horizontalSide = + const isLeft = draggableIdentifier == DraggableId.BOTTOM_LEFT || draggableIdentifier == DraggableId.TOP_LEFT; - const verticalSide = + const isTop = draggableIdentifier == DraggableId.TOP_LEFT || draggableIdentifier == DraggableId.TOP_RIGHT; + const isCenter = draggableIdentifier === DraggableId.CENTER; + // depedning on whether draggable is on left, right, top or bottom, + // we want to either resize, or move and resize our object const positionAdjustment = { - x: horizontalSide ? position.x : 0, - y: verticalSide ? position.y : 0, + x: isLeft ? position.x : 0, + y: isTop ? position.y : 0, }; + const resizingDirection = { - x: horizontalSide ? -1 : 1, - y: verticalSide ? -1 : 1, + x: isLeft ? -1 : 1, + y: isTop ? -1 : 1, }; + const sizeChange = { x: position.x * resizingDirection.x, y: position.y * resizingDirection.y, }; // adjust variables when dragging the center - if (draggableIdentifier == DraggableId.CENTER) { + if (isCenter) { positionAdjustment.x = sizeChange.x; positionAdjustment.y = sizeChange.y; sizeChange.x = 0; sizeChange.y = 0; } + const currentPositionStyles = positionStyles.current; + // stop overreduction in size - if (positionStyles.width + sizeChange.x < 0) - sizeChange.x = -positionStyles.width; - if (positionStyles.height + sizeChange.y < 0) - sizeChange.y = -positionStyles.height; + if (currentPositionStyles.width + sizeChange.x < 0) + sizeChange.x = -currentPositionStyles.width; + if (currentPositionStyles.height + sizeChange.y < 0) + sizeChange.y = -currentPositionStyles.height; // stop dragging a minimized object - if (draggableIdentifier !== DraggableId.CENTER) { - if (positionStyles.width - positionAdjustment.x < 0) + if (!isCenter) { + if (currentPositionStyles.width - positionAdjustment.x < 0) positionAdjustment.x = 0; - if (positionStyles.height - positionAdjustment.y < 0) + if (currentPositionStyles.height - positionAdjustment.y < 0) positionAdjustment.y = 0; } setPositionStyles({ - left: positionStyles.left + positionAdjustment.x, - top: positionStyles.top + positionAdjustment.y, - width: positionStyles.width + sizeChange.x, - height: positionStyles.height + sizeChange.y, + left: currentPositionStyles.left + positionAdjustment.x, + top: currentPositionStyles.top + positionAdjustment.y, + width: currentPositionStyles.width + sizeChange.x, + height: currentPositionStyles.height + sizeChange.y, }); + } + const adjustTextStyles = () => { // these magic numbers are a result of disparity between font's apparent and actual size - const sizeOffsetX = 0.98; - const sizeOffsetY = 1.25; + const sizeOffsetX = 0.99; + const sizeOffsetY = 1.21; // scale starts at 1 and as it gets larger approaches sizeOffset - // prettier-ignore - textScale.x = - (positionStyles.width / constantStyles.initialWidth) - * sizeOffsetX - sizeOffsetX + 1; - // prettier-ignore - textScale.y = - (positionStyles.height / constantStyles.initialHeight) - * sizeOffsetY - sizeOffsetY + 1; + const textScale = { + x: (positionStyles.current.width / constantStyles.current.initialWidth) + * sizeOffsetX - sizeOffsetX + 1, + y: (positionStyles.current.height / constantStyles.current.initialHeight) + * sizeOffsetY - sizeOffsetY + 1, + }; + // prevent text overadjustment if (textScale.x < 0) textScale.x = 0; if (textScale.y < 0) textScale.y = 0; - applyTextScale(); + applyTextScale(textScale.x, textScale.y); + } + + const positionPropagator = ( + position: { x: number; y: number }, + draggableIdentifier: DraggableId + ) => { + if (!isInteractive) return; + + adjustSelectionStyles(position, draggableIdentifier); + + adjustTextStyles(); }; return ( @@ -152,7 +166,7 @@ const SelectedLabel: React.FC<{ ref={selectionRef} className={clsx(styles.headingLabel, styles.selection)} style={{ - position: constantStyles.isTextInteractive ? 'absolute' : 'relative', + position: constantStyles.current.isTextInteractive ? 'absolute' : 'relative', }}>
From 96f78b6ac0224803ed893fa5c29494b6a7c8fc04 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Thu, 14 Mar 2024 18:05:13 +0100 Subject: [PATCH 20/25] Simplify code, fix formatting. --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 64 ++++++----- .../SelectionBox/styles.module.css | 2 +- .../components/Hero/SelectedLabel/index.tsx | 101 +++++++++--------- .../Hero/SelectedLabel/styles.module.css | 14 ++- 4 files changed, 93 insertions(+), 88 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx index 1cb84f1499e3..c2fcb6dcc895 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import React, { useEffect, useMemo, useState } from 'react'; +import React from 'react'; import styles from './styles.module.css'; import Draggable from 'react-draggable'; @@ -13,7 +13,7 @@ export enum DraggableId { const SelectionBox: React.FC<{ propagationFunction: ( - position: { x: number; y: number }, + movementDelta: { x: number; y: number }, draggableIdentifier: DraggableId ) => void; draggableIdentifier: DraggableId; @@ -25,39 +25,37 @@ const SelectionBox: React.FC<{ children, isInteractive, }) => { - const isBottom = draggableIdentifier == DraggableId.BOTTOM_LEFT || - draggableIdentifier == DraggableId.BOTTOM_RIGHT; - const isLeft = draggableIdentifier == DraggableId.BOTTOM_LEFT || - draggableIdentifier == DraggableId.TOP_LEFT; - const isCenter = draggableIdentifier === DraggableId.CENTER; + const isBottom = + draggableIdentifier == DraggableId.BOTTOM_LEFT || + draggableIdentifier == DraggableId.BOTTOM_RIGHT; + const isLeft = + draggableIdentifier == DraggableId.BOTTOM_LEFT || + draggableIdentifier == DraggableId.TOP_LEFT; + const isCenter = draggableIdentifier === DraggableId.CENTER; - let classList = clsx( - styles.selectionBox, - isBottom - ? styles.boxLower - : styles.boxUpper, - isLeft - ? styles.boxLeft - : styles.boxRight - ); + let classList = clsx( + styles.selectionBox, + isBottom ? styles.boxLower : styles.boxUpper, + isLeft ? styles.boxLeft : styles.boxRight + ); - classList = isCenter ? clsx(styles.centerDraggable) : classList; + classList = isCenter ? clsx(styles.centerDraggable) : classList; - return ( - { - propagationFunction( - { x: event.movementX, y: event.movementY }, - draggableIdentifier - ); - }} - allowAnyClick={false} - axis={'none'}> -
- {children} -
-
- ); - }; + return ( + { + propagationFunction( + { x: event.movementX, y: event.movementY }, + draggableIdentifier + ); + }} + allowAnyClick={false} + axis={'none'}> +
+ {children} +
+
+ ); +}; export default SelectionBox; diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css index 9f08c11df4a5..6dcf7bb48a5b 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css @@ -43,4 +43,4 @@ .boxRight { right: -15px; -} \ No newline at end of file +} diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 684e2622ca1d..a13ac4092a91 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useRef } from 'react'; import styles from './styles.module.css'; import SelectionBox, { DraggableId } from './SelectionBox'; @@ -12,21 +12,28 @@ const SelectedLabel: React.FC<{ left: number; width: number; height: number; - } + }; // DOM refs const selectionRef = useRef(null); const selectionContainerRef = useRef(null); const textLabelRef = useRef(null); - // Render-persistent label positioning styles + // Render-persistent label positioning styles const positionStyles = useRef({ top: 0, left: 0, width: null, height: null, }); - const setPositionStyles = (newPositionStyles: PositionStyles) => { + + const constantStyles = useRef({ + initialWidth: null, + initialHeight: null, + enabledTextInteractivity: false, + }); + + const applyPositionStyles = (newPositionStyles: PositionStyles) => { const currentPositionStyles = positionStyles.current; // save changes @@ -41,16 +48,10 @@ const SelectedLabel: React.FC<{ selectionContainerRef.current.style.height = `${currentPositionStyles.height}px`; }; - const applyTextScale = (scaleX: number, scaleY: number) => { - textLabelRef.current.style.transform = `translate(-50%, -50%) scale(${scaleX}, ${scaleY})`; + const applyTextScale = (scaleObject: { x: number; y: number }) => { + textLabelRef.current.style.transform = `translate(-50%, -50%) scale(${scaleObject.x}, ${scaleObject.y})`; }; - const constantStyles = useRef({ - initialWidth: null, - initialHeight: null, - isTextInteractive: false, - }); - useEffect(() => { if (!isInteractive) return; @@ -58,10 +59,10 @@ const SelectedLabel: React.FC<{ constantStyles.current = { initialWidth: rect.width, initialHeight: rect.height, - isTextInteractive: true, + enabledTextInteractivity: true, }; - setPositionStyles({ + applyPositionStyles({ top: 0, left: 0, width: rect.width, @@ -69,33 +70,28 @@ const SelectedLabel: React.FC<{ }); }, []); - const adjustSelectionStyles = ( + const computeSelectionStyles = ( position: { x: number; y: number }, draggableIdentifier: DraggableId ) => { const isLeft = - draggableIdentifier == DraggableId.BOTTOM_LEFT || - draggableIdentifier == DraggableId.TOP_LEFT; + draggableIdentifier === DraggableId.BOTTOM_LEFT || + draggableIdentifier === DraggableId.TOP_LEFT; const isTop = - draggableIdentifier == DraggableId.TOP_LEFT || - draggableIdentifier == DraggableId.TOP_RIGHT; + draggableIdentifier === DraggableId.TOP_LEFT || + draggableIdentifier === DraggableId.TOP_RIGHT; const isCenter = draggableIdentifier === DraggableId.CENTER; - // depedning on whether draggable is on left, right, top or bottom, + // depedning on whether draggable is on left, right, top or bottom, // we want to either resize, or move and resize our object const positionAdjustment = { x: isLeft ? position.x : 0, y: isTop ? position.y : 0, }; - const resizingDirection = { - x: isLeft ? -1 : 1, - y: isTop ? -1 : 1, - }; - const sizeChange = { - x: position.x * resizingDirection.x, - y: position.y * resizingDirection.y, + x: isLeft ? -position.x : position.x, + y: isTop ? -position.y : position.y, }; // adjust variables when dragging the center @@ -122,43 +118,48 @@ const SelectedLabel: React.FC<{ positionAdjustment.y = 0; } - setPositionStyles({ + applyPositionStyles({ left: currentPositionStyles.left + positionAdjustment.x, top: currentPositionStyles.top + positionAdjustment.y, width: currentPositionStyles.width + sizeChange.x, height: currentPositionStyles.height + sizeChange.y, }); - } + }; - const adjustTextStyles = () => { + const computeTextStyles = () => { // these magic numbers are a result of disparity between font's apparent and actual size const sizeOffsetX = 0.99; const sizeOffsetY = 1.21; // scale starts at 1 and as it gets larger approaches sizeOffset const textScale = { - x: (positionStyles.current.width / constantStyles.current.initialWidth) - * sizeOffsetX - sizeOffsetX + 1, - y: (positionStyles.current.height / constantStyles.current.initialHeight) - * sizeOffsetY - sizeOffsetY + 1, + x: + (positionStyles.current.width / constantStyles.current.initialWidth) * + sizeOffsetX - + sizeOffsetX + + 1, + y: + (positionStyles.current.height / constantStyles.current.initialHeight) * + sizeOffsetY - + sizeOffsetY + + 1, }; // prevent text overadjustment if (textScale.x < 0) textScale.x = 0; if (textScale.y < 0) textScale.y = 0; - applyTextScale(textScale.x, textScale.y); - } + applyTextScale(textScale); + }; - const positionPropagator = ( - position: { x: number; y: number }, + const movementPropagator = ( + movementDelta: { x: number; y: number }, draggableIdentifier: DraggableId ) => { if (!isInteractive) return; - adjustSelectionStyles(position, draggableIdentifier); - - adjustTextStyles(); + computeSelectionStyles(movementDelta, draggableIdentifier); + computeTextStyles(); }; return ( @@ -166,34 +167,36 @@ const SelectedLabel: React.FC<{ ref={selectionRef} className={clsx(styles.headingLabel, styles.selection)} style={{ - position: constantStyles.current.isTextInteractive ? 'absolute' : 'relative', + position: constantStyles.current.enabledTextInteractivity + ? 'absolute' + : 'relative', }}>
diff --git a/docs/src/components/Hero/SelectedLabel/styles.module.css b/docs/src/components/Hero/SelectedLabel/styles.module.css index 02dbcb6a6a2f..66fd1fb0961b 100644 --- a/docs/src/components/Hero/SelectedLabel/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/styles.module.css @@ -14,10 +14,14 @@ /* normally one would do this with border dashed but that doesn't allow for modifying spacing between dashes */ /* prettier-ignore */ background: - linear-gradient(to right, var(--swm-landing-heading-selected-border) 50%, transparent 0%) top/var(--swm-dash-spacing) var(--swm-dash-width) repeat-x, /* top */ - linear-gradient(var(--swm-landing-heading-selected-border) 50%, transparent 0%) right/var(--swm-dash-width) var(--swm-dash-spacing) repeat-y, /* right */ - linear-gradient(to right, var(--swm-landing-heading-selected-border) 50%, transparent 0%) bottom/var(--swm-dash-spacing) var(--swm-dash-width) repeat-x, /* bottom */ - linear-gradient(var(--swm-landing-heading-selected-border) 50%, transparent 0%) left/var(--swm-dash-width) var(--swm-dash-spacing) repeat-y; /* left */ + linear-gradient(to right, var(--swm-landing-heading-selected-border) 50%, transparent 0%) top/var(--swm-dash-spacing) var(--swm-dash-width) repeat-x, + /* top */ + linear-gradient(var(--swm-landing-heading-selected-border) 50%, transparent 0%) right/var(--swm-dash-width) var(--swm-dash-spacing) repeat-y, + /* right */ + linear-gradient(to right, var(--swm-landing-heading-selected-border) 50%, transparent 0%) bottom/var(--swm-dash-spacing) var(--swm-dash-width) repeat-x, + /* bottom */ + linear-gradient(var(--swm-landing-heading-selected-border) 50%, transparent 0%) left/var(--swm-dash-width) var(--swm-dash-spacing) repeat-y; + /* left */ } .selectionContainer { @@ -37,7 +41,7 @@ user-select: none; } -.preInteractiveHeaderText { +.preEnabledTextInteractivity { margin-right: 30px; } From 0fb792dd7ac6e99dbf9103dc6f9817584ad7b2ef Mon Sep 17 00:00:00 2001 From: LatekVo Date: Fri, 15 Mar 2024 00:46:28 +0100 Subject: [PATCH 21/25] Moved logic to a separate file. Increased readability. --- .../components/Hero/SelectedLabel/index.tsx | 137 ++++-------------- .../components/Hero/SelectedLabel/utils.ts | 96 ++++++++++++ 2 files changed, 127 insertions(+), 106 deletions(-) create mode 100644 docs/src/components/Hero/SelectedLabel/utils.ts diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index a13ac4092a91..927de0cb6c96 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -2,50 +2,49 @@ import clsx from 'clsx'; import React, { useEffect, useRef } from 'react'; import styles from './styles.module.css'; import SelectionBox, { DraggableId } from './SelectionBox'; +import { + DynamicStyles, + StaticStyles, + computeSelectionStyles, + computeTextStyles, +} from './utils'; const SelectedLabel: React.FC<{ children: React.ReactNode; isInteractive: Boolean; }> = ({ children, isInteractive = false }) => { - type PositionStyles = { - top: number; - left: number; - width: number; - height: number; - }; - // DOM refs const selectionRef = useRef(null); const selectionContainerRef = useRef(null); const textLabelRef = useRef(null); // Render-persistent label positioning styles - const positionStyles = useRef({ + const dynamicStyles = useRef({ top: 0, left: 0, width: null, height: null, }); - const constantStyles = useRef({ + const staticStyles = useRef({ initialWidth: null, initialHeight: null, enabledTextInteractivity: false, }); - const applyPositionStyles = (newPositionStyles: PositionStyles) => { - const currentPositionStyles = positionStyles.current; + const applyDynamicStyles = (newDynamicStyles: DynamicStyles) => { + const currentDynamicStyles = dynamicStyles.current; // save changes - currentPositionStyles.top = newPositionStyles.top; - currentPositionStyles.left = newPositionStyles.left; - currentPositionStyles.width = newPositionStyles.width; - currentPositionStyles.height = newPositionStyles.height; + currentDynamicStyles.top = newDynamicStyles.top; + currentDynamicStyles.left = newDynamicStyles.left; + currentDynamicStyles.width = newDynamicStyles.width; + currentDynamicStyles.height = newDynamicStyles.height; // apply changes to refs - selectionRef.current.style.transform = `translate(${currentPositionStyles.left}px, ${currentPositionStyles.top}px)`; - selectionContainerRef.current.style.width = `${currentPositionStyles.width}px`; - selectionContainerRef.current.style.height = `${currentPositionStyles.height}px`; + selectionRef.current.style.transform = `translate(${currentDynamicStyles.left}px, ${currentDynamicStyles.top}px)`; + selectionContainerRef.current.style.width = `${currentDynamicStyles.width}px`; + selectionContainerRef.current.style.height = `${currentDynamicStyles.height}px`; }; const applyTextScale = (scaleObject: { x: number; y: number }) => { @@ -56,13 +55,13 @@ const SelectedLabel: React.FC<{ if (!isInteractive) return; let rect = selectionContainerRef.current.getBoundingClientRect(); - constantStyles.current = { + staticStyles.current = { initialWidth: rect.width, initialHeight: rect.height, enabledTextInteractivity: true, }; - applyPositionStyles({ + applyDynamicStyles({ top: 0, left: 0, width: rect.width, @@ -70,96 +69,22 @@ const SelectedLabel: React.FC<{ }); }, []); - const computeSelectionStyles = ( - position: { x: number; y: number }, - draggableIdentifier: DraggableId - ) => { - const isLeft = - draggableIdentifier === DraggableId.BOTTOM_LEFT || - draggableIdentifier === DraggableId.TOP_LEFT; - const isTop = - draggableIdentifier === DraggableId.TOP_LEFT || - draggableIdentifier === DraggableId.TOP_RIGHT; - const isCenter = draggableIdentifier === DraggableId.CENTER; - - // depedning on whether draggable is on left, right, top or bottom, - // we want to either resize, or move and resize our object - const positionAdjustment = { - x: isLeft ? position.x : 0, - y: isTop ? position.y : 0, - }; - - const sizeChange = { - x: isLeft ? -position.x : position.x, - y: isTop ? -position.y : position.y, - }; - - // adjust variables when dragging the center - if (isCenter) { - positionAdjustment.x = sizeChange.x; - positionAdjustment.y = sizeChange.y; - sizeChange.x = 0; - sizeChange.y = 0; - } - - const currentPositionStyles = positionStyles.current; - - // stop overreduction in size - if (currentPositionStyles.width + sizeChange.x < 0) - sizeChange.x = -currentPositionStyles.width; - if (currentPositionStyles.height + sizeChange.y < 0) - sizeChange.y = -currentPositionStyles.height; - - // stop dragging a minimized object - if (!isCenter) { - if (currentPositionStyles.width - positionAdjustment.x < 0) - positionAdjustment.x = 0; - if (currentPositionStyles.height - positionAdjustment.y < 0) - positionAdjustment.y = 0; - } - - applyPositionStyles({ - left: currentPositionStyles.left + positionAdjustment.x, - top: currentPositionStyles.top + positionAdjustment.y, - width: currentPositionStyles.width + sizeChange.x, - height: currentPositionStyles.height + sizeChange.y, - }); - }; - - const computeTextStyles = () => { - // these magic numbers are a result of disparity between font's apparent and actual size - const sizeOffsetX = 0.99; - const sizeOffsetY = 1.21; - - // scale starts at 1 and as it gets larger approaches sizeOffset - const textScale = { - x: - (positionStyles.current.width / constantStyles.current.initialWidth) * - sizeOffsetX - - sizeOffsetX + - 1, - y: - (positionStyles.current.height / constantStyles.current.initialHeight) * - sizeOffsetY - - sizeOffsetY + - 1, - }; - - // prevent text overadjustment - if (textScale.x < 0) textScale.x = 0; - if (textScale.y < 0) textScale.y = 0; - - applyTextScale(textScale); - }; - const movementPropagator = ( movementDelta: { x: number; y: number }, draggableIdentifier: DraggableId ) => { if (!isInteractive) return; - computeSelectionStyles(movementDelta, draggableIdentifier); - computeTextStyles(); + applyDynamicStyles( + computeSelectionStyles( + movementDelta, + draggableIdentifier, + dynamicStyles.current + ) + ); + applyTextScale( + computeTextStyles(dynamicStyles.current, staticStyles.current) + ); }; return ( @@ -167,7 +92,7 @@ const SelectedLabel: React.FC<{ ref={selectionRef} className={clsx(styles.headingLabel, styles.selection)} style={{ - position: constantStyles.current.enabledTextInteractivity + position: staticStyles.current.enabledTextInteractivity ? 'absolute' : 'relative', }}> @@ -196,7 +121,7 @@ const SelectedLabel: React.FC<{ ref={textLabelRef} className={clsx( isInteractive ? styles.preEnabledTextInteractivity : null, - constantStyles.current.enabledTextInteractivity + staticStyles.current.enabledTextInteractivity ? styles.interactiveHeaderText : styles.headerText )}> diff --git a/docs/src/components/Hero/SelectedLabel/utils.ts b/docs/src/components/Hero/SelectedLabel/utils.ts new file mode 100644 index 000000000000..ddb2b27e0001 --- /dev/null +++ b/docs/src/components/Hero/SelectedLabel/utils.ts @@ -0,0 +1,96 @@ +import { DraggableId } from './SelectionBox'; + +export type DynamicStyles = { + top: number; + left: number; + width: number; + height: number; +}; + +export type StaticStyles = { + initialWidth: number; + initialHeight: number; + enabledTextInteractivity: boolean; +}; + +export const computeSelectionStyles = ( + position: { x: number; y: number }, + draggableIdentifier: DraggableId, + dynamicStyles +) => { + const isLeft = + draggableIdentifier === DraggableId.BOTTOM_LEFT || + draggableIdentifier === DraggableId.TOP_LEFT; + const isTop = + draggableIdentifier === DraggableId.TOP_LEFT || + draggableIdentifier === DraggableId.TOP_RIGHT; + const isCenter = draggableIdentifier === DraggableId.CENTER; + + // depedning on whether draggable is on left, right, top or bottom, + // we want to either resize, or move and resize our object + const positionAdjustment = { + x: isLeft ? position.x : 0, + y: isTop ? position.y : 0, + }; + + const sizeChange = { + x: isLeft ? -position.x : position.x, + y: isTop ? -position.y : position.y, + }; + + // adjust variables when dragging the center + if (isCenter) { + positionAdjustment.x = sizeChange.x; + positionAdjustment.y = sizeChange.y; + sizeChange.x = 0; + sizeChange.y = 0; + } + + // stop overreduction in size + if (dynamicStyles.width + sizeChange.x < 0) + sizeChange.x = -dynamicStyles.width; + if (dynamicStyles.height + sizeChange.y < 0) + sizeChange.y = -dynamicStyles.height; + + // stop dragging a minimized object + if (!isCenter) { + if (dynamicStyles.width - positionAdjustment.x < 0) + positionAdjustment.x = 0; + if (dynamicStyles.height - positionAdjustment.y < 0) + positionAdjustment.y = 0; + } + + return { + left: dynamicStyles.left + positionAdjustment.x, + top: dynamicStyles.top + positionAdjustment.y, + width: dynamicStyles.width + sizeChange.x, + height: dynamicStyles.height + sizeChange.y, + }; +}; + +export const computeTextStyles = ( + dynamicStyles: DynamicStyles, + staticStyles: StaticStyles +) => { + // these magic numbers are a result of disparity between font's apparent and actual size + const sizeOffsetX = 0.99; + const sizeOffsetY = 1.21; + + // scale starts at 1 and as it gets larger approaches sizeOffset + const textScale = { + x: + (dynamicStyles.width / staticStyles.initialWidth) * sizeOffsetX - + sizeOffsetX + + 1, + y: + (dynamicStyles.height / staticStyles.initialHeight) * sizeOffsetY - + sizeOffsetY + + 1, + }; + + // prevent text overadjustment + if (textScale.x < 0) textScale.x = 0; + if (textScale.y < 0) textScale.y = 0; + + return textScale; +}; From 96621552b5c3e741d1945a56ab043d3637043d03 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Fri, 15 Mar 2024 09:57:21 +0100 Subject: [PATCH 22/25] Remove unnecessary code. Add better typing annotations. Fix pixel alignment issues. --- docs/src/components/Hero/SelectedLabel/index.tsx | 12 +++--------- .../components/Hero/SelectedLabel/styles.module.css | 6 +++--- docs/src/components/Hero/SelectedLabel/utils.ts | 9 +++++++-- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 927de0cb6c96..8e8af49f6b58 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -5,6 +5,7 @@ import SelectionBox, { DraggableId } from './SelectionBox'; import { DynamicStyles, StaticStyles, + TextScaleStyles, computeSelectionStyles, computeTextStyles, } from './utils'; @@ -47,7 +48,7 @@ const SelectedLabel: React.FC<{ selectionContainerRef.current.style.height = `${currentDynamicStyles.height}px`; }; - const applyTextScale = (scaleObject: { x: number; y: number }) => { + const applyTextScale = (scaleObject: TextScaleStyles) => { textLabelRef.current.style.transform = `translate(-50%, -50%) scale(${scaleObject.x}, ${scaleObject.y})`; }; @@ -88,14 +89,7 @@ const SelectedLabel: React.FC<{ }; return ( - +
{ +): DynamicStyles => { const isLeft = draggableIdentifier === DraggableId.BOTTOM_LEFT || draggableIdentifier === DraggableId.TOP_LEFT; @@ -71,7 +76,7 @@ export const computeSelectionStyles = ( export const computeTextStyles = ( dynamicStyles: DynamicStyles, staticStyles: StaticStyles -) => { +): TextScaleStyles => { // these magic numbers are a result of disparity between font's apparent and actual size const sizeOffsetX = 0.99; const sizeOffsetY = 1.21; From 475ef5a4f0cde0ae878606f42c42ead4377976b4 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Fri, 15 Mar 2024 17:17:04 +0100 Subject: [PATCH 23/25] Updated styles to match their original look on mobile. --- .../SelectionBox/styles.module.css | 18 +++++++++++++++ .../Hero/SelectedLabel/styles.module.css | 18 +++++++++++++-- .../Hero/StartScreen/styles.module.css | 23 ++++++------------- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css index 6dcf7bb48a5b..8b515bd45f1e 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css @@ -44,3 +44,21 @@ .boxRight { right: -15px; } + +@media (max-width: 768px) { + .boxUpper { + top: -11px; + } + + .boxLower { + bottom: -13px; + } + + .boxLeft { + left: -7px; + } + + .boxRight { + right: -7px; + } +} \ No newline at end of file diff --git a/docs/src/components/Hero/SelectedLabel/styles.module.css b/docs/src/components/Hero/SelectedLabel/styles.module.css index 0bcd904a76f6..9f624834a416 100644 --- a/docs/src/components/Hero/SelectedLabel/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/styles.module.css @@ -46,7 +46,21 @@ } @media (max-width: 768px) { + :root { + --swm-dash-spacing: 20px; + } + + .selection { + padding: 6px 2px 8px; + display: block; + margin: 6px 0; + } + + .headerText { + margin: 0 10px; + } + .preInteractiveHeaderText { - margin-right: 8px; + margin-right: 0; } -} +} \ No newline at end of file diff --git a/docs/src/components/Hero/StartScreen/styles.module.css b/docs/src/components/Hero/StartScreen/styles.module.css index fd7f89eff171..ea6eab8cbd21 100644 --- a/docs/src/components/Hero/StartScreen/styles.module.css +++ b/docs/src/components/Hero/StartScreen/styles.module.css @@ -16,15 +16,6 @@ height: fit-content; } -.headingColumn { - display: inline-flex; - flex-direction: column; - padding: 0; - margin: 0; - width: max-content; - margin-right: 8px; -} - .headingLabel { font-family: var(--swm-title-landing-font); font-size: 64px; @@ -62,11 +53,6 @@ font-size: 26px; } - .headingColumn { - flex-direction: column-reverse; - width: 100%; - } - .subheadingLabel { font-size: 20px; width: 90%; @@ -115,10 +101,15 @@ flex-direction: column; justify-content: space-between; - margin-top: 64px; + margin-top: 22px; height: 100%; } + .subheadingLabel { + margin-top: 64px; + margin-bottom: 24px; + } + .foregroundLabel { display: flex; flex-direction: column; @@ -138,4 +129,4 @@ width: fit-content; } -} +} \ No newline at end of file From a6166c8bce35f747c48099ff81a756e89cbcf27e Mon Sep 17 00:00:00 2001 From: LatekVo Date: Fri, 15 Mar 2024 17:35:46 +0100 Subject: [PATCH 24/25] Fix lint errors. --- .../Hero/SelectedLabel/SelectionBox/styles.module.css | 2 +- docs/src/components/Hero/SelectedLabel/styles.module.css | 2 +- docs/src/components/Hero/StartScreen/styles.module.css | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css index 8b515bd45f1e..85c5b2c34f37 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/styles.module.css @@ -61,4 +61,4 @@ .boxRight { right: -7px; } -} \ No newline at end of file +} diff --git a/docs/src/components/Hero/SelectedLabel/styles.module.css b/docs/src/components/Hero/SelectedLabel/styles.module.css index 9f624834a416..a578b10f7364 100644 --- a/docs/src/components/Hero/SelectedLabel/styles.module.css +++ b/docs/src/components/Hero/SelectedLabel/styles.module.css @@ -63,4 +63,4 @@ .preInteractiveHeaderText { margin-right: 0; } -} \ No newline at end of file +} diff --git a/docs/src/components/Hero/StartScreen/styles.module.css b/docs/src/components/Hero/StartScreen/styles.module.css index ea6eab8cbd21..390e228545e3 100644 --- a/docs/src/components/Hero/StartScreen/styles.module.css +++ b/docs/src/components/Hero/StartScreen/styles.module.css @@ -129,4 +129,4 @@ width: fit-content; } -} \ No newline at end of file +} From 5e2b8494d692a8a8dbf86cb2c2a2b7e67d9dbfc7 Mon Sep 17 00:00:00 2001 From: LatekVo Date: Mon, 18 Mar 2024 12:11:57 +0100 Subject: [PATCH 25/25] Apply review suggestion. Add dependencies to useEffect. --- .../Hero/SelectedLabel/SelectionBox/index.tsx | 51 ++++++++++++------- .../components/Hero/SelectedLabel/index.tsx | 20 ++++---- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx index c2fcb6dcc895..96ee1b185487 100644 --- a/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/SelectionBox/index.tsx @@ -11,6 +11,34 @@ export enum DraggableId { CENTER, } +const getClassListByIdentifier = ( + identifier: DraggableId, + isInteractive: boolean +) => { + const isBottom = + identifier == DraggableId.BOTTOM_LEFT || + identifier == DraggableId.BOTTOM_RIGHT; + const isLeft = + identifier == DraggableId.BOTTOM_LEFT || identifier == DraggableId.TOP_LEFT; + const isCenter = identifier === DraggableId.CENTER; + + let classList = styles.centerDraggable; + + if (!isCenter) { + classList = clsx( + styles.selectionBox, + isBottom ? styles.boxLower : styles.boxUpper, + isLeft ? styles.boxLeft : styles.boxRight + ); + } + + if (isInteractive) { + classList = clsx(classList, styles.movable); + } + + return classList; +}; + const SelectionBox: React.FC<{ propagationFunction: ( movementDelta: { x: number; y: number }, @@ -18,29 +46,18 @@ const SelectionBox: React.FC<{ ) => void; draggableIdentifier: DraggableId; children?: React.ReactNode; - isInteractive: Boolean; + isInteractive: boolean; }> = ({ propagationFunction, draggableIdentifier, children, isInteractive, }) => { - const isBottom = - draggableIdentifier == DraggableId.BOTTOM_LEFT || - draggableIdentifier == DraggableId.BOTTOM_RIGHT; - const isLeft = - draggableIdentifier == DraggableId.BOTTOM_LEFT || - draggableIdentifier == DraggableId.TOP_LEFT; - const isCenter = draggableIdentifier === DraggableId.CENTER; - - let classList = clsx( - styles.selectionBox, - isBottom ? styles.boxLower : styles.boxUpper, - isLeft ? styles.boxLeft : styles.boxRight + const classList = getClassListByIdentifier( + draggableIdentifier, + isInteractive ); - classList = isCenter ? clsx(styles.centerDraggable) : classList; - return ( { @@ -51,9 +68,7 @@ const SelectionBox: React.FC<{ }} allowAnyClick={false} axis={'none'}> -
- {children} -
+
{children}
); }; diff --git a/docs/src/components/Hero/SelectedLabel/index.tsx b/docs/src/components/Hero/SelectedLabel/index.tsx index 8e8af49f6b58..e901cd2b3063 100644 --- a/docs/src/components/Hero/SelectedLabel/index.tsx +++ b/docs/src/components/Hero/SelectedLabel/index.tsx @@ -12,7 +12,7 @@ import { const SelectedLabel: React.FC<{ children: React.ReactNode; - isInteractive: Boolean; + isInteractive: boolean; }> = ({ children, isInteractive = false }) => { // DOM refs const selectionRef = useRef(null); @@ -68,7 +68,7 @@ const SelectedLabel: React.FC<{ width: rect.width, height: rect.height, }); - }, []); + }, [isInteractive]); const movementPropagator = ( movementDelta: { x: number; y: number }, @@ -88,6 +88,13 @@ const SelectedLabel: React.FC<{ ); }; + const classList = clsx( + isInteractive ? styles.preEnabledTextInteractivity : null, + staticStyles.current.enabledTextInteractivity + ? styles.interactiveHeaderText + : styles.headerText + ); + return (
@@ -111,14 +118,7 @@ const SelectedLabel: React.FC<{ propagationFunction={movementPropagator} draggableIdentifier={DraggableId.CENTER} isInteractive={isInteractive}> - + {children}