{"version":3,"file":"SpinInput.mjs","names":[],"sources":["../../../src/components/SpinInput/SpinInput.tsx"],"sourcesContent":["import { clamp } from '@mantine/hooks';\nimport { padTime } from '../TimePicker/utils/pad-time/pad-time';\n\ninterface SpinInputProps extends Omit<React.ComponentProps<'input'>, 'onChange' | 'value'> {\n  value: number | null;\n  min: number;\n  max: number;\n  onChange: (value: number | null) => void;\n  focusable: boolean;\n  step: number;\n  onNextInput?: () => void;\n  onPreviousInput?: () => void;\n  allowTemporaryZero?: boolean;\n  placeholder?: string;\n  disableAutoAdvance?: boolean;\n}\n\nconst getMaxDigit = (max: number) => Number(max.toFixed(0)[0]);\n\nexport function SpinInput({\n  value,\n  min,\n  max,\n  onChange,\n  focusable,\n  step,\n  onNextInput,\n  onPreviousInput,\n  onFocus,\n  readOnly,\n  allowTemporaryZero = false,\n  placeholder = '--',\n  disableAutoAdvance = false,\n  ...others\n}: SpinInputProps) {\n  const hasMax = Number.isFinite(max);\n  const maxDigit = hasMax ? getMaxDigit(max) : Infinity;\n  const arrowsMax = hasMax ? max + 1 - step : max;\n\n  const handleChange = (value: string) => {\n    if (readOnly) {\n      return;\n    }\n\n    const clearValue = value.replace(/\\D/g, '');\n    if (clearValue !== '') {\n      let parsedValue = 0;\n      for (let i = 0; i < clearValue.length; i += 1) {\n        const digit = clearValue.charCodeAt(i) - 48;\n        const next = parsedValue * 10 + digit;\n        parsedValue = next > max ? digit : next;\n      }\n\n      const clampedValue =\n        allowTemporaryZero && parsedValue === 0 && min > 0 ? 0 : clamp(parsedValue, min, max);\n\n      onChange(clampedValue);\n\n      if (!disableAutoAdvance && (clampedValue > maxDigit || value.startsWith('00'))) {\n        onNextInput?.();\n      }\n    }\n  };\n\n  const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n    if (readOnly) {\n      return;\n    }\n\n    if (event.key === '0' || event.key === 'Num0') {\n      const { selectionStart, selectionEnd, value: inputValue } = event.currentTarget;\n      const isEntireValueSelected =\n        inputValue.length > 0 && selectionStart === 0 && selectionEnd === inputValue.length;\n\n      if (value === 0 && !isEntireValueSelected) {\n        event.preventDefault();\n        onNextInput?.();\n      }\n    }\n\n    if (event.key === 'Home') {\n      event.preventDefault();\n      onChange(min);\n    }\n\n    if (event.key === 'End' && hasMax) {\n      event.preventDefault();\n      onChange(max);\n    }\n\n    if (event.key === 'Backspace' || event.key === 'Delete') {\n      event.preventDefault();\n\n      if (value !== null) {\n        onChange(null);\n      } else {\n        onPreviousInput?.();\n      }\n    }\n\n    if (event.key === 'ArrowRight') {\n      event.preventDefault();\n      onNextInput?.();\n    }\n\n    if (event.key === 'ArrowLeft') {\n      event.preventDefault();\n      onPreviousInput?.();\n    }\n\n    if (event.key === 'ArrowUp') {\n      event.preventDefault();\n      const newValue = value === null ? min : clamp(value + step, min, arrowsMax);\n      onChange(newValue);\n    }\n\n    if (event.key === 'ArrowDown') {\n      event.preventDefault();\n      const fallback = hasMax ? arrowsMax : min;\n      const newValue = value === null ? fallback : clamp(value - step, min, arrowsMax);\n      onChange(newValue);\n    }\n  };\n\n  return (\n    <input\n      type=\"text\"\n      // eslint-disable-next-line jsx-a11y/no-redundant-roles -- input type=\"text\" has implicit role textbox, not spinbutton; the role is required here because this text input acts as a spinbutton\n      role=\"spinbutton\"\n      aria-valuemin={min}\n      aria-valuemax={hasMax ? max : undefined}\n      aria-valuenow={value === null ? 0 : value}\n      data-empty={value === null || undefined}\n      inputMode=\"numeric\"\n      placeholder={placeholder}\n      value={value === null ? '' : padTime(value)}\n      onChange={(event) => handleChange(event.currentTarget.value)}\n      onKeyDown={handleKeyDown}\n      onFocus={(event) => {\n        event.currentTarget.select();\n        onFocus?.(event);\n      }}\n      onClick={(event) => {\n        event.stopPropagation();\n        event.currentTarget.select();\n      }}\n      onMouseDown={(event) => event.stopPropagation()}\n      {...others}\n    />\n  );\n}\n\nSpinInput.displayName = '@mantine/dates/SpinInput';\n"],"mappings":";;;;;AAiBA,MAAM,eAAe,QAAgB,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE;AAE7D,SAAgB,UAAU,EACxB,OACA,KACA,KACA,UACA,WACA,MACA,aACA,iBACA,SACA,UACA,qBAAqB,OACrB,cAAc,MACd,qBAAqB,OACrB,GAAG,UACc;CACjB,MAAM,SAAS,OAAO,SAAS,GAAG;CAClC,MAAM,WAAW,SAAS,YAAY,GAAG,IAAI;CAC7C,MAAM,YAAY,SAAS,MAAM,IAAI,OAAO;CAE5C,MAAM,gBAAgB,UAAkB;EACtC,IAAI,UACF;EAGF,MAAM,aAAa,MAAM,QAAQ,OAAO,EAAE;EAC1C,IAAI,eAAe,IAAI;GACrB,IAAI,cAAc;GAClB,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK,GAAG;IAC7C,MAAM,QAAQ,WAAW,WAAW,CAAC,IAAI;IACzC,MAAM,OAAO,cAAc,KAAK;IAChC,cAAc,OAAO,MAAM,QAAQ;GACrC;GAEA,MAAM,eACJ,sBAAsB,gBAAgB,KAAK,MAAM,IAAI,IAAI,MAAM,aAAa,KAAK,GAAG;GAEtF,SAAS,YAAY;GAErB,IAAI,CAAC,uBAAuB,eAAe,YAAY,MAAM,WAAW,IAAI,IAC1E,cAAc;EAElB;CACF;CAEA,MAAM,iBAAiB,UAAiD;EACtE,IAAI,UACF;EAGF,IAAI,MAAM,QAAQ,OAAO,MAAM,QAAQ,QAAQ;GAC7C,MAAM,EAAE,gBAAgB,cAAc,OAAO,eAAe,MAAM;GAClE,MAAM,wBACJ,WAAW,SAAS,KAAK,mBAAmB,KAAK,iBAAiB,WAAW;GAE/E,IAAI,UAAU,KAAK,CAAC,uBAAuB;IACzC,MAAM,eAAe;IACrB,cAAc;GAChB;EACF;EAEA,IAAI,MAAM,QAAQ,QAAQ;GACxB,MAAM,eAAe;GACrB,SAAS,GAAG;EACd;EAEA,IAAI,MAAM,QAAQ,SAAS,QAAQ;GACjC,MAAM,eAAe;GACrB,SAAS,GAAG;EACd;EAEA,IAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,UAAU;GACvD,MAAM,eAAe;GAErB,IAAI,UAAU,MACZ,SAAS,IAAI;QAEb,kBAAkB;EAEtB;EAEA,IAAI,MAAM,QAAQ,cAAc;GAC9B,MAAM,eAAe;GACrB,cAAc;EAChB;EAEA,IAAI,MAAM,QAAQ,aAAa;GAC7B,MAAM,eAAe;GACrB,kBAAkB;EACpB;EAEA,IAAI,MAAM,QAAQ,WAAW;GAC3B,MAAM,eAAe;GAErB,SADiB,UAAU,OAAO,MAAM,MAAM,QAAQ,MAAM,KAAK,SAAS,CACzD;EACnB;EAEA,IAAI,MAAM,QAAQ,aAAa;GAC7B,MAAM,eAAe;GAGrB,SADiB,UAAU,OADV,SAAS,YAAY,MACO,MAAM,QAAQ,MAAM,KAAK,SAAS,CAC9D;EACnB;CACF;CAEA,OACE,oBAAC,SAAD;EACE,MAAK;EAEL,MAAK;EACL,iBAAe;EACf,iBAAe,SAAS,MAAM,KAAA;EAC9B,iBAAe,UAAU,OAAO,IAAI;EACpC,cAAY,UAAU,QAAQ,KAAA;EAC9B,WAAU;EACG;EACb,OAAO,UAAU,OAAO,KAAK,QAAQ,KAAK;EAC1C,WAAW,UAAU,aAAa,MAAM,cAAc,KAAK;EAC3D,WAAW;EACX,UAAU,UAAU;GAClB,MAAM,cAAc,OAAO;GAC3B,UAAU,KAAK;EACjB;EACA,UAAU,UAAU;GAClB,MAAM,gBAAgB;GACtB,MAAM,cAAc,OAAO;EAC7B;EACA,cAAc,UAAU,MAAM,gBAAgB;EAC9C,GAAI;CACL,CAAA;AAEL;AAEA,UAAU,cAAc"}