Skip to content

Commit 9c0512a

Browse files
committed
feat(desktop): add Desktop component
1 parent d171be5 commit 9c0512a

File tree

5 files changed

+227
-0
lines changed

5 files changed

+227
-0
lines changed

src/Desktop/Desktop.js

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import React from 'react';
2+
import propTypes from 'prop-types';
3+
import styled from 'styled-components';
4+
5+
import { StyledCutout } from '../Cutout/Cutout';
6+
7+
const Wrapper = styled.div`
8+
position: relative;
9+
display: inline-block;
10+
padding-bottom: 26px;
11+
`;
12+
13+
const Inner = styled.div`
14+
position: relative;
15+
`;
16+
17+
const Monitor = styled.div`
18+
position: relative;
19+
z-index: 1;
20+
box-sizing: border-box;
21+
width: 195px;
22+
height: 155px;
23+
padding: 12px;
24+
background: ${({ theme }) => theme.material};
25+
border-top: 4px solid ${({ theme }) => theme.borderLightest};
26+
border-left: 4px solid ${({ theme }) => theme.borderLightest};
27+
border-bottom: 4px solid ${({ theme }) => theme.borderDark};
28+
border-right: 4px solid ${({ theme }) => theme.borderDark};
29+
30+
outline: 1px dotted ${({ theme }) => theme.material};
31+
outline-offset: -3px;
32+
&:before {
33+
content: '';
34+
position: absolute;
35+
left: 0;
36+
top: 0;
37+
width: 100%;
38+
height: 100%;
39+
outline: 1px dotted ${({ theme }) => theme.material};
40+
}
41+
box-shadow: 1px 1px 0 1px ${({ theme }) => theme.borderDarkest};
42+
43+
&:after {
44+
content: '';
45+
display: inline-block;
46+
position: absolute;
47+
bottom: 4px;
48+
right: 12px;
49+
width: 10px;
50+
border-top: 2px solid #4d9046;
51+
border-bottom: 2px solid #07ff00;
52+
}
53+
`;
54+
55+
const Background = styled(StyledCutout).attrs(() => ({
56+
'data-testid': 'background'
57+
}))`
58+
width: 100%;
59+
height: 100%;
60+
`;
61+
62+
const Stand = styled.div`
63+
box-sizing: border-box;
64+
position: absolute;
65+
top: calc(100% + 2px);
66+
left: 50%;
67+
transform: translateX(-50%);
68+
height: 10px;
69+
width: 50%;
70+
background: ${({ theme }) => theme.material};
71+
border-left: 2px solid ${({ theme }) => theme.borderLightest};
72+
border-bottom: 2px solid ${({ theme }) => theme.borderDarkest};
73+
border-right: 2px solid ${({ theme }) => theme.borderDarkest};
74+
box-shadow: inset 0px 0px 0px 2px ${({ theme }) => theme.borderDark};
75+
76+
&:before {
77+
content: '';
78+
position: absolute;
79+
top: calc(100% + 2px);
80+
left: 50%;
81+
transform: translateX(-50%);
82+
width: 80%;
83+
height: 8px;
84+
background: ${({ theme }) => theme.material};
85+
border-left: 2px solid ${({ theme }) => theme.borderLightest};
86+
border-right: 2px solid ${({ theme }) => theme.borderDarkest};
87+
box-shadow: inset 0px 0px 0px 2px ${({ theme }) => theme.borderDark};
88+
}
89+
&:after {
90+
content: '';
91+
position: absolute;
92+
top: calc(100% + 8px);
93+
left: 50%;
94+
transform: translateX(-50%);
95+
width: 150%;
96+
height: 4px;
97+
background: ${({ theme }) => theme.material};
98+
border: 2px solid ${({ theme }) => theme.borderDark};
99+
border-bottom: none;
100+
box-shadow: inset 1px 1px 0px 1px ${({ theme }) => theme.borderLightest},
101+
1px 1px 0 1px ${({ theme }) => theme.borderDarkest};
102+
}
103+
`;
104+
105+
const Desktop = React.forwardRef(function Desktop(props, ref) {
106+
const { backgroundStyles, children, ...otherProps } = props;
107+
108+
return (
109+
<Wrapper ref={ref} {...otherProps}>
110+
<Inner>
111+
<Monitor>
112+
<Background style={backgroundStyles}>{children}</Background>
113+
</Monitor>
114+
<Stand />
115+
</Inner>
116+
</Wrapper>
117+
);
118+
});
119+
120+
Desktop.defaultProps = {
121+
backgroundStyles: null
122+
};
123+
124+
Desktop.propTypes = {
125+
backgroundStyles: propTypes.object,
126+
// eslint-disable-next-line react/require-default-props
127+
children: propTypes.node
128+
};
129+
130+
export default Desktop;

