Skip to content

Commit eb09ae5

Browse files
feat: Add img component for light and dark src
1 parent 02d5b6b commit eb09ae5

File tree

6 files changed

+117
-29
lines changed

6 files changed

+117
-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>
+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

0 commit comments

Comments
 (0)