Repository: dnbexperience/eufemia
Pull request #5102: feat(Forms): add `preventUncommittedChanges` in Form.Isolation to show error during submit after user input
Author: login: tujoworker
Labels: name: released
Created: 2025-05-10T05:47:07Z | Merged: 2025-05-18T19:17:30Z

Same functionality as #5005 – so a lot of code were moved.
Builds on top of #5127

Link to deploy preview: https://eufemia-git-feat-forms-isolation-requirecommit-eufemia.vercel.app/uilib/extensions/forms/Form/Isolation/demos/#require-commit


Diff:
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/Examples.tsx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/Examples.tsx
index cb1faef7d38..0c8c2463999 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/Examples.tsx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/Examples.tsx
@@ -174,6 +174,7 @@ export const TransformCommitData = () => {
                       onCommit={(data, { clearData }) => {
                         clearData()
                       }}
+                      resetDataAfterCommit
                     >
                       <Flex.Stack>
                         <Form.Section path="/newPerson">
@@ -238,3 +239,86 @@ export const InsideSection = () => {
     </ComponentBox>
   )
 }
+
+export const PreventUncommittedChanges = () => {
+  return (
+    <ComponentBox>
+      <Form.Handler
+        onSubmit={async (data) => console.log('onSubmit', data)}
+      >
+        <Flex.Stack>
+          <Form.Isolation preventUncommittedChanges resetDataAfterCommit>
+            <Flex.Stack>
+              <Field.String required label="Isolated" path="/isolated" />
+
+              <Flex.Horizontal>
+                <Form.Isolation.CommitButton />
+                <Form.Isolation.ResetButton showWhen="uncommittedChangeDetected" />
+              </Flex.Horizontal>
+            </Flex.Stack>
+          </Form.Isolation>
+
+          <Form.SubmitButton />
+
+          <Tools.Log />
+        </Flex.Stack>
+      </Form.Handler>
+    </ComponentBox>
+  )
+}
+
+export const UpdateDataReference = () => {
+  return (
+    <ComponentBox>
+      {() => {
+        const dataReference = Form.Isolation.createDataReference()
+
+        const SetDelayedData = () => {
+          const { update } = Form.useData()
+
+          React.useEffect(() => {
+            setTimeout(() => {
+              update('/isolated', 'With a delayed default value')
+              dataReference.refresh() // <-- refresh the data reference
+            }, 1000)
+          }, [update])
+
+          return null
+        }
+        return (
+          <Form.Handler
+            onSubmit={async (data) => console.log('onSubmit', data)}
+          >
+            <Flex.Stack>
+              <Form.Isolation
+                preventUncommittedChanges
+                resetDataAfterCommit
+                dataReference={dataReference}
+              >
+                <SetDelayedData />
+                <Flex.Stack>
+                  <Field.String
+                    required
+                    label="Isolated"
+                    path="/isolated"
+                  />
+
+                  <Flex.Horizontal>
+                    <Form.Isolation.CommitButton />
+                    <Form.Isolation.ResetButton
+                      showConfirmDialog={false}
+                    />
+                  </Flex.Horizontal>
+                </Flex.Stack>
+              </Form.Isolation>
+
+              <Form.SubmitButton />
+
+              <Tools.Log />
+            </Flex.Stack>
+          </Form.Handler>
+        )
+      }}
+    </ComponentBox>
+  )
+}
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/demos.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/demos.mdx
index f3181e23915..fe6e4c91519 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/demos.mdx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/demos.mdx
@@ -23,8 +23,22 @@ import * as Examples from './Examples'
 
 This example has a `defaultValue` both on the Form.Handler and the Form.Isolation.
 
-When no `defaultValue` is set on the Form.Isolation (inner context), the the default value from Form.Handler (outer context) is used for the initial value.
+When no `defaultValue` is set on the Form.Isolation (inner context), the default value from Form.Handler (outer context) is used for the initial value.
 
-When pressing "Legg til" the default value from Form.Isolation is inserted again, because `resetDataAfterCommit` is set to `true`.
+When pressing the "Legg til / Add"-button, the default value from Form.Isolation is inserted again, because `resetDataAfterCommit` is set to `true`.
 
 <Examples.InsideSection />
+
+### Prevent uncommitted changes
+
+This example uses the `preventUncommittedChanges` property to display an error message if the user has made changes and attempts to submit the form.
+
+Try entering something in the input field, then submit the form. An error message will appear to indicate that changes must be committed first.
+
+<Examples.PreventUncommittedChanges />
+
+### Update the data reference
+
+This example shows how to update the data reference at a later point in time.
+
+<Examples.UpdateDataReference />
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/info.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/info.mdx
index d3b17940689..c2bcb10fd32 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/info.mdx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/info.mdx
@@ -17,6 +17,7 @@ It's a provider that lets you provide a `schema` or `data` very similar to what
 - You can provide a `schema`, `data` or `defaultData` like you would do with the `Form.Handler`.
 - You can also provide `data` or `defaultData` to the `Form.Handler` component. If not given on the `Form.Isolation` component, this will define the data that will be used for the isolated data.
 - Using `Form.Isolation` inside of a `Form.Section` is supported.
+- If the user enters data without committing it to the outer context, that data will be lost when navigating to another step in the Wizard. To prevent this, you can use the `preventUncommittedChanges` property on Form.Isolation. When enabled, it will display an error message if the user tries to proceed without committing their changes.
 - `onChange` on the `Form.Handler` will be called when the isolated data gets committed.
 - `onChange` on the `Form.Isolation` will be called on every change of the isolated data. Use `onCommit` to get the data that gets committed.
 
@@ -163,7 +164,7 @@ function MyForm() {
 }
 ```
 
-## Reset data after commit
+## Reset data after commit (`resetDataAfterCommit`)
 
 You can reset the isolation the user committed by using `resetDataAfterCommit`:
 
@@ -182,11 +183,11 @@ function MyForm() {
 }
 ```
 
-### Define the reset data
+### Define your own data reference (`dataReference`)
 
-Technically, when you use `resetDataAfterCommit`, the `Form.Isolation` will reset its data context based on the "initial" internal data set.
+Technically, when you use `preventUncommittedChanges` or `resetDataAfterCommit`, the `Form.Isolation` will use its "initial" internal data set to create a reference. This reference is used to either compare if there is a change or to reset the data context after a commit.
 
-But in some situations, you may need a different data set than the internal data set given at the initial render.
+But in some situations, you may need a different data set than the initial data set given at the initial render.
 
 In order to do that you can create a `dataReference` and pass it to the `Form.Isolation` component and call `refresh` on it whenever you need to update it.
 
