diff --git a/web/app/components/plugins/marketplace/home/__tests__/home-trending-layout.browser.spec.tsx b/web/app/components/plugins/marketplace/home/__tests__/home-trending-layout.browser.spec.tsx index 80b1155be2a..824240fe62c 100644 --- a/web/app/components/plugins/marketplace/home/__tests__/home-trending-layout.browser.spec.tsx +++ b/web/app/components/plugins/marketplace/home/__tests__/home-trending-layout.browser.spec.tsx @@ -34,6 +34,20 @@ const adBanner: PluginBanner = { alt_text: 'Partner campaign', }, } +const eventBanner: PluginBanner = { + id: 'event', + style_type: 'event', + title: 'Launch event', + sort: 2, + language: 'en', + content: { + images: { + desktop: '/api/v1/banners/images/banners/event.png', + }, + link: 'https://dify.ai/event', + alt_text: 'Launch event', + }, +} const carouselBanners = [ createBlogBanner('first', 'First banner', 0), createBlogBanner('second', 'Second banner', 1), @@ -61,21 +75,29 @@ describe('Marketplace home trending layout', () => { expect(adSlide.getBoundingClientRect().height).toBe(blogSlide.getBoundingClientRect().height) }) - it('keeps the ad artwork left-aligned so responsive cropping stays on the right', async () => { + it('keeps event and ad artwork left-aligned so responsive cropping stays on the right', async () => { await page.viewport(600, 900) const screen = await render( -
+
+
, ) - const artwork = screen - .getByRole('link', { name: 'Partner campaign' }) - .element() - .querySelector('img') + const assertLeftCoverCrop = () => { + for (const name of ['Partner campaign', 'Launch event']) { + const artwork = screen.getByRole('link', { name }).element().querySelector('img') - expect(artwork).not.toBeNull() - expect(getComputedStyle(artwork!).objectPosition).toBe('0% 50%') + expect(artwork).not.toBeNull() + expect(getComputedStyle(artwork!).objectFit).toBe('cover') + expect(getComputedStyle(artwork!).objectPosition).toBe('0% 50%') + } + } + + assertLeftCoverCrop() + + await page.viewport(1000, 900) + assertLeftCoverCrop() }) it('keeps the blog artwork left corners rounded when its image is cropped', async () => { diff --git a/web/app/components/plugins/marketplace/home/home-trending-slides.tsx b/web/app/components/plugins/marketplace/home/home-trending-slides.tsx index 3eb13335aaa..550086c28b8 100644 --- a/web/app/components/plugins/marketplace/home/home-trending-slides.tsx +++ b/web/app/components/plugins/marketplace/home/home-trending-slides.tsx @@ -452,8 +452,7 @@ function ImageBannerSlide({ height={200} alt="" aria-hidden - className="size-full object-cover" - style={{ objectPosition: banner.style_type === 'ad' ? 'left center' : undefined }} + className="size-full object-cover object-left" /> diff --git a/web/app/components/plugins/marketplace/home/home-trending.module.css b/web/app/components/plugins/marketplace/home/home-trending.module.css index 38591bc3d47..dca60ffac5f 100644 --- a/web/app/components/plugins/marketplace/home/home-trending.module.css +++ b/web/app/components/plugins/marketplace/home/home-trending.module.css @@ -77,6 +77,12 @@ max-width: 400px; } +/* Crop from the right so left-side artwork stays visible when the frame + is narrower than the image (PC resize and mobile cover). */ +.imageSlide :is(picture, img) { + object-position: left; +} + .readMoreMobile { display: none; } @@ -241,7 +247,8 @@ gap: 4px; } - /* Event/ad mobile: match the fixed 197px artwork + 160px copy height. */ + /* Event/ad mobile: match the fixed 197px artwork + 160px copy height. + Cover + left so shrinking the frame crops the right, not the copy. */ :global([data-marketplace-standalone]) .imageSlide { height: 357px; } @@ -250,7 +257,7 @@ width: 100%; height: 100%; object-fit: cover; - object-position: center; + object-position: left; } :global([data-marketplace-standalone]) .readMoreDesktop {