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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@hadss/react_native_folderstack

v1.0.0-rc.2

Published

这是一个旨在解决 React Native多设备适配问题的三方库,专为不同设备类型(包括折叠屏、平板、手机等)提供了便捷的支持。该库包含的接口和开箱即用的组件,使开发者能够轻松应对各种设备的布局适配需求。

Readme

@hadss/react_native_folderstack

介绍

这是一个旨在解决 React Native多设备适配问题的三方库,专为不同设备类型(包括折叠屏、平板、手机等)提供了便捷的支持。该库包含的接口和开箱即用的组件,使开发者能够轻松应对各种设备的布局适配需求。

目前该库提供的组件如下:

  1. 折叠屏相关组件:基于ArkUI折叠屏相关接口开发的RN获取折叠屏信息的接口,包括折叠屏状态、是否是折叠屏、折叠屏避让区域信息及监听折叠屏变化等能力。
  2. 自适应显隐容器:对标ArkUI的自适应显隐布局开发的容器,使开发者能够轻松的完成自适应显隐布局能力的开发。
  3. 侧边栏组件:对标ArkUI的SideBarContainer组件开发的RN侧边栏组件,使开发者能够轻松的完成侧边栏相关布局能力的开发。
  4. 自适应分栏组件:参考ArkUI的Navigation组件开发的RN分栏组件,使开发者能够轻松的完成分栏及路由跳转能力的开发。
  5. 栅格组件:对标ArkUI的GridRow/GridCol开发的RN栅格组件,提供基础的栅格布局能力,使开发能够直接使用ArkUI栅格布局能力。

工程目录

.
├─harmony
│  ├─folder_stack.har                             // Turbo Modules接口har包
│  └─folder_stack
│     └─src/main/ets
│        ├─FolderStackModule.ets                  // Turbo Modules接口ArkTS实现
│        ├─FolderStackModulePackage.ets           // FolderStackModulesFactory
│        ├─FolderStackModuleSpec.ts               // Turbo Modules接口,提供折叠屏相关接口
│        └─core
│           └─FoldConfig.ts   
├─src
│  ├─index.ts                                // RN模块导出
│  ├─component
│  │  ├─FoldSplitContainer                   // 折叠屏高阶组件FoldSplitContainer
|  |  └─FoldStack                   		     // 折叠屏高阶组件FoldStack
│  ├─turbo
│  |   └─FolderStackModule.ts                // Turbo Modules接口
│  └─utils
│     ├─FoldUtils                            // 封装折叠屏相关接口
│     └─ThrottleUtils                        //  节流(throttle)函数的 TypeScript 实现,用于限制某个函数的执行频率,确保它在指定的时间间隔内最多执行一次。

安装与使用

进入到工程目录并输入以下命令:

npm

npm install @hadss/react_native_folderstack

yarn

yarn add @hadss/react_native_folderstack

下面的代码展示了这个库的基本使用场景:

FoldSplitContainer使用示例

import { Fold, ExpandedRegionLayoutOptions, ExtraRegionPosition, HoverModeRegionLayoutOptions, FoldSplitContainer } from "@hadss/react_native_folderstack";
import React, { useState, useEffect } from "react";
import { View, Text, Button, StyleSheet } from "react-native";