@@ -211,3 +212,25 @@ function MyForm() {
   )
 }
 ```
+
+## Require the user to commit before submitting (`preventUncommittedChanges`)
+
+In scenarios where you want to ensure users commit their changes before submitting or navigating to the next Wizard step, you can use the `preventUncommittedChanges` property. This will prevent form submission (or a step change) and prompt the user to commit any uncommitted changes first.
+
+```jsx
+import { Form, Field } from '@dnb/eufemia/extensions/forms'
+
+function MyForm() {
+  return (
+    <Form.Handler>
+      <Form.Isolation preventUncommittedChanges resetDataAfterCommit>
+        <Field.String path="/isolated" />
+        <Form.Isolation.CommitButton />
+        <Form.Isolation.ResetButton showWhen="uncommittedChangeDetected" />
+      </Form.Isolation>
+    </Form.Handler>
+  )
+}
+```
+
+The `showWhen="uncommittedChangeDetected"` property ensures that the reset button is displayed only when the "prevent uncommitted changes" error is visible. This helps prevent users from resetting the form unnecessarily.
diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolatedContainer.tsx b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolatedContainer.tsx
index efcc0990699..69893e6c4a4 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolatedContainer.tsx
+++ b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolatedContainer.tsx
@@ -1,9 +1,21 @@
 import React, { useCallback, useContext } from 'react'
-import DataContext from '../../DataContext/Context'
+import { FormStatus } from '../../../../components'
+import { useTranslation } from '../../hooks'
+import useHandleStatus from './useHandleStatus'
 import IsolationContext from './IsolationContext'
+import DataContext from '../../DataContext/Context'
 import useDataContextSnapshot from './useDataContextSnapshot'
 
 export default function IsolatedContainer({ children }) {
+  const { outerContext, preventUncommittedChanges } =
+    useContext(IsolationContext)
+  const { preventUncommittedChangesText } = useTranslation().Isolation
+  const { showStatus: showCommitStatus } = useHandleStatus({
+    outerContext,
+    preventUncommittedChanges,
+    error: isolationError,
+  })
+
   const { setFieldEventListener } = useContext(DataContext)
   const { resetDataAfterCommit } = useContext(IsolationContext)
   const { handleReset } = useDataContextSnapshot({
@@ -17,7 +29,21 @@ export default function IsolatedContainer({ children }) {
   }, [handleReset, resetDataAfterCommit])
   setFieldEventListener?.(undefined, 'onBeforeCommit', handleSubmit)
 
-  return <>{children}</>
+  return (
+    <>
+      {children}
+
+      {preventUncommittedChanges && (
+        <FormStatus
+          no_animation={false}
+          shellSpace={{ top: true }}
+          show={Boolean(showCommitStatus)}
+        >
+          {preventUncommittedChangesText}
+        </FormStatus>
+      )}
+    </>
+  )
 }
 
 export const isolationError = new Error('Form.Isolation')
diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/Isolation.tsx b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/Isolation.tsx
index db816a3f453..191ecaa61c4 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/Isolation.tsx
+++ b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/Isolation.tsx
@@ -19,6 +19,7 @@ import {
 import SectionContext from '../Section/SectionContext'
 import useReportError from './useReportError'
 import IsolationCommitButton from './IsolationCommitButton'
+import IsolationResetButton from './IsolationResetButton'
 import {
   clearedData,
   type Props as ProviderProps,
@@ -56,6 +57,10 @@ export type IsolationProviderProps<Data extends JsonObject> = {
    * Prevent the form from being submitted when there are fields with errors inside the Form.Isolation.
    */
   bubbleValidation?: boolean
+  /**
+   * Prevents uncommitted changes before the form is submitted. Will display an error message if user tries to submit without committing their changes.
+   */
+  preventUncommittedChanges?: boolean
   /**
    * If set to `true`, the Form.Isolation will reset its data context after committing the data to the outer context.
    */
@@ -108,6 +113,7 @@ function IsolationProvider<Data extends JsonObject>(
     transformOnCommit: transformOnCommitProp,
     commitHandleRef,
     bubbleValidation,
+    preventUncommittedChanges,
     data,
     defaultData,
     dataReference = dataReferenceFallback,
@@ -261,12 +267,16 @@ function IsolationProvider<Data extends JsonObject>(
     ]
   )
 
+  const setIsolatedData = useCallback((data: Data) => {
+    localDataRef.current = data
+    internalDataRef.current = data
+  }, [])
+
   const onClear = useCallback(() => {
-    localDataRef.current = clearedData
-    internalDataRef.current = clearedData as Data
+    setIsolatedData(clearedData as Data)
     forceUpdate()
     onClearProp?.()
-  }, [onClearProp])
+  }, [onClearProp, setIsolatedData])
 
   const providerProps: IsolationProps<Data> = {
     ...props,
@@ -281,7 +291,13 @@ function IsolationProvider<Data extends JsonObject>(
   return (
     <Provider {...providerProps}>
       <IsolationContext.Provider
-        value={{ dataReference, resetDataAfterCommit, outerContext }}
+        value={{
+          preventUncommittedChanges,
+          dataReference,
+          resetDataAfterCommit,
+          outerContext,
+          setIsolatedData,
+        }}
       >
         <DataContext.Consumer>
           {(dataContext) => {
@@ -329,6 +345,7 @@ function BubbleValidation() {
 const isolationError = new Error('Form.Isolation')
 
 IsolationProvider.CommitButton = IsolationCommitButton
+IsolationProvider.ResetButton = IsolationResetButton
 IsolationProvider.createDataReference = createDataReference
 IsolationProvider._supportsSpacingProps = undefined
 
diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolationContext.ts b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolationContext.ts
index ad889afd356..d5ebf28eff1 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolationContext.ts
+++ b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolationContext.ts
@@ -6,6 +6,8 @@ export type IsolationContext = {
   dataReference: IsolationDataReference
   resetDataAfterCommit: boolean
   outerContext: ContextState
+  preventUncommittedChanges: boolean
+  setIsolatedData: (data: unknown) => void
 }
 
 const IsolationContext = createContext<IsolationContext>(null)
diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolationDocs.ts b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolationDocs.ts
index bd13b62fa58..c8f9bceb2ba 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolationDocs.ts
+++ b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolationDocs.ts
@@ -25,6 +25,11 @@ export const IsolationProperties: PropertiesTableProps = {
     type: 'boolean',
     status: 'optional',
   },
+  preventUncommittedChanges: {
+    doc: 'Prevents uncommitted changes before the form is submitted. Will display an error message if user tries to submit without committing their changes.',
+    type: 'boolean',
+    status: 'optional',
+  },
   resetDataAfterCommit: {
     doc: 'If set to `true`, the Form.Isolation will reset its data context after committing the data to the outer context.',
     type: 'boolean',
diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolationResetButton.tsx b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolationResetButton.tsx
new file mode 100644
index 00000000000..685e353ea76
--- /dev/null
+++ b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolationResetButton.tsx
@@ -0,0 +1,105 @@
+import React, { useCallback, useContext } from 'react'
+import classnames from 'classnames'
+import { Button, Dialog } from '../../../../components'
+import useTranslation from '../../hooks/useTranslation'
+import FieldBoundaryContext from '../../DataContext/FieldBoundary/FieldBoundaryContext'
+import { reset } from '../../../../icons'
+import { ButtonProps } from '../../../../components/Button'
+import useHasContentChanged from './useHasContentChanged'
+import { omitDataValueReadWriteProps } from '../../types'
+import useDataContextSnapshot from './useDataContextSnapshot'
+import useHandleStatus from './useHandleStatus'
+import { isolationError } from './IsolatedContainer'
+import IsolationContext from './IsolationContext'
+
+type Props = ButtonProps & {
+  showConfirmDialog?: boolean
+  showWhen?: 'uncommittedChangeDetected'
+}
+
+export default function IsolationResetButton(props: Props) {
+  const {
+    text,
+    children,
+    onClick,
+    className,
+    hidden,
+    showConfirmDialog = true,
+    showWhen,
+    ...restProps
+  } = props
+
+  const { outerContext, preventUncommittedChanges } =
+    useContext(IsolationContext)
+  const { setShowBoundaryErrors } = useContext(FieldBoundaryContext) || {}
+
+  const { handleReset } = useDataContextSnapshot({ enabled: true })
+  const { hasContentChanged } = useHasContentChanged()
+  const { showStatus: showCommitStatus } = useHandleStatus({
+    outerContext,
+    preventUncommittedChanges,
+    error: isolationError,
+  })
+
+  const buttonProps = omitDataValueReadWriteProps(restProps)
+  const { resetButton } = useTranslation().IterateEditContainer
+  const { confirmResetText } = useTranslation().IterateEditContainer
+  const textContent = text || children || resetButton
+
+  const buttonWrapperRef = React.useRef<HTMLButtonElement>(null)
+  const handleClick = useCallback(
+    ({ close, event }) => {
+      close?.()
+      onClick?.(event)
+      handleReset()
+      setShowBoundaryErrors?.(false)
+      buttonWrapperRef.current?.focus()
+    },
+    [onClick, handleReset, setShowBoundaryErrors]
+  )
+
+  if (hidden) {
+    return null
+  }
+
+  const triggerAttributes: ButtonProps = {
+    className: classnames('dnb-forms-isolate__reset-button', className),
+    text: textContent,
+    variant: textContent ? 'tertiary' : 'secondary',
+    icon: reset,
+    icon_position: 'left',
+    disabled:
+      typeof hasContentChanged === 'boolean' ? !hasContentChanged : false,
+    ...buttonProps,
+  }
+
+  return (
+    <span
+      tabIndex={-1}
+      ref={buttonWrapperRef}
+      className="dnb-no-focus"
+      hidden={
+        !(showWhen === 'uncommittedChangeDetected'
+          ? Boolean(showCommitStatus)
+          : true)
+      }
+    >
+      {showConfirmDialog ? (
+        <Dialog
+          variant="confirmation"
+          title={confirmResetText}
+          triggerAttributes={triggerAttributes}
+          onConfirm={handleClick}
+        />
+      ) : (
+        <Button
+          {...triggerAttributes}
+          on_click={handleClick}
+          {...buttonProps}
+        >
+          {resetButton}
+        </Button>
+      )}
+    </span>
+  )
+}
diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/__tests__/Isolation.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/__tests__/Isolation.test.tsx
index 4acfe08bb79..cf6c25d04cb 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/__tests__/Isolation.test.tsx
+++ b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/__tests__/Isolation.test.tsx
@@ -976,6 +976,50 @@ describe('Form.Isolation', () => {
         )
       })
 
+      it('should reset data context completely (internally) without keeping its previous state', async () => {
+        render(
+          <Form.Handler>
+            <Form.Isolation resetDataAfterCommit>
+              <Field.String className="inside" path="/isolated" />
+              <Form.Isolation.CommitButton />
+            </Form.Isolation>
+
+            <Field.String className="outside" path="/isolated" />
+          </Form.Handler>
+        )
+
+        const inside = document.querySelector('.inside input')
+        const outside = document.querySelector('.outside input')
+
+        const commitButton = document.querySelector(
+          '.dnb-forms-isolate__commit-button'
+        )
+
+        await userEvent.type(inside, 'Isolated')
+        expect(inside).toHaveValue('Isolated')
+        expect(outside).toHaveValue('')
+
+        await userEvent.click(commitButton)
+        await waitFor(() => {
+          expect(inside).toHaveValue('')
+          expect(outside).toHaveValue('Isolated')
+        })
+
+        await userEvent.type(outside, ' - make a change')
+        expect(inside).toHaveValue('')
+        expect(outside).toHaveValue('Isolated - make a change')
+
+        await userEvent.click(commitButton)
+        await waitFor(() => {
+          expect(inside).toHaveValue('')
+          expect(outside).toHaveValue('')
+        })
+
+        await userEvent.type(outside, 'Make a change')
+        expect(inside).toHaveValue('')
+        expect(outside).toHaveValue('Make a change')
+      })
+
       it('should reset data context after commit using enter key when "resetDataAfterCommit" is true', async () => {
         const onChange = jest.fn()
         const onSubmit = jest.fn()
@@ -2230,6 +2274,874 @@ describe('Form.Isolation', () => {
     })
   })
 
+  describe('preventUncommittedChanges', () => {
+    it('should prevent the form from submitting as long as there is uncommitted data', async () => {
+      const onSubmitRequest = jest.fn()
+      const onSubmit = jest.fn()
+      const onCommit = jest.fn()
+
+      render(
+        <Form.Handler
+          onSubmitRequest={onSubmitRequest}
+          onSubmit={onSubmit}
+        >
+          <Form.Isolation
+            preventUncommittedChanges
+            resetDataAfterCommit
+            onCommit={onCommit}
+          >
+            <Field.String path="/name" />
+            <Form.Isolation.CommitButton />
+          </Form.Isolation>
+        </Form.Handler>
+      )
+
+      const input = document.querySelector('input')
+      const form = document.querySelector('form')
+      const commitButton = document.querySelector(
+        '.dnb-forms-isolate__commit-button'
+      )
+
+      await userEvent.type(input, 'Tony')
+
+      fireEvent.submit(form)
+
+      expect(onSubmit).toHaveBeenCalledTimes(0)
+      expect(onSubmitRequest).toHaveBeenCalledTimes(1)
+      expect(onCommit).toHaveBeenCalledTimes(0)
+
+      await userEvent.click(commitButton)
+
+      expect(onCommit).toHaveBeenCalledTimes(1)
+
+      fireEvent.submit(form)
+
+      expect(onSubmit).toHaveBeenCalledTimes(1)
+      expect(onSubmitRequest).toHaveBeenCalledTimes(1)
+      expect(onCommit).toHaveBeenCalledTimes(1)
+    })
+
+    it('should show error when submitting the form', async () => {
+      render(
+        <Form.Handler>
+          <Form.Isolation preventUncommittedChanges resetDataAfterCommit>
+            <Field.String path="/name" />
+            <Form.Isolation.CommitButton />
+          </Form.Isolation>
+        </Form.Handler>
+      )
+
+      const input = document.querySelector('input')
+      const form = document.querySelector('form')
+      const commitButton = document.querySelector(
+        '.dnb-forms-isolate__commit-button'
+      )
+
+      await userEvent.type(input, 'Tony')
+
+      fireEvent.submit(form)
+
+      expect(
+        document.querySelector('.dnb-form-status')
+      ).toBeInTheDocument()
+      expect(document.querySelector('.dnb-form-status')).toHaveTextContent(
+        nb.Isolation.preventUncommittedChangesText
+      )
+
+      await userEvent.click(commitButton)
+
+      await waitFor(() => {
+        expect(
+          document.querySelector('.dnb-form-status')
+        ).not.toBeInTheDocument()
+      })
+
+      fireEvent.submit(form)
+
+      expect(
+        document.querySelector('.dnb-form-status')
+      ).not.toBeInTheDocument()
+    })
+
+    describe('with emptyValue prop', () => {
+      it('should submit when "emptyValue" is given', async () => {
+        const onSubmit = jest.fn()
+
+        render(
+          <Form.Handler onSubmit={onSubmit}>
+            <Form.Isolation preventUncommittedChanges resetDataAfterCommit>
+              <Field.String path="/name" emptyValue="The empty value" />
+              <Form.Isolation.CommitButton />
+            </Form.Isolation>
+          </Form.Handler>
+        )
+
+        const input = document.querySelector('input')
+        const form = document.querySelector('form')
+        const commitButton = document.querySelector(
+          '.dnb-forms-isolate__commit-button'
+        )
+
+        expect(input).toHaveValue('The empty value')
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(1)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          undefined,
+          expect.anything()
+        )
+
+        await userEvent.click(commitButton)
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(2)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          { name: 'The empty value' },
+          expect.anything()
+        )
+      })
+
+      it('should reset to emptyValue when reset button is clicked', async () => {
+        const onSubmit = jest.fn()
+
+        render(
+          <Form.Handler onSubmit={onSubmit}>
+            <Form.Isolation preventUncommittedChanges resetDataAfterCommit>
+              <Field.String path="/name" emptyValue="The empty value" />
+              <Form.Isolation.CommitButton />
+              <Form.Isolation.ResetButton />
+            </Form.Isolation>
+          </Form.Handler>
+        )
+
+        const input = document.querySelector('input')
+        const form = document.querySelector('form')
+        const commitButton = document.querySelector(
+          '.dnb-forms-isolate__commit-button'
+        )
+
+        expect(input).toHaveValue('The empty value')
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(1)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          undefined,
+          expect.anything()
+        )
+
+        await userEvent.type(input, 'X')
+        fireEvent.submit(form)
+
+        expect(input).toHaveValue('The empty valueX')
+        expect(
+          document.querySelector('.dnb-forms-isolate__reset-button')
+        ).toBeInTheDocument()
+
+        await userEvent.click(
+          document.querySelector('.dnb-forms-isolate__reset-button')
+        )
+
+        // Confirm the clear
+        await userEvent.click(
+          document.querySelector('.dnb-button--primary')
+        )
+
+        await waitFor(() => {
+          expect(input).toHaveValue('The empty value')
+          expect(document.querySelector('.dnb-form-status')).toBeNull()
+        })
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(2)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          undefined,
+          expect.anything()
+        )
+
+        await userEvent.click(commitButton)
+
+        expect(input).toHaveValue('The empty value')
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(3)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          { name: 'The empty value' },
+          expect.anything()
+        )
+      })
+    })
+
+    describe('with defaultValue prop', () => {
+      it('should submit when "defaultValue" is given', async () => {
+        const onSubmit = jest.fn()
+
+        render(
+          <Form.Handler onSubmit={onSubmit}>
+            <Form.Isolation preventUncommittedChanges resetDataAfterCommit>
+              <Field.String path="/name" defaultValue="A default value" />
+              <Form.Isolation.CommitButton />
+              <Form.Isolation.ResetButton />
+            </Form.Isolation>
+          </Form.Handler>
+        )
+
+        const input = document.querySelector('input')
+        const form = document.querySelector('form')
+        const commitButton = document.querySelector(
+          '.dnb-forms-isolate__commit-button'
+        )
+
+        expect(input).toHaveValue('A default value')
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(1)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          undefined,
+          expect.anything()
+        )
+
+        await userEvent.click(commitButton)
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(2)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          { name: 'A default value' },
+          expect.anything()
+        )
+      })
+
+      it('should reset to defaultValue when reset button is clicked', async () => {
+        const onSubmit = jest.fn()
+
+        render(
+          <Form.Handler onSubmit={onSubmit}>
+            <Form.Isolation preventUncommittedChanges resetDataAfterCommit>
+              <Field.String path="/name" defaultValue="A default value" />
+              <Form.Isolation.CommitButton />
+              <Form.Isolation.ResetButton />
+            </Form.Isolation>
+          </Form.Handler>
+        )
+
+        const input = document.querySelector('input')
+        const form = document.querySelector('form')
+        const commitButton = document.querySelector(
+          '.dnb-forms-isolate__commit-button'
+        )
+
+        expect(input).toHaveValue('A default value')
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(1)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          undefined,
+          expect.anything()
+        )
+
+        await userEvent.type(input, 'X')
+        fireEvent.submit(form)
+
+        expect(input).toHaveValue('A default valueX')
+        expect(
+          document.querySelector('.dnb-forms-isolate__reset-button')
+        ).toBeInTheDocument()
+
+        await userEvent.click(
+          document.querySelector('.dnb-forms-isolate__reset-button')
+        )
+
+        // Confirm the clear
+        await userEvent.click(
+          document.querySelector('.dnb-button--primary')
+        )
+
+        await waitFor(() => {
+          expect(input).toHaveValue('A default value')
+          expect(document.querySelector('.dnb-form-status')).toBeNull()
+        })
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(2)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          undefined,
+          expect.anything()
+        )
+
+        await userEvent.click(commitButton)
+
+        expect(input).toHaveValue('A default value')
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(3)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          { name: 'A default value' },
+          expect.anything()
+        )
+      })
+    })
+
+    describe('with defaultData prop', () => {
+      it('should submit when "defaultData" is given', async () => {
+        const onSubmit = jest.fn()
+
+        render(
+          <Form.Handler onSubmit={onSubmit}>
+            <Form.Isolation
+              preventUncommittedChanges
+              resetDataAfterCommit
+              defaultData={{ name: 'A default value' }}
+            >
+              <Field.String path="/name" />
+              <Form.Isolation.CommitButton />
+              <Form.Isolation.ResetButton />
+            </Form.Isolation>
+          </Form.Handler>
+        )
+
+        const input = document.querySelector('input')
+        const form = document.querySelector('form')
+        const commitButton = document.querySelector(
+          '.dnb-forms-isolate__commit-button'
+        )
+
+        expect(input).toHaveValue('A default value')
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(1)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          undefined,
+          expect.anything()
+        )
+
+        await userEvent.click(commitButton)
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(2)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          { name: 'A default value' },
+          expect.anything()
+        )
+      })
+
+      it('should reset to defaultData when reset button is clicked', async () => {
+        const onSubmit = jest.fn()
+
+        render(
+          <Form.Handler onSubmit={onSubmit}>
+            <Form.Isolation
+              preventUncommittedChanges
+              resetDataAfterCommit
+              defaultData={{ name: 'A default value' }}
+            >
+              <Field.String path="/name" />
+              <Form.Isolation.CommitButton />
+              <Form.Isolation.ResetButton />
+            </Form.Isolation>
+          </Form.Handler>
+        )
+
+        const input = document.querySelector('input')
+        const form = document.querySelector('form')
+        const commitButton = document.querySelector(
+          '.dnb-forms-isolate__commit-button'
+        )
+
+        expect(input).toHaveValue('A default value')
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(1)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          undefined,
+          expect.anything()
+        )
+
+        await userEvent.type(input, 'X')
+        fireEvent.submit(form)
+
+        expect(input).toHaveValue('A default valueX')
+        expect(
+          document.querySelector('.dnb-forms-isolate__reset-button')
+        ).toBeInTheDocument()
+
+        await userEvent.click(
+          document.querySelector('.dnb-forms-isolate__reset-button')
+        )
+
+        // Confirm the clear
+        await userEvent.click(
+          document.querySelector('.dnb-button--primary')
+        )
+
+        await waitFor(() => {
+          expect(input).toHaveValue('A default value')
+          expect(document.querySelector('.dnb-form-status')).toBeNull()
+        })
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(2)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          undefined,
+          expect.anything()
+        )
+
+        await userEvent.click(commitButton)
+
+        expect(input).toHaveValue('A default value')
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(3)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          { name: 'A default value' },
+          expect.anything()
+        )
+      })
+    })
+
+    describe('with data prop', () => {
+      it('should submit when "data" is given', async () => {
+        const onSubmit = jest.fn()
+
+        render(
+          <Form.Handler onSubmit={onSubmit}>
+            <Form.Isolation
+              preventUncommittedChanges
+              resetDataAfterCommit
+              data={{ name: 'A data value' }}
+            >
+              <Field.String path="/name" />
+              <Form.Isolation.CommitButton />
+              <Form.Isolation.ResetButton />
+            </Form.Isolation>
+          </Form.Handler>
+        )
+
+        const input = document.querySelector('input')
+        const form = document.querySelector('form')
+        const commitButton = document.querySelector(
+          '.dnb-forms-isolate__commit-button'
+        )
+
+        expect(input).toHaveValue('A data value')
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(1)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          undefined,
+          expect.anything()
+        )
+
+        await userEvent.click(commitButton)
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(2)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          { name: 'A data value' },
+          expect.anything()
+        )
+      })
+
+      it('should reset to data when reset button is clicked', async () => {
+        const onSubmit = jest.fn()
+
+        render(
+          <Form.Handler onSubmit={onSubmit}>
+            <Form.Isolation
+              preventUncommittedChanges
+              resetDataAfterCommit
+              data={{ name: 'A data value' }}
+            >
+              <Field.String path="/name" />
+              <Form.Isolation.CommitButton />
+              <Form.Isolation.ResetButton />
+            </Form.Isolation>
+          </Form.Handler>
+        )
+
+        const input = document.querySelector('input')
+        const form = document.querySelector('form')
+        const commitButton = document.querySelector(
+          '.dnb-forms-isolate__commit-button'
+        )
+
+        expect(input).toHaveValue('A data value')
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(1)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          undefined,
+          expect.anything()
+        )
+
+        await userEvent.type(input, 'X')
+        fireEvent.submit(form)
+
+        expect(input).toHaveValue('A data valueX')
+        expect(
+          document.querySelector('.dnb-forms-isolate__reset-button')
+        ).toBeInTheDocument()
+
+        await userEvent.click(
+          document.querySelector('.dnb-forms-isolate__reset-button')
+        )
+
+        // Confirm the clear
+        await userEvent.click(
+          document.querySelector('.dnb-button--primary')
+        )
+
+        await waitFor(() => {
+          expect(input).toHaveValue('A data value')
+          expect(document.querySelector('.dnb-form-status')).toBeNull()
+        })
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(2)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          undefined,
+          expect.anything()
+        )
+
+        await userEvent.click(commitButton)
+
+        await waitFor(() => {
+          expect(input).toHaveValue('A data value')
+          expect(document.querySelector('.dnb-form-status')).toBeNull()
+        })
+
+        fireEvent.submit(form)
+
+        expect(onSubmit).toHaveBeenCalledTimes(3)
+        expect(onSubmit).toHaveBeenLastCalledWith(
+          { name: 'A data value' },
+          expect.anything()
+        )
+      })
+    })
+
+    it('should prevent Wizard step change as long as there is uncommitted data', async () => {
+      const onSubmitRequest = jest.fn()
+      const onSubmit = jest.fn()
+      const onCommit = jest.fn()
+      const onStepChange = jest.fn()
+
+      render(
+        <Form.Handler
+          onSubmitRequest={onSubmitRequest}
+          onSubmit={onSubmit}
+        >
+          <Wizard.Container onStepChange={onStepChange}>
+            <Wizard.Step title="Step 1">
+              <output>Step 1</output>
+
+              <Form.Isolation
+                preventUncommittedChanges
+                resetDataAfterCommit
+                onCommit={onCommit}
+              >
+                <Field.String path="/name" emptyValue="The empty value" />
+                <Form.Isolation.CommitButton />
+              </Form.Isolation>
+
+              <Wizard.Buttons />
+            </Wizard.Step>
+
+            <Wizard.Step title="Step 2">
+              <output>Step 2</output>
+              <Wizard.Buttons />
+              <Form.SubmitButton />
+            </Wizard.Step>
+          </Wizard.Container>
+        </Form.Handler>
+      )
+
+      const input = document.querySelector('input')
+      const form = document.querySelector('form')
+      const commitButton = document.querySelector(
+        '.dnb-forms-isolate__commit-button'
+      )
+
+      const nextButton = () => {
+        return document.querySelector('.dnb-forms-next-button')
+      }
+      const output = () => {
+        return document.querySelector('output')
+      }
+
+      expect(output()).toHaveTextContent('Step 1')
+
+      await userEvent.type(input, 'Tony')
+
+      await userEvent.click(nextButton())
+
+      expect(output()).toHaveTextContent('Step 1')
+      expect(onStepChange).toHaveBeenCalledTimes(0)
+      expect(onSubmit).toHaveBeenCalledTimes(0)
+      expect(onSubmitRequest).toHaveBeenCalledTimes(1)
+      expect(onCommit).toHaveBeenCalledTimes(0)
+
+      expect(
+        document.querySelector('.dnb-form-status')
+      ).toBeInTheDocument()
+      expect(document.querySelector('.dnb-form-status')).toHaveTextContent(
+        nb.Isolation.preventUncommittedChangesText
+      )
+
+      await userEvent.click(commitButton)
+
+      expect(onCommit).toHaveBeenCalledTimes(1)
+      await waitFor(() => {
+        expect(
+          document.querySelector('.dnb-form-status')
+        ).not.toBeInTheDocument()
+      })
+
+      await userEvent.click(nextButton())
+
+      expect(output()).toHaveTextContent('Step 2')
+      expect(onStepChange).toHaveBeenCalledTimes(1)
+      expect(onStepChange).toHaveBeenLastCalledWith(
+        1,
+        'next',
+        expect.anything()
+      )
+
+      fireEvent.submit(form)
+
+      expect(onSubmit).toHaveBeenCalledTimes(1)
+      expect(onSubmitRequest).toHaveBeenCalledTimes(1)
+      expect(onCommit).toHaveBeenCalledTimes(1)
+    })
+
+    it('should hide and show reset button when showWhen="uncommittedChangeDetected" is set', async () => {
+      render(
+        <Form.Handler>
+          <Form.Isolation preventUncommittedChanges resetDataAfterCommit>
+            <Field.String path="/name" emptyValue="The empty value" />
+            <Form.Isolation.CommitButton />
+            <Form.Isolation.ResetButton showWhen="uncommittedChangeDetected" />
+          </Form.Isolation>
+        </Form.Handler>
+      )
+
+      const input = document.querySelector('input')
+      const form = document.querySelector('form')
+
+      expect(
+        document.querySelector('.dnb-forms-isolate__reset-button')
+          .parentElement
+      ).toHaveAttribute('hidden')
+
+      fireEvent.submit(form)
+
+      expect(
+        document.querySelector('.dnb-forms-isolate__reset-button')
+          .parentElement
+      ).toHaveAttribute('hidden')
+
+      await userEvent.type(input, 'X')
+
+      fireEvent.submit(form)
+
+      expect(
+        document.querySelector('.dnb-forms-isolate__reset-button')
+          .parentElement
+      ).not.toHaveAttribute('hidden')
+    })
+
+    it('should enable/disable reset button', async () => {
+      render(
+        <Form.Handler>
+          <Form.Isolation preventUncommittedChanges resetDataAfterCommit>
+            <Field.String path="/name" />
+            <Form.Isolation.CommitButton />
+            <Form.Isolation.ResetButton />
+          </Form.Isolation>
+        </Form.Handler>
+      )
+
+      const input = document.querySelector('input')
+      const form = document.querySelector('form')
+      const commitButton = document.querySelector(
+        '.dnb-forms-isolate__commit-button'
+      )
+
+      expect(
+        document.querySelector('.dnb-forms-isolate__reset-button')
+      ).toHaveAttribute('disabled')
+      expect(
+        document.querySelector('.dnb-forms-isolate__reset-button')
+          .parentElement
+      ).not.toHaveAttribute('hidden')
+
+      await userEvent.type(input, 'Tony')
+
+      fireEvent.submit(form)
+
+      expect(
+        document.querySelector('.dnb-form-status')
+      ).toBeInTheDocument()
+      expect(
+        document.querySelector('.dnb-forms-isolate__reset-button')
+      ).not.toHaveAttribute('disabled')
+      expect(
+        document.querySelector('.dnb-forms-isolate__reset-button')
+          .parentElement
+      ).not.toHaveAttribute('hidden')
+
+      await userEvent.click(commitButton)
+
+      await waitFor(() => {
+        expect(
+          document.querySelector('.dnb-form-status')
+        ).not.toBeInTheDocument()
+      })
+      expect(
+        document.querySelector('.dnb-forms-isolate__reset-button')
+      ).toHaveAttribute('disabled')
+      expect(
+        document.querySelector('.dnb-forms-isolate__reset-button')
+          .parentElement
+      ).not.toHaveAttribute('hidden')
+    })
+
+    it('should submit form when uncommitted data was cleared (with confirmation)', async () => {
+      const onSubmitRequest = jest.fn()
+      const onSubmit = jest.fn()
+      const onCommit = jest.fn()
+
+      render(
+        <Form.Handler
+          onSubmit={onSubmit}
+          onSubmitRequest={onSubmitRequest}
+        >
+          <Form.Isolation
+            preventUncommittedChanges
+            resetDataAfterCommit
+            onCommit={onCommit}
+          >
+            <Field.String path="/name" />
+            <Form.Isolation.CommitButton />
+            <Form.Isolation.ResetButton />
+          </Form.Isolation>
+        </Form.Handler>
+      )
+
+      const input = document.querySelector('input')
+      const form = document.querySelector('form')
+
+      await userEvent.type(input, 'Tony')
+
+      fireEvent.submit(form)
+
+      expect(onSubmit).toHaveBeenCalledTimes(0)
+      expect(onSubmitRequest).toHaveBeenCalledTimes(1)
+      expect(onCommit).toHaveBeenCalledTimes(0)
+      expect(
+        document.querySelector('.dnb-form-status')
+      ).toBeInTheDocument()
+      expect(document.querySelector('.dnb-form-status')).toHaveTextContent(
+        nb.Isolation.preventUncommittedChangesText
+      )
+
+      // Click the reset button
+      await userEvent.click(
+        document.querySelector('.dnb-forms-isolate__reset-button')
+      )
+
+      // Confirm the clear
+      await userEvent.click(document.querySelector('.dnb-button--primary'))
+
+      await waitFor(() => {
+        expect(input).toHaveValue('')
+        expect(document.querySelector('.dnb-form-status')).toBeNull()
+      })
+
+      fireEvent.submit(form)
+
+      expect(onSubmit).toHaveBeenCalledTimes(1)
+      expect(onSubmitRequest).toHaveBeenCalledTimes(1)
+      expect(onCommit).toHaveBeenCalledTimes(0)
+    })
+
+    it('should support a custom "dataReference"', async () => {
+      const onSubmit = jest.fn()
+      const onCommit = jest.fn()
+
+      const dataReference = Form.Isolation.createDataReference()
+
+      const SetDelayedData = () => {
+        const { update } = Form.useData()
+
+        React.useEffect(() => {
+          setTimeout(() => {
+            update('/isolated', 'With a delayed default value')
+            setTimeout(() => {
+              dataReference.refresh() // <-- refresh the data reference
+            }, 100)
+          }, 10)
+          // eslint-disable-next-line react-hooks/exhaustive-deps
+        }, [])
+
+        return null
+      }
+
+      render(
+        <Form.Handler onSubmit={onSubmit}>
+          <Form.Isolation
+            preventUncommittedChanges
+            resetDataAfterCommit
+            dataReference={dataReference}
+            onCommit={onCommit}
+          >
+            <SetDelayedData />
+
+            <Field.String path="/isolated" />
+            <Form.Isolation.CommitButton />
+            <Form.Isolation.ResetButton showConfirmDialog={false} />
+          </Form.Isolation>
+        </Form.Handler>
+      )
+
+      const input = document.querySelector('input')
+      const resetButton = document.querySelector(
+        '.dnb-forms-isolate__reset-button'
+      )
+
+      expect(resetButton).toBeDisabled()
+
+      await waitFor(() => {
+        expect(input).toHaveValue('With a delayed default value')
+      })
+
+      expect(resetButton).not.toBeDisabled()
+
+      await waitFor(() => {
+        expect(resetButton).toBeDisabled()
+      })
+
+      await userEvent.type(input, '2')
+      expect(resetButton).not.toBeDisabled()
+
+      await userEvent.type(input, '{Backspace}')
+      expect(resetButton).toBeDisabled()
+    })
+  })
+
   describe('bubbleValidation', () => {
     it('should prevent the form from submitting as long as there are errors', async () => {
       const onSubmitRequest = jest.fn()
diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/stories/Isolation.stories.tsx b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/stories/Isolation.stories.tsx
index beb81a8f55b..1f8374f6626 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/stories/Isolation.stories.tsx
+++ b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/stories/Isolation.stories.tsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import { Field, Form } from '../../..'
+import { Field, Form, Tools } from '../../..'
 import { Flex, HeightAnimation } from '../../../../../components'
 
 export default {
@@ -172,3 +172,35 @@ export const TransformOnCommit = () => {
     </Form.Handler>
   )
 }
+
+export function preventUncommittedChanges() {
+  return (
+    <Form.Handler onSubmit={async (data) => console.log('onSubmit', data)}>
+      <Flex.Stack>
+        <Form.Isolation
+          preventUncommittedChanges
+          resetDataAfterCommit
+          defaultData={{ isolated: 'Isolated' }}
+        >
+          <Flex.Stack>
+            <Field.String
+              label="Isolated"
+              path="/isolated"
+              required
+              // validateInitially
+            />
+
+            <Flex.Horizontal>
+              <Form.Isolation.CommitButton />
+              <Form.Isolation.ResetButton showWhen="uncommittedChangeDetected" />
+            </Flex.Horizontal>
+          </Flex.Stack>
+        </Form.Isolation>
+
+        <Form.SubmitButton />
+
+        <Tools.Log />
+      </Flex.Stack>
+    </Form.Handler>
+  )
+}
diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/useDataContextSnapshot.ts b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/useDataContextSnapshot.ts
index 4c5e610726a..4174aca6ee8 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/useDataContextSnapshot.ts
+++ b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/useDataContextSnapshot.ts
@@ -1,4 +1,4 @@
-import { useCallback, useContext, useEffect } from 'react'
+import { useCallback, useContext, useEffect, useReducer } from 'react'
 import DataContext from '../../DataContext/Context'
 import IsolationContext from './IsolationContext'
 
@@ -13,8 +13,10 @@ export default function useDataContextSnapshot({
 }: {
   enabled?: boolean
 } = {}) {
+  const [, forceUpdate] = useReducer(() => ({}), {})
   const { internalDataRef, setData } = useContext(DataContext)
-  const { dataReference } = useContext(IsolationContext) || {}
+  const { dataReference, setIsolatedData } =
+    useContext(IsolationContext) || {}
   const { snapshotRef, eventsRef, update, refresh, cleanup } =
     dataReference || {}
 
@@ -22,20 +24,23 @@ export default function useDataContextSnapshot({
     if (enabled && eventsRef) {
       eventsRef.current.push(() => {
         update(structuredClone(internalDataRef?.current))
+        forceUpdate()
       })
       refresh()
     }
 
-    return () => cleanup()
+    return () => cleanup?.()
   }, [cleanup, enabled, eventsRef, internalDataRef, refresh, update])
 
   const handleReset = useCallback(() => {
     window.requestAnimationFrame(() => {
       if (snapshotRef) {
-        setData(snapshotRef.current)
+        const data = structuredClone(snapshotRef.current)
+        setData(data)
+        setIsolatedData(data)
       }
-    }) // To actually reset the data, we need to wait for the next frame
-  }, [setData, snapshotRef])
+    }) // To actually reset the data without influence the data we are about to push, we need to wait for the next frame
+  }, [setData, setIsolatedData, snapshotRef])
 
-  return { handleReset }
+  return { handleReset, snapshotRef }
 }
diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/useHasContentChanged.ts b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/useHasContentChanged.ts
index a03f4d74e16..16d7e68b8d1 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/useHasContentChanged.ts
+++ b/packages/dnb-eufemia/src/extensions/forms/Form/Isolation/useHasContentChanged.ts
@@ -1,27 +1,16 @@
-import { useContext, useEffect, useMemo, useRef } from 'react'
-import DataContext from '../../DataContext/Context'
+import { useContext, useMemo } from 'react'
 import pointer from '../../utils/json-pointer'
-
-/**
- * Deprecated, as it is supported by all major browsers and Node.js >=v18
- * So its a question of time, when we will remove this polyfill
- */
-import structuredClone from '@ungap/structured-clone'
+import DataContext from '../../DataContext/Context'
+import useDataContextSnapshot from './useDataContextSnapshot'
 
 export default function useHasContentChanged() {
   const { internalDataRef } = useContext(DataContext)
-  const snapshotRef = useRef<unknown>()
-
-  useEffect(() => {
-    snapshotRef.current = structuredClone(internalDataRef?.current)
-
-    // We only want to set the initial value once for now.
-    // When e.g. the data from outside is controlled, we do not support it yet.
-  }, [internalDataRef])
+  const { snapshotRef } = useDataContextSnapshot({ enabled: true })
 
   const data = internalDataRef?.current
+  const snapshot = snapshotRef?.current // To support a custom data reference, we need to have a snapshot in the hook deps.
   const hasContentChanged = useMemo(() => {
-    if (data === undefined) {
+    if (!data || !snapshot) {
       return undefined
     }
 
@@ -29,8 +18,8 @@ export default function useHasContentChanged() {
 
     pointer.walk(data, (value, path) => {
       if (
-        pointer.has(snapshotRef.current, path) &&
-        pointer.get(snapshotRef.current, path) !== value
+        pointer.has(snapshot, path) &&
+        pointer.get(snapshot, path) !== value
       ) {
         hasChanged = true
         return false
@@ -38,7 +27,7 @@ export default function useHasContentChanged() {
     })
 
     return hasChanged
-  }, [data])
+  }, [data, snapshot])
 
   return { hasContentChanged }
 }
diff --git a/packages/dnb-eufemia/src/extensions/forms/Iterate/PushContainer/PushContainer.tsx b/packages/dnb-eufemia/src/extensions/forms/Iterate/PushContainer/PushContainer.tsx
index 72055395cc6..6f039940c68 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Iterate/PushContainer/PushContainer.tsx
+++ b/packages/dnb-eufemia/src/extensions/forms/Iterate/PushContainer/PushContainer.tsx
@@ -156,6 +156,7 @@ function PushContainer(props: AllProps) {
     isolatedData,
     bubbleValidation,
     preventUncommittedChanges = props?.requireCommit,
+    requireCommit, // eslint-disable-line @typescript-eslint/no-unused-vars
     showResetButton,
     path,
     itemPath,
@@ -339,8 +340,7 @@ function NewContainer({
 
   switchContainerModeRef.current = switchContainerMode
   const isVisible = Boolean(!showOpenButton || containerMode === 'edit')
-  const { preventUncommittedChangesText } =
-    useTranslation().IteratePushContainer
+  const { preventUncommittedChangesText } = useTranslation().Isolation
   const { createButton } = useTranslation().IteratePushContainer
   const { clearData } = useContext(DataContext) || {}
   const restoreOriginalValue = useCallback(() => {
diff --git a/packages/dnb-eufemia/src/extensions/forms/Iterate/PushContainer/__tests__/PushContainer.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Iterate/PushContainer/__tests__/PushContainer.test.tsx
index 8f6e7048706..1290259ef1e 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Iterate/PushContainer/__tests__/PushContainer.test.tsx
+++ b/packages/dnb-eufemia/src/extensions/forms/Iterate/PushContainer/__tests__/PushContainer.test.tsx
@@ -501,7 +501,7 @@ describe('PushContainer', () => {
         document.querySelector('.dnb-form-status')
       ).toBeInTheDocument()
       expect(document.querySelector('.dnb-form-status')).toHaveTextContent(
-        nb.IteratePushContainer.preventUncommittedChangesText
+        nb.Isolation.preventUncommittedChangesText
       )
 
       await userEvent.click(doneButton)
@@ -1133,7 +1133,7 @@ describe('PushContainer', () => {
         document.querySelector('.dnb-form-status')
       ).toBeInTheDocument()
       expect(document.querySelector('.dnb-form-status')).toHaveTextContent(
-        nb.IteratePushContainer.preventUncommittedChangesText
+        nb.Isolation.preventUncommittedChangesText
       )
 
       // Click the reset button
@@ -1230,7 +1230,7 @@ describe('PushContainer', () => {
         document.querySelector('.dnb-form-status')
       ).toBeInTheDocument()
       expect(document.querySelector('.dnb-form-status')).toHaveTextContent(
-        nb.IteratePushContainer.preventUncommittedChangesText
+        nb.Isolation.preventUncommittedChangesText
       )
 
       await userEvent.click(doneButton)
@@ -1874,7 +1874,7 @@ describe('PushContainer', () => {
         document.querySelector('.dnb-form-status')
       ).toBeInTheDocument()
       expect(document.querySelector('.dnb-form-status')).toHaveTextContent(
-        nb.IteratePushContainer.preventUncommittedChangesText
+        nb.Isolation.preventUncommittedChangesText
       )
 
       // Click the reset button
diff --git a/packages/dnb-eufemia/src/extensions/forms/constants/locales/en-GB.ts b/packages/dnb-eufemia/src/extensions/forms/constants/locales/en-GB.ts
index 76efa33e4bc..0da95ea3392 100644
--- a/packages/dnb-eufemia/src/extensions/forms/constants/locales/en-GB.ts
+++ b/packages/dnb-eufemia/src/extensions/forms/constants/locales/en-GB.ts
@@ -21,6 +21,8 @@ export default {
     },
     Isolation: {
       commitButtonText: 'Add',
+      preventUncommittedChangesText:
+        'You have changes that either need to be added or cleared.',
     },
     Step: {
       summaryTitle: 'Summary',
@@ -74,8 +76,6 @@ export default {
     IteratePushContainer: {
       createButton: 'Add',
       itemsLimitReached: 'You have reached the limit of: {limit}',
-      preventUncommittedChangesText:
-        'You have changes that either need to be added or cleared.',
     },
 
     /**
diff --git a/packages/dnb-eufemia/src/extensions/forms/constants/locales/nb-NO.ts b/packages/dnb-eufemia/src/extensions/forms/constants/locales/nb-NO.ts
index 8e1709914f3..ad877e8e10b 100644
--- a/packages/dnb-eufemia/src/extensions/forms/constants/locales/nb-NO.ts
+++ b/packages/dnb-eufemia/src/extensions/forms/constants/locales/nb-NO.ts
@@ -20,6 +20,8 @@ export default {
     },
     Isolation: {
       commitButtonText: 'Legg til',
+      preventUncommittedChangesText:
+        'Du har endringer som enten må legges til eller nullstilles.',
     },
     Step: {
       summaryTitle: 'Oppsummering',
@@ -74,8 +76,6 @@ export default {
     IteratePushContainer: {
       createButton: 'Legg til',
       itemsLimitReached: 'Du har nådd grensen på: {limit}',
-      preventUncommittedChangesText:
-        'Du har endringer som enten må legges til eller tømmes.',
     },
 
     /**
diff --git a/packages/dnb-eufemia/src/extensions/forms/constants/locales/sv-SE.ts b/packages/dnb-eufemia/src/extensions/forms/constants/locales/sv-SE.ts
index 58744bc8308..b9794d1546e 100644
--- a/packages/dnb-eufemia/src/extensions/forms/constants/locales/sv-SE.ts
+++ b/packages/dnb-eufemia/src/extensions/forms/constants/locales/sv-SE.ts
@@ -21,6 +21,8 @@ export default {
     },
     Isolation: {
       commitButtonText: 'Lägg till',
+      preventUncommittedChangesText:
+        'Du har ändringar som antingen måste läggas till eller rensas.',
     },
     Step: {
       summaryTitle: 'Sammanfattning',
@@ -75,8 +77,6 @@ export default {
     IteratePushContainer: {
       createButton: 'Lägg till',
       itemsLimitReached: 'Du har nått gränsen på: {limit}',
-      preventUncommittedChangesText:
-        'Du har ändringar som antingen måste läggas till eller rensas.',
     },
 
     /**


Reviews:
user: login: langz
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-11T17:57:33Z
user: login: tujoworker
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T07:10:39Z
user: login: tujoworker
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T07:11:20Z
user: login: tujoworker
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T07:15:27Z
user: login: langz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T07:33:45Z
user: login: langz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T08:07:12Z
user: login: langz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T08:08:08Z
user: login: langz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T09:05:37Z
user: login: langz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T09:05:54Z
user: login: langz
body: Functionality-wise, I think this works great :) 

One possible improvement I see is the naming of the prop, as discussed here:  https://github.com/dnbexperience/eufemia/pull/5102#issuecomment-2886063784
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T10:00:46Z
user: login: langz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T10:42:01Z
user: login: langz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T10:44:27Z
user: login: langz
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T12:21:52Z
user: login: langz
body: I gave it a round of testing now, and it seems to work great 😊 👏
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-18T16:12:45Z

Review comments:
diff_hunk: @@ -162,3 +163,44 @@ function MyForm() {
   )
 }
 ```
