diff --git a/packages/doc/content/components/components/actionrequirement/actionrequirement-web.mdx b/packages/doc/content/components/components/actionrequirement/actionrequirement-web.mdx
index e4037f6afb..4d3a36b15c 100644
--- a/packages/doc/content/components/components/actionrequirement/actionrequirement-web.mdx
+++ b/packages/doc/content/components/components/actionrequirement/actionrequirement-web.mdx
@@ -46,6 +46,55 @@ render(() => {
});
```
+### Multiple description paragraphs
+
+You can pass an array of strings to `description` to render multiple paragraphs. Empty, whitespace-only and `null` entries are ignored.
+
+```javascript state
+render(() => {
+ const descriptions = [
+ 'Choose your activities to start the journey.',
+ 'Track progress and adjust goals weekly.',
+ 'Celebrate achievements and stay consistent!',
+ ];
+
+ function handleGetCheckableContent() {
+ return (
+
+ I have read and agree to the Terms of Use and Privacy Policy.
+
+ )
+ };
+ function handleGetIllustration() {
+ return
+ }
+ function handleGetList() {
+ return (
+ <>
+ 1x/day standard access
+ 4x/month 1-on-1 sessions
+ 2x/month premium classes
+ >
+ )
+ }
+
+ return (
+
+
+ Start working
+ Learn more
+
+
+ );
+});
+```
+
### Props
diff --git a/packages/yoga/src/ActionRequirement/web/ActionRequirement.jsx b/packages/yoga/src/ActionRequirement/web/ActionRequirement.jsx
index e8cf716edb..0a4d6b85c3 100644
--- a/packages/yoga/src/ActionRequirement/web/ActionRequirement.jsx
+++ b/packages/yoga/src/ActionRequirement/web/ActionRequirement.jsx
@@ -9,6 +9,7 @@ import {
SecondaryButton,
} from './ActionRequirementStyles';
import Text from '../../Text';
+import parseDescription from '../../utils/parseDescription';
import Box from '../../Box';
const StyledActionRequirement = styled.div`
@@ -64,6 +65,8 @@ function ActionRequirement(props) {
let primaryButton;
let secondaryButton;
+ const descriptionArray = parseDescription(description);
+
function defineCompoundComponents() {
React.Children.forEach(children, child => {
if (isChildFromComponent(child, PrimaryButton)) primaryButton = child;
@@ -85,9 +88,13 @@ function ActionRequirement(props) {
) : (
{title}
)}
-
- {description}
-
+
+ {descriptionArray.map(paragraph => (
+
+ {paragraph}
+
+ ))}
+
{list && {list}}
{checkable && {checkable}}
@@ -102,7 +109,7 @@ function ActionRequirement(props) {
ActionRequirement.propTypes = {
title: oneOfType([arrayOf(node), node]).isRequired,
children: oneOfType([arrayOf(node), node]),
- description: string.isRequired,
+ description: oneOfType([string, arrayOf(string)]).isRequired,
checkable: oneOfType([arrayOf(node), node]),
illustration: oneOfType([arrayOf(node), node]),
list: oneOfType([arrayOf(node), node]),
diff --git a/packages/yoga/src/ActionRequirement/web/ActionRequirement.test.jsx b/packages/yoga/src/ActionRequirement/web/ActionRequirement.test.jsx
index 3468cd0c6c..4692ee3852 100644
--- a/packages/yoga/src/ActionRequirement/web/ActionRequirement.test.jsx
+++ b/packages/yoga/src/ActionRequirement/web/ActionRequirement.test.jsx
@@ -73,4 +73,22 @@ describe('', () => {
expect(container).toMatchSnapshot();
});
+
+ it('should render multiple paragraphs when description is an array', () => {
+ const descriptions = [
+ 'First requirement paragraph.',
+ 'Second requirement giving more context.',
+ 'Final requirement details here.',
+ ];
+
+ const { getByText } = render(
+
+
+ ,
+ );
+
+ descriptions.forEach(d => {
+ expect(getByText(d)).toBeTruthy();
+ });
+ });
});
diff --git a/packages/yoga/src/ActionRequirement/web/__snapshots__/ActionRequirement.test.jsx.snap b/packages/yoga/src/ActionRequirement/web/__snapshots__/ActionRequirement.test.jsx.snap
index 9ba41fcf21..73e3d5eb34 100644
--- a/packages/yoga/src/ActionRequirement/web/__snapshots__/ActionRequirement.test.jsx.snap
+++ b/packages/yoga/src/ActionRequirement/web/__snapshots__/ActionRequirement.test.jsx.snap
@@ -2,6 +2,18 @@
exports[` should default match snapshot 1`] = `
.c3 {
+ margin-top: 16px;
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ gap: 24px;
+}
+
+.c4 {
margin: 0;
padding: 0;
font-size: 16px;
@@ -9,7 +21,6 @@ exports[` should default match snapshot 1`] = `
color: #231B22;
font-family: Rubik;
font-weight: 400;
- margin-top: 16px;
color: #6B6B78;
}
@@ -24,7 +35,7 @@ exports[` should default match snapshot 1`] = `
margin-bottom: 6px;
}
-.c4 {
+.c5 {
margin-top: 32px;
display: -webkit-box;
display: -webkit-flex;
@@ -66,7 +77,7 @@ exports[` should default match snapshot 1`] = `
}
@media (min-width:769px) {
- .c4 {
+ .c5 {
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
@@ -118,14 +129,19 @@ exports[` should default match snapshot 1`] = `
>
title
-
- description
-
+
+ description
+
+
@@ -133,6 +149,18 @@ exports[` should default match snapshot 1`] = `
`;
exports[` should match snapshot with aria-level 2 1`] = `
+.c3 {
+ margin-top: 16px;
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ gap: 24px;
+}
+
.c2 {
margin: 0;
padding: 0;
@@ -143,7 +171,7 @@ exports[` should match snapshot with aria-level 2 1`] = `
font-weight: 700;
}
-.c3 {
+.c4 {
margin: 0;
padding: 0;
font-size: 16px;
@@ -151,11 +179,10 @@ exports[` should match snapshot with aria-level 2 1`] = `
color: #231B22;
font-family: Rubik;
font-weight: 400;
- margin-top: 16px;
color: #6B6B78;
}
-.c4 {
+.c5 {
margin-top: 32px;
display: -webkit-box;
display: -webkit-flex;
@@ -189,7 +216,7 @@ exports[` should match snapshot with aria-level 2 1`] = `
}
@media (min-width:769px) {
- .c4 {
+ .c5 {
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
@@ -241,14 +268,19 @@ exports[` should match snapshot with aria-level 2 1`] = `
>
title
-
- description
-
+
+ description
+
+
@@ -256,11 +288,23 @@ exports[` should match snapshot with aria-level 2 1`] = `
`;
exports[` should match snapshot with list 1`] = `
-.c4 {
+.c3 {
+ margin-top: 16px;
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ gap: 24px;
+}
+
+.c5 {
margin-top: 24px;
}
-.c3 {
+.c4 {
margin: 0;
padding: 0;
font-size: 16px;
@@ -268,11 +312,10 @@ exports[` should match snapshot with list 1`] = `
color: #231B22;
font-family: Rubik;
font-weight: 400;
- margin-top: 16px;
color: #6B6B78;
}
-.c5 {
+.c6 {
margin: 0;
padding: 0;
font-size: 16px;
@@ -283,7 +326,7 @@ exports[` should match snapshot with list 1`] = `
font-size: 16px;
}
-.c6 {
+.c7 {
margin: 0;
padding: 0;
font-size: 16px;
@@ -306,7 +349,7 @@ exports[` should match snapshot with list 1`] = `
margin-bottom: 6px;
}
-.c7 {
+.c8 {
margin-top: 32px;
display: -webkit-box;
display: -webkit-flex;
@@ -348,7 +391,7 @@ exports[` should match snapshot with list 1`] = `
}
@media (min-width:769px) {
- .c7 {
+ .c8 {
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
@@ -401,31 +444,36 @@ exports[` should match snapshot with list 1`] = `
>
title
-
- description
-
+
+ description
+
+
1x/day standard access
4x/month 1-on-1 sessions
@@ -433,7 +481,7 @@ exports[` should match snapshot with list 1`] = `
@@ -441,6 +489,18 @@ exports[` should match snapshot with list 1`] = `
`;
exports[` should match snapshot with text display 1`] = `
+.c3 {
+ margin-top: 16px;
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ gap: 24px;
+}
+
.c2 {
margin: 0;
padding: 0;
@@ -451,7 +511,7 @@ exports[` should match snapshot with text display 1`] = `
font-weight: 700;
}
-.c3 {
+.c4 {
margin: 0;
padding: 0;
font-size: 16px;
@@ -459,11 +519,10 @@ exports[` should match snapshot with text display 1`] = `
color: #231B22;
font-family: Rubik;
font-weight: 400;
- margin-top: 16px;
color: #6B6B78;
}
-.c4 {
+.c5 {
margin-top: 32px;
display: -webkit-box;
display: -webkit-flex;
@@ -497,7 +556,7 @@ exports[` should match snapshot with text display 1`] = `
}
@media (min-width:769px) {
- .c4 {
+ .c5 {
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
@@ -549,14 +608,19 @@ exports[` should match snapshot with text display 1`] = `
>
title
-
- description
-
+
+ description
+
+
diff --git a/packages/yoga/src/Feedback/web/Feedback.jsx b/packages/yoga/src/Feedback/web/Feedback.jsx
index a2012ba1db..66b99e2472 100644
--- a/packages/yoga/src/Feedback/web/Feedback.jsx
+++ b/packages/yoga/src/Feedback/web/Feedback.jsx
@@ -14,6 +14,7 @@ import {
TextContainer,
Caption,
} from './StyledFeedback';
+import parseDescription from '../../utils/parseDescription';
const ICON_SIZE = 64;
const VARIANT_ICONS = {
@@ -43,9 +44,7 @@ function Feedback({
center = true,
...props
}) {
- const descriptionArray = Array.isArray(description)
- ? description
- : [description];
+ const descriptionArray = parseDescription(description);
const iconProps = VARIANT_ICONS[variant];
let primaryButton;
diff --git a/packages/yoga/src/utils/parseDescription.js b/packages/yoga/src/utils/parseDescription.js
new file mode 100644
index 0000000000..997ddf3404
--- /dev/null
+++ b/packages/yoga/src/utils/parseDescription.js
@@ -0,0 +1,10 @@
+export function parseDescription(input) {
+ return (Array.isArray(input) ? input : [input]).flatMap(item => {
+ if (item == null || typeof item !== 'string') return [];
+ const trimmed = item.trim();
+
+ return trimmed ? [trimmed] : [];
+ });
+}
+
+export default parseDescription;
diff --git a/packages/yoga/src/utils/parseDescription.test.jsx b/packages/yoga/src/utils/parseDescription.test.jsx
new file mode 100644
index 0000000000..c4896dd1fe
--- /dev/null
+++ b/packages/yoga/src/utils/parseDescription.test.jsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import parseDescription from './parseDescription';
+
+describe('parseDescription utility', () => {
+ it('should wrap single string and trim it', () => {
+ expect(parseDescription(' hello ')).toEqual(['hello']);
+ });
+
+ it('should filter empty, whitespace and null values', () => {
+ const input = [' ', '', null, 'valid', ' also valid '];
+
+ expect(parseDescription(input)).toEqual(['valid', 'also valid']);
+ });
+
+ it('should ignore non-string items (nodes, numbers, booleans)', () => {
+ const node = Node Content;
+ const input = [node, 42, true, ' keep ', ' ', false, null];
+ const result = parseDescription(input);
+
+ expect(result).toEqual(['keep']);
+ });
+});