Skip to content

Commit 2bdece1

Browse files
tassoevanggazzo
authored andcommitted
feat: Callout component (#69)
1 parent 39e1f28 commit 2bdece1

13 files changed

+174
-4
lines changed

.vscode/fuselage.code-snippets

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
"import React from 'react';",
77
"import ReactDOM from 'react-dom';",
88
"",
9-
"import { $1 } from '.';",
10-
"",
9+
"import { $1 } from '../..';",
1110
"",
1211
"it('renders without crashing', () => {",
1312
" const div = document.createElement('div');",

packages/fuselage/.jest/setup.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const { warn, error } = console;
2+
3+
global.console.warn = (message) => {
4+
warn.call(console, message);
5+
throw (message instanceof Error ? message : new Error(message));
6+
}
7+
8+
global.console.error = (message) => {
9+
error.call(console, message);
10+
throw (message instanceof Error ? message : new Error(message));
11+
}
Loading
Loading
Loading
Loading

packages/fuselage/.storybook/jest-results.json

+1-1
Large diffs are not rendered by default.

packages/fuselage/package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,10 @@
9292
"jest": {
9393
"moduleNameMapper": {
9494
"\\.(css|scss)$": "<rootDir>/.jest/styleMock.js"
95-
}
95+
},
96+
"setupFiles": [
97+
"<rootDir>/.jest/setup.js"
98+
]
9699
},
97100
"loki": {
98101
"configurations": {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { useClassName } from '@rocket.chat/fuselage-hooks';
2+
import PropTypes from 'prop-types';
3+
import React from 'react';
4+
5+
import { useTheme } from '../../hooks/useTheme';
6+
import { Icon } from '../Icon';
7+
import { StyledCallout, Wrapper, Title } from './styles';
8+
9+
export const Callout = React.forwardRef(function Callout({
10+
children,
11+
className,
12+
title,
13+
type = 'info',
14+
...props
15+
}, ref) {
16+
const classNames = {
17+
container: useClassName('rcx-callout', { type }, className),
18+
wrapper: useClassName('rcx-callout__wrapper'),
19+
title: useClassName('rcx-callout__title'),
20+
description: useClassName('rcx-callout__description'),
21+
};
22+
const theme = useTheme();
23+
24+
const iconName = (type === 'info' && 'info-circled')
25+
|| (type === 'success' && 'checkmark-circled')
26+
|| (type === 'warning' && 'warning')
27+
|| (type === 'danger' && 'ban');
28+
29+
return <StyledCallout className={classNames.container} ref={ref} theme={theme} type={type} {...props}>
30+
<Icon name={iconName} />
31+
<Wrapper theme={theme}>
32+
<Title hasChildren={!!children} theme={theme}>{title}</Title>
33+
{children}
34+
</Wrapper>
35+
</StyledCallout>;
36+
});
37+
38+
Callout.defaultProps = {
39+
type: 'info',
40+
};
41+
42+
Callout.displayName = 'Callout';
43+
44+
Callout.propTypes = {
45+
children: PropTypes.node,
46+
invisible: PropTypes.bool,
47+
title: PropTypes.string.isRequired,
48+
type: PropTypes.oneOf(['info', 'success', 'warning', 'danger']).isRequired,
49+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
4+
import { Callout } from '../..';
5+
6+
it('renders without crashing', () => {
7+
const div = document.createElement('div');
8+
ReactDOM.render(<Callout title='' />, div);
9+
ReactDOM.unmountComponentAtNode(div);
10+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { Meta, Preview, Props, Story } from '@storybook/addon-docs/blocks';
2+
import LinkTo from '@storybook/addon-links/react';
3+
4+
import { Callout } from '../..';
5+
6+
<Meta title='Misc|Callout' parameters={{ jest: ['Callout/spec'] }} />
7+
8+
# Callout
9+
10+
The <LinkTo kind='Misc|Callout' story='Default Story'>`Callout`</LinkTo> is used to get the user's attention explaining
11+
something important in the content of the current page.
12+
13+
<Preview>
14+
<Story name='Default'>
15+
<>
16+
<Callout title='This is a generic message' />
17+
<Callout title='This is a successful message' type='success' />
18+
<Callout title='This is a warning message' type='warning' />
19+
<Callout title='This is a danger message' type='danger' />
20+
</>
21+
</Story>
22+
</Preview>
23+
24+
<Props of={Callout} />
25+
26+
## With description
27+
28+
<Preview>
29+
<Story name='With Description'>
30+
<>
31+
<Callout title='This is a generic message'>
32+
This is a generic description.
33+
</Callout>
34+
<Callout title='This is a successful message' type='success'>
35+
This is a successful description.
36+
</Callout>
37+
<Callout title='This is a warning message' type='warning'>
38+
This is a warning description.
39+
</Callout>
40+
<Callout title='This is a danger message' type='danger'>
41+
This is a danger description.
42+
</Callout>
43+
</>
44+
</Story>
45+
</Preview>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import styled, { css } from 'styled-components';
2+
import colors from '@rocket.chat/fuselage-tokens/colors';
3+
4+
import box from '../../styles/box';
5+
import { truncate, caption, captionBold } from '../../styles/utilities/typography';
6+
import { StyledIcon } from '../Icon/styles';
7+
8+
export const StyledCallout = styled.div`
9+
${ box }
10+
11+
display: flex;
12+
margin: 0 0 ${ ({ theme }) => theme.spaces.x24 };
13+
padding: ${ ({ theme }) => theme.spaces.x16 };
14+
border-radius: ${ ({ theme }) => theme.borders.radius.x2 };
15+
16+
${ ({ type }) =>
17+
(type === 'info' && css`
18+
background-color: ${ colors.blue200 };
19+
`)
20+
|| (type === 'success' && css`
21+
background-color: ${ colors.green200 };
22+
`)
23+
|| (type === 'warning' && css`
24+
background-color: ${ colors.yellow200 };
25+
`)
26+
|| (type === 'danger' && css`
27+
background-color: ${ colors.red200 };
28+
`) }
29+
30+
& > ${ StyledIcon } {
31+
font-size: ${ ({ theme }) => theme.sizes.x16 };
32+
}
33+
`;
34+
35+
export const Wrapper = styled.div`
36+
${ box }
37+
flex: 1 1 0;
38+
display: flex;
39+
flex-flow: column nowrap;
40+
margin: 0 ${ ({ theme }) => theme.spaces.x8 };
41+
color: ${ ({ theme }) => theme.textColors.default };
42+
${ ({ theme }) => caption(theme) }
43+
`;
44+
45+
export const Title = styled.div`
46+
${ box }
47+
${ ({ theme }) => captionBold(theme) }
48+
${ ({ hasChildren, theme }) => hasChildren && css`
49+
margin-bottom: ${ theme.spaces.x4 };
50+
` }
51+
${ truncate }
52+
`;

packages/fuselage/src/components/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from './Box';
22
export * from './Button';
33
export * from './ButtonGroup';
4+
export * from './Callout';
45
export * from './CheckBox';
56
export * from './EmailInput';
67
export * from './Field';

0 commit comments

Comments
 (0)