+
+## Clear data after commit
+
+You can clear the isolation the user committed by using `resetAfterCommit`:
+
+```jsx
+import { Form, Field } from '@dnb/eufemia/extensions/forms'
+
+function MyForm() {
+  return (
+    <Form.Handler>
+      <Form.Isolation>
+        <Field.String path="/isolated" />
+        <Form.Isolation.CommitButton resetAfterCommit />
+      </Form.Isolation>
+    </Form.Handler>
+  )
+}
+```
+
+## Require the user to commit before submitting
+
+In scenarios where you want to ensure users commit their changes in an isolated section before submitting the entire form, you can use the `requireCommit` property. This will prevent form submission and prompt the user to commit any uncommitted changes first.
+
+```jsx
+import { Form, Field } from '@dnb/eufemia/extensions/forms'
+
+function MyForm() {
+  return (
+    <Form.Handler>
+      <Form.Isolation requireCommit>
+        <Field.String path="/isolated" />
+        <Form.Isolation.CommitButton resetAfterCommit />
+        <Form.Isolation.ResetButton showWhenErrorIsPresent />
+      </Form.Isolation>
+    </Form.Handler>
+  )
+}
+```
+
+The `showWhenErrorIsPresent` property ensures that the reset button is displayed only when the "commit required" error is visible. This helps prevent users from resetting the form unnecessarily.
path: packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/info.mdx
user: login: langz
body: If we think it could come up more alternatives to when one would like to show this button, one could also potentially name the property `showWhen`, and then have different values, like `showWhen="errorIsPresent"`.
Or just `visibleWhen`, as we use this in other places in forms.
created_at: 2025-05-11T17:53:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -49,6 +52,10 @@ export type IsolationProviderProps<Data extends JsonObject> = {
    * Prevent the form from being submitted when there are fields with errors inside the Form.Isolation.
    */
   bubbleValidation?: boolean
path: packages/dnb-eufemia/src/extensions/forms/Form/Isolation/Isolation.tsx
user: login: langz
body: Can the `requireCommit` property have any correlation or collisions with the `bubbleValidation` property, if both are set? Or ca a specific combination of the two lead to some strange UX? 🤔 
created_at: 2025-05-11T17:57:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -49,6 +52,10 @@ export type IsolationProviderProps<Data extends JsonObject> = {
    * Prevent the form from being submitted when there are fields with errors inside the Form.Isolation.
    */
   bubbleValidation?: boolean
path: packages/dnb-eufemia/src/extensions/forms/Form/Isolation/Isolation.tsx
user: login: tujoworker
body: No, I don't think so. Because `requireCommit` already tells the outer form to not precede. That's the nature of this prop. And `bubbleValidation` only effects each single field, and tells them, that errors should reach the outer form, instead of the isolated one. While the isolated date still stays isolated.
created_at: 2025-05-12T07:10:39Z
author_association: MEMBER
diff_hunk: @@ -162,3 +163,44 @@ function MyForm() {
   )
 }
 ```
+
+## Clear data after commit
+
+You can clear the isolation the user committed by using `resetAfterCommit`:
+
+```jsx
+import { Form, Field } from '@dnb/eufemia/extensions/forms'
+
+function MyForm() {
+  return (
+    <Form.Handler>
+      <Form.Isolation>
+        <Field.String path="/isolated" />
+        <Form.Isolation.CommitButton resetAfterCommit />
+      </Form.Isolation>
+    </Form.Handler>
+  )
+}
+```
+
+## Require the user to commit before submitting
+
+In scenarios where you want to ensure users commit their changes in an isolated section before submitting the entire form, you can use the `requireCommit` property. This will prevent form submission and prompt the user to commit any uncommitted changes first.
+
+```jsx
+import { Form, Field } from '@dnb/eufemia/extensions/forms'
+
+function MyForm() {
+  return (
+    <Form.Handler>
+      <Form.Isolation requireCommit>
+        <Field.String path="/isolated" />
+        <Form.Isolation.CommitButton resetAfterCommit />
+        <Form.Isolation.ResetButton showWhenErrorIsPresent />
+      </Form.Isolation>
+    </Form.Handler>
+  )
+}
+```
+
+The `showWhenErrorIsPresent` property ensures that the reset button is displayed only when the "commit required" error is visible. This helps prevent users from resetting the form unnecessarily.
path: packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/info.mdx
user: login: tujoworker
body: Yeah, I think that's a good idea. Because this prop is ugly long.
created_at: 2025-05-12T07:11:20Z
author_association: MEMBER
diff_hunk: @@ -162,3 +163,44 @@ function MyForm() {
   )
 }
 ```
+
+## Clear data after commit
+
+You can clear the isolation the user committed by using `resetAfterCommit`:
+
+```jsx
+import { Form, Field } from '@dnb/eufemia/extensions/forms'
+
+function MyForm() {
+  return (
+    <Form.Handler>
+      <Form.Isolation>
+        <Field.String path="/isolated" />
+        <Form.Isolation.CommitButton resetAfterCommit />
+      </Form.Isolation>
+    </Form.Handler>
+  )
+}
+```
+
+## Require the user to commit before submitting
+
+In scenarios where you want to ensure users commit their changes in an isolated section before submitting the entire form, you can use the `requireCommit` property. This will prevent form submission and prompt the user to commit any uncommitted changes first.
+
+```jsx
+import { Form, Field } from '@dnb/eufemia/extensions/forms'
+
+function MyForm() {
+  return (
+    <Form.Handler>
+      <Form.Isolation requireCommit>
+        <Field.String path="/isolated" />
+        <Form.Isolation.CommitButton resetAfterCommit />
+        <Form.Isolation.ResetButton showWhenErrorIsPresent />
+      </Form.Isolation>
+    </Form.Handler>
+  )
+}
+```
+
+The `showWhenErrorIsPresent` property ensures that the reset button is displayed only when the "commit required" error is visible. This helps prevent users from resetting the form unnecessarily.
path: packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/info.mdx
user: login: tujoworker
body: `visibleWhen` uses objects in other places. This seems a little clubsy to me:

```tsx
visibleWhen={{
  errorIsPresent: true
}}
```

I'm not sure if `visibleWhen="errorIsPresent"` or `showWhen="errorIsPresent"` is better.
created_at: 2025-05-12T07:15:27Z
author_association: MEMBER
diff_hunk: @@ -162,3 +163,44 @@ function MyForm() {
   )
 }
 ```
+
+## Clear data after commit
+
+You can clear the isolation the user committed by using `resetAfterCommit`:
+
+```jsx
+import { Form, Field } from '@dnb/eufemia/extensions/forms'
+
+function MyForm() {
+  return (
+    <Form.Handler>
+      <Form.Isolation>
+        <Field.String path="/isolated" />
+        <Form.Isolation.CommitButton resetAfterCommit />
+      </Form.Isolation>
+    </Form.Handler>
+  )
+}
+```
+
+## Require the user to commit before submitting
+
+In scenarios where you want to ensure users commit their changes in an isolated section before submitting the entire form, you can use the `requireCommit` property. This will prevent form submission and prompt the user to commit any uncommitted changes first.
+
+```jsx
+import { Form, Field } from '@dnb/eufemia/extensions/forms'
+
+function MyForm() {
+  return (
+    <Form.Handler>
+      <Form.Isolation requireCommit>
+        <Field.String path="/isolated" />
+        <Form.Isolation.CommitButton resetAfterCommit />
+        <Form.Isolation.ResetButton showWhenErrorIsPresent />
+      </Form.Isolation>
+    </Form.Handler>
+  )
+}
+```
+
+The `showWhenErrorIsPresent` property ensures that the reset button is displayed only when the "commit required" error is visible. This helps prevent users from resetting the form unnecessarily.
path: packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/info.mdx
user: login: langz
body: Does it exist any other occurrences of naming like this in our codebase? If so, I would vote for that option🤣👍
created_at: 2025-05-12T07:33:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -182,11 +183,11 @@ function MyForm() {
 }
 ```
 
