react-native-add-calendar-event:基于 React Native for OpenHarmony 的日历事件管理库

使用标准系统对话框在项目中创建日历事件,支持内容配置、交互控制和样式调整,满足提示、确认及信息展示等场景需求。

Branch3Tags2
FilesLast commitLast update
23 days ago
23 days ago
24 days ago
1 month ago
2 months ago
24 days ago
1 month ago
24 days ago
2 months ago
1 month ago
2 months ago
24 days ago
2 months ago

react-native-add-calendar-event

本项目基于 react-native-add-calendar-event 开发,并适配 React Native for OpenHarmony。 如果在使用过程中有任何问题,可以在 GitCode 提交 Issue,我们会及时跟进。

项目介绍

@hxa-rn/react-native-add-calendar-event 是 react-native-add-calendar-event 5.0.0 的 HarmonyOS 适配版本,用于在 React Native 应用中创建、编辑和查看系统日历事件。

HarmonyOS 端已迁移至 RNOH TurboModule,事件读写通过 Calendar Kit 作用于设备默认日历,交互界面由 ArkUI 自定义对话框提供,支持以下能力:

  • 创建普通事件或全天事件,可预填标题、开始时间、结束时间、地点和备注。
  • 通过事件 ID 编辑已有事件,支持修改或清空字段、调整日期时间,以及删除事件。
  • 通过事件 ID 查看事件详情,支持完成查看或删除事件。
  • 首次调用任一公开接口时自动检查并申请日历读写权限。
  • 编辑保存后回读事件字段,确认已持久化后才返回 SAVED。
  • 支持 RNOH Autolinking,无需手动注册 C++ 与 ETS Package。

集成指南

安装

在 React Native 工程根目录执行:

npm install @hxa-rn/react-native-add-calendar-event

Autolinking

安装依赖后由宿主工程自动接入,无需手动注册原生 Package。

导入

import * as AddCalendarEvent from '@hxa-rn/react-native-add-calendar-event';

本模块导出以下函数,类型声明见 src/index.d.ts:

  • presentEventCreatingDialog(config)
  • presentEventEditingDialog(config)
  • presentEventViewingDialog(config)

使用说明

基础用法

import * as AddCalendarEvent from '@hxa-rn/react-native-add-calendar-event';

async function createCalendarEvent() {
  try {
    const result = await AddCalendarEvent.presentEventCreatingDialog({
      title: '项目会议',
      startDate: '2026-09-01T10:00:00.000',
      endDate: '2026-09-01T11:00:00.000',
      location: '会议室 A',
      notes: '讨论项目计划',
      allDay: false,
    });

    if (result.action === 'SAVED') {
      console.info('事件已保存:', result.eventIdentifier);
      return result.eventIdentifier;
    }

    console.info('用户取消了创建');
    return undefined;
  } catch (error) {
    const calendarError = error as { code?: string; message?: string };
    console.error(calendarError.code, calendarError.message);
    return undefined;
  }
}

如需打开空白创建表单,请传入空对象:

AddCalendarEvent.presentEventCreatingDialog({});

不要省略参数。原生实现会读取配置对象字段,传入 {} 是当前已验证的空白表单调用方式。

使用时有以下约定:

  • 三个接口均返回 Promise。用户取消或关闭对话框时 Promise 是 resolve 并返回 action: 'CANCELED',不是 reject,调用方必须按 action 分流。
  • 当前版本未导出 SAVED、CANCELED、DELETED、DONE、RESPONDED 常量,请直接比较返回结果中的字符串字面量。
  • startDate / endDate 按墙上时间解析:2026-09-01T10:00:00.000 在对话框中原样显示为 2026-09-01 10:00,不做时区换算;字符串尾部的 Z 或 +08:00 时区后缀会被忽略,因此显示值不随设备时区漂移。
  • 首次调用会申请日历读写权限,用户拒绝授权时 Promise 被拒绝,请按错误码 PERMISSION_DENIED 处理。

编辑日历事件

使用创建接口返回的 eventIdentifier 作为 eventId。只传 eventId 时,编辑表单加载事件已保存的内容作为预填值;传入其他字段会覆盖对应的预填值。

async function editCalendarEvent(eventId: string) {
  try {
    const result = await AddCalendarEvent.presentEventEditingDialog({
      eventId,
      title: '更新后的项目会议',
      location: '',
      notes: '',
    });

    switch (result.action) {
      case 'SAVED':
        console.info('事件已更新:', result.eventIdentifier);
        break;
      case 'DELETED':
        console.info('事件已删除:', result.eventIdentifier);
        break;
      case 'CANCELED':
        console.info('用户取消了编辑');
        break;
    }
  } catch (error) {
    const calendarError = error as { code?: string; message?: string };
    console.error(calendarError.code, calendarError.message);
  }
}