src/Desktop/Desktop.mdx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
name: Desktop
3+
menu: Components
4+
---
5+
6+
import { Playground, Props } from 'docz';
7+
8+
import Desktop from '../Desktop/Desktop'
9+
10+
# Desktop
11+
12+
## Usage
13+
14+
<Playground>
15+
<Desktop backgroundStyles={{ background: 'blue' }} />
16+
</Playground>
17+
18+
## API
19+
20+
### Import
21+
22+
### Props
23+
24+
<Props of={Desktop} />

src/Desktop/Desktop.spec.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React from 'react';
2+
import { renderWithTheme } from '../../test/utils';
3+
4+
import Desktop from './Desktop';
5+
6+
describe('<Desktop />', () => {
7+
it('should render', () => {
8+
const { container } = renderWithTheme(<Desktop />);
9+
const desktopElement = container.firstChild;
10+
11+
expect(desktopElement).toBeInTheDocument();
12+
});
13+
14+
it('should handle custom props', () => {
15+
const customProps = { title: 'potatoe' };
16+
const { container } = renderWithTheme(<Desktop {...customProps} />);
17+
const desktopElement = container.firstChild;
18+
19+
expect(desktopElement).toHaveAttribute('title', 'potatoe');
20+
});
21+
22+
describe('prop: backgroundStyles', () => {
23+
it('should forward styles to background element', () => {
24+
const { getByTestId } = renderWithTheme(
25+
<Desktop backgroundStyles={{ backgroundColor: 'papayawhip' }} />
26+
);
27+
const backgroundElement = getByTestId('background');
28+
29+
expect(backgroundElement).toHaveAttribute(
30+
'style',
31+
'background-color: papayawhip;'
32+
);
33+
});
34+
});
35+
36+
describe('prop: children', () => {
37+
it('children should be rendered in background element', () => {
38+
const { getByTestId } = renderWithTheme(<Desktop>Hi!</Desktop>);
39+
const backgroundElement = getByTestId('background');
40+
41+
expect(backgroundElement.innerHTML).toBe('Hi!');
42+
});
43+
});
44+
});

src/Desktop/Desktop.stories.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
3+
import { Desktop } from 'react95';
4+
5+
export default {
6+
title: 'Desktop',
7+
component: Desktop,
8+
decorators: [
9+
story => (
10+
<div
11+
style={{
12+
padding: '5rem',
13+
background: 'teal'
14+
}}
15+
>
16+
{story()}
17+
</div>
18+
)
19+
]
20+
};
21+
22+
export const Default = () => (
23+
<Desktop backgroundStyles={{ background: 'blue' }} />
24+
);
25+
26+
Default.story = {
27+
name: 'default'
28+
};

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export { default as Button } from './Button/Button';
1111
export { default as Checkbox } from './Checkbox/Checkbox';
1212
export { default as ColorInput } from './ColorInput/ColorInput';
1313
export { default as Cutout } from './Cutout/Cutout';
14+
export { default as Desktop } from './Desktop/Desktop';
1415
export { default as Divider } from './Divider/Divider';
1516
export { default as Fieldset } from './Fieldset/Fieldset';
1617
export { default as Hourglass } from './Hourglass/Hourglass';

0 commit comments

Comments
 (0)