diff --git a/src/forms/NewFormikNumberField.stories.tsx b/src/forms/NewFormikNumberField.stories.tsx
new file mode 100644
index 00000000..6729c17f
--- /dev/null
+++ b/src/forms/NewFormikNumberField.stories.tsx
@@ -0,0 +1,356 @@
+import { Form, Formik } from 'formik'
+import React from 'react'
+import * as yup from 'yup'
+import Button from '../Button'
+import FormikNumberField from './NewFormikNumberField'
+
+export const Default = () => (
+
+
The default Formik field works with a "name" input
+
{
+ alert(`Form submitted with value: ${values.name}`)
+ resetForm()
+ }}
+ >
+ {({ values }) => {
+ return (
+
+
+
Value: {values.name}
+
+ )
+ }}
+
+
+)
+
+export const MinMax = () => (
+
+
+ Specifying minimum and maximum values will enable additional validation
+ steps. In this case, values between 0 and 1000 will be accepted
+
+
{
+ alert(`Form submitted with value: ${values.name}`)
+ resetForm()
+ }}
+ >
+ {({ values }) => {
+ return (
+
+
+
Value: {values.name}
+
+ )
+ }}
+
+
+)
+
+export const Disabled = () => (
+
+
+ Number inputs can also be disabled with a corresponding prop, not allowing
+ the user to make changes to the field.
+
+
{
+ alert(`Form submitted with value: ${values.name}`)
+ resetForm()
+ }}
+ >
+ {({ values }) => {
+ return (
+
+
+
Value: {values.name}
+
+ )
+ }}
+
+
+)
+
+export const Validation = () => (
+
+
+ This formik field has validation functionalities included. The value is
+ required and should be at least 100.
+
+
{
+ alert(`Form submitted with value: ${parseFloat(values.name || '')}`)
+ resetForm()
+ }}
+ validationSchema={yup.object().shape({
+ name: yup.number().required('This field is required.').min(100),
+ })}
+ >
+ {({ values }) => {
+ return (
+
+
+
+ Value that will be submitted with parseFloat():{' '}
+ {parseFloat(values.name || '')}
+
+
+ )
+ }}
+
+
+)
+
+export const Decimals = () => (
+
+
+ The default Formik field works with a "name" input and allows the user to
+ input decimal numbers as well as integers. The number of decimal places
+ can be specified through the precision prop (set to 2 for this example).
+
+
{
+ alert(`Form submitted with value: ${parseFloat(values.name || '')}`)
+ resetForm()
+ }}
+ >
+ {({ values }) => {
+ return (
+
+
+
+ Value that will be submitted with parseFloat():{' '}
+ {parseFloat(values.name || '')}
+
+
+ )
+ }}
+
+
+)
+
+export const Integer = () => (
+
+
+ By fixing the precision parameter to 0, the user can only input integers.
+
+
{
+ alert(`Form submitted with value: ${parseFloat(values.name || '')}`)
+ resetForm()
+ }}
+ >
+ {({ values }) => {
+ return (
+
+
+
+ Value that will be submitted with parseFloat():{' '}
+ {parseFloat(values.name || '')}
+
+
+ )
+ }}
+
+
+)
+
+export const Required = () => (
+
+
+ By adding a required attribute, the label of the field changes it
+ appearance
+
+
{
+ alert(`Form submitted with value: ${values.name}`)
+ resetForm()
+ }}
+ >
+ {({ values }) => {
+ return (
+
+
+
Value: {values.name}
+
+ )
+ }}
+
+
+)
+
+export const Styled = () => (
+
+
The default Formik field works with a "name" input
+
{
+ alert(`Form submitted with value: ${values.name}`)
+ resetForm()
+ }}
+ >
+ {({ values }) => {
+ return (
+
+
+
Value: {values.name}
+
+ )
+ }}
+
+
+)
+
+export const SmallLabel = () => (
+
+
+ Formik text area component with a small label (designed e.g. for login
+ forms)
+
+
{
+ alert(`Form submitted with value: ${values.name}`)
+ resetForm()
+ }}
+ >
+ {({ values }) => {
+ return (
+
+
+
Value: {values.name}
+
+ )
+ }}
+
+
+)
diff --git a/src/forms/NewFormikNumberField.tsx b/src/forms/NewFormikNumberField.tsx
new file mode 100644
index 00000000..718d5a3f
--- /dev/null
+++ b/src/forms/NewFormikNumberField.tsx
@@ -0,0 +1,149 @@
+import { useField } from 'formik'
+import React from 'react'
+import { twMerge } from 'tailwind-merge'
+import NumberField, { NumberFieldClassName } from './NumberField'
+
+interface FormikNumberFieldProps {
+ id?: string
+ label?: string
+ labelType?: 'small' | 'large'
+ placeholder?: string
+ precision?: number
+ min?: number
+ max?: number
+ tooltip?: string | React.ReactNode
+ required?: boolean
+ hideError?: boolean
+ error?: string
+ disabled?: boolean
+ onBlur?: () => void
+ data?: {
+ cy?: string
+ test?: string
+ }
+ className?: NumberFieldClassName & { root?: string }
+ [key: string]: any
+}
+
+export interface FormikNumberFieldNameProps extends FormikNumberFieldProps {
+ name: string
+ value?: never
+ onChange?: never
+ isTouched?: never
+}
+
+export interface FormikNumberFieldOnChangeProps extends FormikNumberFieldProps {
+ name?: never
+ value: string
+ onChange: (newValue: string) => void
+ isTouched?: boolean
+}
+
+/**
+ * This function returns a text field component for use without formik
+ *
+ * @param id - The id of the input field.
+ * @param value - The value of the input field (external state management).
+ * @param onChange - The onChange function of the input field (external state management).
+ * @param label - The text displayed as label.
+ * @param labelType - The optional labelType can be used to change the size and position of the label according to pre-defined standards.
+ * @param placeholder - The placeholder text for the input field.
+ * @param precision - The optional precision defines the number of decimal places that are allowed.
+ * @param min - The optional min defines the minimum value that is allowed.
+ * @param max - The optional max defines the maximum value that is allowed.
+ * @param tooltip - The optional tooltip is shown on hover over the tooltip next to the label.
+ * @param required - Indicate whether the field is required or not.
+ * @param hideError - Indicate whether the error message should be hidden or not.
+ * @param error - The error message that is displayed below the input field.
+ * @param isTouched - Indicate whether the field has been touched or not (validation is not handled by this component).
+ * @param disabled - Indicate whether the field is disabled or not.
+ * @param onBlur - The onBlur function of the input field.
+ * @param data - The object of data attributes that can be used for testing (e.g. data-test or data-cy)
+ * @param className - The optional className object allows you to override the default styling.
+ */
+export function FormikNumberField({
+ id,
+ name,
+ value,
+ onChange,
+ label,
+ labelType,
+ placeholder,
+ precision,
+ min,
+ max,
+ tooltip,
+ required,
+ hideError,
+ error,
+ isTouched,
+ disabled,
+ onBlur,
+ data,
+ className,
+ ...props
+}: FormikNumberFieldNameProps | FormikNumberFieldOnChangeProps) {
+ const [field, meta, helpers] = useField(name || '')
+
+ if (name) {
+ return (
+
+ helpers.setValue(newValue)}
+ label={label}
+ labelType={labelType}
+ placeholder={placeholder}
+ precision={precision}
+ min={min}
+ max={max}
+ tooltip={tooltip}
+ required={required}
+ hideError={hideError}
+ error={meta.error}
+ isTouched={meta.touched}
+ disabled={disabled}
+ onBlur={() => {
+ helpers.setTouched(true)
+ onBlur?.()
+ }}
+ data={data}
+ className={className}
+ {...props}
+ />
+
+ )
+ }
+
+ return (
+
+ {
+ helpers.setTouched(true)
+ onBlur?.()
+ }}
+ data={data}
+ className={className}
+ {...props}
+ />
+
+ )
+}
+
+export default FormikNumberField
diff --git a/src/forms/NewFormikTextField.tsx b/src/forms/NewFormikTextField.tsx
index e5171904..cc22341c 100644
--- a/src/forms/NewFormikTextField.tsx
+++ b/src/forms/NewFormikTextField.tsx
@@ -31,6 +31,7 @@ export interface FormikTextFieldWithNameProps extends FormikTextFieldProps {
value?: never
onChange?: never
error?: never
+ isTouched?: never
[key: string]: any
}
export interface FormikTextFieldWithOnChangeProps extends FormikTextFieldProps {
@@ -38,6 +39,7 @@ export interface FormikTextFieldWithOnChangeProps extends FormikTextFieldProps {
value: string
onChange: (newValue: string) => void
error?: string
+ isTouched?: boolean
[key: string]: any
}
@@ -79,6 +81,7 @@ export function FormikTextField({
tooltip,
required = false,
hideError = false,
+ isTouched = false,
disabled = false,
onPaste,
className,
@@ -88,7 +91,7 @@ export function FormikTextField({
if (name) {
return (
-
+
+
)
}
+
+export function SmallLabel() {
+ const [value, setValue] = useState('')
+ return (
+
+
setValue(newValue)}
+ label="Nunber Field"
+ labelType="small"
+ tooltip="This is a tooltip for the number field"
+ required
+ />
+ Value: {value}
+
+ )
+}
+
+export function Error() {
+ const [value, setValue] = useState('')
+ const [touched, setTouched] = useState(false)
+
+ return (
+
+
+ As soon as the field has been touched, an error will be displayed.
+
+
setValue(newValue)}
+ onBlur={() => setTouched(true)}
+ label="Nunber Field"
+ labelType="small"
+ tooltip="This is a tooltip for the number field"
+ error="This is an error message"
+ isTouched={touched}
+ required
+ />
+ Value: {value}
+
+ )
+}
diff --git a/src/forms/NumberField.tsx b/src/forms/NumberField.tsx
index bd3998ea..21198124 100644
--- a/src/forms/NumberField.tsx
+++ b/src/forms/NumberField.tsx
@@ -1,32 +1,40 @@
+import { faCircleExclamation } from '@fortawesome/free-solid-svg-icons'
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import React from 'react'
import { twMerge } from 'tailwind-merge'
+import { Tooltip } from '../Tooltip'
import Label from './Label'
export interface NumberFieldClassName {
- root?: string
- input?: string
+ field?: string
label?: string
+ input?: string
+ error?: string
tooltip?: string
}
export interface NumberFieldProps {
id?: string
- data?: {
- cy?: string
- test?: string
- }
value: string | number
onChange: (newValue: string) => void
label?: string
- tooltip?: string | React.ReactNode
- required?: boolean
- onBlur?: () => void
+ labelType?: 'small' | 'large'
placeholder?: string
- disabled?: boolean
- className?: NumberFieldClassName
precision?: number
min?: number
max?: number
+ tooltip?: string | React.ReactNode
+ required?: boolean
+ hideError?: boolean
+ error?: string
+ isTouched?: boolean
+ disabled?: boolean
+ onBlur?: () => void
+ data?: {
+ cy?: string
+ test?: string
+ }
+ className?: NumberFieldClassName
[key: string]: any
}
@@ -34,38 +42,46 @@ export interface NumberFieldProps {
* This function returns a text field component for use without formik
*
* @param id - The id of the input field.
- * @param data - The object of data attributes that can be used for testing (e.g. data-test or data-cy)
* @param value - The value of the input field (external state management).
* @param onChange - The onChange function of the input field (external state management).
* @param label - The text displayed as label.
- * @param tooltip - The optional tooltip is shown on hover over the tooltip next to the label.
- * @param required - Indicate whether the field is required or not.
- * @param onBlur - The onBlur function of the input field.
+ * @param labelType - The optional labelType can be used to change the size and position of the label according to pre-defined standards.
* @param placeholder - The placeholder text for the input field.
- * @param disabled - Indicate whether the field is disabled or not.
* @param precision - The optional precision defines the number of decimal places that are allowed.
* @param min - The optional min defines the minimum value that is allowed.
* @param max - The optional max defines the maximum value that is allowed.
+ * @param tooltip - The optional tooltip is shown on hover over the tooltip next to the label.
+ * @param required - Indicate whether the field is required or not.
+ * @param hideError - Indicate whether the error message should be hidden or not.
+ * @param error - The error message that is displayed below the input field.
+ * @param isTouched - Indicate whether the field has been touched or not (validation is not handled by this component).
+ * @param disabled - Indicate whether the field is disabled or not.
+ * @param onBlur - The onBlur function of the input field.
+ * @param data - The object of data attributes that can be used for testing (e.g. data-test or data-cy)
* @param className - The optional className object allows you to override the default styling.
*/
-
export function NumberField({
id,
- data,
value,
onChange,
label,
- tooltip,
- required,
- onBlur,
+ labelType,
placeholder,
- disabled,
precision,
min,
max,
+ tooltip,
+ required,
+ hideError,
+ error,
+ isTouched,
+ disabled,
+ onBlur,
+ data,
className,
+ ...props
}: NumberFieldProps): React.ReactElement {
- const regex =
+ const validInput =
typeof precision === 'number' && !isNaN(precision)
? precision === 0
? /^[-]?\d*$/
@@ -73,51 +89,77 @@ export function NumberField({
: /^[-]?\d*\.?\d*$/
return (
-
+
)
}
diff --git a/src/forms/TextField.tsx b/src/forms/TextField.tsx
index 68b5a7e0..4c5d4011 100644
--- a/src/forms/TextField.tsx
+++ b/src/forms/TextField.tsx
@@ -100,7 +100,7 @@ export function TextField({
@@ -176,7 +176,7 @@ export function TextField({
/>
)}
- {error && !hideError && (
+ {error && !hideError && isTouched && (