Skip to content

Commit bb6720d

Browse files
WesSouzaarturbien
authored andcommitted
feat(progress): convert to TypeScript and export types
1 parent 3c8729a commit bb6720d

File tree

5 files changed

+62
-72
lines changed

5 files changed

+62
-72
lines changed

src/Progress/Progress.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Progress
33
menu: Components
44
---
55

6-
import Progress from './Progress';
6+
import { Progress } from './Progress';
77

88
# Progress
99

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import React from 'react';
2-
31
import { renderWithTheme } from '../../test/utils';
4-
import Progress from './Progress';
2+
import { Progress } from './Progress';
53

64
describe('<Progress />', () => {
75
it('renders Progress', () => {
@@ -20,8 +18,12 @@ describe('<Progress />', () => {
2018
const value = 32;
2119
const { queryByTestId } = renderWithTheme(<Progress value={value} />);
2220

23-
expect(queryByTestId('defaultProgress1').textContent).toBe(`${value}%`);
24-
expect(queryByTestId('defaultProgress2').textContent).toBe(`${value}%`);
21+
expect(queryByTestId('defaultProgress1')?.textContent).toBe(
22+
`${value}%`
23+
);
24+
expect(queryByTestId('defaultProgress2')?.textContent).toBe(
25+
`${value}%`
26+
);
2527

2628
expect(queryByTestId('defaultProgress2')).toHaveStyleRule(
2729
'clip-path',

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import React, { useState, useEffect } from 'react';
2-
3-
import styled from 'styled-components';
4-
1+
import { ComponentMeta } from '@storybook/react';
2+
import { useEffect, useState } from 'react';
53
import { Progress } from 'react95';
4+
import styled from 'styled-components';
65

76
const Wrapper = styled.div`
87
background: ${({ theme }) => theme.material};
@@ -13,7 +12,7 @@ export default {
1312
title: 'Progress',
1413
component: Progress,
1514
decorators: [story => <Wrapper>{story()}</Wrapper>]
16-
};
15+
} as ComponentMeta<typeof Progress>;
1716

1817
export function Default() {
1918
const [percent, setPercent] = useState(0);

src/Progress/Progress.js renamed to src/Progress/Progress.tsx

Lines changed: 49 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
1-
import React, { forwardRef, useRef, useState, useEffect } from 'react';
2-
import propTypes from 'prop-types';
3-
1+
import React, {
2+
forwardRef,
3+
useCallback,
4+
useEffect,
5+
useRef,
6+
useState
7+
} from 'react';
48
import styled, { css } from 'styled-components';
59

6-
import { StyledCutout } from '../Cutout/Cutout';
710
import { blockSizes } from '../common/system';
11+
import { StyledCutout } from '../Cutout/Cutout';
12+
import { CommonStyledProps } from '../types';
13+
14+
type ProgressProps = {
15+
hideValue?: boolean;
16+
shadow?: boolean;
17+
value?: number;
18+
variant?: 'default' | 'tile';
19+
} & React.HTMLAttributes<HTMLDivElement> &
20+
CommonStyledProps;
821

922
const Wrapper = styled.div`
1023
display: inline-block;
@@ -42,7 +55,7 @@ const WhiteBar = styled.div`
4255
color: ${({ theme }) => theme.materialText};
4356
`;
4457

45-
const BlueBar = styled.div`
58+
const BlueBar = styled.div<Required<Pick<ProgressProps, 'value'>>>`
4659
position: absolute;
4760
top: 2px;
4861
left: 2px;
@@ -79,53 +92,45 @@ const Tile = styled.span`
7992
border-style: solid;
8093
`;
8194

82-
const Progress = forwardRef(function Progress(props, ref) {
83-
const { value, variant, shadow, hideValue, ...otherProps } = props;
95+
const Progress = forwardRef<HTMLDivElement, ProgressProps>(function Progress(
96+
{
97+
hideValue = false,
98+
shadow = true,
99+
value = 0,
100+
variant = 'default',
101+
...otherProps
102+
},
103+
ref
104+
) {
84105
const displayValue = hideValue ? null : `${value}%`;
85106

86-
const progressProps = {};
87-
if (value !== undefined) {
88-
progressProps['aria-valuenow'] = Math.round(value);
89-
}
90-
91-
const tilesWrapperRef = useRef();
92-
const savedCallback = useRef();
93-
const [tilesNumber, setTilesNumber] = useState(0);
107+
const tilesWrapperRef = useRef<HTMLDivElement | null>(null);
108+
const [tiles, setTiles] = useState([]);
94109

95110
// TODO debounce this function
96-
function updateTilesNumber() {
97-
if (tilesWrapperRef.current) {
98-
const progressWidth =
99-
tilesWrapperRef.current.getBoundingClientRect().width;
100-
const newTilesNumber = Math.round(
101-
((value / 100) * progressWidth) / tileWidth
102-
);
103-
setTilesNumber(newTilesNumber);
111+
const updateTilesNumber = useCallback(() => {
112+
if (!tilesWrapperRef.current) {
113+
return;
104114
}
105-
}
106-
useEffect(() => {
107-
savedCallback.current = updateTilesNumber;
108-
});
115+
const progressWidth = tilesWrapperRef.current.getBoundingClientRect().width;
116+
const newTilesNumber = Math.round(
117+
((value / 100) * progressWidth) / tileWidth
118+
);
119+
setTiles(Array.from({ length: newTilesNumber }));
120+
}, [value]);
121+
109122
useEffect(() => {
110-
function update() {
111-
savedCallback.current();
112-
}
123+
updateTilesNumber();
113124

114-
// then listen on window resize to recalculate number of tiles
115-
window.addEventListener('resize', update);
116-
return () => window.removeEventListener('resize', update);
117-
}, []);
125+
window.addEventListener('resize', updateTilesNumber);
126+
return () => window.removeEventListener('resize', updateTilesNumber);
127+
}, [updateTilesNumber]);
118128

119-
// recalculate number of tiles when value changes
120-
useEffect(() => {
121-
savedCallback.current();
122-
}, [value]);
123129
return (
124130
<Wrapper
125-
// TODO what to do with ref from forwardRef ?
131+
aria-valuenow={value !== undefined ? Math.round(value) : undefined}
126132
ref={ref}
127133
role='progressbar'
128-
{...progressProps}
129134
{...otherProps}
130135
>
131136
<ProgressCutout shadow={shadow}>
@@ -138,30 +143,14 @@ const Progress = forwardRef(function Progress(props, ref) {
138143
</>
139144
) : (
140145
<TilesWrapper ref={tilesWrapperRef} data-testid='tileProgress'>
141-
{Array(tilesNumber)
142-
.fill(null)
143-
.map((_, index) => (
144-
<Tile key={index} />
145-
))}
146+
{tiles.map((_, index) => (
147+
<Tile key={index} />
148+
))}
146149
</TilesWrapper>
147150
)}
148151
</ProgressCutout>
149152
</Wrapper>
150153
);
151154
});
152155

153-
Progress.defaultProps = {
154-
value: 0,
155-
shadow: true,
156-
variant: 'default',
157-
hideValue: false
158-
};
159-
160-
Progress.propTypes = {
161-
value: propTypes.number,
162-
shadow: propTypes.bool,
163-
variant: propTypes.oneOf(['default', 'tile']),
164-
hideValue: propTypes.bool
165-
};
166-
167-
export default Progress;
156+
export { Progress, ProgressProps };

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export { default as ListItem } from './ListItem/ListItem';
2121
export { default as LoadingIndicator } from './LoadingIndicator/LoadingIndicator';
2222
export { default as NumberField } from './NumberField/NumberField';
2323
export * from './Panel/Panel';
24-
export { default as Progress } from './Progress/Progress';
24+
export * from './Progress/Progress';
2525
export * from './Radio/Radio';
2626
export * from './Select/Select';
2727
export { default as Slider } from './Slider/Slider';

0 commit comments

Comments
 (0)