Skip to content

Commit

Permalink
feat(Forms): add support for conditional function based info, `warn…
Browse files Browse the repository at this point in the history
…ing` and `error` props to all `Field.*` components
  • Loading branch information
tujoworker committed Dec 20, 2024
1 parent 41e4131 commit c47a0b3
Show file tree
Hide file tree
Showing 6 changed files with 345 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ComponentBox from '../../../../../../shared/tags/ComponentBox'
import { Slider, Grid, Flex } from '@dnb/eufemia/src'
import { Field, Form } from '@dnb/eufemia/src/extensions/forms'
import React from 'react'
import ComponentBox from '../../../../../../shared/tags/ComponentBox'
import { Slider, Grid, Flex, Anchor } from '@dnb/eufemia/src'
import { Field, Form, FormError } from '@dnb/eufemia/src/extensions/forms'

export const Placeholder = () => {
return (
Expand Down Expand Up @@ -421,3 +421,88 @@ export const WithSlider = () => (
}}
</ComponentBox>
)

export const ConditionalInfo = () => {
return (
<ComponentBox scope={{ FormError }}>
{() => {
const conditionalInfo = (
maximum: number,
{ renderMode, getValueByPath, getFieldByPath },
) => {
renderMode('initially') // Your can also use 'continuously' or 'always'

const amount = getValueByPath('/amount')
const { props } = getFieldByPath('/amount')

if (maximum < amount && props) {
const anchor = (
<Anchor
href="#"
onClick={(event) => {
event.preventDefault()
const el = document.getElementById(props.id + '-label')
el?.scrollIntoView()
}}
>
{props.label}
</Anchor>
)

return (
<>
Remember to adjust the {anchor} to be {maximum} or lower.
</>
)
}
}
const onBlurValidator = (amount: number, { connectWithPath }) => {
const { getValue: getMaximum } = connectWithPath('/maximum')

if (amount > getMaximum()) {
return new FormError('NumberField.errorMaximum', {
messageValues: {
maximum: getMaximum(),
},
})
}
}
return (
<Form.Handler
defaultData={{
maximum: 4,
amount: 5,
}}
>
<Form.Card>
<Field.Number
label="Maximum for amount"
labelDescription={
<>
<br />
Defines the maximum amount possible to be entered.
</>
}
path="/maximum"
info={conditionalInfo}
/>
<Field.Number
label="Amount"
labelDescription={
<>
<br />
Should be same or lower than maximum.
</>
}
path="/amount"
onBlurValidator={onBlurValidator}
/>
</Form.Card>

<Form.SubmitButton />
</Form.Handler>
)
}}
</ComponentBox>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ You can also use a function as a prefix or suffix.

<Examples.ValidateMaximumCustomError />

### Validation - Conditional info message

You can provide a function to the `info`, `warning` or `error` props that returns a message based on your conditions.

<Examples.ConditionalInfo />

### Percentage

<Examples.Percentage />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback } from 'react'
import { Field, Form, UseFieldProps } from '../../..'
import { Flex } from '../../../../../components'
import { Field, Form, FormError, UseFieldProps } from '../../..'
import { Anchor, Flex } from '../../../../../components'

export default {
title: 'Eufemia/Extensions/Forms/Number',
Expand Down Expand Up @@ -84,3 +84,83 @@ export const WithFreshValidator = () => {
</Form.Handler>
)
}

export const ConditionalInfo = () => {
const conditionalInfo = (
maximum: number,
{ renderMode, getValueByPath, getFieldByPath }
) => {
renderMode('initially')
// renderMode('continuously')
// renderMode('always')

const amount = getValueByPath('/amount')
const { props } = getFieldByPath('/amount')

if (maximum < amount && props) {
const anchor = (
<Anchor
href={`#${props?.id}-label`}
onClick={(event: React.MouseEvent<HTMLAnchorElement>) => {
event.preventDefault()
const el = document.getElementById(`${props.id}-label`)
el?.scrollIntoView()
}}
>
{props?.label}
</Anchor>
)

return (
<>
Remember to adjust the {anchor} to be {maximum} or lower.{' '}
</>
)
}
}
const onBlurValidator = (amount: number, { connectWithPath }) => {
const { getValue: getMaximum } = connectWithPath('/maximum')

if (amount > getMaximum()) {
return new FormError('NumberField.errorMaximum', {
messageValues: {
maximum: getMaximum(),
},
})
}
}
return (
<Form.Handler
defaultData={{
maximum: 4,
amount: 5,
}}
>
<Form.Card>
<Field.Number
label="Maximum for amount"
labelDescription={
'\nDefines the maximum amount possible to be entered.'
}
path="/maximum"
// defaultValue={4}
info={conditionalInfo}
// warning={conditionalInfo}
// validateInitially
// validateUnchanged
// continuousValidation
/>
<Field.Number
label="Amount"
labelDescription={'\nShould be same or lower than maximum.'}
path="/amount"
// defaultValue={5}
onBlurValidator={onBlurValidator}
// validateInitially
/>
</Form.Card>

<Form.SubmitButton />
</Form.Handler>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ function FieldBlock(props: Props) {
})

const labelProps: FormLabelAllProps = {
id: `${id}-label`,
className: 'dnb-forms-field-block__label',
element: enableFieldset ? 'legend' : 'label',
forId: enableFieldset ? undefined : forId,
Expand Down
Loading

0 comments on commit c47a0b3

Please sign in to comment.