location: '' 和 notes: '' 可用于清空已有地点和备注。保存后原生端会回读标题、开始时间、结束时间、全天状态、地点和备注;只有回读结果与提交内容一致时才返回 SAVED,否则 Promise 被拒绝并返回 UPDATE_VERIFICATION_FAILED。

查看日历事件

查看对话框展示标题、开始时间、结束时间、全天状态、地点和备注,并提供完成和删除操作,查看界面不提供编辑入口。

async function viewCalendarEvent(eventId: string) {
  try {
    const result = await AddCalendarEvent.presentEventViewingDialog({ eventId });

    switch (result.action) {
      case 'DONE':
        console.info('查看完成');
        break;
      case 'DELETED':
        console.info('事件已删除:', result.eventIdentifier);
        break;
      case 'CANCELED':
        console.info('查看对话框已关闭');
        break;
    }
  } catch (error) {
    const calendarError = error as { code?: string; message?: string };
    console.error(calendarError.code, calendarError.message);
  }
}

接口文档

以下 API 依据 src/index.js、src/specs/v1/NativeAddCalendarEvent.ts 和 src/index.d.ts 整理。插件对外导出三个接口,均由 HarmonyOS 侧 AddCalendarEventTurboModule 实现,返回值为 Promise。下表中标注为 iOS 或 Android 专属的参数在 HarmonyOS 端不生效。

presentEventCreatingDialog(config)

打开 HarmonyOS 日历事件创建对话框。用户点击“保存”后,模块通过 Calendar Kit 将事件写入默认日历。

presentEventCreatingDialog(config: CreateOptions): Promise<CreateResult>

CreateOptions

属性 类型 默认值 说明
title string '' 预填标题;保存时去除首尾空白后不能为空,否则提示“请输入事件标题”
startDate string 当前时间 时间字符串,按墙上时间解析;缺失或无法解析时使用当前时间
endDate string 开始时间 + 1 小时 时间字符串,按墙上时间解析;缺失或无法解析时使用开始时间加 1 小时
location string '' 预填地点
notes string '' 预填备注,对应 Calendar Kit 的 description
allDay boolean false 是否为全天事件;为 true 时时间选择器只选择日期
url string — iOS 专属参数,HarmonyOS 不使用
navigationBarIOS NavigationBarIOS — iOS 专属参数,HarmonyOS 不使用

返回值

type CreateResult =
  | { action: 'SAVED'; eventIdentifier: string }
  | { action: 'CANCELED' };

eventIdentifier 是 Calendar Kit 数字事件 ID 转换后的字符串。HarmonyOS 不返回 iOS 的 calendarItemIdentifier。

presentEventEditingDialog(config)

根据事件 ID 查询事件并打开 HarmonyOS 编辑对话框。用户可以保存修改、删除事件或取消编辑;保存后模块会重新读取事件并校验持久化结果。

presentEventEditingDialog(config: EditOptions): Promise<EditResult>

EditOptions

属性 类型 默认值 说明
eventId string 无 必填。Calendar Kit 数字事件 ID 的字符串形式,通常使用创建接口返回的 eventIdentifier
title string 事件当前标题 覆盖编辑表单的初始标题
startDate string 事件当前开始时间 覆盖初始开始时间,按墙上时间解析;无法解析时保留原值
endDate string 事件当前结束时间 覆盖初始结束时间,按墙上时间解析;无法解析时保留原值
location string 事件当前地点 覆盖初始地点,可传空字符串清空
notes string 事件当前备注 覆盖初始备注,可传空字符串清空
allDay boolean 事件当前全天状态 覆盖初始全天状态
useEditIntent boolean — Android 专属参数,HarmonyOS 忽略
navigationBarIOS NavigationBarIOS — iOS 专属参数,HarmonyOS 忽略

返回值

type EditResult =
  | { action: 'SAVED'; eventIdentifier: string }
  | { action: 'DELETED'; eventIdentifier: string }
  | { action: 'CANCELED' };

对话框内的“删除”按钮会先弹出确认框(按钮为“取消”和“确定”),确认后才真正删除事件并返回 DELETED。

presentEventViewingDialog(config)

根据事件 ID 查询事件并打开 HarmonyOS 查看对话框。

presentEventViewingDialog(config: ViewOptions): Promise<ViewResult>

ViewOptions

属性 类型 默认值 说明
eventId string 无 必填。Calendar Kit 数字事件 ID 的字符串形式,通常使用创建接口返回的 eventIdentifier
allowsEditing boolean — iOS 专属参数,HarmonyOS 忽略
allowsCalendarPreview boolean — iOS 专属参数,HarmonyOS 忽略
navigationBarIOS NavigationBarIOS — iOS 专属参数,HarmonyOS 忽略

返回值

type ViewResult =
  | { action: 'DONE' }
  | { action: 'DELETED'; eventIdentifier: string }
  | { action: 'CANCELED' };

点击“完成”返回 DONE;点击“删除”并在确认框中点击“确定”返回 DELETED;通过蒙层、返回键或系统方式关闭对话框时返回 CANCELED。HarmonyOS 不返回 RESPONDED。

