Skip to content

Commit ac438b5

Browse files
WesSouzaarturbien
authored andcommitted
feat(window): convert to TypeScript and export types
1 parent 6c727af commit ac438b5

File tree

11 files changed

+172
-160
lines changed

11 files changed

+172
-160
lines changed

src/Window/Window.spec.js renamed to src/Window/Window.spec.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import React from 'react';
2-
1+
import { createRef } from 'react';
32
import { renderWithTheme } from '../../test/utils';
43

5-
import Window from './Window';
4+
import { Window } from './Window';
65

76
describe('<Window />', () => {
87
it('renders Window', () => {
@@ -28,10 +27,20 @@ describe('<Window />', () => {
2827

2928
expect(queryByTestId('resizeHandle')).not.toBeInTheDocument();
3029
});
30+
3131
it('renders resize handle when set to true', () => {
3232
const { queryByTestId } = renderWithTheme(<Window resizable />);
3333

3434
expect(queryByTestId('resizeHandle')).toBeInTheDocument();
3535
});
36+
37+
it('passes resizeRef to the resizable element', () => {
38+
const ref = createRef<HTMLSpanElement>();
39+
const { queryByTestId } = renderWithTheme(
40+
<Window resizable resizeRef={ref} />
41+
);
42+
43+
expect(queryByTestId('resizeHandle')).toBe(ref.current);
44+
});
3645
});
3746
});

src/Window/Window.stories.js renamed to src/Window/Window.stories.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import React from 'react';
2-
import styled from 'styled-components';
1+
import { ComponentMeta } from '@storybook/react';
32
import {
4-
Window,
5-
WindowContent,
6-
WindowHeader,
73
Button,
4+
Panel,
85
Toolbar,
9-
Panel
6+
Window,
7+
WindowContent,
8+
WindowHeader
109
} from 'react95';
10+
import styled from 'styled-components';
1111

