Skip to content

Commit

Permalink
feat(forms): add Iterate.PushContainer to support an "initially ope…
Browse files Browse the repository at this point in the history
…n" container (#3843)

Co-authored-by: Anders <anderslangseth@gmail.com>
  • Loading branch information
tujoworker and langz authored Aug 20, 2024
1 parent 8747e74 commit 0fe23a9
Show file tree
Hide file tree
Showing 63 changed files with 1,145 additions and 305 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -562,20 +562,26 @@ export const UsingIterate = () => {
return (
<ComponentBox scope={{ Iterate }}>
{() => {
const MyEditItemForm = () => {
return (
<Field.Composition>
<Field.Name.First itemPath="/firstName" width="medium" />
<Field.Name.Last
itemPath="/lastName"
width="medium"
required
/>
</Field.Composition>
)
}

const MyEditItem = () => {
return (
<Iterate.EditContainer
title="Edit account holder"
titleWhenNew="New account holder"
>
<Field.Composition>
<Field.Name.First itemPath="/firstName" width="medium" />
<Field.Name.Last
itemPath="/lastName"
width="medium"
required
/>
</Field.Composition>
<MyEditItemForm />
</Iterate.EditContainer>
)
}
Expand All @@ -591,6 +597,21 @@ export const UsingIterate = () => {
)
}

const CreateNewEntry = () => {
return (
<Iterate.PushContainer
path="/accounts"
title="New account holder"
openButton={
<Iterate.PushContainer.OpenButton text="Add another account" />
}
showOpenButtonWhen={(list) => list.length > 0}
>
<MyEditItemForm />
</Iterate.PushContainer>
)
}

const MyForm = () => {
return (
<Form.Handler
Expand All @@ -616,11 +637,7 @@ export const UsingIterate = () => {
<MyEditItem />
</Iterate.Array>

<Iterate.PushButton
text="Add another account"
path="/accounts"
pushValue={{}}
/>
<CreateNewEntry />
</Card>

<Form.SubmitButton variant="send" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: 'Array'
description: '`Iterate.Array` works in many ways similar to field-components. It has a value-prop that can receive an array or you can give it a path if you want it to retrieve an array from a surrounding DataContext. All children components of Iterate.Array are rendered once per element the array-value consists of.'
description: '`Iterate.Array` works in many ways similar to field-components. It has a value-prop that can receive an array or you can give it a path if you want it to retrieve an array from a surrounding DataContext. All children components of Iterate.Array are rendered once per item the array-value consists of.'
order: 1
showTabs: true
hideInMenu: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from '@dnb/eufemia/src/extensions/forms'
export { Default as AnimatedContainer } from '../AnimatedContainer/Examples'

export const PrimitiveElementsFields = () => {
export const PrimitiveItemsFields = () => {
return (
<ComponentBox scope={{ Iterate }}>
<Iterate.Array
Expand All @@ -21,7 +21,7 @@ export const PrimitiveElementsFields = () => {
)
}

export const PrimitiveElementsValues = () => {
export const PrimitiveItemsValues = () => {
return (
<ComponentBox
scope={{ Iterate }}
Expand Down Expand Up @@ -96,7 +96,7 @@ export const WithTable = () => {
)
}

export const ObjectElements = () => {
export const ObjectItems = () => {
return (
<ComponentBox scope={{ Iterate, Value }}>
<Iterate.Array
Expand All @@ -121,7 +121,7 @@ export const ObjectElements = () => {
)
}

export const RenderPropsPrimitiveElements = () => {
export const RenderPropsPrimitiveItems = () => {
return (
<ComponentBox scope={{ Iterate }}>
<Iterate.Array
Expand All @@ -134,7 +134,7 @@ export const RenderPropsPrimitiveElements = () => {
)
}

export const RenderPropsObjectElements = () => {
export const RenderPropsObjectItems = () => {
return (
<ComponentBox scope={{ Iterate }}>
<Iterate.Array
Expand Down Expand Up @@ -230,20 +230,26 @@ export const ViewAndEditContainer = () => {
data-visual-test="view-and-edit-container"
>
{() => {
const MyEditItemForm = () => {
return (
<Field.Composition>
<Field.Name.First itemPath="/firstName" width="medium" />
<Field.Name.Last
itemPath="/lastName"
width="medium"
required
/>
</Field.Composition>
)
}

const MyEditItem = () => {
return (
<Iterate.EditContainer
title="Edit account holder"
titleWhenNew="New account holder"
>
<Field.Composition>
<Field.Name.First itemPath="/firstName" width="medium" />
<Field.Name.Last
itemPath="/lastName"
width="medium"
required
/>
</Field.Composition>
<MyEditItemForm />
</Iterate.EditContainer>
)
}
Expand All @@ -259,6 +265,21 @@ export const ViewAndEditContainer = () => {
)
}

const CreateNewEntry = () => {
return (
<Iterate.PushContainer
path="/accounts"
title="New account holder"
openButton={
<Iterate.PushContainer.OpenButton text="Add another account" />
}
showOpenButtonWhen={(list) => list.length > 0}
>
<MyEditItemForm />
</Iterate.PushContainer>
)
}

const MyForm = () => {
return (
<Form.Handler
Expand All @@ -284,11 +305,7 @@ export const ViewAndEditContainer = () => {
<MyEditItem />
</Iterate.Array>

<Iterate.PushButton
text="Add another account"
path="/accounts"
pushValue={{}}
/>
<CreateNewEntry />
</Card>

<Form.SubmitButton variant="send" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,25 @@ import * as Examples from './Examples'

## Demos

### Primitive elements as fields
### Primitive items as fields

<Examples.PrimitiveElementsFields />
<Examples.PrimitiveItemsFields />

### Primitive elements as values
### Primitive items as values

<Examples.PrimitiveElementsValues />
<Examples.PrimitiveItemsValues />

### Object elements
### Object items

<Examples.ObjectElements />
<Examples.ObjectItems />

### Render props with primitive elements
### Render props with primitive items

<Examples.RenderPropsPrimitiveElements />
<Examples.RenderPropsPrimitiveItems />

### Render props with object elements
### Render props with object items

<Examples.RenderPropsObjectElements />
<Examples.RenderPropsObjectItems />

### Conditions using Visibility

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ hideInMenu: true

## Description

`Iterate.Array` works in many ways similar to field-components. It has a `value`-prop that can receive an array or you can give it a `path` if you want it to retrieve an array from a surrounding `DataContext`. All children components of `Iterate.Array` are rendered once per element the array-value consists of.
`Iterate.Array` works in many ways similar to field-components. It has a `value`-prop that can receive an array or you can give it a `path` if you want it to retrieve an array from a surrounding `DataContext`. All children components of `Iterate.Array` are rendered once per item the array-value consists of.

```tsx
import { Iterate, Field } from '@dnb/eufemia/extensions/forms'
Expand All @@ -22,7 +22,7 @@ render(

## About `itemPath` and `path`

`itemPath` points to the root of each iterated element, while `path`
`itemPath` points to the root of each iterated item, while `path`
points to the root of the data source:

```tsx
Expand All @@ -40,23 +40,23 @@ render(
onChange={console.log}
>
<Iterate.Array path="/listOfHeroes">
<Field.String itemPath="/name" />
<Field.Name.Last itemPath="/name" />
</Iterate.Array>
</Form.Handler>,
)
```

## Individual values and dynamic paths

Since `Iterate.Array` renders its children once per element, the field components inside must receive values based on the different elements in the array. This can be done in two ways:
Since `Iterate.Array` renders its children once per item, the field components inside must receive values based on the different items in the array. This can be done in two ways:

### 1. itemPath

If field components inside `Iterate.Array` are given an `itemPath` prop, this will look for values based on the array element being the root of the structure, even if the array often comes from a surrounding data set. This means that you do not need to think about which index the field should point to, because it is handled by `Iterate.Array` internally. You can look at the individual element as its own structure.
If field components inside `Iterate.Array` are given an `itemPath` prop, this will look for values based on the array item being the root of the structure, even if the array often comes from a surrounding data set. This means that you do not need to think about which index the field should point to, because it is handled by `Iterate.Array` internally. You can look at the individual item as its own structure.

### 2. Render props

If you want to be able to provide values to the individual field component directly instead of pointing to them with paths, you can give `Iterate.Array` a render prop. It works a bit like an array-map call. The render function receives the value of the element as the first argument, and the index of which element you are on as the second.
If you want to be able to provide values to the individual field component directly instead of pointing to them with paths, you can give `Iterate.Array` a render prop. It works a bit like an array-map call. The render function receives the value of the item as the first argument, and the index of which item you are on as the second.

Examples of both the use of `itemPath` and Render Props in `Iterate.Array` can be found on [demos](/uilib/extensions/forms/Iterate/Array/demos).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ render(
title="Edit account holder"
titleWhenNew="New account holder"
>
<Field.String itemPath="/name" />
<Field.Name.Last itemPath="/name" />
</Iterate.EditContainer>

<Iterate.ViewContainer title="Account holder">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: 'PushButton'
description: '`Iterate.PushButton` builds on top of the same data flow logic as field components, but the only thing it changes in the value it receives or retrieves from source data is adding a new element to the array.'
description: '`Iterate.PushButton` builds on top of the same data flow logic as field components, but the only thing it changes in the value it receives or retrieves from source data is adding a new item to the array.'
order: 6
showTabs: true
hideInMenu: true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import ComponentBox from '../../../../../../shared/tags/ComponentBox'
import { Iterate, Field, Form } from '@dnb/eufemia/src/extensions/forms'

export const PrimitiveElements = () => {
export const PrimitiveItems = () => {
return (
<ComponentBox scope={{ Iterate }}>
<Iterate.PushButton
text="Add another element"
text="Add another item"
value={['foo', 'bar']}
pushValue="new"
onChange={(value) => console.log('onChange', value)}
Expand All @@ -14,7 +14,7 @@ export const PrimitiveElements = () => {
)
}

export const ObjectElements = () => {
export const ObjectItems = () => {
return (
<ComponentBox scope={{ Iterate }}>
<Form.Handler
Expand All @@ -26,12 +26,12 @@ export const ObjectElements = () => {
onChange={(value) => console.log('onChange', value)}
>
<Iterate.Array path="/">
<Field.String itemPath="/name" />
<Field.Name.Last itemPath="/name" />
</Iterate.Array>

<Iterate.PushButton
top="small"
text="Add another element"
text="Add another item"
path="/"
pushValue={{}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import * as Examples from './Examples'

## Demos

### Primitive elements
### Primitive items

<Examples.PrimitiveElements />
<Examples.PrimitiveItems />

### Object elements
### Object items

<Examples.ObjectElements />
<Examples.ObjectItems />
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,20 @@ hideInMenu: true

## Description

`Iterate.PushButton` connects to the array of a surrounding `Iterate.Array` or an array from the source pointed at through `path` and adds a new element to the array when clicked.
`Iterate.PushButton` connects to the array of a surrounding `Iterate.Array` or an array from the source pointed at through `path` and adds a new item to the array when clicked.

```tsx
import { Iterate, Field } from '@dnb/eufemia/extensions/forms'

render(
<>
<Iterate.Array path="/">
<Field.String itemPath="/name" />
<Field.Name.Last itemPath="/name" />
</Iterate.Array>

<Iterate.PushButton
text="Add another element"
path="/"
pushValue={{}}
/>
<Iterate.PushButton text="Add another item" path="/" pushValue={{}} />
</>,
)
```

In order to create new items you can also use the [Iterate.PushContainer](/uilib/extensions/forms/Iterate/PushContainer/) component.
Loading

0 comments on commit 0fe23a9

Please sign in to comment.