From 1f632d12f42d5d1c6b290018b8a315a64d1b2da4 Mon Sep 17 00:00:00 2001 From: IonutGabi Date: Thu, 12 Sep 2024 12:09:50 +0200 Subject: [PATCH 1/5] First prototype to badge component --- public/rich-components/badgelabel.svg | 7 ++ .../front-rich-components/badge-label.tsx | 74 +++++++++++++++++++ .../components/front-rich-components/index.ts | 1 + src/core/model/index.ts | 4 +- src/pods/canvas/canvas.model.ts | 8 ++ src/pods/canvas/shape-renderer/index.tsx | 3 + .../badge-label.renderer.tsx | 32 ++++++++ .../simple-rich-components/index.ts | 1 + .../rich-components-gallery-data/index.ts | 1 + 9 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 public/rich-components/badgelabel.svg create mode 100644 src/common/components/front-rich-components/badge-label.tsx create mode 100644 src/pods/canvas/shape-renderer/simple-rich-components/badge-label.renderer.tsx diff --git a/public/rich-components/badgelabel.svg b/public/rich-components/badgelabel.svg new file mode 100644 index 00000000..68a3c7ea --- /dev/null +++ b/public/rich-components/badgelabel.svg @@ -0,0 +1,7 @@ + + + + + + Badge Label + \ No newline at end of file diff --git a/src/common/components/front-rich-components/badge-label.tsx b/src/common/components/front-rich-components/badge-label.tsx new file mode 100644 index 00000000..ed53fa23 --- /dev/null +++ b/src/common/components/front-rich-components/badge-label.tsx @@ -0,0 +1,74 @@ +import { Group, Rect, Text } from 'react-konva'; +import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; +import { forwardRef } from 'react'; +import { ShapeProps } from '../front-components/shape.model'; +import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; +import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; + +const BadgeLabelShapeSizeRestrictions: ShapeSizeRestrictions = { + minWidth: 150, + minHeight: 40, + maxWidth: -1, + maxHeight: -1, + defaultWidth: 250, + defaultHeight: 40, +}; + +export const getBadgeLabelShapeSizeRestrictions = (): ShapeSizeRestrictions => + BadgeLabelShapeSizeRestrictions; + +const shapeType: ShapeType = 'badgelabel'; + +export const BadgeLabelShape = forwardRef((props, ref) => { + const { + x, + y, + width, + height, + fillColor = 'lightgrey', + textColor = '#000', + id, + onSelected, + ...shapeProps + } = props; + const { width: restrictedWidth, height: restrictedHeigth } = + fitSizeToShapeSizeRestrictions( + BadgeLabelShapeSizeRestrictions, + width, + height + ); + + const { handleSelection } = useShapeComponentSelection(props, shapeType); + + return ( + + + + + + ); +}); diff --git a/src/common/components/front-rich-components/index.ts b/src/common/components/front-rich-components/index.ts index dae1fe33..60b10b7c 100644 --- a/src/common/components/front-rich-components/index.ts +++ b/src/common/components/front-rich-components/index.ts @@ -12,3 +12,4 @@ export * from './table/table'; export * from './modal/modal'; export * from './appBar'; export * from './buttonBar/buttonBar'; +export * from './badge-label'; diff --git a/src/core/model/index.ts b/src/core/model/index.ts index eb7956c5..4df88e81 100644 --- a/src/core/model/index.ts +++ b/src/core/model/index.ts @@ -64,7 +64,8 @@ export type ShapeType = | 'appBar' | 'buttonBar' | 'tooltip' - | 'slider'; + | 'slider' + | 'badgelabel'; export const ShapeDisplayName: Record = { multiple: 'multiple', @@ -119,6 +120,7 @@ export const ShapeDisplayName: Record = { buttonBar: 'Button Bar', tooltip: 'Tooltip', slider: 'Slider', + badgelabel: 'Badge Label', }; export type EditType = 'input' | 'textarea' | 'imageupload'; diff --git a/src/pods/canvas/canvas.model.ts b/src/pods/canvas/canvas.model.ts index 5e28fea0..7cb38912 100644 --- a/src/pods/canvas/canvas.model.ts +++ b/src/pods/canvas/canvas.model.ts @@ -61,6 +61,7 @@ import { getModalShapeSizeRestrictions, getAppBarShapeSizeRestrictions, getButtonBarShapeSizeRestrictions, + getBadgeLabelShapeSizeRestrictions, } from '@/common/components/front-rich-components'; import { getHeading1SizeRestrictions, @@ -181,6 +182,8 @@ export const getSizeRestrictionFromShape = ( return getTooltipShapeSizeRestrictions(); case 'slider': return getSliderShapeSizeRestrictions(); + case 'badgelabel': + return getBadgeLabelShapeSizeRestrictions(); default: console.warn( `** Shape ${shapeType} has not defined default size, check getDefaultSizeFromShape helper function` @@ -238,6 +241,7 @@ const doesShapeAllowInlineEdition = (shapeType: ShapeType): boolean => { case 'buttonBar': case 'tabsbar': case 'tooltip': + case 'badgelabel': return true; default: return false; @@ -269,6 +273,7 @@ const generateTypeOfTransformer = (shapeType: ShapeType): string[] => { case 'appBar': case 'buttonBar': case 'slider': + case 'badgelabel': return ['middle-left', 'middle-right']; case 'verticalScrollBar': return ['top-center', 'bottom-center']; @@ -341,6 +346,8 @@ const generateDefaultTextValue = (shapeType: ShapeType): string | undefined => { return 'Button 1, Button 2, Button 3'; case 'tabsbar': return 'Tab 1, Tab 2, Tab 3'; + case 'badgelabel': + return 'Badge Label'; default: return undefined; } @@ -364,6 +371,7 @@ const getShapeEditInlineType = (shapeType: ShapeType): EditType | undefined => { case 'buttonBar': case 'tabsbar': case 'tooltip': + case 'badgelabel': return 'textarea'; break; case 'image': diff --git a/src/pods/canvas/shape-renderer/index.tsx b/src/pods/canvas/shape-renderer/index.tsx index ed83f5a3..f4463056 100644 --- a/src/pods/canvas/shape-renderer/index.tsx +++ b/src/pods/canvas/shape-renderer/index.tsx @@ -40,6 +40,7 @@ import { renderTable, renderModal, renderButtonBar, + renderBadgeLabel, } from './simple-rich-components'; import { renderDiamond, @@ -170,6 +171,8 @@ export const renderShapeComponent = ( return renderTooltip(shape, shapeRenderedProps); case 'slider': return renderSlider(shape, shapeRenderedProps); + case 'badgelabel': + return renderBadgeLabel(shape, shapeRenderedProps); default: return renderNotFound(shape, shapeRenderedProps); } diff --git a/src/pods/canvas/shape-renderer/simple-rich-components/badge-label.renderer.tsx b/src/pods/canvas/shape-renderer/simple-rich-components/badge-label.renderer.tsx new file mode 100644 index 00000000..9a1a4713 --- /dev/null +++ b/src/pods/canvas/shape-renderer/simple-rich-components/badge-label.renderer.tsx @@ -0,0 +1,32 @@ +import { BadgeLabelShape } from '@/common/components/front-rich-components'; +import { ShapeRendererProps } from '../model'; +import { ShapeModel } from '@/core/model'; + +export const renderBadgeLabel = ( + shape: ShapeModel, + shapeRenderedProps: ShapeRendererProps +) => { + const { handleSelected, shapeRefs, handleDragEnd, handleTransform } = + shapeRenderedProps; + + return ( + + ); +}; diff --git a/src/pods/canvas/shape-renderer/simple-rich-components/index.ts b/src/pods/canvas/shape-renderer/simple-rich-components/index.ts index 08bdae97..220dd259 100644 --- a/src/pods/canvas/shape-renderer/simple-rich-components/index.ts +++ b/src/pods/canvas/shape-renderer/simple-rich-components/index.ts @@ -12,3 +12,4 @@ export * from './table.renderer'; export * from './modal.renderer'; export * from './appBar.renderer'; export * from './button-bar.renderer'; +export * from './badge-label.renderer'; 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 910a4079..deb6ee38 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 @@ -21,4 +21,5 @@ export const mockRichComponentsCollection: ItemInfo[] = [ { 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/badgelabel.svg', type: 'badgelabel' }, ]; From 9ee94d435fd8c2b8ce5bff59e774873db04d169c Mon Sep 17 00:00:00 2001 From: IonutGabi Date: Fri, 13 Sep 2024 17:06:45 +0200 Subject: [PATCH 2/5] Badge label component implementation complete --- .../front-rich-components/badge-label.tsx | 51 +++++++++++++++---- src/pods/canvas/canvas.model.ts | 8 +++ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/common/components/front-rich-components/badge-label.tsx b/src/common/components/front-rich-components/badge-label.tsx index ed53fa23..0167de23 100644 --- a/src/common/components/front-rich-components/badge-label.tsx +++ b/src/common/components/front-rich-components/badge-label.tsx @@ -1,6 +1,7 @@ import { Group, Rect, Text } from 'react-konva'; import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; -import { forwardRef } from 'react'; +import { BASIC_SHAPE } from '../front-components/shape.const'; +import { forwardRef, useMemo } from 'react'; import { ShapeProps } from '../front-components/shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; @@ -25,10 +26,10 @@ export const BadgeLabelShape = forwardRef((props, ref) => { y, width, height, - fillColor = 'lightgrey', - textColor = '#000', id, + text, onSelected, + otherProps, ...shapeProps } = props; const { width: restrictedWidth, height: restrictedHeigth } = @@ -38,6 +39,31 @@ export const BadgeLabelShape = forwardRef((props, ref) => { height ); + const textColor = useMemo( + () => otherProps?.textColor ?? 'black', + [otherProps?.textColor] + ); + + const backgroundColor = useMemo( + () => otherProps?.backgroundColor ?? 'lightgray', + [otherProps?.backgroundColor] + ); + + const strokeColor = useMemo( + () => otherProps?.stroke ?? 'gray', + [otherProps?.stroke] + ); + + const strokeStyle = useMemo( + () => otherProps?.strokeStyle ?? [], + [otherProps?.strokeStyle] + ); + + const borderRadius = useMemo(() => { + const radius = Number(otherProps?.borderRadius); + return isNaN(radius) ? BASIC_SHAPE.DEFAULT_CORNER_RADIUS : radius; + }, [otherProps?.borderRadius]); + const { handleSelection } = useShapeComponentSelection(props, shapeType); return ( @@ -55,19 +81,24 @@ export const BadgeLabelShape = forwardRef((props, ref) => { y={0} width={restrictedWidth} height={restrictedHeigth} - fill={fillColor} - stroke={'gray'} + fill={backgroundColor} + stroke={strokeColor} + dash={strokeStyle} strokeWidth={2} - cornerRadius={restrictedHeigth / 2} + cornerRadius={borderRadius} /> ); diff --git a/src/pods/canvas/canvas.model.ts b/src/pods/canvas/canvas.model.ts index 7cb38912..ac4d7d99 100644 --- a/src/pods/canvas/canvas.model.ts +++ b/src/pods/canvas/canvas.model.ts @@ -519,6 +519,14 @@ export const generateDefaultOtherProps = ( progress: '50', backgroundColor: '#A9A9A9', }; + case 'badgelabel': + return { + stroke: '#808080', + backgroundColor: '#D3D3D3', + textColor: '#000000', + strokeStyle: [], + borderRadius: '30', + }; default: return undefined; } From fef7f4d03bb16a9bcd241202faf97ab175973260 Mon Sep 17 00:00:00 2001 From: IonutGabi Date: Mon, 16 Sep 2024 19:39:15 +0200 Subject: [PATCH 3/5] Fix little errors of badge component --- src/common/components/front-rich-components/badge-label.tsx | 3 ++- src/pods/canvas/canvas.model.ts | 3 +-- .../simple-rich-components/badge-label.renderer.tsx | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/common/components/front-rich-components/badge-label.tsx b/src/common/components/front-rich-components/badge-label.tsx index 0167de23..882ccb3a 100644 --- a/src/common/components/front-rich-components/badge-label.tsx +++ b/src/common/components/front-rich-components/badge-label.tsx @@ -7,7 +7,7 @@ import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-rest import { useShapeComponentSelection } from '../shapes/use-shape-selection.hook'; const BadgeLabelShapeSizeRestrictions: ShapeSizeRestrictions = { - minWidth: 150, + minWidth: 40, minHeight: 40, maxWidth: -1, maxHeight: -1, @@ -99,6 +99,7 @@ export const BadgeLabelShape = forwardRef((props, ref) => { fill={textColor} verticalAlign="middle" align="center" + ellipsis={true} /> ); diff --git a/src/pods/canvas/canvas.model.ts b/src/pods/canvas/canvas.model.ts index 7f811645..bfdad684 100644 --- a/src/pods/canvas/canvas.model.ts +++ b/src/pods/canvas/canvas.model.ts @@ -370,7 +370,6 @@ const getShapeEditInlineType = (shapeType: ShapeType): EditType | undefined => { case 'appBar': case 'tabsBar': case 'tooltip': - case 'badgelabel': return 'textarea'; break; case 'image': @@ -525,7 +524,7 @@ export const generateDefaultOtherProps = ( backgroundColor: '#D3D3D3', textColor: '#000000', strokeStyle: [], - borderRadius: '30', + borderRadius: '12', }; case 'tabsBar': return { diff --git a/src/pods/canvas/shape-renderer/simple-rich-components/badge-label.renderer.tsx b/src/pods/canvas/shape-renderer/simple-rich-components/badge-label.renderer.tsx index 9a1a4713..6063612c 100644 --- a/src/pods/canvas/shape-renderer/simple-rich-components/badge-label.renderer.tsx +++ b/src/pods/canvas/shape-renderer/simple-rich-components/badge-label.renderer.tsx @@ -19,6 +19,7 @@ export const renderBadgeLabel = ( height={shape.height} name="shape" draggable + typeOfTransformer={shape.typeOfTransformer} onSelected={handleSelected} ref={shapeRefs.current[shape.id]} onDragEnd={handleDragEnd(shape.id)} From 504af14348a8f7dee6906481a7a5263932bf2c6f Mon Sep 17 00:00:00 2001 From: IonutGabi Date: Tue, 17 Sep 2024 10:37:56 +0200 Subject: [PATCH 4/5] Fix default width --- src/common/components/front-rich-components/badge-label.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/components/front-rich-components/badge-label.tsx b/src/common/components/front-rich-components/badge-label.tsx index 882ccb3a..dc20872a 100644 --- a/src/common/components/front-rich-components/badge-label.tsx +++ b/src/common/components/front-rich-components/badge-label.tsx @@ -11,7 +11,7 @@ const BadgeLabelShapeSizeRestrictions: ShapeSizeRestrictions = { minHeight: 40, maxWidth: -1, maxHeight: -1, - defaultWidth: 250, + defaultWidth: 150, defaultHeight: 40, }; From 02b8344b5f6ebb831b71c4eded6692d04e4c0ee8 Mon Sep 17 00:00:00 2001 From: IonutGabi Date: Tue, 15 Oct 2024 14:24:49 +0200 Subject: [PATCH 5/5] Fixing the whole badge-component --- .../front-rich-components/badge-label.tsx | 60 ++++++------------- .../canvas/model/inline-editable.model.ts | 3 + .../canvas/model/shape-other-props.utils.ts | 8 +++ src/pods/canvas/model/transformer.model.ts | 1 + 4 files changed, 31 insertions(+), 41 deletions(-) diff --git a/src/common/components/mock-components/front-rich-components/badge-label.tsx b/src/common/components/mock-components/front-rich-components/badge-label.tsx index bff37041..d01530b6 100644 --- a/src/common/components/mock-components/front-rich-components/badge-label.tsx +++ b/src/common/components/mock-components/front-rich-components/badge-label.tsx @@ -1,10 +1,11 @@ import { Group, Rect, Text } from 'react-konva'; import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; import { BASIC_SHAPE } from '../front-components/shape.const'; -import { forwardRef, useMemo } from 'react'; +import { forwardRef } from 'react'; import { ShapeProps } from '../shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; -import { useShapeComponentSelection } from '@/common/components/shapes/use-shape-selection.hook'; +import { useShapeProps } from '../../shapes/use-shape-props.hook'; +import { useGroupShapeProps } from '../mock-components.utils'; const BadgeLabelShapeSizeRestrictions: ShapeSizeRestrictions = { minWidth: 40, @@ -32,57 +33,34 @@ export const BadgeLabelShape = forwardRef((props, ref) => { otherProps, ...shapeProps } = props; - const { width: restrictedWidth, height: restrictedHeigth } = - fitSizeToShapeSizeRestrictions( - BadgeLabelShapeSizeRestrictions, - width, - height - ); - - const textColor = useMemo( - () => otherProps?.textColor ?? 'black', - [otherProps?.textColor] - ); - - const backgroundColor = useMemo( - () => otherProps?.backgroundColor ?? 'lightgray', - [otherProps?.backgroundColor] + const restrictedSize = fitSizeToShapeSizeRestrictions( + BadgeLabelShapeSizeRestrictions, + width, + height ); - const strokeColor = useMemo( - () => otherProps?.stroke ?? 'gray', - [otherProps?.stroke] + const { width: restrictedWidth, height: restrictedHeigth } = restrictedSize; + const { stroke, strokeStyle, borderRadius, fill, textColor } = useShapeProps( + otherProps, + BASIC_SHAPE ); - const strokeStyle = useMemo( - () => otherProps?.strokeStyle ?? [], - [otherProps?.strokeStyle] + const commonGroupProps = useGroupShapeProps( + props, + restrictedSize, + shapeType, + ref ); - const borderRadius = useMemo(() => { - const radius = Number(otherProps?.borderRadius); - return isNaN(radius) ? BASIC_SHAPE.DEFAULT_CORNER_RADIUS : radius; - }, [otherProps?.borderRadius]); - - const { handleSelection } = useShapeComponentSelection(props, shapeType); - return ( - + ([ 'buttonBar', 'tabsBar', 'tooltip', + 'badgelabel', ]); // Check if a shape type allows inline editing @@ -64,6 +65,7 @@ const shapeTypesWithDefaultText = new Set([ 'appBar', 'buttonBar', 'tabsBar', + 'badgelabel', ]); // Map of ShapeTypes to their default text values @@ -95,6 +97,7 @@ const defaultTextValueMap: Partial> = { appBar: 'AppBar', buttonBar: 'Button 1, Button 2, Button 3', tabsBar: 'Tab 1, Tab 2, Tab 3', + badgelabel: 'Badge Label', }; export const generateDefaultTextValue = ( diff --git a/src/pods/canvas/model/shape-other-props.utils.ts b/src/pods/canvas/model/shape-other-props.utils.ts index 8c79411b..b5fb5120 100644 --- a/src/pods/canvas/model/shape-other-props.utils.ts +++ b/src/pods/canvas/model/shape-other-props.utils.ts @@ -162,6 +162,14 @@ export const generateDefaultOtherProps = ( return { activeElement: 0, }; + case 'badgelabel': + return { + stroke: '#939393', + backgroundColor: '#D3D3D3', + textColor: '#000000', + strokeStyle: [], + borderRadius: '12', + }; default: return undefined; } diff --git a/src/pods/canvas/model/transformer.model.ts b/src/pods/canvas/model/transformer.model.ts index 20eaef13..30182b31 100644 --- a/src/pods/canvas/model/transformer.model.ts +++ b/src/pods/canvas/model/transformer.model.ts @@ -66,6 +66,7 @@ export const generateTypeOfTransformer = (shapeType: ShapeType): string[] => { case 'appBar': case 'buttonBar': case 'slider': + case 'badgelabel': return ['middle-left', 'middle-right']; case 'verticalScrollBar': return ['top-center', 'bottom-center'];