Skip to content

Commit 02463ad

Browse files
add infomessage component, hook to compute background color
1 parent 6b5b6d9 commit 02463ad

File tree

5 files changed

+332
-0
lines changed

5 files changed

+332
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
node_modules/
22
dist/
3+
coverage/
34

45
# Logs
56
logs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import styled, { useTheme } from 'styled-components';
2+
import { Link, Text } from '../text/Text.component';
3+
import { Icon } from '../icon/Icon.component';
4+
import { defaultTheme } from '../../style/theme';
5+
import { useEffect, useRef, useState } from 'react';
6+
import {
7+
getBackgroundColor,
8+
useComputeBackgroundColor,
9+
} from './InfoMessageUtils';
10+
11+
type Props = {
12+
title: string;
13+
content: React.ReactNode;
14+
link?: string;
15+
};
16+
17+
const InfoMessageContainer = styled.div`
18+
background-color: ${defaultTheme.darkRebrand.backgroundLevel2};
19+
border-radius: 3px;
20+
padding: 0.5rem;
21+
display: flex;
22+
flex-direction: column;
23+
gap: 0.5rem;
24+
color: white;
25+
`;
26+
const TitleContainer = styled.div`
27+
align-items: center;
28+
display: flex;
29+
gap: 0.5rem;
30+
`;
31+
32+
function InfoMessage({ title, content, link }: Props) {
33+
// function, get parentElement background color if rgba(0,0,0,0) get to parentElement until
34+
// found a rgb(X,X,X) then check if backgroundColorLevel2 -> yes bgCLevel3 else bgCLevel2
35+
//window.getComptutedStyle(element.parentElement)['background-color']
36+
const { containerRef, backgroundColor } = useComputeBackgroundColor();
37+
38+
return (
39+
<InfoMessageContainer
40+
ref={containerRef}
41+
style={{ backgroundColor: backgroundColor }}
42+
>
43+
<TitleContainer>
44+
<Icon
45+
name="Info-circle"
46+
color={defaultTheme.darkRebrand.infoPrimary}
47+
size="lg"
48+
/>
49+
<Text isEmphazed>{title}</Text>
50+
</TitleContainer>
51+
<Text color="textSecondary">{content}</Text>
52+
{link && (
53+
<Link href={link} target="_blank" style={{ alignSelf: 'flex-end' }}>
54+
More infos <Icon name="External-link"></Icon>
55+
</Link>
56+
)}
57+
</InfoMessageContainer>
58+
);
59+
}
60+
61+
export default InfoMessage;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
import { defaultTheme } from '../../style/theme';
2+
import React from 'react';
3+
import {
4+
getBackgroundColor,
5+
useComputeBackgroundColor,
6+
} from './InfoMessageUtils';
7+
import { render } from '@testing-library/react';
8+
import '@testing-library/jest-dom';
9+
import { hex2RGB } from '../../utils';
10+
import { ThemeProvider, useTheme } from 'styled-components';
11+
import { CoreUiThemeProvider } from '../coreuithemeprovider/CoreUiThemeProvider';
12+
13+
describe('useComputeBackgroundColor', () => {
14+
it('should return backgroundlevel2 by default', () => {
15+
//S
16+
const SUT = jest.fn();
17+
const Component = () => {
18+
const { containerRef, backgroundColor } = useComputeBackgroundColor();
19+
SUT(backgroundColor);
20+
return <div ref={containerRef}>{backgroundColor}</div>;
21+
};
22+
render(
23+
<CoreUiThemeProvider theme={defaultTheme.darkRebrand}>
24+
<Component />
25+
</CoreUiThemeProvider>,
26+
);
27+
//V
28+
expect(SUT).toHaveBeenCalledWith(defaultTheme.darkRebrand.backgroundLevel2);
29+
});
30+
31+
it('should return backgroundlevel3 if parent element backgroundColor is level 2', () => {
32+
//S
33+
const SUT = jest.fn();
34+
const Component = () => {
35+
const { containerRef, backgroundColor } = useComputeBackgroundColor();
36+
SUT(backgroundColor);
37+
return (
38+
<div
39+
style={{ backgroundColor: defaultTheme.darkRebrand.backgroundLevel2 }}
40+
>
41+
<div ref={containerRef}>{backgroundColor}</div>
42+
</div>
43+
);
44+
};
45+
render(
46+
<CoreUiThemeProvider theme={defaultTheme.darkRebrand}>
47+
<Component />
48+
</CoreUiThemeProvider>,
49+
);
50+
//V
51+
expect(SUT).toHaveBeenCalledWith(defaultTheme.darkRebrand.backgroundLevel3);
52+
});
53+
it('should return backgroundlevel3 if parent of parent element backgroundColor is level 2', () => {
54+
//S
55+
const SUT = jest.fn();
56+
const Component = () => {
57+
const { containerRef, backgroundColor } = useComputeBackgroundColor();
58+
SUT(backgroundColor);
59+
return (
60+
<div
61+
style={{ backgroundColor: defaultTheme.darkRebrand.backgroundLevel2 }}
62+
>
63+
<div>
64+
<div ref={containerRef}>{backgroundColor}</div>
65+
</div>
66+
</div>
67+
);
68+
};
69+
render(
70+
<CoreUiThemeProvider theme={defaultTheme.darkRebrand}>
71+
<Component />
72+
</CoreUiThemeProvider>,
73+
);
74+
//V
75+
expect(SUT).toHaveBeenCalledWith(defaultTheme.darkRebrand.backgroundLevel3);
76+
});
77+
it('should return backgroundlevel2 if parent of parent element backgroundColor is level 3', () => {
78+
//S
79+
const SUT = jest.fn();
80+
const Component = () => {
81+
const { containerRef, backgroundColor } = useComputeBackgroundColor();
82+
SUT(backgroundColor);
83+
return (
84+
<div
85+
style={{ backgroundColor: defaultTheme.darkRebrand.backgroundLevel3 }}
86+
>
87+
<div>
88+
<div ref={containerRef}>{backgroundColor}</div>
89+
</div>
90+
</div>
91+
);
92+
};
93+
render(
94+
<CoreUiThemeProvider theme={defaultTheme.darkRebrand}>
95+
<Component />
96+
</CoreUiThemeProvider>,
97+
);
98+
//V
99+
expect(SUT).toHaveBeenCalledWith(defaultTheme.darkRebrand.backgroundLevel2);
100+
});
101+
});
102+
103+
test('when no background in parent element, return backgroundlevel2', () => {
104+
//S
105+
const divElement = document.createElement('div');
106+
//E
107+
const computedBackgroundColor = getBackgroundColor(
108+
divElement,
109+
defaultTheme.darkRebrand,
110+
);
111+
//V
112+
expect(computedBackgroundColor).toBe(
113+
defaultTheme.darkRebrand.backgroundLevel2,
114+
);
115+
});
116+
117+
test('when background in parent element is backgroundLevel2 return backgroundlevel3', () => {
118+
//S
119+
const containerElement = document.createElement('body');
120+
const divElement = document.createElement('div');
121+
containerElement.appendChild(divElement);
122+
window.getComputedStyle = jest.fn().mockImplementation(() => ({
123+
['background-color']: 'rgb(50, 50, 69)',
124+
}));
125+
//E
126+
const computedBackgroundColor = getBackgroundColor(
127+
divElement,
128+
defaultTheme.darkRebrand,
129+
);
130+
//V
131+
expect(computedBackgroundColor).toBe(
132+
defaultTheme.darkRebrand.backgroundLevel3,
133+
);
134+
});
135+
136+
test('when background in grand-parent element is backgroundLevel2 return backgroundlevel3', () => {
137+
//S
138+
const containerElement = document.createElement('body');
139+
const intermediateElement = document.createElement('div');
140+
containerElement.appendChild(intermediateElement);
141+
const divElement = document.createElement('div');
142+
intermediateElement.appendChild(divElement);
143+
window.getComputedStyle = jest
144+
.fn()
145+
.mockImplementation((element: HTMLElement) => {
146+
if (element.tagName === 'BODY')
147+
return {
148+
['background-color']: 'rgb(50, 50, 69)',
149+
};
150+
return {};
151+
});
152+
//E
153+
const computedBackgroundColor = getBackgroundColor(
154+
divElement,
155+
defaultTheme.darkRebrand,
156+
);
157+
//V
158+
expect(computedBackgroundColor).toBe(
159+
defaultTheme.darkRebrand.backgroundLevel3,
160+
);
161+
});
162+
163+
test('when background in grand-parent element is backgroundLevel3 return backgroundlevel2', () => {
164+
//S
165+
const containerElement = document.createElement('body');
166+
const intermediateElement = document.createElement('div');
167+
containerElement.appendChild(intermediateElement);
168+
const divElement = document.createElement('div');
169+
intermediateElement.appendChild(divElement);
170+
window.getComputedStyle = jest
171+
.fn()
172+
.mockImplementation((element: HTMLElement) => {
173+
if (element.tagName === 'BODY')
174+
return {
175+
['background-color']: 'rgb(35, 35, 49)',
176+
};
177+
return {};
178+
});
179+
//E
180+
const computedBackgroundColor = getBackgroundColor(
181+
divElement,
182+
defaultTheme.darkRebrand,
183+
);
184+
//V
185+
expect(computedBackgroundColor).toBe(
186+
defaultTheme.darkRebrand.backgroundLevel2,
187+
);
188+
});
189+
190+
/**
191+
* Test to do :
192+
* Return the correct background if a parent element as a background
193+
* Return default background if no parent element as a backgorund
194+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { DefaultTheme, useTheme } from "styled-components";
2+
import { defaultTheme } from "../../style/theme";
3+
import { hex2RGB } from "../../utils";
4+
import { useEffect, useRef, useState } from "react";
5+
6+
export const useComputeBackgroundColor = () => {
7+
const theme = useTheme();
8+
const containerRef = useRef<HTMLDivElement | null>(null);
9+
const [backgroundColor, setBackgroundColor] = useState('');
10+
11+
useEffect(() => {
12+
containerRef.current &&
13+
setBackgroundColor(getBackgroundColor(containerRef.current, theme));
14+
}, [containerRef]);
15+
16+
return {
17+
containerRef,
18+
backgroundColor,
19+
};
20+
};
21+
22+
export const getBackgroundColor = (element: HTMLElement, theme: DefaultTheme) => {
23+
if (element.parentElement) {
24+
const parentElementBackgroundColor = window.getComputedStyle(
25+
element.parentElement,
26+
)['background-color'];
27+
if (/rgba/.test(parentElementBackgroundColor) || !window.getComputedStyle(element.parentElement,)['background-color']) {
28+
// need to test if opacity = 0
29+
return getBackgroundColor(element.parentElement, theme);
30+
} else {
31+
const rgbArray = hex2RGB(theme.backgroundLevel2);
32+
if (
33+
`rgb(${rgbArray[0]}, ${rgbArray[1]}, ${rgbArray[2]})` ===
34+
parentElementBackgroundColor
35+
) {
36+
return theme.backgroundLevel3;
37+
}
38+
}
39+
}
40+
return theme.backgroundLevel2;
41+
};

stories/infomessage.stories.tsx

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from 'react';
2+
import InfoMessage from '../src/lib/components/infomessage/InfoMessage.component';
3+
import { Wrapper, Title } from './common';
4+
import { defaultTheme } from '../src/lib/style/theme';
5+
6+
export default {
7+
title: 'Components/InfoMessage',
8+
component: InfoMessage,
9+
};
10+
11+
export const Default = () => {
12+
return (
13+
<Wrapper>
14+
<Title>Basic usage</Title>
15+
<div
16+
style={{
17+
backgroundColor: defaultTheme.darkRebrand.backgroundLevel2,
18+
padding: '1rem',
19+
}}
20+
>
21+
<div
22+
style={{
23+
padding: '1rem',
24+
}}
25+
>
26+
<InfoMessage
27+
title="What to do with this key?"
28+
content="This key is needed by the Veeam repository to access ARTESCA for data backup."
29+
link="test"
30+
/>
31+
</div>
32+
</div>
33+
</Wrapper>
34+
);
35+
};

0 commit comments

Comments
 (0)