1- import React from 'react' ;
1+ import React , { Fragment } from 'react' ;
22import CrossIcon from 'react-icons/lib/md/clear' ;
33import RefreshIcon from 'react-icons/lib/md/refresh' ;
4+ import ArrowDropDown from 'react-icons/lib/md/keyboard-arrow-down' ;
5+ import ArrowDropUp from 'react-icons/lib/md/keyboard-arrow-up' ;
46
57import { EntryContainer , IconArea , Icon } from '../../elements' ;
68import { Link } from '../elements' ;
7- import { Version } from './elements' ;
9+ import { Version , MoreData } from './elements' ;
10+
11+ const formatSize = value => {
12+ let unit ;
13+ let size ;
14+ if ( Math . log10 ( value ) < 3 ) {
15+ unit = 'B' ;
16+ size = value ;
17+ } else if ( Math . log10 ( value ) < 6 ) {
18+ unit = 'kB' ;
19+ size = value / 1024 ;
20+ } else {
21+ unit = 'mB' ;
22+ size = value / 1024 / 1024 ;
23+ }
24+
25+ return { unit, size : parseFloat ( size ) . toFixed ( 1 ) } ;
26+ } ;
827
928export default class VersionEntry extends React . PureComponent {
1029 state = {
1130 hovering : false ,
1231 version : null ,
32+ open : false ,
33+ size : { } ,
1334 } ;
1435
1536 setVersionsForLatestPkg ( pkg ) {
@@ -20,9 +41,24 @@ export default class VersionEntry extends React.PureComponent {
2041 . catch ( err => console . err ( err ) ) ; // eslint-disable-line no-console
2142 }
2243
44+ getSizeForPKG ( pkg ) {
45+ fetch ( `https://bundlephobia.com/api/size?package=${ pkg } ` )
46+ . then ( response => response . json ( ) )
47+ . then ( size =>
48+ this . setState ( {
49+ size,
50+ } )
51+ )
52+ . catch ( err => console . err ( err ) ) ; // eslint-disable-line no-console
53+ }
54+
2355 componentWillMount ( ) {
2456 const versionRegex = / ^ \d { 1 , 3 } \. \d { 1 , 3 } .\d { 1 , 3 } $ / ;
2557 const version = this . props . dependencies [ this . props . dependency ] ;
58+ const cleanVersion = version . split ( '^' ) ;
59+ this . getSizeForPKG (
60+ `${ this . props . dependency } @${ cleanVersion [ cleanVersion . length - 1 ] } `
61+ ) ;
2662 if ( ! versionRegex . test ( version ) ) {
2763 this . setVersionsForLatestPkg ( `${ this . props . dependency } @${ version } ` ) ;
2864 }
@@ -44,35 +80,55 @@ export default class VersionEntry extends React.PureComponent {
4480 } ;
4581 onMouseEnter = ( ) => this . setState ( { hovering : true } ) ;
4682 onMouseLeave = ( ) => this . setState ( { hovering : false } ) ;
83+ handleOpen = ( ) => this . setState ( ( { open } ) => ( { open : ! open } ) ) ;
4784
4885 render ( ) {
4986 const { dependencies, dependency } = this . props ;
5087
51- const { hovering } = this . state ;
88+ const { hovering, version , size , open } = this . state ;
5289 return (
53- < EntryContainer
54- onMouseEnter = { this . onMouseEnter }
55- onMouseLeave = { this . onMouseLeave }
56- >
57- < Link href = { `https://www.npmjs.com/package/${ dependency } ` } >
58- { dependency }
59- </ Link >
60- < Version hovering = { hovering } >
61- { dependencies [ dependency ] } { ' ' }
62- { hovering &&
63- this . state . version && < span > ({ this . state . version } )</ span > }
64- </ Version >
65- { hovering && (
66- < IconArea >
67- < Icon onClick = { this . handleRefresh } >
68- < RefreshIcon />
69- </ Icon >
70- < Icon onClick = { this . handleRemove } >
71- < CrossIcon />
72- </ Icon >
73- </ IconArea >
74- ) }
75- </ EntryContainer >
90+ < Fragment >
91+ < EntryContainer
92+ onMouseEnter = { this . onMouseEnter }
93+ onMouseLeave = { this . onMouseLeave }
94+ >
95+ < Link href = { `https://www.npmjs.com/package/${ dependency } ` } >
96+ { dependency }
97+ </ Link >
98+ < Version withSize = { ! ! size . size } hovering = { hovering } >
99+ { dependencies [ dependency ] } { ' ' }
100+ { hovering && version && < span > ({ version } )</ span > }
101+ </ Version >
102+
103+ { hovering && (
104+ < IconArea >
105+ { size . size ? (
106+ < Icon onClick = { this . handleOpen } >
107+ { open ? < ArrowDropUp /> : < ArrowDropDown /> }
108+ </ Icon >
109+ ) : null }
110+ < Icon onClick = { this . handleRefresh } >
111+ < RefreshIcon />
112+ </ Icon >
113+ < Icon onClick = { this . handleRemove } >
114+ < CrossIcon />
115+ </ Icon >
116+ </ IconArea >
117+ ) }
118+ </ EntryContainer >
119+ { open ? (
120+ < MoreData >
121+ < li >
122+ < span > Gzip:</ span > { formatSize ( size . gzip ) . size }
123+ { formatSize ( size . gzip ) . unit }
124+ </ li >
125+ < li >
126+ < span > Size:</ span > { formatSize ( size . size ) . size }
127+ { formatSize ( size . size ) . unit }
128+ </ li >
129+ </ MoreData >
130+ ) : null }
131+ </ Fragment >
76132 ) ;
77133 }
78134}
0 commit comments