@chayns-components/core 5.0.0-beta.1257 → 5.0.0-beta.1261

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,8 +33,10 @@ const NumberInput = ({
33
33
  const [shouldRemainPlaceholder, setShouldRemainPlaceholder] = (0, _react.useState)(false);
34
34
  const [isValueInvalid, setIsValueInvalid] = (0, _react.useState)(false);
35
35
  const localPlaceholder = placeholder ?? (isMoneyInput ? '€' : undefined);
36
+ const initialInputRef = (0, _react.useRef)(true);
36
37
  const onLocalChange = event => {
37
38
  const newValue = event.target.value;
39
+ initialInputRef.current = false;
38
40
  const sanitizedValueString = newValue
39
41
  // Removes everything except numbers, commas and points
40
42
  .replace(_numberInput.NUMBER_CLEAR_REGEX, '');
@@ -64,7 +66,7 @@ const NumberInput = ({
64
66
  }
65
67
  };
66
68
  const onLocalBlur = () => {
67
- const sanitizedValue = plainText.length === 0 ? '0' : plainText;
69
+ const sanitizedValue = plainText;
68
70
  let newIsInvalid = false;
69
71
  let parsedNumber = null;
70
72
  if (!isTimeInput) {
@@ -72,7 +74,7 @@ const NumberInput = ({
72
74
  stringValue: sanitizedValue.replace(',', '.').replaceAll(':', '').replace('€', ''),
73
75
  decimals: isMoneyInput ? 2 : undefined
74
76
  });
75
- if (parsedNumber !== 0 && (parsedNumber > maxNumber || parsedNumber < minNumber)) {
77
+ if (parsedNumber && parsedNumber !== 0 && (parsedNumber > maxNumber || parsedNumber < minNumber)) {
76
78
  newIsInvalid = true;
77
79
  }
78
80
  setIsValueInvalid(newIsInvalid);
@@ -92,7 +94,7 @@ const NumberInput = ({
92
94
  if (isTimeInput) {
93
95
  onBlur(newStringValue, newIsInvalid);
94
96
  } else {
95
- onBlur(parsedNumber === 0 ? null : parsedNumber, newIsInvalid);
97
+ onBlur(parsedNumber, newIsInvalid);
96
98
  }
97
99
  }
98
100
  };
@@ -120,7 +122,11 @@ const NumberInput = ({
120
122
 
121
123
  // checks, if a given number is invalid, if the input is not in focus
122
124
  if (!hasFocus) {
123
- setIsValueInvalid(parsedNumber > maxNumber || parsedNumber < minNumber);
125
+ if (parsedNumber === null && initialInputRef.current) {
126
+ setIsValueInvalid(false);
127
+ } else {
128
+ setIsValueInvalid(parsedNumber === null || parsedNumber > maxNumber || parsedNumber < minNumber);
129
+ }
124
130
  }
125
131
  }
126
132
  setFormattedValue(plainText.length === 0 ? '' : `${(0, _numberInput2.formateNumber)({
@@ -1 +1 @@
1
- {"version":3,"file":"NumberInput.js","names":["_react","_interopRequireWildcard","require","_numberInput","_numberInput2","_Input","_interopRequireDefault","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","NumberInput","isDecimalInput","isMoneyInput","isTimeInput","isInvalid","maxNumber","Infinity","value","shouldTriggerChangeOnFormat","placeholder","onBlur","isDisabled","onChange","shouldShowOnlyBottomBorder","minNumber","plainText","setPlainText","useState","formattedValue","setFormattedValue","hasFocus","setHasFocus","shouldRemainPlaceholder","setShouldRemainPlaceholder","isValueInvalid","setIsValueInvalid","localPlaceholder","undefined","onLocalChange","event","newValue","target","sanitizedValueString","replace","NUMBER_CLEAR_REGEX","includes","length","valueToCheck","replaceAll","isValidString","string","Number","match","onLocalBlur","sanitizedValue","newIsInvalid","parsedNumber","parseFloatWithDecimals","stringValue","decimals","newStringValue","formateNumber","number","onLocalFocus","useEffect","createElement","inputMode","onFocus","shouldShowCenteredContent","displayName","_default","exports"],"sources":["../../../../src/components/number-input/NumberInput.tsx"],"sourcesContent":["import React, { ChangeEventHandler, FC, useEffect, useState } from 'react';\nimport { NUMBER_CLEAR_REGEX } from '../../constants/numberInput';\nimport { formateNumber, isValidString, parseFloatWithDecimals } from '../../utils/numberInput';\nimport Input from '../input/Input';\n\nexport type NumberInputProps = {\n /**\n * Applies rules for decimal input.\n * Enables the user to input one zero as number before the comma\n */\n isDecimalInput?: boolean;\n /**\n * Whether the input is disabled\n */\n isDisabled?: boolean;\n /**\n * Whether the value is invalid.\n */\n isInvalid?: boolean;\n /**\n * Applies rules for money input.\n * Rules: only two decimal places, one zero before the comma\n */\n isMoneyInput?: boolean;\n /**\n * Whether the value should be formatted as a time.\n */\n isTimeInput?: boolean;\n /**\n * Limits the number to this value\n */\n maxNumber?: number;\n /**\n * Limits the number to this value\n */\n minNumber?: number;\n /**\n * Callback function that is called when the input gets out of focus\n */\n onBlur?: (newNumber: number | string | null, isInvalid: boolean) => void;\n /**\n * Callback function that is called when the input changes\n * It will pass the text from the input\n */\n onChange?: (newValue: string) => void;\n /**\n * Placeholder for the input field\n */\n placeholder?: string;\n /**\n * Whether only the bottom border should be displayed\n */\n shouldShowOnlyBottomBorder?: boolean;\n /**\n * Whether the onChange function should be triggert when the value is formatted on the focus or blur\n */\n shouldTriggerChangeOnFormat?: boolean;\n /**\n * The value, that should be displayed in the input, when it is in focus.\n * You can also pass a stringified number as default value.\n * NOTE: If you pass a stringified number, it will be formatted to the selected format\n */\n value?: string;\n};\n\nconst NumberInput: FC<NumberInputProps> = ({\n isDecimalInput,\n isMoneyInput,\n isTimeInput,\n isInvalid,\n maxNumber = Infinity,\n value,\n shouldTriggerChangeOnFormat = true,\n placeholder,\n onBlur,\n isDisabled,\n onChange,\n shouldShowOnlyBottomBorder,\n minNumber = -Infinity,\n}) => {\n // the plainText will be shown in the input, when it is in focus\n const [plainText, setPlainText] = useState<string>('');\n // the formattedValue will be shown in the input, when it is not in focus\n const [formattedValue, setFormattedValue] = useState<string>('');\n const [hasFocus, setHasFocus] = useState<boolean>(false);\n const [shouldRemainPlaceholder, setShouldRemainPlaceholder] = useState<boolean>(false);\n\n const [isValueInvalid, setIsValueInvalid] = useState(false);\n const localPlaceholder = placeholder ?? (isMoneyInput ? '€' : undefined);\n\n const onLocalChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n const newValue = event.target.value;\n\n const sanitizedValueString = newValue\n // Removes everything except numbers, commas and points\n .replace(NUMBER_CLEAR_REGEX, '');\n\n if (\n isTimeInput &&\n ((sanitizedValueString.includes(':') && sanitizedValueString.length > 5) ||\n (!sanitizedValueString.includes(':') && sanitizedValueString.length > 4))\n ) {\n return;\n }\n\n const valueToCheck = sanitizedValueString.replaceAll(',', '.');\n\n if (!isValidString({ string: valueToCheck, isMoneyInput, isDecimalInput, isTimeInput })) {\n return;\n }\n\n if (\n (maxNumber && Number(valueToCheck) > maxNumber) ||\n (minNumber && Number(valueToCheck) < minNumber)\n ) {\n return;\n }\n\n if (newValue.length === 1 && newValue.match(/^[0-9]+$/) === null) {\n setShouldRemainPlaceholder(true);\n } else {\n setShouldRemainPlaceholder(false);\n }\n\n setPlainText(sanitizedValueString.replaceAll('.', ','));\n\n if (typeof onChange === 'function') {\n onChange(sanitizedValueString.replaceAll('.', ','));\n }\n };\n\n const onLocalBlur = () => {\n const sanitizedValue = plainText.length === 0 ? '0' : plainText;\n let newIsInvalid = false;\n let parsedNumber = null;\n\n if (!isTimeInput) {\n parsedNumber = parseFloatWithDecimals({\n stringValue: sanitizedValue.replace(',', '.').replaceAll(':', '').replace('€', ''),\n decimals: isMoneyInput ? 2 : undefined,\n });\n\n if (parsedNumber !== 0 && (parsedNumber > maxNumber || parsedNumber < minNumber)) {\n newIsInvalid = true;\n }\n\n setIsValueInvalid(newIsInvalid);\n }\n\n const newStringValue =\n plainText.length === 0\n ? ''\n : formateNumber({\n number: isTimeInput ? sanitizedValue : parsedNumber,\n isMoneyInput,\n isTimeInput,\n });\n\n setFormattedValue(`${newStringValue} ${isMoneyInput ? '€' : ''}`);\n setPlainText(newStringValue.replaceAll('.', ''));\n setHasFocus(false);\n\n if (typeof onChange === 'function' && shouldTriggerChangeOnFormat) {\n onChange(newStringValue.replaceAll('.', ''));\n }\n\n if (typeof onBlur === 'function') {\n if (isTimeInput) {\n onBlur(newStringValue, newIsInvalid);\n } else {\n onBlur(parsedNumber === 0 ? null : parsedNumber, newIsInvalid);\n }\n }\n };\n\n const onLocalFocus = () => {\n // formattedValue will be a number string with german number format (e.g. 1.000,00)\n // It will remove all dots, so that the user can type in the number\n setPlainText(formattedValue.replaceAll('.', '').replace('€', '').replaceAll(' ', ''));\n\n // This will update the external state\n if (typeof onChange === 'function' && shouldTriggerChangeOnFormat) {\n onChange(formattedValue.replaceAll('.', '').replace('€', '').replaceAll(' ', ''));\n }\n\n setIsValueInvalid(false);\n setHasFocus(true);\n };\n\n // updates the formattedValue, when the value changes\n useEffect(() => {\n let parsedNumber = null;\n\n if (!isTimeInput) {\n parsedNumber = parseFloatWithDecimals({\n stringValue: plainText\n .replace(',', '.')\n .replaceAll(':', '')\n .replace('€', '')\n .replaceAll(' ', ''),\n decimals: isMoneyInput ? 2 : undefined,\n });\n\n // checks, if a given number is invalid, if the input is not in focus\n if (!hasFocus) {\n setIsValueInvalid(parsedNumber > maxNumber || parsedNumber < minNumber);\n }\n }\n\n setFormattedValue(\n plainText.length === 0\n ? ''\n : `${formateNumber({\n number: isTimeInput ? plainText : parsedNumber,\n isMoneyInput,\n isTimeInput,\n })}${isMoneyInput ? ' €' : ''}`,\n );\n }, [hasFocus, isMoneyInput, isTimeInput, maxNumber, minNumber, plainText]);\n\n useEffect(() => {\n if (typeof value === 'string') {\n setPlainText(value.replace('€', '').replaceAll(' ', ''));\n }\n }, [value]);\n\n return (\n <Input\n shouldRemainPlaceholder={shouldRemainPlaceholder}\n shouldShowOnlyBottomBorder={shouldShowOnlyBottomBorder}\n inputMode=\"decimal\"\n onChange={onLocalChange}\n value={hasFocus ? plainText : formattedValue}\n placeholder={localPlaceholder}\n onBlur={onLocalBlur}\n onFocus={onLocalFocus}\n isDisabled={isDisabled}\n isInvalid={typeof isInvalid === 'boolean' ? isInvalid : isValueInvalid}\n shouldShowCenteredContent={shouldShowOnlyBottomBorder}\n />\n );\n};\n\nNumberInput.displayName = 'NumberInput';\n\nexport default NumberInput;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"NumberInput.js","names":["_react","_interopRequireWildcard","require","_numberInput","_numberInput2","_Input","_interopRequireDefault","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","NumberInput","isDecimalInput","isMoneyInput","isTimeInput","isInvalid","maxNumber","Infinity","value","shouldTriggerChangeOnFormat","placeholder","onBlur","isDisabled","onChange","shouldShowOnlyBottomBorder","minNumber","plainText","setPlainText","useState","formattedValue","setFormattedValue","hasFocus","setHasFocus","shouldRemainPlaceholder","setShouldRemainPlaceholder","isValueInvalid","setIsValueInvalid","localPlaceholder","undefined","initialInputRef","useRef","onLocalChange","event","newValue","target","current","sanitizedValueString","replace","NUMBER_CLEAR_REGEX","includes","length","valueToCheck","replaceAll","isValidString","string","Number","match","onLocalBlur","sanitizedValue","newIsInvalid","parsedNumber","parseFloatWithDecimals","stringValue","decimals","newStringValue","formateNumber","number","onLocalFocus","useEffect","createElement","inputMode","onFocus","shouldShowCenteredContent","displayName","_default","exports"],"sources":["../../../../src/components/number-input/NumberInput.tsx"],"sourcesContent":["import React, { ChangeEventHandler, FC, useEffect, useRef, useState } from 'react';\nimport { NUMBER_CLEAR_REGEX } from '../../constants/numberInput';\nimport { formateNumber, isValidString, parseFloatWithDecimals } from '../../utils/numberInput';\nimport Input from '../input/Input';\n\nexport type NumberInputProps = {\n /**\n * Applies rules for decimal input.\n * Enables the user to input one zero as number before the comma\n */\n isDecimalInput?: boolean;\n /**\n * Whether the input is disabled\n */\n isDisabled?: boolean;\n /**\n * Whether the value is invalid.\n */\n isInvalid?: boolean;\n /**\n * Applies rules for money input.\n * Rules: only two decimal places, one zero before the comma\n */\n isMoneyInput?: boolean;\n /**\n * Whether the value should be formatted as a time.\n */\n isTimeInput?: boolean;\n /**\n * Limits the number to this value\n */\n maxNumber?: number;\n /**\n * Limits the number to this value\n */\n minNumber?: number;\n /**\n * Callback function that is called when the input gets out of focus\n */\n onBlur?: (newNumber: number | string | null, isInvalid: boolean) => void;\n /**\n * Callback function that is called when the input changes\n * It will pass the text from the input\n */\n onChange?: (newValue: string) => void;\n /**\n * Placeholder for the input field\n */\n placeholder?: string;\n /**\n * Whether only the bottom border should be displayed\n */\n shouldShowOnlyBottomBorder?: boolean;\n /**\n * Whether the onChange function should be triggert when the value is formatted on the focus or blur\n */\n shouldTriggerChangeOnFormat?: boolean;\n /**\n * The value, that should be displayed in the input, when it is in focus.\n * You can also pass a stringified number as default value.\n * NOTE: If you pass a stringified number, it will be formatted to the selected format\n */\n value?: string;\n};\n\nconst NumberInput: FC<NumberInputProps> = ({\n isDecimalInput,\n isMoneyInput,\n isTimeInput,\n isInvalid,\n maxNumber = Infinity,\n value,\n shouldTriggerChangeOnFormat = true,\n placeholder,\n onBlur,\n isDisabled,\n onChange,\n shouldShowOnlyBottomBorder,\n minNumber = -Infinity,\n}) => {\n // the plainText will be shown in the input, when it is in focus\n const [plainText, setPlainText] = useState<string>('');\n // the formattedValue will be shown in the input, when it is not in focus\n const [formattedValue, setFormattedValue] = useState<string>('');\n const [hasFocus, setHasFocus] = useState<boolean>(false);\n const [shouldRemainPlaceholder, setShouldRemainPlaceholder] = useState<boolean>(false);\n\n const [isValueInvalid, setIsValueInvalid] = useState(false);\n const localPlaceholder = placeholder ?? (isMoneyInput ? '€' : undefined);\n\n const initialInputRef = useRef(true);\n\n const onLocalChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n const newValue = event.target.value;\n\n initialInputRef.current = false;\n\n const sanitizedValueString = newValue\n // Removes everything except numbers, commas and points\n .replace(NUMBER_CLEAR_REGEX, '');\n\n if (\n isTimeInput &&\n ((sanitizedValueString.includes(':') && sanitizedValueString.length > 5) ||\n (!sanitizedValueString.includes(':') && sanitizedValueString.length > 4))\n ) {\n return;\n }\n\n const valueToCheck = sanitizedValueString.replaceAll(',', '.');\n\n if (!isValidString({ string: valueToCheck, isMoneyInput, isDecimalInput, isTimeInput })) {\n return;\n }\n\n if (\n (maxNumber && Number(valueToCheck) > maxNumber) ||\n (minNumber && Number(valueToCheck) < minNumber)\n ) {\n return;\n }\n\n if (newValue.length === 1 && newValue.match(/^[0-9]+$/) === null) {\n setShouldRemainPlaceholder(true);\n } else {\n setShouldRemainPlaceholder(false);\n }\n\n setPlainText(sanitizedValueString.replaceAll('.', ','));\n\n if (typeof onChange === 'function') {\n onChange(sanitizedValueString.replaceAll('.', ','));\n }\n };\n\n const onLocalBlur = () => {\n const sanitizedValue = plainText;\n let newIsInvalid = false;\n let parsedNumber = null;\n\n if (!isTimeInput) {\n parsedNumber = parseFloatWithDecimals({\n stringValue: sanitizedValue.replace(',', '.').replaceAll(':', '').replace('€', ''),\n decimals: isMoneyInput ? 2 : undefined,\n });\n\n if (\n parsedNumber &&\n parsedNumber !== 0 &&\n (parsedNumber > maxNumber || parsedNumber < minNumber)\n ) {\n newIsInvalid = true;\n }\n\n setIsValueInvalid(newIsInvalid);\n }\n\n const newStringValue =\n plainText.length === 0\n ? ''\n : formateNumber({\n number: isTimeInput ? sanitizedValue : parsedNumber,\n isMoneyInput,\n isTimeInput,\n });\n\n setFormattedValue(`${newStringValue} ${isMoneyInput ? '€' : ''}`);\n setPlainText(newStringValue.replaceAll('.', ''));\n setHasFocus(false);\n\n if (typeof onChange === 'function' && shouldTriggerChangeOnFormat) {\n onChange(newStringValue.replaceAll('.', ''));\n }\n\n if (typeof onBlur === 'function') {\n if (isTimeInput) {\n onBlur(newStringValue, newIsInvalid);\n } else {\n onBlur(parsedNumber, newIsInvalid);\n }\n }\n };\n\n const onLocalFocus = () => {\n // formattedValue will be a number string with german number format (e.g. 1.000,00)\n // It will remove all dots, so that the user can type in the number\n setPlainText(formattedValue.replaceAll('.', '').replace('€', '').replaceAll(' ', ''));\n\n // This will update the external state\n if (typeof onChange === 'function' && shouldTriggerChangeOnFormat) {\n onChange(formattedValue.replaceAll('.', '').replace('€', '').replaceAll(' ', ''));\n }\n\n setIsValueInvalid(false);\n setHasFocus(true);\n };\n\n // updates the formattedValue, when the value changes\n useEffect(() => {\n let parsedNumber = null;\n\n if (!isTimeInput) {\n parsedNumber = parseFloatWithDecimals({\n stringValue: plainText\n .replace(',', '.')\n .replaceAll(':', '')\n .replace('€', '')\n .replaceAll(' ', ''),\n decimals: isMoneyInput ? 2 : undefined,\n });\n\n // checks, if a given number is invalid, if the input is not in focus\n if (!hasFocus) {\n if (parsedNumber === null && initialInputRef.current) {\n setIsValueInvalid(false);\n } else {\n setIsValueInvalid(\n parsedNumber === null ||\n parsedNumber > maxNumber ||\n parsedNumber < minNumber,\n );\n }\n }\n }\n\n setFormattedValue(\n plainText.length === 0\n ? ''\n : `${formateNumber({\n number: isTimeInput ? plainText : parsedNumber,\n isMoneyInput,\n isTimeInput,\n })}${isMoneyInput ? ' €' : ''}`,\n );\n }, [hasFocus, isMoneyInput, isTimeInput, maxNumber, minNumber, plainText]);\n\n useEffect(() => {\n if (typeof value === 'string') {\n setPlainText(value.replace('€', '').replaceAll(' ', ''));\n }\n }, [value]);\n\n return (\n <Input\n shouldRemainPlaceholder={shouldRemainPlaceholder}\n shouldShowOnlyBottomBorder={shouldShowOnlyBottomBorder}\n inputMode=\"decimal\"\n onChange={onLocalChange}\n value={hasFocus ? plainText : formattedValue}\n placeholder={localPlaceholder}\n onBlur={onLocalBlur}\n onFocus={onLocalFocus}\n isDisabled={isDisabled}\n isInvalid={typeof isInvalid === 'boolean' ? isInvalid : isValueInvalid}\n shouldShowCenteredContent={shouldShowOnlyBottomBorder}\n />\n );\n};\n\nNumberInput.displayName = 'NumberInput';\n\nexport default NumberInput;\n"],"mappings":"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","ignoreList":[]}
@@ -9,6 +9,9 @@ const parseFloatWithDecimals = ({
9
9
  stringValue,
10
10
  decimals
11
11
  }) => {
12
+ if (stringValue === '') {
13
+ return null;
14
+ }
12
15
  const parsed = parseFloat(stringValue);
13
16
  if (decimals) {
14
17
  return parseFloat(parsed.toFixed(decimals));
@@ -1 +1 @@
1
- {"version":3,"file":"numberInput.js","names":["_numberInput","require","parseFloatWithDecimals","stringValue","decimals","parsed","parseFloat","toFixed","exports","formateNumber","number","isMoneyInput","isTimeInput","hours","minutes","firstTwoDigits","substring","includes","replace","firstTwoNumbers","Number","lastTwoNumbers","lastTwoNumbersLength","length","hoursStr","minutesStr","toLocaleString","useGrouping","minimumFractionDigits","undefined","maximumFractionDigits","maximumSignificantDigits","isValidString","isDecimalInput","string","isValid","DECIMAL_TEST","test","MONEY_TEST","TIME_TEST","INTEGER_TEST","startsWith"],"sources":["../../../src/utils/numberInput.ts"],"sourcesContent":["import { DECIMAL_TEST, INTEGER_TEST, MONEY_TEST, TIME_TEST } from '../constants/numberInput';\n\ninterface ParseFloatWithDecimals {\n ({ stringValue, decimals }: { stringValue: string; decimals?: number }): number;\n}\n\nexport const parseFloatWithDecimals: ParseFloatWithDecimals = ({ stringValue, decimals }) => {\n const parsed = parseFloat(stringValue);\n\n if (decimals) {\n return parseFloat(parsed.toFixed(decimals));\n }\n\n return parsed;\n};\n\ninterface FormateNumberOptions {\n number: number | string | null;\n isMoneyInput?: boolean;\n isTimeInput?: boolean;\n}\n\nexport const formateNumber = ({ number, isMoneyInput, isTimeInput }: FormateNumberOptions) => {\n if (isTimeInput && typeof number === 'string') {\n let hours = 0;\n let minutes = 0;\n\n let firstTwoDigits = number.substring(0, 2);\n\n if (firstTwoDigits.includes(':')) {\n firstTwoDigits = firstTwoDigits.replace(':', '');\n\n firstTwoDigits = `0${firstTwoDigits}`;\n }\n\n const firstTwoNumbers = Number(firstTwoDigits);\n let lastTwoNumbers = 0;\n let lastTwoNumbersLength = 0;\n\n if (number.includes(':')) {\n lastTwoNumbers = Number(number.substring(3, 5));\n lastTwoNumbersLength = number.substring(3, 5).length;\n } else {\n lastTwoNumbers = Number(number.substring(2, 4));\n lastTwoNumbersLength = number.substring(2, 4).length;\n }\n\n hours = firstTwoNumbers > 23 ? 23 : firstTwoNumbers;\n\n if (lastTwoNumbers < 7 && lastTwoNumbersLength === 1) {\n minutes = lastTwoNumbers * 10;\n } else {\n minutes = lastTwoNumbers > 59 ? 59 : lastTwoNumbers;\n }\n\n const hoursStr = hours < 10 ? `0${hours}` : `${hours}`;\n const minutesStr = minutes < 10 ? `0${minutes}` : `${minutes}`;\n\n return `${hoursStr}:${minutesStr}`;\n }\n\n if (typeof number !== 'number') {\n return '';\n }\n\n return number.toLocaleString('de-DE', {\n useGrouping: true,\n minimumFractionDigits: isMoneyInput ? 2 : undefined,\n maximumFractionDigits: isMoneyInput ? 2 : undefined,\n maximumSignificantDigits: !isMoneyInput ? 20 : undefined,\n });\n};\n\ninterface IsValidString {\n (config: {\n string: string;\n isDecimalInput?: boolean;\n isMoneyInput?: boolean;\n isTimeInput?: boolean;\n }): boolean;\n}\n\nexport const isValidString: IsValidString = ({\n isDecimalInput,\n isMoneyInput,\n isTimeInput,\n string,\n}) => {\n let isValid = false;\n\n // Allows numbers, one (comma/point) and any number of decimal places\n if (isDecimalInput && DECIMAL_TEST.test(string)) {\n isValid = true;\n }\n\n // Allows numbers but excludes numbers with leading 0\n if (isMoneyInput && MONEY_TEST.test(string)) {\n isValid = true;\n }\n\n if (isTimeInput && TIME_TEST) {\n isValid = true;\n }\n\n // Allows numbers but excludes numbers with leading 0\n if (!isDecimalInput && !isMoneyInput && !isTimeInput && INTEGER_TEST.test(string)) {\n isValid = true;\n }\n\n if (string.length === 0) {\n isValid = true;\n }\n\n if (string.startsWith('0')) {\n isValid = true;\n }\n\n return isValid;\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"numberInput.js","names":["_numberInput","require","parseFloatWithDecimals","stringValue","decimals","parsed","parseFloat","toFixed","exports","formateNumber","number","isMoneyInput","isTimeInput","hours","minutes","firstTwoDigits","substring","includes","replace","firstTwoNumbers","Number","lastTwoNumbers","lastTwoNumbersLength","length","hoursStr","minutesStr","toLocaleString","useGrouping","minimumFractionDigits","undefined","maximumFractionDigits","maximumSignificantDigits","isValidString","isDecimalInput","string","isValid","DECIMAL_TEST","test","MONEY_TEST","TIME_TEST","INTEGER_TEST","startsWith"],"sources":["../../../src/utils/numberInput.ts"],"sourcesContent":["import { DECIMAL_TEST, INTEGER_TEST, MONEY_TEST, TIME_TEST } from '../constants/numberInput';\n\ninterface ParseFloatWithDecimals {\n ({ stringValue, decimals }: { stringValue: string; decimals?: number }): number | null;\n}\n\nexport const parseFloatWithDecimals: ParseFloatWithDecimals = ({ stringValue, decimals }) => {\n if (stringValue === '') {\n return null;\n }\n\n const parsed = parseFloat(stringValue);\n\n if (decimals) {\n return parseFloat(parsed.toFixed(decimals));\n }\n\n return parsed;\n};\n\ninterface FormateNumberOptions {\n number: number | string | null;\n isMoneyInput?: boolean;\n isTimeInput?: boolean;\n}\n\nexport const formateNumber = ({ number, isMoneyInput, isTimeInput }: FormateNumberOptions) => {\n if (isTimeInput && typeof number === 'string') {\n let hours = 0;\n let minutes = 0;\n\n let firstTwoDigits = number.substring(0, 2);\n\n if (firstTwoDigits.includes(':')) {\n firstTwoDigits = firstTwoDigits.replace(':', '');\n\n firstTwoDigits = `0${firstTwoDigits}`;\n }\n\n const firstTwoNumbers = Number(firstTwoDigits);\n let lastTwoNumbers = 0;\n let lastTwoNumbersLength = 0;\n\n if (number.includes(':')) {\n lastTwoNumbers = Number(number.substring(3, 5));\n lastTwoNumbersLength = number.substring(3, 5).length;\n } else {\n lastTwoNumbers = Number(number.substring(2, 4));\n lastTwoNumbersLength = number.substring(2, 4).length;\n }\n\n hours = firstTwoNumbers > 23 ? 23 : firstTwoNumbers;\n\n if (lastTwoNumbers < 7 && lastTwoNumbersLength === 1) {\n minutes = lastTwoNumbers * 10;\n } else {\n minutes = lastTwoNumbers > 59 ? 59 : lastTwoNumbers;\n }\n\n const hoursStr = hours < 10 ? `0${hours}` : `${hours}`;\n const minutesStr = minutes < 10 ? `0${minutes}` : `${minutes}`;\n\n return `${hoursStr}:${minutesStr}`;\n }\n\n if (typeof number !== 'number') {\n return '';\n }\n\n return number.toLocaleString('de-DE', {\n useGrouping: true,\n minimumFractionDigits: isMoneyInput ? 2 : undefined,\n maximumFractionDigits: isMoneyInput ? 2 : undefined,\n maximumSignificantDigits: !isMoneyInput ? 20 : undefined,\n });\n};\n\ninterface IsValidString {\n (config: {\n string: string;\n isDecimalInput?: boolean;\n isMoneyInput?: boolean;\n isTimeInput?: boolean;\n }): boolean;\n}\n\nexport const isValidString: IsValidString = ({\n isDecimalInput,\n isMoneyInput,\n isTimeInput,\n string,\n}) => {\n let isValid = false;\n\n // Allows numbers, one (comma/point) and any number of decimal places\n if (isDecimalInput && DECIMAL_TEST.test(string)) {\n isValid = true;\n }\n\n // Allows numbers but excludes numbers with leading 0\n if (isMoneyInput && MONEY_TEST.test(string)) {\n isValid = true;\n }\n\n if (isTimeInput && TIME_TEST) {\n isValid = true;\n }\n\n // Allows numbers but excludes numbers with leading 0\n if (!isDecimalInput && !isMoneyInput && !isTimeInput && INTEGER_TEST.test(string)) {\n isValid = true;\n }\n\n if (string.length === 0) {\n isValid = true;\n }\n\n if (string.startsWith('0')) {\n isValid = true;\n }\n\n return isValid;\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, { useEffect, useRef, useState } from 'react';
2
2
  import { NUMBER_CLEAR_REGEX } from '../../constants/numberInput';
3
3
  import { formateNumber, isValidString, parseFloatWithDecimals } from '../../utils/numberInput';
4
4
  import Input from '../input/Input';
@@ -25,8 +25,10 @@ const NumberInput = ({
25
25
  const [shouldRemainPlaceholder, setShouldRemainPlaceholder] = useState(false);
26
26
  const [isValueInvalid, setIsValueInvalid] = useState(false);
27
27
  const localPlaceholder = placeholder ?? (isMoneyInput ? '€' : undefined);
28
+ const initialInputRef = useRef(true);
28
29
  const onLocalChange = event => {
29
30
  const newValue = event.target.value;
31
+ initialInputRef.current = false;
30
32
  const sanitizedValueString = newValue
31
33
  // Removes everything except numbers, commas and points
32
34
  .replace(NUMBER_CLEAR_REGEX, '');
@@ -56,7 +58,7 @@ const NumberInput = ({
56
58
  }
57
59
  };
58
60
  const onLocalBlur = () => {
59
- const sanitizedValue = plainText.length === 0 ? '0' : plainText;
61
+ const sanitizedValue = plainText;
60
62
  let newIsInvalid = false;
61
63
  let parsedNumber = null;
62
64
  if (!isTimeInput) {
@@ -64,7 +66,7 @@ const NumberInput = ({
64
66
  stringValue: sanitizedValue.replace(',', '.').replaceAll(':', '').replace('€', ''),
65
67
  decimals: isMoneyInput ? 2 : undefined
66
68
  });
67
- if (parsedNumber !== 0 && (parsedNumber > maxNumber || parsedNumber < minNumber)) {
69
+ if (parsedNumber && parsedNumber !== 0 && (parsedNumber > maxNumber || parsedNumber < minNumber)) {
68
70
  newIsInvalid = true;
69
71
  }
70
72
  setIsValueInvalid(newIsInvalid);
@@ -84,7 +86,7 @@ const NumberInput = ({
84
86
  if (isTimeInput) {
85
87
  onBlur(newStringValue, newIsInvalid);
86
88
  } else {
87
- onBlur(parsedNumber === 0 ? null : parsedNumber, newIsInvalid);
89
+ onBlur(parsedNumber, newIsInvalid);
88
90
  }
89
91
  }
90
92
  };
@@ -112,7 +114,11 @@ const NumberInput = ({
112
114
 
113
115
  // checks, if a given number is invalid, if the input is not in focus
114
116
  if (!hasFocus) {
115
- setIsValueInvalid(parsedNumber > maxNumber || parsedNumber < minNumber);
117
+ if (parsedNumber === null && initialInputRef.current) {
118
+ setIsValueInvalid(false);
119
+ } else {
120
+ setIsValueInvalid(parsedNumber === null || parsedNumber > maxNumber || parsedNumber < minNumber);
121
+ }
116
122
  }
117
123
  }
118
124
  setFormattedValue(plainText.length === 0 ? '' : `${formateNumber({
@@ -1 +1 @@
1
- {"version":3,"file":"NumberInput.js","names":["React","useEffect","useState","NUMBER_CLEAR_REGEX","formateNumber","isValidString","parseFloatWithDecimals","Input","NumberInput","isDecimalInput","isMoneyInput","isTimeInput","isInvalid","maxNumber","Infinity","value","shouldTriggerChangeOnFormat","placeholder","onBlur","isDisabled","onChange","shouldShowOnlyBottomBorder","minNumber","plainText","setPlainText","formattedValue","setFormattedValue","hasFocus","setHasFocus","shouldRemainPlaceholder","setShouldRemainPlaceholder","isValueInvalid","setIsValueInvalid","localPlaceholder","undefined","onLocalChange","event","newValue","target","sanitizedValueString","replace","includes","length","valueToCheck","replaceAll","string","Number","match","onLocalBlur","sanitizedValue","newIsInvalid","parsedNumber","stringValue","decimals","newStringValue","number","onLocalFocus","createElement","inputMode","onFocus","shouldShowCenteredContent","displayName"],"sources":["../../../../src/components/number-input/NumberInput.tsx"],"sourcesContent":["import React, { ChangeEventHandler, FC, useEffect, useState } from 'react';\nimport { NUMBER_CLEAR_REGEX } from '../../constants/numberInput';\nimport { formateNumber, isValidString, parseFloatWithDecimals } from '../../utils/numberInput';\nimport Input from '../input/Input';\n\nexport type NumberInputProps = {\n /**\n * Applies rules for decimal input.\n * Enables the user to input one zero as number before the comma\n */\n isDecimalInput?: boolean;\n /**\n * Whether the input is disabled\n */\n isDisabled?: boolean;\n /**\n * Whether the value is invalid.\n */\n isInvalid?: boolean;\n /**\n * Applies rules for money input.\n * Rules: only two decimal places, one zero before the comma\n */\n isMoneyInput?: boolean;\n /**\n * Whether the value should be formatted as a time.\n */\n isTimeInput?: boolean;\n /**\n * Limits the number to this value\n */\n maxNumber?: number;\n /**\n * Limits the number to this value\n */\n minNumber?: number;\n /**\n * Callback function that is called when the input gets out of focus\n */\n onBlur?: (newNumber: number | string | null, isInvalid: boolean) => void;\n /**\n * Callback function that is called when the input changes\n * It will pass the text from the input\n */\n onChange?: (newValue: string) => void;\n /**\n * Placeholder for the input field\n */\n placeholder?: string;\n /**\n * Whether only the bottom border should be displayed\n */\n shouldShowOnlyBottomBorder?: boolean;\n /**\n * Whether the onChange function should be triggert when the value is formatted on the focus or blur\n */\n shouldTriggerChangeOnFormat?: boolean;\n /**\n * The value, that should be displayed in the input, when it is in focus.\n * You can also pass a stringified number as default value.\n * NOTE: If you pass a stringified number, it will be formatted to the selected format\n */\n value?: string;\n};\n\nconst NumberInput: FC<NumberInputProps> = ({\n isDecimalInput,\n isMoneyInput,\n isTimeInput,\n isInvalid,\n maxNumber = Infinity,\n value,\n shouldTriggerChangeOnFormat = true,\n placeholder,\n onBlur,\n isDisabled,\n onChange,\n shouldShowOnlyBottomBorder,\n minNumber = -Infinity,\n}) => {\n // the plainText will be shown in the input, when it is in focus\n const [plainText, setPlainText] = useState<string>('');\n // the formattedValue will be shown in the input, when it is not in focus\n const [formattedValue, setFormattedValue] = useState<string>('');\n const [hasFocus, setHasFocus] = useState<boolean>(false);\n const [shouldRemainPlaceholder, setShouldRemainPlaceholder] = useState<boolean>(false);\n\n const [isValueInvalid, setIsValueInvalid] = useState(false);\n const localPlaceholder = placeholder ?? (isMoneyInput ? '€' : undefined);\n\n const onLocalChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n const newValue = event.target.value;\n\n const sanitizedValueString = newValue\n // Removes everything except numbers, commas and points\n .replace(NUMBER_CLEAR_REGEX, '');\n\n if (\n isTimeInput &&\n ((sanitizedValueString.includes(':') && sanitizedValueString.length > 5) ||\n (!sanitizedValueString.includes(':') && sanitizedValueString.length > 4))\n ) {\n return;\n }\n\n const valueToCheck = sanitizedValueString.replaceAll(',', '.');\n\n if (!isValidString({ string: valueToCheck, isMoneyInput, isDecimalInput, isTimeInput })) {\n return;\n }\n\n if (\n (maxNumber && Number(valueToCheck) > maxNumber) ||\n (minNumber && Number(valueToCheck) < minNumber)\n ) {\n return;\n }\n\n if (newValue.length === 1 && newValue.match(/^[0-9]+$/) === null) {\n setShouldRemainPlaceholder(true);\n } else {\n setShouldRemainPlaceholder(false);\n }\n\n setPlainText(sanitizedValueString.replaceAll('.', ','));\n\n if (typeof onChange === 'function') {\n onChange(sanitizedValueString.replaceAll('.', ','));\n }\n };\n\n const onLocalBlur = () => {\n const sanitizedValue = plainText.length === 0 ? '0' : plainText;\n let newIsInvalid = false;\n let parsedNumber = null;\n\n if (!isTimeInput) {\n parsedNumber = parseFloatWithDecimals({\n stringValue: sanitizedValue.replace(',', '.').replaceAll(':', '').replace('€', ''),\n decimals: isMoneyInput ? 2 : undefined,\n });\n\n if (parsedNumber !== 0 && (parsedNumber > maxNumber || parsedNumber < minNumber)) {\n newIsInvalid = true;\n }\n\n setIsValueInvalid(newIsInvalid);\n }\n\n const newStringValue =\n plainText.length === 0\n ? ''\n : formateNumber({\n number: isTimeInput ? sanitizedValue : parsedNumber,\n isMoneyInput,\n isTimeInput,\n });\n\n setFormattedValue(`${newStringValue} ${isMoneyInput ? '€' : ''}`);\n setPlainText(newStringValue.replaceAll('.', ''));\n setHasFocus(false);\n\n if (typeof onChange === 'function' && shouldTriggerChangeOnFormat) {\n onChange(newStringValue.replaceAll('.', ''));\n }\n\n if (typeof onBlur === 'function') {\n if (isTimeInput) {\n onBlur(newStringValue, newIsInvalid);\n } else {\n onBlur(parsedNumber === 0 ? null : parsedNumber, newIsInvalid);\n }\n }\n };\n\n const onLocalFocus = () => {\n // formattedValue will be a number string with german number format (e.g. 1.000,00)\n // It will remove all dots, so that the user can type in the number\n setPlainText(formattedValue.replaceAll('.', '').replace('€', '').replaceAll(' ', ''));\n\n // This will update the external state\n if (typeof onChange === 'function' && shouldTriggerChangeOnFormat) {\n onChange(formattedValue.replaceAll('.', '').replace('€', '').replaceAll(' ', ''));\n }\n\n setIsValueInvalid(false);\n setHasFocus(true);\n };\n\n // updates the formattedValue, when the value changes\n useEffect(() => {\n let parsedNumber = null;\n\n if (!isTimeInput) {\n parsedNumber = parseFloatWithDecimals({\n stringValue: plainText\n .replace(',', '.')\n .replaceAll(':', '')\n .replace('€', '')\n .replaceAll(' ', ''),\n decimals: isMoneyInput ? 2 : undefined,\n });\n\n // checks, if a given number is invalid, if the input is not in focus\n if (!hasFocus) {\n setIsValueInvalid(parsedNumber > maxNumber || parsedNumber < minNumber);\n }\n }\n\n setFormattedValue(\n plainText.length === 0\n ? ''\n : `${formateNumber({\n number: isTimeInput ? plainText : parsedNumber,\n isMoneyInput,\n isTimeInput,\n })}${isMoneyInput ? ' €' : ''}`,\n );\n }, [hasFocus, isMoneyInput, isTimeInput, maxNumber, minNumber, plainText]);\n\n useEffect(() => {\n if (typeof value === 'string') {\n setPlainText(value.replace('€', '').replaceAll(' ', ''));\n }\n }, [value]);\n\n return (\n <Input\n shouldRemainPlaceholder={shouldRemainPlaceholder}\n shouldShowOnlyBottomBorder={shouldShowOnlyBottomBorder}\n inputMode=\"decimal\"\n onChange={onLocalChange}\n value={hasFocus ? plainText : formattedValue}\n placeholder={localPlaceholder}\n onBlur={onLocalBlur}\n onFocus={onLocalFocus}\n isDisabled={isDisabled}\n isInvalid={typeof isInvalid === 'boolean' ? isInvalid : isValueInvalid}\n shouldShowCenteredContent={shouldShowOnlyBottomBorder}\n />\n );\n};\n\nNumberInput.displayName = 'NumberInput';\n\nexport default NumberInput;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"NumberInput.js","names":["React","useEffect","useRef","useState","NUMBER_CLEAR_REGEX","formateNumber","isValidString","parseFloatWithDecimals","Input","NumberInput","isDecimalInput","isMoneyInput","isTimeInput","isInvalid","maxNumber","Infinity","value","shouldTriggerChangeOnFormat","placeholder","onBlur","isDisabled","onChange","shouldShowOnlyBottomBorder","minNumber","plainText","setPlainText","formattedValue","setFormattedValue","hasFocus","setHasFocus","shouldRemainPlaceholder","setShouldRemainPlaceholder","isValueInvalid","setIsValueInvalid","localPlaceholder","undefined","initialInputRef","onLocalChange","event","newValue","target","current","sanitizedValueString","replace","includes","length","valueToCheck","replaceAll","string","Number","match","onLocalBlur","sanitizedValue","newIsInvalid","parsedNumber","stringValue","decimals","newStringValue","number","onLocalFocus","createElement","inputMode","onFocus","shouldShowCenteredContent","displayName"],"sources":["../../../../src/components/number-input/NumberInput.tsx"],"sourcesContent":["import React, { ChangeEventHandler, FC, useEffect, useRef, useState } from 'react';\nimport { NUMBER_CLEAR_REGEX } from '../../constants/numberInput';\nimport { formateNumber, isValidString, parseFloatWithDecimals } from '../../utils/numberInput';\nimport Input from '../input/Input';\n\nexport type NumberInputProps = {\n /**\n * Applies rules for decimal input.\n * Enables the user to input one zero as number before the comma\n */\n isDecimalInput?: boolean;\n /**\n * Whether the input is disabled\n */\n isDisabled?: boolean;\n /**\n * Whether the value is invalid.\n */\n isInvalid?: boolean;\n /**\n * Applies rules for money input.\n * Rules: only two decimal places, one zero before the comma\n */\n isMoneyInput?: boolean;\n /**\n * Whether the value should be formatted as a time.\n */\n isTimeInput?: boolean;\n /**\n * Limits the number to this value\n */\n maxNumber?: number;\n /**\n * Limits the number to this value\n */\n minNumber?: number;\n /**\n * Callback function that is called when the input gets out of focus\n */\n onBlur?: (newNumber: number | string | null, isInvalid: boolean) => void;\n /**\n * Callback function that is called when the input changes\n * It will pass the text from the input\n */\n onChange?: (newValue: string) => void;\n /**\n * Placeholder for the input field\n */\n placeholder?: string;\n /**\n * Whether only the bottom border should be displayed\n */\n shouldShowOnlyBottomBorder?: boolean;\n /**\n * Whether the onChange function should be triggert when the value is formatted on the focus or blur\n */\n shouldTriggerChangeOnFormat?: boolean;\n /**\n * The value, that should be displayed in the input, when it is in focus.\n * You can also pass a stringified number as default value.\n * NOTE: If you pass a stringified number, it will be formatted to the selected format\n */\n value?: string;\n};\n\nconst NumberInput: FC<NumberInputProps> = ({\n isDecimalInput,\n isMoneyInput,\n isTimeInput,\n isInvalid,\n maxNumber = Infinity,\n value,\n shouldTriggerChangeOnFormat = true,\n placeholder,\n onBlur,\n isDisabled,\n onChange,\n shouldShowOnlyBottomBorder,\n minNumber = -Infinity,\n}) => {\n // the plainText will be shown in the input, when it is in focus\n const [plainText, setPlainText] = useState<string>('');\n // the formattedValue will be shown in the input, when it is not in focus\n const [formattedValue, setFormattedValue] = useState<string>('');\n const [hasFocus, setHasFocus] = useState<boolean>(false);\n const [shouldRemainPlaceholder, setShouldRemainPlaceholder] = useState<boolean>(false);\n\n const [isValueInvalid, setIsValueInvalid] = useState(false);\n const localPlaceholder = placeholder ?? (isMoneyInput ? '€' : undefined);\n\n const initialInputRef = useRef(true);\n\n const onLocalChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n const newValue = event.target.value;\n\n initialInputRef.current = false;\n\n const sanitizedValueString = newValue\n // Removes everything except numbers, commas and points\n .replace(NUMBER_CLEAR_REGEX, '');\n\n if (\n isTimeInput &&\n ((sanitizedValueString.includes(':') && sanitizedValueString.length > 5) ||\n (!sanitizedValueString.includes(':') && sanitizedValueString.length > 4))\n ) {\n return;\n }\n\n const valueToCheck = sanitizedValueString.replaceAll(',', '.');\n\n if (!isValidString({ string: valueToCheck, isMoneyInput, isDecimalInput, isTimeInput })) {\n return;\n }\n\n if (\n (maxNumber && Number(valueToCheck) > maxNumber) ||\n (minNumber && Number(valueToCheck) < minNumber)\n ) {\n return;\n }\n\n if (newValue.length === 1 && newValue.match(/^[0-9]+$/) === null) {\n setShouldRemainPlaceholder(true);\n } else {\n setShouldRemainPlaceholder(false);\n }\n\n setPlainText(sanitizedValueString.replaceAll('.', ','));\n\n if (typeof onChange === 'function') {\n onChange(sanitizedValueString.replaceAll('.', ','));\n }\n };\n\n const onLocalBlur = () => {\n const sanitizedValue = plainText;\n let newIsInvalid = false;\n let parsedNumber = null;\n\n if (!isTimeInput) {\n parsedNumber = parseFloatWithDecimals({\n stringValue: sanitizedValue.replace(',', '.').replaceAll(':', '').replace('€', ''),\n decimals: isMoneyInput ? 2 : undefined,\n });\n\n if (\n parsedNumber &&\n parsedNumber !== 0 &&\n (parsedNumber > maxNumber || parsedNumber < minNumber)\n ) {\n newIsInvalid = true;\n }\n\n setIsValueInvalid(newIsInvalid);\n }\n\n const newStringValue =\n plainText.length === 0\n ? ''\n : formateNumber({\n number: isTimeInput ? sanitizedValue : parsedNumber,\n isMoneyInput,\n isTimeInput,\n });\n\n setFormattedValue(`${newStringValue} ${isMoneyInput ? '€' : ''}`);\n setPlainText(newStringValue.replaceAll('.', ''));\n setHasFocus(false);\n\n if (typeof onChange === 'function' && shouldTriggerChangeOnFormat) {\n onChange(newStringValue.replaceAll('.', ''));\n }\n\n if (typeof onBlur === 'function') {\n if (isTimeInput) {\n onBlur(newStringValue, newIsInvalid);\n } else {\n onBlur(parsedNumber, newIsInvalid);\n }\n }\n };\n\n const onLocalFocus = () => {\n // formattedValue will be a number string with german number format (e.g. 1.000,00)\n // It will remove all dots, so that the user can type in the number\n setPlainText(formattedValue.replaceAll('.', '').replace('€', '').replaceAll(' ', ''));\n\n // This will update the external state\n if (typeof onChange === 'function' && shouldTriggerChangeOnFormat) {\n onChange(formattedValue.replaceAll('.', '').replace('€', '').replaceAll(' ', ''));\n }\n\n setIsValueInvalid(false);\n setHasFocus(true);\n };\n\n // updates the formattedValue, when the value changes\n useEffect(() => {\n let parsedNumber = null;\n\n if (!isTimeInput) {\n parsedNumber = parseFloatWithDecimals({\n stringValue: plainText\n .replace(',', '.')\n .replaceAll(':', '')\n .replace('€', '')\n .replaceAll(' ', ''),\n decimals: isMoneyInput ? 2 : undefined,\n });\n\n // checks, if a given number is invalid, if the input is not in focus\n if (!hasFocus) {\n if (parsedNumber === null && initialInputRef.current) {\n setIsValueInvalid(false);\n } else {\n setIsValueInvalid(\n parsedNumber === null ||\n parsedNumber > maxNumber ||\n parsedNumber < minNumber,\n );\n }\n }\n }\n\n setFormattedValue(\n plainText.length === 0\n ? ''\n : `${formateNumber({\n number: isTimeInput ? plainText : parsedNumber,\n isMoneyInput,\n isTimeInput,\n })}${isMoneyInput ? ' €' : ''}`,\n );\n }, [hasFocus, isMoneyInput, isTimeInput, maxNumber, minNumber, plainText]);\n\n useEffect(() => {\n if (typeof value === 'string') {\n setPlainText(value.replace('€', '').replaceAll(' ', ''));\n }\n }, [value]);\n\n return (\n <Input\n shouldRemainPlaceholder={shouldRemainPlaceholder}\n shouldShowOnlyBottomBorder={shouldShowOnlyBottomBorder}\n inputMode=\"decimal\"\n onChange={onLocalChange}\n value={hasFocus ? plainText : formattedValue}\n placeholder={localPlaceholder}\n onBlur={onLocalBlur}\n onFocus={onLocalFocus}\n isDisabled={isDisabled}\n isInvalid={typeof isInvalid === 'boolean' ? isInvalid : isValueInvalid}\n shouldShowCenteredContent={shouldShowOnlyBottomBorder}\n />\n );\n};\n\nNumberInput.displayName = 'NumberInput';\n\nexport default NumberInput;\n"],"mappings":"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","ignoreList":[]}
@@ -3,6 +3,9 @@ export const parseFloatWithDecimals = ({
3
3
  stringValue,
4
4
  decimals
5
5
  }) => {
6
+ if (stringValue === '') {
7
+ return null;
8
+ }
6
9
  const parsed = parseFloat(stringValue);
7
10
  if (decimals) {
8
11
  return parseFloat(parsed.toFixed(decimals));
@@ -1 +1 @@
1
- {"version":3,"file":"numberInput.js","names":["DECIMAL_TEST","INTEGER_TEST","MONEY_TEST","TIME_TEST","parseFloatWithDecimals","stringValue","decimals","parsed","parseFloat","toFixed","formateNumber","number","isMoneyInput","isTimeInput","hours","minutes","firstTwoDigits","substring","includes","replace","firstTwoNumbers","Number","lastTwoNumbers","lastTwoNumbersLength","length","hoursStr","minutesStr","toLocaleString","useGrouping","minimumFractionDigits","undefined","maximumFractionDigits","maximumSignificantDigits","isValidString","isDecimalInput","string","isValid","test","startsWith"],"sources":["../../../src/utils/numberInput.ts"],"sourcesContent":["import { DECIMAL_TEST, INTEGER_TEST, MONEY_TEST, TIME_TEST } from '../constants/numberInput';\n\ninterface ParseFloatWithDecimals {\n ({ stringValue, decimals }: { stringValue: string; decimals?: number }): number;\n}\n\nexport const parseFloatWithDecimals: ParseFloatWithDecimals = ({ stringValue, decimals }) => {\n const parsed = parseFloat(stringValue);\n\n if (decimals) {\n return parseFloat(parsed.toFixed(decimals));\n }\n\n return parsed;\n};\n\ninterface FormateNumberOptions {\n number: number | string | null;\n isMoneyInput?: boolean;\n isTimeInput?: boolean;\n}\n\nexport const formateNumber = ({ number, isMoneyInput, isTimeInput }: FormateNumberOptions) => {\n if (isTimeInput && typeof number === 'string') {\n let hours = 0;\n let minutes = 0;\n\n let firstTwoDigits = number.substring(0, 2);\n\n if (firstTwoDigits.includes(':')) {\n firstTwoDigits = firstTwoDigits.replace(':', '');\n\n firstTwoDigits = `0${firstTwoDigits}`;\n }\n\n const firstTwoNumbers = Number(firstTwoDigits);\n let lastTwoNumbers = 0;\n let lastTwoNumbersLength = 0;\n\n if (number.includes(':')) {\n lastTwoNumbers = Number(number.substring(3, 5));\n lastTwoNumbersLength = number.substring(3, 5).length;\n } else {\n lastTwoNumbers = Number(number.substring(2, 4));\n lastTwoNumbersLength = number.substring(2, 4).length;\n }\n\n hours = firstTwoNumbers > 23 ? 23 : firstTwoNumbers;\n\n if (lastTwoNumbers < 7 && lastTwoNumbersLength === 1) {\n minutes = lastTwoNumbers * 10;\n } else {\n minutes = lastTwoNumbers > 59 ? 59 : lastTwoNumbers;\n }\n\n const hoursStr = hours < 10 ? `0${hours}` : `${hours}`;\n const minutesStr = minutes < 10 ? `0${minutes}` : `${minutes}`;\n\n return `${hoursStr}:${minutesStr}`;\n }\n\n if (typeof number !== 'number') {\n return '';\n }\n\n return number.toLocaleString('de-DE', {\n useGrouping: true,\n minimumFractionDigits: isMoneyInput ? 2 : undefined,\n maximumFractionDigits: isMoneyInput ? 2 : undefined,\n maximumSignificantDigits: !isMoneyInput ? 20 : undefined,\n });\n};\n\ninterface IsValidString {\n (config: {\n string: string;\n isDecimalInput?: boolean;\n isMoneyInput?: boolean;\n isTimeInput?: boolean;\n }): boolean;\n}\n\nexport const isValidString: IsValidString = ({\n isDecimalInput,\n isMoneyInput,\n isTimeInput,\n string,\n}) => {\n let isValid = false;\n\n // Allows numbers, one (comma/point) and any number of decimal places\n if (isDecimalInput && DECIMAL_TEST.test(string)) {\n isValid = true;\n }\n\n // Allows numbers but excludes numbers with leading 0\n if (isMoneyInput && MONEY_TEST.test(string)) {\n isValid = true;\n }\n\n if (isTimeInput && TIME_TEST) {\n isValid = true;\n }\n\n // Allows numbers but excludes numbers with leading 0\n if (!isDecimalInput && !isMoneyInput && !isTimeInput && INTEGER_TEST.test(string)) {\n isValid = true;\n }\n\n if (string.length === 0) {\n isValid = true;\n }\n\n if (string.startsWith('0')) {\n isValid = true;\n }\n\n return isValid;\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"numberInput.js","names":["DECIMAL_TEST","INTEGER_TEST","MONEY_TEST","TIME_TEST","parseFloatWithDecimals","stringValue","decimals","parsed","parseFloat","toFixed","formateNumber","number","isMoneyInput","isTimeInput","hours","minutes","firstTwoDigits","substring","includes","replace","firstTwoNumbers","Number","lastTwoNumbers","lastTwoNumbersLength","length","hoursStr","minutesStr","toLocaleString","useGrouping","minimumFractionDigits","undefined","maximumFractionDigits","maximumSignificantDigits","isValidString","isDecimalInput","string","isValid","test","startsWith"],"sources":["../../../src/utils/numberInput.ts"],"sourcesContent":["import { DECIMAL_TEST, INTEGER_TEST, MONEY_TEST, TIME_TEST } from '../constants/numberInput';\n\ninterface ParseFloatWithDecimals {\n ({ stringValue, decimals }: { stringValue: string; decimals?: number }): number | null;\n}\n\nexport const parseFloatWithDecimals: ParseFloatWithDecimals = ({ stringValue, decimals }) => {\n if (stringValue === '') {\n return null;\n }\n\n const parsed = parseFloat(stringValue);\n\n if (decimals) {\n return parseFloat(parsed.toFixed(decimals));\n }\n\n return parsed;\n};\n\ninterface FormateNumberOptions {\n number: number | string | null;\n isMoneyInput?: boolean;\n isTimeInput?: boolean;\n}\n\nexport const formateNumber = ({ number, isMoneyInput, isTimeInput }: FormateNumberOptions) => {\n if (isTimeInput && typeof number === 'string') {\n let hours = 0;\n let minutes = 0;\n\n let firstTwoDigits = number.substring(0, 2);\n\n if (firstTwoDigits.includes(':')) {\n firstTwoDigits = firstTwoDigits.replace(':', '');\n\n firstTwoDigits = `0${firstTwoDigits}`;\n }\n\n const firstTwoNumbers = Number(firstTwoDigits);\n let lastTwoNumbers = 0;\n let lastTwoNumbersLength = 0;\n\n if (number.includes(':')) {\n lastTwoNumbers = Number(number.substring(3, 5));\n lastTwoNumbersLength = number.substring(3, 5).length;\n } else {\n lastTwoNumbers = Number(number.substring(2, 4));\n lastTwoNumbersLength = number.substring(2, 4).length;\n }\n\n hours = firstTwoNumbers > 23 ? 23 : firstTwoNumbers;\n\n if (lastTwoNumbers < 7 && lastTwoNumbersLength === 1) {\n minutes = lastTwoNumbers * 10;\n } else {\n minutes = lastTwoNumbers > 59 ? 59 : lastTwoNumbers;\n }\n\n const hoursStr = hours < 10 ? `0${hours}` : `${hours}`;\n const minutesStr = minutes < 10 ? `0${minutes}` : `${minutes}`;\n\n return `${hoursStr}:${minutesStr}`;\n }\n\n if (typeof number !== 'number') {\n return '';\n }\n\n return number.toLocaleString('de-DE', {\n useGrouping: true,\n minimumFractionDigits: isMoneyInput ? 2 : undefined,\n maximumFractionDigits: isMoneyInput ? 2 : undefined,\n maximumSignificantDigits: !isMoneyInput ? 20 : undefined,\n });\n};\n\ninterface IsValidString {\n (config: {\n string: string;\n isDecimalInput?: boolean;\n isMoneyInput?: boolean;\n isTimeInput?: boolean;\n }): boolean;\n}\n\nexport const isValidString: IsValidString = ({\n isDecimalInput,\n isMoneyInput,\n isTimeInput,\n string,\n}) => {\n let isValid = false;\n\n // Allows numbers, one (comma/point) and any number of decimal places\n if (isDecimalInput && DECIMAL_TEST.test(string)) {\n isValid = true;\n }\n\n // Allows numbers but excludes numbers with leading 0\n if (isMoneyInput && MONEY_TEST.test(string)) {\n isValid = true;\n }\n\n if (isTimeInput && TIME_TEST) {\n isValid = true;\n }\n\n // Allows numbers but excludes numbers with leading 0\n if (!isDecimalInput && !isMoneyInput && !isTimeInput && INTEGER_TEST.test(string)) {\n isValid = true;\n }\n\n if (string.length === 0) {\n isValid = true;\n }\n\n if (string.startsWith('0')) {\n isValid = true;\n }\n\n return isValid;\n};\n"],"mappings":"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","ignoreList":[]}
@@ -2,7 +2,7 @@ interface ParseFloatWithDecimals {
2
2
  ({ stringValue, decimals }: {
3
3
  stringValue: string;
4
4
  decimals?: number;
5
- }): number;
5
+ }): number | null;
6
6
  }
7
7
  export declare const parseFloatWithDecimals: ParseFloatWithDecimals;
8
8
  interface FormateNumberOptions {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chayns-components/core",
3
- "version": "5.0.0-beta.1257",
3
+ "version": "5.0.0-beta.1261",
4
4
  "description": "A set of beautiful React components for developing your own applications with chayns.",
5
5
  "sideEffects": false,
6
6
  "browserslist": [
@@ -23,8 +23,9 @@
23
23
  "exports": {
24
24
  ".": {
25
25
  "types": "./lib/types/index.d.ts",
26
+ "node": "./lib/cjs/index.js",
26
27
  "require": "./lib/cjs/index.js",
27
- "import": "./lib/esm/index.js"
28
+ "default": "./lib/esm/index.js"
28
29
  }
29
30
  },
30
31
  "directories": {
@@ -85,5 +86,5 @@
85
86
  "publishConfig": {
86
87
  "access": "public"
87
88
  },
88
- "gitHead": "12b9552306e97366118d0ef56c225433fea1b6ae"
89
+ "gitHead": "2facfbaea4548854cd3aa824a72aa6623c3861b9"
89
90
  }