From 645a24bdb2ece78afd5a0b00fe82d4289490b013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20H=C3=B8egh?= Date: Tue, 7 Jan 2025 13:38:45 +0100 Subject: [PATCH] Enhance resetting --- .../forms/base-fields/Number/Examples.tsx | 4 +--- .../forms/base-fields/Number/demos.mdx | 2 +- .../Field/Number/__tests__/Number.test.tsx | 5 ++-- .../Field/Number/stories/Number.stories.tsx | 5 ++-- .../forms/FieldBlock/FieldBlock.tsx | 24 +++++-------------- .../extensions/forms/hooks/useFieldProps.ts | 8 +++++++ 6 files changed, 21 insertions(+), 27 deletions(-) diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/Examples.tsx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/Examples.tsx index 654759d174d..d40a3407398 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/Examples.tsx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/Examples.tsx @@ -490,9 +490,7 @@ export const ConditionalInfo = () => { path="/amount" required onBlurValidator={(amount: number, { connectWithPath }) => { - const { getValue: getMaximum } = - connectWithPath('/maximum') - const maximum = getMaximum() + const maximum = connectWithPath('/maximum').getValue() if (amount > maximum) { return new FormError('NumberField.errorMaximum', { diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/demos.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/demos.mdx index d768fd98f8e..679c8406222 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/demos.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/demos.mdx @@ -86,7 +86,7 @@ Optionally, use the `visibleWhen` modifier function to control when the message - `onBlur` – The **preferred** UX behavior. It will show the message only when the field is blurred (onBlur). - `initially` – It will show the message initially, and later like `onBlur`. -- `continuously` – It will show the message on every change. +- `continuously` – It will show and update the message on every field value change. - `always` – Same as `initially` and `continuously` together. diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Number/__tests__/Number.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/Number/__tests__/Number.test.tsx index 72262a684c3..8a98afe98e8 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Number/__tests__/Number.test.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Number/__tests__/Number.test.tsx @@ -248,11 +248,13 @@ describe('Field.Number', () => { document.querySelector('.dnb-form-status') ).not.toBeInTheDocument() + await userEvent.type(input, '4') + expect( document.querySelector('.dnb-form-status') ).not.toBeInTheDocument() - await userEvent.type(input, '4') + await userEvent.tab() expect( document.querySelector('.dnb-form-status') @@ -264,7 +266,6 @@ describe('Field.Number', () => { document.querySelector('.dnb-form-status') ).not.toBeInTheDocument() - await userEvent.tab() await userEvent.type(input, '4') expect( diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Number/stories/Number.stories.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/Number/stories/Number.stories.tsx index 7dd2deaa2d8..4aba49d5ca5 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Number/stories/Number.stories.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Number/stories/Number.stories.tsx @@ -91,7 +91,7 @@ export const ConditionalInfo = () => { { visibleWhen, getValueByPath, getFieldByPath } ) => { if (maximum < getValueByPath('/amount')) { - visibleWhen('continuously') + visibleWhen('initially') const { props, id } = getFieldByPath('/amount') @@ -122,8 +122,7 @@ export const ConditionalInfo = () => { amount: number, { connectWithPath } ) => { - const { getValue: getMaximum } = connectWithPath('/maximum') - const maximum = getMaximum() + const maximum = connectWithPath('/maximum').getValue() if (amount > maximum) { return new FormError('NumberField.errorMaximum', { diff --git a/packages/dnb-eufemia/src/extensions/forms/FieldBlock/FieldBlock.tsx b/packages/dnb-eufemia/src/extensions/forms/FieldBlock/FieldBlock.tsx index b6c61fd04fd..33a06817ec8 100644 --- a/packages/dnb-eufemia/src/extensions/forms/FieldBlock/FieldBlock.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/FieldBlock/FieldBlock.tsx @@ -179,7 +179,7 @@ function FieldBlock(props: Props) { const { index: iterateIndex } = iterateItemContext ?? {} const blockId = useId(props.id) - const [wasUpdated, forceUpdate] = useReducer(() => ({}), {}) + const [salt, forceUpdate] = useReducer(() => ({}), {}) const mountedFieldsRef = useRef({}) const fieldStateRef = useRef(null) const stateRecordRef = useRef({}) @@ -309,17 +309,8 @@ function FieldBlock(props: Props) { [nestedFieldBlockContext] ) - const hasStateRecord = useCallback( - (state: StateTypes) => { - return stateRecordRef.current[blockId]?.some( - (item) => item.type === state - ) - }, - [blockId] - ) - const statusContent = useMemo(() => { - if (typeof errorProp !== 'undefined' || hasStateRecord('error')) { + if (typeof errorProp !== 'undefined') { setInternalRecord({ identifier: blockId, showInitially: hasInitiallyErrorProp, @@ -328,7 +319,7 @@ function FieldBlock(props: Props) { }) } - if (typeof warning !== 'undefined' || hasStateRecord('warning')) { + if (typeof warning !== 'undefined') { setInternalRecord({ identifier: blockId, showInitially: true, @@ -337,7 +328,7 @@ function FieldBlock(props: Props) { }) } - if (typeof info !== 'undefined' || hasStateRecord('info')) { + if (typeof info !== 'undefined') { setInternalRecord({ identifier: blockId, showInitially: true, @@ -449,21 +440,18 @@ function FieldBlock(props: Props) { } return acc - }, {}) as StatusContent - - // eslint-disable-next-line react-hooks/exhaustive-deps + }, salt) as StatusContent }, [ errorProp, - hasStateRecord, warning, info, + salt, setInternalRecord, blockId, hasInitiallyErrorProp, props.id, forId, label, - wasUpdated, // wasUpdated is needed to get the current errors ]) // Handle the error prop from outside diff --git a/packages/dnb-eufemia/src/extensions/forms/hooks/useFieldProps.ts b/packages/dnb-eufemia/src/extensions/forms/hooks/useFieldProps.ts index 04936e06ac1..b69d6c10a92 100644 --- a/packages/dnb-eufemia/src/extensions/forms/hooks/useFieldProps.ts +++ b/packages/dnb-eufemia/src/extensions/forms/hooks/useFieldProps.ts @@ -363,6 +363,11 @@ export default function useFieldProps( getFieldByPath, }) + if (msg === undefined) { + messageCacheRef.current.message = undefined + return null // hide the message + } + const isError = msg instanceof Error || msg instanceof FormError || @@ -424,6 +429,7 @@ export default function useFieldProps( }, [getFieldByPath, getValueByPath] ) + const error = executeMessage< Error | FormError | Array >(errorProp) @@ -711,6 +717,8 @@ export default function useFieldProps( ? prepareError(error) ?? localErrorRef.current ?? contextErrorRef.current + : error === null + ? null : undefined const hasVisibleError =