From 8dfe68ec59c428391331608a72d725bc714d3beb Mon Sep 17 00:00:00 2001 From: "LAPTOP-G2U17NSB\\duy_9" Date: Wed, 4 Sep 2024 15:48:31 +0200 Subject: [PATCH 01/50] Unit test aded for calendar.business.tsx component --- .../calendar/calendar.business.spec.ts | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/common/components/front-rich-components/calendar/calendar.business.spec.ts diff --git a/src/common/components/front-rich-components/calendar/calendar.business.spec.ts b/src/common/components/front-rich-components/calendar/calendar.business.spec.ts new file mode 100644 index 00000000..fec35e06 --- /dev/null +++ b/src/common/components/front-rich-components/calendar/calendar.business.spec.ts @@ -0,0 +1,104 @@ +import { + calculateNextMonth, + calculatePreviousMonth, + getCurrentMonthDays, +} from './calendar.business'; + +describe('calculatePreviousMonth', () => { + it('should return previous month', () => { + //Arrange + const date = new Date(2024, 11, 4); + //Act + const prevMonth = calculatePreviousMonth(date); + //Assert + expect(prevMonth.getMonth()).toBe(10); + }); + it('should return previous month', () => { + //Arrange + const date = new Date(1992, 8, 20); + //Act + const prevMonth = calculatePreviousMonth(date); + //Assert + expect(prevMonth.getMonth()).toBe(7); + }); + it('should return previous month', () => { + //Arrange + const date = new Date(2121, 6, 20); + //Act + const prevMonth = calculatePreviousMonth(date); + //Assert + expect(prevMonth.getMonth()).toBe(5); + }); +}); + +describe('calculateNextMonth', () => { + it('should return next month', () => { + //Arrange + const date = new Date(2024, 1, 4); + //Act + const nextMonth = calculateNextMonth(date); + //Assert + expect(nextMonth.getMonth()).toBe(2); + }); + it('should return next month', () => { + //Arrange + const date = new Date(2011, 5, 4); + //Act + const nextMonth = calculateNextMonth(date); + //Assert + expect(nextMonth.getMonth()).toBe(6); + }); + it('should return next month', () => { + //Arrange + const date = new Date(2532, 12, 4); + //Act + const nextMonth = calculateNextMonth(date); + //Assert + expect(nextMonth.getMonth()).toBe(1); + }); +}); + +describe('getCurrentMonthDays', () => { + it('should return 31 days when selected month is july', () => { + //Arrange + const date = new Date(2024, 6, 1); + //Act + const result = getCurrentMonthDays(date); + //Assert + expect(result.days).toEqual([ + [null, 1, 2, 3, 4, 5, 6], + [7, 8, 9, 10, 11, 12, 13], + [14, 15, 16, 17, 18, 19, 20], + [21, 22, 23, 24, 25, 26, 27], + [28, 29, 30, 31], + ]); + }); + it('should return 30 days when selected month is september', () => { + //Arrange + const date = new Date(2024, 8, 1); + //Act + const result = getCurrentMonthDays(date); + //Assert + expect(result.days).toEqual([ + [1, 2, 3, 4, 5, 6, 7], + [8, 9, 10, 11, 12, 13, 14], + [15, 16, 17, 18, 19, 20, 21], + [22, 23, 24, 25, 26, 27, 28], + [29, 30], + ]); + }); + it('should return 31 days when selected month is january', () => { + //Arrange + const date = new Date(2024, 0, 1); + //Act + const result = getCurrentMonthDays(date); + //Assert + expect(result.days).toEqual([ + [null, 1, 2, 3, 4, 5, 6], + [7, 8, 9, 10, 11, 12, 13], + [14, 15, 16, 17, 18, 19, 20], + [21, 22, 23, 24, 25, 26, 27], + [28, 29, 30, 31], + ]); + }); +}); From f77b73523a301c551c43db8c9f99115c613d0af6 Mon Sep 17 00:00:00 2001 From: "LAPTOP-G2U17NSB\\duy_9" Date: Wed, 4 Sep 2024 17:05:25 +0200 Subject: [PATCH 02/50] Added mark on horizontal-menu selected option --- .../horizontal-menu/horizontal-menu.tsx | 25 ++++++++++++++++--- .../horizontal-menu/hozontal-menu.business.ts | 9 ++++++- src/pods/canvas/canvas.model.ts | 2 +- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/common/components/front-rich-components/horizontal-menu/horizontal-menu.tsx b/src/common/components/front-rich-components/horizontal-menu/horizontal-menu.tsx index 3eae1c0c..87461c8f 100644 --- a/src/common/components/front-rich-components/horizontal-menu/horizontal-menu.tsx +++ b/src/common/components/front-rich-components/horizontal-menu/horizontal-menu.tsx @@ -34,12 +34,20 @@ export const HorizontalMenu = forwardRef((props, ref) => { ...shapeProps } = props; - const [items, setItems] = useState([]); + const [selectedItem, setSelectedItem] = useState(null); + const [items, setItems] = useState([ + '[*]Home, About, Services, Contact', + ]); + const handleClick = (itemIndex: number) => { + setSelectedItem(itemIndex); + onSelected(id, 'horizontal-menu', true); + }; useEffect(() => { if (typeof text === 'string') { - const { items } = mapHorizontalMenuTextToItems(text); + const { items, selectedItemIndex } = mapHorizontalMenuTextToItems(text); setItems(items); + setSelectedItem(selectedItemIndex); } else { setItems([]); } @@ -88,6 +96,8 @@ export const HorizontalMenu = forwardRef((props, ref) => { const { handleSelection } = useShapeComponentSelection(props, shapeType); + const itemVerticalPadding = 4; + return ( ((props, ref) => { /> {items.map((e: string, index: number) => ( - + handleClick(index)}> + { - let items: string[] = text.trim().split(','); + let items: string[] = text.split(',').map(item => item.trim()); + + const selectedItemIndex = items.findIndex(item => item.startsWith('[*]')); + + items = items.map(item => item.replace(/^\[\*\]/, '')); + items = items.filter(item => item !== ''); return { items: items, + selectedItemIndex: selectedItemIndex === -1 ? 0 : selectedItemIndex, }; }; diff --git a/src/pods/canvas/canvas.model.ts b/src/pods/canvas/canvas.model.ts index f605da3a..de35d073 100644 --- a/src/pods/canvas/canvas.model.ts +++ b/src/pods/canvas/canvas.model.ts @@ -314,7 +314,7 @@ const generateDefaultTextValue = (shapeType: ShapeType): string | undefined => { case 'listbox': return '[*]Item\nItem1\nItem2\nItem3\nItem4\nItem5\nItem6'; case 'horizontal-menu': - return 'Home, About, Services, Contact'; + return '[*]Home, About, Services, Contact'; case 'vertical-menu': return 'Option 1\nOption 2\n----\nOption 3\nOption 4'; case 'heading1': From 10c0d59e7b72bff494ef313e577829d4e8c71ef5 Mon Sep 17 00:00:00 2001 From: Braulio Date: Thu, 5 Sep 2024 12:22:19 +0200 Subject: [PATCH 03/50] cleand up post it and input shapes --- .../front-basic-sapes/postit-basic-shape.tsx | 29 +++---------- .../front-components/input-shape.tsx | 30 +++---------- .../front-components/shape.const.ts | 16 ++++++- .../components/shapes/use-shape-props.hook.ts | 42 +++++++++++++++++++ 4 files changed, 67 insertions(+), 50 deletions(-) create mode 100644 src/common/components/shapes/use-shape-props.hook.ts diff --git a/src/common/components/front-basic-sapes/postit-basic-shape.tsx b/src/common/components/front-basic-sapes/postit-basic-shape.tsx index 14636c52..31ac24d1 100644 --- a/src/common/components/front-basic-sapes/postit-basic-shape.tsx +++ b/src/common/components/front-basic-sapes/postit-basic-shape.tsx @@ -3,8 +3,9 @@ import { forwardRef, useMemo } from 'react'; import { ShapeProps } from '../front-components/shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; import { Group, Rect, Text } from 'react-konva'; -import { INPUT_SHAPE } from '../front-components/shape.const'; +import { INPUT_SHAPE, POSTIT_SHAPE } from '../front-components/shape.const'; import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; +import { useShapeProps } from '../shapes/use-shape-props.hook'; const postItShapeRestrictions: ShapeSizeRestrictions = { minWidth: 80, @@ -47,31 +48,11 @@ export const PostItShape = forwardRef((props, ref) => { const tapeRotation = -10; - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? '#FFFF99', - [otherProps?.backgroundColor] - ); - - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] + const { stroke, fill, textColor, strokeStyle, borderRadius } = useShapeProps( + otherProps, + POSTIT_SHAPE ); - const borderRadius = useMemo(() => { - const radius = Number(otherProps?.borderRadius); - return isNaN(radius) ? INPUT_SHAPE.DEFAULT_CORNER_RADIUS : radius; - }, [otherProps?.borderRadius]); - return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(inputShapeRestrictions, width, height); - const stroke = useMemo( - () => otherProps?.stroke ?? INPUT_SHAPE.DEFAULT_STROKE_COLOR, - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? INPUT_SHAPE.DEFAULT_FILL_BACKGROUND, - [otherProps?.backgroundColor] - ); - - const textColor = useMemo( - () => otherProps?.textColor ?? INPUT_SHAPE.DEFAULT_FILL_TEXT, - [otherProps?.textColor] - ); - - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] + const { stroke, fill, textColor, strokeStyle, borderRadius } = useShapeProps( + otherProps, + INPUT_SHAPE ); - - const borderRadius = useMemo(() => { - const radius = Number(otherProps?.borderRadius); - return isNaN(radius) ? INPUT_SHAPE.DEFAULT_CORNER_RADIUS : radius; - }, [otherProps?.borderRadius]); - const { handleSelection } = useShapeComponentSelection(props, shapeType); return ( diff --git a/src/common/components/front-components/shape.const.ts b/src/common/components/front-components/shape.const.ts index 03ac73b3..a3112c3f 100644 --- a/src/common/components/front-components/shape.const.ts +++ b/src/common/components/front-components/shape.const.ts @@ -13,7 +13,7 @@ const DEFAULT_FONT_SIZE_INPUT = 15; const DEFAULT_TEXT_WIDTH = 155; const DEFAULT_TEXT_HEIGHT = 38; -interface DefaultStyleShape { +export interface DefaultStyleShape { DEFAULT_CORNER_RADIUS: number; DEFAULT_STROKE_COLOR: string; DEFAULT_STROKE_WIDTH: number; @@ -59,3 +59,17 @@ export const INPUT_SHAPE: DefaultStyleShape = { }; //! maybe a function to calc max height base on the text +export const POSTIT_SHAPE: DefaultStyleShape = { + DEFAULT_CORNER_RADIUS, + DEFAULT_STROKE_COLOR, + DEFAULT_STROKE_WIDTH, + DEFAULT_FILL_BACKGROUND: '#FFFF99', + DEFAULT_FONT_FAMILY, + DEFAULT_FONT_SIZE: DEFAULT_FONT_SIZE_INPUT, + DEFAULT_FILL_TEXT: '#000000', + DEFAULT_PADDING, + DEFAULT_LINE_HEIGHT, + DEFAULT_TEXT_WIDTH, + DEFAULT_TEXT_HEIGHT, + DEFAULT_STROKE_STYLE, +}; diff --git a/src/common/components/shapes/use-shape-props.hook.ts b/src/common/components/shapes/use-shape-props.hook.ts new file mode 100644 index 00000000..9d7d79cd --- /dev/null +++ b/src/common/components/shapes/use-shape-props.hook.ts @@ -0,0 +1,42 @@ +import { OtherProps } from '@/core/model'; +import { useMemo } from 'react'; +import { DefaultStyleShape } from '../front-components/shape.const'; + +export const useShapeProps = ( + otherProps: OtherProps | undefined, + defaultStyleShape: DefaultStyleShape +) => { + const stroke = useMemo( + () => otherProps?.stroke ?? defaultStyleShape.DEFAULT_STROKE_COLOR, + [otherProps?.stroke] + ); + + const fill = useMemo( + () => + otherProps?.backgroundColor ?? defaultStyleShape.DEFAULT_FILL_BACKGROUND, + [otherProps?.backgroundColor] + ); + + const textColor = useMemo( + () => otherProps?.textColor ?? defaultStyleShape.DEFAULT_FILL_TEXT, + [otherProps?.textColor] + ); + + const strokeStyle = useMemo( + () => otherProps?.strokeStyle ?? [], + [otherProps?.strokeStyle] + ); + + const borderRadius = useMemo(() => { + const radius = Number(otherProps?.borderRadius); + return isNaN(radius) ? defaultStyleShape.DEFAULT_CORNER_RADIUS : radius; + }, [otherProps?.borderRadius]); + + return { + stroke, + fill, + textColor, + strokeStyle, + borderRadius, + }; +}; From 6f7840618349fc777b3ade1166b51f5c161686ea Mon Sep 17 00:00:00 2001 From: Braulio Date: Thu, 5 Sep 2024 12:22:31 +0200 Subject: [PATCH 04/50] post it --- .../components/front-basic-sapes/postit-basic-shape.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/components/front-basic-sapes/postit-basic-shape.tsx b/src/common/components/front-basic-sapes/postit-basic-shape.tsx index 31ac24d1..72ff9f67 100644 --- a/src/common/components/front-basic-sapes/postit-basic-shape.tsx +++ b/src/common/components/front-basic-sapes/postit-basic-shape.tsx @@ -1,9 +1,9 @@ import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; -import { forwardRef, useMemo } from 'react'; +import { forwardRef } from 'react'; import { ShapeProps } from '../front-components/shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; import { Group, Rect, Text } from 'react-konva'; -import { INPUT_SHAPE, POSTIT_SHAPE } from '../front-components/shape.const'; +import { POSTIT_SHAPE } from '../front-components/shape.const'; import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; import { useShapeProps } from '../shapes/use-shape-props.hook'; From 22bb40b5298415542aeb83b4ab15cc46a41c3373 Mon Sep 17 00:00:00 2001 From: Leticia de la Osa Date: Wed, 4 Sep 2024 16:00:32 +0200 Subject: [PATCH 05/50] Gallery hover --- .../components/item-component.module.css | 11 ++++++ .../gallery/components/item-component.tsx | 34 ++++++++++++++++++- src/main.css | 1 + src/scenes/main.module.css | 1 + 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/common/components/gallery/components/item-component.module.css b/src/common/components/gallery/components/item-component.module.css index 41221fc8..e5521801 100644 --- a/src/common/components/gallery/components/item-component.module.css +++ b/src/common/components/gallery/components/item-component.module.css @@ -1,4 +1,5 @@ .container { + position: relative; display: flex; flex-direction: column; justify-content: space-between; @@ -10,16 +11,26 @@ } .image { + position: relative; padding: var(--space-xs); width: var(--gallery-item-size); height: var(--gallery-item-size); border-radius: var(--border-radius-s); display: flex; align-items: center; + background-color: var(--primary-50); + cursor: grab; + transition: all 0.3s ease-in-out; } + .image img { pointer-events: none; width: 100%; height: 100%; object-fit: contain; } + +.image:hover { + background-color: #fafafa; + box-shadow: 0 0 5px 0px var(--primary-200); +} diff --git a/src/common/components/gallery/components/item-component.tsx b/src/common/components/gallery/components/item-component.tsx index 1e4852dd..53beb3e5 100644 --- a/src/common/components/gallery/components/item-component.tsx +++ b/src/common/components/gallery/components/item-component.tsx @@ -1,5 +1,7 @@ import { useEffect, useRef, useState } from 'react'; +import { createRoot } from 'react-dom/client'; import { draggable } from '@atlaskit/pragmatic-drag-and-drop/element/adapter'; +import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview'; import invariant from 'tiny-invariant'; import { ShapeDisplayName, ShapeType } from '@/core/model'; import { ItemInfo } from './model'; @@ -11,7 +13,7 @@ interface Props { export const ItemComponent: React.FC = props => { const { item } = props; - const dragRef = useRef(null); + const dragRef = useRef(null); const [isDragging, setIsDragging] = useState(false); useEffect(() => { @@ -24,6 +26,20 @@ export const ItemComponent: React.FC = props => { getInitialData: () => ({ type: item.type }), onDragStart: () => setIsDragging(true), onDrop: () => setIsDragging(false), + onGenerateDragPreview: ({ nativeSetDragImage }) => { + setCustomNativeDragPreview({ + //Important: this numbers are the half of the width and height of var(--gallery-item-size) + getOffset: () => ({ x: 55, y: 55 }), + render({ container }) { + const root = createRoot(container); + root.render(); + return function cleanup() { + root.unmount(); + }; + }, + nativeSetDragImage, + }); + }, }); }, []); @@ -38,9 +54,25 @@ export const ItemComponent: React.FC = props => { title={ShapeDisplayName[item.type as ShapeType]} /> + {ShapeDisplayName[item.type as ShapeType]} ); }; + +const Preview: React.FC = props => { + const { item } = props; + + return ( + + ); +}; diff --git a/src/main.css b/src/main.css index b0381fd2..a0aee024 100644 --- a/src/main.css +++ b/src/main.css @@ -44,6 +44,7 @@ --canvas-min-size: 500px; /*gallery*/ + /*If this var change need to change getOffset x and y on item-component.tsx*/ --gallery-item-size: 110px; /*Main styles*/ diff --git a/src/scenes/main.module.css b/src/scenes/main.module.css index 85dd51a6..2c370d81 100644 --- a/src/scenes/main.module.css +++ b/src/scenes/main.module.css @@ -22,6 +22,7 @@ border-bottom: 1px solid var(--primary-900); } .title { + z-index: 1; position: sticky; top: 0; background-color: var(--primary-200); From b62f5d4066dea567ac10015b19a5ed54cefe6e4e Mon Sep 17 00:00:00 2001 From: Braulio Date: Fri, 6 Sep 2024 11:16:20 +0200 Subject: [PATCH 06/50] added comment --- .../gallery/components/item-component.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/common/components/gallery/components/item-component.tsx b/src/common/components/gallery/components/item-component.tsx index 53beb3e5..9bf0ec36 100644 --- a/src/common/components/gallery/components/item-component.tsx +++ b/src/common/components/gallery/components/item-component.tsx @@ -29,6 +29,21 @@ export const ItemComponent: React.FC = props => { onGenerateDragPreview: ({ nativeSetDragImage }) => { setCustomNativeDragPreview({ //Important: this numbers are the half of the width and height of var(--gallery-item-size) + // TODO, we may extract the size variable value from the HTML variable it self + // watch out this variable returs an string something like "110px" + // + // Sample + // const getGallerySize = () => { + // + // const rootElement = document.documentElement; + // const itemSize = getComputedStyle(rootElement) + // .getPropertyValue('--gallery-item-size') + // .trim(); + // + // console.log('itemSize', itemSize); + // + // return itemSize; + //}; getOffset: () => ({ x: 55, y: 55 }), render({ container }) { const root = createRoot(container); From 099e0507bfc32c6882ae0c46a6dccd96beddb261 Mon Sep 17 00:00:00 2001 From: Fran Lopez Date: Fri, 6 Sep 2024 18:12:26 +0200 Subject: [PATCH 07/50] refactor all basic shapes --- .../front-basic-sapes/circle-basic-shape.tsx | 19 +++---------- .../front-basic-sapes/diamond-shape.tsx | 19 +++---------- .../front-basic-sapes/large-arrow-shape.tsx | 19 +++---------- .../front-basic-sapes/line-basic-shape.tsx | 16 ++++------- .../rectangle-basic-shape.tsx | 28 +++++-------------- .../front-basic-sapes/star-shape.tsx | 21 ++++---------- .../triangle-basic-shape.tsx | 21 ++++---------- 7 files changed, 34 insertions(+), 109 deletions(-) diff --git a/src/common/components/front-basic-sapes/circle-basic-shape.tsx b/src/common/components/front-basic-sapes/circle-basic-shape.tsx index 9cd4a7ac..7ceb61d0 100644 --- a/src/common/components/front-basic-sapes/circle-basic-shape.tsx +++ b/src/common/components/front-basic-sapes/circle-basic-shape.tsx @@ -1,9 +1,11 @@ import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; -import { forwardRef, useMemo } from 'react'; +import { forwardRef } from 'react'; import { ShapeProps } from '../front-components/shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; import { Circle, Group } from 'react-konva'; import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; +import { useShapeProps } from '../shapes/use-shape-props.hook'; +import { BASIC_SHAPE } from '../front-components/shape.const'; const circleShapeRestrictions: ShapeSizeRestrictions = { minWidth: 10, @@ -29,20 +31,7 @@ export const CircleShape = forwardRef((props, ref) => { const { handleSelection } = useShapeComponentSelection(props, shapeType); - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] - ); + const { stroke, fill, strokeStyle } = useShapeProps(otherProps, BASIC_SHAPE); return ( ((props, ref) => { halfHeight, // Left point ]; - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] - ); + const { stroke, fill, strokeStyle } = useShapeProps(otherProps, BASIC_SHAPE); return ( ((props, ref) => { return restrictedHeight / LARGE_ARROW_FIX_HEIGHT; }, [restrictedHeight]); - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { stroke, fill, strokeStyle } = useShapeProps(otherProps, BASIC_SHAPE); + return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(lineShapeRestrictions, width, height); - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { stroke, strokeStyle } = useShapeProps(otherProps, BASIC_SHAPE); + return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(rectangleShapeRestrictions, width, height); - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); + const { handleSelection } = useShapeComponentSelection(props, shapeType); - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] + const { stroke, strokeStyle, fill, borderRadius } = useShapeProps( + otherProps, + BASIC_SHAPE ); - const borderRadius = useMemo(() => { - const radius = Number(otherProps?.borderRadius); - return isNaN(radius) ? INPUT_SHAPE.DEFAULT_CORNER_RADIUS : radius; - }, [otherProps?.borderRadius]); - - const { handleSelection } = useShapeComponentSelection(props, shapeType); - return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(starShapeRestrictions, width, height); - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { stroke, strokeStyle, fill } = useShapeProps(otherProps, BASIC_SHAPE); + return ( ((props, ref) => { restrictedHeight, // Left point ]; - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { stroke, strokeStyle, fill } = useShapeProps(otherProps, BASIC_SHAPE); + return ( Date: Fri, 6 Sep 2024 20:24:43 +0200 Subject: [PATCH 08/50] refactor all components shapes --- .../front-components/button-shape.tsx | 33 ++++-------------- .../front-components/checkbox-shape.tsx | 15 +++----- .../front-components/combobox-shape.tsx | 34 +++++-------------- .../datepickerinput-shape.tsx | 28 ++++----------- .../front-components/input-shape.tsx | 3 +- .../front-components/label-shape.tsx | 11 +++--- .../listbox/listbox-shape.tsx | 28 ++++----------- .../front-components/progressbar-shape.tsx | 11 +++--- .../front-components/radiobutton-shape.tsx | 16 +++------ .../front-components/slider-shape.tsx | 22 ++++-------- .../front-components/textarea-shape.tsx | 33 ++++-------------- .../timepickerinput-shape.tsx | 28 ++++----------- .../front-components/toggleswitch-shape.tsx | 11 +++--- .../front-components/tooltip-shape.tsx | 26 ++++---------- 14 files changed, 82 insertions(+), 217 deletions(-) diff --git a/src/common/components/front-components/button-shape.tsx b/src/common/components/front-components/button-shape.tsx index baec0779..0e8f9335 100644 --- a/src/common/components/front-components/button-shape.tsx +++ b/src/common/components/front-components/button-shape.tsx @@ -1,10 +1,11 @@ import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; -import { forwardRef, useMemo } from 'react'; +import { forwardRef } from 'react'; import { ShapeProps } from './shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; import { Group, Rect, Text } from 'react-konva'; -import { INPUT_SHAPE } from './shape.const'; +import { BASIC_SHAPE } from './shape.const'; import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; +import { useShapeProps } from '../shapes/use-shape-props.hook'; const buttonShapeRestrictions: ShapeSizeRestrictions = { minWidth: 50, @@ -35,33 +36,13 @@ export const ButtonShape = forwardRef((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(buttonShapeRestrictions, width, height); - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); + const { handleSelection } = useShapeComponentSelection(props, shapeType); - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] + const { stroke, strokeStyle, fill, textColor, borderRadius } = useShapeProps( + otherProps, + BASIC_SHAPE ); - const borderRadius = useMemo(() => { - const radius = Number(otherProps?.borderRadius); - return isNaN(radius) ? INPUT_SHAPE.DEFAULT_CORNER_RADIUS : radius; - }, [otherProps?.borderRadius]); - - const { handleSelection } = useShapeComponentSelection(props, shapeType); - return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(checkBoxShapeRestrictions, width, height); - const isOn = useMemo( - () => otherProps?.checked ?? true, - [otherProps?.checked] - ); - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { isOn, textColor } = useShapeProps(otherProps, BASIC_SHAPE); + return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(comboBoxShapeRestrictions, width, height); - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - - const textColor = useMemo( - () => otherProps?.textColor ?? 'white', - [otherProps?.textColor] - ); - - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] - ); - - const borderRadius = useMemo(() => { - const stringBorderRadius = otherProps?.borderRadius ?? '12'; - return parseFloat(stringBorderRadius); - }, [otherProps?.borderRadius]); - const { handleSelection } = useShapeComponentSelection(props, shapeType); const createPathWithRoundedCorners = (w: number, h: number, r: number) => { @@ -74,6 +51,11 @@ export const ComboBoxShape = forwardRef((props, ref) => { Z`; }; + const { stroke, strokeStyle, fill, textColor, borderRadius } = useShapeProps( + otherProps, + BASIC_SHAPE + ); + return ( ( const separator1X = restrictedWidth / 3; const separator2X = (2 * restrictedWidth) / 3; - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); + const { handleSelection } = useShapeComponentSelection(props, shapeType); - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] + const { stroke, strokeStyle, fill, borderRadius } = useShapeProps( + otherProps, + BASIC_SHAPE ); - const borderRadius = useMemo(() => { - const radius = Number(otherProps?.borderRadius); - return isNaN(radius) ? INPUT_SHAPE.DEFAULT_CORNER_RADIUS : radius; - }, [otherProps?.borderRadius]); - - const { handleSelection } = useShapeComponentSelection(props, shapeType); - return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(inputShapeRestrictions, width, height); + const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { stroke, fill, textColor, strokeStyle, borderRadius } = useShapeProps( otherProps, INPUT_SHAPE ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(labelSizeRestrictions, width, height); - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { textColor } = useShapeProps(otherProps, BASIC_SHAPE); + return ( ( listboxShapeSizeRestrictions, }); - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] - ); - - const borderRadius = useMemo(() => { - const radius = Number(otherProps?.borderRadius); - return isNaN(radius) ? INPUT_SHAPE.DEFAULT_CORNER_RADIUS : radius; - }, [otherProps?.borderRadius]); + const { stroke, strokeStyle, fill, borderRadius, textColor } = + useShapeProps(otherProps, BASIC_SHAPE); return ( ( height={singleHeaderHeight - 12} fontFamily="Comic Sans MS, cursive" fontSize={15} - fill="black" + fill={textColor} wrap="none" ellipsis={true} /> diff --git a/src/common/components/front-components/progressbar-shape.tsx b/src/common/components/front-components/progressbar-shape.tsx index 8ccc6ef8..4b2e5b97 100644 --- a/src/common/components/front-components/progressbar-shape.tsx +++ b/src/common/components/front-components/progressbar-shape.tsx @@ -4,6 +4,8 @@ import { ShapeProps } from './shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; import { Group, Rect } from 'react-konva'; import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; +import { useShapeProps } from '../shapes/use-shape-props.hook'; +import { BASIC_SHAPE } from './shape.const'; const progressBarShapeRestrictions: ShapeSizeRestrictions = { minWidth: 100, @@ -25,18 +27,15 @@ export const ProgressBarShape = forwardRef((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(progressBarShapeRestrictions, width, height); - const progress = useMemo(() => { - const prog = otherProps?.progress ?? 50; - return typeof prog === 'string' ? parseFloat(prog) : prog; - }, [otherProps?.progress]); + const { handleSelection } = useShapeComponentSelection(props, shapeType); + + const { progress } = useShapeProps(otherProps, BASIC_SHAPE); const progressWidth = useMemo( () => (progress / 100) * restrictedWidth, [progress, restrictedWidth] ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); - return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(radioButtonShapeRestrictions, width, height); - const isOn = useMemo( - () => otherProps?.checked ?? true, - [otherProps?.checked] - ); - - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); const radius = restrictedHeight / 2; + const { isOn, textColor } = useShapeProps(otherProps, BASIC_SHAPE); + return ( ( const sliderStart = thumbRadius; const sliderEnd = width - thumbRadius; - const progressPosition = useMemo(() => { - const prog = otherProps?.progress ?? 50; - console.log('Raw progress:', otherProps?.progress); - const progressValue = typeof prog === 'string' ? parseFloat(prog) : prog; - console.log('Parsed progress:', progressValue); + const { fill, progress } = useShapeProps(otherProps, BASIC_SHAPE); - const position = - sliderStart + (progressValue / 100) * (sliderEnd - sliderStart); - console.log('Calculated position:', position); - return position; - }, [otherProps?.progress, sliderStart, sliderEnd]); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] + const progressWidth = useMemo( + () => (progress / 100) * restrictedWidth, + [progress, restrictedWidth] ); return ( @@ -63,7 +55,7 @@ export const SliderShape = forwardRef( {/* Thumb del slider */} ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(textAreaShapeRestrictions, width, height); - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); + const { handleSelection } = useShapeComponentSelection(props, shapeType); - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] + const { stroke, strokeStyle, fill, textColor, borderRadius } = useShapeProps( + otherProps, + BASIC_SHAPE ); - const borderRadius = useMemo(() => { - const radius = Number(otherProps?.borderRadius); - return isNaN(radius) ? INPUT_SHAPE.DEFAULT_CORNER_RADIUS : radius; - }, [otherProps?.borderRadius]); - - const { handleSelection } = useShapeComponentSelection(props, shapeType); - return ( ( const separator1X = restrictedWidth / 3; const separator2X = (2 * restrictedWidth) / 3; - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); + const { handleSelection } = useShapeComponentSelection(props, shapeType); - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] + const { stroke, strokeStyle, fill, borderRadius } = useShapeProps( + otherProps, + BASIC_SHAPE ); - const borderRadius = useMemo(() => { - const radius = Number(otherProps?.borderRadius); - return isNaN(radius) ? INPUT_SHAPE.DEFAULT_CORNER_RADIUS : radius; - }, [otherProps?.borderRadius]); - - const { handleSelection } = useShapeComponentSelection(props, shapeType); - return ( ((props, ref) => { height ); - const isOn = useMemo( - () => otherProps?.checked ?? true, - [otherProps?.checked] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { isOn } = useShapeProps(otherProps, BASIC_SHAPE); + const circleX = isOn ? restrictedWidth - restrictedHeight / 2 : restrictedHeight / 2; diff --git a/src/common/components/front-components/tooltip-shape.tsx b/src/common/components/front-components/tooltip-shape.tsx index ec45f162..96fb6ca0 100644 --- a/src/common/components/front-components/tooltip-shape.tsx +++ b/src/common/components/front-components/tooltip-shape.tsx @@ -1,10 +1,11 @@ import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; -import { forwardRef, useMemo } from 'react'; +import { forwardRef } from 'react'; import { ShapeProps } from './shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; import { Text, Group, Rect, Line } from 'react-konva'; import { BASIC_SHAPE } from './shape.const'; import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; +import { useShapeProps } from '../shapes/use-shape-props.hook'; const tooltipShapeRestrictions: ShapeSizeRestrictions = { minWidth: 80, @@ -39,28 +40,13 @@ export const TooltipShape = forwardRef((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(tooltipShapeRestrictions, width, height); - const stroke = useMemo( - () => otherProps?.stroke ?? BASIC_SHAPE.DEFAULT_STROKE_COLOR, - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? BASIC_SHAPE.DEFAULT_FILL_BACKGROUND, - [otherProps?.backgroundColor] - ); - - const textColor = useMemo( - () => otherProps?.textColor ?? BASIC_SHAPE.DEFAULT_FILL_TEXT, - [otherProps?.textColor] - ); + const { handleSelection } = useShapeComponentSelection(props, shapeType); - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] + const { stroke, strokeStyle, fill, textColor } = useShapeProps( + otherProps, + BASIC_SHAPE ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); - // Ajusta la posición del triángulo en función del alto del rectángulo const trianglePoints = [ tooltipWidth / 2 - pointerWidth / 20, // x1 From 729bc2746bf51fac142247b6d8d7013d6c05c6f6 Mon Sep 17 00:00:00 2001 From: Fran Lopez Date: Fri, 6 Sep 2024 20:25:24 +0200 Subject: [PATCH 09/50] add isOn and progress --- src/common/components/shapes/use-shape-props.hook.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/common/components/shapes/use-shape-props.hook.ts b/src/common/components/shapes/use-shape-props.hook.ts index 9d7d79cd..acb5f82e 100644 --- a/src/common/components/shapes/use-shape-props.hook.ts +++ b/src/common/components/shapes/use-shape-props.hook.ts @@ -32,11 +32,23 @@ export const useShapeProps = ( return isNaN(radius) ? defaultStyleShape.DEFAULT_CORNER_RADIUS : radius; }, [otherProps?.borderRadius]); + const isOn = useMemo( + () => otherProps?.checked ?? true, + [otherProps?.checked] + ); + + const progress = useMemo(() => { + const prog = otherProps?.progress ?? 50; + return typeof prog === 'string' ? parseFloat(prog) : prog; + }, [otherProps?.progress]); + return { stroke, fill, textColor, strokeStyle, borderRadius, + isOn, + progress, }; }; From f47056cd9bded12508a6c5bfcbccac9665d56e68 Mon Sep 17 00:00:00 2001 From: Braulio Date: Fri, 6 Sep 2024 22:10:34 +0200 Subject: [PATCH 10/50] adding analytics --- editor.html | 14 ++++++++++++++ index.html | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/editor.html b/editor.html index 4dccf22b..5a1cc85c 100644 --- a/editor.html +++ b/editor.html @@ -1,6 +1,20 @@ + + + Quickmock diff --git a/index.html b/index.html index 7687386b..f0017d26 100644 --- a/index.html +++ b/index.html @@ -1,6 +1,20 @@ + + + Quickmock From e9668e1c0861d9b0419edde57eac19edf0a63ec6 Mon Sep 17 00:00:00 2001 From: Fran Lopez Date: Sat, 7 Sep 2024 12:26:02 +0200 Subject: [PATCH 11/50] refactor all rich shapes --- .../front-rich-components/appBar.tsx | 28 ++++---------- .../breadcrumb/breadcrumb.tsx | 11 +++--- .../buttonBar/buttonBar.tsx | 28 +++++--------- .../horizontal-menu/horizontal-menu.tsx | 37 +++++-------------- .../front-rich-components/modal/modal.tsx | 34 +++++++---------- .../vertical-menu/vertical-menu.tsx | 33 +++-------------- 6 files changed, 50 insertions(+), 121 deletions(-) diff --git a/src/common/components/front-rich-components/appBar.tsx b/src/common/components/front-rich-components/appBar.tsx index 28c816e3..18896efb 100644 --- a/src/common/components/front-rich-components/appBar.tsx +++ b/src/common/components/front-rich-components/appBar.tsx @@ -1,10 +1,11 @@ -import { forwardRef, useMemo } from 'react'; +import { forwardRef } from 'react'; import { Group, Rect, Text } from 'react-konva'; import { ShapeProps } from '../front-components/shape.model'; import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; import { BASIC_SHAPE } from '../front-components/shape.const'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; +import { useShapeProps } from '../shapes/use-shape-props.hook'; const AppBarShapeSizeRestrictions: ShapeSizeRestrictions = { minWidth: 155, @@ -39,26 +40,6 @@ export const AppBarShape = forwardRef((props, ref) => { const iconWidth = 30; const iconPadding = 10; - const textColor = useMemo( - () => otherProps?.textColor ?? '#ffffff', - [otherProps?.textColor] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'lightgrey', - [otherProps?.backgroundColor] - ); - - const stroke = useMemo( - () => otherProps?.stroke ?? BASIC_SHAPE.DEFAULT_STROKE_COLOR, - [otherProps?.stroke] - ); - - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? BASIC_SHAPE.DEFAULT_STROKE_STYLE, - [otherProps?.strokeStyle] - ); - const padding = 10; const textStartX = iconPadding + iconWidth + padding; const textWidth = restrictedWidth - textStartX - padding; @@ -69,6 +50,11 @@ export const AppBarShape = forwardRef((props, ref) => { const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { stroke, strokeStyle, fill, textColor } = useShapeProps( + otherProps, + BASIC_SHAPE + ); + return ( ((props, ref) => { setGroupWidth(newGroupWidth); }, [sections]); - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { textColor } = useShapeProps(otherProps, BASIC_SHAPE); + return ( ( const itemWidth = numberOfItems > 0 ? restrictedWidth / numberOfItems : restrictedWidth; - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - const backgroundColor = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - const strokeColor = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] + const { stroke, strokeStyle, fill, textColor } = useShapeProps( + otherProps, + BASIC_SHAPE ); return ( @@ -75,10 +65,10 @@ export const ButtonBarShape = forwardRef( > {buttonItems.map((e: string, index: number) => ( @@ -86,7 +76,7 @@ export const ButtonBarShape = forwardRef( {/* Vertical strokes */} diff --git a/src/common/components/front-rich-components/horizontal-menu/horizontal-menu.tsx b/src/common/components/front-rich-components/horizontal-menu/horizontal-menu.tsx index 3eae1c0c..880fed45 100644 --- a/src/common/components/front-rich-components/horizontal-menu/horizontal-menu.tsx +++ b/src/common/components/front-rich-components/horizontal-menu/horizontal-menu.tsx @@ -1,11 +1,12 @@ import { Group, Rect, Text } from 'react-konva'; import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; -import { forwardRef, useEffect, useMemo, useState } from 'react'; +import { forwardRef, useEffect, useState } from 'react'; import { ShapeProps } from '../../front-components/shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; -import { INPUT_SHAPE } from '../../front-components/shape.const'; +import { BASIC_SHAPE } from '../../front-components/shape.const'; import { useShapeComponentSelection } from '../../shapes/use-shape-selection.hook'; import { mapHorizontalMenuTextToItems } from './hozontal-menu.business'; +import { useShapeProps } from '../../shapes/use-shape-props.hook'; const horizontalMenuShapeSizeRestrictions: ShapeSizeRestrictions = { minWidth: 75, @@ -61,33 +62,13 @@ export const HorizontalMenu = forwardRef((props, ref) => { const totalMargins = restrictedWidth - itemSpacing * (numberOfItems + 1); const itemWidth = totalMargins / numberOfItems; - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - - const backgroundColor = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - - const strokeColor = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); + const { handleSelection } = useShapeComponentSelection(props, shapeType); - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] + const { stroke, strokeStyle, fill, textColor, borderRadius } = useShapeProps( + otherProps, + BASIC_SHAPE ); - const borderRadius = useMemo(() => { - const radius = Number(otherProps?.borderRadius); - return isNaN(radius) ? INPUT_SHAPE.DEFAULT_CORNER_RADIUS : radius; - }, [otherProps?.borderRadius]); - - const { handleSelection } = useShapeComponentSelection(props, shapeType); - return ( ((props, ref) => { y={0} width={restrictedWidth} height={restrictedHeight} - stroke={strokeColor} + stroke={stroke} strokeWidth={2} dash={strokeStyle} - fill={backgroundColor} + fill={fill} cornerRadius={borderRadius} /> diff --git a/src/common/components/front-rich-components/modal/modal.tsx b/src/common/components/front-rich-components/modal/modal.tsx index 59447d3a..09037c47 100644 --- a/src/common/components/front-rich-components/modal/modal.tsx +++ b/src/common/components/front-rich-components/modal/modal.tsx @@ -1,10 +1,12 @@ import { Group, Rect, Text } from 'react-konva'; import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; -import { forwardRef, useMemo } from 'react'; +import { forwardRef } from 'react'; import { ShapeProps } from '../../front-components/shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; import { darkenColor, getModalPartsText } from './modal.utils'; import { useShapeComponentSelection } from '../../shapes/use-shape-selection.hook'; +import { useShapeProps } from '../../shapes/use-shape-props.hook'; +import { BASIC_SHAPE } from '../../front-components/shape.const'; const modalShapeSizeRestrictions: ShapeSizeRestrictions = { minWidth: 235, @@ -46,25 +48,15 @@ export const Modal = forwardRef((props, ref) => { const buttonWidth = (restrictedWidth - (buttons.length + 1) * buttonSpacing) / buttons.length; - const textColor = useMemo( - () => otherProps?.textColor ?? '000000', - [otherProps?.textColor] - ); - - const backgroundColor = useMemo( - () => otherProps?.backgroundColor ?? '#00FFFF', - [otherProps?.backgroundColor] - ); + const { handleSelection } = useShapeComponentSelection(props, shapeType); - const strokeColor = useMemo( - () => otherProps?.stroke ?? '000000', - [otherProps?.stroke] + const { stroke, strokeStyle, fill, textColor } = useShapeProps( + otherProps, + BASIC_SHAPE ); - const darkHeaderColor = darkenColor(backgroundColor, 40); - const darkButtonColor = darkenColor(backgroundColor, 60); - - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const darkHeaderColor = darkenColor(fill, 40); + const darkButtonColor = darkenColor(fill, 60); return ( ((props, ref) => { y={0} width={restrictedWidth} height={restrictedHeight} - fill={backgroundColor} - stroke={strokeColor} + fill={fill} + stroke={stroke} strokeWidth={2} + dash={strokeStyle} /> {/* Header */} @@ -94,8 +87,9 @@ export const Modal = forwardRef((props, ref) => { width={restrictedWidth} height={headerHeight} fill={darkHeaderColor} - stroke={strokeColor} + stroke={stroke} strokeWidth={2} + dash={strokeStyle} /> ( verticalMenuShapeSizeRestrictions, }); - const stroke = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - - const fill = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] - ); - - const borderRadius = useMemo(() => { - const radius = Number(otherProps?.borderRadius); - return isNaN(radius) ? INPUT_SHAPE.DEFAULT_CORNER_RADIUS : radius; - }, [otherProps?.borderRadius]); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { stroke, strokeStyle, fill, textColor, borderRadius } = + useShapeProps(otherProps, BASIC_SHAPE); + return ( Date: Sat, 7 Sep 2024 12:30:32 +0200 Subject: [PATCH 12/50] refactor all text shapes --- .../front-text-components/heading1-text-shape.tsx | 11 +++++------ .../front-text-components/heading2-text-shape.tsx | 11 +++++------ .../front-text-components/heading3-text-shape.tsx | 11 +++++------ .../front-text-components/normaltext-shape.tsx | 11 +++++------ .../front-text-components/paragraph-text-shape.tsx | 11 +++++------ .../front-text-components/smalltext-shape.tsx | 11 +++++------ 6 files changed, 30 insertions(+), 36 deletions(-) diff --git a/src/common/components/front-text-components/heading1-text-shape.tsx b/src/common/components/front-text-components/heading1-text-shape.tsx index 715e5a60..0e30024a 100644 --- a/src/common/components/front-text-components/heading1-text-shape.tsx +++ b/src/common/components/front-text-components/heading1-text-shape.tsx @@ -1,9 +1,11 @@ -import { forwardRef, useMemo } from 'react'; +import { forwardRef } from 'react'; import { Group, Text } from 'react-konva'; import { ShapeProps } from '../front-components/shape.model'; import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; +import { useShapeProps } from '../shapes/use-shape-props.hook'; +import { BASIC_SHAPE } from '../front-components/shape.const'; const heading1SizeRestrictions: ShapeSizeRestrictions = { minWidth: 150, @@ -34,13 +36,10 @@ export const Heading1Shape = forwardRef((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(heading1SizeRestrictions, width, height); - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { textColor } = useShapeProps(otherProps, BASIC_SHAPE); + return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(heading2SizeRestrictions, width, height); - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { textColor } = useShapeProps(otherProps, BASIC_SHAPE); + return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(heading3SizeRestrictions, width, height); - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { textColor } = useShapeProps(otherProps, BASIC_SHAPE); + return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(normaltextSizeRestrictions, width, height); - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { textColor } = useShapeProps(otherProps, BASIC_SHAPE); + return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(paragraphSizeRestrictions, width, height); - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { textColor } = useShapeProps(otherProps, BASIC_SHAPE); + return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(smalltextSizeRestrictions, width, height); - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - const { handleSelection } = useShapeComponentSelection(props, shapeType); + const { textColor } = useShapeProps(otherProps, BASIC_SHAPE); + return ( Date: Sat, 7 Sep 2024 13:20:07 +0200 Subject: [PATCH 13/50] fix horizontal bug --- .../buttonBar/buttonBar.tsx | 181 ++++++++++-------- 1 file changed, 96 insertions(+), 85 deletions(-) diff --git a/src/common/components/front-rich-components/buttonBar/buttonBar.tsx b/src/common/components/front-rich-components/buttonBar/buttonBar.tsx index 77503de7..ade694fd 100644 --- a/src/common/components/front-rich-components/buttonBar/buttonBar.tsx +++ b/src/common/components/front-rich-components/buttonBar/buttonBar.tsx @@ -1,9 +1,10 @@ -import { ShapeSizeRestrictions } from '@/core/model'; +import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; import { forwardRef, useEffect, useMemo, useState } from 'react'; import { Group, Path, Text } from 'react-konva'; import { ShapeProps } from '../../front-components/shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; import { mapButtonBarTextToItems } from './buttonBar.utils'; +import { useShapeComponentSelection } from '../../shapes/use-shape-selection.hook'; const horizontalMenuShapeSizeRestrictions: ShapeSizeRestrictions = { minWidth: 75, @@ -17,96 +18,106 @@ const horizontalMenuShapeSizeRestrictions: ShapeSizeRestrictions = { export const getButtonBarShapeSizeRestrictions = (): ShapeSizeRestrictions => horizontalMenuShapeSizeRestrictions; -export const ButtonBarShape = forwardRef( - ( - { x, y, width, height, id, onSelected, text, otherProps, ...shapeProps }, - ref - ) => { - const [buttonItems, setButtonItems] = useState([]); +const shapeType: ShapeType = 'buttonBar'; - useEffect(() => { - console.log('Hola'); - if (typeof text === 'string') { - const { items } = mapButtonBarTextToItems(text); - setButtonItems(items); - } else { - setButtonItems([]); - } - }, [text]); +export const ButtonBarShape = forwardRef((props, ref) => { + const { + x, + y, + width, + height, + id, + onSelected, + text, + otherProps, + ...shapeProps + } = props; + const [buttonItems, setButtonItems] = useState([]); - const numberOfItems = buttonItems.length; + useEffect(() => { + console.log('Hola'); + if (typeof text === 'string') { + const { items } = mapButtonBarTextToItems(text); + setButtonItems(items); + } else { + setButtonItems([]); + } + }, [text]); - const { width: restrictedWidth, height: restrictedHeight } = - fitSizeToShapeSizeRestrictions( - horizontalMenuShapeSizeRestrictions, - width, - height - ); + const numberOfItems = buttonItems.length; - const itemWidth = - numberOfItems > 0 ? restrictedWidth / numberOfItems : restrictedWidth; - - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - const backgroundColor = useMemo( - () => otherProps?.backgroundColor ?? 'white', - [otherProps?.backgroundColor] - ); - const strokeColor = useMemo( - () => otherProps?.stroke ?? 'black', - [otherProps?.stroke] - ); - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] + const { width: restrictedWidth, height: restrictedHeight } = + fitSizeToShapeSizeRestrictions( + horizontalMenuShapeSizeRestrictions, + width, + height ); - return ( - onSelected(id, 'buttonBar', true)} - > - + const itemWidth = + numberOfItems > 0 ? restrictedWidth / numberOfItems : restrictedWidth; - {buttonItems.map((e: string, index: number) => ( - - {/* Vertical strokes */} - - - - ))} - - ); - } -); + const textColor = useMemo( + () => otherProps?.textColor ?? 'black', + [otherProps?.textColor] + ); + const backgroundColor = useMemo( + () => otherProps?.backgroundColor ?? 'white', + [otherProps?.backgroundColor] + ); + const strokeColor = useMemo( + () => otherProps?.stroke ?? 'black', + [otherProps?.stroke] + ); + const strokeStyle = useMemo( + () => otherProps?.strokeStyle ?? [], + [otherProps?.strokeStyle] + ); + + const { handleSelection } = useShapeComponentSelection(props, shapeType); + + return ( + + + + {buttonItems.map((e: string, index: number) => ( + + {/* Vertical strokes */} + + + + ))} + + ); +}); export default ButtonBarShape; From 872bfef043ac8ab557b502325894f27ce3a8f3e1 Mon Sep 17 00:00:00 2001 From: Braulio Date: Sat, 7 Sep 2024 13:25:21 +0200 Subject: [PATCH 14/50] component list orders --- src/pods/component-gallery/component-gallery-data/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pods/component-gallery/component-gallery-data/index.ts b/src/pods/component-gallery/component-gallery-data/index.ts index c7c99257..ec5f7b14 100644 --- a/src/pods/component-gallery/component-gallery-data/index.ts +++ b/src/pods/component-gallery/component-gallery-data/index.ts @@ -7,16 +7,16 @@ export const mockWidgetCollection: ItemInfo[] = [ { thumbnailSrc: '/widgets/button.svg', type: 'button' }, { thumbnailSrc: '/widgets/textarea.svg', type: 'textarea' }, { thumbnailSrc: '/widgets/combobox.svg', type: 'combobox' }, + { thumbnailSrc: '/widgets/radiobutton.svg', type: 'radiobutton' }, { thumbnailSrc: '/widgets/checkbox.svg', type: 'checkbox' }, { thumbnailSrc: '/widgets/toggleswitch.svg', type: 'toggleswitch' }, { thumbnailSrc: '/widgets/progressbar.svg', type: 'progressbar' }, { thumbnailSrc: '/widgets/listbox.svg', type: 'listbox' }, + { thumbnailSrc: '/widgets/slider.svg', type: 'slider' }, { thumbnailSrc: '/widgets/datepicker.svg', type: 'datepickerinput' }, { thumbnailSrc: '/widgets/timepicker.svg', type: 'timepickerinput' }, - { thumbnailSrc: '/widgets/radiobutton.svg', type: 'radiobutton' }, - { thumbnailSrc: '/widgets/verticalscrollbar.svg', type: 'verticalScrollBar' }, { thumbnailSrc: '/widgets/tooltip.svg', type: 'tooltip' }, - { thumbnailSrc: '/widgets/slider.svg', type: 'slider' }, + { thumbnailSrc: '/widgets/verticalscrollbar.svg', type: 'verticalScrollBar' }, { thumbnailSrc: '/widgets/horizontalscrollbar.svg', type: 'horizontalScrollBar', From ed68acbe5bd433577e874df4a195cc5cab2f7431 Mon Sep 17 00:00:00 2001 From: Braulio Date: Sat, 7 Sep 2024 13:26:31 +0200 Subject: [PATCH 15/50] reorder basic --- src/pods/basic-shapes-gallery/basic-gallery-data/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pods/basic-shapes-gallery/basic-gallery-data/index.ts b/src/pods/basic-shapes-gallery/basic-gallery-data/index.ts index da252dba..05a2e866 100644 --- a/src/pods/basic-shapes-gallery/basic-gallery-data/index.ts +++ b/src/pods/basic-shapes-gallery/basic-gallery-data/index.ts @@ -1,13 +1,13 @@ import { ItemInfo } from '@/common/components/gallery/components/model'; export const mockBasicShapesCollection: ItemInfo[] = [ - { thumbnailSrc: '/shapes/rectangle.svg', type: 'rectangle' }, { thumbnailSrc: '/shapes/postit.svg', type: 'postit' }, - { thumbnailSrc: '/shapes/diamond.svg', type: 'diamond' }, - { thumbnailSrc: '/shapes/line.svg', type: 'line' }, + { thumbnailSrc: '/shapes/image.svg', type: 'image' }, + { thumbnailSrc: '/shapes/rectangle.svg', type: 'rectangle' }, { thumbnailSrc: '/shapes/triangle.svg', type: 'triangle' }, { thumbnailSrc: '/shapes/circle.svg', type: 'circle' }, + { thumbnailSrc: '/shapes/diamond.svg', type: 'diamond' }, { thumbnailSrc: '/shapes/star.svg', type: 'star' }, + { thumbnailSrc: '/shapes/line.svg', type: 'line' }, { thumbnailSrc: '/shapes/largeArrow.svg', type: 'largeArrow' }, - { thumbnailSrc: '/shapes/image.svg', type: 'image' }, ]; From 0d9259564cf920e3880c1994d764d53573436e6e Mon Sep 17 00:00:00 2001 From: Braulio Date: Sat, 7 Sep 2024 13:28:52 +0200 Subject: [PATCH 16/50] rich order reorganized --- .../rich-components-gallery-data/index.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/pods/rich-components-gallery/rich-components-gallery-data/index.ts b/src/pods/rich-components-gallery/rich-components-gallery-data/index.ts index 7239c2a1..ca8bfa0b 100644 --- a/src/pods/rich-components-gallery/rich-components-gallery-data/index.ts +++ b/src/pods/rich-components-gallery/rich-components-gallery-data/index.ts @@ -1,25 +1,25 @@ import { ItemInfo } from '@/common/components/gallery/components/model'; export const mockRichComponentsCollection: ItemInfo[] = [ - { thumbnailSrc: '/rich-components/videoPlayer.svg', type: 'videoPlayer' }, + { thumbnailSrc: '/rich-components/table.svg', type: 'table' }, { thumbnailSrc: '/rich-components/accordion.svg', type: 'accordion' }, - { thumbnailSrc: '/rich-components/pie.svg', type: 'pie' }, { thumbnailSrc: '/rich-components/horizontal-menu.svg', type: 'horizontal-menu', }, + { thumbnailSrc: '/rich-components/button-bar-group.svg', type: 'buttonBar' }, { thumbnailSrc: '/rich-components/vertical-menu.svg', type: 'vertical-menu', }, + { thumbnailSrc: '/rich-components/appBar.svg', type: 'appBar' }, { thumbnailSrc: '/rich-components/breadcrumb.svg', type: 'breadcrumb' }, - { thumbnailSrc: '/rich-components/map.svg', type: 'map' }, - { thumbnailSrc: '/rich-components/barchart.svg', type: 'bar' }, - { thumbnailSrc: '/rich-components/line-chart.svg', type: 'linechart' }, - { thumbnailSrc: '/rich-components/calendar.svg', type: 'calendar' }, - { thumbnailSrc: '/rich-components/table.svg', type: 'table' }, { thumbnailSrc: '/rich-components/modal.svg', type: 'modal' }, - { thumbnailSrc: '/rich-components/appBar.svg', type: 'appBar' }, - { thumbnailSrc: '/rich-components/button-bar-group.svg', type: 'buttonBar' }, { thumbnailSrc: '/rich-components/tabsbar.svg', type: 'tabsBar' }, + { thumbnailSrc: '/rich-components/calendar.svg', type: 'calendar' }, + { thumbnailSrc: '/rich-components/videoPlayer.svg', type: 'videoPlayer' }, + { thumbnailSrc: '/rich-components/pie.svg', type: 'pie' }, + { thumbnailSrc: '/rich-components/line-chart.svg', type: 'linechart' }, + { thumbnailSrc: '/rich-components/barchart.svg', type: 'bar' }, + { thumbnailSrc: '/rich-components/map.svg', type: 'map' }, ]; From d1551cb9a9c314a3c23f8cf163dfe57956ed2d14 Mon Sep 17 00:00:00 2001 From: Braulio Date: Sat, 7 Sep 2024 13:38:28 +0200 Subject: [PATCH 17/50] reorder --- src/scenes/main.scene.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/scenes/main.scene.tsx b/src/scenes/main.scene.tsx index e5b3a55a..086b26f9 100644 --- a/src/scenes/main.scene.tsx +++ b/src/scenes/main.scene.tsx @@ -26,14 +26,14 @@ export const MainScene = () => { Components -
- Basic Shapes - -
Rich Components
+
+ Basic Shapes + +
Text Components From 0679d846f8a20ef43fd243ec538834613bed00c2 Mon Sep 17 00:00:00 2001 From: Braulio Date: Sat, 7 Sep 2024 13:48:56 +0200 Subject: [PATCH 18/50] button bar input inline edit --- src/pods/canvas/canvas.model.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pods/canvas/canvas.model.ts b/src/pods/canvas/canvas.model.ts index 4ee404d7..3c652813 100644 --- a/src/pods/canvas/canvas.model.ts +++ b/src/pods/canvas/canvas.model.ts @@ -361,7 +361,6 @@ const getShapeEditInlineType = (shapeType: ShapeType): EditType | undefined => { case 'table': case 'modal': case 'appBar': - case 'buttonBar': case 'tabsBar': case 'tooltip': return 'textarea'; From 9f279049ea33c0dd880af1e35d13e6417df96337 Mon Sep 17 00:00:00 2001 From: Fran Lopez Date: Sat, 7 Sep 2024 14:19:34 +0200 Subject: [PATCH 19/50] fix vite warning: The "??" operator here will always return the left operand --- src/pods/canvas/use-keyboard-displacement.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pods/canvas/use-keyboard-displacement.tsx b/src/pods/canvas/use-keyboard-displacement.tsx index c1be222f..70bdcbd9 100644 --- a/src/pods/canvas/use-keyboard-displacement.tsx +++ b/src/pods/canvas/use-keyboard-displacement.tsx @@ -41,7 +41,7 @@ export const useKeyboardDisplacement = () => { // then we return and let the input and textare control it const isInlineEditing = (event.target as any)?.attributes['data-is-inline-edition-on'] !== - undefined ?? false; + undefined; if (isInlineEditing || !isKeyboardKey(event.key)) { return; } From 15e7bc61261063365c27f098a35c20f0bbbe5810 Mon Sep 17 00:00:00 2001 From: Braulio Date: Sat, 7 Sep 2024 21:13:36 +0200 Subject: [PATCH 20/50] first update --- README.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c7d27f5d..e6d3e3af 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,29 @@ -# Quick mock 🎨 +# Quick mock + +![Contributors](https://img.shields.io/github/contributors/Lemoncode/mongo-modeler) +![Forks](https://img.shields.io/github/forks/Lemoncode/mongo-modeler) +![Stars](https://img.shields.io/github/stars/Lemoncode/mongo-modeler) +![Licence](https://img.shields.io/github/license/Lemoncode/mongo-modeler) +![Issues](https://img.shields.io/github/issues/Lemoncode/mongo-modeler) + +## Project + +Quick Mock is a free, open source online tool for quickly creating low fidelity UI mockups. + +You can take a look at the desktop community preview at [Quick Mock](https://www.quickmock.net/) + +Click to watch the video tutorial: + +TODO: replace with the final video tutorial once uploaded to YouTube +[![Quick mock video tutorial](https://img.youtube.com/vi/87ZZbDZLido/0.jpg)](https://www.youtube.com/watch?v=87ZZbDZLido) + +## 🚀 Installation + +To install the project, clone the repository and run the following commands: + +```sh +git clone https://github.com/Lemoncode/quickmock.git +``` **Work in progres... 🚧 ** @@ -6,10 +31,6 @@ The goal of this project is to create an open source low fidelity UI mock tool ![quickmock](https://github.com/user-attachments/assets/a26e7302-0847-4377-80f0-39098791b371) -# 🚀 Installation - -Clone this repository and run the following commands: - Install dependencies ```bash @@ -24,9 +45,49 @@ npm run dev Open your browser and go to http://localhost:5173 (if this port is busy it will be changed to the next available port) +## Contributing + +Your feedback and contributions are welcome! If you have ideas for new features or have found a bug, we would love to hear about it. Here's how you can contribute: + +Report a Bug 🐛 + +If you encounter a bug in the project, please first check if it has already been reported in our GitHub Issues. If you don't find it there, feel free to open a new issue. Provide as many details as possible, including steps to reproduce the bug, the environment in which it occurs (operating system, project version, etc.), and any other relevant details. + +Propose a New Feature ✨ + +Do you have an idea to improve the project? Great! Share your thoughts with us by opening a new GitHub Issue under the feature request label. Describe the feature you would like to see, how and why you think it would be a valuable addition to the project. + +## Technologies + +The application is being developed using the following technologies: + +- [React](https://react.dev/) +- [React Konva](https://konvajs.org/) +- [TypeScript](https://www.typescriptlang.org/) +- [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) / [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS) / [SVG](https://developer.mozilla.org/en-US/docs/Web/SVG) +- [Vite](https://vitejs.dev/) +- [Vitest](https://vitest.dev/) + +## Sponsor Quick Mock + +Are you or your company interested in supporting Quick Mock? Sponsorship is a powerful way to contribute to the development and maintenance of our project, and we're always looking for partners who share our vision. + +Why Sponsor Quick Mock? + +- **Support Open Source:** Your sponsorship directly contributes to the open-source community, enabling us to maintain and improve our project. + +- **Visibility for Your Brand:** Sponsoring Quick Mock can provide visibility for your brand in the tech community. It's an excellent way to demonstrate your commitment to supporting innovative software development. + +- **Direct Impact:** Your support makes a tangible difference, allowing us to focus more on development, add new features, and improve the user experience. + +If you're interested in sponsoring this project, please feel free to reach out to us at: info@lemoncode.net + +Thank you for supporting open-source development! + + ## 👥 Team -Contributors to this project +Team members participating in this project

From e99dfdea22d7d71db51302729ab40fb84a403dc4 Mon Sep 17 00:00:00 2001 From: Braulio Date: Sat, 7 Sep 2024 21:16:31 +0200 Subject: [PATCH 21/50] updated badges --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e6d3e3af..03fea58e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # Quick mock -![Contributors](https://img.shields.io/github/contributors/Lemoncode/mongo-modeler) -![Forks](https://img.shields.io/github/forks/Lemoncode/mongo-modeler) -![Stars](https://img.shields.io/github/stars/Lemoncode/mongo-modeler) -![Licence](https://img.shields.io/github/license/Lemoncode/mongo-modeler) -![Issues](https://img.shields.io/github/issues/Lemoncode/mongo-modeler) +![Contributors](https://img.shields.io/github/contributors/Lemoncode/quickmock) +![Forks](https://img.shields.io/github/forks/Lemoncode/quickmock) +![Stars](https://img.shields.io/github/stars/Lemoncode/quickmock) +![Licence](https://img.shields.io/github/license/Lemoncode/quickmock) +![Issues](https://img.shields.io/github/issues/Lemoncode/quickmock) ## Project From b793e9bcbab004e57a925841875f671f79191f18 Mon Sep 17 00:00:00 2001 From: Braulio Date: Sat, 7 Sep 2024 21:18:17 +0200 Subject: [PATCH 22/50] updated license --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..84b4929b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Lemoncode + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file From 03719c24a33036cfdf6eaa081146adb55a122199 Mon Sep 17 00:00:00 2001 From: Braulio Diez Date: Sat, 7 Sep 2024 21:19:03 +0200 Subject: [PATCH 23/50] Update LICENSE --- LICENSE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index 84b4929b..580346f6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Lemoncode +Copyright (c) 2024 Lemoncode Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. From f71f8b579cad5a6ea4d9267cd967abafbf7a0669 Mon Sep 17 00:00:00 2001 From: Braulio Date: Sat, 7 Sep 2024 21:20:09 +0200 Subject: [PATCH 24/50] updated --- README.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 03fea58e..19bc312d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ ## Project -Quick Mock is a free, open source online tool for quickly creating low fidelity UI mockups. +Quick Mock is a free, open source online tool for quickly creating low fidelity UI mockups. You can take a look at the desktop community preview at [Quick Mock](https://www.quickmock.net/) @@ -25,13 +25,7 @@ To install the project, clone the repository and run the following commands: git clone https://github.com/Lemoncode/quickmock.git ``` -**Work in progres... 🚧 ** - -The goal of this project is to create an open source low fidelity UI mock tool - -![quickmock](https://github.com/user-attachments/assets/a26e7302-0847-4377-80f0-39098791b371) - -Install dependencies +Install the dependencies ```bash npm install @@ -84,7 +78,6 @@ If you're interested in sponsoring this project, please feel free to reach out t Thank you for supporting open-source development! - ## 👥 Team Team members participating in this project From 59300e060b3d282db0551c4c65f3d870485f5bda Mon Sep 17 00:00:00 2001 From: Braulio Date: Sat, 7 Sep 2024 21:20:49 +0200 Subject: [PATCH 25/50] adding bold --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 19bc312d..21509746 100644 --- a/README.md +++ b/README.md @@ -43,11 +43,11 @@ Open your browser and go to http://localhost:5173 (if this port is busy it will Your feedback and contributions are welcome! If you have ideas for new features or have found a bug, we would love to hear about it. Here's how you can contribute: -Report a Bug 🐛 +**Report a Bug 🐛** If you encounter a bug in the project, please first check if it has already been reported in our GitHub Issues. If you don't find it there, feel free to open a new issue. Provide as many details as possible, including steps to reproduce the bug, the environment in which it occurs (operating system, project version, etc.), and any other relevant details. -Propose a New Feature ✨ +**Propose a New Feature ✨** Do you have an idea to improve the project? Great! Share your thoughts with us by opening a new GitHub Issue under the feature request label. Describe the feature you would like to see, how and why you think it would be a valuable addition to the project. From 1d6899a60ea05fd16b7e2ea562289d6978dd2954 Mon Sep 17 00:00:00 2001 From: Braulio Date: Sat, 7 Sep 2024 21:28:27 +0200 Subject: [PATCH 26/50] tailor made --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 21509746..cad53fde 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,12 @@ If you're interested in sponsoring this project, please feel free to reach out t Thank you for supporting open-source development! +## 📐 Custom Component Libraries for Enterprise + +If your organization has its own design system and component library, we can create a custom set of low-fidelity mock components tailored to your palette and guidelines. This allows your team to create wireframes that align perfectly with your branding and design standards. + +For more information and to request a quote, feel free to contact us at: info@lemoncode.net. + ## 👥 Team Team members participating in this project From 94b146ed79b98636b107450f81c21f19d61d94e9 Mon Sep 17 00:00:00 2001 From: Braulio Date: Sat, 7 Sep 2024 21:36:00 +0200 Subject: [PATCH 27/50] adding emoticons --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cad53fde..051089d3 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ![Licence](https://img.shields.io/github/license/Lemoncode/quickmock) ![Issues](https://img.shields.io/github/issues/Lemoncode/quickmock) -## Project +## 🌟 Project Quick Mock is a free, open source online tool for quickly creating low fidelity UI mockups. @@ -39,7 +39,7 @@ npm run dev Open your browser and go to http://localhost:5173 (if this port is busy it will be changed to the next available port) -## Contributing +## 🤝 Contributing Your feedback and contributions are welcome! If you have ideas for new features or have found a bug, we would love to hear about it. Here's how you can contribute: @@ -51,7 +51,7 @@ If you encounter a bug in the project, please first check if it has already been Do you have an idea to improve the project? Great! Share your thoughts with us by opening a new GitHub Issue under the feature request label. Describe the feature you would like to see, how and why you think it would be a valuable addition to the project. -## Technologies +## 🛠️ Technologies The application is being developed using the following technologies: @@ -62,7 +62,7 @@ The application is being developed using the following technologies: - [Vite](https://vitejs.dev/) - [Vitest](https://vitest.dev/) -## Sponsor Quick Mock +## 💖 Sponsor Quick Mock Are you or your company interested in supporting Quick Mock? Sponsorship is a powerful way to contribute to the development and maintenance of our project, and we're always looking for partners who share our vision. From 530d1b0e6f629df614c9c52221bdc5600ac0d6ab Mon Sep 17 00:00:00 2001 From: Braulio Diez Date: Sat, 7 Sep 2024 21:38:24 +0200 Subject: [PATCH 28/50] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..580346f6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Lemoncode + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From ca16218936c4068bbc31eecf800447f3c0d375f4 Mon Sep 17 00:00:00 2001 From: Braulio Date: Mon, 9 Sep 2024 17:23:56 +0200 Subject: [PATCH 29/50] fonts uncommented --- src/main.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index 2c531376..63f0a6b4 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,12 +1,9 @@ import ReactDOM from 'react-dom/client'; import App from './App.tsx'; -// TODO: -// This blow away the application :) -// I think it's missing to uplaod some font or something? -//import '@fontsource/balsamiq-sans/400.css'; -//import '@fontsource/balsamiq-sans/700.css'; -//import '@fontsource/balsamiq-sans/400-italic.css'; -//import '@fontsource/balsamiq-sans/700-italic.css'; +import '@fontsource/balsamiq-sans/400.css'; +import '@fontsource/balsamiq-sans/700.css'; +import '@fontsource/balsamiq-sans/400-italic.css'; +import '@fontsource/balsamiq-sans/700-italic.css'; import './normalize.css'; import './reset.css'; import './main.css'; From f7ffb9affa059a09bfbe8074c65b33742a20f8c1 Mon Sep 17 00:00:00 2001 From: LeticiadelaOsa Date: Thu, 5 Sep 2024 18:38:24 +0200 Subject: [PATCH 30/50] changed image button colors --- .../components/image-upload.widget.module.css | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/common/components/inline-edit/components/image-upload.widget.module.css b/src/common/components/inline-edit/components/image-upload.widget.module.css index b6690b5f..a9900191 100644 --- a/src/common/components/inline-edit/components/image-upload.widget.module.css +++ b/src/common/components/inline-edit/components/image-upload.widget.module.css @@ -15,19 +15,23 @@ } .uploadButton { - background-color: #4caf50; /* Verde */ + background-color: #2d9a8b; border: none; color: white; - padding: 15px 32px; + padding: 12px var(--space-lg); text-align: center; - text-decoration: none; - display: inline-block; - font-size: 16px; + display: block; + font-size: var(--fs-s); cursor: pointer; - border-radius: 8px; - transition: background-color 0.3s ease; + border-radius: var(--border-radius-m); + box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); + transition: all 0.3s ease; } .uploadButton:hover { - background-color: #45a049; /* Verde más oscuro cuando se pasa el ratón por encima */ + background-color: #257f72; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); +} +.uploadButton:active { + background-color: #1d6359; } From 3d243b9f4f5904934eee58ce6823ed181daa0596 Mon Sep 17 00:00:00 2001 From: LeticiadelaOsa Date: Mon, 9 Sep 2024 22:22:35 +0200 Subject: [PATCH 31/50] Updated checkbox styles --- public/widgets/checkbox.svg | 12 +++--- .../front-components/checkbox-shape.tsx | 43 +++++++++++-------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/public/widgets/checkbox.svg b/public/widgets/checkbox.svg index 15db3501..d17ed3d7 100644 --- a/public/widgets/checkbox.svg +++ b/public/widgets/checkbox.svg @@ -1,14 +1,14 @@ - + - + - + - + Check me! \ No newline at end of file diff --git a/src/common/components/front-components/checkbox-shape.tsx b/src/common/components/front-components/checkbox-shape.tsx index a51a3804..58e2d6fe 100644 --- a/src/common/components/front-components/checkbox-shape.tsx +++ b/src/common/components/front-components/checkbox-shape.tsx @@ -7,13 +7,15 @@ import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; import { useShapeProps } from '../shapes/use-shape-props.hook'; import { BASIC_SHAPE } from './shape.const'; +const CHECKBOX_DEFAULT_HEIGHT = 20; + const checkBoxShapeRestrictions: ShapeSizeRestrictions = { minWidth: 100, - minHeight: 30, + minHeight: CHECKBOX_DEFAULT_HEIGHT, maxWidth: -1, - maxHeight: 50, - defaultWidth: 200, - defaultHeight: 50, + maxHeight: CHECKBOX_DEFAULT_HEIGHT, + defaultWidth: BASIC_SHAPE.DEFAULT_TEXT_WIDTH, + defaultHeight: CHECKBOX_DEFAULT_HEIGHT, }; const shapeType: ShapeType = 'checkbox'; @@ -22,8 +24,9 @@ export const getCheckboxShapeSizeRestrictions = (): ShapeSizeRestrictions => checkBoxShapeRestrictions; const marginTick = 5; -const boxTickWidth = 50; -const tickWidth = boxTickWidth - marginTick; +const boxTickWidth = CHECKBOX_DEFAULT_HEIGHT; +const tickWidth = boxTickWidth; +const marginText = 3; export const CheckBoxShape = forwardRef((props, ref) => { const { @@ -59,35 +62,37 @@ export const CheckBoxShape = forwardRef((props, ref) => { y={0} width={boxTickWidth} height={restrictedHeight} - cornerRadius={5} - stroke="black" - strokeWidth={2} + cornerRadius={BASIC_SHAPE.DEFAULT_CORNER_RADIUS} + stroke={BASIC_SHAPE.DEFAULT_STROKE_COLOR} + strokeWidth={BASIC_SHAPE.DEFAULT_STROKE_WIDTH} fill="white" /> {isOn && ( )} Date: Tue, 10 Sep 2024 13:23:33 +0200 Subject: [PATCH 32/50] Updated radio button styles --- public/widgets/radiobutton.svg | 8 ++--- .../front-components/radiobutton-shape.tsx | 31 ++++++++++++------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/public/widgets/radiobutton.svg b/public/widgets/radiobutton.svg index 72fe299a..06e69b34 100644 --- a/public/widgets/radiobutton.svg +++ b/public/widgets/radiobutton.svg @@ -1,12 +1,12 @@ - + - + - + - + Select me! \ No newline at end of file diff --git a/src/common/components/front-components/radiobutton-shape.tsx b/src/common/components/front-components/radiobutton-shape.tsx index f2681d55..42d93ed1 100644 --- a/src/common/components/front-components/radiobutton-shape.tsx +++ b/src/common/components/front-components/radiobutton-shape.tsx @@ -7,13 +7,15 @@ import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; import { useShapeProps } from '../shapes/use-shape-props.hook'; import { BASIC_SHAPE } from './shape.const'; +const RADIO_BUTTON_DEFAULT_HEIGHT = 18; + const radioButtonShapeRestrictions: ShapeSizeRestrictions = { minWidth: 50, - minHeight: 30, - maxWidth: 200, - maxHeight: 50, - defaultWidth: 120, - defaultHeight: 50, + minHeight: RADIO_BUTTON_DEFAULT_HEIGHT, + maxWidth: -1, + maxHeight: RADIO_BUTTON_DEFAULT_HEIGHT, + defaultWidth: BASIC_SHAPE.DEFAULT_TEXT_WIDTH, + defaultHeight: RADIO_BUTTON_DEFAULT_HEIGHT, }; export const getRadioButtonShapeSizeRestrictions = (): ShapeSizeRestrictions => @@ -57,27 +59,32 @@ export const RadioButtonShape = forwardRef((props, ref) => { x={radius} y={radius} radius={radius} - stroke="black" - strokeWidth={2} + stroke={BASIC_SHAPE.DEFAULT_STROKE_COLOR} + strokeWidth={BASIC_SHAPE.DEFAULT_STROKE_WIDTH} /> {/* Círculo interior del radio button (checked) */} {/* Texto */} ); From 0bc69ec1f12e6e17d2ddd75b6f6ec1389c44b668 Mon Sep 17 00:00:00 2001 From: Leticia de la Osa Date: Tue, 10 Sep 2024 16:36:22 +0200 Subject: [PATCH 33/50] updated combobox styles --- public/widgets/combobox.svg | 9 +-- .../front-components/combobox-shape.tsx | 79 ++++++++----------- .../front-components/shape.const.ts | 2 +- 3 files changed, 38 insertions(+), 52 deletions(-) diff --git a/public/widgets/combobox.svg b/public/widgets/combobox.svg index 55c29099..91008d70 100644 --- a/public/widgets/combobox.svg +++ b/public/widgets/combobox.svg @@ -1,7 +1,6 @@ - - - - - Select an option + + + + Select an option \ No newline at end of file diff --git a/src/common/components/front-components/combobox-shape.tsx b/src/common/components/front-components/combobox-shape.tsx index c5bc8cda..37f41311 100644 --- a/src/common/components/front-components/combobox-shape.tsx +++ b/src/common/components/front-components/combobox-shape.tsx @@ -2,18 +2,18 @@ import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; import { forwardRef } from 'react'; import { ShapeProps } from './shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; -import { Path, Group, Text } from 'react-konva'; +import { Group, Text, Rect, Line } from 'react-konva'; import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; import { useShapeProps } from '../shapes/use-shape-props.hook'; import { BASIC_SHAPE } from './shape.const'; const comboBoxShapeRestrictions: ShapeSizeRestrictions = { minWidth: 100, - minHeight: 50, + minHeight: BASIC_SHAPE.DEFAULT_TEXT_HEIGHT, maxWidth: -1, - maxHeight: 50, - defaultWidth: 220, - defaultHeight: 50, + maxHeight: BASIC_SHAPE.DEFAULT_TEXT_HEIGHT, + defaultWidth: BASIC_SHAPE.DEFAULT_TEXT_WIDTH, + defaultHeight: BASIC_SHAPE.DEFAULT_TEXT_HEIGHT, }; const shapeType: ShapeType = 'combobox'; @@ -38,19 +38,6 @@ export const ComboBoxShape = forwardRef((props, ref) => { const { handleSelection } = useShapeComponentSelection(props, shapeType); - const createPathWithRoundedCorners = (w: number, h: number, r: number) => { - return `M${r},0 - H${w - r} - Q${w},0 ${w},${r} - V${h - r} - Q${w},${h} ${w - r},${h} - H${r} - Q0,${h} 0,${h - r} - V${r} - Q0,0 ${r},0 - Z`; - }; - const { stroke, strokeStyle, fill, textColor, borderRadius } = useShapeProps( otherProps, BASIC_SHAPE @@ -66,44 +53,44 @@ export const ComboBoxShape = forwardRef((props, ref) => { {...shapeProps} onClick={handleSelection} > - {/* Rectangle with rounded corners */} - - {/* Polygon (Arrow), combo triangle dropdown */} - - {/* Combo arrow vertical line separator */} - + ); }); diff --git a/src/common/components/front-components/shape.const.ts b/src/common/components/front-components/shape.const.ts index 43d177da..de5e36ce 100644 --- a/src/common/components/front-components/shape.const.ts +++ b/src/common/components/front-components/shape.const.ts @@ -10,7 +10,7 @@ const DEFAULT_PADDING = 10; const DEFAULT_LINE_HEIGHT = 1.25; const DEFAULT_FILL_TEXT_INPUT = '#8c8c8c'; const DEFAULT_FONT_SIZE_INPUT = 15; -const DEFAULT_TEXT_WIDTH = 155; +const DEFAULT_TEXT_WIDTH = 165; const DEFAULT_TEXT_HEIGHT = 38; export interface DefaultStyleShape { From cd5cc0b1eb6d255297c8f078d1501bba0dc44b7a Mon Sep 17 00:00:00 2001 From: nasdan Date: Tue, 10 Sep 2024 18:09:21 +0200 Subject: [PATCH 34/50] ci: add Azure Static Web Apps workflow file on-behalf-of: @Azure opensource@microsoft.com --- ...e-static-web-apps-ashy-field-0dcd26f03.yml | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/azure-static-web-apps-ashy-field-0dcd26f03.yml diff --git a/.github/workflows/azure-static-web-apps-ashy-field-0dcd26f03.yml b/.github/workflows/azure-static-web-apps-ashy-field-0dcd26f03.yml new file mode 100644 index 00000000..f2c3fc9b --- /dev/null +++ b/.github/workflows/azure-static-web-apps-ashy-field-0dcd26f03.yml @@ -0,0 +1,46 @@ +name: Azure Static Web Apps CI/CD + +on: + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened, closed] + branches: + - main + +jobs: + build_and_deploy_job: + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') + runs-on: ubuntu-latest + name: Build and Deploy Job + steps: + - uses: actions/checkout@v3 + with: + submodules: true + lfs: false + - name: Build And Deploy + id: builddeploy + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_FIELD_0DCD26F03 }} + repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) + action: "upload" + ###### Repository/Build Configurations - These values can be configured to match your app requirements. ###### + # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig + app_location: "/" # App source code path + api_location: "" # Api source code path - optional + output_location: "build" # Built app content directory - optional + ###### End of Repository/Build Configurations ###### + + close_pull_request_job: + if: github.event_name == 'pull_request' && github.event.action == 'closed' + runs-on: ubuntu-latest + name: Close Pull Request Job + steps: + - name: Close Pull Request + id: closepullrequest + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_FIELD_0DCD26F03 }} + action: "close" From 32fd5b98a98a2ea6a1b38887ccbced763a361555 Mon Sep 17 00:00:00 2001 From: "daniel.sanchez" Date: Tue, 10 Sep 2024 18:24:34 +0200 Subject: [PATCH 35/50] update cd github workflow --- ...e-static-web-apps-ashy-field-0dcd26f03.yml | 46 ------------------- .github/workflows/cd.yml | 35 ++++++++++++++ 2 files changed, 35 insertions(+), 46 deletions(-) delete mode 100644 .github/workflows/azure-static-web-apps-ashy-field-0dcd26f03.yml create mode 100644 .github/workflows/cd.yml diff --git a/.github/workflows/azure-static-web-apps-ashy-field-0dcd26f03.yml b/.github/workflows/azure-static-web-apps-ashy-field-0dcd26f03.yml deleted file mode 100644 index f2c3fc9b..00000000 --- a/.github/workflows/azure-static-web-apps-ashy-field-0dcd26f03.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Azure Static Web Apps CI/CD - -on: - push: - branches: - - main - pull_request: - types: [opened, synchronize, reopened, closed] - branches: - - main - -jobs: - build_and_deploy_job: - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') - runs-on: ubuntu-latest - name: Build and Deploy Job - steps: - - uses: actions/checkout@v3 - with: - submodules: true - lfs: false - - name: Build And Deploy - id: builddeploy - uses: Azure/static-web-apps-deploy@v1 - with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_FIELD_0DCD26F03 }} - repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) - action: "upload" - ###### Repository/Build Configurations - These values can be configured to match your app requirements. ###### - # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig - app_location: "/" # App source code path - api_location: "" # Api source code path - optional - output_location: "build" # Built app content directory - optional - ###### End of Repository/Build Configurations ###### - - close_pull_request_job: - if: github.event_name == 'pull_request' && github.event.action == 'closed' - runs-on: ubuntu-latest - name: Close Pull Request Job - steps: - - name: Close Pull Request - id: closepullrequest - uses: Azure/static-web-apps-deploy@v1 - with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_FIELD_0DCD26F03 }} - action: "close" diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 00000000..44077597 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,35 @@ +name: CD Workflow + +on: + push: + branches: + - main + +jobs: + cd: + environment: + name: Production + url: https://quickmock.net + runs-on: ubuntu-latest + name: Deploy Quickmock + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install + run: npm ci + + - name: Build + run: npm run build + + - name: Deploy + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_FIELD_0DCD26F03 }} + repo_token: ${{ secrets.GITHUB_TOKEN }} + action: "upload" + app_location: "/dist" + skip_app_build: true + skip_api_build: true + env: + NODE_VERSION: 20.17.0 From 2145896d3fa4b2c08afe29bcc7a8be381a2e2ec2 Mon Sep 17 00:00:00 2001 From: Braulio Date: Tue, 10 Sep 2024 18:27:44 +0200 Subject: [PATCH 36/50] change url --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index f0017d26..2925b419 100644 --- a/index.html +++ b/index.html @@ -336,7 +336,7 @@

-
START DESIGN + START DESIGN

Now, only available on desktop.

From 5798ca0189810c96da303bd2ee6f7798809f7790 Mon Sep 17 00:00:00 2001 From: "daniel.sanchez" Date: Tue, 10 Sep 2024 18:31:35 +0200 Subject: [PATCH 37/50] update vite config --- vite.config.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vite.config.ts b/vite.config.ts index e2df0a8e..c71f18f2 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -15,6 +15,14 @@ const vitestConfig: VitestUserConfigInterface = { // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], + build: { + rollupOptions: { + input: { + main: './index.html', + editor: './editor.html', + }, + }, + }, test: { globals: true, environment: 'jsdom', From c9d9dc5e3422749f2ccf46093438aea608524102 Mon Sep 17 00:00:00 2001 From: LeticiadelaOsa Date: Tue, 10 Sep 2024 19:23:49 +0200 Subject: [PATCH 38/50] use the default border in border selection --- src/pods/canvas/canvas.model.ts | 10 +++++----- .../border-radius/border-radius.component.tsx | 17 +++++++++++------ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/pods/canvas/canvas.model.ts b/src/pods/canvas/canvas.model.ts index 3c652813..e5a4fc52 100644 --- a/src/pods/canvas/canvas.model.ts +++ b/src/pods/canvas/canvas.model.ts @@ -382,7 +382,7 @@ export const generateDefaultOtherProps = ( backgroundColor: INPUT_SHAPE.DEFAULT_FILL_BACKGROUND, textColor: INPUT_SHAPE.DEFAULT_FILL_TEXT, strokeStyle: [], - borderRadius: '12', + borderRadius: `${INPUT_SHAPE.DEFAULT_CORNER_RADIUS}`, }; case 'tooltip': return { @@ -403,7 +403,7 @@ export const generateDefaultOtherProps = ( backgroundColor: BASIC_SHAPE.DEFAULT_FILL_BACKGROUND, textColor: BASIC_SHAPE.DEFAULT_FILL_TEXT, strokeStyle: [], - borderRadius: '12', + borderRadius: `${INPUT_SHAPE.DEFAULT_CORNER_RADIUS}`, }; case 'combobox': return { @@ -411,7 +411,7 @@ export const generateDefaultOtherProps = ( backgroundColor: BASIC_SHAPE.DEFAULT_FILL_BACKGROUND, textColor: BASIC_SHAPE.DEFAULT_FILL_TEXT, strokeStyle: [], - borderRadius: '12', + borderRadius: `${INPUT_SHAPE.DEFAULT_CORNER_RADIUS}`, }; case 'modal': case 'buttonBar': @@ -433,7 +433,7 @@ export const generateDefaultOtherProps = ( backgroundColor: '#FFFF99', textColor: '#000000', strokeStyle: [], - borderRadius: '12', + borderRadius: `${INPUT_SHAPE.DEFAULT_CORNER_RADIUS}`, }; case 'circle': @@ -450,7 +450,7 @@ export const generateDefaultOtherProps = ( stroke: '#000000', backgroundColor: '#ffffff', strokeStyle: [], - borderRadius: '12', + borderRadius: `${INPUT_SHAPE.DEFAULT_CORNER_RADIUS}`, }; case 'line': return { diff --git a/src/pods/properties/components/border-radius/border-radius.component.tsx b/src/pods/properties/components/border-radius/border-radius.component.tsx index 1cc2cb38..356d36a1 100644 --- a/src/pods/properties/components/border-radius/border-radius.component.tsx +++ b/src/pods/properties/components/border-radius/border-radius.component.tsx @@ -1,3 +1,4 @@ +import { BASIC_SHAPE } from '@/common/components/front-components/shape.const'; import classes from './border-radius.module.css'; interface Props { @@ -6,6 +7,10 @@ interface Props { onChange: (borderRadius: string) => void; } +const BORDER_RADIUS_NONE = '0'; +const BORDER_RADIUS_SMALL = `${BASIC_SHAPE.DEFAULT_CORNER_RADIUS}`; +const BORDER_RADIUS_BIG = '12'; + export const BorderRadius: React.FC = props => { const { label, borderRadius, onChange } = props; @@ -14,8 +19,8 @@ export const BorderRadius: React.FC = props => {

{label}

- + >
From 665db5e3622932898172a9f4b8b5852437bd5d0a Mon Sep 17 00:00:00 2001 From: Fran Lopez Date: Thu, 12 Sep 2024 12:38:48 +0200 Subject: [PATCH 46/50] refactor refactor active tab to active element to be more generic --- .../buttonBar/buttonBar.tsx | 11 ++-- .../tabsbar/tabsbar-shape.tsx | 11 ++-- .../active-element-selector.utils.ts} | 10 ++-- src/core/model/index.ts | 2 +- src/pods/canvas/canvas.model.ts | 4 +- ...ive-element-selector.component.module.css} | 0 .../active-element-selector.component.tsx | 58 +++++++++++++++++++ .../active-element-selector/index.ts | 1 + .../active-tab-selector.component.tsx | 55 ------------------ .../components/active-tab-selector/index.ts | 1 - src/pods/properties/properties.pod.tsx | 12 ++-- 11 files changed, 87 insertions(+), 78 deletions(-) rename src/common/{components/front-rich-components/tabsbar/tabsbar.utils.ts => utils/active-element-selector.utils.ts} (54%) rename src/pods/properties/components/{active-tab-selector/active-tab-selector.component.module.css => active-element-selector/active-element-selector.component.module.css} (100%) create mode 100644 src/pods/properties/components/active-element-selector/active-element-selector.component.tsx create mode 100644 src/pods/properties/components/active-element-selector/index.ts delete mode 100644 src/pods/properties/components/active-tab-selector/active-tab-selector.component.tsx delete mode 100644 src/pods/properties/components/active-tab-selector/index.ts diff --git a/src/common/components/front-rich-components/buttonBar/buttonBar.tsx b/src/common/components/front-rich-components/buttonBar/buttonBar.tsx index fb72b060..a4c460f0 100644 --- a/src/common/components/front-rich-components/buttonBar/buttonBar.tsx +++ b/src/common/components/front-rich-components/buttonBar/buttonBar.tsx @@ -6,7 +6,10 @@ import { BASIC_SHAPE } from '../../front-components/shape.const'; import { useShapeProps } from '../../shapes/use-shape-props.hook'; import { useShapeComponentSelection } from '../../shapes/use-shape-selection.hook'; import { forwardRef } from 'react'; -import { parseCSVHeader, splitCSVIntoRows } from '../tabsbar/tabsbar.utils'; +import { + extractCSVHeaders, + splitCSVContentIntoRows, +} from '@/common/utils/active-element-selector.utils'; const buttonBarShapeSizeRestrictions: ShapeSizeRestrictions = { minWidth: 200, @@ -42,8 +45,8 @@ export const ButtonBarShape = forwardRef((props, ref) => { height ); - const csvData = splitCSVIntoRows(text); - const headers = parseCSVHeader(csvData[0]); + const csvData = splitCSVContentIntoRows(text); + const headers = extractCSVHeaders(csvData[0]); const tabLabels = headers.map(header => header.text); const dynamicTabWidth = restrictedWidth / tabLabels.length; @@ -55,7 +58,7 @@ export const ButtonBarShape = forwardRef((props, ref) => { BASIC_SHAPE ); - const activeTab = otherProps?.activeTab ?? 0; + const activeTab = otherProps?.activeElement ?? 0; return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = fitSizeToShapeSizeRestrictions(tabsBarShapeSizeRestrictions, width, height); - const csvData = splitCSVIntoRows(text); - const headers = parseCSVHeader(csvData[0]); + const csvData = splitCSVContentIntoRows(text); + const headers = extractCSVHeaders(csvData[0]); const tabLabels = headers.map(header => header.text); // Calculate tab dimensions and margin @@ -48,7 +51,7 @@ export const TabsBarShape = forwardRef((props, ref) => { const { handleSelection } = useShapeComponentSelection(props, shapeType); - const activeTab = otherProps?.activeTab ?? 0; + const activeTab = otherProps?.activeElement ?? 0; return ( { +export const splitCSVContentIntoRows = (csvContent: string): string[] => { return csvContent.trim().split('\n'); }; -export const parseCSVHeader = (headerRow: string): Header[] => { +export const extractCSVHeaders = (headerRow: string): CSVHeader[] => { return headerRow .split(',') .map(header => header.trim()) .filter(header => header.length > 0) .map(header => { - const textWithoutAlignment = header + const cleanedHeaderText = header .replace(/(?:\s+\^?\s*v?|\s+v?\s*\^?)$/, '') .trim(); return { - text: textWithoutAlignment, + text: cleanedHeaderText, }; }); }; diff --git a/src/core/model/index.ts b/src/core/model/index.ts index acd2c438..442f9da7 100644 --- a/src/core/model/index.ts +++ b/src/core/model/index.ts @@ -160,7 +160,7 @@ export interface OtherProps { imageBlackAndWhite?: boolean; progress?: string; borderRadius?: string; - activeTab?: number; + activeElement?: number; } export const BASE_ICONS_URL = '/icons/'; diff --git a/src/pods/canvas/canvas.model.ts b/src/pods/canvas/canvas.model.ts index de5b1ba1..3811f8b4 100644 --- a/src/pods/canvas/canvas.model.ts +++ b/src/pods/canvas/canvas.model.ts @@ -420,7 +420,7 @@ export const generateDefaultOtherProps = ( backgroundColor: BASIC_SHAPE.DEFAULT_FILL_BACKGROUND, textColor: BASIC_SHAPE.DEFAULT_FILL_TEXT, strokeStyle: [], - activeTab: 0, + activeElement: 0, }; case 'largeArrow': return { @@ -513,7 +513,7 @@ export const generateDefaultOtherProps = ( }; case 'tabsBar': return { - activeTab: 0, + activeElement: 0, }; default: return undefined; diff --git a/src/pods/properties/components/active-tab-selector/active-tab-selector.component.module.css b/src/pods/properties/components/active-element-selector/active-element-selector.component.module.css similarity index 100% rename from src/pods/properties/components/active-tab-selector/active-tab-selector.component.module.css rename to src/pods/properties/components/active-element-selector/active-element-selector.component.module.css diff --git a/src/pods/properties/components/active-element-selector/active-element-selector.component.tsx b/src/pods/properties/components/active-element-selector/active-element-selector.component.tsx new file mode 100644 index 00000000..6975a80f --- /dev/null +++ b/src/pods/properties/components/active-element-selector/active-element-selector.component.tsx @@ -0,0 +1,58 @@ +import classes from './active-element-selector.component.module.css'; + +interface Props { + text?: string; + type?: string; + activeElement: number; + label: string; + onChange: (activeElement: number) => void; +} + +export const ActiveElementSelector: React.FC = ({ + text, + type, + activeElement, + label, + onChange, +}) => { + // Function to parse the tabsbar text and get the names of the tabs + const extractElementNames = (text: string): string[] => { + return text + .split('\n')[0] + .trim() + .split(',') + .map(elementName => elementName.trim()) + .filter(elementName => elementName.length > 0); + }; + + // Checking whether the type is tabsBar and parsing the text + const isElementTypeSupported = type === 'tabsBar' || 'buttonBar'; + const elementNames = + isElementTypeSupported && text ? extractElementNames(text) : []; + + const handleActiveElementChange = ( + e: React.ChangeEvent + ) => { + onChange(Number(e.target.value)); + }; + + return ( + isElementTypeSupported && + elementNames.length > 0 && ( +
+

{label}

+ +
+ ) + ); +}; diff --git a/src/pods/properties/components/active-element-selector/index.ts b/src/pods/properties/components/active-element-selector/index.ts new file mode 100644 index 00000000..8e9bf69a --- /dev/null +++ b/src/pods/properties/components/active-element-selector/index.ts @@ -0,0 +1 @@ +export * from './active-element-selector.component'; diff --git a/src/pods/properties/components/active-tab-selector/active-tab-selector.component.tsx b/src/pods/properties/components/active-tab-selector/active-tab-selector.component.tsx deleted file mode 100644 index e5943ba9..00000000 --- a/src/pods/properties/components/active-tab-selector/active-tab-selector.component.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import classes from './active-tab-selector.component.module.css'; - -interface Props { - text?: string; - type?: string; - activeTab: number; - label: string; - onChange: (activeTab: number) => void; -} - -export const ActiveTabSelector: React.FC = ({ - text, - type, - activeTab, - label, - onChange, -}) => { - // Function to parse the tabsbar text and get the names of the tabs - const parseTabsBarText = (text: string): string[] => { - return text - .split('\n')[0] - .trim() - .split(',') - .map(tab => tab.trim()) - .filter(tab => tab.length > 0); - }; - - // Checking whether the type is tabsBar and parsing the text - const isTabsBar = type === 'tabsBar' || 'buttonBar'; - const tabs = isTabsBar && text ? parseTabsBarText(text) : []; - - const handleTabChange = (e: React.ChangeEvent) => { - onChange(Number(e.target.value)); - }; - - return ( - isTabsBar && - tabs.length > 0 && ( -
-

{label}

- -
- ) - ); -}; diff --git a/src/pods/properties/components/active-tab-selector/index.ts b/src/pods/properties/components/active-tab-selector/index.ts deleted file mode 100644 index b3c2f46c..00000000 --- a/src/pods/properties/components/active-tab-selector/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './active-tab-selector.component'; diff --git a/src/pods/properties/properties.pod.tsx b/src/pods/properties/properties.pod.tsx index 8a737e49..04eaebd2 100644 --- a/src/pods/properties/properties.pod.tsx +++ b/src/pods/properties/properties.pod.tsx @@ -8,7 +8,7 @@ import { StrokeStyle } from './components/stroke-style/stroke.style.component'; import { ImageSrc } from './components/image-src/image-selector.component'; import { ImageBlackAndWhite } from './components/image-black-and-white/image-black-and-white-selector.component'; import { Progress } from './components/progress/progress.component'; -import { ActiveTabSelector } from './components/active-tab-selector/active-tab-selector.component'; +import { ActiveElementSelector } from './components/active-element-selector/active-element-selector.component'; export const PropertiesPod = () => { const { selectionInfo } = useCanvasContext(); @@ -137,14 +137,14 @@ export const PropertiesPod = () => { )} )} - {selectedShapeData?.otherProps?.activeTab !== undefined && ( - - updateOtherPropsOnSelected('activeTab', activeTab) + activeElement={selectedShapeData?.otherProps?.activeElement ?? 0} + onChange={activeElement => + updateOtherPropsOnSelected('activeElement', activeElement) } /> )} From 7c0bc3b52173fe40d9f2a7d61a4281ed6ac6e1d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Rodr=C3=ADguez=20Montalvo?= Date: Fri, 13 Sep 2024 11:25:30 +0200 Subject: [PATCH 47/50] Handle shortcuts for single key shortcut and Ctrl or Meta combinations --- src/pods/toolbar/shortcut/shortcut.const.ts | 10 +++++----- src/pods/toolbar/shortcut/shortcut.hook.tsx | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/pods/toolbar/shortcut/shortcut.const.ts b/src/pods/toolbar/shortcut/shortcut.const.ts index fd25ef86..6158771e 100644 --- a/src/pods/toolbar/shortcut/shortcut.const.ts +++ b/src/pods/toolbar/shortcut/shortcut.const.ts @@ -8,31 +8,31 @@ export const SHORTCUTS: Shortcut = { delete: { description: 'Delete', id: 'delete-button-shortcut', - targetKey: ['Backspace'], + targetKey: ['backspace'], targetKeyLabel: 'Backspace', }, copy: { description: 'Copy', id: 'copy-button-shortcut', - targetKey: ['c'], + targetKey: ['Ctrl+c', 'Meta+c'], targetKeyLabel: 'Ctrl + C', }, paste: { description: 'Paste', id: 'paste-button-shortcut', - targetKey: ['v'], + targetKey: ['Ctrl+v', 'Meta+v'], targetKeyLabel: 'Ctrl + V', }, undo: { description: 'Undo', id: 'undo-button-shortcut', - targetKey: ['z'], + targetKey: ['Ctrl+z', 'Meta+z'], targetKeyLabel: 'Ctrl + Z', }, redo: { description: 'Redo', id: 'red-button-shortcut', - targetKey: ['y'], + targetKey: ['Ctrl+y', 'Meta+y'], targetKeyLabel: 'Ctrl + Y', }, }; diff --git a/src/pods/toolbar/shortcut/shortcut.hook.tsx b/src/pods/toolbar/shortcut/shortcut.hook.tsx index 49278cdb..ccf8ca2e 100644 --- a/src/pods/toolbar/shortcut/shortcut.hook.tsx +++ b/src/pods/toolbar/shortcut/shortcut.hook.tsx @@ -13,15 +13,15 @@ export const useShortcut = ({ targetKey, callback }: ShortcutHookProps) => { //const isAltKeyPressed = event.getModifierState('Alt'); //const isCtrlKeyPressed = event.getModifierState('Control'); const isCtrlOrCmdPressed = event.ctrlKey || event.metaKey; + const ctrlKey = isMacOS() ? 'Meta' : 'Ctrl'; + const pressedKey = event.key.toLowerCase(); if ( - (isWindowsOrLinux() && isCtrlOrCmdPressed) || - (isMacOS() && isCtrlOrCmdPressed) + targetKey.includes(pressedKey) || + (isCtrlOrCmdPressed && targetKey.includes(`${ctrlKey}+${pressedKey}`)) ) { - if (targetKey.includes(event.key)) { - event.preventDefault(); - callback(); - } + event.preventDefault(); + callback(); } }; From 9d6b46fe02fd478a3c5e7e1d68daf349483ce36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Rodr=C3=ADguez=20Montalvo?= Date: Fri, 13 Sep 2024 11:26:27 +0200 Subject: [PATCH 48/50] Not needed isWindowsOrLinux check --- src/pods/toolbar/shortcut/shortcut.hook.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pods/toolbar/shortcut/shortcut.hook.tsx b/src/pods/toolbar/shortcut/shortcut.hook.tsx index ccf8ca2e..9069b142 100644 --- a/src/pods/toolbar/shortcut/shortcut.hook.tsx +++ b/src/pods/toolbar/shortcut/shortcut.hook.tsx @@ -1,4 +1,4 @@ -import { isMacOS, isWindowsOrLinux } from '@/common/helpers/platform.helpers'; +import { isMacOS } from '@/common/helpers/platform.helpers'; import { useEffect } from 'react'; export interface ShortcutHookProps { @@ -13,6 +13,7 @@ export const useShortcut = ({ targetKey, callback }: ShortcutHookProps) => { //const isAltKeyPressed = event.getModifierState('Alt'); //const isCtrlKeyPressed = event.getModifierState('Control'); const isCtrlOrCmdPressed = event.ctrlKey || event.metaKey; + const ctrlKey = isMacOS() ? 'Meta' : 'Ctrl'; const pressedKey = event.key.toLowerCase(); From a5eaaeb3d21c7397b2623e57f80bff98bc0e4422 Mon Sep 17 00:00:00 2001 From: Braulio Date: Sun, 15 Sep 2024 17:31:19 +0200 Subject: [PATCH 49/50] refactor galleries pods folder structure --- .../basic-shapes-gallery/basic-gallery-data/index.ts | 0 .../basic-shapes-gallery/basic-shapes-gallery.pod.tsx | 0 .../component-gallery/component-gallery-data/index.ts | 0 .../component-gallery/component-gallery.pod.tsx | 0 .../container-gallery/container-gallery-data/index.ts | 0 .../container-gallery/container-gallery.pod.tsx | 0 src/pods/galleries/index.ts | 5 +++++ .../rich-components-gallery-data/index.ts | 0 .../rich-components-gallery/rich-shapes-gallery.pod.tsx} | 2 +- .../text-component-gallery/text-component-gallery.pod.tsx | 0 .../text-component-galley-data/index.ts | 0 src/pods/index.ts | 6 +----- 12 files changed, 7 insertions(+), 6 deletions(-) rename src/pods/{ => galleries}/basic-shapes-gallery/basic-gallery-data/index.ts (100%) rename src/pods/{ => galleries}/basic-shapes-gallery/basic-shapes-gallery.pod.tsx (100%) rename src/pods/{ => galleries}/component-gallery/component-gallery-data/index.ts (100%) rename src/pods/{ => galleries}/component-gallery/component-gallery.pod.tsx (100%) rename src/pods/{ => galleries}/container-gallery/container-gallery-data/index.ts (100%) rename src/pods/{ => galleries}/container-gallery/container-gallery.pod.tsx (100%) create mode 100644 src/pods/galleries/index.ts rename src/pods/{ => galleries}/rich-components-gallery/rich-components-gallery-data/index.ts (100%) rename src/pods/{rich-components-gallery/basic-shapes-gallery.pod.tsx => galleries/rich-components-gallery/rich-shapes-gallery.pod.tsx} (66%) rename src/pods/{ => galleries}/text-component-gallery/text-component-gallery.pod.tsx (100%) rename src/pods/{ => galleries}/text-component-gallery/text-component-galley-data/index.ts (100%) diff --git a/src/pods/basic-shapes-gallery/basic-gallery-data/index.ts b/src/pods/galleries/basic-shapes-gallery/basic-gallery-data/index.ts similarity index 100% rename from src/pods/basic-shapes-gallery/basic-gallery-data/index.ts rename to src/pods/galleries/basic-shapes-gallery/basic-gallery-data/index.ts diff --git a/src/pods/basic-shapes-gallery/basic-shapes-gallery.pod.tsx b/src/pods/galleries/basic-shapes-gallery/basic-shapes-gallery.pod.tsx similarity index 100% rename from src/pods/basic-shapes-gallery/basic-shapes-gallery.pod.tsx rename to src/pods/galleries/basic-shapes-gallery/basic-shapes-gallery.pod.tsx diff --git a/src/pods/component-gallery/component-gallery-data/index.ts b/src/pods/galleries/component-gallery/component-gallery-data/index.ts similarity index 100% rename from src/pods/component-gallery/component-gallery-data/index.ts rename to src/pods/galleries/component-gallery/component-gallery-data/index.ts diff --git a/src/pods/component-gallery/component-gallery.pod.tsx b/src/pods/galleries/component-gallery/component-gallery.pod.tsx similarity index 100% rename from src/pods/component-gallery/component-gallery.pod.tsx rename to src/pods/galleries/component-gallery/component-gallery.pod.tsx diff --git a/src/pods/container-gallery/container-gallery-data/index.ts b/src/pods/galleries/container-gallery/container-gallery-data/index.ts similarity index 100% rename from src/pods/container-gallery/container-gallery-data/index.ts rename to src/pods/galleries/container-gallery/container-gallery-data/index.ts diff --git a/src/pods/container-gallery/container-gallery.pod.tsx b/src/pods/galleries/container-gallery/container-gallery.pod.tsx similarity index 100% rename from src/pods/container-gallery/container-gallery.pod.tsx rename to src/pods/galleries/container-gallery/container-gallery.pod.tsx diff --git a/src/pods/galleries/index.ts b/src/pods/galleries/index.ts new file mode 100644 index 00000000..8cc286a4 --- /dev/null +++ b/src/pods/galleries/index.ts @@ -0,0 +1,5 @@ +export * from './basic-shapes-gallery/basic-shapes-gallery.pod'; +export * from './component-gallery/component-gallery.pod'; +export * from './container-gallery/container-gallery.pod'; +export * from './rich-components-gallery/rich-shapes-gallery.pod'; +export * from './text-component-gallery/text-component-gallery.pod'; diff --git a/src/pods/rich-components-gallery/rich-components-gallery-data/index.ts b/src/pods/galleries/rich-components-gallery/rich-components-gallery-data/index.ts similarity index 100% rename from src/pods/rich-components-gallery/rich-components-gallery-data/index.ts rename to src/pods/galleries/rich-components-gallery/rich-components-gallery-data/index.ts diff --git a/src/pods/rich-components-gallery/basic-shapes-gallery.pod.tsx b/src/pods/galleries/rich-components-gallery/rich-shapes-gallery.pod.tsx similarity index 66% rename from src/pods/rich-components-gallery/basic-shapes-gallery.pod.tsx rename to src/pods/galleries/rich-components-gallery/rich-shapes-gallery.pod.tsx index 9edcafd5..a55a4c9b 100644 --- a/src/pods/rich-components-gallery/basic-shapes-gallery.pod.tsx +++ b/src/pods/galleries/rich-components-gallery/rich-shapes-gallery.pod.tsx @@ -1,5 +1,5 @@ import { GalleryComponent } from '@/common/components/gallery/gallery-component'; -import { mockRichComponentsCollection } from '../rich-components-gallery/rich-components-gallery-data'; +import { mockRichComponentsCollection } from './rich-components-gallery-data'; export const RichComponentsGalleryPod = () => { return ; diff --git a/src/pods/text-component-gallery/text-component-gallery.pod.tsx b/src/pods/galleries/text-component-gallery/text-component-gallery.pod.tsx similarity index 100% rename from src/pods/text-component-gallery/text-component-gallery.pod.tsx rename to src/pods/galleries/text-component-gallery/text-component-gallery.pod.tsx diff --git a/src/pods/text-component-gallery/text-component-galley-data/index.ts b/src/pods/galleries/text-component-gallery/text-component-galley-data/index.ts similarity index 100% rename from src/pods/text-component-gallery/text-component-galley-data/index.ts rename to src/pods/galleries/text-component-gallery/text-component-galley-data/index.ts diff --git a/src/pods/index.ts b/src/pods/index.ts index 22c6f3ea..cf15cf9a 100644 --- a/src/pods/index.ts +++ b/src/pods/index.ts @@ -1,7 +1,3 @@ export * from './canvas/canvas.pod'; -export * from './container-gallery/container-gallery.pod'; -export * from './component-gallery/component-gallery.pod'; -export * from './basic-shapes-gallery/basic-shapes-gallery.pod'; -export * from './rich-components-gallery/basic-shapes-gallery.pod'; -export * from './text-component-gallery/text-component-gallery.pod'; +export * from './galleries'; export * from './toolbar/toolbar.pod'; From a7eeeb032c9c911a6ab3573efa51042b08209515 Mon Sep 17 00:00:00 2001 From: Braulio Date: Tue, 17 Sep 2024 12:11:47 +0200 Subject: [PATCH 50/50] removed temporary delete issue --- src/pods/toolbar/shortcut/shortcut.const.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pods/toolbar/shortcut/shortcut.const.ts b/src/pods/toolbar/shortcut/shortcut.const.ts index 6158771e..0483bcca 100644 --- a/src/pods/toolbar/shortcut/shortcut.const.ts +++ b/src/pods/toolbar/shortcut/shortcut.const.ts @@ -8,8 +8,8 @@ export const SHORTCUTS: Shortcut = { delete: { description: 'Delete', id: 'delete-button-shortcut', - targetKey: ['backspace'], - targetKeyLabel: 'Backspace', + targetKey: ['Ctrl+backspace', 'Meta+backspace'], + targetKeyLabel: 'Ctrl + Backspace', }, copy: { description: 'Copy',