Skip to content

Commit

Permalink
Make validateInitially={false} on field work together with validate…
Browse files Browse the repository at this point in the history
…Initially on section
  • Loading branch information
tujoworker committed Sep 11, 2024
1 parent 7517098 commit b432a50
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import { Flex } from '../../../../../components'
import { Props as FlexContainerProps } from '../../../../../components/flex/Container'
import { Lead } from '../../../../../elements'
import FieldBoundaryProvider from '../../../DataContext/FieldBoundary/FieldBoundaryProvider'
import SectionContainerContext from '../containers/SectionContainerContext'
import EditToolbarTools from './EditToolbarTools'
import SectionContainer, {
SectionContainerProps,
} from '../containers/SectionContainer'
import Toolbar from '../containers/Toolbar'
import { Path } from '../../../types'
import SectionContainerContext from '../containers/SectionContainerContext'

export type Props = {
title?: React.ReactNode
Expand All @@ -36,7 +36,7 @@ function EditContainer(props: AllProps) {

return (
<FieldBoundaryProvider
showErrors={validateInitially && initialContainerMode === 'auto'}
showErrors={validateInitially}
onPathError={onPathError}
>
<SectionContainer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ export default function EditToolbarTools() {

return (
<>
<FormStatus show={showError && hasVisibleError} no_animation={false}>
{translation.errorInSection}
</FormStatus>
<Flex.Horizontal gap="large">
<Button
variant="tertiary"
Expand All @@ -84,6 +81,14 @@ export default function EditToolbarTools() {
{translation.cancelButton}
</Button>
</Flex.Horizontal>

<FormStatus
show={showError && hasVisibleError}
shellSpace={{ top: 'x-small' }}
no_animation={false}
>
{translation.errorInSection}
</FormStatus>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,26 @@ describe('EditContainer and ViewContainer', () => {
expect(containerMode).toBe('view')
})

it('fields with validateInitially=false should not validate initially', async () => {
render(
<Form.Section validateInitially>
<Form.Section.EditContainer>
<Field.String required />
<Field.String required validateInitially={false} />
</Form.Section.EditContainer>
</Form.Section>
)

expect(document.querySelectorAll('.dnb-form-status')).toHaveLength(1)
const [, second] = Array.from(document.querySelectorAll('input'))
expect(second).toHaveValue('')

await userEvent.type(second, 'x{Backspace}')
fireEvent.blur(second)

expect(document.querySelectorAll('.dnb-form-status')).toHaveLength(2)
})

it('the cancel button should not cancel the edit mode', async () => {
let containerMode = null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ export function OpenWhenFieldValidationError() {
return (
<Form.Section.EditContainer>
<Field.Name.First path="/firstName" />
<Field.Name.Last path="/lastName" />
<Field.Name.Last path="/lastName" validateInitially={false} />
</Form.Section.EditContainer>
)
}, [])
Expand All @@ -272,6 +272,7 @@ export function OpenWhenFieldValidationError() {
defaultData={{
nestedPath: {
firstName: 'Nora',
lastName: undefined, // initiate error
},
}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,29 @@ describe('useFieldProps', () => {
})
})

it('should not return error when validateInitially is set to false', async () => {
const { result } = renderHook(useFieldProps, {
initialProps: {
value: '',
error: new Error('Error message'),
validateInitially: false,
},
})

await waitFor(() => {
expect(result.current.error).toBeUndefined()
})

act(() => {
result.current.handleChange('x')
result.current.handleBlur()
})

await waitFor(() => {
expect(result.current.error).toBeInstanceOf(Error)
})
})

describe('with async validator', () => {
const validateBlur = async (result, value = Date.now()) => {
act(() => {
Expand Down
17 changes: 14 additions & 3 deletions packages/dnb-eufemia/src/extensions/forms/hooks/useFieldProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ export default function useFieldProps<Value, EmptyValue, Props>(
// - Should errors received through validation be shown initially. Assume that providing a direct prop to
// the component means it is supposed to be shown initially.
const revealErrorRef = useRef<boolean>(
Boolean(validateInitially || errorProp)
validateInitially ?? Boolean(errorProp)
)
// - Local errors are errors based on validation instructions received by
const errorMethodRef = useRef<
Expand Down Expand Up @@ -367,16 +367,27 @@ export default function useFieldProps<Value, EmptyValue, Props>(
)

const revealError = useCallback(() => {
// To support "validateInitially={false}" prop, we need to make sure that the error is not shown initially
if (revealErrorRef.current === false && validateInitially === false) {
revealErrorRef.current = undefined
return // stop here
}

if (!revealErrorRef.current) {
revealErrorRef.current = true
showFieldErrorFieldBlock?.(identifier, true)
setHasVisibleErrorDataContext?.(identifier, !!localErrorRef.current)
}
}, [identifier, setHasVisibleErrorDataContext, showFieldErrorFieldBlock])
}, [
identifier,
setHasVisibleErrorDataContext,
showFieldErrorFieldBlock,
validateInitially,
])

const hideError = useCallback(() => {
if (revealErrorRef.current) {
revealErrorRef.current = false
revealErrorRef.current = undefined
showFieldErrorFieldBlock?.(identifier, false)
setHasVisibleErrorDataContext?.(identifier, false)
}
Expand Down

0 comments on commit b432a50

Please sign in to comment.