Skip to content

Commit ea7efb1

Browse files
authored
allow collapsing more sections on package page, adjust arrangement (#2281)
1 parent 178bd28 commit ea7efb1

File tree

12 files changed

+184
-155
lines changed

12 files changed

+184
-155
lines changed

bun.lock

Lines changed: 50 additions & 50 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

common/styleguide.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,14 @@ const textStyles = StyleSheet.create({
2727
h1: tw`text-[57.25px] font-semibold`,
2828
h2: tw`text-[35.5px] font-semibold`,
2929
h3: tw`text-[26.5px] font-semibold`,
30-
h4: tw`text-[22px]`,
30+
h4: tw`text-[22px] tracking-tight`,
3131
h5: tw`text-[20px]`,
3232
h6: tw`text-[18px]`,
33+
h6section: tw`text-[16px] tracking-tight text-secondary`,
3334
headline: tw`text-[16px] font-medium`,
3435
p: tw`text-[16px]`,
35-
caption: tw`text-[15px] leading-[22px]`,
36-
label: tw`text-[12px] font-medium`,
36+
caption: tw`text-[15px] leading-[22px] tracking-normal`,
37+
label: tw`text-[12px] font-medium tracking-normal`,
3738
});
3839

3940
type CustomTextProps = TextProps &
@@ -77,6 +78,7 @@ export const H3 = createTextComponent(HtmlElements.H3, textStyles.h3);
7778
export const H4 = createTextComponent(HtmlElements.H4, textStyles.h4);
7879
export const H5 = createTextComponent(HtmlElements.H5, textStyles.h5);
7980
export const H6 = createTextComponent(HtmlElements.H6, textStyles.h6);
81+
export const H6Section = createTextComponent(HtmlElements.H6, textStyles.h6section);
8082
export const P = createTextComponent(HtmlElements.P, textStyles.p);
8183
export const Headline = createTextComponent(HtmlElements.P, textStyles.headline);
8284
export const Caption = createTextComponent(HtmlElements.P, textStyles.caption);

components/Library/TrendingMark.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default function TrendingMark({ library, style, markOnly = false }: Props
3333
/>
3434
<P
3535
style={[
36-
tw`pl-10 font-bold`,
36+
tw`pl-10`,
3737
markOnly ? tw`-my-px text-[15px]` : tw`my-0.5 text-xs`,
3838
{
3939
color: popularityStyles.backgroundColor,

components/Package/CollapsibleSection.tsx

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,37 @@
1-
import { useEffect, useState } from 'react';
2-
import { View } from 'react-native';
3-
import useSWR from 'swr';
1+
import { type PropsWithChildren, type ReactElement, useEffect, useState } from 'react';
2+
import { type StyleProp, View } from 'react-native';
3+
import { type Style } from 'twrnc';
44

5-
import { H6 } from '~/common/styleguide';
5+
import { H6Section } from '~/common/styleguide';
66
import { Button } from '~/components/Button';
77
import { Arrow } from '~/components/Icons';
8-
import { type PeerDependencyData } from '~/types';
9-
import { TimeRange } from '~/util/datetime';
108
import tw from '~/util/tailwind';
119

12-
import DependencyRow from './DependencyRow';
1310
import EntityCounter from './EntityCounter';
1411

15-
type Props = {
12+
type Props = PropsWithChildren<{
1613
title: string;
17-
data?: Record<string, string | PeerDependencyData> | null;
18-
checkExistence?: boolean;
19-
};
14+
count?: number;
15+
rightSlot?: ReactElement;
16+
headerStyle?: StyleProp<Style>;
17+
}>;
2018

21-
export default function CollapsibleSection({ title, data, checkExistence }: Props) {
19+
export default function CollapsibleSection({
20+
title,
21+
count,
22+
rightSlot,
23+
headerStyle,
24+
children,
25+
}: Props) {
2226
const sectionKey = sanitizeTitle(title);
2327
const key = `@ReactNativeDirectory:PackageSectionCollapsed:${sectionKey}`;
24-
const noData = !data || Object.keys(data).length === 0;
2528

2629
const [collapsed, setCollapsed] = useState<boolean>(Boolean(window.localStorage.getItem(key)));
2730

28-
const { data: checkData } = useSWR(
29-
checkExistence && !noData
30-
? `/api/library?name=${Object.keys(data).join(',')}&check=true`
31-
: null,
32-
(url: string) => fetch(url).then(res => res.json()),
33-
{
34-
dedupingInterval: TimeRange.HOUR * 1000,
35-
revalidateOnFocus: false,
36-
}
37-
);
38-
3931
useEffect(() => {
4032
setCollapsed(window.localStorage.getItem(key) === 'true');
4133
}, [key]);
4234

43-
if (noData) {
44-
return null;
45-
}
46-
4735
async function toggleSection() {
4836
const nextState = !collapsed;
4937
setCollapsed(nextState);
@@ -53,10 +41,11 @@ export default function CollapsibleSection({ title, data, checkExistence }: Prop
5341
return (
5442
<>
5543
<View style={tw`flex-row items-center justify-between gap-1.5`}>
56-
<H6 style={tw`flex items-center gap-1.5 text-[16px] text-secondary`}>
44+
<H6Section style={[tw`flex items-center gap-1.5`, headerStyle]}>
5745
{title}
58-
<EntityCounter count={Object.keys(data).length} />
59-
</H6>
46+
{count && <EntityCounter count={count} />}
47+
</H6Section>
48+
{!collapsed ? rightSlot : undefined}
6049
<Button
6150
onPress={toggleSection}
6251
style={tw`bg-palette-gray2 p-1 dark:bg-palette-gray7`}
@@ -65,20 +54,7 @@ export default function CollapsibleSection({ title, data, checkExistence }: Prop
6554
<Arrow style={[tw`h-3 w-4 text-icon`, collapsed ? tw`rotate-90` : tw`rotate-270`]} />
6655
</Button>
6756
</View>
68-
{!collapsed && (
69-
<View>
70-
{Object.entries(data)
71-
.sort(([aName], [bName]) => aName.localeCompare(bName))
72-
.map(([name, depData]) => (
73-
<DependencyRow
74-
key={`${sectionKey}-${name}`}
75-
name={name}
76-
data={depData}
77-
packageExists={checkData?.[name]}
78-
/>
79-
))}
80-
</View>
81-
)}
57+
{!collapsed && <View>{children}</View>}
8258
</>
8359
);
8460
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import useSWR from 'swr';
2+
3+
import CollapsibleSection from '~/components/Package/CollapsibleSection';
4+
import { type PeerDependencyData } from '~/types';
5+
import { TimeRange } from '~/util/datetime';
6+
7+
import DependencyRow from './DependencyRow';
8+
9+
type Props = {
10+
title: string;
11+
data?: Record<string, string | PeerDependencyData> | null;
12+
checkExistence?: boolean;
13+
};
14+
15+
export default function DependenciesSection({ title, data, checkExistence }: Props) {
16+
const noData = !data || Object.keys(data).length === 0;
17+
18+
const { data: checkData } = useSWR(
19+
checkExistence && !noData
20+
? `/api/library?name=${Object.keys(data).join(',')}&check=true`
21+
: null,
22+
(url: string) => fetch(url).then(res => res.json()),
23+
{
24+
dedupingInterval: TimeRange.HOUR * 1000,
25+
revalidateOnFocus: false,
26+
}
27+
);
28+
29+
if (noData) {
30+
return null;
31+
}
32+
33+
return (
34+
<CollapsibleSection title={title} count={Object.keys(data).length}>
35+
{Object.entries(data)
36+
.sort(([aName], [bName]) => aName.localeCompare(bName))
37+
.map(([name, depData]) => (
38+
<DependencyRow
39+
key={`${title.toLocaleLowerCase()}-${name}`}
40+
name={name}
41+
data={depData}
42+
packageExists={checkData?.[name]}
43+
/>
44+
))}
45+
</CollapsibleSection>
46+
);
47+
}

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`h-4.5 mt-[3px] rounded-xl bg-palette-gray2 px-1.5 py-0.5 text-[11px] text-[inherit] dark:bg-accented`,
16+
tw`h-4.5 mt-[3px] rounded-xl bg-palette-gray2 px-1.5 py-0.5 text-[11px] tabular-nums text-[inherit] dark:bg-accented`,
1717
style,
1818
]}>
1919
{count}

components/Package/MorePackagesBox.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { useMemo } from 'react';
66
import { View } from 'react-native';
77
import useSWR from 'swr';
88

9-
import { A, Caption, H6, Label, useLayout } from '~/common/styleguide';
9+
import { A, Caption, H6Section, Label, useLayout } from '~/common/styleguide';
1010
import { Download, Star, Warning } from '~/components/Icons';
1111
import Tooltip from '~/components/Tooltip';
1212
import { type APIResponseType, type LibraryType } from '~/types';
@@ -52,21 +52,17 @@ export default function MorePackagesBox({ library }: Props) {
5252

5353
return (
5454
<>
55-
<H6
56-
style={[
57-
tw`flex items-center gap-1.5 text-[16px] text-secondary`,
58-
!isSmallScreen && tw`mt-4`,
59-
]}>
55+
<H6Section style={[tw`flex items-center gap-1.5`, !isSmallScreen && tw`mt-4`]}>
6056
More packages from {startCase(owner)}
6157
{!isLoading && data?.total && data.total > 0 ? (
6258
<EntityCounter count={data.total > LIMIT ? data.total : data.total - 1} />
6359
) : null}
6460
{!isSmallScreen && data?.total && data.total > LIMIT && (
6561
<A href={`/packages?owner=${encodeURI(owner)}`} style={tw`ml-auto`}>
66-
<Caption style={tw`font-light`}>See all packages</Caption>
62+
<Label style={tw`font-light`}>See all packages</Label>
6763
</A>
6864
)}
69-
</H6>
65+
</H6Section>
7066
{!data || isLoading ? (
7167
<ThreeDotsLoader />
7268
) : (

components/Package/TopicsSection.tsx

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { useState } from 'react';
22
import { View } from 'react-native';
33

4-
import { A, H6, Label } from '~/common/styleguide';
4+
import { A, Label } from '~/common/styleguide';
55
import { Button } from '~/components/Button';
6-
import EntityCounter from '~/components/Package/EntityCounter';
6+
import CollapsibleSection from '~/components/Package/CollapsibleSection';
77
import tw from '~/util/tailwind';
88

99
type Props = {
@@ -23,19 +23,20 @@ export default function TopicsSection({ topics }: Props) {
2323
const trimmedTopics = hasManyTopics && !expanded ? topics.slice(0, MAX_TOPICS) : topics;
2424

2525
return (
26-
<>
27-
<H6 style={tw`-mb-0.5 flex min-h-[25px] items-center gap-1.5 text-[16px] text-secondary`}>
28-
Topics
29-
<EntityCounter count={topics.length} />
30-
{hasManyTopics && !expanded && (
26+
<CollapsibleSection
27+
title="Topics"
28+
count={topics.length}
29+
headerStyle={tw`-mb-0.5 min-h-[25px]`}
30+
rightSlot={
31+
hasManyTopics && !expanded ? (
3132
<Button
3233
containerStyle={tw`ml-auto`}
3334
style={tw`border border-default bg-default px-2 py-1`}
3435
onPress={() => setExpanded(true)}>
35-
<Label>Show All</Label>
36+
<Label style={tw`text-[10px]`}>Show All</Label>
3637
</Button>
37-
)}
38-
</H6>
38+
) : undefined
39+
}>
3940
<View style={tw`flex-row flex-wrap items-start gap-x-2 gap-y-0.5`}>
4041
{trimmedTopics.map(topic => (
4142
<A key={topic} href={`/packages?search=${topic}`} style={tw`text-[12px] font-light`}>
@@ -48,6 +49,6 @@ export default function TopicsSection({ topics }: Props) {
4849
</Label>
4950
)}
5051
</View>
51-
</>
52+
</CollapsibleSection>
5253
);
5354
}

components/Package/VersionsSection.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useEffect, useMemo, useRef, useState } from 'react';
33
import { type ColorValue, TextInput, View } from 'react-native';
44
import { useDebouncedCallback } from 'use-debounce';
55

6-
import { Caption, H6, Label, useLayout } from '~/common/styleguide';
6+
import { Caption, H6Section, Label, useLayout } from '~/common/styleguide';
77
import { Button } from '~/components/Button';
88
import { Search } from '~/components/Icons';
99
import InputKeyHint from '~/components/InputKeyHint';
@@ -73,15 +73,15 @@ export default function VersionsSection({ registryData, npmDownloads }: Props) {
7373

7474
return (
7575
<>
76-
<H6 style={tw`mt-3 flex items-end justify-between text-secondary`}>
76+
<H6Section style={tw`mt-3 flex items-end justify-between text-secondary`}>
7777
<span>Versions</span>
7878
<Label style={tw`font-light text-secondary`}>
7979
<span style={tw`font-medium text-primary-darker dark:text-primary-dark`}>
8080
{filteredVersions.length}
8181
</span>{' '}
8282
matching {pluralize('version', filteredVersions.length)}
8383
</Label>
84-
</H6>
84+
</H6Section>
8585
<View style={tw`gap-2`}>
8686
<View
8787
style={tw`flex-row items-center rounded-lg border-2 border-default bg-palette-gray1 dark:bg-dark`}>

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@
7272
"next-compose-plugins": "^2.2.1",
7373
"next-fonts": "^1.5.1",
7474
"next-images": "^1.8.5",
75-
"oxfmt": "^0.40.0",
76-
"oxlint": "^1.55.0",
77-
"oxlint-tsgolint": "^0.16.0",
75+
"oxfmt": "^0.41.0",
76+
"oxlint": "^1.56.0",
77+
"oxlint-tsgolint": "^0.17.0",
7878
"simple-git-hooks": "^2.13.1",
7979
"typescript": "^5.9.3",
8080
"user-agent-data-types": "^0.4.2"

0 commit comments

Comments
 (0)