diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/Count.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/Count.mdx
index a0f46dc4df7..9dcaf49444a 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/Count.mdx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/Count.mdx
@@ -1,7 +1,6 @@
---
title: 'Count'
description: '`Iterate.Count` is a helper component / function that returns the count of a data array or object.'
-order: 11
showTabs: true
tabs:
- title: Info
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/ItemNo.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/ItemNo.mdx
new file mode 100644
index 00000000000..b7e8da841b3
--- /dev/null
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/ItemNo.mdx
@@ -0,0 +1,25 @@
+---
+title: 'ItemNo'
+description: '`Iterate.ItemNo` is a helper component that can be used to render the current item number (index) in a given string.'
+showTabs: true
+tabs:
+ - title: Info
+ key: '/info'
+ - title: Demos
+ key: '/demos'
+breadcrumb:
+ - text: Forms
+ href: /uilib/extensions/forms/
+ - text: Extended features
+ href: /uilib/extensions/forms/
+ - text: Iterate
+ href: /uilib/extensions/forms/Iterate/
+ - text: ItemNo
+ href: /uilib/extensions/forms/Iterate/ItemNo/
+---
+
+import Info from 'Docs/uilib/extensions/forms/Iterate/ItemNo/info'
+import Demos from 'Docs/uilib/extensions/forms/Iterate/ItemNo/demos'
+
+
+
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/ItemNo/Examples.tsx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/ItemNo/Examples.tsx
new file mode 100644
index 00000000000..270e261dd60
--- /dev/null
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/ItemNo/Examples.tsx
@@ -0,0 +1,14 @@
+import ComponentBox from '../../../../../../shared/tags/ComponentBox'
+import { Form, Iterate } from '@dnb/eufemia/src/extensions/forms'
+
+export const Default = () => {
+ return (
+
+
+
+ {'Item no. {itemNo}'}
+
+
+
+ )
+}
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/ItemNo/demos.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/ItemNo/demos.mdx
new file mode 100644
index 00000000000..13d1e6b62f6
--- /dev/null
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/ItemNo/demos.mdx
@@ -0,0 +1,11 @@
+---
+showTabs: true
+---
+
+import * as Examples from './Examples'
+
+## Demos
+
+### Default
+
+
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/ItemNo/info.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/ItemNo/info.mdx
new file mode 100644
index 00000000000..03205372016
--- /dev/null
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/ItemNo/info.mdx
@@ -0,0 +1,21 @@
+---
+showTabs: true
+---
+
+## Description
+
+`Iterate.ItemNo` is a helper component that can be used to render the current item number (index) in a given string. It will replace `{itemNo}` with the current item number.
+
+```tsx
+import { Form, Iterate } from '@dnb/eufemia/extensions/forms'
+
+const myString = 'Item no. {itemNo}'
+
+render(
+
+
+ {myString}
+
+ ,
+)
+```
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/PushContainer.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/PushContainer.mdx
index 2f2b6fe73a7..748b1c55a6c 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/PushContainer.mdx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/PushContainer.mdx
@@ -1,7 +1,7 @@
---
title: 'PushContainer'
description: '`Iterate.PushContainer` enables users to create a new item in the array.'
-order: 9
+order: 7
showTabs: true
tabs:
- title: Info
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/Toolbar.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/Toolbar.mdx
index cb6f333183f..8a16d1dc731 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/Toolbar.mdx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Iterate/Toolbar.mdx
@@ -1,7 +1,6 @@
---
title: 'Toolbar'
description: '`Iterate.Toolbar` is a helper component to be used within an `Iterate.AnimatedContainer` to add a toolbar to each item in the array.'
-order: 10
showTabs: true
tabs:
- title: Info
diff --git a/packages/dnb-eufemia/src/extensions/forms/Iterate/EditContainer/EditContainer.tsx b/packages/dnb-eufemia/src/extensions/forms/Iterate/EditContainer/EditContainer.tsx
index 7da3dbf8647..72ab1170946 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Iterate/EditContainer/EditContainer.tsx
+++ b/packages/dnb-eufemia/src/extensions/forms/Iterate/EditContainer/EditContainer.tsx
@@ -9,6 +9,7 @@ import Toolbar from '../Toolbar'
import { useSwitchContainerMode } from '../hooks'
import DoneButton from './DoneButton'
import CancelButton, { useWasNew } from './CancelButton'
+import { replaceItemNo } from '../ItemNo'
export type Props = {
/**
@@ -88,18 +89,12 @@ export function EditContainerWithoutToolbar(
} = props || {}
const wasNew = useWasNew({ isNew, containerMode })
- let itemTitle = wasNew && titleWhenNew ? titleWhenNew : title
- let ariaLabel = useMemo(() => convertJsxToString(itemTitle), [itemTitle])
- if (ariaLabel.includes('{itemN')) {
- /**
- * {itemNr} is deprecated, and can be removed in v11 in favor of {itemNo}
- * So in v11 we can use '{itemNo}' instead of a regex
- */
- itemTitle = ariaLabel = ariaLabel.replace(
- /\{itemN(r|o)\}/g,
- String(index + 1)
+ const itemTitle = useMemo(() => {
+ return replaceItemNo(
+ wasNew && titleWhenNew ? titleWhenNew : title,
+ index
)
- }
+ }, [index, title, titleWhenNew, wasNew])
useSwitchContainerMode({ path })
@@ -107,7 +102,7 @@ export function EditContainerWithoutToolbar(
{itemTitle && {itemTitle}}
diff --git a/packages/dnb-eufemia/src/extensions/forms/Iterate/ItemNo/ItemNo.tsx b/packages/dnb-eufemia/src/extensions/forms/Iterate/ItemNo/ItemNo.tsx
new file mode 100644
index 00000000000..6fb99f548f1
--- /dev/null
+++ b/packages/dnb-eufemia/src/extensions/forms/Iterate/ItemNo/ItemNo.tsx
@@ -0,0 +1,35 @@
+import React, { useMemo } from 'react'
+import { useItem } from '../hooks'
+import { convertJsxToString } from '../../../../shared/component-helper'
+
+function ItemNo({ children }) {
+ const { index } = useItem()
+
+ children = useMemo(
+ () => replaceItemNo(children, index),
+ [children, index]
+ )
+
+ return <>{replaceItemNo(children, index)}>
+}
+
+export function replaceItemNo(
+ children: React.ReactNode,
+ index: number
+): string | React.ReactNode {
+ const text =
+ typeof children !== 'string' ? convertJsxToString(children) : children
+
+ if (text.includes('{itemN')) {
+ /**
+ * {itemNr} is deprecated, and can be removed in v11 in favor of {itemNo}
+ * So in v11 we can use '{itemNo}' instead of a regex
+ */
+ return text.replace(/\{itemN(r|o)\}/g, String(index + 1))
+ }
+
+ return children
+}
+
+ItemNo._supportsSpacingProps = false
+export default ItemNo
diff --git a/packages/dnb-eufemia/src/extensions/forms/Iterate/ItemNo/__tests__/ItemNo.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Iterate/ItemNo/__tests__/ItemNo.test.tsx
new file mode 100644
index 00000000000..d34d90d69f7
--- /dev/null
+++ b/packages/dnb-eufemia/src/extensions/forms/Iterate/ItemNo/__tests__/ItemNo.test.tsx
@@ -0,0 +1,35 @@
+import React from 'react'
+import { render } from '@testing-library/react'
+import { Iterate } from '../../..'
+
+describe('Iterate.ItemNo', () => {
+ it('should replace {itemNo} in children given as a string', () => {
+ render(
+
+ {'Item no. {itemNo} string'}
+
+ )
+ expect(document.body).toHaveTextContent('Item no. 1 string')
+ })
+
+ it('should replace several array items', () => {
+ render(
+
+ {'Item no. {itemNo} string'}
+
+ )
+ expect(document.body).toHaveTextContent('Item no. 1 string')
+ expect(document.body).toHaveTextContent('Item no. 2 string')
+ })
+
+ it('should remove jsx and return only a string', () => {
+ render(
+
+
+ {'Item no. {itemNo} string'}
+
+
+ )
+ expect(document.body).toHaveTextContent('Item no. 1 string')
+ })
+})
diff --git a/packages/dnb-eufemia/src/extensions/forms/Iterate/ItemNo/index.ts b/packages/dnb-eufemia/src/extensions/forms/Iterate/ItemNo/index.ts
new file mode 100644
index 00000000000..8bfd3c6ca4a
--- /dev/null
+++ b/packages/dnb-eufemia/src/extensions/forms/Iterate/ItemNo/index.ts
@@ -0,0 +1,2 @@
+export { default } from './ItemNo'
+export * from './ItemNo'
diff --git a/packages/dnb-eufemia/src/extensions/forms/Iterate/ViewContainer/ViewContainer.tsx b/packages/dnb-eufemia/src/extensions/forms/Iterate/ViewContainer/ViewContainer.tsx
index e5002c5ba00..cc49e27fa4c 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Iterate/ViewContainer/ViewContainer.tsx
+++ b/packages/dnb-eufemia/src/extensions/forms/Iterate/ViewContainer/ViewContainer.tsx
@@ -9,6 +9,7 @@ import IterateItemContext from '../IterateItemContext'
import Toolbar from '../Toolbar'
import EditButton from './EditButton'
import RemoveButton from './RemoveButton'
+import { replaceItemNo } from '../ItemNo'
export type Props = {
/**
@@ -37,19 +38,9 @@ function ViewContainer(props: AllProps) {
...restProps
} = props || {}
const { index, arrayValue } = useContext(IterateItemContext)
-
- let itemTitle = title
- let ariaLabel = useMemo(() => convertJsxToString(itemTitle), [itemTitle])
- if (ariaLabel.includes('{itemN')) {
- /**
- * {itemNr} is deprecated, and can be removed in v11 in favor of {itemNo}
- * So in v11 we can use '{itemNo}' instead of a regex
- */
- itemTitle = ariaLabel = ariaLabel.replace(
- /\{itemN(r|o)\}/g,
- String(index + 1)
- )
- }
+ const itemTitle = useMemo(() => {
+ return replaceItemNo(title, index)
+ }, [index, title])
let toolbarElement = toolbar
if (toolbarVariant === 'minimumOneItem' && arrayValue.length <= 1) {
@@ -69,7 +60,7 @@ function ViewContainer(props: AllProps) {
return (
diff --git a/packages/dnb-eufemia/src/extensions/forms/Iterate/index.ts b/packages/dnb-eufemia/src/extensions/forms/Iterate/index.ts
index 0b045e6969b..4f0a3712380 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Iterate/index.ts
+++ b/packages/dnb-eufemia/src/extensions/forms/Iterate/index.ts
@@ -9,6 +9,7 @@ export { default as EditContainer } from './EditContainer'
export { default as ViewContainer } from './ViewContainer'
export { default as AnimatedContainer } from './AnimatedContainer'
export { default as Toolbar } from './Toolbar'
+export { default as ItemNo } from './ItemNo'
export { useCount, count, Count } from './Count'
export { default as useItem } from './hooks/useItem'
export { default as IterateItemContext } from './IterateItemContext'