Skip to content

Commit d333f38

Browse files
authored
fix(Forms): add support for using Visibility inside PushContainer (#4623)
This change allows `Form.Visibility` to work as expected inside an `Iterate.PushContainer`. Using it within a `Form.Isolation` already behaved correctly, because the data context flows in from the outside. That wasn’t happening in a `PushContainer`, and since `Form.Visibility` depends on a reachable data context, it now functions properly there as well.
1 parent c5219ca commit d333f38

File tree

3 files changed

+79
-1
lines changed

3 files changed

+79
-1
lines changed

packages/dnb-eufemia/src/extensions/forms/Form/Isolation/__tests__/Isolation.test.tsx

+40
Original file line numberDiff line numberDiff line change
@@ -1705,4 +1705,44 @@ describe('Form.Isolation', () => {
17051705
expect(onCommit).toHaveBeenCalledTimes(1)
17061706
})
17071707
})
1708+
1709+
describe('Visibility', () => {
1710+
it('should show the children initially', () => {
1711+
render(
1712+
<Form.Handler
1713+
defaultData={{
1714+
isVisible: true,
1715+
}}
1716+
>
1717+
<Form.Isolation>
1718+
<Form.Visibility pathTrue="/isVisible">
1719+
<output>content</output>
1720+
</Form.Visibility>
1721+
</Form.Isolation>
1722+
</Form.Handler>
1723+
)
1724+
1725+
expect(document.querySelector('output')).toBeInTheDocument()
1726+
})
1727+
1728+
it('should support Visibility', async () => {
1729+
render(
1730+
<Form.Handler>
1731+
<Field.Boolean variant="button" path="/isVisible" />
1732+
1733+
<Form.Isolation>
1734+
<Form.Visibility pathTrue="/isVisible">
1735+
<output>content</output>
1736+
</Form.Visibility>
1737+
</Form.Isolation>
1738+
</Form.Handler>
1739+
)
1740+
1741+
expect(document.querySelector('output')).toBeNull()
1742+
1743+
await userEvent.click(document.querySelector('button'))
1744+
1745+
expect(document.querySelector('output')).toBeInTheDocument()
1746+
})
1747+
})
17081748
})

packages/dnb-eufemia/src/extensions/forms/Iterate/PushContainer/PushContainer.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ export type AllProps = Props & SpacingProps & ArrayItemAreaProps
120120

121121
function PushContainer(props: AllProps) {
122122
const [, forceUpdate] = useReducer(() => ({}), {})
123-
const requiredInherited = useContext(DataContext)?.required
123+
const { data: outerData, required: requiredInherited } =
124+
useContext(DataContext) || {}
124125

125126
const {
126127
data: dataProp,
@@ -180,6 +181,14 @@ function PushContainer(props: AllProps) {
180181
}
181182
}, [dataProp, defaultDataProp, isolatedData])
182183

184+
if (outerData) {
185+
// Use assign to avoid mutating the original data object.
186+
// Because changes from outside should only silently be applied to the
187+
// data object, without triggering a rerender.
188+
// This way "pushContainerItems" will not clear/unset changed data.
189+
Object.assign(data, outerData)
190+
}
191+
183192
const defaultData = useMemo(() => {
184193
return {
185194
...(!dataProp ? isolatedData : null),

packages/dnb-eufemia/src/extensions/forms/Iterate/PushContainer/__tests__/PushContainer.test.tsx

+29
Original file line numberDiff line numberDiff line change
@@ -1235,4 +1235,33 @@ describe('PushContainer', () => {
12351235
)
12361236
})
12371237
})
1238+
1239+
it('should support Visibility', async () => {
1240+
render(
1241+
<Form.Handler
1242+
defaultData={{
1243+
isVisible: false,
1244+
entries: [
1245+
{
1246+
foo: 'First entry',
1247+
},
1248+
],
1249+
}}
1250+
>
1251+
<Field.Boolean variant="button" path="/isVisible" />
1252+
1253+
<Iterate.PushContainer path="/entries">
1254+
<Form.Visibility pathTrue="/isVisible">
1255+
<output>content</output>
1256+
</Form.Visibility>
1257+
</Iterate.PushContainer>
1258+
</Form.Handler>
1259+
)
1260+
1261+
expect(document.querySelector('output')).toBeNull()
1262+
1263+
await userEvent.click(document.querySelector('button'))
1264+
1265+
expect(document.querySelector('output')).toBeInTheDocument()
1266+
})
12381267
})

0 commit comments

Comments
 (0)