Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions common/styleguide.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import * as HtmlElements from '@expo/html-elements';
import { type TextProps } from '@expo/html-elements/build/primitives/Text';
import Link from 'next/link';
import { type ComponentType, type CSSProperties, type PropsWithChildren, useState } from 'react';
import {
type ComponentType,
type CSSProperties,
type PropsWithChildren,
type Ref,
useState,
} from 'react';
import {
Pressable,
type PressableProps,
Expand Down Expand Up @@ -91,6 +97,7 @@ type AProps = PropsWithChildren<{
hoverStyle?: StyleProp<Style>;
containerStyle?: CSSProperties;
role?: Role;
ref?: Ref<HTMLAnchorElement>;
}>;

export function A({
Expand All @@ -101,6 +108,7 @@ export function A({
hoverStyle,
containerStyle,
role,
ref,
...rest
}: AProps) {
const [isHovered, setIsHovered] = useState(false);
Expand All @@ -116,6 +124,7 @@ export function A({
return (
<Link
{...rest}
ref={ref}
href={href}
onPointerEnter={() => setIsHovered(true)}
onPointerLeave={() => setIsHovered(false)}
Expand All @@ -137,6 +146,7 @@ export function A({
style={{ ...tw`contents`, ...containerStyle }}>
<HtmlElements.A
{...rest}
ref={ref as any}
href={href}
numberOfLines={containerStyle ? 1 : undefined}
target={target ?? '_blank'}
Expand Down Expand Up @@ -167,7 +177,7 @@ export function HoverEffect({
<Pressable
style={({ hovered, pressed }) => [
tw`-outline-offset-2`,
{ transition: 'opacity 0.33s' },
{ transition: 'all 0.33s' },
style,
hovered && (hoveredStyle ?? tw`opacity-75`),
pressed && (pressedStyle ?? tw`opacity-50`),
Expand Down
71 changes: 71 additions & 0 deletions components/AddLibrarySelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import * as Popover from '@radix-ui/react-popover';
import { useRef, useState } from 'react';
import { View } from 'react-native';

import { A, HoverEffect, P, useLayout } from '~/common/styleguide';
import { ArrowUpRightIcon, PlusIcon } from '~/components/Icons';
import SelectorItemHoverEffect from '~/components/Selector/SelectorItemHoverEffect';
import tw from '~/util/tailwind';

export default function AddLibrarySelector() {
const { isSmallScreen } = useLayout();

const [open, setOpen] = useState(false);
const firstOptionRef = useRef<HTMLAnchorElement>(null);

return (
<Popover.Root open={open} onOpenChange={state => setOpen(state)}>
<HoverEffect>
<Popover.Trigger asChild>
<View>
<View
role="button"
style={[
tw`cursor-pointer select-none items-center justify-center rounded bg-primary-darker outline-offset-1 dark:bg-primary-dark`,
tw`max-h-8.5 flex-row items-center gap-1 px-4 py-2`,
isSmallScreen && tw`w-8.5 px-0`,
]}>
<PlusIcon style={[tw`size-3.5 text-white`, !isSmallScreen && tw`-ml-0.5`]} />
{!isSmallScreen && <P style={tw`ml-1 text-white`}>Add a library</P>}
</View>
</View>
</Popover.Trigger>
</HoverEffect>
<Popover.Portal>
<Popover.Content
align="center"
sideOffset={6}
alignOffset={4}
onOpenAutoFocus={event => {
event.preventDefault();
firstOptionRef.current?.focus();
}}>
<View
style={tw`w-40 overflow-hidden rounded-lg border-2 border-secondary bg-palette-gray7 py-0.5 dark:border-default dark:bg-default`}>
<SelectorItemHoverEffect
focusable={false}
hoveredStyle={tw`bg-[#2a2e36] dark:bg-palette-gray7`}>
<A
ref={firstOptionRef}
style={tw`flex items-center justify-between rounded-lg px-2.5 py-1.5 text-white no-underline -outline-offset-2`}
href="https://github.com/react-native-community/directory/?tab=readme-ov-file#how-do-i-add-a-library">
Add manually
<ArrowUpRightIcon style={tw`size-3.5 text-icon`} />
</A>
</SelectorItemHoverEffect>
<SelectorItemHoverEffect
focusable={false}
hoveredStyle={tw`bg-[#2a2e36] dark:bg-palette-gray7`}>
<A
style={tw`flex items-center justify-between rounded-lg px-2.5 py-1.5 text-white no-underline -outline-offset-2`}
href="https://github.com/simek/rn-directory?tab=readme-ov-file#rn-directory">
Add via CLI
<ArrowUpRightIcon style={tw`size-3.5 text-icon`} />
</A>
</SelectorItemHoverEffect>
</View>
</Popover.Content>
</Popover.Portal>
</Popover.Root>
);
}
26 changes: 26 additions & 0 deletions components/Icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1773,3 +1773,29 @@ export function MarkdownPreviewIcon({ style }: IconProps) {
</Svg>
);
}

export function ArrowUpRightIcon({ style }: IconProps) {
return (
<Svg viewBox="0 0 256 256" style={[tw`size-6`, style]}>
<Line
x1="64"
y1="192"
x2="192"
y2="64"
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
/>
<Polyline
points="88 64 192 64 192 168"
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
/>
</Svg>
);
}
81 changes: 47 additions & 34 deletions components/Package/CodeBrowser/PackageVersionSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { type ColorValue, ScrollView, TextInput, View } from 'react-native';
import useSWR from 'swr';
import { useDebounce } from 'use-debounce';

import { Label } from '~/common/styleguide';
import { HoverEffect, Label } from '~/common/styleguide';
import { ArrowIcon } from '~/components/Icons';
import ThreeDotsLoader from '~/components/Package/ThreeDotsLoader';
import SelectorGroupHeader from '~/components/Selector/SelectorGroupHeader';
Expand Down Expand Up @@ -78,30 +78,41 @@ export default function PackageVersionSelector({

return (
<Popover.Root open={open} onOpenChange={handleOpenChange}>
<Popover.Trigger asChild>
<View
role="button"
style={tw`min-h-8 w-[180px] cursor-pointer justify-center overflow-hidden rounded-lg border border-palette-gray2 bg-default px-2 dark:border-default dark:bg-dark`}>
{isLoading ? (
<View style={tw`scale-75 text-center`}>
<ThreeDotsLoader />
</View>
) : (
<View style={tw`flex-row items-center justify-between gap-1.5`}>
<Label numberOfLines={1} style={tw`select-none text-[13px]`}>
{selectedVersion}
</Label>
<ArrowIcon
style={[tw`h-3 w-4 shrink-0 text-icon`, open ? tw`rotate-270` : tw`rotate-90`]}
/>
</View>
)}
</View>
</Popover.Trigger>
<HoverEffect
hoveredStyle={tw`border-palette-gray3 dark:border-[#333842]`}
pressedStyle={tw`opacity-100`}
style={tw`border-palette-gray2 dark:border-default`}>
<Popover.Trigger asChild>
<View
role="button"
style={tw`min-h-8 w-[180px] cursor-pointer justify-center overflow-hidden rounded-lg border border-[inherit] bg-default px-2 dark:bg-dark`}>
{isLoading ? (
<View style={tw`scale-75 text-center`}>
<ThreeDotsLoader />
</View>
) : (
<View style={tw`flex-row items-center justify-between gap-1.5`}>
<Label numberOfLines={1} style={tw`select-none text-[13px]`}>
{selectedVersion}
</Label>
<ArrowIcon
style={[
tw`h-3 w-4 shrink-0 text-icon`,
open
? tw`rotate-270 text-primary-darker dark:text-primary-dark`
: tw`rotate-90`,
{ transition: 'all 0.2s' },
]}
/>
</View>
)}
</View>
</Popover.Trigger>
</HoverEffect>
<Popover.Portal>
<Popover.Content align="end" sideOffset={6}>
<Popover.Content align="center" sideOffset={6}>
<View
style={tw`w-56 overflow-hidden rounded-lg border border-palette-gray2 bg-default shadow-lg dark:border-default`}>
style={tw`max-w-68 min-w-32 overflow-hidden rounded-lg border-2 border-palette-gray2 bg-default shadow-lg dark:border-default`}>
<View style={tw`border-b border-palette-gray2 dark:border-default`}>
<TextInput
ref={inputRef}
Expand All @@ -119,7 +130,7 @@ export default function PackageVersionSelector({
/>
</View>
<ScrollView
style={tw`max-h-76`}
style={tw`max-h-76 pb-0.5`}
focusable={false}
keyboardShouldPersistTaps="handled"
id="dropdown-list">
Expand All @@ -128,14 +139,16 @@ export default function PackageVersionSelector({
<SelectorGroupHeader>Dist tags</SelectorGroupHeader>
{filteredDistTags.map(([tag, version]) => (
<SelectorItemHoverEffect key={tag} onPressIn={() => handleSelect(tag)}>
<Label
style={[
tw`text-[inherit]`,
selectedVersion === tag && tw`text-primary-darker dark:text-primary`,
]}>
{tag}
</Label>
<Label style={tw`text-[10px] font-thin text-secondary`}>{version}</Label>
<View style={tw`px-2.5 py-1.5`}>
<Label
style={[
tw`text-[inherit]`,
selectedVersion === tag && tw`text-primary-darker dark:text-primary`,
]}>
{tag}
</Label>
<Label style={tw`text-[10px] font-thin text-secondary`}>{version}</Label>
</View>
</SelectorItemHoverEffect>
))}
{filteredVersions.length > 0 && (
Expand All @@ -150,7 +163,7 @@ export default function PackageVersionSelector({
<SelectorItemHoverEffect key={version} onPressIn={() => handleSelect(version)}>
<Label
style={[
tw`text-[inherit]`,
tw`px-2.5 py-1.5 text-[inherit]`,
selectedVersion === version && tw`text-primary-darker dark:text-primary`,
]}>
{version}
Expand All @@ -160,7 +173,7 @@ export default function PackageVersionSelector({
</>
)}
{filteredVersions.length === 0 && !filteredDistTags && (
<View style={tw`px-3 py-2`}>
<View style={tw`px-2.5 py-3`}>
<Label style={tw`text-center font-thin text-secondary`}>No versions match</Label>
</View>
)}
Expand Down
2 changes: 1 addition & 1 deletion components/Selector/SelectorGroupHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import tw from '~/util/tailwind';

export default function SelectorGroupHeader({ children }: PropsWithChildren) {
return (
<View style={tw`px-3 pt-2`}>
<View style={tw`px-2.5 pt-1.5`}>
<Caption style={tw`text-[11px] font-thin uppercase text-palette-gray4 dark:text-tertiary`}>
{children}
</Caption>
Expand Down
14 changes: 11 additions & 3 deletions components/Selector/SelectorItemHoverEffect.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { type PressableProps } from 'react-native';
import { type Style } from 'twrnc';

import { HoverEffect } from '~/common/styleguide';
import tw from '~/util/tailwind';

export default function SelectorItemHoverEffect({ children, ...rest }: PressableProps) {
type Props = PressableProps & {
hoveredStyle?: Style;
};

export default function SelectorItemHoverEffect({ children, hoveredStyle, ...rest }: Props) {
return (
<HoverEffect
style={tw`cursor-pointer px-3 py-1.5 text-black dark:text-white`}
hoveredStyle={tw`bg-palette-gray2 dark:bg-palette-gray7`}
style={[
tw`mx-0.5 cursor-pointer rounded text-black dark:text-white`,
{ transition: 'background-color 0.2s' },
]}
hoveredStyle={hoveredStyle ?? tw`bg-palette-gray2 dark:bg-palette-gray7`}
focusable
{...rest}>
{children}
Expand Down
15 changes: 4 additions & 11 deletions components/TopBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import { Header as HtmlHeader } from '@expo/html-elements';
import { useContext } from 'react';
import { View } from 'react-native';

import { A, H5, P, useLayout } from '~/common/styleguide';
import { A, H5, useLayout } from '~/common/styleguide';
import AddLibrarySelector from '~/components/AddLibrarySelector';
import ContentContainer from '~/components/ContentContainer';
import NavigationTab from '~/components/NavigationTab';
import CustomAppearanceContext from '~/context/CustomAppearanceContext';
import tw from '~/util/tailwind';

import { Button } from './Button';
import { GitHubIcon, Logo, PlusIcon, ThemeDarkIcon, ThemeLightIcon, ToolsIcon } from './Icons';
import { GitHubIcon, Logo, ThemeDarkIcon, ThemeLightIcon, ToolsIcon } from './Icons';
import Tooltip from './Tooltip';

export default function TopBar() {
Expand Down Expand Up @@ -87,15 +88,7 @@ export default function TopBar() {
}>
GitHub
</Tooltip>
<Button
openInNewTab
href="https://github.com/react-native-community/directory/?tab=readme-ov-file#how-do-i-add-a-library"
style={[tw`max-h-8.5 px-4 py-2`, isSmallScreen && tw`w-8.5`]}>
<View style={tw`flex-row items-center gap-1`}>
<PlusIcon style={[tw`size-3.5 text-white`, !isSmallScreen && tw`-ml-0.5`]} />
{!isSmallScreen && <P style={tw`ml-1 text-white`}>Add a library</P>}
</View>
</Button>
<AddLibrarySelector />
</View>
</View>
<ContentContainer style={[tw`flex-row gap-2.5 px-4`, !isSmallScreen && tw`hidden`]}>
Expand Down