diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components/tabs/Examples.tsx b/packages/dnb-design-system-portal/src/docs/uilib/components/tabs/Examples.tsx
index c9d6b39ce41..625c3d4bd3a 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/components/tabs/Examples.tsx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/components/tabs/Examples.tsx
@@ -338,3 +338,27 @@ export const TabsNoBorder = () => (
)
+
+export const TabsSingleChildrenReactElement = () =>
+ !globalThis.IS_TEST ? null : (
+
+
+
+
+ hello1
+
+
+
+
+ )
+
+export const TabsSingleElementData = () =>
+ !globalThis.IS_TEST ? null : (
+
+
+ hello1 }]}
+ />
+
+
+ )
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components/tabs/demos.mdx b/packages/dnb-design-system-portal/src/docs/uilib/components/tabs/demos.mdx
index d45e4babf5a..37e395dbbff 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/components/tabs/demos.mdx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/components/tabs/demos.mdx
@@ -13,6 +13,8 @@ import {
TabsExampleReachRouterNavigation,
TabsNoBorder,
TabsExamplePrerender,
+ TabsSingleChildrenReactElement,
+ TabsSingleElementData,
} from 'Docs/uilib/components/tabs/Examples'
## Demos
@@ -86,3 +88,6 @@ const exampleContent = {
fourth: 'Fourth as a string only',
}
```
+
+
+
diff --git a/packages/dnb-eufemia/src/components/tabs/Tabs.js b/packages/dnb-eufemia/src/components/tabs/Tabs.js
index 54e54cba228..51885f1ab3c 100644
--- a/packages/dnb-eufemia/src/components/tabs/Tabs.js
+++ b/packages/dnb-eufemia/src/components/tabs/Tabs.js
@@ -199,56 +199,71 @@ export default class Tabs extends React.PureComponent {
}
static getData(props) {
+ const addReactElement = (list, reactElem, reactElemIndex) => {
+ if (
+ reactElem.props &&
+ reactElem.props.displayName === 'CustomContent' // we use this solution, as Component.displayName
+ ) {
+ // tabs data from main prop
+ const dataProps =
+ (props.tabs &&
+ Array.isArray(props.tabs) &&
+ props.tabs[reactElemIndex]) ||
+ {}
+
+ // props from the "CustomContent" Component
+ const componentProps = { ...reactElem.props }
+ if (componentProps.title === null) {
+ delete componentProps.title
+ }
+
+ const {
+ title,
+ key: _key,
+ hash,
+ ...rest
+ } = {
+ ...dataProps,
+ ...componentProps,
+ ...{ children: null }, // remove children, if there is some
+ }
+
+ list.push({
+ title,
+ key: (!_key && hash ? hash : _key) || slugify(title),
+ content: reactElem, // can be a Node or a Function
+ ...rest,
+ })
+ }
+ }
+
let res = []
// check if we have to use the children prop to prepare our data
const data =
!props.data && props.children ? props.children : props.data
- // if it is a React Component - collect data from Tabs.Content component
+ // if it is an array of React Components - collect data from Tabs.Content component
if (
Array.isArray(props.children) &&
(typeof props.children[0] === 'function' ||
React.isValidElement(props.children[0]))
) {
- res = props.children.reduce((acc, content, i) => {
- if (
- content.props &&
- content.props.displayName === 'CustomContent' // we use this solution, as Component.displayName
- ) {
- // tabs data from main prop
- const dataProps =
- (props.tabs && Array.isArray(props.tabs) && props.tabs[i]) ||
- {}
-
- // props from the "CustomContent" Component
- const componentProps = { ...content.props }
- if (componentProps.title === null) {
- delete componentProps.title
- }
-
- const {
- title,
- key: _key,
- hash,
- ...rest
- } = {
- ...dataProps,
- ...componentProps,
- ...{ children: null }, // remove children, if there is some
- }
-
- acc.push({
- title,
- key: (!_key && hash ? hash : _key) || slugify(title),
- content, // can be a Node or a Function
- ...rest,
- })
- }
- return acc
+ res = props.children.reduce((list, reactElem, i) => {
+ addReactElement(list, reactElem, i)
+ return list
}, [])
}
+ // if it is a single React Component - collect data from Tabs.Content component
+ if (
+ !Array.isArray(props.children) &&
+ (typeof props.children === 'function' ||
+ React.isValidElement(props.children))
+ ) {
+ addReactElement(res, props.children)
+ }
+
// continue, while the children didn't contain our data
if (!(res && res.length > 0)) {
// if data is array, it looks good!
diff --git a/packages/dnb-eufemia/src/components/tabs/__tests__/Tabs.screenshot.test.ts b/packages/dnb-eufemia/src/components/tabs/__tests__/Tabs.screenshot.test.ts
index 7d426cd55b0..02279bfba18 100644
--- a/packages/dnb-eufemia/src/components/tabs/__tests__/Tabs.screenshot.test.ts
+++ b/packages/dnb-eufemia/src/components/tabs/__tests__/Tabs.screenshot.test.ts
@@ -21,6 +21,20 @@ describe('Tabs', () => {
expect(screenshot).toMatchImageSnapshot()
})
+ it('have to match when used with a single children as react element', async () => {
+ const screenshot = await makeScreenshot({
+ selector: '[data-visual-test="tabs-single-children-react-element"]',
+ })
+ expect(screenshot).toMatchImageSnapshot()
+ })
+
+ it('have to match when used with a single element in data', async () => {
+ const screenshot = await makeScreenshot({
+ selector: '[data-visual-test="tabs-single-element-data"]',
+ })
+ expect(screenshot).toMatchImageSnapshot()
+ })
+
it('have to match a tablist with a click handler', async () => {
const screenshot = await makeScreenshot({
selector: '[data-visual-test="tabs-clickhandler"] .dnb-tabs__tabs',
diff --git a/packages/dnb-eufemia/src/components/tabs/__tests__/Tabs.test.tsx b/packages/dnb-eufemia/src/components/tabs/__tests__/Tabs.test.tsx
index d4cd92d57db..662e8fa329c 100644
--- a/packages/dnb-eufemia/src/components/tabs/__tests__/Tabs.test.tsx
+++ b/packages/dnb-eufemia/src/components/tabs/__tests__/Tabs.test.tsx
@@ -546,6 +546,42 @@ describe('A single Tab component', () => {
expect(testKey).toBe('third')
})
+ it('has to work with "Tabs.Content" as a single children', () => {
+ render(
+
+
+ single
+
+
+ )
+
+ expect(
+ document.querySelector('div.dnb-tabs__content__inner').textContent
+ ).toBe('single')
+ expect(
+ document.querySelector('button span.dnb-tabs__button__title')
+ .textContent
+ ).toBe('single title')
+ })
+
+ it('has to work with a single element for data property', () => {
+ render(
+ single },
+ ]}
+ />
+ )
+
+ expect(
+ document.querySelector('div.dnb-tabs__content').textContent
+ ).toBe('single')
+ expect(
+ document.querySelector('button span.dnb-tabs__button__title')
+ .textContent
+ ).toBe('single title')
+ })
+
it('should render in StrictMode', () => {
render(
diff --git a/packages/dnb-eufemia/src/components/tabs/__tests__/__image_snapshots__/tabs-have-to-match-single-single-children-as-react-element.snap.png b/packages/dnb-eufemia/src/components/tabs/__tests__/__image_snapshots__/tabs-have-to-match-single-single-children-as-react-element.snap.png
new file mode 100644
index 00000000000..2c78fa1c383
Binary files /dev/null and b/packages/dnb-eufemia/src/components/tabs/__tests__/__image_snapshots__/tabs-have-to-match-single-single-children-as-react-element.snap.png differ
diff --git a/packages/dnb-eufemia/src/components/tabs/__tests__/__image_snapshots__/tabs-have-to-match-single-single-element-in-data.snap.png b/packages/dnb-eufemia/src/components/tabs/__tests__/__image_snapshots__/tabs-have-to-match-single-single-element-in-data.snap.png
new file mode 100644
index 00000000000..2c78fa1c383
Binary files /dev/null and b/packages/dnb-eufemia/src/components/tabs/__tests__/__image_snapshots__/tabs-have-to-match-single-single-element-in-data.snap.png differ
diff --git a/packages/dnb-eufemia/src/components/tabs/__tests__/__image_snapshots__/tabs-have-to-match-when-used-with-a-single-children-as-react-element.snap.png b/packages/dnb-eufemia/src/components/tabs/__tests__/__image_snapshots__/tabs-have-to-match-when-used-with-a-single-children-as-react-element.snap.png
new file mode 100644
index 00000000000..1736a3df94d
Binary files /dev/null and b/packages/dnb-eufemia/src/components/tabs/__tests__/__image_snapshots__/tabs-have-to-match-when-used-with-a-single-children-as-react-element.snap.png differ
diff --git a/packages/dnb-eufemia/src/components/tabs/__tests__/__image_snapshots__/tabs-have-to-match-when-used-with-a-single-element-in-data.snap.png b/packages/dnb-eufemia/src/components/tabs/__tests__/__image_snapshots__/tabs-have-to-match-when-used-with-a-single-element-in-data.snap.png
new file mode 100644
index 00000000000..1736a3df94d
Binary files /dev/null and b/packages/dnb-eufemia/src/components/tabs/__tests__/__image_snapshots__/tabs-have-to-match-when-used-with-a-single-element-in-data.snap.png differ
diff --git a/packages/dnb-eufemia/src/components/tabs/stories/Tabs.stories.tsx b/packages/dnb-eufemia/src/components/tabs/stories/Tabs.stories.tsx
index 1e3d381caf2..fc2e944ba22 100644
--- a/packages/dnb-eufemia/src/components/tabs/stories/Tabs.stories.tsx
+++ b/packages/dnb-eufemia/src/components/tabs/stories/Tabs.stories.tsx
@@ -52,10 +52,20 @@ export const TabsSandbox = () => {
- First
+ hello1
+
+
+ hello1 }]}
+ />
+
+
+ hello1
- Second
+ hello2