Skip to content

Commit a869199

Browse files
Merge branch 'main' into cy/hide_gh_banner_not_associated
2 parents 642d734 + a2f8a95 commit a869199

File tree

8 files changed

+176
-29
lines changed

8 files changed

+176
-29
lines changed

src/pages/CodecovAIPage/CodecovAICommands/CodecovAICommands.tsx

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
import darkModeImage from 'assets/codecovAI/pr-review-example-dark-mode.png'
22
import lightModeImage from 'assets/codecovAI/pr-review-example-light-mode.png'
3-
import { Theme, useThemeContext } from 'shared/ThemeContext'
43
import { Card } from 'ui/Card'
54
import { ExpandableSection } from 'ui/ExpandableSection'
5+
import LightDarkImg from 'ui/LightDarkImg'
66

77
const CodecovAICommands: React.FC = () => {
8-
const { theme } = useThemeContext()
9-
const prReviewExampleSource =
10-
theme === Theme.DARK ? darkModeImage : lightModeImage
118
return (
129
<div>
1310
<Card>
@@ -34,10 +31,11 @@ const CodecovAICommands: React.FC = () => {
3431
</p>
3532
</ExpandableSection.Trigger>
3633
<ExpandableSection.Content className="m-0 p-0">
37-
<img
34+
<LightDarkImg
3835
className="size-full object-cover"
36+
src={lightModeImage}
37+
darkSrc={darkModeImage}
3938
alt="codecov pr review example"
40-
src={prReviewExampleSource}
4139
/>
4240
</ExpandableSection.Content>
4341
</ExpandableSection>

src/pages/RepoPage/CoverageOnboarding/GitHubActions/TokenStep.tsx

+12-7
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ import { useRepo } from 'services/repo'
1616
import { useUploadTokenRequired } from 'services/uploadTokenRequired'
1717
import { useIsCurrentUserAnAdmin } from 'services/user'
1818
import { Provider } from 'shared/api/helpers'
19-
import { Theme, useThemeContext } from 'shared/ThemeContext'
2019
import A from 'ui/A'
2120
import Button from 'ui/Button'
2221
import { Card } from 'ui/Card'
2322
import { CodeSnippet } from 'ui/CodeSnippet'
2423
import { ExpandableSection } from 'ui/ExpandableSection'
24+
import LightDarkImg from 'ui/LightDarkImg'
2525
import { RadioTileGroup } from 'ui/RadioTileGroup'
2626

2727
export const TOKEN_OPTIONS = {
@@ -53,11 +53,6 @@ function GitHubOrgSecretExample({
5353
uploadToken,
5454
owner,
5555
}: SecretGHExampleProps) {
56-
const { theme } = useThemeContext()
57-
const isDarkMode = theme === Theme.DARK
58-
const orgSecretImg = isDarkMode ? orgSecretDark : orgSecretLight
59-
const repoSecretImg = isDarkMode ? repoSecretDark : repoSecretLight
60-
6156
return (
6257
<>
6358
<p>
@@ -94,14 +89,24 @@ function GitHubOrgSecretExample({
9489
</p>
9590
</ExpandableSection.Trigger>
9691
<ExpandableSection.Content>
97-
<img
92+
{/* <img
9893
className="size-full object-cover"
9994
alt={
10095
isUsingGlobalToken
10196
? 'org settings secret example'
10297
: 'repo settings secret example'
10398
}
10499
src={isUsingGlobalToken ? orgSecretImg : repoSecretImg}
100+
/> */}
101+
<LightDarkImg
102+
alt={
103+
isUsingGlobalToken
104+
? 'org settings secret example'
105+
: 'repo settings secret example'
106+
}
107+
className="size-full object-cover"
108+
src={isUsingGlobalToken ? orgSecretLight : repoSecretLight}
109+
darkSrc={isUsingGlobalToken ? orgSecretDark : repoSecretDark}
105110
/>
106111
</ExpandableSection.Content>
107112
</ExpandableSection>

src/pages/RepoPage/FailedTestsTab/CodecovCLI/CodecovCLI.tsx

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import testsPRComment from 'assets/svg/onboardingTests/testsPRComment.svg'
22
import testsPRCommentDark from 'assets/svg/onboardingTests/testsPRCommentDark.svg'
33
import testsRunning from 'assets/svg/onboardingTests/testsRunning.svg'
4-
import { Theme, useThemeContext } from 'shared/ThemeContext'
54
import A from 'ui/A'
65
import { Card } from 'ui/Card'
76
import { CodeSnippet } from 'ui/CodeSnippet'
87
import { ExpandableSection } from 'ui/ExpandableSection/ExpandableSection'
8+
import LightDarkImg from 'ui/LightDarkImg'
99

1010
import { FrameworkTabsCard } from '../FrameworkTabsCard'
1111

@@ -110,11 +110,6 @@ function Step4() {
110110
}
111111

112112
function Step5() {
113-
const { theme } = useThemeContext()
114-
115-
const testPRsImageSource =
116-
theme === Theme.LIGHT ? testsPRComment : testsPRCommentDark
117-
118113
return (
119114
<div>
120115
<Card>
@@ -141,10 +136,11 @@ function Step5() {
141136
</p>
142137
</ExpandableSection.Trigger>
143138
<ExpandableSection.Content>
144-
<img
145-
src={testPRsImageSource.toString()}
139+
<LightDarkImg
140+
src={testsPRComment.toString()}
146141
alt="Tests in PR comment"
147142
className="w-full"
143+
darkSrc={testsPRCommentDark.toString()}
148144
/>
149145
</ExpandableSection.Content>
150146
</ExpandableSection>

src/pages/RepoPage/FailedTestsTab/GitHubActions/GitHubActions.tsx

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import testsPRComment from 'assets/svg/onboardingTests/testsPRComment.svg'
22
import testsPRCommentDark from 'assets/svg/onboardingTests/testsPRCommentDark.svg'
33
import testsRunning from 'assets/svg/onboardingTests/testsRunning.svg'
4-
import { Theme, useThemeContext } from 'shared/ThemeContext'
54
import A from 'ui/A'
65
import { Card } from 'ui/Card'
76
import { CodeSnippet } from 'ui/CodeSnippet'
87
import { ExpandableSection } from 'ui/ExpandableSection/ExpandableSection'
8+
import LightDarkImg from 'ui/LightDarkImg'
99

1010
import { FrameworkTabsCard } from '../FrameworkTabsCard'
1111

@@ -103,11 +103,6 @@ function Step2() {
103103
}
104104

105105
function Step3() {
106-
const { theme } = useThemeContext()
107-
108-
const testPRsImageSource =
109-
theme === Theme.LIGHT ? testsPRComment : testsPRCommentDark
110-
111106
return (
112107
<div>
113108
<Card>
@@ -134,10 +129,11 @@ function Step3() {
134129
</p>
135130
</ExpandableSection.Trigger>
136131
<ExpandableSection.Content>
137-
<img
138-
src={testPRsImageSource.toString()}
132+
<LightDarkImg
133+
src={testsPRComment.toString()}
139134
alt="Tests in PR comment"
140135
className="w-full"
136+
darkSrc={testsPRCommentDark.toString()}
141137
/>
142138
</ExpandableSection.Content>
143139
</ExpandableSection>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { type Meta, type StoryObj } from '@storybook/react'
2+
3+
import orgSecretDark from 'assets/onboarding/org_secret_dark.png'
4+
import orgSecretLight from 'assets/onboarding/org_secret_light.png'
5+
import {
6+
Theme,
7+
ThemeContextProvider,
8+
useThemeContext,
9+
} from 'shared/ThemeContext'
10+
11+
import LightDarkImg, { type LightDarkImgSrcProps } from './LightDarkImg'
12+
13+
const meta: Meta<typeof LightDarkImg> = {
14+
title: 'Components/LightDarkImg',
15+
component: LightDarkImg,
16+
}
17+
18+
export default meta
19+
20+
type Story = StoryObj<typeof LightDarkImg>
21+
22+
const LightDarkImgElements = (args: LightDarkImgSrcProps) => {
23+
const { theme, setTheme } = useThemeContext()
24+
return (
25+
<div>
26+
<button
27+
onClick={() =>
28+
setTheme(theme === Theme.LIGHT ? Theme.DARK : Theme.LIGHT)
29+
}
30+
style={{
31+
marginTop: '20px',
32+
padding: '10px 20px',
33+
backgroundColor: theme === 'light' ? '#000' : '#fff',
34+
color: theme === 'light' ? '#fff' : '#000',
35+
border: 'none',
36+
borderRadius: '4px',
37+
}}
38+
>
39+
Toggle Theme
40+
</button>
41+
<div>Current Theme: {theme}</div>
42+
<LightDarkImg {...args} />
43+
</div>
44+
)
45+
}
46+
47+
export const SimpleLightDarkImg: Story = {
48+
args: {
49+
alt: 'test text',
50+
src: orgSecretLight,
51+
darkSrc: orgSecretDark,
52+
},
53+
render: (args) => (
54+
<ThemeContextProvider>
55+
<LightDarkImgElements {...args} />
56+
</ThemeContextProvider>
57+
),
58+
}
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { render, screen } from '@testing-library/react'
2+
import React from 'react'
3+
import { describe, expect, it, vi } from 'vitest'
4+
5+
import { Theme, ThemeContext } from 'shared/ThemeContext/ThemeContext'
6+
7+
import LightDarkImg from './LightDarkImg'
8+
9+
const wrapper = (theme: Theme) => {
10+
return ({ children }: { children: React.ReactNode }) => {
11+
return (
12+
<ThemeContext.Provider value={{ theme, setTheme: vi.fn() }}>
13+
{children}
14+
</ThemeContext.Provider>
15+
)
16+
}
17+
}
18+
19+
describe('LightDarkImg', () => {
20+
const mockProps = {
21+
src: '/light-image.png',
22+
darkSrc: '/dark-image.png',
23+
alt: 'Test image',
24+
}
25+
26+
it('renders with light source in light mode', () => {
27+
render(<LightDarkImg {...mockProps} />, { wrapper: wrapper(Theme.LIGHT) })
28+
29+
const img = screen.getByAltText('Test image')
30+
expect(img).toBeInTheDocument()
31+
expect(img).toHaveAttribute('src', '/light-image.png')
32+
})
33+
34+
it('renders with dark source in dark mode', () => {
35+
render(<LightDarkImg {...mockProps} />, { wrapper: wrapper(Theme.DARK) })
36+
37+
const img = screen.getByAltText('Test image')
38+
expect(img).toBeInTheDocument()
39+
expect(img).toHaveAttribute('src', '/dark-image.png')
40+
})
41+
42+
it('falls back to light source when dark source is not provided', () => {
43+
const propsWithoutDark = {
44+
src: '/light-image.png',
45+
alt: 'Test image',
46+
}
47+
48+
render(<LightDarkImg {...propsWithoutDark} />, {
49+
wrapper: wrapper(Theme.DARK),
50+
})
51+
52+
const img = screen.getByAltText('Test image')
53+
expect(img).toBeInTheDocument()
54+
expect(img).toHaveAttribute('src', '/light-image.png')
55+
})
56+
57+
it('passes through additional props to img element', () => {
58+
render(
59+
<LightDarkImg {...mockProps} className="w-10" data-testid="test-img" />,
60+
{ wrapper: wrapper(Theme.LIGHT) }
61+
)
62+
63+
const img = screen.getByAltText('Test image')
64+
expect(img).toHaveClass('w-10')
65+
expect(img).toHaveAttribute('data-testid', 'test-img')
66+
})
67+
})

src/ui/LightDarkImg/LightDarkImg.tsx

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react'
2+
3+
import { Theme, useThemeContext } from 'shared/ThemeContext'
4+
5+
export interface LightDarkImgSrcProps {
6+
alt: string
7+
src: string
8+
darkSrc?: string
9+
}
10+
11+
type LightDarkImgProps = Omit<
12+
React.ImgHTMLAttributes<HTMLImageElement>,
13+
'alt' | 'src'
14+
> &
15+
LightDarkImgSrcProps
16+
17+
function LightDarkImg({ src, darkSrc, alt, ...props }: LightDarkImgProps) {
18+
const { theme } = useThemeContext()
19+
const isDarkMode = theme === Theme.DARK
20+
21+
return (
22+
<img {...props} alt={alt} src={isDarkMode && darkSrc ? darkSrc : src} />
23+
)
24+
}
25+
26+
export default LightDarkImg

src/ui/LightDarkImg/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './LightDarkImg'

0 commit comments

Comments
 (0)