-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Forms): add
Form.useSnapshot
hook to handle snapshots of data (#…
…4102) Here is a [demo](https://eufemia-git-feat-use-snapshot-eufemia.vercel.app/uilib/extensions/forms/Form/useSnapshot/#used-in-a-wizard). --------- Co-authored-by: Anders <[email protected]>
- Loading branch information
1 parent
f67b3bb
commit d451793
Showing
25 changed files
with
1,049 additions
and
157 deletions.
There are no files selected for viewing
23 changes: 23 additions & 0 deletions
23
...s/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/useSnapshot.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
--- | ||
title: 'useSnapshot' | ||
description: '`Form.useSnapshot` lets you store data snapshots of your form data, either inside or outside of the form context.' | ||
showTabs: true | ||
tabs: | ||
- title: Info | ||
key: '/info' | ||
- title: Demos | ||
key: '/demos' | ||
breadcrumb: | ||
- text: Forms | ||
href: /uilib/extensions/forms/ | ||
- text: Form | ||
href: /uilib/extensions/forms/Form/ | ||
- text: Form.useSnapshot | ||
href: /uilib/extensions/forms/Form/useSnapshot/ | ||
--- | ||
|
||
import Info from 'Docs/uilib/extensions/forms/Form/useSnapshot/info' | ||
import Demos from 'Docs/uilib/extensions/forms/Form/useSnapshot/demos' | ||
|
||
<Info /> | ||
<Demos /> |
117 changes: 117 additions & 0 deletions
117
...es/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/useSnapshot/Examples.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
import React from 'react' | ||
import { Button, Card } from '@dnb/eufemia/src' | ||
import ComponentBox from '../../../../../../shared/tags/ComponentBox' | ||
import { | ||
Field, | ||
Form, | ||
Tools, | ||
Wizard, | ||
} from '@dnb/eufemia/src/extensions/forms' | ||
|
||
export const InWizard = () => { | ||
return ( | ||
<ComponentBox> | ||
{() => { | ||
const MyForm = () => { | ||
const { createSnapshot, revertSnapshot } = | ||
Form.useSnapshot('my-form') | ||
|
||
return ( | ||
<Form.Handler id="my-form"> | ||
<Wizard.Container | ||
onStepChange={(index, mode, args) => { | ||
if (mode === 'previous') { | ||
revertSnapshot(String(args.id), 'my-snapshot-slice') | ||
} else { | ||
createSnapshot( | ||
args.previousStep.id, | ||
'my-snapshot-slice', | ||
) | ||
} | ||
}} | ||
> | ||
<Wizard.Step title="Step A" id="step-a"> | ||
<Form.Snapshot name="my-snapshot-slice"> | ||
<Field.String path="/foo" label="Will be reverted" /> | ||
</Form.Snapshot> | ||
<Field.String path="/bar" label="Will stay" /> | ||
<Wizard.Buttons /> | ||
</Wizard.Step> | ||
|
||
<Wizard.Step title="Step B" id="step-b"> | ||
<Field.String path="/foo" label="Will be reverted" /> | ||
<Field.String path="/bar" label="Will stay" /> | ||
<Wizard.Buttons /> | ||
</Wizard.Step> | ||
</Wizard.Container> | ||
</Form.Handler> | ||
) | ||
} | ||
|
||
return <MyForm /> | ||
}} | ||
</ComponentBox> | ||
) | ||
} | ||
|
||
export const UndoRedo = () => { | ||
return ( | ||
<ComponentBox scope={{ Tools }}> | ||
{() => { | ||
const MyComponent = () => { | ||
const { createSnapshot, applySnapshot } = Form.useSnapshot() | ||
const pointerRef = React.useRef(0) | ||
|
||
React.useEffect(() => { | ||
createSnapshot(pointerRef.current, 'my-snapshot-slice') | ||
}, [createSnapshot]) | ||
|
||
const changeHandler = React.useCallback(() => { | ||
pointerRef.current += 1 | ||
createSnapshot(pointerRef.current, 'my-snapshot-slice') | ||
}, [createSnapshot]) | ||
const undoHandler = React.useCallback(() => { | ||
pointerRef.current -= 1 | ||
applySnapshot(pointerRef.current, 'my-snapshot-slice') | ||
}, [applySnapshot]) | ||
const redoHandler = React.useCallback(() => { | ||
pointerRef.current += 1 | ||
applySnapshot(pointerRef.current, 'my-snapshot-slice') | ||
}, [applySnapshot]) | ||
|
||
return ( | ||
<> | ||
<Card stack> | ||
<Form.Snapshot name="my-snapshot-slice"> | ||
<Field.String | ||
path="/foo" | ||
label="Will be reverted" | ||
onChange={changeHandler} | ||
/> | ||
</Form.Snapshot> | ||
<Field.String path="/bar" label="Will stay" /> | ||
</Card> | ||
|
||
<Form.ButtonRow> | ||
<Button variant="secondary" onClick={undoHandler}> | ||
Undo | ||
</Button> | ||
<Button variant="secondary" onClick={redoHandler}> | ||
Redo | ||
</Button> | ||
</Form.ButtonRow> | ||
|
||
<Tools.Log top /> | ||
</> | ||
) | ||
} | ||
|
||
return ( | ||
<Form.Handler> | ||
<MyComponent /> | ||
</Form.Handler> | ||
) | ||
}} | ||
</ComponentBox> | ||
) | ||
} |
17 changes: 17 additions & 0 deletions
17
...design-system-portal/src/docs/uilib/extensions/forms/Form/useSnapshot/demos.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
--- | ||
showTabs: true | ||
--- | ||
|
||
import * as Examples from './Examples' | ||
|
||
## Demos | ||
|
||
### Undo / Redo | ||
|
||
<Examples.UndoRedo /> | ||
|
||
### Used in a Wizard | ||
|
||
This example reverts the form data to its previous state when the user navigates back to a previous step. | ||
|
||
<Examples.InWizard /> |
107 changes: 107 additions & 0 deletions
107
...-design-system-portal/src/docs/uilib/extensions/forms/Form/useSnapshot/info.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
--- | ||
showTabs: true | ||
--- | ||
|
||
## Description | ||
|
||
The `Form.useSnapshot` hook lets you store data snapshots of your form data, either inside or outside of the form context. | ||
|
||
```tsx | ||
import { Form } from '@dnb/eufemia/extensions/forms' | ||
|
||
function MyComponent() { | ||
const { createSnapshot, applySnapshot, revertSnapshot } = | ||
Form.useSnapshot() | ||
|
||
return <>MyComponent</> | ||
} | ||
|
||
render( | ||
<Form.Handler> | ||
<MyComponent /> | ||
</Form.Handler>, | ||
) | ||
``` | ||
|
||
The hook returns an object with the following properties: | ||
|
||
- `createSnapshot` will store the current data as a new snapshot with the given id. | ||
- `applySnapshot` will revert the data to the snapshot with the given id (required). | ||
- `revertSnapshot` will revert the data to the snapshot with the given id (required). A reverted snapshot gets deleted from the memory. | ||
|
||
## Partial data snapshots | ||
|
||
In order to create and revert a snapshot for a specific part of the data context, you can use the `Form.Snapshot` component: | ||
|
||
```tsx | ||
import { Form, Field } from '@dnb/eufemia/extensions/forms' | ||
|
||
function MyForm() { | ||
return ( | ||
<Form.Handler> | ||
<Form.Snapshot name="my-snapshot-slice-name"> | ||
<Field.String path="/foo" label="Will be reverted" /> | ||
<Field.String path="/bar" label="Me too" /> | ||
</Form.Snapshot> | ||
|
||
<Field.String path="/baz" label="Will stay as before" /> | ||
</Form.Handler> | ||
) | ||
} | ||
``` | ||
|
||
When calling the `createSnapshot` or `revertSnapshot` functions, you can pass in your snapshot `name` (my-snapshot-slice-name) as the second parameter. This will make sure that the snapshot is only applied to the given part of the form data. | ||
|
||
```tsx | ||
createSnapshot('my-snapshot-1', 'my-snapshot-slice-name') | ||
revertSnapshot('my-snapshot-1', 'my-snapshot-slice-name') | ||
``` | ||
|
||
You can check out examples in the demo section. | ||
|
||
## Usage of the `Form.useSnapshot` hook | ||
|
||
You can use the `Form.useSnapshot` hook with or without an `id` (string) property, which is optional and can be used to link the data to a specific [Form.Handler](/uilib/extensions/forms/Form/Handler/) component. | ||
|
||
### Without an `id` property | ||
|
||
Here "Component" is rendered inside the `Form.Handler` component and does not need an `id` property to access the snapshot: | ||
|
||
```jsx | ||
import { Form } from '@dnb/eufemia/extensions/forms' | ||
|
||
function MyForm() { | ||
return ( | ||
<Form.Handler> | ||
<Component /> | ||
</Form.Handler> | ||
) | ||
} | ||
|
||
function Component() { | ||
const { createSnapshot, revertSnapshot } = Form.useSnapshot() | ||
} | ||
``` | ||
|
||
### With an `id` property | ||
|
||
While in this example, "Component" is outside the `Form.Handler` context, but linked together via the `id` (string) property: | ||
|
||
```jsx | ||
import { Form } from '@dnb/eufemia/extensions/forms' | ||
|
||
function MyForm() { | ||
return ( | ||
<> | ||
<Form.Handler id="unique">...</Form.Handler> | ||
<Component /> | ||
</> | ||
) | ||
} | ||
|
||
function Component() { | ||
const { createSnapshot, revertSnapshot } = Form.useSnapshot('unique') | ||
} | ||
``` | ||
|
||
This is beneficial when you need to utilize the form data in other places within your application. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.