Skip to content

Create an input stepper component (place it under rich components) #216

Open
@brauliodiez

Description

@brauliodiez
image
<svg width="120" height="50" xmlns="http://www.w3.org/2000/svg">
  <!-- Caja del input -->
  <rect x="10" y="10" width="60" height="30" style="fill:white;stroke:black;stroke-width:2"/>

  <!-- Texto del input -->
  <text x="60" y="30" font-family="Arial" font-size="16" fill="black" text-anchor="end">0</text>

  <!-- Botón de incremento (flecha arriba) -->
  <rect x="70" y="10" width="20" height="15" style="fill:lightgray;stroke:black;stroke-width:2"/>
  <text x="77" y="22" font-family="Arial" font-size="14" fill="black">▲</text>

  <!-- Botón de decremento (flecha abajo) -->
  <rect x="70" y="25" width="20" height="15" style="fill:lightgray;stroke:black;stroke-width:2"/>
  <text x="77" y="37" font-family="Arial" font-size="14" fill="black">▼</text>
</svg>

Tsx (just take it as starting point):

import React, { useState, forwardRef } from 'react';
import { Group, Rect, Text } from 'react-konva';
import { ShapeConfig } from 'konva/lib/Shape';

interface InputWithStepperProps extends ShapeConfig {
  id: string;
  x: number;
  y: number;
  width: number;
  height: number;
  initialValue?: number;
}

export const InputWithStepper = forwardRef<any, InputWithStepperProps>(
  ({ x, y, width, height, initialValue = 0, id, ...shapeProps }, ref) => {
    const [value, setValue] = useState(initialValue);

    const handleIncrement = () => {
      setValue(value + 1);
    };

    const handleDecrement = () => {
      setValue(value - 1);
    };

    const inputWidth = width - 30;  // Reservar espacio para el stepper
    const buttonHeight = height / 2;

    return (
      <Group x={x} y={y} ref={ref} {...shapeProps}>
        {/* Caja del input */}
        <Rect
          x={0}
          y={0}
          width={inputWidth / 2}  // Reducir ancho a la mitad
          height={height}
          fill="white"
          stroke="black"
          strokeWidth={2}
          cornerRadius={0}  // Sin bordes redondeados
        />

        {/* Texto del input */}
        <Text
          x={inputWidth / 2 - 10}  // Alinear a la derecha
          y={height / 2 - 8}  // Centrar verticalmente
          text={value.toString()}
          fontFamily="Arial"
          fontSize={16}
          fill="black"
          align="right"
        />

        {/* Botón de incremento (flecha arriba) */}
        <Group x={inputWidth / 2} y={0} onClick={handleIncrement}>
          <Rect
            x={0}
            y={0}
            width={30}
            height={buttonHeight}
            fill="lightgray"
            stroke="black"
            strokeWidth={2}
          />
          <Text
            x={10}
            y={buttonHeight / 2 - 8}
            text="▲"
            fontFamily="Arial"
            fontSize={14}
            fill="black"
          />
        </Group>

        {/* Botón de decremento (flecha abajo) */}
        <Group x={inputWidth / 2} y={buttonHeight} onClick={handleDecrement}>
          <Rect
            x={0}
            y={0}
            width={30}
            height={buttonHeight}
            fill="lightgray"
            stroke="black"
            strokeWidth={2}
          />
          <Text
            x={10}
            y={buttonHeight / 2 - 8}
            text="▼"
            fontFamily="Arial"
            fontSize={14}
            fill="black"
          />
        </Group>
      </Group>
    );
  }
);

export default InputWithStepper;

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

In Review

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions