diff --git a/public/rich-components/input-stepper.svg b/public/rich-components/input-stepper.svg
new file mode 100644
index 00000000..be747f48
--- /dev/null
+++ b/public/rich-components/input-stepper.svg
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/src/common/components/mock-components/front-rich-components/horizontal-menu/horizontal-menu.tsx b/src/common/components/mock-components/front-rich-components/horizontal-menu/horizontal-menu.tsx
index c50151b1..39121266 100644
--- a/src/common/components/mock-components/front-rich-components/horizontal-menu/horizontal-menu.tsx
+++ b/src/common/components/mock-components/front-rich-components/horizontal-menu/horizontal-menu.tsx
@@ -10,7 +10,6 @@ import {
splitCSVContentIntoRows,
} from '@/common/utils/active-element-selector.utils';
import { useGroupShapeProps } from '../../mock-components.utils';
-import { useResizeOnFontSizeChange } from '../../front-text-components/front-text-hooks/resize-fontsize-change.hook';
const horizontalMenuShapeSizeRestrictions: ShapeSizeRestrictions = {
minWidth: 200,
@@ -42,7 +41,7 @@ export const HorizontalMenu = forwardRef((props, ref) => {
const csvData = splitCSVContentIntoRows(text);
const headers = extractCSVHeaders(csvData[0]);
const itemLabels = headers.map(header => header.text);
- const verticalPadding = 8;
+
const numberOfItems = itemLabels.length;
const itemSpacing = 10;
@@ -55,15 +54,10 @@ export const HorizontalMenu = forwardRef((props, ref) => {
const totalMargins = restrictedWidth - itemSpacing * (numberOfItems + 1);
const itemWidth = totalMargins / numberOfItems;
- const {
- stroke,
- strokeStyle,
- fill,
- textColor,
- borderRadius,
- fontSize,
- fontVariant,
- } = useShapeProps(otherProps, BASIC_SHAPE);
+ const { stroke, strokeStyle, fill, textColor, borderRadius } = useShapeProps(
+ otherProps,
+ BASIC_SHAPE
+ );
const itemVerticalPadding = 4;
@@ -75,7 +69,7 @@ export const HorizontalMenu = forwardRef((props, ref) => {
shapeType,
ref
);
- useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant);
+
return (
((props, ref) => {
x={itemSpacing * (index + 1) + itemWidth * index}
y={itemVerticalPadding}
width={itemWidth}
- height={restrictedHeight - verticalPadding}
+ height={restrictedHeight - 2 * itemVerticalPadding}
fill={index === activeSelected ? 'lightblue' : fill}
/>
))}
diff --git a/src/common/components/mock-components/front-rich-components/index.ts b/src/common/components/mock-components/front-rich-components/index.ts
index b1e5f180..0ef87edb 100644
--- a/src/common/components/mock-components/front-rich-components/index.ts
+++ b/src/common/components/mock-components/front-rich-components/index.ts
@@ -2,6 +2,7 @@ export * from './accordion';
export * from './breadcrumb/breadcrumb';
export * from './pie-chart';
export * from './horizontal-menu/horizontal-menu';
+export * from './input-stepper';
export * from './map-chart';
export * from './video-player';
export * from './bar-chart';
diff --git a/src/common/components/mock-components/front-rich-components/input-stepper.tsx b/src/common/components/mock-components/front-rich-components/input-stepper.tsx
new file mode 100644
index 00000000..9d60dd2a
--- /dev/null
+++ b/src/common/components/mock-components/front-rich-components/input-stepper.tsx
@@ -0,0 +1,127 @@
+import { forwardRef } from 'react';
+import { Group, Rect, Text } from 'react-konva';
+import { ShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions';
+import { useGroupShapeProps } from '../mock-components.utils';
+import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions';
+import { ShapeType } from '@/core/model';
+import { ShapeProps } from '../shape.model';
+import { useShapeProps } from '../../shapes/use-shape-props.hook';
+import { INPUT_SHAPE } from '../front-components/shape.const';
+
+// Size restrictions (igual patrón que file-tree)
+export const inputStepperShapeRestrictions: ShapeSizeRestrictions = {
+ minWidth: 80,
+ minHeight: 24,
+ maxWidth: -1,
+ maxHeight: -1,
+ defaultWidth: 120,
+ defaultHeight: 32,
+};
+
+export const getInputStepperShapeSizeRestrictions = (): ShapeSizeRestrictions =>
+ inputStepperShapeRestrictions;
+
+export const InputWithStepper = forwardRef((props, ref) => {
+ const { x, y, width, height, text, onSelect, otherProps, id, ...shapeProps } =
+ props;
+
+ const inputWidth = width - 30; // Reservar espacio para el stepper
+ const buttonHeight = height / 2;
+
+ const restrictedSize = fitSizeToShapeSizeRestrictions(
+ inputStepperShapeRestrictions,
+ width,
+ height
+ );
+
+ const shapeType: ShapeType = 'input-stepper';
+
+ const commonGroupProps = useGroupShapeProps(
+ props,
+ restrictedSize,
+ shapeType,
+ ref
+ );
+ const { stroke, textColor, strokeStyle, fill, strokeWidth } = useShapeProps(
+ otherProps,
+ INPUT_SHAPE
+ );
+
+ const { width: restrictedWidth } = restrictedSize;
+
+ return (
+
+ {/* Caja del input */}
+
+
+ {/* Texto del input */}
+
+
+ {/* Botón de incremento (flecha arriba) */}
+
+
+
+
+
+ {/* Botón de decremento (flecha abajo) */}
+
+
+
+
+
+ );
+});
+
+export default InputWithStepper;
diff --git a/src/core/model/index.ts b/src/core/model/index.ts
index bf189305..f2dbc4b4 100644
--- a/src/core/model/index.ts
+++ b/src/core/model/index.ts
@@ -38,6 +38,7 @@ export type ShapeType =
| 'accordion'
| 'pie'
| 'horizontal-menu'
+ | 'input-stepper'
| 'breadcrumb'
| 'map'
| 'circle'
@@ -130,6 +131,7 @@ export const ShapeDisplayName: Record = {
link: 'Link',
triangle: 'Triangle',
'horizontal-menu': 'Horizontal Menu',
+ 'input-stepper': 'Input Stepper',
largeArrow: 'Large Arrow',
icon: 'Icon',
bar: 'Bar Chart',
@@ -238,3 +240,8 @@ export interface ShapeModel {
text?: string;
otherProps?: OtherProps;
}
+
+export interface inputStepper {
+ id: string;
+ min: number;
+}
diff --git a/src/pods/canvas/model/inline-editable.model.ts b/src/pods/canvas/model/inline-editable.model.ts
index bc99eecc..cbdf7709 100644
--- a/src/pods/canvas/model/inline-editable.model.ts
+++ b/src/pods/canvas/model/inline-editable.model.ts
@@ -40,6 +40,7 @@ const inlineEditableShapes = new Set([
'gauge',
'loading-indicator',
'fileTree',
+ 'input-stepper',
]);
// Check if a shape type allows inline editing
@@ -62,6 +63,7 @@ const shapeTypesWithDefaultText = new Set([
'listbox',
'horizontal-menu',
'vertical-menu',
+ 'input-stepper',
'heading1',
'heading2',
'heading3',
@@ -125,6 +127,7 @@ const defaultTextValueMap: Partial> = {
browser: 'https://example.com',
modalDialog: 'Title here...',
'loading-indicator': 'Loading...',
+ 'input-stepper': '0',
};
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 6e06de10..8ad7a6d3 100644
--- a/src/pods/canvas/model/shape-other-props.utils.ts
+++ b/src/pods/canvas/model/shape-other-props.utils.ts
@@ -48,8 +48,13 @@ export const generateDefaultOtherProps = (
strokeStyle: [],
borderRadius: `${BASIC_SHAPE.DEFAULT_CORNER_RADIUS}`,
activeElement: 0,
- fontSize: FONT_SIZE_VALUES.NORMALTEXT,
- fontVariant: `${INPUT_SHAPE.DEFAULT_FONT_VARIANT}`,
+ };
+ case 'input-stepper':
+ return {
+ stroke: INPUT_SHAPE.DEFAULT_STROKE_COLOR,
+ backgroundColor: INPUT_SHAPE.DEFAULT_FILL_BACKGROUND,
+ textColor: INPUT_SHAPE.DEFAULT_FILL_TEXT,
+ strokeStyle: [],
};
case 'datepickerinput':
case 'timepickerinput':
diff --git a/src/pods/canvas/model/shape-size.mapper.ts b/src/pods/canvas/model/shape-size.mapper.ts
index 3c4ea531..19dcbf18 100644
--- a/src/pods/canvas/model/shape-size.mapper.ts
+++ b/src/pods/canvas/model/shape-size.mapper.ts
@@ -1,5 +1,6 @@
// src/common/shape-utils/shapeSizeMap.ts
import { ShapeType, ShapeSizeRestrictions } from '@/core/model';
+import { getInputStepperShapeSizeRestrictions } from '@/common/components/mock-components/front-rich-components/input-stepper';
import {
getButtonShapeSizeRestrictions,
getCheckboxShapeSizeRestrictions,
@@ -128,6 +129,7 @@ const shapeSizeMap: Record ShapeSizeRestrictions> = {
postit: getPostItShapeSizeRestrictions,
pie: getPieChartShapeSizeRestrictions,
'horizontal-menu': getHorizontalMenuShapeSizeRestrictions,
+ 'input-stepper': getInputStepperShapeSizeRestrictions,
'vertical-menu': getVerticalMenuShapeSizeRestrictions,
breadcrumb: getBreadcrumbShapeSizeRestrictions,
map: getMapChartShapeSizeRestrictions,
@@ -172,9 +174,9 @@ const shapeSizeMap: Record ShapeSizeRestrictions> = {
rectangleLow: getRectangleLowShapeRestrictions,
circleLow: getCircleLowShapeSizeRestrictions,
textScribbled: getTextScribbledShapeRestrictions,
- paragraphScribbled: getParagraphScribbledShapeRestrictions,
fabButton: getFabButtonShapeSizeRestrictions,
fileTree: getFileTreeShapeSizeRestrictions,
+ paragraphScribbled: getParagraphScribbledShapeRestrictions,
};
export default shapeSizeMap;
diff --git a/src/pods/canvas/model/transformer.model.ts b/src/pods/canvas/model/transformer.model.ts
index bf601b42..e6a71e22 100644
--- a/src/pods/canvas/model/transformer.model.ts
+++ b/src/pods/canvas/model/transformer.model.ts
@@ -71,6 +71,7 @@ export const generateTypeOfTransformer = (shapeType: ShapeType): string[] => {
case 'buttonBar':
case 'slider':
case 'chip':
+ case 'input-stepper':
return ['middle-left', 'middle-right'];
case 'verticalLine':
case 'verticalScrollBar':
diff --git a/src/pods/canvas/shape-renderer/index.tsx b/src/pods/canvas/shape-renderer/index.tsx
index 37a59949..62cdc417 100644
--- a/src/pods/canvas/shape-renderer/index.tsx
+++ b/src/pods/canvas/shape-renderer/index.tsx
@@ -29,6 +29,7 @@ import {
} from './simple-container';
import {
renderVideoPlayer,
+ renderInputStepper,
renderAccordion,
renderHorizontalMenu,
renderPieChart,
@@ -153,6 +154,8 @@ export const renderShapeComponent = (
return renderTriangle(shape, shapeRenderedProps);
case 'horizontal-menu':
return renderHorizontalMenu(shape, shapeRenderedProps);
+ case 'input-stepper':
+ return renderInputStepper(shape, shapeRenderedProps);
case 'vertical-menu':
return renderVerticalMenuShape(shape, shapeRenderedProps);
case 'breadcrumb':
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 2a32d3d1..48b03e78 100644
--- a/src/pods/canvas/shape-renderer/simple-rich-components/index.ts
+++ b/src/pods/canvas/shape-renderer/simple-rich-components/index.ts
@@ -6,6 +6,7 @@ export * from './breadcrumb.renderer';
export * from './button-bar.renderer';
export * from './calendar.renderer';
export * from './horizontal-menu.renderer';
+export * from './input-stepper.renderer';
export * from './line-chart.renderer';
export * from './map-chart.renderer';
export * from './table.renderer';
diff --git a/src/pods/canvas/shape-renderer/simple-rich-components/input-stepper.renderer.tsx b/src/pods/canvas/shape-renderer/simple-rich-components/input-stepper.renderer.tsx
new file mode 100644
index 00000000..2cbc2e8f
--- /dev/null
+++ b/src/pods/canvas/shape-renderer/simple-rich-components/input-stepper.renderer.tsx
@@ -0,0 +1,32 @@
+import { InputWithStepper } from '@/common/components/mock-components/front-rich-components/input-stepper';
+import { ShapeRendererProps } from '../model';
+import { ShapeModel } from '@/core/model';
+
+export const renderInputStepper = (
+ shape: ShapeModel,
+ shapeRenderedProps: ShapeRendererProps
+) => {
+ const { handleSelected, shapeRefs, handleDragEnd, handleTransform } =
+ shapeRenderedProps;
+
+ return (
+
+ );
+};
diff --git a/src/pods/galleries/rich-components-gallery/rich-components-gallery-data/index.ts b/src/pods/galleries/rich-components-gallery/rich-components-gallery-data/index.ts
index b44eee90..a96a8ca5 100644
--- a/src/pods/galleries/rich-components-gallery/rich-components-gallery-data/index.ts
+++ b/src/pods/galleries/rich-components-gallery/rich-components-gallery-data/index.ts
@@ -44,4 +44,8 @@ export const mockRichComponentsCollection: ItemInfo[] = [
thumbnailSrc: '/rich-components/file-tree.svg',
type: 'fileTree',
},
+ {
+ thumbnailSrc: '/rich-components/input-stepper.svg',
+ type: 'input-stepper',
+ },
];