-### Define the reset data
+### Define your own data reference (`dataReference`)
 
-Technically, when you use `resetAfterCommit`, the `Form.Isolation` will reset its data context based on the "initial" internal data set.
+Technically, when you use `requireCommit` or `resetAfterCommit`, the `Form.Isolation` will use its "initial" internal data set to crate a reference. This reference is used to either compare if there is a change or to reset the data context after a commit.
path: packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/info.mdx
user: login: langz
body: ```suggestion
Technically, when you use `requireCommit` or `resetAfterCommit`, the `Form.Isolation` will use its "initial" internal data set to create a reference. This reference is used to either compare if there is a change or to reset the data context after a commit.
```
created_at: 2025-05-16T08:07:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -182,11 +183,11 @@ function MyForm() {
 }
 ```
 
-### Define the reset data
+### Define your own data reference (`dataReference`)
 
-Technically, when you use `resetAfterCommit`, the `Form.Isolation` will reset its data context based on the "initial" internal data set.
+Technically, when you use `requireCommit` or `resetAfterCommit`, the `Form.Isolation` will use its "initial" internal data set to crate a reference. This reference is used to either compare if there is a change or to reset the data context after a commit.
 
-But in some situations, you may need a different data set than the internal data set given at the initial render.
+But in some situations, you may need a different data set than the initial data set given at the initial render.
path: packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/info.mdx
user: login: langz
body: Perhaps we could provide an example (just textual) of a situation like this? I don't fully see it 😅 
created_at: 2025-05-16T08:08:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -56,6 +57,10 @@ export type IsolationProviderProps<Data extends JsonObject> = {
    * Prevent the form from being submitted when there are fields with errors inside the Form.Isolation.
    */
   bubbleValidation?: boolean
+  /**
+   * If the container should be committed before the form is submitted.
path: packages/dnb-eufemia/src/extensions/forms/Form/Isolation/Isolation.tsx
user: login: langz
body: ```suggestion
   * If the isolation containing changes should be committed before the form is submitted.
