import * as React from 'react'; import { createFormattedNumberInput } from 'react-formatted-number-input'; import { formatMoney } from '../../../formatters'; import { Slider } from '../Slider'; import styled from '../../../'; const Minus = () => ( ); const Plus = () => ( ); const Container = styled.div({ marginBottom: '3em', }); const InputContainer = styled.div(({ theme }) => ({ border: `1px solid ${theme.colors.mediumGray}`, borderRadius: theme.borderRadius.small, display: 'flex', height: 70, position: 'relative', zIndex: 2, marginBottom: '1em', })); const Input = styled.input(({ theme }) => ({ appearance: 'none', boxShadow: 'none', border: `solid ${theme.colors.mediumGray}`, borderWidth: '0 1px', borderRadius: 0, textAlign: 'center', width: '100%', flex: '80% 1 1', font: theme.fonts.desktop.xl, [theme.breakpoints.mobileAndLower]: { font: theme.fonts.mobile.xl, }, '::-ms-clear': { display: 'none', }, })); const AmountInput = createFormattedNumberInput(Input); const Button = styled.button(({ theme }) => ({ fontFamily: 'inherit', background: 'transparent', border: 0, display: 'flex', justifyContent: 'center', alignItems: 'center', flexShrink: 0, width: 55, fontSize: 40, padding: 0, cursor: 'pointer', borderRadius: theme.borderRadius.small, transition: 'background-color 100ms', color: theme.colors.black, ':hover': { background: theme.colors.offWhite, }, })); const Range = styled.div(({ theme }) => ({ display: 'flex', justifyContent: 'space-between', font: theme.fonts.desktop.medium, [theme.breakpoints.mobileAndLower]: { font: theme.fonts.mobile.medium, }, })); interface Props { currency: string; min: number; max: number; value: number; onChange: (value: number) => void; stepSize: number; } interface State { isDrafting: boolean; draftValue?: number; } export class AmountSelector extends React.Component { static displayName = 'Collector.AmountSelector'; state: State = { isDrafting: false, }; private increase = () => { const remainder = this.props.value % this.props.stepSize; const value = remainder > 0 ? this.props.value + this.props.stepSize - remainder : this.props.value + this.props.stepSize; this.props.onChange(Math.min(value, this.props.max)); }; private decrease = () => { const remainder = this.props.value % this.props.stepSize; const value = remainder > 0 ? this.props.value - remainder : this.props.value - this.props.stepSize; this.props.onChange(Math.max(value, this.props.min)); }; private handleRangeInputChange = (event: React.FormEvent) => { const middle = this.props.max - this.props.min; let value = Number(event.currentTarget.value); if (value > middle) { value = Math.ceil(value / this.props.stepSize) * this.props.stepSize; value = Math.min(value, this.props.max); } else { value = Math.floor(value / this.props.stepSize) * this.props.stepSize; value = Math.max(value, this.props.min); } this.props.onChange(value); }; private changeDraftValue = (draftValue: number) => { this.setState({ isDrafting: true, draftValue, }); }; private commitDraftValue = () => { if (this.state.isDrafting && this.state.draftValue != null) { const normalized = this.clampAndRound(this.state.draftValue); this.props.onChange(normalized); this.setState({ isDrafting: false, draftValue: undefined, }); } }; private clampAndRound = (value: number) => { if (value <= this.props.min) { return this.props.min; } else if (value >= this.props.max) { return this.props.max; } else { return Math.round(value / this.props.stepSize) * this.props.stepSize; } }; render() { const { min, max, value, currency } = this.props; const { isDrafting, draftValue } = this.state; return (
{formatMoney(min, currency, false)}
{formatMoney(max, currency, false)}
); } }