@@ -2,8 +2,11 @@ import { useContext } from 'react';
22import { Platform , StyleSheet , View } from 'react-native' ;
33
44import { colors , A , P , Caption , darkColors } from '~/common/styleguide' ;
5+ import Tooltip from '~/components/Tooltip' ;
56import CustomAppearanceContext from '~/context/CustomAppearanceContext' ;
6- import { type LibraryType } from '~/types' ;
7+ import { type LibraryType , MetadataEntryType } from '~/types' ;
8+ import { partition } from '~/util/arrays' ;
9+ import { formatBytes } from '~/util/formatBytes' ;
710
811import { DirectoryScore } from './DirectoryScore' ;
912import {
@@ -17,25 +20,26 @@ import {
1720 Code ,
1821 TypeScript ,
1922 NativeCode ,
23+ PackageSize ,
24+ Dependency ,
2025} from '../Icons' ;
2126
2227type Props = {
2328 library : LibraryType ;
2429 secondary ?: boolean ;
2530} ;
2631
27- function generateData ( { github, score, npm, npmPkg } : LibraryType , isDark : boolean ) {
32+ function generateData (
33+ { github, score, npm, npmPkg } : LibraryType ,
34+ isDark : boolean
35+ ) : MetadataEntryType [ ] {
2836 const iconColor = isDark ? darkColors . pewter : colors . gray5 ;
2937 return [
3038 {
3139 id : 'score' ,
3240 icon : < DirectoryScore score = { score } /> ,
3341 content : (
34- < A
35- target = "_self"
36- href = "/scoring"
37- style = { { ...styles . link , ...styles . mutedLink } }
38- hoverStyle = { isDark && { color : colors . primaryDark } } >
42+ < A target = "_self" href = "/scoring" style = { styles . link } >
3943 Directory Score
4044 </ A >
4145 ) ,
@@ -63,15 +67,38 @@ function generateData({ github, score, npm, npmPkg }: LibraryType, isDark: boole
6367 </ A >
6468 ) ,
6569 } ,
70+ {
71+ id : 'dependencies' ,
72+ icon : < Dependency fill = { iconColor } /> ,
73+ content : (
74+ < A
75+ href = { `https://www.npmjs.com/package/${ npmPkg } ?activeTab=dependencies` }
76+ style = { styles . link } >
77+ { `${ github . stats . dependencies } ${ github . stats . dependencies === 1 ? 'dependency' : 'dependencies' } ` }
78+ </ A >
79+ ) ,
80+ } ,
81+ npm . size
82+ ? {
83+ id : 'size' ,
84+ icon : < PackageSize fill = { iconColor } /> ,
85+ content : (
86+ < A href = { `https://packagephobia.com/result?p=${ npmPkg } ` } style = { styles . link } >
87+ { `${ formatBytes ( npm . size ) } package size` }
88+ </ A >
89+ ) ,
90+ }
91+ : null ,
6692 github . stats . forks
6793 ? {
6894 id : 'forks' ,
6995 icon : < Fork fill = { iconColor } width = { 16 } height = { 17 } /> ,
7096 content : (
7197 < A href = { `${ github . urls . repo } /network/members` } style = { styles . link } >
72- { `${ github . stats . forks . toLocaleString ( ) } ` } forks
98+ { `${ github . stats . forks . toLocaleString ( ) } ` }
7399 </ A >
74100 ) ,
101+ tooltip : 'Forks' ,
75102 }
76103 : null ,
77104 github . stats . subscribers
@@ -80,9 +107,10 @@ function generateData({ github, score, npm, npmPkg }: LibraryType, isDark: boole
80107 icon : < Eye fill = { iconColor } /> ,
81108 content : (
82109 < A href = { `${ github . urls . repo } /watchers` } style = { styles . link } >
83- { `${ github . stats . subscribers . toLocaleString ( ) } ` } watchers
110+ { `${ github . stats . subscribers . toLocaleString ( ) } ` }
84111 </ A >
85112 ) ,
113+ tooltip : 'Watchers' ,
86114 }
87115 : null ,
88116 github . stats . issues
@@ -91,9 +119,10 @@ function generateData({ github, score, npm, npmPkg }: LibraryType, isDark: boole
91119 icon : < Issue fill = { iconColor } /> ,
92120 content : (
93121 < A href = { `${ github . urls . repo } /issues` } style = { styles . link } >
94- { `${ github . stats . issues . toLocaleString ( ) } ` } issues
122+ { `${ github . stats . issues . toLocaleString ( ) } ` }
95123 </ A >
96124 ) ,
125+ tooltip : 'Issues' ,
97126 }
98127 : null ,
99128 ] ;
@@ -106,7 +135,10 @@ function generateSecondaryData({ github, examples }: LibraryType, isDark: boolea
106135 const iconColor = isDark ? darkColors . pewter : colors . secondary ;
107136 const paragraphStyles = [ styles . secondaryText , secondaryTextColor ] ;
108137 const linkStyles = [ ...paragraphStyles , styles . mutedLink ] ;
109- const hoverStyle = isDark && { color : colors . primaryDark } ;
138+ const hoverStyle = [
139+ { textDecorationColor : isDark ? colors . gray6 : colors . gray4 } ,
140+ isDark && { color : colors . primaryDark } ,
141+ ] ;
110142
111143 return [
112144 github . urls . homepage
@@ -173,26 +205,57 @@ function generateSecondaryData({ github, examples }: LibraryType, isDark: boolea
173205
174206export function MetaData ( { library, secondary } : Props ) {
175207 const { isDark } = useContext ( CustomAppearanceContext ) ;
176- const data = secondary ? generateSecondaryData ( library , isDark ) : generateData ( library , isDark ) ;
177208
178- return (
179- < >
180- { data . filter ( Boolean ) . map ( ( { id, icon, content } , i ) => (
181- < View
182- key = { id }
183- style = { [
184- styles . displayHorizontal ,
185- i + 1 !== data . length ? styles . datumContainer : { } ,
186- secondary ? styles . secondaryContainer : { } ,
187- ] } >
188- < View style = { [ styles . iconContainer , secondary ? styles . secondaryIconContainer : { } ] } >
189- { icon }
209+ if ( secondary ) {
210+ const data = generateSecondaryData ( library , isDark ) . filter ( Boolean ) ;
211+ return (
212+ < >
213+ { data . map ( ( { id, icon, content } , i ) => (
214+ < View
215+ key = { id }
216+ style = { [
217+ styles . displayHorizontal ,
218+ i + 1 !== data . length ? styles . datumContainer : { } ,
219+ styles . secondaryContainer ,
220+ ] } >
221+ < View style = { [ styles . iconContainer , styles . secondaryIconContainer ] } > { icon } </ View >
222+ { content }
190223 </ View >
191- { content }
224+ ) ) }
225+ </ >
226+ ) ;
227+ } else {
228+ const data = generateData ( library , isDark ) . filter ( entry => ! ! entry ) ;
229+ const [ bottomData , listData ] = partition < NonNullable < MetadataEntryType > > ( data , ( { id } ) => {
230+ return [ 'forks' , 'subscribers' , 'issues' ] . includes ( id ) ;
231+ } ) ;
232+ return (
233+ < >
234+ { listData . map ( ( { id, icon, content } , i ) => (
235+ < View
236+ key = { id }
237+ style = { [ styles . displayHorizontal , i + 1 !== data . length ? styles . datumContainer : { } ] } >
238+ < View style = { styles . iconContainer } > { icon } </ View >
239+ { content }
240+ </ View >
241+ ) ) }
242+ < View style = { [ styles . displayHorizontal , styles . bottomStats ] } >
243+ { bottomData . map ( ( { id, icon, content, tooltip } ) => (
244+ < View key = { id } style = { styles . displayHorizontal } >
245+ < Tooltip
246+ key = { id }
247+ sideOffset = { 2 }
248+ delayDuration = { 100 }
249+ trigger = { < View style = { styles . iconContainer } > { icon } </ View > } >
250+ { tooltip }
251+ </ Tooltip >
252+ { content }
253+ </ View >
254+ ) ) }
192255 </ View >
193- ) ) }
194- </ >
195- ) ;
256+ </ >
257+ ) ;
258+ }
196259}
197260
198261const styles = StyleSheet . create ( {
@@ -205,6 +268,9 @@ const styles = StyleSheet.create({
205268 flexDirection : 'row' ,
206269 alignItems : 'center' ,
207270 } ,
271+ bottomStats : {
272+ gap : 16 ,
273+ } ,
208274 iconContainer : {
209275 marginRight : 7 ,
210276 width : 22 ,
0 commit comments