Add styling to marketplace to identify sponsored products (#45684)
* Pass 'Sponsored' detail down to product cards from API * Style a "Sponsored" label * Stripe on top of sponsored products * Add 'blob' next to sponsored listings * Fix indentation bug * Add changefile(s) from automation for the following project(s): woocommerce * Update plugins/woocommerce-admin/client/marketplace/components/product-card/product-card.tsx Co-authored-by: Remi Corson <remicorson@gmail.com> * Update plugins/woocommerce-admin/client/marketplace/components/product-card/product-card.tsx Co-authored-by: Remi Corson <remicorson@gmail.com> * Update plugins/woocommerce-admin/client/marketplace/components/product-card/product-card.tsx Co-authored-by: Remi Corson <remicorson@gmail.com> * Apply suggestions from code review Co-authored-by: Remi Corson <remicorson@gmail.com> * Add missing close parenthesis following linter changes * Make linter happier about hex colors (still needs variablising) * Fix margins around vendor name * Fixed height of product stripe * Linting * Moved color to variable and calculated alpha using Sass functions * Update plugins/woocommerce-admin/client/marketplace/components/product-card/product-card.scss * Update plugins/woocommerce-admin/client/marketplace/stylesheets/_variables.scss --------- Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: Remi Corson <remicorson@gmail.com>
This commit is contained in:
parent
99853c19bf
commit
b0ea77326f
|
@ -165,11 +165,22 @@
|
|||
position: relative;
|
||||
}
|
||||
|
||||
&__vendor-details {
|
||||
display: flex;
|
||||
gap: $grid-unit-10;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
&__separator {
|
||||
color: $gray-300;
|
||||
font-size: 28px;
|
||||
line-height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&__vendor {
|
||||
display: flex;
|
||||
gap: $grid-unit-05;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
/* Allow vendor link to "punch through" the "whole card clickable" trick: */
|
||||
position: relative;
|
||||
}
|
||||
|
@ -181,6 +192,10 @@
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
&__sponsored-label {
|
||||
color: $gray-700;
|
||||
}
|
||||
|
||||
&__description {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
|
|
|
@ -24,6 +24,9 @@ export interface ProductCardProps {
|
|||
}
|
||||
|
||||
function ProductCard( props: ProductCardProps ): JSX.Element {
|
||||
const SPONSORED_PRODUCT_LABEL = 'promoted'; // what product.label indicates a sponsored placement
|
||||
const SPONSORED_PRODUCT_STRIPE_SIZE = '5px'; // unfortunately can't be defined in CSS - height of "stripe"
|
||||
|
||||
const { isLoading, type } = props;
|
||||
const query = useQuery();
|
||||
// Get the product if provided; if not provided, render a skeleton loader
|
||||
|
@ -33,6 +36,8 @@ function ProductCard( props: ProductCardProps ): JSX.Element {
|
|||
vendorName: '',
|
||||
vendorUrl: '',
|
||||
icon: '',
|
||||
label: null,
|
||||
primary_color: null,
|
||||
url: '',
|
||||
price: 0,
|
||||
image: '',
|
||||
|
@ -40,6 +45,24 @@ function ProductCard( props: ProductCardProps ): JSX.Element {
|
|||
reviewsCount: null,
|
||||
};
|
||||
|
||||
function isSponsored(): boolean {
|
||||
return SPONSORED_PRODUCT_LABEL === product.label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sponsored products with a primary_color set have that color applied as a dynamically-colored stripe at the top of the card.
|
||||
* In an ideal world this could be set in a data- attribute and we'd use CSS calc() and attr() to get it, but
|
||||
* attr() doesn't have very good support yet, so we need to apply some inline CSS to stripe sponsored results.
|
||||
*/
|
||||
function inlineCss(): object {
|
||||
if ( ! isSponsored() || ! product.primary_color ) {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
background: `linear-gradient(${ product.primary_color } 0, ${ product.primary_color } ${ SPONSORED_PRODUCT_STRIPE_SIZE }, white ${ SPONSORED_PRODUCT_STRIPE_SIZE }, white)`,
|
||||
};
|
||||
}
|
||||
|
||||
function recordTracksEvent( event: string, data: ExtraProperties ) {
|
||||
const tracksData = props.tracksData;
|
||||
|
||||
|
@ -104,11 +127,16 @@ function ProductCard( props: ProductCardProps ): JSX.Element {
|
|||
{
|
||||
'is-loading': isLoading,
|
||||
'is-small': props.small,
|
||||
'is-sponsored': isSponsored(),
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<Card className={ classNames } aria-hidden={ isLoading }>
|
||||
<Card
|
||||
className={ classNames }
|
||||
aria-hidden={ isLoading }
|
||||
style={ inlineCss() }
|
||||
>
|
||||
<div className="woocommerce-marketplace__product-card__content">
|
||||
{ isTheme && (
|
||||
<div className="woocommerce-marketplace__product-card__image">
|
||||
|
@ -158,12 +186,33 @@ function ProductCard( props: ProductCardProps ): JSX.Element {
|
|||
</a>
|
||||
</h2>
|
||||
{ isLoading && (
|
||||
<p className="woocommerce-marketplace__product-card__vendor" />
|
||||
<p className="woocommerce-marketplace__product-card__vendor-details">
|
||||
<span className="woocommerce-marketplace__product-card__vendor" />
|
||||
</p>
|
||||
) }
|
||||
{ ! isLoading && productVendor && (
|
||||
<p className="woocommerce-marketplace__product-card__vendor">
|
||||
<span>{ __( 'By ', 'woocommerce' ) }</span>
|
||||
{ productVendor }
|
||||
{ ! isLoading && (
|
||||
<p className="woocommerce-marketplace__product-card__vendor-details">
|
||||
{ productVendor && (
|
||||
<span className="woocommerce-marketplace__product-card__vendor">
|
||||
<span>
|
||||
{ __( 'By ', 'woocommerce' ) }
|
||||
</span>
|
||||
{ productVendor }
|
||||
</span>
|
||||
) }
|
||||
{ productVendor && isSponsored() && (
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className="woocommerce-marketplace__product-card__vendor-details__separator"
|
||||
>
|
||||
·
|
||||
</span>
|
||||
) }
|
||||
{ isSponsored() && (
|
||||
<span className="woocommerce-marketplace__product-card__sponsored-label">
|
||||
{ __( 'Sponsored', 'woocommerce' ) }
|
||||
</span>
|
||||
) }
|
||||
</p>
|
||||
) }
|
||||
</div>
|
||||
|
|
|
@ -73,6 +73,8 @@ export default function ProductListContent( props: {
|
|||
image: product.image,
|
||||
type: product.type,
|
||||
icon: product.icon,
|
||||
label: product.label,
|
||||
primary_color: product.primary_color,
|
||||
vendorName: product.vendorName,
|
||||
vendorUrl: product.vendorUrl
|
||||
? appendURLParams( product.vendorUrl, [
|
||||
|
|
|
@ -39,6 +39,7 @@ export interface Product {
|
|||
averageRating?: number | null;
|
||||
reviewsCount?: number | null;
|
||||
label?: string;
|
||||
primary_color?: string;
|
||||
group?: string;
|
||||
searchTerm?: string;
|
||||
category?: string;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: enhancement
|
||||
|
||||
Made sponsored product listings in the Extensions marketplace easier to identify.
|
Loading…
Reference in New Issue