```
created_at: 2025-05-16T09:05:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -25,6 +25,11 @@ export const IsolationProperties: PropertiesTableProps = {
     type: 'boolean',
     status: 'optional',
   },
+  requireCommit: {
+    doc: 'If the container should be committed before the form is submitted.',
path: packages/dnb-eufemia/src/extensions/forms/Form/Isolation/IsolationDocs.ts
user: login: langz
body: ```suggestion
    doc: 'If the isolation containing changes should be committed before the form is submitted.',
```
created_at: 2025-05-16T09:05:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -23,8 +23,16 @@ import * as Examples from './Examples'
 
 This example has a `defaultValue` both on the Form.Handler and the Form.Isolation.
 
-When no `defaultValue` is set on the Form.Isolation (inner context), the the default value from Form.Handler (outer context) is used for the initial value.
+When no `defaultValue` is set on the Form.Isolation (inner context), the default value from Form.Handler (outer context) is used for the initial value.
 
-When pressing "Legg til" the default value from Form.Isolation is inserted again, because `resetDataAfterCommit` is set to `true`.
+When pressing the "Legg til / Add"-button, the default value from Form.Isolation is inserted again, because `resetDataAfterCommit` is set to `true`.
 
 <Examples.InsideSection />
+
+### Require commit
path: packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/demos.mdx
user: login: langz
body: ```suggestion
### Prevent uncommited changes
```
created_at: 2025-05-16T10:42:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -182,11 +183,11 @@ function MyForm() {
 }
 ```
 
