Repository: Yoast/wordpress-seo
Pull request #22103: Finalizes widget tooltips
Author: login: leonidasmi
Labels: name: changelog: non-user-facing
description: Needs to be included in the 'Non-userfacing' category in the changelog
Created: 2025-03-13T08:54:37Z | Merged: 2025-03-18T11:51:26Z

## Context
<!--
What do we want to achieve with this PR? Why did we write this code?
-->

*

## Summary

<!--
Attach one of the following labels to the PR: `changelog: bugfix`, `changelog: enhancement`, `changelog: other`, `changelog: non-user-facing`.
If the changelog item is a bugfix, please use the following sentence structure: Fixes a bug where ... would ... (when ...).
If the changelog item is meant for the changelog of another add-on, start your changelog item with the name of that add-on's repo between square brackets, for example: * [wordpress-seo-premium] Fixes a bug where ....
If the changelog items is meant for the changelog of a javascript package, specify between square brackets in which package changelog the item should be included, for example: * [@yoast/components] Fixes a bug where ....
If the same changelog item is applicable to multiple changelogs/add-ons, add a separate changelog item for all of them.
-->
This PR can be summarized in the following changelog entry:

* Finalizes widget tooltips.

## Relevant technical choices:

*

## Test instructions
<!--
Please follow these guidelines when creating test instructions:
- Please provide step-by-step instructions how to reproduce the issue, if applicable.
- Write step-by-step test instructions aimed at non-tech-savvy users, even if the PR is not user-facing.
-->
### Test instructions for the acceptance test before the PR gets merged
This PR can be acceptance tested by following these steps:

* Check the tooltips of every widget and compare it with [the designs](https://www.figma.com/proto/DXKVj4tji7M65FYCYwBFUl/Dashboard?page-id=1599%3A2169&node-id=2666-3831&viewport=41%2C48%2C0.35&t=K8UNKfTjyFDiEznE-8&scaling=min-zoom&content-scaling=fixed&starting-point-node-id=2666%3A3831&hide-ui=1)

#### Relevant test scenarios
* [x] Changes should be tested with the browser console open
* [ ] Changes should be tested on different posts/pages/taxonomies/custom post types/custom taxonomies
* [ ] Changes should be tested on different editors (Default Block/Gutenberg/Classic/Elementor/other)
* [ ] Changes should be tested on different browsers
* [ ] Changes should be tested on multisite
<!--
If you have checked any of the above cases, please add some context about the reason, what to check in the console,
which type/editor/browser should be tested in particular, multisite with subfolders or subdomains, etc.
-->

### Test instructions for QA when the code is in the RC
<!--
Sometimes some steps from the test instructions for the acceptance test aren't relevant anymore once the code has been merged or the feature is complete. If that is the case, do not check the checkbox below.
QA is our Quality Assurance team. The RC is the release candidate zip that is tested before a release
-->

* [x] QA should use the same steps as above.

## Impact check
<!--
Sometimes PRs have a bigger impact than is suggested in the user-facing changes. In such cases,
additional (regression) testing might be necessary. To make it clear what parts might need additional testing, please outline which parts of the plugin have been impacted by this PR.
-->
This PR affects the following parts of the plugin, which may require extra testing:

*

## UI changes

* [ ] This PR changes the UI in the plugin. I have added the 'UI change' label to this PR.

## Other environments

* [ ] This PR also affects Shopify. I have added a changelog entry starting with `[shopify-seo]`, added test instructions for Shopify and attached the `Shopify` label to this PR.

## Documentation

* [ ] I have written documentation for this change. For example, comments in the Relevant technical choices, comments in the code, documentation on Confluence / shared Google Drive / [Yoast developer portal](https://developer.yoast.com/), or other.

## Quality assurance

* [x] I have tested this code to the best of my abilities.
* [ ] During testing, I had activated [all plugins that Yoast SEO provides integrations for](https://github.com/Yoast/wordpress-seo/blob/trunk/readme.txt#L106).
* [ ] I have added unit tests to verify the code works as intended.
* [ ] If any part of the code is behind a feature flag, my test instructions also cover cases where the feature flag is switched off.
* [x] I have written this PR in accordance with my team's definition of done.
* [x] I have checked that the base branch is correctly set.

## Innovation

* [ ] No innovation project is applicable for this PR.
* [ ] This PR falls under an innovation project. I have attached the `innovation` label.
* [ ] I have added my hours to [the WBSO document](http://yoa.st/wbso).

Fixes https://github.com/Yoast/reserved-tasks/issues/474



Diff:
diff --git a/packages/js/src/dashboard/components/info-tooltip.js b/packages/js/src/dashboard/components/info-tooltip.js
index 9002e69d177..2f2e6fa3e7c 100644
--- a/packages/js/src/dashboard/components/info-tooltip.js
+++ b/packages/js/src/dashboard/components/info-tooltip.js
@@ -9,11 +9,11 @@ import { InformationCircleIcon } from "@heroicons/react/outline";
  * @returns {JSX.Element} The element.
  */
 export const InfoTooltip = ( { children } ) => (
-	<TooltipContainer className="yst-h-fit yst-leading-[0]">
+	<TooltipContainer as="div" className="yst-h-fit yst-leading-[0]">
 		<TooltipTrigger>
 			<InformationCircleIcon className="yst-w-5 yst-h-5 yst-text-slate-400" />
 		</TooltipTrigger>
-		<TooltipWithContext variant="light" className="yst-max-w-80 yst-p-4" position="left">
+		<TooltipWithContext variant="light" className="yst-leading-normal yst-max-w-80 yst-p-4 yst-shadow-md" position="left">
 			{ children }
 		</TooltipWithContext>
 	</TooltipContainer>
diff --git a/packages/js/src/dashboard/widgets/organic-sessions-widget.js b/packages/js/src/dashboard/widgets/organic-sessions-widget.js
index 58475b7c600..818dfd4c153 100644
--- a/packages/js/src/dashboard/widgets/organic-sessions-widget.js
+++ b/packages/js/src/dashboard/widgets/organic-sessions-widget.js
@@ -25,8 +25,12 @@ export const OrganicSessionsWidget = ( { dataProvider, remoteDataProvider, dataF
 	const widgetProps = {
 		className: "yst-paper__content yst-col-span-4",
 		title: __( "Organic sessions", "wordpress-seo" ),
-		tooltip: __( "The number of organic sessions on your website.", "wordpress-seo" ),
-		tooltipLearnMoreLink: dataProvider.getLink( "organicSessionsInfoLearnMore" ),
+		tooltip: __( "The number of organic sessions that began on your website.", "wordpress-seo" ),
+		dataSources: [
+			{
+				source: "Site Kit by Google",
+			},
+		],
 	};
 
 	// Collapse the errors if they are the same.
diff --git a/packages/js/src/dashboard/widgets/search-ranking-compare/search-ranking-compare-metric.js b/packages/js/src/dashboard/widgets/search-ranking-compare/search-ranking-compare-metric.js
index aa0596f5296..f8dbbc9d5c9 100644
--- a/packages/js/src/dashboard/widgets/search-ranking-compare/search-ranking-compare-metric.js
+++ b/packages/js/src/dashboard/widgets/search-ranking-compare/search-ranking-compare-metric.js
@@ -1,19 +1,20 @@
 import { Trend } from "../../components/trend";
-import { WidgetTooltip } from "../widget";
+import { WidgetTooltip, WidgetDataSources } from "../widget";
 
 /**
  * Represents one of the organic sessions compare metrics.
  * @param {string} metricName The name of the metric.
  * @param {object} data The data of the metric.
- * @param {string} tooltipLocalizedString The content of the tooltip.
+ * @param {object[]} dataSources The sources of the data in the widget.
+ * @param {ReactNode} tooltipLocalizedContent The content of the tooltip.
  *
  * @returns {JSX.Element}
  */
-export const SearchRankingCompareMetric = ( { metricName, data, tooltipLocalizedString } ) => {
+export const SearchRankingCompareMetric = ( { metricName, data, dataSources, tooltipLocalizedContent } ) => {
 	return <div className="yst-flex yst-flex-col yst-relative yst-items-center yst-min-w-72">
 		<div className="yst-absolute yst-end-6 yst-top-2">
-			<WidgetTooltip>
-				<>{ tooltipLocalizedString }</>
+			<WidgetTooltip content={ tooltipLocalizedContent }>
+				<WidgetDataSources dataSources={ dataSources } />
 			</WidgetTooltip>
 		</div>
 		<div className="yst-text-center yst-text-2xl yst-font-bold yst-text-slate-900">
diff --git a/packages/js/src/dashboard/widgets/search-ranking-compare/search-ranking-compare-widget-content.js b/packages/js/src/dashboard/widgets/search-ranking-compare/search-ranking-compare-widget-content.js
index 87f757a74e9..6e88d403841 100644
--- a/packages/js/src/dashboard/widgets/search-ranking-compare/search-ranking-compare-widget-content.js
+++ b/packages/js/src/dashboard/widgets/search-ranking-compare/search-ranking-compare-widget-content.js
@@ -3,20 +3,21 @@ import { SearchRankingCompareMetric } from "./search-ranking-compare-metric";
 import { SearchRankingCompareMetricDivider } from "./search-ranking-compare-metric-divider";
 import { __ } from "@wordpress/i18n";
 import { NoDataParagraph } from "../../components/no-data-paragraph";
-import { WidgetTooltip } from "../widget";
+import { WidgetTooltip, WidgetDataSources } from "../widget";
 import { ErrorAlert } from "../../components/error-alert";
 
 /**
  * Represents the skeleton loader for an organic sessions compare metric component.
- * @param {string} tooltipLocalizedString The content of the tooltip.
+ * @param {ReactNode} tooltipLocalizedContent The content of the tooltip.
+ * @param {object[]} dataSources The sources of the data in the widget.
  *
  * @returns {JSX.Element}
  */
-const SearchRankingCompareMetricSkeletonLoader = ( { tooltipLocalizedString } ) => {
+const SearchRankingCompareMetricSkeletonLoader = ( { tooltipLocalizedContent, dataSources } ) => {
 	return <div className="yst-flex yst-flex-col yst-relative yst-items-center yst-w-72">
 		<div className="yst-absolute yst-end-6 yst-top-2">
-			<WidgetTooltip>
-				{ tooltipLocalizedString }
+			<WidgetTooltip content={ tooltipLocalizedContent }>
+				<WidgetDataSources dataSources={ dataSources } />
 			</WidgetTooltip>
 		</div>
 		<SkeletonLoader className="yst-text-center yst-text-2xl yst-font-bold yst-text-slate-900">12345</SkeletonLoader>
@@ -32,22 +33,26 @@ const SearchRankingCompareSkeletonLoader = () => {
 	return (
 		<div className="yst-flex yst-flex-col yst-justify-center yst-items-center @6xl:yst-flex-row @6xl:yst-justify-evenly rtl:yst-flex-row-reverse ">
 			<SearchRankingCompareMetricSkeletonLoader
-				tooltipLocalizedString={ __( "The number of times your website appeared in Google search results over the last 28 days.", "wordpress-seo" ) }
+				tooltipLocalizedContent={ __( "The number of times your website appeared in Google search results over the last 28 days.", "wordpress-seo" ) }
+				dataSources={ [ { source: __( "Site Kit by Google", "wordpress-seo" ) }  ] }
 			/>
 			<SearchRankingCompareMetricDivider />
 
 			<SearchRankingCompareMetricSkeletonLoader
-				tooltipLocalizedString={ __( "The total number of times users clicked on your website's link in Google search results over the last 28 days.", "wordpress-seo" ) }
+				tooltipLocalizedContent={ __( "The total number of times users clicked on your website's link in Google search results over the last 28 days.", "wordpress-seo" ) }
+				dataSources={ [ { source: __( "Site Kit by Google", "wordpress-seo" ) }  ] }
 			/>
 			<SearchRankingCompareMetricDivider />
 
 			<SearchRankingCompareMetricSkeletonLoader
-				tooltipLocalizedString={ __( "The average click-through-rate for your website over the last 28 days.", "wordpress-seo" ) }
+				tooltipLocalizedContent={ __( "The average click-through-rate for your website over the last 28 days.", "wordpress-seo" ) }
+				dataSources={ [ { source: __( "Site Kit by Google", "wordpress-seo" ) }  ] }
 			/>
 			<SearchRankingCompareMetricDivider />
 
 			<SearchRankingCompareMetricSkeletonLoader
-				tooltipLocalizedString={ __( "Average position is the average position of your site in search results over the last 28 days.", "wordpress-seo" ) }
+				tooltipLocalizedContent={ __( "Average position is the average position of your site in search results over the last 28 days.", "wordpress-seo" ) }
+				dataSources={ [ { source: __( "Site Kit by Google", "wordpress-seo" ) }  ] }
 			/>
 		</div>
 	);
@@ -80,28 +85,32 @@ export const SearchRankingCompareWidgetContent = ( { data, error, isPending, dat
 			<SearchRankingCompareMetric
 				metricName="Impressions"
 				data={ data.impressions }
-				tooltipLocalizedString={ __( "The number of times your website appeared in Google search results over the last 28 days.", "wordpress-seo" ) }
+				tooltipLocalizedContent={ __( "The number of times your website appeared in Google search results over the last 28 days.", "wordpress-seo" ) }
+				dataSources={ [ { source: __( "Site Kit by Google", "wordpress-seo" ) }  ] }
 			/>
 			<SearchRankingCompareMetricDivider />
 
 			<SearchRankingCompareMetric
 				metricName="Clicks"
 				data={ data.clicks }
-				tooltipLocalizedString={ __( "The total number of times users clicked on your website's link in Google search results over the last 28 days.", "wordpress-seo" ) }
+				tooltipLocalizedContent={ __( "The total number of times users clicked on your website's link in Google search results over the last 28 days.", "wordpress-seo" ) }
+				dataSources={ [ { source: __( "Site Kit by Google", "wordpress-seo" ) }  ] }
 			/>
 			<SearchRankingCompareMetricDivider />
 
 			<SearchRankingCompareMetric
 				metricName="CTR"
 				data={ data.ctr }
-				tooltipLocalizedString={ __( "The average click-through-rate for your website over the last 28 days.", "wordpress-seo" ) }
+				tooltipLocalizedContent={ __( "The average click-through-rate for your website over the last 28 days.", "wordpress-seo" ) }
+				dataSources={ [ { source: __( "Site Kit by Google", "wordpress-seo" ) }  ] }
 			/>
 			<SearchRankingCompareMetricDivider />
 
 			<SearchRankingCompareMetric
 				metricName="Position"
 				data={ data.position }
-				tooltipLocalizedString={ __( "Average position is the average position of your site in search results over the last 28 days.", "wordpress-seo" ) }
+				tooltipLocalizedContent={ __( "Average position is the average position of your site in search results over the last 28 days.", "wordpress-seo" ) }
+				dataSources={ [ { source: __( "Site Kit by Google", "wordpress-seo" ) }  ] }
 			/>
 		</div>;
 	}
diff --git a/packages/js/src/dashboard/widgets/top-pages-widget.js b/packages/js/src/dashboard/widgets/top-pages-widget.js
index 09aa6323c2d..6aed2e0d0cc 100644
--- a/packages/js/src/dashboard/widgets/top-pages-widget.js
+++ b/packages/js/src/dashboard/widgets/top-pages-widget.js
@@ -1,6 +1,6 @@
 import { PencilIcon } from "@heroicons/react/outline";
 import { useCallback, useMemo } from "@wordpress/element";
-import { __ } from "@wordpress/i18n";
+import { __, sprintf } from "@wordpress/i18n";
 import { Button, SkeletonLoader, TooltipContainer, TooltipTrigger, TooltipWithContext } from "@yoast/ui-library";
 import { ErrorAlert } from "../components/error-alert";
 import { NoDataParagraph } from "../components/no-data-paragraph";
@@ -207,8 +207,6 @@ export const TopPagesWidget = ( { dataProvider, remoteDataProvider, dataFormatte
 			options );
 	}, [ dataProvider, limit ] );
 
-	const infoLink = dataProvider.getLink( "topPagesInfoLearnMore" );
-
 	/**
 	 * @type {function(?TopPageData[]): TopPageData[]} Function to format the top pages data.
 	 */
@@ -216,14 +214,29 @@ export const TopPagesWidget = ( { dataProvider, remoteDataProvider, dataFormatte
 
 	const { data, error, isPending } = useRemoteData( getTopPages, formatTopPages );
 
+	const dataSources = [
+		{
+			source: "Site Kit by Google",
+			feature: __( "Clicks, Impressions, CTR, Position", "wordpress-seo" ),
+		},
+		{
+			source: "Yoast SEO",
+			feature: sprintf(
+				/* translators: 1: Yoast SEO. */
+				__( "%1$s score", "wordpress-seo" ),
+				"Yoast SEO"
+			),
+		},
+	];
+
 	return <Widget
 		className="yst-paper__content yst-col-span-4"
 		title={ __( "Top 5 most popular content", "wordpress-seo" ) }
 		tooltip={ __(
-			"The top 5 URLs on your website with the highest number of clicks.",
+			"The top 5 URLs on your website with the highest number of clicks over the last 28 days.",
 			"wordpress-seo"
 		) }
-		tooltipLearnMoreLink={ infoLink }
+		dataSources={ dataSources }
 	>
 		<TopPagesWidgetContent
 			data={ data }
diff --git a/packages/js/src/dashboard/widgets/top-queries-widget.js b/packages/js/src/dashboard/widgets/top-queries-widget.js
index a381347494c..5bb751c9ba9 100644
--- a/packages/js/src/dashboard/widgets/top-queries-widget.js
+++ b/packages/js/src/dashboard/widgets/top-queries-widget.js
@@ -124,7 +124,6 @@ export const TopQueriesWidget = ( { dataProvider, remoteDataProvider, dataFormat
 			options );
 	}, [ dataProvider, limit ] );
 
-	const infoLink = dataProvider.getLink( "topQueriesInfoLearnMore" );
 	const supportLink = dataProvider.getLink( "errorSupport" );
 
 	/**
@@ -134,14 +133,20 @@ export const TopQueriesWidget = ( { dataProvider, remoteDataProvider, dataFormat
 
 	const { data, error, isPending } = useRemoteData( getTopQueries, formatTopQueries );
 
+	const dataSources = [
+		{
+			source: "Site Kit by Google",
+		},
+	];
+
 	return <Widget
 		className="yst-paper__content yst-col-span-4"
 		title={ __( "Top 5 search queries", "wordpress-seo" ) }
 		tooltip={ __(
-			"The top 5 search queries on your website with the highest number of clicks.",
+			"The top 5 search queries on your website with the highest number of clicks over the last 28 days.",
 			"wordpress-seo"
 		) }
-		tooltipLearnMoreLink={ infoLink }
+		dataSources={ dataSources }
 	>
 		<TopQueriesWidgetContent
 			data={ data }
diff --git a/packages/js/src/dashboard/widgets/widget.js b/packages/js/src/dashboard/widgets/widget.js
index ccef1ea9fd7..3a977dd1c83 100644
--- a/packages/js/src/dashboard/widgets/widget.js
+++ b/packages/js/src/dashboard/widgets/widget.js
@@ -1,7 +1,7 @@
 import { Paper, Title } from "@yoast/ui-library";
 import classNames from "classnames";
 import { InfoTooltip } from "../components/info-tooltip";
-import { LearnMoreLink } from "../components/learn-more-link";
+import { __ } from "@wordpress/i18n";
 
 /**
  * @param {ReactNode} children The content of the title.
@@ -16,31 +16,57 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-xxs">
+		<div className="yst-mt-3 yst-font-semibold yst-text-slate-800">{ __( "Data provided by:", "wordpress-seo" ) }</div>
+		<ul>
+			{ dataSources.map( ( dataSource, index ) => (
+				<li className="yst-text-slate-500" key={ index }>
+					{ dataSource.feature
+						? <><span className="yst-font-medium">{ dataSource.source } - </span>{ dataSource.feature }</>
+						: dataSource.source
+					}
+				</li>
+			) ) }
+		</ul>
+	</div>
+);
+WidgetDataSources.displayName = "Widget.DataSources";
+
 /**
  * @param {string} [className] The class name.
  * @param {string} [title] The title in an H2.
- * @param {string} [tooltip] The description in a tooltip of an info button.
- * @param {string} [tooltipLearnMoreLink] The learn more link for the tooltip.
+ * @param {ReactNode} [tooltip] The widget description in a tooltip of an info button.
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
  * @param {ReactNode} children The content.
  * @returns {JSX.Element} The widget.
  */
-export const Widget = ( { className = "yst-paper__content", title, tooltip, tooltipLearnMoreLink, children } ) => (
+// eslint-disable-next-line complexity
+export const Widget = ( { className = "yst-paper__content", title, tooltip, dataSources, children } ) => (
 	<Paper className={ classNames( "yst-shadow-md", className ) }>
 		{ ( title || tooltip ) && <div className="yst-flex yst-justify-between">
 			{ title && <WidgetTitle>{ title }</WidgetTitle> }
-			{ tooltip && <WidgetTooltip learnMoreLink={ tooltipLearnMoreLink }>{ tooltip }</WidgetTooltip> }
+			{ tooltip &&
+				<WidgetTooltip content={ tooltip }>
+					{ dataSources && dataSources.length > 0 && <WidgetDataSources dataSources={ dataSources } /> }
+				</WidgetTooltip>
+			}
 		</div> }
 		{ children }
 	</Paper>
diff --git a/packages/js/tests/dashboard/widgets/organic-sessions-widget.test.js b/packages/js/tests/dashboard/widgets/organic-sessions-widget.test.js
index 7f96fc87fee..26d6974763c 100644
--- a/packages/js/tests/dashboard/widgets/organic-sessions-widget.test.js
+++ b/packages/js/tests/dashboard/widgets/organic-sessions-widget.test.js
@@ -42,15 +42,11 @@ describe( "OrganicSessionsWidget", () => {
 		} );
 
 		const tooltip = getByRole( "tooltip" );
-		const tooltipMessage = getByText( "The number of organic sessions on your website." );
+		const tooltipMessage = getByText( "The number of organic sessions that began on your website." );
+		const tooltipDataSource = getByText( "Site Kit by Google" );
 		expect( tooltip ).toBeInTheDocument();
 		expect( tooltipMessage ).toBeInTheDocument();
-
-		const link = getByText( "Learn more" );
-		expect( link ).toBeInTheDocument();
-		expect( link ).toHaveAttribute( "href", "https://example.com/organic-sessions-learn-more" );
-		expect( link ).toHaveAttribute( "rel", "noopener" );
-		expect( link ).toHaveAttribute( "target", "_blank" );
+		expect( tooltipDataSource ).toBeInTheDocument();
 	} );
 
 	it( "should render without data", async() => {


Reviews:
user: login: igorschoester
body: CR 🏗️ 

Looks nice! Couple comments 😅 
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T09:40:57Z
user: login: leonidasmi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T10:07:03Z
user: login: leonidasmi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T10:09:46Z
user: login: leonidasmi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T10:12:44Z
user: login: leonidasmi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T10:16:19Z
user: login: leonidasmi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T10:21:04Z
user: login: leonidasmi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T10:24:28Z
user: login: leonidasmi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T10:28:34Z
user: login: leonidasmi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T10:48:33Z
user: login: igorschoester
body: CR && AT ✅ 
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T11:46:28Z

Review comments:
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
+		<span className="yst-block yst-mt-3 yst-font-semibold yst-text-slate-800">{ __( "Data provided by:", "wordpress-seo" ) }</span>
path: packages/js/src/dashboard/widgets/widget.js
user: login: igorschoester
body: Why a span, only to turn it into a block for the margin top?
created_at: 2025-03-18T08:31:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
+		<span className="yst-block yst-mt-3 yst-font-semibold yst-text-slate-800">{ __( "Data provided by:", "wordpress-seo" ) }</span>
+		<ul>
+			{ dataSources.map( ( dataSource, index ) => (
+				<li className="yst-text-slate-500" key={ index }>
+					{ dataSource.feature && (
+						<div>
path: packages/js/src/dashboard/widgets/widget.js
user: login: igorschoester
body: I think this and below `div`' are not needed.
If you need a parent for the React tree, you can use a Fragment (shorthand: `<>`). This will not output anything in the DOM tree.
created_at: 2025-03-18T08:33:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
+		<span className="yst-block yst-mt-3 yst-font-semibold yst-text-slate-800">{ __( "Data provided by:", "wordpress-seo" ) }</span>
+		<ul>
+			{ dataSources.map( ( dataSource, index ) => (
+				<li className="yst-text-slate-500" key={ index }>
+					{ dataSource.feature && (
+						<div>
+							<strong className="yst-font-medium">{ dataSource.source } - </strong> { dataSource.feature }
path: packages/js/src/dashboard/widgets/widget.js
user: login: igorschoester
body: Is this actually of strong importance? Or more for the styling?
If the latter, than you should probably use a `span` or `b` element instead.

Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong#usage_notes
created_at: 2025-03-18T08:40:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
+		<span className="yst-block yst-mt-3 yst-font-semibold yst-text-slate-800">{ __( "Data provided by:", "wordpress-seo" ) }</span>
+		<ul>
+			{ dataSources.map( ( dataSource, index ) => (
+				<li className="yst-text-slate-500" key={ index }>
+					{ dataSource.feature && (
+						<div>
+							<strong className="yst-font-medium">{ dataSource.source } - </strong> { dataSource.feature }
path: packages/js/src/dashboard/widgets/widget.js
user: login: igorschoester
body: The double space is confusing, as they seem to be collapsed in the DOM.
* after `-`
* after closing strong tag, before feature

You can remove either and the result is the same.
created_at: 2025-03-18T08:46:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
+		<span className="yst-block yst-mt-3 yst-font-semibold yst-text-slate-800">{ __( "Data provided by:", "wordpress-seo" ) }</span>
+		<ul>
+			{ dataSources.map( ( dataSource, index ) => (
+				<li className="yst-text-slate-500" key={ index }>
+					{ dataSource.feature && (
+						<div>
+							<strong className="yst-font-medium">{ dataSource.source } - </strong> { dataSource.feature }
+						</div>
+					) }
+					{ ! dataSource.feature && (
+						<div>
+							{ dataSource.source }
+						</div>
+					) }
+
path: packages/js/src/dashboard/widgets/widget.js
user: login: igorschoester
body: I would opt for a ternary here for readability. Here is that, plus my other remarks:

```suggestion
					{ dataSource.feature
						? <><b className="yst-font-medium">{ dataSource.source } - </b>{ dataSource.feature }</>
						: dataSource.source
					}
```
created_at: 2025-03-18T08:47:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
path: packages/js/src/dashboard/widgets/widget.js
user: login: igorschoester
body: Let's not do font size in pixels. Preferably not a specific size either, as that seems to take away a benefit of using Tailwind: utility for re-use.
We have [their selection to pick from](https://v3.tailwindcss.com/docs/font-size). However, I just found out again we have changed that [in our configuration](https://github.com/Yoast/wordpress-seo/blob/trunk/packages/tailwindcss-preset/index.js#L6), we actually have a `xxs` variant that will work out to 10.8px in this case.

```suggestion
	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-xxs">
```
created_at: 2025-03-18T08:52:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,19 +1,20 @@
 import { Trend } from "../../components/trend";
-import { WidgetTooltip } from "../widget";
+import { WidgetTooltip, WidgetDataSources } from "../widget";
 
 /**
  * Represents one of the organic sessions compare metrics.
  * @param {string} metricName The name of the metric.
  * @param {object} data The data of the metric.
- * @param {string} tooltipLocalizedString The content of the tooltip.
+ * @param {object[]} dataSources The sources of the data in the widget.
+ * @param {ReactNode} tooltipLocalizedString The content of the tooltip.
path: packages/js/src/dashboard/widgets/search-ranking-compare/search-ranking-compare-metric.js
user: login: igorschoester
body: Making the name a bit silly 😁 
created_at: 2025-03-18T08:59:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
path: packages/js/src/dashboard/widgets/widget.js
user: login: igorschoester
body: This `leading` requirement here makes me think.
I messed up with the `leading-[0]` in the InfoTooltip, we should reset it on the `TooltipWithContext` wrapper instead.
The reason you don't see it for the paragraph is due to WP styling.
I suggest removing the `yst-leading-4` here, in favor of adding it there.
created_at: 2025-03-18T09:38:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,11 +9,11 @@ import { InformationCircleIcon } from "@heroicons/react/outline";
  * @returns {JSX.Element} The element.
  */
 export const InfoTooltip = ( { children } ) => (
-	<TooltipContainer className="yst-h-fit yst-leading-[0]">
+	<TooltipContainer as="div" className="yst-h-fit yst-leading-[0]">
 		<TooltipTrigger>
 			<InformationCircleIcon className="yst-w-5 yst-h-5 yst-text-slate-400" />
 		</TooltipTrigger>
-		<TooltipWithContext variant="light" className="yst-max-w-80 yst-p-4" position="left">
+		<TooltipWithContext variant="light" className="yst-max-w-80 yst-p-4 yst-shadow-md" position="left">
path: packages/js/src/dashboard/components/info-tooltip.js
user: login: igorschoester
body: See my comment on `yst-leading-4` in the `WidgetDataSources`. I think it should be `normal` though?

```suggestion
		<TooltipWithContext variant="light" className="yst-leading-normal yst-max-w-80 yst-p-4 yst-shadow-md" position="left">
```
created_at: 2025-03-18T09:39:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
+		<span className="yst-block yst-mt-3 yst-font-semibold yst-text-slate-800">{ __( "Data provided by:", "wordpress-seo" ) }</span>
path: packages/js/src/dashboard/widgets/widget.js
user: login: leonidasmi
body: [Fixed](https://github.com/Yoast/wordpress-seo/pull/22103/commits/5c75c4c68d15dbb762bf53d06b0c848c10ff7cec).
created_at: 2025-03-18T10:07:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
+		<span className="yst-block yst-mt-3 yst-font-semibold yst-text-slate-800">{ __( "Data provided by:", "wordpress-seo" ) }</span>
+		<ul>
+			{ dataSources.map( ( dataSource, index ) => (
+				<li className="yst-text-slate-500" key={ index }>
+					{ dataSource.feature && (
+						<div>
+							<strong className="yst-font-medium">{ dataSource.source } - </strong> { dataSource.feature }
path: packages/js/src/dashboard/widgets/widget.js
user: login: leonidasmi
body: [Fixed](https://github.com/Yoast/wordpress-seo/pull/22103/commits/d0c31a620dd7e57e09e1f5bd4c8efab15e025e7a)
created_at: 2025-03-18T10:09:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
+		<span className="yst-block yst-mt-3 yst-font-semibold yst-text-slate-800">{ __( "Data provided by:", "wordpress-seo" ) }</span>
+		<ul>
+			{ dataSources.map( ( dataSource, index ) => (
+				<li className="yst-text-slate-500" key={ index }>
+					{ dataSource.feature && (
+						<div>
path: packages/js/src/dashboard/widgets/widget.js
user: login: leonidasmi
body: [Fixed](https://github.com/Yoast/wordpress-seo/pull/22103/commits/6e36cef48b7e383252a33df26c452c0053150722)
created_at: 2025-03-18T10:12:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
+		<span className="yst-block yst-mt-3 yst-font-semibold yst-text-slate-800">{ __( "Data provided by:", "wordpress-seo" ) }</span>
+		<ul>
+			{ dataSources.map( ( dataSource, index ) => (
+				<li className="yst-text-slate-500" key={ index }>
+					{ dataSource.feature && (
+						<div>
+							<strong className="yst-font-medium">{ dataSource.source } - </strong> { dataSource.feature }
path: packages/js/src/dashboard/widgets/widget.js
user: login: leonidasmi
body: Good point, [fixed](https://github.com/Yoast/wordpress-seo/pull/22103/commits/2980a9a94fdc21b8ba2477cb8a90c972ea8f1ef7).
created_at: 2025-03-18T10:16:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
+		<span className="yst-block yst-mt-3 yst-font-semibold yst-text-slate-800">{ __( "Data provided by:", "wordpress-seo" ) }</span>
+		<ul>
+			{ dataSources.map( ( dataSource, index ) => (
+				<li className="yst-text-slate-500" key={ index }>
+					{ dataSource.feature && (
+						<div>
+							<strong className="yst-font-medium">{ dataSource.source } - </strong> { dataSource.feature }
+						</div>
+					) }
+					{ ! dataSource.feature && (
+						<div>
+							{ dataSource.source }
+						</div>
+					) }
+
path: packages/js/src/dashboard/widgets/widget.js
user: login: leonidasmi
body: [Fixed](https://github.com/Yoast/wordpress-seo/pull/22103/commits/6992f87a5ce51d7e84965edbbaa4ba0a2ece86bd).
created_at: 2025-03-18T10:21:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
path: packages/js/src/dashboard/widgets/widget.js
user: login: leonidasmi
body: 10.8 is practically 11px, so yeah, [fixed](https://github.com/Yoast/wordpress-seo/pull/22103/commits/66a4257987bfaf05157509ed68d39cb17d2c309e). 
created_at: 2025-03-18T10:24:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,19 +1,20 @@
 import { Trend } from "../../components/trend";
-import { WidgetTooltip } from "../widget";
+import { WidgetTooltip, WidgetDataSources } from "../widget";
 
 /**
  * Represents one of the organic sessions compare metrics.
  * @param {string} metricName The name of the metric.
  * @param {object} data The data of the metric.
- * @param {string} tooltipLocalizedString The content of the tooltip.
+ * @param {object[]} dataSources The sources of the data in the widget.
+ * @param {ReactNode} tooltipLocalizedString The content of the tooltip.
path: packages/js/src/dashboard/widgets/search-ranking-compare/search-ranking-compare-metric.js
user: login: leonidasmi
body: [Fixed](https://github.com/Yoast/wordpress-seo/pull/22103/commits/74f0b7805194019f816fda601e461d4d27e183dc), hope you like that better.
created_at: 2025-03-18T10:28:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,31 +16,64 @@ export const WidgetTitle = ( { children, ...props } ) => (
 WidgetTitle.displayName = "Widget.Title";
 
 /**
- * @param {ReactNode} children The content of the paragraph.
- * @param {string} [learnMoreLink] The URL to the learn more page.
- * @returns {JSX.Element} The widget tooltip with paragraph and optional learn more link.
+ * @param {ReactNode} content The content of the tooltip.
+ * @param {ReactNode} children The rest of the tooltip.
+ * @returns {JSX.Element} The widget tooltip.
  */
-export const WidgetTooltip = ( { children, learnMoreLink } ) => (
+export const WidgetTooltip = ( { content, children } ) => (
 	<InfoTooltip>
-		<p className="yst-mb-2">{ children }</p>
-		{ learnMoreLink && <LearnMoreLink href={ learnMoreLink } /> }
+		<p className="yst-mb-2 yst-text-slate-600">{ content }</p>
+		{ children }
 	</InfoTooltip>
 );
 WidgetTooltip.displayName = "Widget.Tooltip";
 
+/**
+ * @param {Object[]} [dataSources] The sources of the data in the widget.
+ * @returns {JSX.Element} The sources of the data in the widget as a component.
+ */
+export const WidgetDataSources = ( { dataSources } ) => (
+	<div className="yst-leading-4 yst-border-t yst-mt-3 yst-border-slate-200 yst-italic yst-text-[11px]">
path: packages/js/src/dashboard/widgets/widget.js
user: login: leonidasmi
body: [Fixed](https://github.com/Yoast/wordpress-seo/pull/22103/commits/1ba93349d4bac595d8231fb663fa62388c770078).
created_at: 2025-03-18T10:48:33Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-13T15:44:09Z
body: A merge conflict has been detected for the proposed code changes in this PR. Please resolve the conflict by either rebasing the PR or merging in changes from the base branch.
author_association: NONE
user: login: coveralls
created_at: 2025-03-17T12:59:45Z
body: ## Pull Request Test Coverage Report for [Build 037c9cb9e819983364751411366be534c76067bb](https://coveralls.io/builds/72783832)

### Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

- For more information on this, see <a target="_blank" href="https://docs.coveralls.io/build-types#tracking-coverage-changes-with-pull_request-builds">Tracking coverage changes with pull request builds</a>.
- To avoid this issue with future PRs, see these <a target="_blank" href="https://docs.coveralls.io/build-types#recommended-ci-configurations">Recommended CI Configurations</a>.
- For a quick fix, <a target="_blank" href="https://github.blog/changelog/2022-02-03-more-ways-to-keep-your-pull-request-branch-up-to-date/#update-your-pull-request-branch-by-rebasing">rebase this PR at GitHub</a>. Your next report should be accurate.

### Details

* **11** of **11**   **(100.0%)**  changed or added relevant lines in **6** files are covered.
* **2** unchanged lines in **1** file lost coverage.
* Overall coverage increased (+**0.002%**) to **53.561%**

---


|  Files with Coverage Reduction | New Missed Lines | % |
| :-----|--------------|--: |
| [packages/js/src/dashboard/components/learn-more-link.js](https://coveralls.io/builds/72783832/source?filename=packages%2Fjs%2Fsrc%2Fdashboard%2Fcomponents%2Flearn-more-link.js#L13) | 2 | 0.0% |
<!-- | **Total:** | **2** |  | -->

|  Totals | [![Coverage Status](https://coveralls.io/builds/72783832/badge)](https://coveralls.io/builds/72783832) |
| :-- | --: |
| Change from base [Build 31bce8f100613e3041a227ad5701a87b85ba63b8](https://coveralls.io/builds/72759173): |  0.002% |
| Covered Lines: | 30664 |
| Relevant Lines: | 58066 |

---
##### 💛  - [Coveralls](https://coveralls.io)

author_association: NONE