Skip to content

Commit df42227

Browse files
committed
feat(panel): add panel component
1 parent 606e48f commit df42227

File tree

4 files changed

+156
-0
lines changed

4 files changed

+156
-0
lines changed

src/components/Panel/Panel.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import React from 'react';
2+
import propTypes from 'prop-types';
3+
import styled, { css } from 'styled-components';
4+
import {
5+
createBorderStyles,
6+
createBoxStyles,
7+
createWellBorderStyles
8+
} from '../common';
9+
10+
const createPanelStyles = (variant = 'default') => {
11+
switch (variant) {
12+
case 'well':
13+
return css`
14+
${createWellBorderStyles(true)}
15+
`;
16+
case 'outside':
17+
return css`
18+
${createBorderStyles({ windowBorders: true })}
19+
`;
20+
default:
21+
return css`
22+
${createBorderStyles()}
23+
`;
24+
}
25+
};
26+
27+
const StyledPanel = styled.div`
28+
position: relative;
29+
font-size: 1rem;
30+
${({ variant }) => createPanelStyles(variant)}
31+
${createBoxStyles()}
32+
`;
33+
34+
const Panel = React.forwardRef(function Panel(props, ref) {
35+
const { children, variant, ...otherProps } = props;
36+
return (
37+
<StyledPanel ref={ref} variant={variant} {...otherProps}>
38+
{children}
39+
</StyledPanel>
40+
);
41+
});
42+
43+
Panel.defaultProps = {
44+
children: null,
45+
shadow: false,
46+
variant: 'outside'
47+
};
48+
49+
Panel.propTypes = {
50+
variant: propTypes.oneOf(['outside', 'inside', 'well']),
51+
children: propTypes.node,
52+
shadow: propTypes.bool
53+
};
54+
55+
export default Panel;

src/components/Panel/Panel.spec.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React from 'react';
2+
import { render } from '@testing-library/react';
3+
4+
import Panel from './Panel';
5+
6+
describe('<Panel />', () => {
7+
it('should render panel', () => {
8+
const { container } = render(<Panel />);
9+
const panel = container.firstChild;
10+
11+
expect(panel).toBeInTheDocument();
12+
});
13+
14+
it('should render custom styles', () => {
15+
const { container } = render(
16+
<Panel style={{ backgroundColor: 'papayawhip' }} />
17+
);
18+
const panel = container.firstChild;
19+
20+
expect(panel).toHaveAttribute('style', 'background-color: papayawhip;');
21+
});
22+
23+
it('should render children', async () => {
24+
const { findByText } = render(
25+
<Panel>
26+
<span>Cool panel</span>
27+
</Panel>
28+
);
29+
const content = await findByText(/cool panel/i);
30+
31+
expect(content).toBeInTheDocument();
32+
});
33+
34+
it('should render custom props', () => {
35+
const customProps = { title: 'panel' };
36+
const { container } = render(<Panel {...customProps} />);
37+
const panel = container.firstChild;
38+
39+
expect(panel).toHaveAttribute('title', 'panel');
40+
});
41+
});

src/components/Panel/Panel.stories.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react';
2+
import styled from 'styled-components';
3+
4+
import { Panel } from 'react95';
5+
6+
const Wrapper = styled.div`
7+
padding: 5rem;
8+
background: ${({ theme }) => theme.material};
9+
#default-buttons button {
10+
margin-bottom: 1rem;
11+
margin-right: 1rem;
12+
}
13+
14+
#cutout {
15+
background: ${({ theme }) => theme.canvas};
16+
padding: 1rem;
17+
width: 300px;
18+
}
19+
`;
20+
21+
export default {
22+
title: 'Panel',
23+
component: Panel,
24+
decorators: [story => <Wrapper>{story()}</Wrapper>]
25+
};
26+
27+
export const Default = () => (
28+
<Panel
29+
variant='outside'
30+
shadow
31+
style={{ padding: '0.5rem', lineHeight: '1.5', width: 600 }}
32+
>
33+
<p style={{ padding: '0.5rem' }}>
34+
Notice the subtle difference in borders. The lightest border is not on the
35+
edge of this panel.
36+
</p>
37+
<Panel variant='default' style={{ margin: '1rem', padding: '1rem' }}>
38+
This panel on the other hand has the lightest border on the edge. Use this
39+
panel inside &apos;outside&apos; panels.
40+
<br />
41+
<Panel
42+
variant='well'
43+
style={{ marginTop: '1rem', padding: '1rem', height: 200, width: 100 }}
44+
>
45+
Put some content here
46+
</Panel>
47+
</Panel>
48+
<Panel
49+
variant='well'
50+
style={{ marginTop: '1rem', padding: '0.1rem 0.25rem', width: '100%' }}
51+
>
52+
The &apos;well&apos; variant of a panel is often used as a window footer.
53+
</Panel>
54+
</Panel>
55+
);
56+
57+
Default.story = {
58+
name: 'default'
59+
};

src/components/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export { default as List } from './List/List';
1919
export { default as ListItem } from './ListItem/ListItem';
2020
export { default as LoadingIndicator } from './LoadingIndicator/LoadingIndicator';
2121
export { default as NumberField } from './NumberField/NumberField';
22+
export { default as Panel } from './Panel/Panel';
2223
export { default as Progress } from './Progress/Progress';
2324
export { default as Radio } from './Radio/Radio';
2425
export { default as Select } from './Select/Select';

0 commit comments

Comments
 (0)