const TestSample = () => {
    const [foldCreaseRegion, setFoldCreaseRegion] = useState<number[]>([]);
    const [foldStatus, setFoldStatus] = useState('');
    const [isDeviceFoldable, setIsDeviceFoldable] = useState(false);
  
    useEffect(() => {
      const checkFoldable = () => {
        // 判断当前设备是否可折叠
        const foldable = Fold.isFoldable();
        setIsDeviceFoldable(foldable);
        if (foldable) {
          // 获取折痕区域
          setFoldCreaseRegion(Fold?.getFoldCreaseRegion()==null ?[]:Fold?.getFoldCreaseRegion()[0]);
          
          // 获取当前折叠屏状态
          setFoldStatus(Fold.getFoldStatus());
        }
      };
  
      checkFoldable();
  
      // 监听折叠屏状态变化
      Fold.addFoldListener((foldStatus) => {
        console.log('折叠屏状态发生变化', foldStatus);
      });
  
      return () => {
        // 销毁监听折叠屏状态变化
        Fold.removeFoldListener();
      };
    }, []);
  
    const handleGetFoldStatus = () => {
      if (isDeviceFoldable) {
        // 获取当前折叠屏状态
        setFoldStatus(Fold.getFoldStatus());
      }
    };
    
    // FoldSplitContainer 主要区域
    const primaryRender = () => (
      <View style={{ flex: 1 }}>
        <Text>Is Device Foldable: {isDeviceFoldable ? 'Yes' : 'No'}</Text>
  
        {isDeviceFoldable && (
          <>
            <Text>Fold Crease Region: {JSON.stringify(foldCreaseRegion)}</Text>
            <Button title="Get Fold Status" onPress={handleGetFoldStatus} />
            {foldStatus && <Text>Fold Status: {foldStatus}</Text>}
          </>
        )}
      </View>
    );
  
    // FoldSplitContainer 次要区域
    const secondRender = () => (
      <View style={{ flex: 1, backgroundColor: 'blue' }}>
        <Text style={{ fontSize: 20 }}>secondRender</Text>
      </View>
    );
  
    // FoldSplitContainer 扩展区域
    const extraRender = () => (
      <View style={{ flex: 1, backgroundColor: 'red' }}>
        <Text style={{ fontSize: 20 }}>extraRender</Text>
      </View>
    );
  
    // 折叠屏展开态配置
    const expandedLayoutOptions: ExpandedRegionLayoutOptions = {
      isExtraRegionPerpendicular: false,
      extraRegionPosition: ExtraRegionPosition.BOTTOM,
    };
  
    // 折叠屏悬停态配置
    const hoverModeRegionLayoutOptions: HoverModeRegionLayoutOptions = {
      showExtraRegion: true,
    };
  
    return (
      <View style={styles.container}>
        <FoldSplitContainer
          primary={primaryRender()}
          secondary={secondRender()}
          extra={extraRender()}
          expandedLayoutOptions={expandedLayoutOptions}
          hoverModeLayoutOptions={hoverModeRegionLayoutOptions}
        />
      </View>
    );
  };
  
  const styles = StyleSheet.create({
    container: {
      flex: 1,
    },
  });
  
  export default TestSample;

FoldStack使用示例

import React from 'react';
import {
  View,
  Text,
  StyleSheet,
} from 'react-native';
import { FolderStack } from '@hadss/react_native_folderstack';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'rgb(39, 135, 217)'
  },
  videoContainer: {
    width: '100%',
    height: '100%',
    justifyContent: 'center',
    backgroundColor: 'rgb(100, 135, 217)'
  },
  videoText: {
    fontSize: 25,
    color: 'white',
    textAlign: 'center'
  },
  controlBar: {
    height: '100%',
    width: '100%',
  },
  controlText: {
    fontSize: 25,
    textAlign: 'center',
    width: '100%',
    height: 50
  }
});


const FolderStackDemo = () => {
  return (
    <View style={[styles.videoContainer]}>
      <FolderStack
        upperItems={["upperitemsId"]}
        enableAnimation={true}
        autoHalfFold={true}
        alignContent='End'
        onFolderStateChange={(foldStatus) => {
          console.log(`onFolderStateChange params is ${JSON.stringify(foldStatus)}`)
        }
        }
        onHoverStatusChange={(HoverStatus) => {
          console.log(`onHoverStatusChange params is ${JSON.stringify(HoverStatus)}`)
        }
        }
      >
        {/* 上半屏视频区域 */}
        <View style={[styles.videoContainer, { backgroundColor: 'rgb(0, 74, 175)' }]} id="upperitemsId">
          <Text style={styles.videoText}>video zone</Text>
        </View>

        {/* 下半屏操作区域 */}
        <View style={[styles.controlBar, { justifyContent: 'flex-start' }]} id="2">
          <Text style={[styles.controlText, { backgroundColor: 'rgb(213, 213, 213)' }]}>video title</Text>
        </View>

        <View style={[styles.controlBar, { justifyContent: 'flex-end', zIndex: 5 }]} id="3">
          <Text style={[styles.controlText, { backgroundColor: 'rgb(213, 213, 213)' }]}>video bar</Text>
        </View>
      </FolderStack>
    </View>
  );
};

export default FolderStackDemo;

Link

本库依赖以下三方库,请查看对应文档:

@react-native-oh-tpl/react-native-orientation

目前OpenHarmony暂不支持AutoLink,所以Link步骤需要手动配置。

首先需要使用DevEco Studio打开项目里的OpenHarmony工程,在工程根目录的oh-package.json5添加overrides字段:

{
  ...
  "overrides": {
    "@rnoh/react-native-openharmony" : "./react_native_openharmony"
  }
}

引入原生端代码

目前有两种方法:

  1. 通过har包引入(在IDE完善相关功能后该方法会被遗弃,目前首选此方法)。

    说明: har包位于三方库安装路径的harmony文件夹下。

    a. 打开entry/oh-package.json5,添加以下依赖:

    "dependencies": {
        "@rnoh/react-native-openharmony": "file:../react_native_openharmony",
        "@hadss/react_native_folderstack": "file:../../node_modules/@hadss/react_native_folderstack/harmony/folder_stack.har",
      }

    b. 配置CMakeLists和引入RNOHGeneratedPackage:

    打开entry/src/main/cpp/CMakeLists.txt,添加:

    project(rnapp)
    cmake_minimum_required(VERSION 3.4.1)
    set(CMAKE_SKIP_BUILD_RPATH TRUE)
    set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
    set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
       
    set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/cpp")
    set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
    set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
    set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
    add_compile_definitions(WITH_HITRACE_SYSTRACE)
    set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
    + file(GLOB GENERATED_CPP_FILES "./generated/*.cpp")
       
    add_subdirectory("${RNOH_CPP_DIR}" ./rn)
       
    add_library(rnoh_app SHARED
    +    ${GENERATED_CPP_FILES}
        "./PackageProvider.cpp"
        "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
    )
       
    target_link_libraries(rnoh_app PUBLIC rnoh)

    c. 打开entry/src/main/cpp/PackageProvider.cpp,添加:

    #include "RNOH/PackageProvider.h"
    + #include "generated/RNOHGeneratedPackage.h"
       
    using namespace rnoh;
       
    std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
        return {
    +        std::make_shared<RNOHGeneratedPackage>(ctx)
        };
    }

    d. 在ArkTs侧引入FolderStackModulePackage:

    打开entry/src/main/ets/RNPackagesFactory.ts,添加:

      ...
    + import { FolderStackModulePackage } from '@hadss/react_native_folderstack/ts';
       
    export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
      return [
    +   new FolderStackModulePackage(ctx),
      ];
    }

    e. 运行:

    点击右上角的sync按钮

    或者在终端执行:

    cd entry
    ohpm install

    然后编译、运行即可。

说明 若项目启动时报错:can not find record '&@rnoh/react-native-openharmony/generated/ts&X.X.X'。需在entry\oh_modules@rnoh\react-native-openharmony\ts.ts文件中添加export * from './generated/ts',并删除.cxx文件夹、build文件夹,然后执行sync操作同步代码。

  1. 直接链接源码。

    如需使用直接链接源码,请参考直接链接源码说明

API

说明: "Platform"列表示支持的平台,All表示支持所有平台。

折叠屏适配

折叠屏接口

| Name | Description | Type | Platform | | ------------------- | ------------------------------------------------------------ | -------- | --------- | | getFoldCreaseRegion | 获取可折叠设备屏幕的折痕区域。 | function | OpenHarmony | | getFoldStatus | 获取当前可折叠设备的状态(例如:展开、半折叠或折叠)。 | function | OpenHarmony | | isFoldable | 判断设备是否可折叠。如果为 true,设备是可折叠的;否则是不可折叠设备。 | function | OpenHarmony | | addFoldListener | 监听折叠设备的折叠状态变化。 | function | OpenHarmony | | removeFoldListener | 移除已添加的折叠状态变化监听。 | function | OpenHarmony |

FoldSplitContainer组件

| Name | Description | Type | Platform | | :--------------------- | :--------------------------------------------- | :--------------------------- | :-------- | | primary | 主要区域回调函数。 | function | OpenHarmony | | secondary | 次要区域回调函数。 | function | OpenHarmony | | extra | 扩展区域回调函数,不传入的情况,没有对应区域。 | function | OpenHarmony | | expandedLayoutOptions | 展开态布局信息。 | ExpandedRegionLayoutOptions | OpenHarmony | | hoverModeLayoutOptions | 悬停态布局信息。 | HoverModeRegionLayoutOptions | OpenHarmony | | foldedLayoutOptions | 折叠态布局信息。 | FoldedRegionLayoutOptions | OpenHarmony | | onHoverStatusChange | 折叠屏进入或退出悬停模式时触发的回调函数。 | onHoverStatusChangeHandler | OpenHarmony |

FoldStack组件

| Name | Description | Type | Platform | | :--------------------- | :--------------------------------------------- | :--------------------------- | :-------- | | upperItems | 主要区域回调函数。 | string[] | OpenHarmony | | enableAnimation | 动画是否开启。 | boolean | OpenHarmony | | alignContent | 布局形式。 | Alignment | OpenHarmony | | autoHalfFold | 自动旋转开关。 | boolean | OpenHarmony | | onFolderStateChange | 折叠屏状态变化触发的回调函数。 | (event: { foldStatus: FoldStatus }) => void | OpenHarmony | | onHoverStatusChange | 折叠屏进入或退出悬停模式时触发的回调函数。 | onHoverStatusChangeHandler | OpenHarmony |

ExpandedRegionLayoutOptions

| Name | Description | Type | Platform | | :------------------------- | :----------------------------------------------------------- | :------------------ | --------- | | isExtraRegionPerpendicular | 扩展区域是否从上到下贯穿整个组件,当且仅当extra有效时此字段才生效。默认值:true。 | boolean | OpenHarmony | | verticalSplitRatio | 主要区域与次要区域之间的高度比例。默认值:PresetSplitRatio.LAYOUT_1V1。 | number | OpenHarmony | | horizontalSplitRatio | 主要区域与扩展区域之间的宽度比例,当且仅当extra有效时此字段才生效。默认值:PresetSplitRatio.LAYOUT_3V2。 | number | OpenHarmony | | extraRegionPosition | 扩展区域的位置信息,当且仅当isExtraRegionPerpendicular = false有效时此字段才生效。默认值:ExtraRegionPosition.top。 | ExtraRegionPosition | OpenHarmony |

HoverModeRegionLayoutOptions

| Name | Description | Type | Platform | | :------------------- | :----------------------------------------------------------- | :------------------ | :-------- | | showExtraRegion | 可折叠屏幕在半折叠状态下是否显示扩展区域。默认值:false。 | boolean | OpenHarmony | | horizontalSplitRatio | 主要区域与扩展区域之间的宽度比例,当且仅当extra有效时此字段才生效。默认值:PresetSplitRatio.LAYOUT_3V2。 | number | OpenHarmony | | extraRegionPosition | 扩展区域的位置信息,当且仅当showExtraRegion时此字段才生效。默认值:ExtraRegionPosition.top。 | ExtraRegionPosition | OpenHarmony |

FoldedRegionLayoutOptions

| Name | Description | Type | Platform | | :----------------- | :----------------------------------------------------------- | :----- | :-------- | | verticalSplitRatio | 主要区域与次要区域之间的高度比例。默认值:PresetSplitRatio.LAYOUT_1V1。 | number | OpenHarmony |

onHoverStatusChangeHandler

| Name | Description | Type | Platform | | :------- | :----------------------------------------- | :-------------------------------- | :-------- | | callback | 折叠屏进入或退出悬停模式时触发的回调函数。 | (status: HoverModeStatus) => void | OpenHarmony |

HoverModeStatus

| Name | Description | Type | Platform | | :---------- | :---------------------- | :--------- | :-------- | | foldStatus | 设备的折叠状态。 | FoldStatus | OpenHarmony | | isHoverMode | app当前是否处于悬停态。 | boolean | OpenHarmony | | appRotation | AppRotation。 | AppRotation | OpenHarmony |

AppRotation

| Name | Description | Value | | :----- | :----------------------- | :---- | | ROTATION_0 | 应用方向为0度。 | 0 | | ROTATION_90 | 应用方向为90度。 | 1 | | ROTATION_180 | 应用方向为180度。 | 2 | | ROTATION_270 | 应用方向为270度。 | 3 |

ExtraRegionPosition

| Name | Description | Value | | :----- | :----------------------- | :---- | | top | 扩展区域在组件上半区域。 | 1 | | bottom | 扩展区域在组件下半区域。 | 2 |

PresetSplitRatio

| Name | Description | Value | | :--------- | :---------- | :---- | | LAYOUT_1V1 | 1:1比例。 | 1/1 | | LAYOUT_3V2 | 3:2比例。 | 3/2 | | LAYOUT_2V3 | 2:3比例。 | 2/3 |

约束与限制

系统与设备:本示例仅支持在标准系统的华为手机上运行。 开发环境:需要DevEco Studio 5.0.1 Release或更高版本。 功能与SDK版本对应关系: 双折叠的悬停适配:需要SDK API 12及以上版本。 三折叠的悬停适配:需要SDK API 15及以上版本。