better number handling

This commit is contained in:
Nate Kelley 2025-03-31 15:27:15 -06:00
parent 7111f9e110
commit e839b630ee
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
2 changed files with 97 additions and 1 deletions

View File

@ -0,0 +1,94 @@
import type { Meta, StoryObj } from '@storybook/react';
import { InputNumber } from './InputNumber';
const meta: Meta<typeof InputNumber> = {
title: 'UI/Inputs/InputNumber',
component: InputNumber,
tags: ['autodocs'],
argTypes: {
disabled: {
control: 'boolean'
},
value: {
control: 'number'
},
onChange: { action: 'changed' },
min: {
control: 'number'
},
max: {
control: 'number'
},
step: {
control: 'number'
},
size: {
control: 'select',
options: ['default', 'tall', 'small']
},
variant: {
control: 'select',
options: ['default', 'ghost']
}
}
};
export default meta;
type Story = StoryObj<typeof InputNumber>;
export const Default: Story = {
args: {
placeholder: 'Enter number...'
}
};
export const WithValue: Story = {
args: {
value: 42,
placeholder: 'Enter number...'
}
};
export const WithMinMax: Story = {
args: {
min: 0,
max: 100,
placeholder: 'Enter number (0-100)...'
}
};
export const WithStep: Story = {
args: {
step: 5,
placeholder: 'Enter number (step: 5)...'
}
};
export const Disabled: Story = {
args: {
disabled: true,
value: 42,
placeholder: 'Disabled number input'
}
};
export const Small: Story = {
args: {
size: 'small',
placeholder: 'Small number input...'
}
};
export const Tall: Story = {
args: {
size: 'tall',
placeholder: 'Tall number input...'
}
};
export const Ghost: Story = {
args: {
variant: 'ghost',
placeholder: 'Ghost number input...'
}
};

View File

@ -1,6 +1,7 @@
import React from 'react';
import { Input, InputProps } from './Input';
import { useMemoizedFn } from '@/hooks';
import { cn } from '@/lib/classMerge';
export interface InputNumberProps extends Omit<InputProps, 'type' | 'value' | 'onChange'> {
value?: number;
@ -11,7 +12,7 @@ export interface InputNumberProps extends Omit<InputProps, 'type' | 'value' | 'o
}
export const InputNumber = React.forwardRef<HTMLInputElement, InputNumberProps>(
({ value, onChange, min, max, step = 1, ...props }, ref) => {
({ value, onChange, min, max, step = 1, className, ...props }, ref) => {
const handleChange = useMemoizedFn((e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = parseFloat(e.target.value);
@ -42,6 +43,7 @@ export const InputNumber = React.forwardRef<HTMLInputElement, InputNumberProps>(
max={max}
step={step}
ref={ref}
className={cn('pr-0.5', className)}
{...props}
/>
);