From dac48b8303e26dc36bdf1a63c4b4e916922cba0c Mon Sep 17 00:00:00 2001 From: Fran Lopez Date: Tue, 19 Nov 2024 19:56:17 +0100 Subject: [PATCH 1/2] add text alignment functionality to the TextAlignment component --- .../front-components/shape.const.ts | 5 ++ .../heading1-text-shape.tsx | 12 +++- .../heading2-text-shape.tsx | 12 +++- .../heading3-text-shape.tsx | 12 +++- .../front-text-components/link-text-shape.tsx | 4 +- .../normaltext-shape.tsx | 12 +++- .../paragraph-text-shape.tsx | 7 +- .../front-text-components/smalltext-shape.tsx | 12 +++- .../components/shapes/use-shape-props.hook.ts | 6 ++ src/core/model/index.ts | 1 + .../canvas/model/shape-other-props.utils.ts | 7 ++ .../components/text-alignment/index.ts | 1 + .../text-alignment/text-alignment.module.css | 39 +++++++++++ .../text-alignment/text-alignment.tsx | 70 +++++++++++++++++++ src/pods/properties/properties.pod.tsx | 10 +++ 15 files changed, 191 insertions(+), 19 deletions(-) create mode 100644 src/pods/properties/components/text-alignment/index.ts create mode 100644 src/pods/properties/components/text-alignment/text-alignment.module.css create mode 100644 src/pods/properties/components/text-alignment/text-alignment.tsx diff --git a/src/common/components/mock-components/front-components/shape.const.ts b/src/common/components/mock-components/front-components/shape.const.ts index 458d4178..63656560 100644 --- a/src/common/components/mock-components/front-components/shape.const.ts +++ b/src/common/components/mock-components/front-components/shape.const.ts @@ -15,6 +15,7 @@ const DEFAULT_TEXT_HEIGHT = 38; const DEFAULT_FONT_VARIANT = 'normal'; const DEFAULT_FONT_STYLE = 'normal'; const DEFAULT_TEXT_DECORATION = 'none'; +const DEFAULT_TEXT_ALIGNMENT = 'left'; export interface DefaultStyleShape { DEFAULT_CORNER_RADIUS: number; @@ -32,6 +33,7 @@ export interface DefaultStyleShape { DEFAULT_FONT_VARIANT: string; DEFAULT_FONT_STYLE: string; DEFAULT_TEXT_DECORATION: string; + DEFAULT_TEXT_ALIGNMENT: 'left' | 'center' | 'right'; } export const BASIC_SHAPE: DefaultStyleShape = { @@ -50,6 +52,7 @@ export const BASIC_SHAPE: DefaultStyleShape = { DEFAULT_FONT_VARIANT, DEFAULT_FONT_STYLE, DEFAULT_TEXT_DECORATION, + DEFAULT_TEXT_ALIGNMENT, }; export const INPUT_SHAPE: DefaultStyleShape = { @@ -68,6 +71,7 @@ export const INPUT_SHAPE: DefaultStyleShape = { DEFAULT_FONT_VARIANT, DEFAULT_FONT_STYLE, DEFAULT_TEXT_DECORATION, + DEFAULT_TEXT_ALIGNMENT, }; //! maybe a function to calc max height base on the text @@ -87,6 +91,7 @@ export const POSTIT_SHAPE: DefaultStyleShape = { DEFAULT_FONT_VARIANT, DEFAULT_FONT_STYLE, DEFAULT_TEXT_DECORATION, + DEFAULT_TEXT_ALIGNMENT, }; interface FontValues { diff --git a/src/common/components/mock-components/front-text-components/heading1-text-shape.tsx b/src/common/components/mock-components/front-text-components/heading1-text-shape.tsx index edd483fe..ed5ef8c5 100644 --- a/src/common/components/mock-components/front-text-components/heading1-text-shape.tsx +++ b/src/common/components/mock-components/front-text-components/heading1-text-shape.tsx @@ -40,8 +40,14 @@ export const Heading1Shape = forwardRef((props, ref) => { ); const { width: restrictedWidth, height: restrictedHeight } = restrictedSize; - const { textColor, textDecoration, fontStyle, fontVariant, fontSize } = - useShapeProps(otherProps, BASIC_SHAPE); + const { + textColor, + textDecoration, + fontStyle, + fontVariant, + fontSize, + textAlignment, + } = useShapeProps(otherProps, BASIC_SHAPE); const commonGroupProps = useGroupShapeProps( props, @@ -61,7 +67,7 @@ export const Heading1Shape = forwardRef((props, ref) => { fontFamily={BASIC_SHAPE.DEFAULT_FONT_FAMILY} fontSize={fontSize} fill={textColor} - align="center" + align={textAlignment} verticalAlign="middle" ellipsis={true} wrap="none" diff --git a/src/common/components/mock-components/front-text-components/heading2-text-shape.tsx b/src/common/components/mock-components/front-text-components/heading2-text-shape.tsx index 02d8184b..f7398556 100644 --- a/src/common/components/mock-components/front-text-components/heading2-text-shape.tsx +++ b/src/common/components/mock-components/front-text-components/heading2-text-shape.tsx @@ -40,8 +40,14 @@ export const Heading2Shape = forwardRef((props, ref) => { ); const { width: restrictedWidth, height: restrictedHeight } = restrictedSize; - const { textColor, fontVariant, fontStyle, textDecoration, fontSize } = - useShapeProps(otherProps, BASIC_SHAPE); + const { + textColor, + fontVariant, + fontStyle, + textDecoration, + fontSize, + textAlignment, + } = useShapeProps(otherProps, BASIC_SHAPE); const commonGroupProps = useGroupShapeProps( props, @@ -61,7 +67,7 @@ export const Heading2Shape = forwardRef((props, ref) => { fontFamily={BASIC_SHAPE.DEFAULT_FONT_FAMILY} fontSize={fontSize} fill={textColor} - align="center" + align={textAlignment} verticalAlign="middle" ellipsis={true} wrap="none" diff --git a/src/common/components/mock-components/front-text-components/heading3-text-shape.tsx b/src/common/components/mock-components/front-text-components/heading3-text-shape.tsx index 4f02a862..c8b0d720 100644 --- a/src/common/components/mock-components/front-text-components/heading3-text-shape.tsx +++ b/src/common/components/mock-components/front-text-components/heading3-text-shape.tsx @@ -41,8 +41,14 @@ export const Heading3Shape = forwardRef((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = restrictedSize; - const { textColor, fontVariant, fontStyle, textDecoration, fontSize } = - useShapeProps(otherProps, BASIC_SHAPE); + const { + textColor, + fontVariant, + fontStyle, + textDecoration, + fontSize, + textAlignment, + } = useShapeProps(otherProps, BASIC_SHAPE); const commonGroupProps = useGroupShapeProps( props, @@ -62,7 +68,7 @@ export const Heading3Shape = forwardRef((props, ref) => { fontFamily={BASIC_SHAPE.DEFAULT_FONT_FAMILY} fontSize={fontSize} fill={textColor} - align="center" + align={textAlignment} verticalAlign="middle" ellipsis={true} wrap="none" diff --git a/src/common/components/mock-components/front-text-components/link-text-shape.tsx b/src/common/components/mock-components/front-text-components/link-text-shape.tsx index e139ce70..042297b2 100644 --- a/src/common/components/mock-components/front-text-components/link-text-shape.tsx +++ b/src/common/components/mock-components/front-text-components/link-text-shape.tsx @@ -41,7 +41,7 @@ export const LinkShape = forwardRef((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = restrictedSize; - const { textColor, textDecoration, fontSize } = useShapeProps( + const { textColor, textDecoration, fontSize, textAlignment } = useShapeProps( otherProps, BASIC_SHAPE ); @@ -64,7 +64,7 @@ export const LinkShape = forwardRef((props, ref) => { fontFamily={BASIC_SHAPE.DEFAULT_FONT_FAMILY} fontSize={fontSize} fill={textColor} - align="center" + align={textAlignment} verticalAlign="middle" ellipsis={true} wrap="none" diff --git a/src/common/components/mock-components/front-text-components/normaltext-shape.tsx b/src/common/components/mock-components/front-text-components/normaltext-shape.tsx index 6f3bd419..fc9e1b98 100644 --- a/src/common/components/mock-components/front-text-components/normaltext-shape.tsx +++ b/src/common/components/mock-components/front-text-components/normaltext-shape.tsx @@ -40,8 +40,14 @@ export const NormaltextShape = forwardRef((props, ref) => { ); const { width: restrictedWidth, height: restrictedHeight } = restrictedSize; - const { textColor, fontVariant, fontStyle, textDecoration, fontSize } = - useShapeProps(otherProps, BASIC_SHAPE); + const { + textColor, + fontVariant, + fontStyle, + textDecoration, + fontSize, + textAlignment, + } = useShapeProps(otherProps, BASIC_SHAPE); const commonGroupProps = useGroupShapeProps( props, @@ -61,7 +67,7 @@ export const NormaltextShape = forwardRef((props, ref) => { fontFamily={BASIC_SHAPE.DEFAULT_FONT_FAMILY} fontSize={fontSize} fill={textColor} - align="center" + align={textAlignment} verticalAlign="middle" ellipsis={true} wrap="none" diff --git a/src/common/components/mock-components/front-text-components/paragraph-text-shape.tsx b/src/common/components/mock-components/front-text-components/paragraph-text-shape.tsx index 3d44c447..97fd5943 100644 --- a/src/common/components/mock-components/front-text-components/paragraph-text-shape.tsx +++ b/src/common/components/mock-components/front-text-components/paragraph-text-shape.tsx @@ -40,7 +40,10 @@ export const ParagraphShape = forwardRef((props, ref) => { ); const { width: restrictedWidth, height: restrictedHeight } = restrictedSize; - const { textColor, fontSize } = useShapeProps(otherProps, BASIC_SHAPE); + const { textColor, fontSize, textAlignment } = useShapeProps( + otherProps, + BASIC_SHAPE + ); const commonGroupProps = useGroupShapeProps( props, @@ -60,7 +63,7 @@ export const ParagraphShape = forwardRef((props, ref) => { fontFamily={BASIC_SHAPE.DEFAULT_FONT_FAMILY} fontSize={fontSize} fill={textColor} - align="left" + align={textAlignment} ellipsis={true} /> diff --git a/src/common/components/mock-components/front-text-components/smalltext-shape.tsx b/src/common/components/mock-components/front-text-components/smalltext-shape.tsx index ec0393a2..c22a72d5 100644 --- a/src/common/components/mock-components/front-text-components/smalltext-shape.tsx +++ b/src/common/components/mock-components/front-text-components/smalltext-shape.tsx @@ -40,8 +40,14 @@ export const SmalltextShape = forwardRef((props, ref) => { ); const { width: restrictedWidth, height: restrictedHeight } = restrictedSize; - const { textColor, fontVariant, fontStyle, textDecoration, fontSize } = - useShapeProps(otherProps, BASIC_SHAPE); + const { + textColor, + fontVariant, + fontStyle, + textDecoration, + fontSize, + textAlignment, + } = useShapeProps(otherProps, BASIC_SHAPE); const commonGroupProps = useGroupShapeProps( props, @@ -61,7 +67,7 @@ export const SmalltextShape = forwardRef((props, ref) => { fontFamily={BASIC_SHAPE.DEFAULT_FONT_FAMILY} fontSize={fontSize} fill={textColor} - align="center" + align={textAlignment} verticalAlign="middle" ellipsis={true} wrap="none" diff --git a/src/common/components/shapes/use-shape-props.hook.ts b/src/common/components/shapes/use-shape-props.hook.ts index 1a68f6d9..f3d79f85 100644 --- a/src/common/components/shapes/use-shape-props.hook.ts +++ b/src/common/components/shapes/use-shape-props.hook.ts @@ -43,6 +43,11 @@ export const useShapeProps = ( [otherProps?.textDecoration] ); + const textAlignment = useMemo( + () => otherProps?.textAlignment ?? defaultStyleShape.DEFAULT_TEXT_ALIGNMENT, + [otherProps?.textAlignment] + ); + const strokeStyle = useMemo( () => otherProps?.strokeStyle ?? [], [otherProps?.strokeStyle] @@ -81,5 +86,6 @@ export const useShapeProps = ( fontStyle, fontSize, textDecoration, + textAlignment, }; }; diff --git a/src/core/model/index.ts b/src/core/model/index.ts index 843d0979..c4580e2c 100644 --- a/src/core/model/index.ts +++ b/src/core/model/index.ts @@ -174,6 +174,7 @@ export interface OtherProps { borderRadius?: string; activeElement?: number; selectedBackgroundColor?: string; + textAlignment?: 'left' | 'center' | 'right'; } export const BASE_ICONS_URL = '/icons/'; diff --git a/src/pods/canvas/model/shape-other-props.utils.ts b/src/pods/canvas/model/shape-other-props.utils.ts index afff3625..62f09261 100644 --- a/src/pods/canvas/model/shape-other-props.utils.ts +++ b/src/pods/canvas/model/shape-other-props.utils.ts @@ -126,6 +126,7 @@ export const generateDefaultOtherProps = ( fontStyle: `${INPUT_SHAPE.DEFAULT_FONT_STYLE}`, textDecoration: `${INPUT_SHAPE.DEFAULT_TEXT_DECORATION}`, fontSize: FONT_SIZE_VALUES.HEADING1, + textAlignment: `${BASIC_SHAPE.DEFAULT_TEXT_ALIGNMENT}`, }; case 'heading2': @@ -135,6 +136,7 @@ export const generateDefaultOtherProps = ( fontStyle: `${INPUT_SHAPE.DEFAULT_FONT_STYLE}`, textDecoration: `${INPUT_SHAPE.DEFAULT_TEXT_DECORATION}`, fontSize: FONT_SIZE_VALUES.HEADING2, + textAlignment: `${BASIC_SHAPE.DEFAULT_TEXT_ALIGNMENT}`, }; case 'heading3': return { @@ -143,12 +145,14 @@ export const generateDefaultOtherProps = ( fontStyle: `${INPUT_SHAPE.DEFAULT_FONT_STYLE}`, textDecoration: `${INPUT_SHAPE.DEFAULT_TEXT_DECORATION}`, fontSize: FONT_SIZE_VALUES.HEADING3, + textAlignment: `${BASIC_SHAPE.DEFAULT_TEXT_ALIGNMENT}`, }; case 'link': return { textColor: `${LINK_SHAPE.DEFAULT_FILL_TEXT}`, textDecoration: 'underline', fontSize: FONT_SIZE_VALUES.LINK, + textAlignment: `${BASIC_SHAPE.DEFAULT_TEXT_ALIGNMENT}`, }; case 'normaltext': return { @@ -157,6 +161,7 @@ export const generateDefaultOtherProps = ( fontStyle: `${INPUT_SHAPE.DEFAULT_FONT_STYLE}`, textDecoration: `${INPUT_SHAPE.DEFAULT_TEXT_DECORATION}`, fontSize: FONT_SIZE_VALUES.NORMALTEXT, + textAlignment: `${BASIC_SHAPE.DEFAULT_TEXT_ALIGNMENT}`, }; case 'smalltext': return { @@ -165,10 +170,12 @@ export const generateDefaultOtherProps = ( fontStyle: `${INPUT_SHAPE.DEFAULT_FONT_STYLE}`, textDecoration: `${INPUT_SHAPE.DEFAULT_TEXT_DECORATION}`, fontSize: FONT_SIZE_VALUES.SMALLTEXT, + textAlignment: `${BASIC_SHAPE.DEFAULT_TEXT_ALIGNMENT}`, }; case 'paragraph': return { fontSize: FONT_SIZE_VALUES.PARAGRAPH, + textAlignment: `${BASIC_SHAPE.DEFAULT_TEXT_ALIGNMENT}`, }; case 'label': return { diff --git a/src/pods/properties/components/text-alignment/index.ts b/src/pods/properties/components/text-alignment/index.ts new file mode 100644 index 00000000..e292c99a --- /dev/null +++ b/src/pods/properties/components/text-alignment/index.ts @@ -0,0 +1 @@ +export * from './text-alignment'; diff --git a/src/pods/properties/components/text-alignment/text-alignment.module.css b/src/pods/properties/components/text-alignment/text-alignment.module.css new file mode 100644 index 00000000..4e0a8ade --- /dev/null +++ b/src/pods/properties/components/text-alignment/text-alignment.module.css @@ -0,0 +1,39 @@ +.container { + display: flex; + align-items: center; + gap: 1.5em; + padding: var(--space-xs) var(--space-md); + border-bottom: 1px solid var(--primary-300); +} + +.buttonsContainer { + display: flex; + gap: 1em; + align-items: center; + margin-left: auto; +} + +.button { + border: none; + color: var(--text-color); + background-color: inherit; + width: auto; + min-width: 30px; + border-radius: 10px; + font-size: var(--fs-xs); + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease-in-out; + cursor: pointer; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); +} + +.button:hover { + background-color: var(--primary-100); +} + +.active { + background-color: var(--primary-200); + box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.2); +} diff --git a/src/pods/properties/components/text-alignment/text-alignment.tsx b/src/pods/properties/components/text-alignment/text-alignment.tsx new file mode 100644 index 00000000..a18860be --- /dev/null +++ b/src/pods/properties/components/text-alignment/text-alignment.tsx @@ -0,0 +1,70 @@ +import classes from './text-alignment.module.css'; + +interface Props { + textAlignment: 'left' | 'center' | 'right' | undefined; + label: string; + onChange: (textAlignment: 'left' | 'center' | 'right') => void; +} + +export const TextAlignment: React.FC = props => { + const { label, textAlignment, onChange } = props; + + return ( +
+

{label}

+
+ + + +
+
+ ); +}; diff --git a/src/pods/properties/properties.pod.tsx b/src/pods/properties/properties.pod.tsx index 452577cd..65402ae7 100644 --- a/src/pods/properties/properties.pod.tsx +++ b/src/pods/properties/properties.pod.tsx @@ -13,6 +13,7 @@ import { FontStyle } from './components/font-style'; import { FontVariant } from './components/font-variant/font-variant'; import { TextDecoration } from './components/text-decoration/text-decoration'; import { FontSize } from './components/font-size'; +import { TextAlignment } from './components/text-alignment'; export const PropertiesPod = () => { const { selectionInfo } = useCanvasContext(); @@ -139,6 +140,15 @@ export const PropertiesPod = () => { } /> )} + {selectedShapeData?.otherProps?.textAlignment && ( + + updateOtherPropsOnSelected('textAlignment', textAlignment) + } + /> + )} {selectedShapeData?.otherProps?.fontStyle && ( Date: Wed, 20 Nov 2024 17:55:32 +0100 Subject: [PATCH 2/2] adde center on old verion --- src/core/local-disk/shapes-to-document.mapper.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/local-disk/shapes-to-document.mapper.ts b/src/core/local-disk/shapes-to-document.mapper.ts index d34a23c0..1efb0be6 100644 --- a/src/core/local-disk/shapes-to-document.mapper.ts +++ b/src/core/local-disk/shapes-to-document.mapper.ts @@ -30,6 +30,7 @@ const mapTextElementFromV0_1ToV0_2 = (shape: ShapeModel): ShapeModel => { otherProps: { ...shape, fontSize: FONT_SIZE_VALUES.HEADING1, + textAlignment: 'center', }, }; case 'heading2': @@ -38,6 +39,7 @@ const mapTextElementFromV0_1ToV0_2 = (shape: ShapeModel): ShapeModel => { otherProps: { ...shape, fontSize: FONT_SIZE_VALUES.HEADING2, + textAlignment: 'center', }, }; case 'heading3': @@ -46,6 +48,7 @@ const mapTextElementFromV0_1ToV0_2 = (shape: ShapeModel): ShapeModel => { otherProps: { ...shape, fontSize: FONT_SIZE_VALUES.HEADING3, + textAlignment: 'center', }, }; case 'link': @@ -54,6 +57,7 @@ const mapTextElementFromV0_1ToV0_2 = (shape: ShapeModel): ShapeModel => { otherProps: { ...shape, fontSize: FONT_SIZE_VALUES.LINK, + textAlignment: 'center', }, }; case 'normaltext': @@ -62,6 +66,7 @@ const mapTextElementFromV0_1ToV0_2 = (shape: ShapeModel): ShapeModel => { otherProps: { ...shape, fontSize: FONT_SIZE_VALUES.NORMALTEXT, + textAlignment: 'center', }, }; case 'smalltext': @@ -70,6 +75,7 @@ const mapTextElementFromV0_1ToV0_2 = (shape: ShapeModel): ShapeModel => { otherProps: { ...shape, fontSize: FONT_SIZE_VALUES.SMALLTEXT, + textAlignment: 'center', }, }; case 'paragraph': @@ -78,6 +84,7 @@ const mapTextElementFromV0_1ToV0_2 = (shape: ShapeModel): ShapeModel => { otherProps: { ...shape, fontSize: FONT_SIZE_VALUES.PARAGRAPH, + textAlignment: 'center', }, }; default: