npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gaozh1024/photo-album-picker

v0.2.0

Published

Photo album picker for Expo / React Native with grid picker, preview and crop flow.

Readme

@gaozh1024/photo-album-picker

Expo / React Native 相册选择组件包,内置网格选择、全屏预览和图片裁剪流程。

适合聊天发送图片、头像裁剪、发布页多图选择等场景。

✨ 包含能力

  • PhotoAlbumButton:开箱即用的相册按钮入口
  • PhotoAlbumGrid:相册网格选择组件
  • usePhotoAlbum:相册数据加载与选择状态管理 hook
  • PhotoAlbumScreen:完整相册页面
  • PhotoCropScreen:图片裁剪页面
  • MEDIA_PICKER_ROUTES:默认路由名常量
  • normalizeOpenOptions / resolveMediaTypes / createCroppedPhotoAlbumItem

📦 安装

pnpm add @gaozh1024/photo-album-picker

当前兼容基线

当前版本按 Expo SDK 54 验证,推荐依赖基线:

  • expo: ~54.0.33
  • expo-image: ~3.0.11
  • expo-image-manipulator: ~14.0.8
  • expo-media-library: ~18.2.1

当前 npm 包版本:0.2.0

必需依赖

这个包本身依赖以下库:

pnpm add @gaozh1024/rn-kit
pnpm add @react-navigation/native @shopify/flash-list
npx expo install expo-image expo-image-manipulator expo-media-library
npx expo install react-native-safe-area-context react-native-gesture-handler react-native-reanimated
pnpm add react-native-zoom-toolkit

请优先使用 npx expo install 安装 Expo 官方包,让 Expo 根据当前 SDK 自动选择兼容版本;不要手动把 expo-image-manipulator 升到 55.x,否则在 Expo 54 项目里可能出现原生不兼容。

Expo 54 推荐安装示例

pnpm add @gaozh1024/photo-album-picker@^0.2.0
pnpm add @gaozh1024/rn-kit @react-navigation/native @shopify/flash-list
npx expo install expo-image expo-image-manipulator expo-media-library
npx expo install react-native-safe-area-context react-native-gesture-handler react-native-reanimated
pnpm add react-native-zoom-toolkit

哪些库是必须的?

直接必需

  • @gaozh1024/rn-kit
  • @react-navigation/native
  • @shopify/flash-list
  • expo-image
  • expo-image-manipulator
  • expo-media-library
  • react-native-safe-area-context
  • react-native-zoom-toolkit

间接必需

react-native-zoom-toolkit 依赖:

  • react-native-gesture-handler
  • react-native-reanimated

如果你的项目已经在使用 @gaozh1024/rn-kit,通常这几个基础依赖已经存在;但接入 @gaozh1024/photo-album-picker 时仍建议确认版本兼容。

版本兼容与排障

Expo SDK 54

当前版本按 Expo SDK 54 验证,裁剪能力依赖的 expo-image-manipulator 必须使用 14.x

如果你在 Expo 54 项目里手动安装了 [email protected],可能在裁剪时看到类似错误:

Error: Call to function 'ExpoImageManipulator.manipulate' has been rejected.
Caused by: java.lang.NoSuchMethodError

处理方式:

npx expo install expo-image-manipulator

不要使用 npm install --legacy-peer-deps 去掩盖这个问题;正确做法是让 Expo 官方依赖回到和当前 SDK 一致的版本。

权限与 Expo 配置

1. 配置 expo-media-library plugin

app.json 中加入:

{
  "expo": {
    "plugins": [
      [
        "expo-media-library",
        {
          "photosPermission": "允许访问相册以选择图片或视频"
        }
      ]
    ]
  }
}

2. 重新生成原生工程

如果你的项目使用 Expo prebuild / dev build:

npx expo prebuild

或重新运行:

npx expo run:ios
npx expo run:android

🚀 最小接入方式

第一步:注册路由

import { StackNavigator } from '@gaozh1024/rn-kit';
import {
  MEDIA_PICKER_ROUTES,
  PhotoAlbumScreen,
  PhotoCropScreen,
} from '@gaozh1024/photo-album-picker';

export function RootNavigator() {
  return (
    <StackNavigator screenOptions={{ headerShown: false }}>
      {/* 你的业务页面 */}

      <StackNavigator.Screen
        name={MEDIA_PICKER_ROUTES.PHOTO_ALBUM}
        component={PhotoAlbumScreen}
        options={{ freezeOnBlur: true }}
      />

      <StackNavigator.Screen
        name={MEDIA_PICKER_ROUTES.PHOTO_CROP}
        component={PhotoCropScreen}
        options={{
          animation: 'none',
          detachPreviousScreen: false,
          gestureEnabled: false,
          freezeOnBlur: true,
        }}
      />
    </StackNavigator>
  );
}

如果你不会用裁剪流程,也可以先只注册 PhotoAlbumScreen;但推荐两个页面都注册好,后续开启 crop 时无需再改导航。

第二步:页面里调用按钮

import { PhotoAlbumButton } from '@gaozh1024/photo-album-picker';

function ChatToolbar() {
  return (
    <PhotoAlbumButton
      buttonText="选择图片"
      options={{
        maxSelection: 9,
        mediaType: 'all',
      }}
      onPhotosSelected={photos => {
        console.log('selected photos', photos);
      }}
    />
  );
}

🧩 常见用法

1. 只选图片

<PhotoAlbumButton
  onPhotosSelected={handlePhotosSelected}
  options={{
    maxSelection: 9,
    mediaType: 'photo',
  }}
/>

2. 只选视频

<PhotoAlbumButton
  onPhotosSelected={handleVideosSelected}
  options={{
    maxSelection: 1,
    mediaType: 'video',
    maxVideoDuration: 60,
  }}
/>

3. 单图裁剪

<PhotoAlbumButton
  onPhotosSelected={photos => {
    const [photo] = photos;
    console.log('cropped photo', photo);
  }}
  options={{
    crop: {
      aspect: [1, 1],
      shape: 'rect',
      quality: 1,
    },
  }}
/>

crop 开启后会自动收敛为:

  • mediaType = 'photo'
  • maxSelection = 1
  • allowsMultipleSelection = false

4. 自定义路由名

<PhotoAlbumButton
  onPhotosSelected={handlePhotosSelected}
  routeNames={{
    photoAlbum: 'MyPhotoAlbum',
    photoCrop: 'MyPhotoCrop',
  }}
/>

同时你也要在导航里注册同名页面。

🖼️ 直接使用网格组件

import { PhotoAlbumGrid } from '@gaozh1024/photo-album-picker';

function AlbumBody() {
  return (
    <PhotoAlbumGrid
      maxSelection={9}
      allowsMultipleSelection
      onComplete={photos => {
        console.log('done', photos);
      }}
      onCancel={() => {
        console.log('cancel');
      }}
      onSelectionChange={photos => {
        console.log('selection change', photos.length);
      }}
    />
  );
}

🪝 使用底层 hook

import { usePhotoAlbum } from '@gaozh1024/photo-album-picker';

function CustomAlbumView() {
  const {
    photos,
    loading,
    hasMore,
    selectedCount,
    toggleSelection,
    loadMore,
    refresh,
    getSelectedPhotos,
  } = usePhotoAlbum({
    initialLoadCount: 60,
    loadMoreCount: 40,
    mediaType: ['photo', 'video'],
  });

  return null;
}

📚 主要类型

import type {
  PhotoAlbumItem,
  PhotoAlbumOpenOptions,
  PhotoAlbumCropOptions,
  PhotoAlbumButtonProps,
  PhotoAlbumGridProps,
  MediaPickerRouteNames,
  PhotoAlbumRouteParams,
  PhotoCropRouteParams,
  DefaultPhotoAlbumParamList,
} from '@gaozh1024/photo-album-picker';

默认路由名

MEDIA_PICKER_ROUTES.PHOTO_ALBUM; // 'PhotoAlbum'
MEDIA_PICKER_ROUTES.PHOTO_CROP; // 'PhotoCrop'

⚠️ 注意事项

  1. 这个包依赖 React Navigation 页面跳转,不是纯函数式 picker。
  2. 开启裁剪能力时,需要同时接入 PhotoCropScreen
  3. expo-media-library 权限没配好时,组件会停留在权限申请界面。
  4. 视频时长限制通过 maxVideoDuration 控制,单位是秒。
  5. 当前裁剪流程只支持图片,不支持视频裁剪。

🛠️ 本地开发

pnpm --filter @gaozh1024/photo-album-picker typecheck
pnpm --filter @gaozh1024/photo-album-picker build