该配置仅用于 iOS,HarmonyOS 原生端会忽略其全部字段。

interface NavigationBarIOS {
  tintColor: string;
  barTintColor: string;
  backgroundColor: string;
  translucent: boolean;
  titleColor: string;
}

错误码

Promise 被拒绝时,可从错误对象中读取 code 和 message。

错误码 触发条件
PERMISSION_DENIED 用户未授予日历读写权限
NO_CALENDAR 无法获取可用的默认日历
INVALID_EVENT_ID eventId 缺失或不能解析为数字
EVENT_NOT_FOUND 指定事件不存在
INVALID_DIALOG_RESULT 编辑对话框未返回事件数据
UPDATE_VERIFICATION_FAILED 编辑保存后回读字段与提交内容不一致
DIALOG_ALREADY_OPEN 已有日历事件对话框处于打开状态
DIALOG_CONTEXT_UNAVAILABLE 当前无法获取前台 UIContext
DIALOG_OPEN_FAILED ArkUI 自定义对话框打开失败
DIALOG_CLOSE_FAILED ArkUI 自定义对话框关闭失败
ERROR 其他未分类的原生错误

快速验证(运行 Example)

前置条件

依赖 版本要求
Node.js >=20
React Native for OpenHarmony 0.72.139
HarmonyOS SDK API 21+

运行步骤

  1. 获取开发分支源码:

    git clone -b react-native-add-calendar-event_dev https://gitcode.com/hxa-rn/react-native-add-calendar-event.git
    
  2. 进入仓库根目录:

    cd react-native-add-calendar-event
    
  3. 安装根目录依赖:

    npm install
    
  4. 生成供示例工程安装的本地安装包:

    npm pack
    
  5. 进入 example 目录:

    cd example
    
  6. 安装示例工程依赖:

    npm install
    
  7. 生成 React Native JavaScript Bundle:

    npm run dev
    
  8. 使用 DevEco Studio 打开 example/harmony,同步依赖并完成签名配置后构建运行。

约束与限制

兼容性

依赖 要求
React Native for OpenHarmony 0.72.139
HarmonyOS SDK 6.0.1(API 21) 及以上
Example 工程 compatibleSdkVersion 6.0.1(21)
Example 工程 targetSdkVersion 6.1.1(24)
Node.js >=18

使用限制

  • HarmonyOS 端使用 ArkUI 自定义对话框,不调用系统日历应用的标准事件对话框。
  • 模块仅操作 Calendar Kit 返回的默认日历,不提供日历账户选择接口。
  • 同一时刻只能打开一个日历事件对话框,重复调用会返回 DIALOG_ALREADY_OPEN。
  • 应用必须位于前台,并且原生模块能够获取当前 UIContext。
  • 创建和编辑事件时,标题不能为空或仅包含空白字符。
  • 结束时间按分钟精度必须晚于开始时间;在对话框内选择不晚于开始时间的结束时间会被拒绝并提示。
  • 对话框中的日期选择范围为 1900-01-01 至 2100-12-31。
  • 编辑和查看接口要求传入当前日历数据库中有效的数字事件 ID 字符串。
  • startDate / endDate 按墙上时间解析,不做时区换算,传入 UTC 字符串不会按设备时区偏移。
  • url、navigationBarIOS、useEditIntent、allowsEditing 和 allowsCalendarPreview 为 iOS 或 Android 平台参数,在 HarmonyOS 端不生效。
  • HarmonyOS 不返回 RESPONDED 动作,也不返回 iOS 的 calendarItemIdentifier。
  • 当前发布包未导出动作常量,请直接比较返回结果中的字符串字面量。
  • 本模块通过交互式对话框操作单个事件,不适用于无交互批量创建或批量修改事件的场景。

系统权限

模块依赖以下全部系统权限,首次调用任一公开接口时统一申请:

权限 用途 授权方式
ohos.permission.READ_CALENDAR 查询、编辑和查看日历事件 user_grant,运行时申请
ohos.permission.WRITE_CALENDAR 创建、编辑和删除日历事件 user_grant,运行时申请

应用必须处理用户拒绝授权时的 Promise 异常(错误码 PERMISSION_DENIED)。

开源 License

本项目采用 MIT,与上游项目保持一致。

问题反馈渠道

如在使用过程中遇到问题,请在 GitCode 提交 Issue,我们会及时跟进。

  • 提交问题时建议附上项目版本、RN 版本、OpenHarmony SDK/API 版本、DevEco Studio 版本、设备信息、复现步骤及相关日志。
  • 涉及签名、账号、密钥或用户数据时,请勿在 Issue 中上传敏感信息;可按组织安全流程提交脱敏日志。

Introduction

使用标准系统对话框在项目中创建日历事件,支持内容配置、交互控制和样式调整,满足提示、确认及信息展示等场景需求。

Customize your domain