import {forwardRef, useRef} from 'react'; import styled from '@emotion/styled'; import {useButton} from '@react-aria/button'; import {useLocale} from '@react-aria/i18n'; import {AriaNumberFieldProps, useNumberField} from '@react-aria/numberfield'; import {useNumberFieldState} from '@react-stately/numberfield'; import {Button} from 'sentry/components/button'; import {InputStylesProps} from 'sentry/components/input'; import {InputGroup} from 'sentry/components/inputGroup'; import {IconChevron} from 'sentry/icons/iconChevron'; import {space} from 'sentry/styles/space'; import mergeRefs from 'sentry/utils/mergeRefs'; import {FormSize} from 'sentry/utils/theme'; export interface NumberInputProps extends InputStylesProps, AriaNumberFieldProps, Pick< React.InputHTMLAttributes, 'name' | 'disabled' | 'readOnly' | 'required' | 'className' > { max?: number; min?: number; } function BaseNumberInput( { disabled, readOnly, monospace, min, max, size, placeholder, nativeSize, className, ...props }: NumberInputProps, forwardedRef: React.Ref ) { const ref = useRef(null); const ariaProps = { isDisabled: disabled, isReadOnly: readOnly, minValue: min, maxValue: max, placeholder, ...props, }; const {locale} = useLocale(); const state = useNumberFieldState({locale, ...ariaProps}); const {groupProps, inputProps, incrementButtonProps, decrementButtonProps} = useNumberField(ariaProps, state, ref); const incrementButtonRef = useRef(null); const {buttonProps: incrementProps} = useButton( incrementButtonProps, incrementButtonRef ); const decrementButtonRef = useRef(null); const {buttonProps: decrementProps} = useButton( decrementButtonProps, decrementButtonRef ); return ( ); } const NumberInput = forwardRef(BaseNumberInput); export default NumberInput; const StepWrap = styled('div')<{size?: FormSize}>` display: flex; flex-direction: column; align-items: center; width: ${space(1.5)}; height: ${p => (p.size === 'xs' ? '1rem' : '1.25rem')}; `; const StepButton = styled(Button)` display: flex; height: 50%; padding: 0 ${space(0.25)}; color: ${p => p.theme.subText}; `; const StyledIconChevron = styled(IconChevron)` width: 0.5rem; height: 0.5rem; `;