1212
const Wrapper = styled.div`
1313
padding: 5rem;
@@ -66,7 +66,7 @@ export default {
6666
component: Window,
6767
subcomponents: { WindowHeader, WindowContent },
6868
decorators: [story => <Wrapper>{story()}</Wrapper>]
69-
};
69+
} as ComponentMeta<typeof Window>;
7070

7171
export function Default() {
7272
return (
@@ -97,7 +97,7 @@ export function Default() {
9797
</p>
9898
</WindowContent>
9999
<Panel variant='well' className='footer'>
100-
Put some useful informations here
100+
Put some useful information here
101101
</Panel>
102102
</Window>
103103

src/Window/Window.js renamed to src/Window/Window.tsx

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
import React from 'react';
2-
import propTypes from 'prop-types';
3-
1+
import React, { forwardRef } from 'react';
42
import styled, { css } from 'styled-components';
53
import { createBorderStyles, createBoxStyles } from '../common';
4+
import { CommonStyledProps } from '../types';
5+
6+
type WindowProps = {
7+
children?: React.ReactNode;
8+
resizable?: boolean;
9+
resizeRef?: React.Ref<HTMLSpanElement>;
10+
shadow?: boolean;
11+
} & React.HTMLAttributes<HTMLDivElement> &
12+
CommonStyledProps;
613

714
const StyledWindow = styled.div`
815
position: relative;
@@ -11,6 +18,7 @@ const StyledWindow = styled.div`
1118
${createBorderStyles({ windowBorders: true })}
1219
${createBoxStyles()}
1320
`;
21+
1422
const ResizeHandle = styled.span`
1523
${({ theme }) => css`
1624
display: inline-block;
@@ -39,27 +47,16 @@ const ResizeHandle = styled.span`
3947
`}
4048
`;
4149

42-
const Window = React.forwardRef(function Window(props, ref) {
43-
const { resizable, children, ...otherProps } = props;
44-
50+
const Window = forwardRef<HTMLDivElement, WindowProps>(function Window(
51+
{ children, resizable = false, resizeRef, shadow = true, ...otherProps },
52+
ref
53+
) {
4554
return (
46-
<StyledWindow ref={ref} {...otherProps}>
55+
<StyledWindow ref={ref} shadow={shadow} {...otherProps}>
4756
{children}
48-
{resizable && <ResizeHandle data-testid='resizeHandle' />}
57+
{resizable && <ResizeHandle data-testid='resizeHandle' ref={resizeRef} />}
4958
</StyledWindow>
5059
);
5160
});
5261

53-
Window.defaultProps = {
54-
resizable: false,
55-
shadow: true,
56-
children: null
57-
};
58-
59-
Window.propTypes = {
60-
shadow: propTypes.bool,
61-
resizable: propTypes.bool,
62-
children: propTypes.node
63-
};
64-
65-
export default Window;
62+
export { Window, WindowProps };

src/WindowContent/WindowContent.js

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/WindowContent/WindowContent.spec.js renamed to src/WindowContent/WindowContent.spec.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import React from 'react';
2-
31
import { renderWithTheme } from '../../test/utils';
42

5-
import WindowContent from './WindowContent';
3+
import { WindowContent } from './WindowContent';
64

75
describe('<WindowContent />', () => {
86
it('renders WindowContent', () => {

src/WindowContent/WindowContent.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React, { forwardRef } from 'react';
2+
import styled from 'styled-components';
3+
import { CommonStyledProps } from '../types';
4+
5+
type WindowContentProps = {
6+
children?: React.ReactNode;
7+
} & React.HTMLAttributes<HTMLDivElement> &
8+
CommonStyledProps;
9+
10+
const StyledWindowContent = styled.div`
11+
padding: 16px;
12+
`;
13+
14+
const WindowContent = forwardRef<HTMLDivElement, WindowContentProps>(
15+
function WindowContent({ children, ...otherProps }, ref) {
16+
return (
17+
<StyledWindowContent ref={ref} {...otherProps}>
18+
{children}
19+
</StyledWindowContent>
20+
);
21+
}
22+
);
23+
24+
export { WindowContent, WindowContentProps };

src/WindowHeader/WindowHeader.js

Lines changed: 0 additions & 54 deletions
This file was deleted.

src/WindowHeader/WindowHeader.spec.js

Lines changed: 0 additions & 40 deletions
This file was deleted.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { renderWithTheme, theme } from '../../test/utils';
2+
3+
import { WindowHeader } from './WindowHeader';
4+
5+
describe('<WindowHeader />', () => {
6+
it('renders WindowHeader', () => {
7+
const { container } = renderWithTheme(<WindowHeader />);
8+
const windowHeader = container.firstChild;
9+
10+
expect(windowHeader).toBeInTheDocument();
11+
});
12+
13+
it('renders children', () => {
14+
const textContent = 'Hi there!';
15+
const { getByText } = renderWithTheme(
16+
<WindowHeader>
17+
<span>{textContent}</span>
18+
</WindowHeader>
19+
);
20+
expect(getByText(textContent)).toBeInTheDocument();
21+
});
22+
23+
describe('prop: active', () => {
24+
it('displays active header by default', () => {
25+
const { container } = renderWithTheme(<WindowHeader />);
26+
const windowHeader = container.firstChild as HTMLDivElement;
27+
28+
expect(windowHeader).toHaveStyleRule('color', theme.headerText);
29+
expect(windowHeader).toHaveStyleRule(
30+
'background',
31+
theme.headerBackground
32+
);
33+
});
34+
35+
it('displays active header when set to true', () => {
36+
const { container } = renderWithTheme(<WindowHeader active />);
37+
const windowHeader = container.firstChild as HTMLDivElement;
38+
39+
expect(windowHeader).toHaveStyleRule('color', theme.headerText);
40+
expect(windowHeader).toHaveStyleRule(
41+
'background',
42+
theme.headerBackground
43+
);
44+
});
45+
46+
it('renders non-active header when set to false', () => {
47+
const { container } = renderWithTheme(<WindowHeader active={false} />);
48+
const windowHeader = container.firstChild;
49+
50+
expect(windowHeader).toHaveStyleRule('color', theme.headerNotActiveText);
51+
expect(windowHeader).toHaveStyleRule(
52+
'background',
53+
theme.headerNotActiveBackground
54+
);
55+
});
56+
});
57+
});

src/WindowHeader/WindowHeader.tsx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React, { forwardRef } from 'react';
2+
import styled, { css } from 'styled-components';
3+
import { StyledButton } from '../Button/Button';
4+
import { CommonStyledProps } from '../types';
5+
6+
type WindowHeaderProps = {
7+
children?: React.ReactNode;
8+
active?: boolean;
9+
} & React.HTMLAttributes<HTMLDivElement> &
10+
CommonStyledProps;
11+
12+
const StyledWindowHeader = styled.div<Pick<WindowHeaderProps, 'active'>>`
13+
height: 33px;
14+
line-height: 33px;
15+
padding-left: 0.25rem;
16+
padding-right: 3px;
17+
font-weight: bold;
18+
border: 2px solid ${({ theme }) => theme.material};
19+
${({ active }) =>
20+
active === false
21+
? css`
22+
background: ${({ theme }) => theme.headerNotActiveBackground};
23+
color: ${({ theme }) => theme.headerNotActiveText};
24+
`
25+
: css`
26+
background: ${({ theme }) => theme.headerBackground};
27+
color: ${({ theme }) => theme.headerText};
28+
`}
29+
30+
${StyledButton} {
31+
padding-left: 0;
32+
padding-right: 0;
33+
height: 27px;
34+
width: 31px;
35+
}
36+
`;
37+
38+
// TODO - should we add some aria label indicating if window is currently active?
39+
const WindowHeader = forwardRef<HTMLDivElement, WindowHeaderProps>(
40+
function WindowHeader({ active = true, children, ...otherProps }, ref) {
41+
return (
42+
<StyledWindowHeader active={active} ref={ref} {...otherProps}>
43+
{children}
44+
</StyledWindowHeader>
45+
);
46+
}
47+
);
48+
49+
export { WindowHeader, WindowHeaderProps };

0 commit comments

Comments
 (0)