-### Define the reset data
+### Define your own data reference (`dataReference`)
 
-Technically, when you use `resetAfterCommit`, the `Form.Isolation` will reset its data context based on the "initial" internal data set.
+Technically, when you use `requireCommit` or `resetAfterCommit`, the `Form.Isolation` will use its "initial" internal data set to crate a reference. This reference is used to either compare if there is a change or to reset the data context after a commit.
 
-But in some situations, you may need a different data set than the internal data set given at the initial render.
+But in some situations, you may need a different data set than the initial data set given at the initial render.
path: packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Isolation/info.mdx
user: login: langz
body: @tujoworker 
created_at: 2025-05-16T10:44:27Z
author_association: CONTRIBUTOR

PR comments:
user: login: vercel[bot]
created_at: 2025-05-10T05:47:13Z
body: [vc]: #ByhYFG567wTkcRunEkojQxNEhrU2iaHNwqzkUhzuXYc=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJldWZlbWlhIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL2V1ZmVtaWEvZXVmZW1pYS8ydkpSZW5qRUVRYkRFUGZHeDhGVExzem11Qk45IiwicHJldmlld1VybCI6ImV1ZmVtaWEtZ2l0LWZlYXQtZm9ybXMtaXNvbGF0aW9uLXJlcXVpcmVjb21taXQtZXVmZW1pYS52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IkRFUExPWUVEIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6ImV1ZmVtaWEtZ2l0LWZlYXQtZm9ybXMtaXNvbGF0aW9uLXJlcXVpcmVjb21taXQtZXVmZW1pYS52ZXJjZWwuYXBwIn0sInJvb3REaXJlY3RvcnkiOm51bGx9XX0=
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **eufemia** | ✅ Ready ([Inspect](https://vercel.com/eufemia/eufemia/2vJRenjEEQbDEPfGx8FTLszmuBN9)) | [Visit Preview](https://eufemia-git-feat-forms-isolation-requirecommit-eufemia.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/eufemia-git-feat-forms-isolation-requirecommit-eufemia.vercel.app?via=pr-comment-feedback-link) | May 18, 2025 0:01am |


author_association: NONE
user: login: codesandbox-ci[bot]
created_at: 2025-05-10T05:55:02Z
body: This pull request is automatically built and testable in [CodeSandbox](https://codesandbox.io).

  To see build info of the built libraries, click [here](https://ci.codesandbox.io/status/dnbexperience/eufemia/pr/5102/builds/617322) or the icon next to each commit SHA.
author_association: NONE
user: login: langz
created_at: 2025-05-16T08:47:22Z
body: `requireCommit`, to me it could sound like one is required to make a commit, or so, which is not the case. 
I feel like the prop name could be more descriptive in regards to preventing dirty/unsaved changes.
Also using the word require makes me think about the html required attribute/property.

Potential alternatives:
- `preventUnsavedChanges`
- `preventUncommitedChanges`
- `requireChangesToBeCommited`

I think I like `preventUncommitedChanges` the best for the `Form.Isolation` as the the word commit has meaning 🤔 
But for PushContainer, I'm not sure, the word "commit" is rarely used, https://eufemia.dnb.no/uilib/extensions/forms/Iterate/PushContainer/properties/

For PushContainer, perhaps `preventUnsavedChanges`?

Not sure if I want to change it, as we already use it in Iterate.PushContainer, etc.
We don't need to change this as part of this PR or this release, but could be worth thinking about.

Here's two PRs:
- https://github.com/dnbexperience/eufemia/pull/5134
- https://github.com/dnbexperience/eufemia/pull/5137
author_association: CONTRIBUTOR
user: login: langz
created_at: 2025-05-16T08:52:36Z
body: `resetAfterCommit`, what does it reset? Is it  Should we state that it resets the values of the isolated form?

Potential alternatives:
- `resetValuesAfterCommit`
- `resetInputsAfterCommit`
- `resetFieldsAfterCommit`
- `resetDataAfterCommit`

Also, could it be that one would only want to reset a given field of the `Form.Isolation`? How would one do that? Is this something we should support?

Whops, I meant to make a pull request, but somehow managed to push to main, haha. Sorry.
https://github.com/dnbexperience/eufemia/commit/d10caa02fe3d1319e196626c4c77365061dec008
author_association: CONTRIBUTOR
user: login: langz
created_at: 2025-05-16T11:17:04Z
body: > `resetDataAfterCommit` is available like `<Form.Isolation resetDataAfterCommit />`.
> Could it be that one would only want to reset a given field of the `Form.Isolation`? How would one do that? Is this something we should support? Or should we only support resetting all fields/children of the Form.Isolation?

What do you think @tujoworker ?


author_association: CONTRIBUTOR
user: login: tujoworker
created_at: 2025-05-16T11:22:25Z
body: > Could it be that one would only want to reset a given field of the Form.Isolation?

Yes, but then it probably is easier to do it imperative/manually. 

> How would one do that? 

I think using the [snapshot functionality](https://eufemia.dnb.no/uilib/extensions/forms/Form/useSnapshot/) (`<Form.Snapshot name="my-snapshot-slice-name">`) could be interesting to use here.

Is this something we should support?

Yes, but we may add such a feature at a later stage. 

> Or should we only support resetting all fields/children of the Form.Isolation?

I would argue, that this is the most common way a form would work.
author_association: MEMBER
user: login: langz
created_at: 2025-05-16T12:26:57Z
body: I think I discovered a new issue. But that's likely related to `resetDataAfterCommit`, and not `preventUncommittedChanges`.
- Visit the following example https://eufemia-git-feat-forms-isolation-requirecommit-eufemia.vercel.app/uilib/extensions/forms/Form/Isolation/demos/#using-the-commitbutton
- Write`abc` in the Isolated field
- Press the "Commit"-button
- Write `something` in the Outside of isolation field
- Watch the Isolated field suddenly having the value `abc`.

Video:

https://github.com/user-attachments/assets/e8acd2a5-59e0-40b9-bb9e-1facf785e196



author_association: CONTRIBUTOR
user: login: tujoworker
created_at: 2025-05-19T10:12:36Z
body: :tada: This PR is included in version 10.74.0 :tada:

The release is available on:
- [npm package (@latest dist-tag)](https://www.npmjs.com/package/@dnb/eufemia/v/10.74.0)
- [GitHub release](https://github.com/dnbexperience/eufemia/releases/tag/v10.74.0)

Your **[semantic-release](https://github.com/semantic-release/semantic-release)** bot :package::rocket:
author_association: MEMBER