Skip to content

Commit af71ff6

Browse files
authored
add ability to collapse dependencies section, remember user preference (#2104)
1 parent 7396b77 commit af71ff6

3 files changed

Lines changed: 83 additions & 52 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import AsyncStorage from '@react-native-async-storage/async-storage';
2+
import { useEffect, useState } from 'react';
3+
import { View } from 'react-native';
4+
5+
import { H6 } from '~/common/styleguide';
6+
import { Button } from '~/components/Button';
7+
import { Arrow } from '~/components/Icons';
8+
import tw from '~/util/tailwind';
9+
10+
import DependencyRow from './DependencyRow';
11+
import EntityCounter from './EntityCounter';
12+
13+
type Props = {
14+
title: string;
15+
data?: Record<string, string> | null;
16+
};
17+
18+
export default function CollapsibleSection({ title, data }: Props) {
19+
const sectionKey = sanitizeTitle(title);
20+
const key = `@ReactNativeDirectory:PackageSectionCollapsed:${sectionKey}`;
21+
22+
const [collapsed, setCollapsed] = useState<boolean>(
23+
Boolean(window.localStorage.getItem(key)) ?? false
24+
);
25+
26+
useEffect(() => {
27+
async function refreshState() {
28+
const val = await AsyncStorage.getItem(key);
29+
setCollapsed(val === 'true');
30+
}
31+
32+
void refreshState();
33+
}, []);
34+
35+
if (!data || Object.keys(data).length === 0) {
36+
return null;
37+
}
38+
39+
async function toggleSection() {
40+
const next = !collapsed;
41+
setCollapsed(next);
42+
await AsyncStorage.setItem(key, next ? 'true' : 'false');
43+
}
44+
45+
return (
46+
<>
47+
<View style={tw`flex-row gap-1.5 justify-between items-center`}>
48+
<H6 style={tw`flex items-center gap-1.5 text-[16px] text-secondary`}>
49+
{title}
50+
<EntityCounter count={Object.keys(data).length} />
51+
</H6>
52+
<Button
53+
onPress={toggleSection}
54+
style={tw`p-1 bg-palette-gray2 dark:bg-palette-gray7`}
55+
containerStyle={tw`mt-px`}
56+
aria-label={`${collapsed ? 'Expand' : 'Collapse'} section`}>
57+
<Arrow style={[tw`w-4 h-3 text-icon`, collapsed ? tw`rotate-90` : tw`rotate-270`]} />
58+
</Button>
59+
</View>
60+
{!collapsed && (
61+
<View>
62+
{Object.entries(data).map(([name, version]) => (
63+
<DependencyRow key={`${sectionKey}-${name}`} name={name} version={version} />
64+
))}
65+
</View>
66+
)}
67+
</>
68+
);
69+
}
70+
71+
function sanitizeTitle(input: string) {
72+
return String(input)
73+
.toLowerCase()
74+
.trim()
75+
.replace(/[^a-z0-9]+/g, '-')
76+
.replace(/^-+|-+$/g, '');
77+
}

components/Package/EntityCounter.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default function EntityCounter({ count, style }: Props) {
1313
return (
1414
<Label
1515
style={[
16-
tw`mt-[3px] text-[11px] rounded-xl py-0.5 px-1.5 text-[inherit] bg-palette-gray2 dark:bg-accented`,
16+
tw`mt-[3px] h-4.5 text-[11px] rounded-xl py-0.5 px-1.5 text-[inherit] bg-palette-gray2 dark:bg-accented`,
1717
style,
1818
]}>
1919
{count}

scenes/PackageOverviewScene.tsx

Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import ContentContainer from '~/components/ContentContainer';
88
import MetaData from '~/components/Library/MetaData';
99
import TrendingMark from '~/components/Library/TrendingMark';
1010
import UpdatedAtView from '~/components/Library/UpdateAtView';
11-
import DependencyRow from '~/components/Package/DependencyRow';
11+
import CollapsibleSection from '~/components/Package/CollapsibleSection';
1212
import DetailsNavigation from '~/components/Package/DetailsNavigation';
1313
import EntityCounter from '~/components/Package/EntityCounter';
1414
import ExampleBox from '~/components/Package/ExampleBox';
@@ -19,7 +19,6 @@ import ReadmeBox from '~/components/Package/ReadmeBox';
1919
import PageMeta from '~/components/PageMeta';
2020
import { type NpmUser } from '~/types';
2121
import { type PackageOverviewPageProps } from '~/types/pages';
22-
import mapDependencies from '~/util/mapDependencies';
2322
import tw from '~/util/tailwind';
2423

2524
const ReadmeBoxWithLoading = dynamic(() => import('~/components/Package/ReadmeBox'), {
@@ -184,55 +183,10 @@ export default function PackageOverviewScene({
184183
</ul>
185184
</>
186185
)}
187-
{dependencies && Object.keys(dependencies).length > 0 && (
188-
<>
189-
<H6 style={tw`flex gap-1.5 text-[16px] text-secondary`}>
190-
Dependencies
191-
<EntityCounter count={Object.keys(dependencies).length} />
192-
</H6>
193-
<View>
194-
{mapDependencies(dependencies, ([name, version]: [string, string]) => (
195-
<DependencyRow key={`dep-${name}`} name={name} version={version} />
196-
))}
197-
</View>
198-
</>
199-
)}
200-
{peerDependencies && Object.keys(peerDependencies).length > 0 && (
201-
<>
202-
<H6 style={tw`flex gap-1.5 text-[16px] text-secondary`}>
203-
Peer dependencies
204-
<EntityCounter count={Object.keys(peerDependencies).length} />
205-
</H6>
206-
<View>
207-
{mapDependencies(peerDependencies, ([name, version]: [string, string]) => (
208-
<DependencyRow key={`peer-dep-${name}`} name={name} version={version} />
209-
))}
210-
</View>
211-
</>
212-
)}
213-
{devDependencies && Object.keys(devDependencies).length > 0 && (
214-
<>
215-
<H6 style={tw`flex gap-1.5 text-[16px] text-secondary`}>
216-
Development dependencies
217-
<EntityCounter count={Object.keys(devDependencies).length} />
218-
</H6>
219-
<View>
220-
{mapDependencies(devDependencies, ([name, version]: [string, string]) => (
221-
<DependencyRow key={`dev-dep-${name}`} name={name} version={version} />
222-
))}
223-
</View>
224-
</>
225-
)}
226-
{engines && Object.keys(engines).length > 0 && (
227-
<>
228-
<H6 style={tw`text-[16px] text-secondary`}>Engines</H6>
229-
<View>
230-
{mapDependencies(engines, ([name, version]: [string, string]) => (
231-
<DependencyRow key={`engine-${name}`} name={name} version={version} />
232-
))}
233-
</View>
234-
</>
235-
)}
186+
<CollapsibleSection title="Dependencies" data={dependencies} />
187+
<CollapsibleSection title="Peer dependencies" data={peerDependencies} />
188+
<CollapsibleSection title="Development dependencies" data={devDependencies} />
189+
<CollapsibleSection title="Engines" data={engines} />
236190
</View>
237191
</View>
238192
</ContentContainer>

0 commit comments

Comments
 (0)