Skip to content

Commit

Permalink
Merge pull request #282 from Lemoncode/feature/#218-creating-AppBar
Browse files Browse the repository at this point in the history
Feature/#218 creating app bar
  • Loading branch information
brauliodiez authored Aug 28, 2024
2 parents 1501fa7 + 4007da4 commit 5960b17
Show file tree
Hide file tree
Showing 16 changed files with 310 additions and 7 deletions.
12 changes: 12 additions & 0 deletions public/rich-components/appBar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 14 additions & 4 deletions src/common/components/front-components/progressbar-shape.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ShapeSizeRestrictions } from '@/core/model';
import { forwardRef } from 'react';
import { forwardRef, useMemo } from 'react';
import { ShapeProps } from './shape.model';
import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions';
import { Group, Rect } from 'react-konva';
Expand All @@ -17,14 +17,24 @@ export const getProgressBarShapeSizeRestrictions = (): ShapeSizeRestrictions =>
progressBarShapeRestrictions;

export const ProgressBarShape = forwardRef<any, ShapeProps>(
({ x, y, width, height, id, onSelected, ...shapeProps }, ref) => {
({ x, y, width, height, id, onSelected, otherProps, ...shapeProps }, 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 progressWidth = useMemo(
() => (progress / 100) * restrictedWidth,
[progress, restrictedWidth]
);

return (
<Group
x={x}
Expand All @@ -51,12 +61,12 @@ export const ProgressBarShape = forwardRef<any, ShapeProps>(
<Rect
x={0}
y={0}
width={restrictedWidth / 2}
width={progressWidth}
height={restrictedHeight}
cornerRadius={10}
stroke="black"
strokeWidth={2}
fill="lightgrey"
fill="green"
/>
</Group>
);
Expand Down
4 changes: 4 additions & 0 deletions src/common/components/front-components/shape.const.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const DEFAULT_CORNER_RADIUS = 4;
const DEFAULT_STROKE_COLOR = '#000000';
const DEFAULT_STROKE_WIDTH = 1;
const DEFAULT_STROKE_STYLE: number[] = [];
const DEFAULT_FILL_BACKGROUND = '#ffffff';
const DEFAULT_FONT_FAMILY = 'Comic Sans MS, cursive';
const DEFAULT_FONT_SIZE = 16;
Expand All @@ -24,6 +25,7 @@ interface DefaultStyleShape {
DEFAULT_LINE_HEIGHT: number;
DEFAULT_TEXT_WIDTH: number;
DEFAULT_TEXT_HEIGHT: number;
DEFAULT_STROKE_STYLE: number[];
}

export const BASIC_SHAPE: DefaultStyleShape = {
Expand All @@ -38,6 +40,7 @@ export const BASIC_SHAPE: DefaultStyleShape = {
DEFAULT_LINE_HEIGHT,
DEFAULT_TEXT_WIDTH,
DEFAULT_TEXT_HEIGHT,
DEFAULT_STROKE_STYLE,
};

export const INPUT_SHAPE: DefaultStyleShape = {
Expand All @@ -52,6 +55,7 @@ export const INPUT_SHAPE: DefaultStyleShape = {
DEFAULT_LINE_HEIGHT,
DEFAULT_TEXT_WIDTH,
DEFAULT_TEXT_HEIGHT,
DEFAULT_STROKE_STYLE,
};

//! maybe a function to calc max height base on the text
137 changes: 137 additions & 0 deletions src/common/components/front-rich-components/appBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { forwardRef, useMemo } from 'react';
import { Group, Rect, Text } from 'react-konva';
import { ShapeProps } from '../front-components/shape.model';
import { ShapeSizeRestrictions } from '@/core/model';
import { BASIC_SHAPE } from '../front-components/shape.const';
import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions';

const AppBarShapeSizeRestrictions: ShapeSizeRestrictions = {
minWidth: 155,
minHeight: 38,
maxWidth: -1,
maxHeight: -1,
defaultWidth: 250,
defaultHeight: BASIC_SHAPE.DEFAULT_TEXT_HEIGHT,
};

export const getAppBarShapeSizeRestrictions = (): ShapeSizeRestrictions =>
AppBarShapeSizeRestrictions;

export const AppBarShape = forwardRef<any, ShapeProps>(
(
{
x,
y,
width,
height,
title,
id,
text,
otherProps,
onSelected,
...shapeProps
},
ref
) => {
const { width: restrictedWidth, height: restrictedHeight } =
fitSizeToShapeSizeRestrictions(
AppBarShapeSizeRestrictions,
width,
height
);

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;

const barHeight = 3; // Height bar
const barSpacing = 2; // Space between bars
const totalIconHeight = 3 * barHeight + 2 * barSpacing; // Total height including spacing

return (
<Group
x={x}
y={y}
ref={ref}
width={restrictedWidth}
height={restrictedHeight}
{...shapeProps}
onClick={() => onSelected(id, 'appBar')}
>
{/* AppBar background */}
<Rect
x={0}
y={0}
width={width}
height={height}
fill={fill}
stroke={stroke}
dash={strokeStyle}
strokeWidth={BASIC_SHAPE.DEFAULT_STROKE_WIDTH}
/>

{/* Menu Icon */}
<Rect
x={iconPadding}
y={(height - totalIconHeight) / 2}
width={iconWidth}
height={barHeight}
fill="lightgrey"
/>
<Rect
x={iconPadding}
y={(height - totalIconHeight) / 2 + barHeight + barSpacing}
width={iconWidth}
height={barHeight}
fill="lightgrey"
/>
<Rect
x={iconPadding}
y={(height - totalIconHeight) / 2 + 2 * (barHeight + barSpacing)}
width={iconWidth}
height={barHeight}
fill="lightgrey"
/>

{/* AppBar title */}
<Text
x={textStartX}
y={restrictedHeight / 2 - 7}
width={textWidth}
text={text}
fontFamily={BASIC_SHAPE.DEFAULT_FONT_FAMILY}
fontSize={BASIC_SHAPE.DEFAULT_FONT_SIZE}
fill={textColor}
align="center"
ellipsis={true}
wrap="none"
/>
</Group>
);
}
);

export default AppBarShape;
1 change: 1 addition & 0 deletions src/common/components/front-rich-components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './vertical-menu/vertical-menu';
export * from './calendar/calendar';
export * from './table/table';
export * from './modal/modal';
export * from './appBar';
5 changes: 4 additions & 1 deletion src/core/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ export type ShapeType =
| 'table'
| 'verticalScrollBar'
| 'horizontalScrollBar'
| 'modal';
| 'modal'
| 'appBar';

export const ShapeDisplayName: Record<ShapeType, string> = {
combobox: 'Combobox',
Expand Down Expand Up @@ -106,6 +107,7 @@ export const ShapeDisplayName: Record<ShapeType, string> = {
calendar: 'Calendar',
verticalScrollBar: 'Vertical Scroll Bar',
modal: 'Modal',
appBar: 'AppBar',
};

export type EditType = 'input' | 'textarea' | 'imageupload';
Expand Down Expand Up @@ -144,6 +146,7 @@ export interface OtherProps {
icon?: IconInfo;
iconSize?: IconSize;
imageSrc?: string;
progress?: string;
}

export const BASE_ICONS_URL = '/icons/';
Expand Down
22 changes: 20 additions & 2 deletions src/pods/canvas/canvas.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import {
getCalendarShapeSizeRestrictions,
getTableSizeRestrictions,
getModalShapeSizeRestrictions,
getAppBarShapeSizeRestrictions,
} from '@/common/components/front-rich-components';
import {
getHeading1SizeRestrictions,
Expand Down Expand Up @@ -88,9 +89,8 @@ export const getSizeRestrictionFromShape = (
return getDatepickerInputShapeSizeRestrictions();
case 'button':
return getButtonShapeSizeRestrictions();
case 'progressbar': {
case 'progressbar':
return getProgressBarShapeSizeRestrictions();
}
case 'listbox':
return getListboxShapeSizeRestrictions();
case 'browser':
Expand Down Expand Up @@ -167,6 +167,8 @@ export const getSizeRestrictionFromShape = (
return getVerticalScrollBarShapeSizeRestrictions();
case 'modal':
return getModalShapeSizeRestrictions();
case 'appBar':
return getAppBarShapeSizeRestrictions();
default:
console.warn(
`** Shape ${shapeType} has not defined default size, check getDefaultSizeFromShape helper function`
Expand Down Expand Up @@ -220,6 +222,7 @@ const doesShapeAllowInlineEdition = (shapeType: ShapeType): boolean => {
case 'image':
case 'table':
case 'modal':
case 'appBar':
return true;
default:
return false;
Expand Down Expand Up @@ -248,6 +251,7 @@ const generateTypeOfTransformer = (shapeType: ShapeType): string[] => {
case 'normaltext':
case 'smalltext':
case 'horizontalScrollBar':
case 'appBar':
return ['middle-left', 'middle-right'];
case 'verticalScrollBar':
return ['top-center', 'bottom-center'];
Expand Down Expand Up @@ -311,6 +315,8 @@ const generateDefaultTextValue = (shapeType: ShapeType): string | undefined => {
return 'Name ^, Age ^v, Country v\nJohn Doe, 30, USA\nJane Smith, 25, UK\nLuis Gomez, 35, Argentina\n{*L,20R,30C}';
case 'modal':
return 'Alert\nWarning: The action you are about to perform may affect existing data. Are you sure you want to proceed? Once confirmed, this action cannot be undone.\nConfirm,Cancel';
case 'appBar':
return 'AppBar';
default:
return undefined;
}
Expand All @@ -330,6 +336,7 @@ const getShapeEditInlineType = (shapeType: ShapeType): EditType | undefined => {
case 'vertical-menu':
case 'table':
case 'modal':
case 'appBar':
return 'textarea';
break;
case 'image':
Expand Down Expand Up @@ -415,6 +422,13 @@ export const generateDefaultOtherProps = (
textColor: '#000000',
};

case 'appBar':
return {
stroke: BASIC_SHAPE.DEFAULT_STROKE_COLOR,
backgroundColor: '#A9A9A9',
textColor: '#ffffff',
strokeStyle: [],
};
case 'icon':
return {
icon: {
Expand All @@ -425,6 +439,10 @@ export const generateDefaultOtherProps = (
},
iconSize: 'M',
};
case 'progressbar':
return {
progress: '50',
};
default:
return undefined;
}
Expand Down
3 changes: 3 additions & 0 deletions src/pods/canvas/shape-renderer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import { renderSmalltext } from './simple-text-components/smalltext.renderer';
import { renderParagraph } from './simple-text-components/paragraph.renderer';
import { renderImage } from './simple-basic-shapes/image.renderer';
import { renderCalendar } from './simple-rich-components/calendar.renderer';
import { renderAppBar } from './simple-rich-components/appBar.renderer';

export const renderShapeComponent = (
shape: ShapeModel,
Expand Down Expand Up @@ -155,6 +156,8 @@ export const renderShapeComponent = (
return renderVerticalScrollBar(shape, shapeRenderedProps);
case 'modal':
return renderModal(shape, shapeRenderedProps);
case 'appBar':
return renderAppBar(shape, shapeRenderedProps);
default:
return renderNotFound(shape, shapeRenderedProps);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { AppBarShape } from '@/common/components/front-rich-components/appBar';
import { ShapeRendererProps } from '../model';
import { ShapeModel } from '@/core/model';

export const renderAppBar = (
shape: ShapeModel,
shapeRenderedProps: ShapeRendererProps
) => {
const { handleSelected, shapeRefs, handleDragEnd, handleTransform } =
shapeRenderedProps;

return (
<AppBarShape
id={shape.id}
key={shape.id}
x={shape.x}
y={shape.y}
width={shape.width}
height={shape.height}
name="shape"
draggable
typeOfTransformer={shape.typeOfTransformer}
onSelected={handleSelected}
ref={shapeRefs.current[shape.id]}
onDragEnd={handleDragEnd(shape.id)}
onTransform={handleTransform}
onTransformEnd={handleTransform}
isEditable={shape.allowsInlineEdition}
text={shape.text}
otherProps={shape.otherProps}
/>
);
};
Loading

0 comments on commit 5960b17

Please sign in to comment.