diff --git a/.changeset/calm-scrolls-rest.md b/.changeset/calm-scrolls-rest.md new file mode 100644 index 0000000000..8ff12d4975 --- /dev/null +++ b/.changeset/calm-scrolls-rest.md @@ -0,0 +1,5 @@ +--- +'@primer/react-brand': patch +--- + +Fixed the global reset so smooth scrolling is disabled consistently when users prefer reduced motion. diff --git a/.changeset/fresh-images-flow.md b/.changeset/fresh-images-flow.md new file mode 100644 index 0000000000..cb6c91f951 --- /dev/null +++ b/.changeset/fresh-images-flow.md @@ -0,0 +1,9 @@ +--- +'@primer/react-brand': minor +--- + +Removed the global `block` layout applied to `img` and `picture` elements to prevent overriding of default inline behavior. + +To minimize regressions, `block` has been applied to image elements at a component level instead. + +⚠️ If you previously relied on the `display: block` styling from our `reset.css`, please apply it manually in your application code. diff --git a/packages/react/src/Avatar/Avatar.module.css b/packages/react/src/Avatar/Avatar.module.css index 2650cb1235..36545576e6 100644 --- a/packages/react/src/Avatar/Avatar.module.css +++ b/packages/react/src/Avatar/Avatar.module.css @@ -14,6 +14,7 @@ } .Avatar__image { + display: block; width: 100%; height: 100%; object-fit: cover; diff --git a/packages/react/src/Bento/Bento.visual.spec.ts-snapshots/Visual-Comparison-Bento-Bento-Mixed-2-1-darwin.png b/packages/react/src/Bento/Bento.visual.spec.ts-snapshots/Visual-Comparison-Bento-Bento-Mixed-2-1-darwin.png index 48cb092c39..da78ae2c53 100644 Binary files a/packages/react/src/Bento/Bento.visual.spec.ts-snapshots/Visual-Comparison-Bento-Bento-Mixed-2-1-darwin.png and b/packages/react/src/Bento/Bento.visual.spec.ts-snapshots/Visual-Comparison-Bento-Bento-Mixed-2-1-darwin.png differ diff --git a/packages/react/src/BreakoutBanner/BreakoutBanner.features.stories.tsx b/packages/react/src/BreakoutBanner/BreakoutBanner.features.stories.tsx index ae484bdfad..21511dfa6f 100644 --- a/packages/react/src/BreakoutBanner/BreakoutBanner.features.stories.tsx +++ b/packages/react/src/BreakoutBanner/BreakoutBanner.features.stories.tsx @@ -9,6 +9,7 @@ import lightNarrowBg from '../fixtures/images/light-vertical-banner.png' import lightWideBg from '../fixtures/images/light-horizontal-banner.png' import darkNarrowBg from '../fixtures/images/dark-vertical-banner.png' import darkWideBg from '../fixtures/images/dark-horizontal-banner.png' +import placeholderImage from '../fixtures/images/placeholder.png' import {LogoGithubIcon} from '@primer/octicons-react' import {ThemeProvider} from '../ThemeProvider' @@ -100,6 +101,21 @@ export const AlignedCenter = () => ( ) +export const LeadingMedia = () => ( + + Placeholder leading visual + + } + > + Where the most ambitious teams build great things + + Primary action + + +) + export const OptionalDescription = () => ( Where the most ambitious teams build great things diff --git a/packages/react/src/BreakoutBanner/BreakoutBanner.module.css b/packages/react/src/BreakoutBanner/BreakoutBanner.module.css index f2c88b7a57..15bee61037 100644 --- a/packages/react/src/BreakoutBanner/BreakoutBanner.module.css +++ b/packages/react/src/BreakoutBanner/BreakoutBanner.module.css @@ -62,6 +62,10 @@ margin-block-end: var(--base-size-48); } +.BreakoutBanner-leadingVisual :is(img, picture) { + display: block; +} + /* Regular */ @media screen and (min-width: 48rem) { .BreakoutBanner { diff --git a/packages/react/src/BreakoutBanner/BreakoutBanner.test.tsx b/packages/react/src/BreakoutBanner/BreakoutBanner.test.tsx index 94470ccb3c..04f58e2b06 100644 --- a/packages/react/src/BreakoutBanner/BreakoutBanner.test.tsx +++ b/packages/react/src/BreakoutBanner/BreakoutBanner.test.tsx @@ -102,18 +102,23 @@ describe('BreakoutBanner', () => { }) it('provides an escape hatch to render a custom leading visual', () => { - const MockLeadingVisual = () => + const MockLeadingVisual = () => ( + + Mock visual + + ) - const {getByTestId} = render( + const {getByRole} = render( }> This is your heading This is your description , ) - const elLeadingVisual = getByTestId('mock-svg') + const leadingVisual = getByRole('img', {name: 'Mock visual'}) - expect(elLeadingVisual).toBeInTheDocument() + expect(leadingVisual).toBeInTheDocument() + expect(leadingVisual.closest('div')).toHaveClass('BreakoutBanner-leadingVisual') }) it('provides a way to pass a background image', () => { diff --git a/packages/react/src/BreakoutBanner/BreakoutBanner.visual.spec.ts b/packages/react/src/BreakoutBanner/BreakoutBanner.visual.spec.ts index 18efe3f8a3..087254fdb1 100644 --- a/packages/react/src/BreakoutBanner/BreakoutBanner.visual.spec.ts +++ b/packages/react/src/BreakoutBanner/BreakoutBanner.visual.spec.ts @@ -71,6 +71,17 @@ test.describe('Visual Comparison: BreakoutBanner', () => { await expect(page).toHaveScreenshot({fullPage: true}) }) + test('BreakoutBanner / Leading Media', async ({page}) => { + await page.goto( + 'http://localhost:6006/iframe.html?args=&id=components-breakoutbanner-features--leading-media&viewMode=story', + {waitUntil: 'networkidle'}, + ) + await page.locator('body.sb-show-main').waitFor({state: 'visible'}) + + await page.waitForTimeout(500) + await expect(page).toHaveScreenshot({fullPage: true}) + }) + test('BreakoutBanner / Optional Description', async ({page}) => { await page.goto( 'http://localhost:6006/iframe.html?args=&id=components-breakoutbanner-features--optional-description&viewMode=story', diff --git a/packages/react/src/BreakoutBanner/BreakoutBanner.visual.spec.ts-snapshots/Visual-Comparison-BreakoutBanner-BreakoutBanner-Leading-Media-1-darwin.png b/packages/react/src/BreakoutBanner/BreakoutBanner.visual.spec.ts-snapshots/Visual-Comparison-BreakoutBanner-BreakoutBanner-Leading-Media-1-darwin.png new file mode 100644 index 0000000000..6d72d6ef17 Binary files /dev/null and b/packages/react/src/BreakoutBanner/BreakoutBanner.visual.spec.ts-snapshots/Visual-Comparison-BreakoutBanner-BreakoutBanner-Leading-Media-1-darwin.png differ diff --git a/packages/react/src/CTABanner/CTABanner.features.stories.tsx b/packages/react/src/CTABanner/CTABanner.features.stories.tsx index 95f8401f7b..1a64ec2f4a 100644 --- a/packages/react/src/CTABanner/CTABanner.features.stories.tsx +++ b/packages/react/src/CTABanner/CTABanner.features.stories.tsx @@ -271,6 +271,22 @@ export const WithLeadingComponent: Story = { ), } +export const WithMediaComponents: Story = { + render: () => ( + ( + + Placeholder leading visual + + )} + trailingComponent={() => Placeholder trailing visual} + > + Where the most ambitious teams build great things + Build, scale, and deliver secure software with GitHub. + + ), +} + export const WithOctovisualLeadingComponent: Story = { render: () => ( { }) it('provides an escape hatch to render a custom trailing component', () => { - const trailingText = 'Custom trailing' - const MockTrailingComponent = () =>
{trailingText}
+ const MockTrailingComponent = () => ( + + Custom trailing + + ) - const {getByText} = render( + const {getByRole} = render( This is your heading This is your description , ) - const elTrailing = getByText(trailingText) + const trailingImage = getByRole('img', {name: 'Custom trailing'}) - expect(elTrailing).toBeInTheDocument() + expect(trailingImage).toBeInTheDocument() + expect(trailingImage.closest('[class*="CTABanner-content"]')).toBeInTheDocument() }) it('provides a way to pass a background image', () => { @@ -433,19 +437,23 @@ describe('CTABanner', () => { }) it('provides an escape hatch to render a custom leading component', () => { - const leadingText = 'Custom leading' - const MockLeadingComponent = () =>
{leadingText}
+ const MockLeadingComponent = () => ( + + Custom leading + + ) - const {getByText} = render( + const {getByRole} = render( This is your heading This is your description , ) - const elLeading = getByText(leadingText) + const leadingImage = getByRole('img', {name: 'Custom leading'}) - expect(elLeading).toBeInTheDocument() + expect(leadingImage).toBeInTheDocument() + expect(leadingImage.closest('[class*="CTABanner-content"]')).toBeInTheDocument() }) it('renders leading component before heading and trailing component after children', () => { diff --git a/packages/react/src/CTABanner/CTABanner.visual.spec.ts b/packages/react/src/CTABanner/CTABanner.visual.spec.ts index 4ff4528bcf..39eb505785 100644 --- a/packages/react/src/CTABanner/CTABanner.visual.spec.ts +++ b/packages/react/src/CTABanner/CTABanner.visual.spec.ts @@ -126,6 +126,17 @@ test.describe('Visual Comparison: CTABanner', () => { await expect(page).toHaveScreenshot({fullPage: true}) }) + test('CTABanner / With Media Components', async ({page}) => { + await page.goto( + 'http://localhost:6006/iframe.html?args=&id=components-ctabanner-features--with-media-components&viewMode=story', + {waitUntil: 'networkidle'}, + ) + await page.locator('body.sb-show-main').waitFor({state: 'visible'}) + + await page.waitForTimeout(500) + await expect(page).toHaveScreenshot({fullPage: true}) + }) + test('CTABanner / With Octovisual Leading Component', async ({page}) => { await page.goto( 'http://localhost:6006/iframe.html?args=&id=components-ctabanner-features--with-octovisual-leading-component&viewMode=story', diff --git a/packages/react/src/CTABanner/CTABanner.visual.spec.ts-snapshots/Visual-Comparison-CTABanner-CTABanner-With-Media-Components-1-darwin.png b/packages/react/src/CTABanner/CTABanner.visual.spec.ts-snapshots/Visual-Comparison-CTABanner-CTABanner-With-Media-Components-1-darwin.png new file mode 100644 index 0000000000..66bc6b2e35 Binary files /dev/null and b/packages/react/src/CTABanner/CTABanner.visual.spec.ts-snapshots/Visual-Comparison-CTABanner-CTABanner-With-Media-Components-1-darwin.png differ diff --git a/packages/react/src/EyebrowBanner/EyebrowBanner.module.css b/packages/react/src/EyebrowBanner/EyebrowBanner.module.css index 6f040d6781..0c9e4a4bbe 100644 --- a/packages/react/src/EyebrowBanner/EyebrowBanner.module.css +++ b/packages/react/src/EyebrowBanner/EyebrowBanner.module.css @@ -41,6 +41,11 @@ max-height: var(--base-size-44); } +.EyebrowBanner__leadingVisual img, +.EyebrowBanner__leadingVisual picture { + display: block; +} + .EyebrowBanner__trailingVisual { display: flex; } diff --git a/packages/react/src/Hero/Hero.features.stories.tsx b/packages/react/src/Hero/Hero.features.stories.tsx index ff3bb830e6..ece70024d7 100644 --- a/packages/react/src/Hero/Hero.features.stories.tsx +++ b/packages/react/src/Hero/Hero.features.stories.tsx @@ -8,6 +8,7 @@ import {Button} from '../Button' import {ActionMenu} from '../ActionMenu' import {Grid} from '../Grid' import {EyebrowBanner} from '../EyebrowBanner' +import placeholderImage from '../fixtures/images/placeholder.png' const meta = { title: 'Components/Hero/Features', @@ -210,6 +211,21 @@ export const WithTrailingComponent: Story = { ), } +export const WithMediaTrailingComponent: Story = { + render: () => ( + ( + + Placeholder trailing visual + + )} + > + This is my super sweet hero heading + Build, scale, and deliver secure software with GitHub. + + ), +} + export const WithCustomClassnames: Story = { render: () => ( diff --git a/packages/react/src/Hero/Hero.module.css b/packages/react/src/Hero/Hero.module.css index d396be1bea..894d8ff198 100644 --- a/packages/react/src/Hero/Hero.module.css +++ b/packages/react/src/Hero/Hero.module.css @@ -315,6 +315,10 @@ margin-block-start: var(--base-size-32); } +.Hero-trailing :is(img, picture) { + display: block; +} + .Hero-eyebrow { margin-block-end: var(--base-size-32); } diff --git a/packages/react/src/Hero/Hero.test.tsx b/packages/react/src/Hero/Hero.test.tsx index 258a8751db..08716613e8 100644 --- a/packages/react/src/Hero/Hero.test.tsx +++ b/packages/react/src/Hero/Hero.test.tsx @@ -296,19 +296,23 @@ describe('Hero', () => { }) it('provides an escape hatch to render a custom trailing component', () => { - const trailingText = 'Custom trailing' - const MockTrailingComponent = () =>
{trailingText}
+ const MockTrailingComponent = () => ( + + Custom trailing + + ) - const {getByText} = render( + const {getByRole} = render( {mockHeading} {mockDescription} , ) - const elTrailing = getByText(trailingText) + const trailingImage = getByRole('img', {name: 'Custom trailing'}) - expect(elTrailing).toBeInTheDocument() + expect(trailingImage).toBeInTheDocument() + expect(trailingImage.closest('[class*="Hero-trailing"]')).toBeInTheDocument() }) it('no a11y violations', async () => { diff --git a/packages/react/src/Hero/Hero.visual.spec.ts b/packages/react/src/Hero/Hero.visual.spec.ts index 1b318a6c0c..00bf2e60c5 100644 --- a/packages/react/src/Hero/Hero.visual.spec.ts +++ b/packages/react/src/Hero/Hero.visual.spec.ts @@ -212,6 +212,17 @@ test.describe('Visual Comparison: Hero', () => { await expect(page).toHaveScreenshot({fullPage: true}) }) + test('Hero / With Media Trailing Component', async ({page}) => { + await page.goto( + 'http://localhost:6006/iframe.html?args=&id=components-hero-features--with-media-trailing-component&viewMode=story', + {waitUntil: 'networkidle'}, + ) + await page.locator('body.sb-show-main').waitFor({state: 'visible'}) + + await page.waitForTimeout(500) + await expect(page).toHaveScreenshot({fullPage: true}) + }) + test('Hero / With Custom Classnames', async ({page}) => { await page.goto( 'http://localhost:6006/iframe.html?args=&id=components-hero-features--with-custom-classnames&viewMode=story', diff --git a/packages/react/src/Hero/Hero.visual.spec.ts-snapshots/Visual-Comparison-Hero-Hero-With-Media-Trailing-Component-1-darwin.png b/packages/react/src/Hero/Hero.visual.spec.ts-snapshots/Visual-Comparison-Hero-Hero-With-Media-Trailing-Component-1-darwin.png new file mode 100644 index 0000000000..44c330283d Binary files /dev/null and b/packages/react/src/Hero/Hero.visual.spec.ts-snapshots/Visual-Comparison-Hero-Hero-With-Media-Trailing-Component-1-darwin.png differ diff --git a/packages/react/src/LogoSuite/LogoSuite.module.css b/packages/react/src/LogoSuite/LogoSuite.module.css index dcdaa21c92..3fa446d60b 100644 --- a/packages/react/src/LogoSuite/LogoSuite.module.css +++ b/packages/react/src/LogoSuite/LogoSuite.module.css @@ -69,6 +69,10 @@ height: var(--base-size-32); } +.LogoSuite__logobar img { + display: block; +} + .LogoSuite__logobar--variant-muted svg, .LogoSuite__logobar--variant-muted path { fill: var(--brand-LogoSuite-color-logo-muted); diff --git a/packages/react/src/MinimalFooter/MinimalFooter.module.css b/packages/react/src/MinimalFooter/MinimalFooter.module.css index b3c7b1a0ad..aeb28308a3 100644 --- a/packages/react/src/MinimalFooter/MinimalFooter.module.css +++ b/packages/react/src/MinimalFooter/MinimalFooter.module.css @@ -77,6 +77,7 @@ } .Footer__social-icon { + display: block; width: 24px; height: auto; } diff --git a/packages/react/src/PricingOptions/PricingOptions.module.css b/packages/react/src/PricingOptions/PricingOptions.module.css index 9822a64d94..6a0e6e1fcb 100644 --- a/packages/react/src/PricingOptions/PricingOptions.module.css +++ b/packages/react/src/PricingOptions/PricingOptions.module.css @@ -405,6 +405,10 @@ grid-row: leadingComponent; } +.PricingOptions__leading-component :is(img, picture) { + display: block; +} + .PricingOptions__label { color: var(--brand-color-text-default); font-family: var(--brand-fontStack-monospace); diff --git a/packages/react/src/PricingOptions/PricingOptions.test.tsx b/packages/react/src/PricingOptions/PricingOptions.test.tsx index 798e5dab10..d83145c1dc 100644 --- a/packages/react/src/PricingOptions/PricingOptions.test.tsx +++ b/packages/react/src/PricingOptions/PricingOptions.test.tsx @@ -622,6 +622,28 @@ describe('PricingOptions', () => { expect(getByTestId(PricingOptions.testIds.actionsMessage)).toBeInTheDocument() }) + it('renders media in the Item leadingComponent escape hatch', () => { + mockUseWindowSize.mockReturnValue(mediumBreakpoint) + + const {getByRole} = render( + + + Leading visual + + } + > + Pro + + , + ) + + const leadingImage = getByRole('img', {name: 'Leading visual'}) + + expect(leadingImage.closest('[class*="PricingOptions__leading-component"]')).toBeInTheDocument() + }) + it('renders PricingOptions.ActionsMessage leadingComponent without modifying its props', () => { mockUseWindowSize.mockReturnValue(mediumBreakpoint) diff --git a/packages/react/src/SectionIntro/SectionIntro.features.stories.tsx b/packages/react/src/SectionIntro/SectionIntro.features.stories.tsx index 1daa8a8f94..a85c7a59e0 100644 --- a/packages/react/src/SectionIntro/SectionIntro.features.stories.tsx +++ b/packages/react/src/SectionIntro/SectionIntro.features.stories.tsx @@ -2,6 +2,7 @@ import React from 'react' import type {Meta} from '@storybook/react' import {SectionIntro} from '.' import {CopilotIcon} from '@primer/octicons-react' +import placeholderImage from '../fixtures/images/placeholder.png' export default { title: 'Components/SectionIntro/Features', @@ -125,3 +126,18 @@ export const LeadingComponent = () => { ) } + +export const LeadingMedia = () => ( + ( + + Placeholder leading visual + + )} + align="center" + > + + Expressive headline about an exclusive set of features. + + +) diff --git a/packages/react/src/SectionIntro/SectionIntro.module.css b/packages/react/src/SectionIntro/SectionIntro.module.css index 40ac50a75c..2afe8c594b 100644 --- a/packages/react/src/SectionIntro/SectionIntro.module.css +++ b/packages/react/src/SectionIntro/SectionIntro.module.css @@ -6,6 +6,10 @@ padding-block: var(--base-size-24); } +.SectionIntro :is(img, picture) { + display: block; +} + .SectionIntro-heading--muted { color: var(--brand-color-text-muted); } diff --git a/packages/react/src/SectionIntro/SectionIntro.test.tsx b/packages/react/src/SectionIntro/SectionIntro.test.tsx index 88f154da02..c822a91753 100644 --- a/packages/react/src/SectionIntro/SectionIntro.test.tsx +++ b/packages/react/src/SectionIntro/SectionIntro.test.tsx @@ -234,7 +234,13 @@ describe('SectionIntro', () => { const mockImage = 'mockImage.png' const {getByRole, container} = render( - mock}> + ( + + mock + + )} + > {mockHeading} {mockDescription} {mockLinkText} @@ -246,6 +252,6 @@ describe('SectionIntro', () => { expect(imgEl).toHaveAttribute('src', mockImage) const sectionIntroEl = container.firstChild - expect(sectionIntroEl?.firstChild).toBe(imgEl) + expect(sectionIntroEl?.firstChild).toBe(imgEl.parentElement) }) }) diff --git a/packages/react/src/SectionIntro/SectionIntro.visual.spec.ts b/packages/react/src/SectionIntro/SectionIntro.visual.spec.ts index 5677fd6a85..4b2ba6b405 100644 --- a/packages/react/src/SectionIntro/SectionIntro.visual.spec.ts +++ b/packages/react/src/SectionIntro/SectionIntro.visual.spec.ts @@ -147,4 +147,15 @@ test.describe('Visual Comparison: SectionIntro', () => { await page.waitForTimeout(500) await expect(page).toHaveScreenshot({fullPage: true}) }) + + test('SectionIntro / Leading Media', async ({page}) => { + await page.goto( + 'http://localhost:6006/iframe.html?args=&id=components-sectionintro-features--leading-media&viewMode=story', + {waitUntil: 'networkidle'}, + ) + await page.locator('body.sb-show-main').waitFor({state: 'visible'}) + + await page.waitForTimeout(500) + await expect(page).toHaveScreenshot({fullPage: true}) + }) }) diff --git a/packages/react/src/SectionIntro/SectionIntro.visual.spec.ts-snapshots/Visual-Comparison-SectionIntro-SectionIntro-Leading-Media-1-darwin.png b/packages/react/src/SectionIntro/SectionIntro.visual.spec.ts-snapshots/Visual-Comparison-SectionIntro-SectionIntro-Leading-Media-1-darwin.png new file mode 100644 index 0000000000..c84b884805 Binary files /dev/null and b/packages/react/src/SectionIntro/SectionIntro.visual.spec.ts-snapshots/Visual-Comparison-SectionIntro-SectionIntro-Leading-Media-1-darwin.png differ diff --git a/packages/react/src/Stack/Stack.visual.spec.ts-snapshots/Visual-Comparison-Stack-Stack-Playground-1-darwin.png b/packages/react/src/Stack/Stack.visual.spec.ts-snapshots/Visual-Comparison-Stack-Stack-Playground-1-darwin.png index 207a4ea6f8..f9035a3a82 100644 Binary files a/packages/react/src/Stack/Stack.visual.spec.ts-snapshots/Visual-Comparison-Stack-Stack-Playground-1-darwin.png and b/packages/react/src/Stack/Stack.visual.spec.ts-snapshots/Visual-Comparison-Stack-Stack-Playground-1-darwin.png differ diff --git a/packages/react/src/Stack/Stack.visual.spec.ts-snapshots/Visual-Comparison-Stack-Stack-Responsive-1-darwin.png b/packages/react/src/Stack/Stack.visual.spec.ts-snapshots/Visual-Comparison-Stack-Stack-Responsive-1-darwin.png index 207a4ea6f8..f9035a3a82 100644 Binary files a/packages/react/src/Stack/Stack.visual.spec.ts-snapshots/Visual-Comparison-Stack-Stack-Responsive-1-darwin.png and b/packages/react/src/Stack/Stack.visual.spec.ts-snapshots/Visual-Comparison-Stack-Stack-Responsive-1-darwin.png differ diff --git a/packages/react/src/Stack/Stack.visual.spec.ts-snapshots/Visual-Comparison-Stack-Stack-Responsive-Base-Scale-1-darwin.png b/packages/react/src/Stack/Stack.visual.spec.ts-snapshots/Visual-Comparison-Stack-Stack-Responsive-Base-Scale-1-darwin.png index 12d12e2a0d..a625771ebd 100644 Binary files a/packages/react/src/Stack/Stack.visual.spec.ts-snapshots/Visual-Comparison-Stack-Stack-Responsive-Base-Scale-1-darwin.png and b/packages/react/src/Stack/Stack.visual.spec.ts-snapshots/Visual-Comparison-Stack-Stack-Responsive-Base-Scale-1-darwin.png differ diff --git a/packages/react/src/Statistic/Statistic.features.stories.tsx b/packages/react/src/Statistic/Statistic.features.stories.tsx index 82d12e9be6..0401bb6122 100644 --- a/packages/react/src/Statistic/Statistic.features.stories.tsx +++ b/packages/react/src/Statistic/Statistic.features.stories.tsx @@ -160,6 +160,23 @@ export const CustomIntro: Story = { ), } +export const MediaComponents: Story = { + render: () => ( + ( + + Placeholder leading visual + + )} + trailingComponent={() => Placeholder trailing visual} + > + 100M+ + Developers + + ), +} + export const Animations: Story = { render: () => ( diff --git a/packages/react/src/Statistic/Statistic.module.css b/packages/react/src/Statistic/Statistic.module.css index 71afd7209a..ff930d09e2 100644 --- a/packages/react/src/Statistic/Statistic.module.css +++ b/packages/react/src/Statistic/Statistic.module.css @@ -1,6 +1,10 @@ /** * Variants */ +.Statistic :is(img, picture) { + display: block; +} + .Statistic--variant-boxed { background-color: var(--brand-color-canvas-subtle); border-radius: var(--brand-borderRadius-large); diff --git a/packages/react/src/Statistic/Statistic.module.css.d.ts b/packages/react/src/Statistic/Statistic.module.css.d.ts index 1b479c2cb1..72455e8205 100644 --- a/packages/react/src/Statistic/Statistic.module.css.d.ts +++ b/packages/react/src/Statistic/Statistic.module.css.d.ts @@ -1,4 +1,5 @@ declare const styles: { + readonly "Statistic": string; readonly "Statistic--narrow-padding-condensed": string; readonly "Statistic--narrow-padding-none": string; readonly "Statistic--narrow-padding-normal": string; diff --git a/packages/react/src/Statistic/Statistic.test.tsx b/packages/react/src/Statistic/Statistic.test.tsx index f68b3a6844..3a78bd9e3f 100644 --- a/packages/react/src/Statistic/Statistic.test.tsx +++ b/packages/react/src/Statistic/Statistic.test.tsx @@ -106,18 +106,24 @@ describe('Statistic', () => { }) it('renders the Statistic with leading and trailing visuals', async () => { - const leadingComponent = () =>
Leading Visual
- const trailingComponent = () =>
Trailing Visual
+ const leadingComponent = () => ( + + Leading visual + + ) + const trailingComponent = () => Trailing visual - const {getByTestId} = render( + const {getByRole, getByTestId} = render( {mockHeading} {mockDescription} , ) - const leadingComponentElement = getByTestId('leadingComponent') - const trailingComponentElement = getByTestId('trailingComponent') + const statistic = getByTestId('Statistic') + const leadingComponentElement = getByRole('img', {name: 'Leading visual'}) + const trailingComponentElement = getByRole('img', {name: 'Trailing visual'}) + expect(statistic).toHaveClass('Statistic') expect(leadingComponentElement).toBeInTheDocument() expect(trailingComponentElement).toBeInTheDocument() }) diff --git a/packages/react/src/Statistic/Statistic.tsx b/packages/react/src/Statistic/Statistic.tsx index fcee8cbdd6..7cced6c5b6 100644 --- a/packages/react/src/Statistic/Statistic.tsx +++ b/packages/react/src/Statistic/Statistic.tsx @@ -150,7 +150,13 @@ const _Statistic = forwardRef> return (
{ await expect(page).toHaveScreenshot({fullPage: true}) }) + test('Statistic / Media Components', async ({page}) => { + await page.goto( + 'http://localhost:6006/iframe.html?args=&id=components-statistic-features--media-components&viewMode=story', + {waitUntil: 'networkidle'}, + ) + await page.locator('body.sb-show-main').waitFor({state: 'visible'}) + + await page.waitForTimeout(500) + await expect(page).toHaveScreenshot({fullPage: true}) + }) + test('Statistic / With Footnote', async ({page}) => { await page.goto( 'http://localhost:6006/iframe.html?args=&id=components-statistic-features--with-footnote&viewMode=story', diff --git a/packages/react/src/Statistic/Statistic.visual.spec.ts-snapshots/Visual-Comparison-Statistic-Statistic-Media-Components-1-darwin.png b/packages/react/src/Statistic/Statistic.visual.spec.ts-snapshots/Visual-Comparison-Statistic-Statistic-Media-Components-1-darwin.png new file mode 100644 index 0000000000..65c08ebbf3 Binary files /dev/null and b/packages/react/src/Statistic/Statistic.visual.spec.ts-snapshots/Visual-Comparison-Statistic-Statistic-Media-Components-1-darwin.png differ diff --git a/packages/react/src/Testimonial/Testimonial.module.css b/packages/react/src/Testimonial/Testimonial.module.css index 457ec76a8f..c1de1e820a 100644 --- a/packages/react/src/Testimonial/Testimonial.module.css +++ b/packages/react/src/Testimonial/Testimonial.module.css @@ -134,6 +134,10 @@ margin-top: var(--base-size-24); } +.Testimonial-logo-image { + display: block; +} + .Testimonial--size-large .Testimonial__media { margin-top: var(--base-size-64); } diff --git a/packages/react/src/Testimonial/Testimonial.module.css.d.ts b/packages/react/src/Testimonial/Testimonial.module.css.d.ts index 0713a7b573..27d4ec4fcc 100644 --- a/packages/react/src/Testimonial/Testimonial.module.css.d.ts +++ b/packages/react/src/Testimonial/Testimonial.module.css.d.ts @@ -9,6 +9,7 @@ declare const styles: { readonly "Testimonial-caption": string; readonly "Testimonial-from": string; readonly "Testimonial-link": string; + readonly "Testimonial-logo-image": string; readonly "Testimonial-quote": string; readonly "Testimonial__media": string; readonly "Testimonial__quoteMark": string; diff --git a/packages/react/src/Testimonial/Testimonial.test.tsx b/packages/react/src/Testimonial/Testimonial.test.tsx index 626111ec6e..371bc79b01 100644 --- a/packages/react/src/Testimonial/Testimonial.test.tsx +++ b/packages/react/src/Testimonial/Testimonial.test.tsx @@ -357,16 +357,17 @@ describe('Testimonial', () => { expect(avatarContainer).toHaveClass('Avatar--size-48') }) - it('renders logo with img element', () => { + it('renders logo with img element and preserves its class name', () => { const logoSrc = '/logo.png' const logoAlt = 'Company logo' + const logoClassName = 'custom-logo' const {getByRole} = render( Quote text Name - {logoAlt} + {logoAlt} , ) @@ -374,6 +375,7 @@ describe('Testimonial', () => { const logo = getByRole('img', {name: logoAlt}) expect(logo).toBeInTheDocument() expect(logo).toHaveAttribute('src', logoSrc) + expect(logo).toHaveClass('Testimonial-logo-image', logoClassName) }) it('renders logo container', () => { diff --git a/packages/react/src/Testimonial/Testimonial.tsx b/packages/react/src/Testimonial/Testimonial.tsx index ace3a96f24..a58798a1eb 100644 --- a/packages/react/src/Testimonial/Testimonial.tsx +++ b/packages/react/src/Testimonial/Testimonial.tsx @@ -192,7 +192,7 @@ function _Logo({children, ...rest}: LogoProps, ref) { if (child.type === 'img') { const imageChild = child as React.ReactElement> const imageProps: ComponentPropsWithRef<'img'> = { - className: clsx(styles['Testimonial-logo-image']), + className: clsx(styles['Testimonial-logo-image'], imageChild.props.className), ref: ref as ComponentPropsWithRef<'img'>['ref'], } diff --git a/packages/react/src/css/reset.css b/packages/react/src/css/reset.css index d729d61542..1de512b697 100644 --- a/packages/react/src/css/reset.css +++ b/packages/react/src/css/reset.css @@ -33,11 +33,19 @@ ol[role='list'] { list-style: none; } -/* Set core root defaults */ +/* Set core root scrolling behavior */ +html, html:focus-within { scroll-behavior: smooth; } +@media (prefers-reduced-motion: reduce) { + html, + html:focus-within { + scroll-behavior: auto; + } +} + /* Set core body defaults */ body { min-height: 100vh; @@ -53,7 +61,6 @@ a:not([class]) { img, picture { max-width: 100%; - display: block; } /* Inherit fonts for inputs and buttons */ @@ -63,14 +70,3 @@ textarea, select { font: inherit; } - -/* Remove all animations, transitions and smooth scroll for people that prefer not to see them */ -@media (prefers-reduced-motion: reduce) { - html:focus-within { - scroll-behavior: auto; - } -} - -html { - scroll-behavior: smooth; -} diff --git a/packages/react/src/river/River/River.features.stories.tsx b/packages/react/src/river/River/River.features.stories.tsx index 2eafb493b3..295faeeb1a 100644 --- a/packages/react/src/river/River/River.features.stories.tsx +++ b/packages/react/src/river/River/River.features.stories.tsx @@ -192,6 +192,30 @@ export const CustomTrailingContent: StoryFn = () => ( ) CustomTrailingContent.storyName = 'Custom trailing content' +export const CustomMediaContent: StoryFn = () => ( +
+ + + + + ( + + Placeholder leading visual + + )} + trailingComponent={() => ( + Placeholder trailing visual + )} + > + Heading + Test showing custom images in the slots + + +
+) +CustomMediaContent.storyName = 'Custom media content' + export const CustomTrailingContentWithDivider: StoryFn = () => (
diff --git a/packages/react/src/river/River/River.test.tsx b/packages/react/src/river/River/River.test.tsx index 79c74aa516..281fae2e07 100644 --- a/packages/react/src/river/River/River.test.tsx +++ b/packages/react/src/river/River/River.test.tsx @@ -243,11 +243,14 @@ describe('River', () => { }) it('provides an escape hatch to enter leading and trailing custom components', () => { - const [mockLeading, mockTrailing] = ['custom-leading', 'custom-trailing'] - const MockLeadingComponent = () =>
- const MockTrailingComponent = () =>
+ const MockLeadingComponent = () => ( + + Custom leading + + ) + const MockTrailingComponent = () => Custom trailing - const {getByTestId} = render( + const {getByRole} = render( @@ -258,11 +261,11 @@ describe('River', () => { , ) - const elLeading = getByTestId(mockLeading) - const elTrailing = getByTestId(mockTrailing) + const leadingImage = getByRole('img', {name: 'Custom leading'}) + const trailingImage = getByRole('img', {name: 'Custom trailing'}) - expect(elLeading).toBeInTheDocument() - expect(elTrailing).toBeInTheDocument() + expect(leadingImage.closest('[class*="River__leadingComponent"]')).toBeInTheDocument() + expect(trailingImage.closest('[class*="River__trailingComponent"]')).toBeInTheDocument() }) it('renders a h3 Heading by default', () => { diff --git a/packages/react/src/river/River/River.tsx b/packages/react/src/river/River/River.tsx index 5357a1a6f7..9370b65054 100644 --- a/packages/react/src/river/River/River.tsx +++ b/packages/react/src/river/River/River.tsx @@ -218,7 +218,7 @@ export const RiverContent = forwardRef( )} {!LabelChild && !EyebrowTextChild && LeadingComponent && ( -
+
)} diff --git a/packages/react/src/river/River/River.visual.spec.ts b/packages/react/src/river/River/River.visual.spec.ts index 64b912f7e4..8480079005 100644 --- a/packages/react/src/river/River/River.visual.spec.ts +++ b/packages/react/src/river/River/River.visual.spec.ts @@ -187,6 +187,17 @@ test.describe('Visual Comparison: River', () => { await expect(page).toHaveScreenshot({fullPage: true}) }) + test('River / Custom media content', async ({page}) => { + await page.goto( + 'http://localhost:6006/iframe.html?args=&id=components-river-features--custom-media-content&viewMode=story', + {waitUntil: 'networkidle'}, + ) + await page.locator('body.sb-show-main').waitFor({state: 'visible'}) + + await page.waitForTimeout(500) + await expect(page).toHaveScreenshot({fullPage: true}) + }) + test('River / Custom trailing content w/ divider', async ({page}) => { await page.goto( 'http://localhost:6006/iframe.html?args=&id=components-river-features--custom-trailing-content-with-divider&viewMode=story', diff --git a/packages/react/src/river/River/River.visual.spec.ts-snapshots/Visual-Comparison-River-River-Custom-media-content-1-darwin.png b/packages/react/src/river/River/River.visual.spec.ts-snapshots/Visual-Comparison-River-River-Custom-media-content-1-darwin.png new file mode 100644 index 0000000000..4e4181f9d6 Binary files /dev/null and b/packages/react/src/river/River/River.visual.spec.ts-snapshots/Visual-Comparison-River-River-Custom-media-content-1-darwin.png differ diff --git a/packages/react/src/river/River/River.visual.spec.ts-snapshots/Visual-Comparison-River-River-Larger-Placeholder-Image-1-darwin.png b/packages/react/src/river/River/River.visual.spec.ts-snapshots/Visual-Comparison-River-River-Larger-Placeholder-Image-1-darwin.png index e0a0e2ac09..bd18a4621f 100644 Binary files a/packages/react/src/river/River/River.visual.spec.ts-snapshots/Visual-Comparison-River-River-Larger-Placeholder-Image-1-darwin.png and b/packages/react/src/river/River/River.visual.spec.ts-snapshots/Visual-Comparison-River-River-Larger-Placeholder-Image-1-darwin.png differ diff --git a/packages/react/src/river/RiverStoryScroll/RiverStoryScroll.module.css b/packages/react/src/river/RiverStoryScroll/RiverStoryScroll.module.css index 7cfa1c9099..8dd6463834 100644 --- a/packages/react/src/river/RiverStoryScroll/RiverStoryScroll.module.css +++ b/packages/react/src/river/RiverStoryScroll/RiverStoryScroll.module.css @@ -42,6 +42,7 @@ } .RiverStoryScroll__image { + display: block; margin-left: auto; margin-right: auto; width: auto; diff --git a/packages/react/src/river/river-shared.module.css b/packages/react/src/river/river-shared.module.css index b80137b198..3bf6a20008 100644 --- a/packages/react/src/river/river-shared.module.css +++ b/packages/react/src/river/river-shared.module.css @@ -34,6 +34,10 @@ order: 2; } +.River__visual :is(img, picture) { + display: block; +} + .River__visual--fill-media img, .River__visual--fill-media picture, .River__visual--fill-media video { @@ -154,6 +158,11 @@ line-height: calc(1lh * 1.1); } +.River__leadingComponent :is(img, picture), +.River__trailingComponent :is(img, picture) { + display: block; +} + .River__trailingComponent { margin-block-start: var(--brand-River-spacing-inner); } diff --git a/packages/react/src/river/river-shared.module.css.d.ts b/packages/react/src/river/river-shared.module.css.d.ts index 503bbf5e50..b264856a42 100644 --- a/packages/react/src/river/river-shared.module.css.d.ts +++ b/packages/react/src/river/river-shared.module.css.d.ts @@ -17,6 +17,7 @@ declare const styles: { readonly "River__heading": string; readonly "River__heading-inner": string; readonly "River__label": string; + readonly "River__leadingComponent": string; readonly "River__text": string; readonly "River__trailingComponent": string; readonly "River__trailingComponent--divider": string;