Skip to content

feat(calendar): 合并2.x功能,支持月面板、季面板,支持展示周号,鸿蒙适配 #3091

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: feat_v3.x
Choose a base branch
from

Conversation

xiaoyatong
Copy link
Collaborator

@xiaoyatong xiaoyatong commented Mar 17, 2025

🤔 这个变动的性质是?

  • 新特性提交
  • 日常 bug 修复
  • 站点、文档改进
  • 演示代码改进
  • 组件样式/交互改进
  • TypeScript 定义更新
  • 包体积优化
  • 性能优化
  • 功能增强
  • 国际化改进
  • 重构
  • 代码风格优化
  • 测试用例
  • 分支合并
  • 其他改动(是关于什么的改动?)

🔗 相关 Issue

💡 需求背景和解决方案

☑️ 请求合并前的自查清单

⚠️ 请自检并全部勾选全部选项⚠️

  • 文档已补充或无须补充
  • 代码演示已提供或无须提供
  • TypeScript 定义已补充或无须补充
  • fork仓库代码是否为最新避免文件冲突
  • Files changed 没有 package.json lock 等无关文件

Summary by CodeRabbit

  • 新功能

    • 扩展日历本地化支持,新增“周”、“月”、“年”、“季度”字段,多语言下可显示简写。
    • 日历组件现支持天、月、季度多视图模式,增强日期选择的灵活性。
    • 新增多个演示示例,展示多日期、区间及周选择等多种操作方式。
    • 新增属性 viewMode,支持选择显示模式为“天”、“月”或“季度”。
    • 新增属性 showMonthNumber,控制是否显示月份编号。
    • 新增事件处理器 onItemClick,用于处理月份和季度面板中的项目点击事件。
  • 样式

    • 优化日历布局与样式,并引入自定义样式变量,提高界面适应性。
    • 新增日历面板项宽度的样式变量,增强样式灵活性。
  • 测试

    • 扩充测试覆盖,确保各视图模式和点击交互正常运行。

@xiaoyatong xiaoyatong requested a review from oasis-cloud March 17, 2025 12:09
@xiaoyatong xiaoyatong requested review from Miles-hxy and removed request for oasis-cloud March 17, 2025 12:09
Copy link

coderabbitai bot commented Mar 17, 2025

Walkthrough

此次 PR 修改主要扩展了日历组件及其本地化支持。新增了 API 属性(week、month、year、quarter)以提供更细粒度的时间区段信息,并同步在各语言包中添加了对应的翻译。此外,对样式、组件逻辑、演示案例、工具函数、类型定义和测试用例等进行了重构和动态化处理,提升了组件的灵活性和可维护性。

Changes

文件路径 修改摘要
src/locales/... (base.ts, en-US.ts, id-ID.ts, tr-TR.ts, zh-CN.ts, zh-TW.ts, zh-UG.ts) calendaritem 对象中新增四个属性(week、month、year、quarter),并为各语言提供对应的翻译。
src/packages/calendar/calendar.scss 更新了日历样式,新增了 weeknumber、shrink、panel 等类,并修改了部分类名(如从 day-info 改为 item-info)。
src/packages/calendar/calendar.taro.tsx
src/packages/calendar/calendar.tsx
在 Calendar 组件中新增 viewMode、value、showMonthNumber,并调整日期处理逻辑及条件渲染(区分日模式和其他视图)。
src/packages/calendar/calendarviewmodeitem.taro.tsx
src/packages/calendar/calendarviewmodeitem.tsx
新增 CalendarViewModeItem 组件,用于支持月和季视图,处理初始化、滚动和点击事件。
src/packages/calendar/demo*.tsx
src/packages/calendar/demos/*
各 Demo 组件统一重命名为 Demo,并更新了日期状态初始化为动态日期,调整了展示逻辑和演示配置。
src/packages/calendar/utils.ts
src/packages/calendarcard/utils.ts
src/packages/calendaritem/...
重构工具函数:移除 Utils 对象,改为直接导入具体函数,并新增涉及月份、季度计算的函数;同时在 CalendarItem 中新增 showMonthNumber 属性和改进渲染/对比逻辑。
src/styles/variables.scss 新增 $calendar-panel-item-width 变量,用于定义日历面板项的宽度。
src/types/spec/calendar/base.ts
src/packages/configprovider/types.ts
更新和扩展了日历相关类型定义,新增属性如 viewMode、value、showMonthNumber、onItemClick,以及新的接口(CalendarMonth、CalendarQuarter 等)。
src/utils/date.ts 对日期工具函数进行重构:将原 Utils 对象中的函数拆分成独立导出函数,并新增 getDateString 等函数。
src/packages/calendar/__tests__/calendar.spec.tsx 更新测试用例名称和逻辑,增加对视图模式、点击事件等场景的验证,并加入辅助测试函数。

Sequence Diagram(s)

sequenceDiagram
    participant U as 用户
    participant C as Calendar 组件
    participant V as CalendarViewModeItem
    participant D as CalendarItem
    U->>C: 触发日期选择
    alt viewMode ≠ 'day'
        C->>V: 渲染视图模式组件
        V->>C: 触发 onItemClick 回调
    else viewMode == 'day'
        C->>D: 渲染日历项组件
        D->>C: 触发 onDayClick 回调
    end
Loading

Possibly related PRs

Suggested reviewers

  • oasis-cloud
  • Alex-huxiyang

Poem

我是小兔跳跳乐,
代码草原春意浓,
日历新添四时风,
样式调整巧如梦,
Demo 变换显灵动,
工具重构理更通,
欢喜涂鸦不止步 🐰🌸


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@xiaoyatong xiaoyatong requested a review from oasis-cloud March 17, 2025 12:09
@github-actions github-actions bot added action:review This PR needs more reviews (less than 2 approvals) 3.x Target branch 3.x labels Mar 17, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (28)
src/packages/calendar/demos/taro/demo101.tsx (1)

1-36: 功能演示代码结构清晰,实现了季度面板的展示

这个新增的示例代码很好地展示了日历组件的季度视图功能。代码逻辑清晰,使用了恰当的React hooks进行状态管理,并通过回调函数处理了用户交互。

几点建议:

  1. 考虑添加相关注释,解释此演示的目的和功能点
  2. 在控制台日志中使用 param 变量名不够直观,建议改为更具描述性的名称如 quarterValue
- const select = (param: string) => {
-   console.log('select quarter', param)
-   setDate(param)
+ const select = (quarterValue: string) => {
+   console.log('选择的季度', quarterValue)
+   setDate(quarterValue)
src/packages/calendar/demos/h5/demo103.tsx (1)

1-38: 示例代码功能完整,展示了月号显示和多选功能

这个Demo组件很好地展示了日历组件的月号显示功能以及多选日期的能力。代码结构清晰,功能实现完整。

有两点可以改进的地方:

  1. 类型定义不够严谨,chooseData 和映射中的 item 都使用了 any 类型
  2. 映射操作可以更简洁

建议修改如下:

- const setChooseValue = (chooseData: any) => {
-   const dateArr = chooseData.map((item: any) => {
-     return item[3]
-   })
+ interface CalendarData {
+   [index: number]: string | number;
+ }
+ const setChooseValue = (chooseData: CalendarData[]) => {
+   const dateArr = chooseData.map((item) => item[3] as string)
src/packages/calendar/demos/taro/demo102.tsx (1)

1-36: 新增月视图示例

这个新增的示例很好地展示了PR中添加的月视图功能。代码结构清晰,正确使用了React Hooks,并设置了适当的属性来展示月视图模式。viewMode="month"属性的使用与PR目标一致,向用户展示了如何配置和使用新的月面板功能。

建议考虑添加一些注释来解释参数的作用,特别是viewMode属性的可选值,这将帮助开发者更快地理解如何使用这一新功能。

      <Calendar
        viewMode="month"  // 月视图模式,支持day/month/quarter
        showTitle={false}
        value={date}
        defaultValue={date}
        startDate={`${d - 2}-09-12`}
        endDate={`${d + 2}-09-12`}
        onItemClick={select}
      />
src/packages/calendar/demo.tsx (1)

57-70: 繁体中文本地化

繁体中文翻译基本完整,但有几处仍使用了简体中文(如第53-54行的"请选择起始时间"和"请选择截止时间")。

建议将这些文案也翻译为繁体中文,保持本地化的一致性。

src/packages/calendar/demos/taro/demo103.tsx (1)

5-14: 日期选择处理逻辑

组件实现了多选日期的功能,但setChooseValue函数中使用了any类型,这降低了类型安全性。

建议明确定义chooseData的类型,避免使用any

-  const setChooseValue = (chooseData: any) => {
-    const dateArr = chooseData.map((item: any) => {
+  const setChooseValue = (chooseData: Array<Array<any>>) => {
+    const dateArr = chooseData.map((item: Array<any>) => {

理想情况下,还应该进一步明确内部数组元素的具体类型。

src/packages/calendar/calendar.tsx (1)

136-136: 避免通过 prop 直接传递 children。
React 官方通常推荐以 JSX 形式编写子节点,而非将 children 作为独立的 prop 使用。

可考虑改为直接在父组件中使用 JSX 包裹内容,避免显式地传入 children={children}

- children={children}
+ {children}
🧰 Tools
🪛 Biome (1.9.4)

[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

src/packages/calendar/calendarviewmodeitem.taro.tsx (1)

83-185: 面板数据初始化逻辑完备,但需考虑特殊边界。
常规跨年、跨月与季度的处理逻辑清晰,可进一步加固对闰年或大幅跨越时间的边界情况测试。

src/packages/calendar/calendar.taro.tsx (1)

136-136: 避免在 Taro 端通过 prop 直接传递 children。
同样建议使用 JSX 包裹子节点,而非 children prop。

- children={children}
+ {children}
🧰 Tools
🪛 Biome (1.9.4)

[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

src/packages/calendar/calendarviewmodeitem.tsx (3)

29-33: 在常量定义处添加补充注释以提高可读性

建议在 YearMonthPanelHeightYearQuarterPanelHeight 附近添加注释,明确这两个常量的高度是通过对应样式计算或测量得到的,方便后续维护人员理解其由来。


130-170: 合并重复逻辑以精简代码结构

requestAniFrameFunc 方法中,case 'month'case 'quarter' 的逻辑大同小异,仅操作的面板数据结构不同。可以考虑抽取公共部分,通过参数传入 panelDate.monthspanelDate.quarters,以减少代码重复并提高可维护性。

- switch (viewMode) {
-   case 'month':
-     // ... 操作 panelDate.months
-     break
-   case 'quarter':
-     // ... 操作 panelDate.quarters
-     break
- }
+ const targetPanel = viewMode === 'month' ? panelDate.months : panelDate.quarters
+ // 使用相同的滚动初始化逻辑

305-313: 可点击类型判断逻辑可考虑兼容更多场景

当前只对 item.type === 'curr' 才允许点击,直接跳过 prevnext。若后续需求中需要让用户可选择其他面板范围的日期,可在此适当简化或添加注释说明限制原因。

src/packages/calendaritem/calendaritem.tsx (4)

7-14: 日期工具函数的引入规范

这里引入多项日期工具函数(getDateString, compareDate, getMonthDays 等)较为分散,且部分工具函数与该文件下的 utils 重叠。建议统一管理并减少重复工具函数的定义,以避免维护成本过高。


84-85: 默认的开始与结束日期易受「365 天后」限制影响

这里将 endDate 默认为 getDateString(365),对于可能跨年度或遇到闰年的情境,会带来一定的边界问题。可以在注释处明确标注此默认值的含义,或改用更显意图的方式(例如 addOneYear() 函数)。


196-207: 重复或复杂的数组拼接逻辑

getMonthData 中,连续拼接了 getPreMonthDatesgetDaysStatus 等逻辑,且嵌套条件较多。若后续扩展到更复杂的日历场景,可考虑抽离公共处理流程,将这些数据源收敛到一个核心合并函数,以避免多处散落的判断和拼接。


609-615: weekArr 的边界修正需要更详尽的校验

在生成周数据后,只对 weekArr[0]weekArr[1]propStartDatepropEndDate 做日期比较与修正,当周同时跨多个特殊边界(如跨两个月或闰月)时,仍可能需要额外判断。可在此加强校验或在注释中说明使用限制。

src/types/spec/calendar/base.ts (2)

14-16: 可选字段的含义应在注释中加以说明

这里新增了 weekNo?, cssHeight?, scrollTop? 三个可选字段,建议在接口顶部或字段旁增加注释,说明具体用途与取值范围。


90-118: 统一管理散落的日历类型定义

新增的 CalendarMonthCalendarQuarterCalendarMonthInfoOfPanelCalendarQuarterInfoOfPanel 等,与上方已有的 CalendarMonthInfoCalendarDay 等多种类型定义可能存在重叠字段。可以考虑通过更灵活的公共类型或泛型减少重复字段,使整体结构更加精简。

src/packages/calendar/utils.ts (6)

12-12: 逻辑函数调用正确。
在判断是否存在某个值时,使用 isEqual(item, day) 可以保证字符串比较的准确性。如需提高健壮性,可在外层先对 itemday 做空值校验。


20-20: 提升可读性的小建议。
此处比较当日与当前系统日期(date2Str(new Date(), '/'))逻辑正确,但若后续要在多处比较“是否为今日”,可考虑抽离成为一个通用函数,提升可读性。


58-75: 函数 getMonths:区间生成逻辑良好。

  1. 使用 type 字段区分数据类别,可在后续业务场景中灵活扩展。
  2. 尽管循环创建对象性能无较大问题,但若月范围非常大,可考虑进一步优化实现(例如仅在大区间内才进行懒加载)。

101-122: 函数 getQuarters:循环步长为 3,逻辑直观。

  1. 每个季度通过 getQuarter 进一步验证,避免非预期值。
  2. 返回对象里包含 yearAndQuarter,在渲染层可直接使用。
    若需要跨年,可进一步查看 endMonth 是否越界,但现阶段实现已满足一般需求。

124-139: 函数 getPreQuarters:减少重复代码可进一步提升维护性。
逻辑与 getQuarters 基本一致,仅范围有所差异。若后续有更多衍生函数,可将公共部分抽离。


141-161: 函数 getNextQuarters:实现与 getPreQuarters类似。

  1. 同样通过 for 循环按步长 3 处理季度信息。
  2. 建议与 getPreQuarters 统一封装公共逻辑,减少重复。
src/packages/calendaritem/calendaritem.taro.tsx (2)

18-22: 引入 getWeekDateformatResultDate 等 utils 函数后,代码可读性提升。
配合其他同类函数使得日期处理结构更直观,如后续有大规模日期逻辑,可考虑共同维护在统一的日期工具模块中。


66-66: scrollAnimation 默认值为 true。
滚动动画可提升交互体验,但要注意移动端性能,过多动画会影响流畅度。

src/utils/date.ts (3)

7-7: JSDoc 注释中存在拼写错误

返回类型应该是 {Boolean} 而不是 {Boolse}


39-42: 函数名称可能导致混淆

函数名 getMonthPreDay 不太直观,实际上这个函数是计算某月第一天是星期几。建议重命名为更直观的名称,如 getFirstDayOfMonthWeekday


115-118: 防御性编程不一致

函数对date1进行了空值检查(使用(date1 || '')),但没有对date2进行相同的处理,这可能导致在处理空值时出现不一致的行为。

-  const startTime = new Date((date1 || '').replace(/-/g, '/')).getTime()
-  const endTime = new Date(date2.replace(/-/g, '/')).getTime()
+  const startTime = new Date((date1 || '').replace(/-/g, '/')).getTime()
+  const endTime = new Date((date2 || '').replace(/-/g, '/')).getTime()
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 31dd4ee and 95632c9.

📒 Files selected for processing (50)
  • src/locales/base.ts (1 hunks)
  • src/locales/en-US.ts (1 hunks)
  • src/locales/id-ID.ts (1 hunks)
  • src/locales/tr-TR.ts (1 hunks)
  • src/locales/zh-CN.ts (1 hunks)
  • src/locales/zh-TW.ts (1 hunks)
  • src/locales/zh-UG.ts (1 hunks)
  • src/packages/calendar/calendar.scss (4 hunks)
  • src/packages/calendar/calendar.taro.tsx (6 hunks)
  • src/packages/calendar/calendar.tsx (6 hunks)
  • src/packages/calendar/calendarviewmode.scss (1 hunks)
  • src/packages/calendar/calendarviewmodeitem.taro.tsx (1 hunks)
  • src/packages/calendar/calendarviewmodeitem.tsx (1 hunks)
  • src/packages/calendar/demo.taro.tsx (3 hunks)
  • src/packages/calendar/demo.tsx (3 hunks)
  • src/packages/calendar/demos/h5/demo1.tsx (2 hunks)
  • src/packages/calendar/demos/h5/demo10.tsx (3 hunks)
  • src/packages/calendar/demos/h5/demo101.tsx (1 hunks)
  • src/packages/calendar/demos/h5/demo102.tsx (1 hunks)
  • src/packages/calendar/demos/h5/demo103.tsx (1 hunks)
  • src/packages/calendar/demos/h5/demo11.tsx (3 hunks)
  • src/packages/calendar/demos/h5/demo2.tsx (2 hunks)
  • src/packages/calendar/demos/h5/demo3.tsx (2 hunks)
  • src/packages/calendar/demos/h5/demo4.tsx (2 hunks)
  • src/packages/calendar/demos/h5/demo5.tsx (3 hunks)
  • src/packages/calendar/demos/h5/demo6.tsx (3 hunks)
  • src/packages/calendar/demos/h5/demo7.tsx (2 hunks)
  • src/packages/calendar/demos/h5/demo8.tsx (2 hunks)
  • src/packages/calendar/demos/h5/demo9.tsx (3 hunks)
  • src/packages/calendar/demos/taro/demo10.tsx (3 hunks)
  • src/packages/calendar/demos/taro/demo101.tsx (1 hunks)
  • src/packages/calendar/demos/taro/demo102.tsx (1 hunks)
  • src/packages/calendar/demos/taro/demo103.tsx (1 hunks)
  • src/packages/calendar/demos/taro/demo11.tsx (3 hunks)
  • src/packages/calendar/demos/taro/demo2.tsx (2 hunks)
  • src/packages/calendar/demos/taro/demo3.tsx (2 hunks)
  • src/packages/calendar/demos/taro/demo4.tsx (2 hunks)
  • src/packages/calendar/demos/taro/demo5.tsx (3 hunks)
  • src/packages/calendar/demos/taro/demo6.tsx (3 hunks)
  • src/packages/calendar/demos/taro/demo7.tsx (2 hunks)
  • src/packages/calendar/demos/taro/demo8.tsx (2 hunks)
  • src/packages/calendar/demos/taro/demo9.tsx (3 hunks)
  • src/packages/calendar/utils.ts (2 hunks)
  • src/packages/calendarcard/utils.ts (3 hunks)
  • src/packages/calendaritem/calendaritem.taro.tsx (16 hunks)
  • src/packages/calendaritem/calendaritem.tsx (19 hunks)
  • src/packages/calendaritem/utils.ts (1 hunks)
  • src/styles/variables.scss (1 hunks)
  • src/types/spec/calendar/base.ts (5 hunks)
  • src/utils/date.ts (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/packages/calendar/calendar.taro.tsx

[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

src/packages/calendar/calendar.tsx

[error] 160-160: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (140)
src/packages/calendar/demos/taro/demo7.tsx (1)

4-4: 组件名称更改为更简洁的形式

组件名称从 Demo7 改为 Demo,这样命名更加统一和简洁,有助于保持整个项目的命名一致性。

Also applies to: 37-37

src/styles/variables.scss (1)

1028-1031: 新增日历面板项宽度变量

添加了 $calendar-panel-item-width 变量,为日历组件的月面板和季面板提供了宽度支持,默认值设置为 24.85%,这有助于保持面板项的适当间距和排列。

src/packages/calendar/demos/h5/demo7.tsx (1)

4-4: 组件名称统一更改为 Demo

与 Taro 版本保持一致,H5 版本的演示组件名称也从 Demo7 更改为 Demo,保持了跨平台实现的命名一致性。

Also applies to: 37-37

src/locales/tr-TR.ts (1)

45-48: 为土耳其语言添加日历新功能本地化支持

为土耳其语言文件添加了日历组件的周、月、年和季度的简写标识:

  • 'H' 代表周(Hafta)
  • 'A' 代表月(Ay)
  • 'Y' 代表年(Yıl)
  • 'Ç' 代表季度(Çeyrek)

这些新增属性支持了日历组件的月面板、季面板和周号显示功能。

src/packages/calendar/calendarviewmode.scss (1)

1-182: 优秀的新样式文件实现!

这个SCSS文件为日历组件的新视图模式提供了全面的样式支持。代码组织清晰,使用了变量保持一致性,并提供了RTL布局支持。

几点小建议:

  1. 考虑在复杂的嵌套选择器中添加更多注释,特别是在.nut-calendar-viewmode-item部分。
  2. .nut-calendar-viewmode-item-info-curr.nut-calendar-viewmode-item-info有几乎相同的样式,可以考虑合并这些选择器以减少代码重复。
src/packages/calendar/demos/h5/demo1.tsx (1)

5-5: 组件命名更新为统一风格

将组件从Demo1重命名为Demo有助于保持演示文件之间的命名一致性,这是个好的改变。

Also applies to: 48-48

src/packages/calendar/demos/taro/demo2.tsx (2)

5-6: 使用动态年份替代硬编码日期值

使用new Date().getFullYear()获取当前年份来动态生成日期,提高了代码的维护性和适应性。这种方法避免了硬编码日期值导致的过时问题。


36-37: 动态生成日期范围

更新起始日期和结束日期以基于当前年份,使示例更加实用且长期有效。

src/packages/calendar/demos/h5/demo102.tsx (1)

1-36: 出色的月视图模式演示组件

这个新组件很好地展示了Calendar组件的月视图模式功能。代码结构清晰,展示了如何配置和使用新的viewMode="month"属性。

几点建议:

  1. 考虑添加注释,解释参数param的结构和格式,以便其他开发者更好地理解select函数。
  2. 可以添加一些关于该演示如何与多语言支持(week、month、year和quarter属性)配合使用的说明。
src/locales/base.ts (1)

37-40: 为日历组件添加了新的本地化字符串

添加了weekmonthyearquarter这四个新的本地化字符串属性,用于支持日历组件的月面板、季面板和周号显示功能。这些属性将使日历组件在不同语言环境下能够正确显示相应的时间单位标签。

src/packages/calendar/demos/h5/demo101.tsx (1)

4-34: 季度面板展示示例代码实现正确

这个示例完美地展示了日历组件的季度视图功能(通过viewMode="quarter"属性),并且使用了动态年份计算来确保示例不会过时。选择逻辑处理和UI布局也很合理。

src/packages/calendar/demos/h5/demo9.tsx (3)

12-14: 组件命名统一化并使用动态年份

Demo9重命名为Demo,使命名更加统一,并使用new Date().getFullYear()获取当前年份来动态生成日期,避免了硬编码日期导致的示例过时问题。


60-61: 起始日期和结束日期动态化

将日历控件的startDateendDate属性从硬编码日期修改为基于当前年份的动态计算值,提高了示例的通用性和可维护性。


75-75: 导出组件名称更新

导出组件名称从Demo9更新为Demo,与上面的组件重命名保持一致。

src/packages/calendarcard/utils.ts (2)

1-1: 优化工具函数导入方式

从使用统一的Utils对象改为直接导入具体的getMonthPreDaygetMonthDays函数,符合现代JavaScript的最佳实践,提高了代码的可读性和可维护性。


32-33: 更新函数调用方式

将通过Utils对象调用方法的方式改为直接调用导入的函数,使代码更加简洁清晰,同时保持功能不变。

Also applies to: 38-39, 54-55

src/packages/calendar/demos/h5/demo4.tsx (1)

4-5: 组件改名并使用动态年份计算日期范围,提升了维护性

Demo4 改名为 Demo 并引入动态年份计算是很好的改进。使用当前年份动态计算 startDateendDate 比硬编码日期更灵活,随着时间推移不需要手动更新代码。

Also applies to: 32-33, 41-41

src/packages/calendar/demos/taro/demo6.tsx (1)

20-21: 组件统一命名规范并动态计算日期范围

Demo6 改名为 Demo 并使用当前年份动态计算日期范围是很好的改进。这样的修改使得示例代码更具有可维护性,不再需要定期更新硬编码的日期值。

这些更改与其他示例文件保持了一致的命名和日期处理模式,增强了代码库的整体一致性。

Also applies to: 91-92, 138-138

src/packages/calendar/demos/taro/demo5.tsx (1)

4-5: 组件名称标准化和日期范围动态化的改进

改进通过以下方式优化了组件:

  1. 将组件名从 Demo5 标准化为 Demo
  2. 引入 d 变量获取当前年份
  3. 动态设置 startDateendDate,使日期范围相对于当前年份

这种改进使日历演示更具可持续性,无需每年手动更新日期范围,同时保持了组件的功能一致性。

Also applies to: 38-39, 48-48

src/packages/calendar/demos/taro/demo4.tsx (1)

4-5: 组件名称统一和日期范围动态化的良好实践

此更改与其他演示文件保持一致:

  1. 将组件名从 Demo4 统一为 Demo
  2. 使用 d 变量捕获当前年份
  3. 将固定日期字符串改为基于当前年份的动态计算

这种方法提高了代码的可维护性,使日历组件在不同年份中始终显示合理的日期范围。

Also applies to: 32-33, 41-41

src/packages/calendar/demos/h5/demo6.tsx (1)

19-20: 统一组件命名和改进日期处理

以下更改符合整体代码库的改进方向:

  1. 将组件名从 Demo6 统一为 Demo
  2. 添加 d 变量获取当前年份
  3. 使用动态计算的日期替代硬编码值

这种实现方式确保了日历组件具有更好的适应性,可以根据当前年份自动调整显示范围,无需手动更新。

Also applies to: 95-96, 142-142

src/packages/calendar/demos/h5/demo5.tsx (1)

4-5: 优化组件命名和日期处理逻辑

此更改与其他演示文件保持一致:

  1. 组件名称从 Demo5 更改为标准化的 Demo
  2. 引入变量 d 获取当前年份
  3. startDateendDate 从硬编码值改为基于当前年份的动态计算

这些改进使日历组件更具通用性和可持续性,同时维持了一致的代码风格和命名约定。

Also applies to: 38-39, 49-49

src/packages/calendar/demos/taro/demo3.tsx (1)

4-5: 重构和动态日期范围的改进

组件重命名和添加动态日期范围是很好的改进。使用当前年份来动态计算日期范围可以确保示例代码在长期使用中保持相关性,避免了硬编码固定日期的缺点。这种方法使得示例代码能够适应不同的时间点,始终展示合理的日期范围。

Also applies to: 35-36, 43-43

src/locales/id-ID.ts (1)

37-40: 增加日历本地化支持

新增的本地化键值对(周、月、年、季度)对应印尼语的缩写,很好地支持了新增的月面板和季面板功能。这些添加与PR的目标一致,为国际化用户提供了更完整的本地化体验。

src/packages/calendar/demos/h5/demo3.tsx (1)

4-5: 重构和动态日期范围的改进

与Taro版本的示例一样,这里的H5版本也进行了相同的优化 - 组件重命名和动态日期范围计算。这种一致性确保了不同平台上的示例代码保持同步,并且都能够随着时间的推移自动适应当前年份。

Also applies to: 35-36, 43-43

src/packages/calendar/demos/taro/demo9.tsx (3)

12-14: 组件重命名与日期动态化处理

将组件从 Demo9 重命名为 Demo,并使用当前年份动态计算日期值,增强了演示代码的可维护性。使用 new Date().getFullYear() 获取当前年份,避免了硬编码日期导致的演示过时问题。


60-61: 起始日期和结束日期动态化

将固定的日期范围改为基于当前年份的动态计算方式,保证了日历组件始终展示与当前年份相关的有效日期范围。这种方法使示例更具实用性,不会因为年份变化而失效。


75-75: 导出组件更新

将导出语句从 export default Demo9 更新为 export default Demo,与组件名称变更保持一致。

src/packages/calendar/demos/h5/demo10.tsx (4)

55-57: 组件重命名与日期初始化改进

将组件从 Demo10 重命名为 Demo,并引入了基于当前年份的动态日期计算。这种方法替代了硬编码的日期值,使示例代码更具通用性和持久性。


77-77: 日期滚动逻辑优化

修改了 scrollToDate 方法的调用参数,使用动态年份计算目标日期,避免了固定日期可能过期的问题。这确保了日历组件总是滚动到当前年份的相关日期。


139-140: 日期范围动态设置

将 Calendar 组件的 startDateendDate 属性从硬编码值改为基于当前年份的动态表达式。这种改进使日历组件能够适应不同年份的使用场景,增强了组件的灵活性和用户体验。


148-148: 导出组件更新

将导出语句更新为新的组件名称,保持了代码的一致性。

src/packages/calendar/demos/h5/demo8.tsx (3)

4-6: 组件重命名与日期动态计算

将组件从 Demo8 重命名为 Demo,并通过 new Date().getFullYear() 获取当前年份来动态设置日期值。这种改进避免了硬编码日期可能导致的示例失效问题,使组件演示更具实用性。


37-38: 日期范围动态设置

将日历组件的起始日期和结束日期属性改为基于当前年份的动态计算方式,确保了日期范围始终与当前年份相关联,增强了组件在不同时期的适用性。


46-46: 导出组件更新

导出语句更新为与新组件名称一致,维持了代码的一致性。

src/locales/en-US.ts (1)

37-40: 添加日历项本地化属性

calendaritem 对象添加了四个新属性:

  • week: 'W' - 周的简写表示
  • month: 'M' - 月的简写表示
  • year: 'Y' - 年的简写表示
  • quarter: 'Q' - 季度的简写表示

这些新增属性支持了日历组件的月面板、季面板以及周号显示功能,与 PR 目标一致。这些本地化属性将确保多语言环境下新功能的正确显示。

src/packages/calendar/demos/taro/demo11.tsx (4)

3-3: 导入了 Taro 组件库的 View

引入 Taro 组件库中的 View 组件替代之前的 div 元素,符合 Taro 的最佳实践。


5-7: 组件重命名和动态日期生成

将组件从 Demo11 重命名为 Demo,并使用当前年份动态生成日期,避免了硬编码年份。这种方式更加灵活且易于维护。


19-40: 使用 Taro 的 View 组件并动态设置日期范围

  1. 将 div 替换为 Taro 的 View 组件,符合跨平台开发规范
  2. 日期范围现在基于当前年份动态计算,提高了代码的灵活性和可维护性
-      <div
+      <View

44-44: 更新导出语句

导出语句已更新为匹配重命名后的组件。

src/locales/zh-CN.ts (1)

39-42: 添加日历相关的本地化文本

为日历组件添加了四个新的本地化文本项:周、月、年和季度。这些新增项支持了PR中提到的月面板、季面板功能和周号显示功能,使本地化更加完整。

src/locales/zh-TW.ts (1)

39-42: 添加繁体中文日历相关的本地化文本

为繁体中文版本添加了与简体中文版本一致的日历本地化文本:周、月、年和季度。确保了不同语言版本的功能一致性。

src/packages/calendar/demos/h5/demo2.tsx (3)

4-6: 组件重命名和使用动态日期

将组件从 Demo2 重命名为 Demo,并使用当前年份动态生成日期范围,取代了之前的硬编码日期。这样的修改使示例代码更具通用性和可维护性。


36-37: 动态设置日历的起始和结束日期

使用当前年份动态计算日历组件的 startDate 和 endDate,替代了固定的硬编码日期。这种方法确保了示例在任何年份都能正常工作。


45-45: 更新导出语句

导出语句已更新为匹配重命名后的组件名称。

src/locales/zh-UG.ts (1)

37-40: 添加了日历组件的多语言支持

为维吾尔语言环境添加了日历组件所需的时间单位缩写,支持了新的日历功能特性。

src/packages/calendar/demos/taro/demo8.tsx (3)

4-6: 组件名称更改和动态日期处理

组件从 Demo8 重命名为 Demo,并使用当前年份动态生成日期范围,提高了演示示例的时效性。


37-38: 使用动态年份计算日期范围

将固定的日期范围改为基于当前年份的动态计算,使演示效果始终保持相关性。


46-46: 更新导出组件名

与组件重命名保持一致,将导出名称更新为 Demo

src/packages/calendar/demos/taro/demo10.tsx (5)

55-57: 组件重命名和动态日期初始化

组件从 Demo10 重命名为 Demo,并使用当前年份初始化日期范围,增强了示例的实用性。


74-77: 添加平台兼容性说明注释

说明了京东小程序IDE下的问题修复方法,增加了代码的可维护性。


78-78: 使用动态年份跳转日期

将固定年份的日期跳转改为使用当前年份,确保示例始终展示相关时间。


137-138: 动态设置日历可选范围

更新日历组件的起止日期范围,使用相对于当前年份的计算方式,保持示例的长期有效性。


146-146: 更新导出组件名

与组件重命名保持一致,更新为导出 Demo

src/packages/calendar/demo.taro.tsx (5)

18-20: 引入新的日历演示组件

新增了月面板、季度面板和周号显示的演示组件,实现PR要求的功能。


29-32: 增加中文多语言支持

为新增的日历功能添加了中文翻译,包括日期范围选择的文案和新增面板类型的描述。

Also applies to: 36-40


55-57: 增加繁体中文多语言支持

为新增的日历功能添加了繁体中文翻译,保持了多语言环境的一致性。

Also applies to: 61-63


81-89: 增加英文多语言支持

为新增的日历功能添加了英文翻译,确保国际化支持完整。


123-128: 添加新功能的演示区块

在演示界面中添加了季度面板、月面板和周号显示的演示区块,直观展示新增功能。

src/packages/calendar/demos/h5/demo11.tsx (2)

4-6: 动态日期改进

通过使用当前年份动态生成日期,这个改动提高了组件的适应性和可维护性。不再依赖硬编码的2023年日期,使得示例在未来仍然保持相关性。


31-32: 动态日期范围设置

同样地,使用动态计算的日期范围替代固定值是个很好的改进。这样确保了日历示例在任何时间点展示都能显示相关的可选日期范围。

src/packages/calendar/demo.tsx (3)

15-17: 引入新的演示组件

新增的三个演示组件很好地扩展了功能展示,符合PR中"支持月面板、季面板,支持展示周号"的目标。


32-46: 中文本地化扩展

为新功能添加的中文翻译完整且准确,覆盖了所有新增的日历功能项。


117-122: UI结构清晰

新增的功能展示区域结构清晰,使用适当的标题和组件,与现有代码风格保持一致。

src/packages/calendar/calendar.scss (4)

2-2: 新样式文件导入

导入calendarviewmode.scss支持新的视图模式,符合PR目标中关于支持月面板、季面板的功能需求。


66-68: 周视图缩进样式

添加的&-shrink类使得在显示周号时能够正确调整内容区域,17%的左内边距与周号宽度相协调。


118-132: 周号显示样式

新增的&-weeknumber相关样式实现了PR中"支持展示周号"的功能。样式设置合理,保持了与整体设计的一致性。


221-223: 弹性布局支持

添加.shrink类支持弹性布局,这对于实现周号与日历内容的并排显示是必要的。

src/packages/calendar/demos/taro/demo103.tsx (1)

26-35: 日历组件配置

组件配置清晰地展示了"展示周号"功能,通过showMonthNumber属性启用。日期范围设置为当前年份前后两年,覆盖范围合理。

设置firstDayOfWeek={1}使日历以星期一为一周的第一天,这符合大多数国家的使用习惯。

src/packages/calendar/calendar.tsx (5)

4-5: 引入新组件与方法无冲突,便于扩展多视图模式功能。
这两行新增了 CalendarViewModeItemgetDateString 的导入,对整体架构无明显副作用。


13-13: DefaultProps 增加多项配置项,增强日历组件灵活性。
新增 viewMode, value, startDate, endDate, showMonthNumber, onItemClick 等字段,有助于满足多种业务场景。

Also applies to: 18-18, 20-21, 28-28, 39-39


55-55: 从 props 中解构新参数使逻辑更清晰。
在组件中解构 viewMode, value, showMonthNumber, onItemClick 等字段便于维护和阅读。

Also applies to: 58-58, 68-68, 81-81


113-164: 根据 viewMode 进行条件渲染,结构合理。
通过判断 viewMode !== 'day' 来分别渲染 CalendarViewModeItemCalendarItem,提升了组件可扩展性。

🧰 Tools
🪛 Biome (1.9.4)

[error] 160-160: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)


170-170: 判定弹窗条件可满足多视图需求。
popup && viewMode === 'day' 的判断简洁明了,使弹窗仅在日视图下弹出。

src/packages/calendar/calendarviewmodeitem.taro.tsx (7)

1-17: 文件头部导入合理,涵盖 Taro、工具函数等依赖。
所有依赖与组件需求匹配,无冲突迹象。


36-48: 接口定义清晰,为后续功能提供良好类型约束。
CalendarViewModeItemProps 对外暴露了核心属性,如 viewModetypeonItemClick 等,设计合理。


49-61: defaultProps 提供便捷默认行为。
涵盖了 viewModestartDateendDateonItemClick 等,帮助组件在常规场景下更易用。


63-67: 使用 forwardRef 并结合 Taro 场景,有利于获取内部方法。
可在父组件调用 scrollToDate 等函数,保证可控性与复用性。

Also applies to: 68-81


315-323: 点击事件逻辑简明,且可通过内部值更新触发回调。
如后续需支持多选或取消选中,可在此处扩展。


349-361: 面板及内容渲染结构清晰,区分 header 与内容主区域。
可读性较好,滚动与 CSS 布局逻辑分离度高,后期维护成本低。

Also applies to: 363-383, 385-400, 402-416, 418-424


426-427: 组件名称标记与默认导出便于快速定位与导入。
displayNameexport default 命名一致,符合代码风格。

Also applies to: 428-428

src/packages/calendar/calendar.taro.tsx (5)

4-5: 新增 CalendarViewModeItem 与日期工具方法,可在 Taro 环境下复用。
对 Taro 组件依赖无冲突,导入正常。


13-13: DefaultProps 再次引入多视图相关字段,保持 Web 端与 Taro 端一致。
viewMode, value, startDate, endDate, showMonthNumber, onItemClick 等属性可统一日历配置。

Also applies to: 18-18, 20-21, 28-28, 39-39


55-55: 针对 Taro 端解构新属性,提升易读性和可维护性。
提取 viewMode, value, showMonthNumber, onItemClick 等字段有助于后续扩展。

Also applies to: 58-58, 68-68, 81-81


113-164: 条件渲染增加多视图支持,使用逻辑与 Web 端保持一致。
实现了 CalendarViewModeItemCalendarItem 的组件切换,代码结构清晰。

🧰 Tools
🪛 Biome (1.9.4)

[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)


170-170: 弹窗与关闭图标逻辑无异常。
结合 popupcloseIcon 保证交互流程符合预期。

Also applies to: 177-177

src/packages/calendar/utils.ts (9)

1-3: 导入语句正常,建议保留简洁性。
此处直接从 @/utils/date 导入 isEqualdate2StrgetNumTwoBit 有助于减少对 Utils 整体对象的依赖,代码更具可维护性。


24-24: 字符串拼接表现正确。
通过 getNumTwoBit(+day.day) 格式化日报,能确保数字统一为两位。实现简洁,逻辑完备。


28-28: 函数设计简洁明了。
isEqual(days[0], day) 用于判断当前是否为起始点,逻辑正确,无多余复杂度。


32-32: 与上一函数一致,保持风格统一。
同样用于判断是否为终止点,与 isStart 保持一致性,逻辑清晰。


37-38: 简洁地判断开始结束时间相等。
days.length >= 2 并同时比较 days[0]days[1],符合常见的区间判断方式。


44-56: 函数 getPreMonths:命名及实现逻辑清晰。

  1. 通过 Array.from 生成月份信息数组,紧凑易读。
  2. 内部返回 month, year 等字段,便于使用方直接获取结构化信息。
    若后续需要适配更多场景(如自定义开始月份),可考虑再封装一个通用的月份生成方法。

77-79: 函数 formatMonth:实现符合需求。
使用 String(month).padStart(2, '0') 来补零,逻辑简单有效。


81-83: 函数 formatQuarter:易于理解。
季度使用 Q 标记,并附加年份,形式简洁。无可见安全或性能风险。


85-99: 函数 getQuarter:包含基本错误处理。

  • month < 1month > 12 时抛出异常,确保入参有效。
  • 通过 Math.floor((month - 1) / 3) + 1 计算季度逻辑正确。
src/packages/calendaritem/calendaritem.taro.tsx (35)

3-14: 新增依赖及导入方法合理。

  1. @/utils/date 和本地 utils 中按需引入,有助于代码分层。
  2. 相关方法的命名清晰,可快速理解用途。

24-24: 使用 useConfig 注入多语言上下文。
国际化逻辑独立且可读,符合多语言需求。


31-33: 保留对多选、单选等类型的区分。
在不同日历类型下,需分别处理日期选择逻辑,语义清晰。


40-40: 更改 renderBottomButton 的导出位置。
保证底部按钮可定制,保持组件灵活度。


44-46: 附加到默认属性合并处。
valuestartDateendDate 等属性置于同处初始化,逻辑一致。


50-55: 属性定义合理。
showMonthNumber 布尔值用于展示月数/周数,增强可配置性。


85-86: 使用 getDateString(0)getDateString(365) 生成起止日期默认值。
此举展示了较清晰的时间范围,如需动态配置,可做进一步扩展。


132-132: 对于大部分场景默认不显示月数。
符合常用日历展示方式,避免过度信息。需显示时再显式传参。


136-136: 自定义底部按钮接口。
用户可直接注入自定义 JSX 模板,保证灵活度。


144-144: 事件回调 onPageChange
当切换月份时触发,便于外部同步日历滚动状态。


146-148: 更新 classPrefixdayPrefix
减少硬编码字符串的使用,统一前缀便于样式维护。


200-210: getMonthData 函数:填充月份数据,逻辑集中。

  1. 借助 getPreMonthDatesgetDaysStatus 获取前置天数与当前月天数。
  2. 通过 cssHeight 区分月份显示高度,简化渲染层计算。

217-220: 记录 scrollTop 并计算高度后存储。
配合后续滚动逻辑,能实现日历展现的区间化与懒加载策略。


228-233: 边界校验:若没有 endDates 直接跳过比较。
内部逻辑避免空数组异常,有效避免潜在崩溃。


235-235: 数据追加到 monthData。
此处将组装好的 monthInfo 推入列表,为后续渲染打基础。


306-316: 数组去重并限制日期范围。

  1. 当用户多选时,利用 currentDate.forEach 和对象缓存进行去重处理,减少重复选择。
  2. 合理地限制日期在 propStartDatepropEndDate 之间,防止越界。

309-311: 使用对比函数前先行空值校验。
compareDate(item, propStartDate)compareDate(propEndDate, item) 能防止越界,逻辑完善。


313-313: 借助临时对象进行判断,确保不会重复插入相同日期。
降低多次插入带来的逻辑错误,为多选场景提供更好体验。


319-319: 选定第一天默认值。
将剩余日期挪到 currentDate,同时为多选模式漏斗收敛起点。


324-335: 生成周范围并校验边界。
getWeekDate 返回周起始,然后与 propStartDate / propEndDate 比较,保证日期合法性。


327-329: 向前对比超出范围时替换为最小值或最大值。
写法简洁直观。


690-690: 处理标题样式条件。
保持全局日历头部可在网页端或小程序端一致呈现。


713-722: 渲染头部区域及标题按钮。

  1. title 优先使用外部传入,否则用本地化信息。
  2. 头部按钮可插入定制元素,提高扩展性。

725-729: 副标题展示当前年月。
利用 yearMonthTitle 动态更新,若需多语言也可在本地化文件中配合使用。


732-734: weekdays 渲染。
一行循环即可,展示一周信息;若需求拓展,可增加判断规则例如节假日标注等。


744-750: 渲染单元格事件绑定。
使用 handleDayClick 做统一日期点击逻辑。若要区分长按或双击,再行扩展即可。


752-763: 统一渲染顶部和底部信息插槽。
让使用方自定义日历单元格外观,其它模式同理可扩展。


764-780: 标记"今日"的逻辑。
showToday 为真,并且 isCurrDay(month, day.day) 为真时,显示文案,可提升用户对当前日期位置的感知。


782-787: 渲染开始/结束标签。
同时处理开始结束为同一天的情况(例如单日Range),通过 .active-start.active-end 设置特殊样式。


792-814: renderPanel:将月份的标题与其内的日期列表分离渲染。

  1. showMonthNumbertrue,则显示周数列;
  2. 板块清晰易于维护。

827-828: 面板容器使用 ref={monthsPanel} 实现可控高度。
结合 ScrollView 组件来管理日历滚动区域尺寸。


833-835: 分段渲染月数据。
monthDefaultRange 控制实际呈现范围,减少一次性渲染过多月份的问题。


837-837: 使用 renderPanel 迭代每个月元素。
结合上层数据结构可直观生成整段日历。


845-857: 渲染底部区域。

  • 包括确认按钮与外部 children 插入,灵活度高。
  • 点击事件与 confirm 方法呼应,一致性好。

861-865: 整合组件最终结构。
同时渲染头部、内容与可选底部按钮,很好地将显示与逻辑隔离。

src/packages/calendaritem/utils.ts (8)

1-7: 集中导入日期相关辅助函数,减少对外部依赖的重复使用。
getNumTwoBitgetMonthDays 等函数覆盖常见日期处理场景,为后续方法提供坚实基础。


9-19: 函数 getCurrMonthData:前后月切换处理简洁。

  1. type'prev',则向前调月;若 type'next',则向后调月。
  2. 返回 [year, getNumTwoBit(month), getMonthDays(...)],便于一处计算、多处复用。

21-36: 函数 getDaysStatus:批量生成当月天数并标记类型。

  1. 对当月天数进行 -7 的特殊修正逻辑,避免当1号为周日时出现额外空行。
  2. 返回结构中含有 yearmonth 等信息,方便后续判断。

38-68: 函数 getPreMonthDates:填充上个月末尾天数。

  1. days -= firstDayOfWeek 后,再判断当月首日是否为周日,做二次校正。
  2. 取切片 months.slice(preDates - days) 获取目标区段,直观易懂。
    若有非公历的情况,可再行扩展转换逻辑。

70-98: 函数 getWeekDate:计算周起始与结束日期。

  1. 兼容 firstDayOfWeek 为 0 与其他模式。
  2. 通过 new Date(year, month - 1, date) 巧妙定位,再用 day 位移得到整周区间。

100-106: 函数 formatResultDate:返回丰富的日期元信息。
包括 [year, month, formatterDay, formatterDate, dayOfWeek],可下游直接使用。


108-151: 函数 getWeekOfYearByYMD:完整处理 ISO 8601 周数计算。

  1. 通过对 dayOfYeardayOfWeekfirstDayOfWeek 等综合计算周数。
  2. 考虑了周号可能为 0 或 53 的特殊场景,并向前/向后追溯,确保周数准确。

153-177: 函数 getWeekNosOfYear:利用 getWeekOfYearByYMD 的首尾周号并生成其间序列。

  1. 若末尾周为 1,视为跨年情况,做 53 兜底判断。
  2. 通过 Array.from 创建周号序列,拼接出完整的周列表。
src/utils/date.ts (2)

17-33: 实现正确,但可以完善文档

函数实现正确地返回了对应日期的星期名称。建议在JSDoc中明确说明函数返回的是中文星期名称,以便更好地理解函数用途。


9-11: 代码清晰有效

这些函数实现逻辑清晰,能够有效完成其预期功能。从Utils对象方法重构为独立导出函数的改变提升了代码的模块化和可用性。

Also applies to: 22-33, 40-41, 75-88, 95-99

Comment on lines +106 to +107
const startTime = new Date(date1.replace('-', '/').replace('-', '/'))
const endTime = new Date(date2.replace('-', '/').replace('-', '/'))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

replace方法使用不当

replace方法只会替换第一个匹配项,当日期格式中包含多个'-'时可能导致问题。应该使用带有全局标志的正则表达式。

-  const startTime = new Date(date1.replace('-', '/').replace('-', '/'))
-  const endTime = new Date(date2.replace('-', '/').replace('-', '/'))
+  const startTime = new Date(date1.replace(/-/g, '/'))
+  const endTime = new Date(date2.replace(/-/g, '/'))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const startTime = new Date(date1.replace('-', '/').replace('-', '/'))
const endTime = new Date(date2.replace('-', '/').replace('-', '/'))
const startTime = new Date(date1.replace(/-/g, '/'))
const endTime = new Date(date2.replace(/-/g, '/'))

Comment on lines +48 to +69
export const getMonthDays = (year: string, month: string): number => {
if (/^0/.test(month)) {
month = month.split('')[1]
}
return (
[
0,
31,
isLeapYear(Number(year)) ? 29 : 28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31,
] as number[]
)[month as any]
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

函数实现存在潜在问题

该函数存在几个问题:

  1. 参数类型定义为string,但在使用时当作number处理,类型不一致
  2. 使用正则表达式处理月份前导零的方式不够优雅
  3. 数组索引访问缺少边界检查

建议重构如下:

-export const getMonthDays = (year: string, month: string): number => {
-  if (/^0/.test(month)) {
-    month = month.split('')[1]
-  }
-  return (
-    [
-      0,
-      31,
-      isLeapYear(Number(year)) ? 29 : 28,
-      31,
-      30,
-      31,
-      30,
-      31,
-      31,
-      30,
-      31,
-      30,
-      31,
-    ] as number[]
-  )[month as any]
+export const getMonthDays = (year: string | number, month: string | number): number => {
+  const yearNum = Number(year);
+  const monthNum = Number(month);
+  
+  if (monthNum < 1 || monthNum > 12) {
+    throw new Error('月份必须在1-12之间');
+  }
+  
+  const daysInMonth = [
+    31,
+    isLeapYear(yearNum) ? 29 : 28,
+    31,
+    30,
+    31,
+    30,
+    31,
+    31,
+    30,
+    31,
+    30,
+    31
+  ];
+  
+  return daysInMonth[monthNum - 1];
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const getMonthDays = (year: string, month: string): number => {
if (/^0/.test(month)) {
month = month.split('')[1]
}
return (
[
0,
31,
isLeapYear(Number(year)) ? 29 : 28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31,
] as number[]
)[month as any]
}
export const getMonthDays = (year: string | number, month: string | number): number => {
const yearNum = Number(year);
const monthNum = Number(month);
if (monthNum < 1 || monthNum > 12) {
throw new Error('月份必须在1-12之间');
}
const daysInMonth = [
31,
isLeapYear(yearNum) ? 29 : 28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31
];
return daysInMonth[monthNum - 1];
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🔭 Outside diff range comments (1)
src/packages/calendaritem/calendaritem.taro.tsx (1)

520-533: 🛠️ Refactor suggestion

滚动事件 monthsViewScroll
在滚动时,根据 avgHeight 推算当前所在月份并更新顶部标题,思路可行。但在首尾月份判断和切换区间时逻辑复杂,未来可考虑基于交叉观察器(IntersectionObserver)或更稳定的计算方式。

🧹 Nitpick comments (48)
src/packages/calendar/demos/h5/demo101.tsx (2)

6-6: 建议增加注释说明日期格式

初始化的日期格式${d + 1}-Q2比较特殊,建议添加简短注释说明该格式的含义(下一年的第二季度),以提高代码可读性。

- const [date, setDate] = useState(`${d + 1}-Q2`)
+ // 初始化为下一年的第二季度
+ const [date, setDate] = useState(`${d + 1}-Q2`)

23-31: 建议增加国际化示例

当前演示只展示了基本功能,建议添加国际化相关的示例,以展示刚刚添加的本地化字符串如何在不同语言环境下显示。

src/packages/calendar/demos/taro/demo103.tsx (1)

1-39: 新增的示例正确演示了日历组件的月号显示功能

这个新增的示例组件很好地展示了日历组件中显示月号的功能。示例中通过 showMonthNumber 属性启用了月号显示,并使用动态计算的方式设置了日期范围(当前年份前后两年)。

代码实现合理,但有几点建议:

  1. 函数 setChooseValuechooseData.map 的返回类型为 any,建议明确定义类型
  2. 代码第 11 行直接使用索引 item[3] 获取日期,建议考虑使用更有语义的方式获取日期值

可以考虑这样优化类型定义:

- const setChooseValue = (chooseData: any) => {
-   const dateArr = chooseData.map((item: any) => {
+ interface DateItem {
+   [index: number]: string | number;
+ }
+ const setChooseValue = (chooseData: DateItem[]) => {
+   const dateArr = chooseData.map((item: DateItem) => {
    return item[3]
  })
  setDate([...dateArr])
}
src/packages/calendar/demos/h5/demo103.tsx (1)

15-35: 展示了月份编号功能

这个示例很好地展示了新增的 showMonthNumber 属性功能,允许日历显示月份编号。内联(非弹出式)日历的样式设置合理,高度足够展示完整内容。

建议考虑添加一个简短的注释或者标题,以明确说明这个示例的目的是展示月份编号功能。

<div
  className="test-calendar-wrapper"
+ // 展示带月份编号的多选日历
  style={{
    display: 'flex',
    width: '100%',
    height: '550px',
    overflow: 'hidden',
  }}
>
src/packages/calendar/demos/taro/demo101.tsx (1)

14-33: 季度视图展示和配置

该示例有效地展示了季度视图模式的配置和使用方法。通过设置 viewMode="quarter" 启用季度视图,并提供了合适的样式和尺寸。

值得注意的是,日期范围设置为当前年份的前后两年,这为用户提供了足够的灵活性来查看和选择不同季度。

建议考虑添加一个简短的注释,解释这个示例如何使用季度视图功能。

<View
  className="test-calendar-wrapper"
+ // 演示季度视图模式,允许选择具体季度
  style={{
    display: 'flex',
    width: '100%',
    height: '350px',
    overflow: 'hidden',
  }}
>
src/packages/calendar/demo.taro.tsx (1)

123-128: 添加新功能演示区域

新增了展示季度面板、月面板和周号的演示区域,使用了正确的翻译标题和相应的演示组件。这样可以完整地展示日历组件的新功能。

请确保h2标签与代码其他部分使用的View className="h2"保持一致的样式,可能需要进行样式统一。

-        <h2>{translated.ees99933}</h2>
+        <View className="h2">{translated.ees99933}</View>
-        <h2>{translated.e2s99933}</h2>
+        <View className="h2">{translated.e2s99933}</View>
-        <h2>{translated.e4s99933}</h2>
+        <View className="h2">{translated.e4s99933}</View>
src/packages/calendar/calendar.tsx (2)

113-164: 优化渲染逻辑以支持多种视图模式

重构了 renderItem 函数,根据 viewMode 属性值决定渲染 CalendarViewModeItemCalendarItem 组件。这种条件渲染方式使组件能够灵活支持日、月、季度等不同的视图模式,满足了多样化的日历展示需求。

建议在 onDayClick 处理中使用可选链,避免回调函数为空时的潜在问题:

-onDayClick={(param) => onDayClick && onDayClick(param)}
+onDayClick={(param) => onDayClick?.(param)}
🧰 Tools
🪛 Biome (1.9.4)

[error] 160-160: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)


136-136: 建议避免使用 children 属性传递子组件

React 中传递子组件的标准方式是使用 JSX 元素,而非属性传递。建议修改为:

-<CalendarItem
-  ref={calendarRef}
-  style={style}
-  className={className}
-  children={children}
-  type={type}
-  ...
+<CalendarItem
+  ref={calendarRef}
+  style={style}
+  className={className}
+  type={type}
+  ...
+>
+  {children}
+</CalendarItem>
🧰 Tools
🪛 Biome (1.9.4)

[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

src/packages/calendar/calendarviewmodeitem.taro.tsx (4)

127-176: 初始化与滚动定位逻辑较为复杂,可考虑适度拆分。
requestAniFrameFunc 内部针对不同 viewMode 做多分支处理,与 panelDate 结构互相配合。建议后期根据业务演进将其拆分为更细粒度的函数,增强可读性。


234-284: 季度面板组装逻辑与月面板保持一致。
大体重复了月面板逻辑,便于维护与对照;如后续需要兼容更多模式,可尝试提取公共逻辑做通用处理。


363-383: 子项渲染可扩展程度高。
允许通过 renderDay 定制内容,若无自定义则显示默认文本;建议之后将 <div> 替换为 <View> 以保持 Taro 组件风格一致。

-<div
-  className={classNames(
-    ...
-  )}
-  ...
->
+<View
+  className={classNames(
+    ...
+  )}
+  ...
+>

402-416: 滚动容器合理,样式命名保持连贯。
ScrollView + 内部 <div> 形成容器与面板布局,可考虑后续统一成 Taro 组件 <View> 以保持一致。

src/packages/calendar/calendar.taro.tsx (1)

136-136: 静态分析提示:谨慎使用 children prop。
根据 lint 建议,最好通过 <CalendarItem>子元素</CalendarItem> 的形式传递,确保 JSX 在使用时保持语义一致。

🧰 Tools
🪛 Biome (1.9.4)

[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

src/packages/calendaritem/calendaritem.tsx (4)

14-21: 导入更多日历相关工具函数。

与上一条类似,这些方法与日历逻辑强关联,保持了代码的一致性。建议在文档中集中说明它们的作用和适用场景。


197-231: getMonthData 函数逻辑较复杂。

此处包含多重迭代与条件分支,建议将特定计算(例如天数处理、滚动计算等)抽离为独立小函数,以增强可读性与可测试性。


429-439: initData 汇总初始化流程。

集中管理对月数据、默认值及渲染等多步骤处理,结构清晰,但当调用场景频繁时需留意性能。


525-531: isDisable 函数对非 active 的 day 都视为禁用。

若未来出现自定义类型或特殊标记,需扩展此逻辑;目前功能足以满足常规禁用场景。

src/packages/calendar/calendarviewmodeitem.tsx (1)

84-118: panelDate 数据信息存储。

将 year、months 或 quarters 等整体保存在一个状态中,方便统一管理;若区间跨度过大,可能需考虑虚拟滚动以提升性能。

src/packages/calendar/utils.ts (7)

24-24: 命名改进建议

此处返回 ${month.curData[0]}/${month.curData[1]}/${getNumTwoBit(+day.day)},参数 day 同时作为 CalendarDay 对象也包含 day.day,命名略显混淆。可将 day 改为 cellcalendarDay,提升可读性。


37-38: 函数 isStartAndEnd 的安全性

该函数通过 days.length >= 2 && isEqual(days[0], days[1]) 检查开始和结束是否相同,逻辑明了。但若 days 数组的长度未知,仍需谨慎校验边界值以防数组越界。


39-39: 保持注释风格统一

此行仅为结束花括号或空行,建议保持文件中注释和空行的风格一致,保证代码整洁一致。


40-40: 注释语言

如需兼顾国际化团队协作,可考虑在注释中同时添加英文说明,便于他人理解。


58-75: 函数 getMonths 的区间合理性

通过 endMonth - month + 1 计算剩余月份数组,逻辑直接易懂。但若 month 超过 endMonth 或数值异常,可能产生空结果或无意义数组。可按实际业务场景添加校验。


81-83: formatQuarter 符号约定

使用 Q${quarter} 表示季度,易于理解和通用。如需适配更多语言或自定义命名,可在函数外部统一管理格式化方式。


141-161: 函数 getNextQuarters 的边界说明

month + 3 作为起始,循环到 endMonth,对年底月份的后续季度自然返回空或少量结果,合乎正常逻辑。可通过注释向使用者提示此函数的适用范围和返回值边界。

src/packages/calendaritem/utils.ts (4)

9-19: 函数 getCurrMonthData

通过 type 来判断是 'prev' 还是 'next',然后修改 yearmonth,逻辑清晰。可在 TypeScript 类型声明时,限制 type 的可选字符串值(如 'prev' | 'next'),避免滥用。


21-36: 函数 getDaysStatus

针对某些月份第一天是周日时,去除多余的 7 天以避免界面留白,思路可行。如需适配更多特殊场景,建议在函数内加入对首日星期数的判定注释和单测。


70-98: 函数 getWeekDate

根据 firstDayOfWeek 不同,分别处理周日到周六或周一到周日。对 day=0 做特殊处理,以符合自然语言习惯。建议在注释中进一步说明该逻辑的来由,以便后期维护或修改。


100-106: 函数 formatResultDate

返回丰富的数组 [year, month, formatterDay, formatterDate, dayOfWeek],使用灵活。但如果数据在更多场景下被复用,返回对象形式可能更具可读性和可扩展性。

src/utils/date.ts (4)

17-33: 函数 getWhatDay

利用 new Date(year, month - 1, day) 拿到星期索引再映射到汉字数组,直观易懂。若需多语言支持,可将 '星期〇' 等字符串外置成可配置数据。


39-42: 函数 getMonthPreDay

返回指定月份第一天的星期数并将周日设为 7,适用于部分日历的排布。若项目中存在以周一为一周起点的场景,建议通过参数或配置来区分。


44-69: 函数 getMonthDays

依赖 isLeapYear 来处理 2 月天数,同时针对其他月份一一列举,逻辑完备。正则去掉月份前导零也有效,但可考虑直接用 Number() 转型,让代码更简洁。


79-88: 函数 date2Str

借助 getNumTwoBit 统一格式化年、月、日,并用可自定义的 split 拼接成字符串,常规场景下实用方便。请留意与其他函数中的日期分隔符保持一致。

src/packages/calendaritem/calendaritem.taro.tsx (15)

18-22: 引入 formatResultDate 等工具函数
新增的工具函数能使日期解析或格式化逻辑更易理解。但请确保与上层业务的日期格式约束保持一致,并在测试中覆盖不同的日期边界情况。


25-25: usePropsValue 用法检查
这里使用 usePropsValue 管理受控与非受控状态。在整合默认值与外部传入值时,要注意回调 onChange 与组件内部状态保持同步,避免意外的状态丢失或重复渲染。


93-93: 默认不显示月数字
showMonthNumber 设置为 false,意味着默认情况下不展示月份数字或周号。若此项是 PR 要点功能之一,建议在文档或示例中突出其配置方式,方便使用者了解。


146-148: 新增 classPrefix 与 dayPrefix
通过统一的 classPrefix 定义 BEM 命名空间有助于隔离样式、减少冲突,做法合理。可在后续考虑提取至公共常量配置,便于多处组件复用相同风格。


182-182: 单选模式下空字符串默认值
type='single' 且不传入 defaultValue 时,返回空字符串符合逻辑。但若日历必须要有一个初始选中日期,可在文档里强调或提示开发者尽量提供具体日期,避免意外无选中状态。


200-235: getMonthData & 月度数据初始化
该段逻辑根据年月动态生成月度信息,包含天数与滚动高度等,对于性能较大的日期范围(如跨多年)有可能加载压力较大。可考虑分批懒加载或虚拟渲染技术,以优化在移动端的滚动体验。


242-248: setReachedYearMonthInfo 更改回调
当翻阅到指定月份后,触发 onPageChange 回调并更新 yearMonthTitle。逻辑清晰,但需要确保翻页频次较多时不会造成不必要的多次触发,可在实际滚动行为中进行一定的阈值或去抖处理。


376-412: renderCurrentDate 与初始化点击事件
在默认值的渲染过程中调用 handleDayClick,以便设置组件内部状态。需注意当默认值合法性较复杂或数据量较大时,可能多次触发 handleDayClick 导致渲染开销变大,可在后续进行性能测试。


414-416: getMonthsPanel 函数返回值可简化
此函数只是获取 monthsPanel.current 引用。若仅在少数位置使用,可直接使用 monthsPanel.current,减少中间函数调用。此类封装可在必要时再添加。


418-420: getMonthsRef 函数相同建议
与上面类似,若这个函数占用较少场景,可考虑合并至视图逻辑或直接使用 ref,减少代码跳转。


452-462: initData 函数执行流程
依次计算月数 → 生成月数据 → 初始化默认值 → 指定可见范围 → 进行动画定位,很完整的业务流程。建议在注释中进一步说明各步骤的顺序与耦合度,提升团队可读性。


482-517: 平滑滚动到指定日期
使用 setInterval 模拟了动画滚动,配合 10 次循环均匀移动。可考虑使用 CSS 滚动动画或 ScrollView 自带 scrollWithAnimation 以减少自定义逻辑,并确保多端一致性。


543-543: 调用 setDefaultRange 后重绘
在滚动判断结尾调用 setDefaultRange,对可见区间做了再次筛选。需注意避免在一次滚动事件中重复多次触发范围更新,从而造成可能的循环触发。


559-584: getClasses 用于获取日期单元格的样式
在 range 或 week 模式下,通过比较 currentDate 数组来判断是否处于选中态,结构分支多且容易出错。若有机会,可拆分逻辑并使用集中式的状态判断函数,减少嵌套。


792-814: renderPanel 函数
此函数除了渲染月份标题和天数外,新增了一个可选的周号区域 month.weekNo,满足展示周数的需求。要注意 weekNo 仅在特定视图(如周视图或指定需求)下才有效,可能需要额外条件判断尽量避免多余渲染。

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 31dd4ee and 95632c9.

📒 Files selected for processing (50)
  • src/locales/base.ts (1 hunks)
  • src/locales/en-US.ts (1 hunks)
  • src/locales/id-ID.ts (1 hunks)
  • src/locales/tr-TR.ts (1 hunks)
  • src/locales/zh-CN.ts (1 hunks)
  • src/locales/zh-TW.ts (1 hunks)
  • src/locales/zh-UG.ts (1 hunks)
  • src/packages/calendar/calendar.scss (4 hunks)
  • src/packages/calendar/calendar.taro.tsx (6 hunks)
  • src/packages/calendar/calendar.tsx (6 hunks)
  • src/packages/calendar/calendarviewmode.scss (1 hunks)
  • src/packages/calendar/calendarviewmodeitem.taro.tsx (1 hunks)
  • src/packages/calendar/calendarviewmodeitem.tsx (1 hunks)
  • src/packages/calendar/demo.taro.tsx (3 hunks)
  • src/packages/calendar/demo.tsx (3 hunks)
  • src/packages/calendar/demos/h5/demo1.tsx (2 hunks)
  • src/packages/calendar/demos/h5/demo10.tsx (3 hunks)
  • src/packages/calendar/demos/h5/demo101.tsx (1 hunks)
  • src/packages/calendar/demos/h5/demo102.tsx (1 hunks)
  • src/packages/calendar/demos/h5/demo103.tsx (1 hunks)
  • src/packages/calendar/demos/h5/demo11.tsx (3 hunks)
  • src/packages/calendar/demos/h5/demo2.tsx (2 hunks)
  • src/packages/calendar/demos/h5/demo3.tsx (2 hunks)
  • src/packages/calendar/demos/h5/demo4.tsx (2 hunks)
  • src/packages/calendar/demos/h5/demo5.tsx (3 hunks)
  • src/packages/calendar/demos/h5/demo6.tsx (3 hunks)
  • src/packages/calendar/demos/h5/demo7.tsx (2 hunks)
  • src/packages/calendar/demos/h5/demo8.tsx (2 hunks)
  • src/packages/calendar/demos/h5/demo9.tsx (3 hunks)
  • src/packages/calendar/demos/taro/demo10.tsx (3 hunks)
  • src/packages/calendar/demos/taro/demo101.tsx (1 hunks)
  • src/packages/calendar/demos/taro/demo102.tsx (1 hunks)
  • src/packages/calendar/demos/taro/demo103.tsx (1 hunks)
  • src/packages/calendar/demos/taro/demo11.tsx (3 hunks)
  • src/packages/calendar/demos/taro/demo2.tsx (2 hunks)
  • src/packages/calendar/demos/taro/demo3.tsx (2 hunks)
  • src/packages/calendar/demos/taro/demo4.tsx (2 hunks)
  • src/packages/calendar/demos/taro/demo5.tsx (3 hunks)
  • src/packages/calendar/demos/taro/demo6.tsx (3 hunks)
  • src/packages/calendar/demos/taro/demo7.tsx (2 hunks)
  • src/packages/calendar/demos/taro/demo8.tsx (2 hunks)
  • src/packages/calendar/demos/taro/demo9.tsx (3 hunks)
  • src/packages/calendar/utils.ts (2 hunks)
  • src/packages/calendarcard/utils.ts (3 hunks)
  • src/packages/calendaritem/calendaritem.taro.tsx (16 hunks)
  • src/packages/calendaritem/calendaritem.tsx (19 hunks)
  • src/packages/calendaritem/utils.ts (1 hunks)
  • src/styles/variables.scss (1 hunks)
  • src/types/spec/calendar/base.ts (5 hunks)
  • src/utils/date.ts (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/packages/calendar/calendar.tsx

[error] 160-160: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

src/packages/calendar/calendar.taro.tsx

[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

🔇 Additional comments (177)
src/locales/tr-TR.ts (1)

45-48: 添加了日历组件所需的语言缩写

新增的这四个键值对很好地支持了日历组件的月面板、季面板功能,使得土耳其语本地化更加完整。缩写选择恰当且保持了简洁性。

src/locales/zh-UG.ts (1)

37-40: 维吾尔语本地化支持日历新功能

为日历组件添加了维吾尔语的周、月、年、季度缩写,这些缩写符合维吾尔语的语言特点,与其他语言文件保持了一致的更新模式。这些更改很好地支持了日历组件的新增功能。

src/packages/calendar/demos/taro/demo7.tsx (1)

4-4: 组件命名更加简洁

将组件从 Demo7 重命名为 Demo,使命名更加简洁明了。同时移除了 startDateendDate 属性,这可能是因为组件现在采用了动态的日期处理方式。

Also applies to: 37-37

src/styles/variables.scss (1)

1028-1031: 新增日历面板项宽度变量

添加了 $calendar-panel-item-width 变量,用于控制日历面板项的宽度,默认值为 24.85%。这个变量的添加对支持月面板和季面板的显示非常必要,确保了不同视图模式下的布局一致性。

src/locales/en-US.ts (1)

37-40: 已添加日历组件所需的国际化字符串

这些新增的字符串键值对为日历组件的新功能提供了必要的语言支持,包括周、月、年和季度的英文简写。这与PR的目标一致,为支持月面板和季面板提供了必要的国际化基础。

src/packages/calendar/demos/h5/demo1.tsx (1)

5-5: 组件命名统一为Demo

将组件从Demo1重命名为Demo,保持了demo文件中组件命名的一致性,使代码风格更加统一。

Also applies to: 48-48

src/locales/base.ts (1)

37-40: 已添加日历本地化接口的新属性

calendaritem接口添加了四个新属性(week、month、year、quarter),确保所有语言文件可以正确实现这些属性。这是支持新的日历显示模式所必需的,与PR目标一致。

src/packages/calendar/demos/h5/demo101.tsx (1)

1-36: 新增季度视图模式的演示组件

这个新增的演示组件展示了日历组件的季度视图模式功能,通过viewMode="quarter"属性实现。代码结构清晰,功能完整,很好地展示了PR中"支持季面板"的目标功能。

布局和样式设置合理,确保了日历在容器中的正确显示。日期范围设置(前后两年)提供了良好的用户体验。

src/packages/calendar/demos/h5/demo102.tsx (1)

1-35: 组件实现清晰规范,月视图功能展示完整

代码实现了一个展示日历月视图的示例组件,通过正确配置 Calendar 组件的 viewMode="month" 属性来实现。代码结构清晰,逻辑简洁,且符合 React 最佳实践:

  • 使用 useState 正确管理日期状态
  • 动态计算日期范围,基于当前年份
  • 提供了用户交互的回调函数

这个示例很好地演示了日历组件的月视图功能,是此 PR 新增的重要特性之一。

src/locales/id-ID.ts (1)

37-40: 已正确添加印尼语言的日历缩写标签

为 calendaritem 对象添加了四个新属性,以支持印尼语(ID)的日历缩写标签:

  • week: 'Mg' (周)
  • month: 'Bl' (月)
  • year: 'Th' (年)
  • quarter: 'Kt' (季度)

这些添加与其他语言文件的更新保持一致,完善了日历组件的国际化支持。

src/packages/calendar/demos/h5/demo4.tsx (3)

4-5: 组件名称规范化并优化了实现

将组件从 Demo4 重命名为 Demo,符合命名规范,有助于组件在文档中的统一展示。同时添加了当前年份的动态获取,提高了代码的复用性。


32-33: 日期范围动态化处理,增强了示例的灵活性

将日历的起止日期从硬编码值修改为基于当前年份的动态计算,使示例更具通用性和可维护性:

  • startDate 设置为去年的 11 月 21 日
  • endDate 设置为明年的 9 月 10 日

这种实现方式避免了示例过时的问题,无论何时运行示例都能展示合适的日期范围。


41-41: 更新了导出语句以匹配组件名称更改

导出语句从 export default Demo4 更新为 export default Demo,与组件重命名保持一致。

src/packages/calendar/demos/h5/demo3.tsx (3)

4-5: 组件名称规范化并添加了动态年份获取

将组件从 Demo3 重命名为 Demo,保持了所有示例组件的命名一致性。同时添加了当前年份的动态获取,这有助于后续日期计算的灵活性。


35-36: 优化了日期范围的设置方式

将日历的起止日期从静态值更改为基于当前年份的动态计算:

  • startDate: 设置为前一年的 11 月 21 日
  • endDate: 设置为后一年的 9 月 10 日

这种实现方式确保了示例在任何时间点运行都能显示相对合理的日期范围,增强了示例的实用性和时效性。


43-43: 更新了导出语句以匹配新的组件名称

导出语句从 export default Demo3 更新为 export default Demo,与组件重命名保持一致。

src/locales/zh-CN.ts (1)

39-42: 这些新增的本地化字符串提供了日历组件所需的支持

新增的 weekmonthyearquarter 本地化字符串与 PR 的目标相符,为日历组件的新功能提供了必要的本地化支持。这些新增的文本用于标记月面板、季面板以及周号显示。

建议检查其他语言文件是否也已添加对应的翻译,以确保多语言一致性。

src/packages/calendar/demos/h5/demo5.tsx (3)

4-6: 组件重命名和动态日期计算的改进

将组件从 Demo5 重命名为 Demo 符合标准化命名的最佳实践。引入变量 d 来动态获取当前年份是一个很好的改进,使示例更具通用性和可维护性。


38-39: 动态日期范围设置

使用动态计算的方式设置 startDateendDate,替换了之前的硬编码日期,这样可以确保示例在不同时间点都能正常工作,显示合理的日期范围。


49-49: 更新了默认导出名称

默认导出名称已更新为 Demo,与组件名称保持一致。

src/packages/calendar/demos/taro/demo5.tsx (3)

4-6: 组件重命名和动态日期计算的改进

将组件从 Demo5 重命名为 Demo 符合标准化命名的最佳实践。引入变量 d 来动态获取当前年份是一个很好的改进,使示例更具通用性和可维护性。


38-39: 动态日期范围设置

使用动态计算的方式设置 startDateendDate,替换了之前的硬编码日期,这样可以确保示例在不同时间点都能正常工作,显示合理的日期范围。


48-48: 更新了默认导出名称

默认导出名称已更新为 Demo,与组件名称保持一致。

src/packages/calendar/demos/taro/demo3.tsx (3)

4-5: 组件重命名和添加动态年份处理

组件从 Demo3 重命名为 Demo,并添加了获取当前年份的变量 d,用于动态计算日期范围。这种命名简化和动态计算的方式更加符合最佳实践。


35-36: 动态日期范围设置

使用当前年份变量 d 动态计算 startDateendDate,替换了原先的硬编码日期值。这样的改动使示例更加通用,可以适应不同年份,提高了代码的可维护性。


43-43: 更新默认导出

导出名称从 Demo3 改为 Demo,与组件命名保持一致,符合代码规范。

src/packages/calendar/demos/taro/demo102.tsx (1)

1-37: 新增月视图演示组件

这个新组件很好地展示了日历组件的月视图功能,符合PR的目标。以下几点值得注意:

  1. 正确使用了 viewMode="month" 属性来显示月视图
  2. 添加了动态年份计算,使演示更具通用性
  3. 提供了样式设置和交互功能(onItemClick)
  4. 设置了合理的日期范围(前后两年)

这是一个设计良好的示例组件,清晰地展示了月视图功能。

src/packages/calendar/demos/h5/demo9.tsx (3)

12-14: 组件重命名和动态日期初始化

组件从 Demo9 重命名为 Demo,并添加了动态年份变量 d。初始日期数组也从硬编码值改为基于当前年份的动态值,这样的改动提高了代码的可维护性和通用性。


60-61: 更新日期范围为动态计算

使用当前年份变量 d 动态计算 startDateendDate,确保示例在任何时候都能显示合理的日期范围。这种方式比硬编码日期值更加灵活。


75-75: 更新默认导出

导出名称从 Demo9 改为 Demo,保持与组件命名一致性。

src/packages/calendar/demos/taro/demo4.tsx (3)

4-5: 组件重命名和动态年份处理

组件从 Demo4 重命名为 Demo,并添加了动态年份变量 d,用于计算日期范围。这种改动提高了代码的可维护性。


32-33: 动态日期范围设置

将硬编码的日期范围改为基于当前年份的动态计算,使示例在任何时间点都能正确展示,并保持适当的日期范围。这种改进增强了组件的通用性。


41-41: 更新默认导出

导出名称从 Demo4 改为 Demo,与组件命名保持一致,遵循了代码规范。

src/packages/calendar/demos/h5/demo8.tsx (3)

4-6: 改进了组件的动态性

使用当前年份动态生成日期,使得示例更加灵活,不依赖于硬编码年份。这种改进使得组件能够长期保持相关性,而不需要定期更新硬编码日期。


37-38: 日期范围更加灵活

使用动态计算的年份设置起始日期和结束日期,比之前的硬编码值更加灵活。这样做确保日历组件总是显示与当前年份相关的合理日期范围。


46-46: 组件命名更加统一

将组件名从 Demo8 更改为 Demo,与其他演示文件保持一致的命名规范。

src/packages/calendar/demos/h5/demo103.tsx (1)

1-13: 日期选择逻辑实现合理

setChooseValue 函数通过提取选定日期数组中的第四个元素(索引为3)来更新状态,处理方式简洁有效。这种实现方式与其他日历示例保持一致。

src/packages/calendar/demos/h5/demo10.tsx (3)

55-57: 改进了日期动态生成

使用当前年份动态计算日期范围,替换了硬编码的年份,使示例更具可维护性。这种方法确保示例代码不会因年份变化而过时。


75-79: 动态日期导航功能

现在 goDate 函数使用动态年份计算目标日期,这与整体改进保持一致,使组件更加灵活。


139-140: 日期范围设置一致性

使用动态计算的年份范围设置 startDateendDate,与其他示例保持一致的实现方式。范围设置为当前年份的前后一年,提供了合理的可选日期范围。

src/packages/calendar/demos/taro/demo101.tsx (1)

5-12: 季度视图功能实现

这个组件很好地展示了新增的季度视图功能。select 函数处理季度项目的点击事件,并更新状态,实现逻辑清晰。

使用当前年份+1年作为默认季度(${d + 1}-Q2)是一个好的选择,它展示了日历在未来日期上的功能。

src/packages/calendar/demos/taro/demo6.tsx (1)

20-22: 组件重命名并使用动态日期范围的优化

将组件从 Demo6 重命名为 Demo,并引入当前年份变量 d,使日历组件的日期范围更加动态化。这种改进使得示例代码更具可持续性,不再需要每年手动更新硬编码的日期值。

-const Demo6 = () => {
+const Demo = () => {
+  const d = new Date().getFullYear()

-  startDate="2023-01-01"
-  endDate="2024-09-10"
+  startDate={`${d - 1}-11-21`}
+  endDate={`${d + 1}-09-10`}

-export default Demo6
+export default Demo

Also applies to: 91-92, 138-138

src/packages/calendar/demos/h5/demo6.tsx (1)

19-20: 组件重命名并使用动态日期范围的优化

将组件从 Demo6 重命名为 Demo,并引入当前年份变量 d,使日历组件的日期范围更加动态化。这种改进使得示例代码更具可持续性,不再需要每年手动更新硬编码的日期值。

-const Demo6 = () => {
+const Demo = () => {
+  const d = new Date().getFullYear()

-  startDate="2023-01-01"
-  endDate="2024-09-10"
+  startDate={`${d - 1}-11-21`}
+  endDate={`${d + 1}-09-10`}

-export default Demo6
+export default Demo

Also applies to: 95-96, 142-142

src/packages/calendar/demos/taro/demo10.tsx (1)

55-57: 组件重命名并使用动态日期实现

将组件从 Demo10 重命名为 Demo,并通过引入当前年份变量 d 使所有日期相关的值动态化:

  1. 初始日期范围设置为当年的1月23日至30日
  2. 导航函数目标日期设置为当年的4月23日
  3. 日历组件的开始和结束日期分别设置为去年11月21日和明年9月10日

另外,添加了关于京东小程序IDE兼容性的注释说明,这有助于其他开发者理解特定环境下的处理方式。

-const Demo10 = () => {
+const Demo = () => {
+  const d = new Date().getFullYear()
-  const [date, setDate] = useState<string[]>(['2023-01-23', '2023-01-30'])
+  const [date, setDate] = useState<string[]>([`${d}-01-23`, `${d}-01-30`])

+  // setDate(['2024-10-01', '2024-10-01'])
+  // 该行用于京东小程序IDE下问题的修复。
+  // 京东小程序,真机可不需要。

-  calendarRef.current.scrollToDate('2023-04-01')
+  calendarRef.current.scrollToDate(`${d}-04-23`)

-  startDate="2022-12-22"
-  endDate="2024-12-31"
+  startDate={`${d - 1}-11-21`}
+  endDate={`${d + 1}-09-10`}

-export default Demo10
+export default Demo

Also applies to: 74-77, 78-78, 137-138, 146-146

src/packages/calendar/demos/h5/demo7.tsx (1)

4-4: 组件重命名为统一命名风格

将组件从 Demo7 重命名为 Demo,保持与其他示例组件的命名一致性。这种统一的命名方式有助于提高代码的可读性和可维护性。

-const Demo7 = () => {
+const Demo = () => {

-export default Demo7
+export default Demo

Also applies to: 37-37

src/packages/calendar/demos/h5/demo2.tsx (3)

4-6: 组件重命名并使用动态年份更新

将组件从Demo2重命名为Demo,并添加了根据当前年份动态设置日期的功能。这样可以确保示例代码在不同年份都能正常显示相关日期,无需手动更新。


36-37: 日历范围使用动态计算

使用当前年份动态计算日历的起始和结束日期,提高了组件的灵活性和可维护性。这种方式可以确保示例在任何年份运行时都能显示合理的日期范围。


45-45: 更新导出名称

已更新导出语句以匹配新的组件名称Demo,保持代码一致性。

src/packages/calendar/demo.taro.tsx (2)

18-20: 添加新的演示组件

导入了三个新的演示组件:Demo101Demo102Demo103,用于展示日历组件的新功能。确保这些组件已经正确实现并且不会导致运行时错误。


29-101: 添加多语言翻译支持

为新功能添加了中文简体、繁体和英文的翻译文本,包括"季度面板"、"月面板"、"展示周号"等。这确保了新功能在不同语言环境下有一致的用户体验。

建议检查一下翻译文本的一致性和准确性,特别是繁体中文和英文版本的翻译。

src/packages/calendar/demos/taro/demo9.tsx (3)

12-14: 组件重命名并使用动态年份

将组件从Demo9重命名为Demo,并添加了根据当前年份动态设置日期的功能。这种方式可以确保示例在不同年份都能正常运行,提高了代码的可维护性。


60-61: 动态计算日历范围

使用当前年份变量动态计算日历的起始和结束日期,使示例更加灵活。这样可以避免硬编码日期带来的维护问题,确保示例在未来几年内无需修改也能正常工作。


75-75: 更新导出语句

已更新导出语句以匹配新的组件名称Demo,保持代码一致性。

src/packages/calendar/demos/taro/demo8.tsx (3)

4-6: 组件重命名并使用动态年份

将组件从Demo8重命名为Demo,并引入了当前年份的动态计算,用于设置日期状态初始值。这种方式使示例更加灵活,能够适应不同年份的使用场景。


37-38: 动态设置日历日期范围

使用当前年份动态计算日历组件的startDateendDate属性,替换了硬编码的日期值。这样可以确保示例在未来几年内都能正常运行,无需手动更新日期。


46-46: 更新导出语句

已更新导出语句以匹配新的组件名称Demo,保持代码一致性。

src/locales/zh-TW.ts (1)

39-42: 很好的本地化添加!

为日历组件添加了"周"、"月"、"年"和"季度"的繁體中文翻译,与PR目标中提到的支持月面板、季面板以及展示周号功能相符。这些添加确保了繁體中文用户界面的完整性。

src/packages/calendar/demos/h5/demo11.tsx (3)

4-6: 优化了组件名称和动态日期处理

将组件名从Demo11改为更通用的Demo,并使用new Date().getFullYear()动态获取当前年份,使示例更具时效性。这样的改进使得示例代码在未来几年内都能正常工作,而不会显示过时的日期。


31-32: 使用动态年份计算日期范围

通过使用计算后的年份(${d - 1}${d + 1})来设置startDateendDate,使日历范围相对于当前年份动态调整,提高了代码的可维护性。


43-43: 更新了导出声明

导出声明已更新为匹配新的组件名称Demo,保持了代码的一致性。

src/packages/calendar/demos/taro/demo2.tsx (3)

5-6: 引入了动态日期计算

添加了动态年份计算,并使用模板字符串动态生成日期值,使示例更加通用。这是一个很好的改进,避免了硬编码特定年份。


36-37: 使用动态年份设置日期范围

通过使用计算后的年份(${d - 1}${d + 1})来设置startDateendDate,使日历范围能够动态调整,无需每年手动更新代码。


4-45: 组件名称未更新

注意到组件名称仍然是Demo2,而导出语句也没有更改。与其他示例文件(如demo11.tsx)的模式不一致,那里组件名已更新为Demo。请确认这是否是有意为之,或者是否应该保持一致性。

src/packages/calendar/demo.tsx (3)

15-17: 新增了三个演示组件

导入了新的演示组件Demo101Demo102Demo103,用于展示新增的功能(季度面板、月面板和周号展示)。


26-96: 完善了多语言翻译支持

为新增功能添加了中文(简体和繁体)和英文的翻译条目,包括"至"、"请选择起始时间"、"请选择截止时间"、"季度面板"、"月面板"、"展示周号"等。这些翻译条目确保了新功能在不同语言环境下的用户体验一致性。


117-122: 添加了新功能的演示部分

使用新导入的组件创建了展示季度面板、月面板和周号功能的新部分,与PR目标完全一致。这些演示部分将帮助用户理解和使用新增的功能。

src/packages/calendar/calendarviewmode.scss (1)

1-181: 良好的风格和组织结构

新增的 calendarviewmode.scss 文件结构清晰,使用了与现有日历组件一致的样式命名和布局方式。样式变量的使用有助于保持整个组件库的一致性。这个文件为新增的日历视图模式提供了必要的样式支持,符合设计规范。

建议:可以考虑将一些与 calendar.scss 重复的样式提取到共享的 mixin 中,以减少代码重复,提高维护性。

src/packages/calendar/calendar.scss (4)

2-2: 引入新的视图模式样式文件

引入 calendarviewmode.scss 文件,为日历组件的不同视图模式提供样式支持,符合组件扩展需求。


66-68: 添加周视图缩进样式

为周视图添加左侧缩进,当显示周号时保证布局合理。


118-132: 增加周号显示样式

新增周号显示的样式定义,包括宽度和索引样式,使周号显示更加清晰和美观。使用了与整体设计一致的样式变量(如字体大小、行高等),保持了UI的一致性。


221-223: 添加收缩布局样式

新增 shrink 类设置为 flex 布局,支持在不同视图模式下的灵活布局调整。

src/packages/calendarcard/utils.ts (4)

1-1: 优化导入方式

Utils 对象导入更改为直接导入具体函数 getMonthPreDaygetMonthDays,这种修改有利于代码的可读性和可维护性,同时也有利于打包工具进行摇树优化(tree-shaking)。


32-32: 使用直接导入的函数替换

Utils.getMonthPreDay 替换为直接使用 getMonthPreDay,保持了功能一致性的同时简化了代码。


38-38: 使用直接导入的函数替换

Utils.getMonthDays 替换为直接使用 getMonthDays,保持了功能一致性的同时简化了代码。


54-54: 使用直接导入的函数替换

Utils.getMonthDays 替换为直接使用 getMonthDays,保持了功能一致性的同时简化了代码。

src/packages/calendar/calendar.tsx (6)

4-5: 导入新的视图模式组件和工具函数

添加了 CalendarViewModeItem 组件导入和 getDateString 工具函数导入,为支持多种视图模式(日、月、季度)提供了必要的组件和功能支持。


13-13: 添加视图模式默认属性

为日历组件添加 viewMode 默认属性,并设置默认值为 'day',支持不同视图模式的渲染,符合需求。


18-22: 更新默认属性和日期处理方式

添加了 value 默认属性,并将 startDateendDate 更新为使用 getDateString 函数处理,简化了日期字符串的生成逻辑,提高了代码的可维护性。


28-28: 添加月份数字显示控制

新增 showMonthNumber 属性并默认设为 false,该属性用于控制是否在日历中显示月份数字,增强了组件的可配置性。


39-39: 添加项目点击回调

新增 onItemClick 回调函数,为不同视图模式下的项目点击事件提供处理机制,增强了组件的交互能力。


170-170: 更新弹出条件

更新了 Popup 组件的渲染条件,增加了对 viewMode === 'day' 的判断,确保只有在日视图模式下才显示弹出框,这符合用户体验的设计,使交互更加合理。

src/packages/calendar/demos/taro/demo11.tsx (5)

3-3: 使用 Taro View 替换原生 div 的做法良好。
这能确保在 Taro 环境中保持更好的组件兼容性。


5-7: 动态年份处理可提升组件的适配性。
使用 new Date().getFullYear() 替换硬编码年份,有助于让日期始终与当前年份同步,增强可维护性。


19-19: 语义化标签替换对接 Taro UI 生态。
将父级元素改用 <View>,在 Taro 中更符合组件化规范,布局也更统一。


32-33: 日期范围设置宽泛,建议确认是否符合业务需求。
此处将开始日期设为去年、结束日期设为明年,时间跨度较大,请确保与实际使用场景相符。

您可在相关业务逻辑或文档中确认实际所需的选择范围;如需缩小范围,可进一步修改。


44-44: 组件命名统一性良好。
将组件命名改为 Demo,与其他示例文件看齐,有助于更好地管理与识别。

src/packages/calendar/calendarviewmodeitem.taro.tsx (17)

1-10: 导入与基础工具依赖合理。
这些依赖涵盖了 Taro、classnames、自定义工具函数等,整体结构清晰,没有明显多余或遗漏引入。


28-34: 常量命名含义明确。
YearMonthPanelHeightYearQuarterPanelHeight 分别用于月面板和季度面板高度,命名直观易于理解。


36-48: Props 接口类型定义全面。
CalendarViewModeItemProps 在支持多种视图模式与回调方面描述得较为清晰,满足业务需求。


49-61: 默认参数覆盖合理。
通过 defaultProps 合并可选配置,使组件的可用性和扩展性更好。尤其是 showTodayscrollAnimation 等默认值可为多数场景提供便利。


63-82: 使用 forwardRef 提供滚动控制效果不错。
在日历场景中,通过 ref 自动滚动到指定位置很常见,这样组件可复用性更高。


85-107: 月份与季度数据结构一体化管理可提高扩展性。
panelDate 同时存储 months 与 quarters,有助于在后续功能中快速调整视图模式;但同时需注意数据结构的可维护性,如有更多视图模式时可能需要更灵活的结构。


177-179: 当前年份判断逻辑简洁。
通过字符串分割后只比较年份部分,能够快捷地标明当年数据。


180-233: 跨年区间的月面板数据生成逻辑完备。
在同一年、跨多年的场景下都能正确收集月份信息。若业务对天精度要求更高,可考虑进一步精细化日期截断逻辑。


290-300: 初始化数据与默认值滚动位置关联。
initData 将调用 getMonthsDatagetQuartersData 生成完整面板数据,并配合后续副作用进行滚动处理,流程合理。


302-304: 二次 useEffect 优化面板滚动。
panelDate 更新后再调用 requestAniFrameFunc 完成面板定位,可以避免滚动位置计算不准的闪烁。


306-308: 组件初始化向副作用中抽离。
仅在组件首次挂载时执行 initData,不会在依赖变化时重复触发,逻辑稳健。


315-323: 点击事件响应与 onItemClick 回调整合准确。
通过 viewMode 区分月份与季度拼接逻辑,适配当前组件需求;能正确拿到并设置选中值。


329-345: isDisableisActive 辅助方法具备良好可读性。
携带 item.type 区分状态,能直观决定是否显示禁用态与选中态,后续如需更多状态可在此扩展。


349-361: 头部标题可按需隐藏。
renderHeader 如显示标题则渲染 <View> ,若不需要则返回 null,用可选逻辑避免重复渲染。


385-400: 面板遍历与布局逻辑清晰。
按年份拆分渲染 <div> 面板,再循环渲染月或季度项目,有助于快速定位与管理。


418-424: 整体返回结构良好,组件封装完整。
在必要位置渲染头部与主要内容,方便后续在项目中复用。


426-428: 组件命名与导出保持简洁。
displayName 的指定也能帮助在调试工具中更好地识别组件。

src/packages/calendar/calendar.taro.tsx (11)

4-4: 添加新组件 CalendarViewModeItem 引入,多视图模式更灵活。
在同一日历组件内区分 “day” 与其他模式,能更好地满足多种展示需求。


5-5: getDateString 替换老方法,数据更易维护。
以统一方式生成日期字符串,减少对特定工具函数的依赖,也方便后续进行国际化或其他处理。


13-13: 默认视图模式设为 'day' 符合常见业务场景。
大部分场景下用户都会关注天视图,可节省额外配置;若需要切换到月、季等模式可在外部传参覆盖。


18-18: value 属性并入默认值便于初始渲染。
同时支持受控与非受控方式,避免业务方二次封装时增加复杂度。


20-21: getDateString 生成默认起止时间。
替代原先写死的函数或硬编码,让组件在初始化时更具灵活性。


28-28: 新属性 showMonthNumber 提供更丰富的日历显示选项。
能够在天视图中加上月份数字或做更多定制,增强可视化对比。


39-39: 新增 onItemClick 回调更细化事件处理。
与 dayClick 相比,可在多视图模式下统一使用此回调处理月份或季度点击行为。


55-55: 视图模式通过 viewMode 统一控制。
通过区分 'day' 与非 'day',减少大量 if/else 逻辑,代码更清晰。


81-81: onItemClick 函数传递到子组件,关注点击事件更直观。
这样不会破坏原有的 onDayClick 逻辑,同时能兼容多模式需求。


113-131: 多视图分支渲染逻辑简明易懂。
viewMode 不为 'day' 时渲染 CalendarViewModeItem,否则渲染 CalendarItem,实现多模式共用同一组件。


170-177: 仅在 viewMode='day' 时使用 Popup 合理。
其他视图模式无需弹窗效果,可直接以内嵌方式展示,减少多余交互。

src/packages/calendaritem/calendaritem.tsx (19)

7-13: 引入新的日期工具函数,增强可读性。

这些函数替代原先的通用工具,使日历逻辑更具可维护性。请在文档中同步说明它们的用法,以便后续维护。


64-64: 新增 showMonthNumber 属性。

此属性有利于在月面板中显示月份编号,满足部分界面的需求,建议在文档或示例中提供对应的使用演示。


84-85: 默认日期范围配置可能受闰年影响。

这里将起始和结束日期分别设置为当日与当日后 365 天,若用户跨越闰年或特殊日历规则,可能存在小幅误差。建议确认闰年的边界情况或在上层逻辑对日期范围进行校验。


92-92: showMonthNumber 的默认值设为 false。

此默认值与大多数使用场景相符,暂不需要额外配置即可正常展示日历。


119-119: 保留对 value 的解构。

代码结构清晰,未发现明显问题。


129-129: 在解构 props 时包含 showMonthNumber。

与默认值设置保持一致,无需额外关注。


144-145: 使用单独前缀 classPrefix/dayPrefix。

该做法可避免类名冲突,增强样式维护的可控性。


160-161: 通过 propStartDate/propEndDate 设置默认日期。

与调用方传入值结合使用时,提升可读性并减少重复逻辑。


179-179: 根据类型决定返回值类型(字符串或数组)。

此逻辑简明直观,方便后续处理。


238-243: 翻页事件 onPageChange。

在这部分可实时获取用户滚动到的年月信息,接口设计合理,可在外部进行分析或统计。


270-328: setDefaultDate 函数覆盖多种类型逻辑。

涉及 single、range、multiple、week 等多种情况,建议在单元测试中重点覆盖这些分支,避免未来新增逻辑时出现回归。


451-451: 在 defaultValue 变化后重设 currentDate。

此处理可保证数据与 UI 同步,暂未发现风险。


460-464: scrollToDate 修正越界日期。

防止用户滚动到超出范围的日期,增强了边界兼容性。


498-509: monthsViewScroll 对滚动位置进行多层判断。

需要进一步确认在极端场景(如滚动过快或可见区域小)下,current 是否会越界、出现负数等问题。


641-644: onConfirm 与 onUpdate 调用顺序明确。

此处逻辑清晰,弹窗模式下可及时执行更新。


649-655: classNames 用于合并类名。

写法简洁,符合 React + classNames 的最佳实践。


697-700: showMonthNumber 时添加 -weeks-shrink 样式。

能直观区分有无月份编号的不同布局,简洁有效。


711-759: renderItem 方法提高组件可拓展性。

支持自定义渲染顶部与底部内容,灵活度高,功能完备。


762-784: renderPanel 函数整合月标题、周号与日期网格。

与 showMonthNumber 配合,可自由切换展示模式,便于多种日历布局需求。

src/packages/calendar/calendarviewmodeitem.tsx (4)

1-15: 导入多项日历工具与组件依赖。

当前导入较为集中,可持续关注包体积变化,必要时可做 Lazy Load 或按需拆分。


35-47: 定义 CalendarViewModeItemProps。

通过 viewMode 区分月/季度,能够减少在同一组件中处理过多模式的复杂度,API 设计清晰。


130-170: requestAniFrameFunc 动态设置滚动与容器高度。

针对月/季视图分别计算最后一项面板位置,逻辑合理,减少了重复代码。


305-313: handleItemClick 只对 type 为 'curr' 做处理。

避免无效或越界点击带来副作用,逻辑简单明了,满足常见使用场景。

src/types/spec/calendar/base.ts (9)

14-16: CalendarMonthInfo 增加 weekNo/cssHeight/scrollTop 等可选字段。

这类信息有助于日历组件进行滚动定位和辅助展示,多针对视觉层面或布局逻辑提供便利。


29-29: viewMode 支持 'day' | 'month' | 'quarter'。

扩展了使用场景,减少了在主代码中对不同模式的硬编码判断。


34-34: value 字段必须为字符串。

需要确认与 CalendarValue 类型间的兼容关系,若外部调用传入数组或空值可能需要额外处理。


44-44: showMonthNumber 字段引入。

与 calendaritem 中的属性对应,能够确保多处组件对月编号显示需求的统一。


57-57: onItemClick 回调。

适用于多种视图模式的交互场景,让父组件可监听并自定义处理用户点击行为。


90-95: 新增 CalendarMonth 接口。

结构简单且含冗余标记字段,如 type 或 yearAndMonth,后续可结合具体需求灵活拓展。


97-102: CalendarQuarter 接口提供季度信息。

在季度视图或财务场景下非常实用,保持与月视图接口一致的设计风格。


104-110: CalendarMonthInfoOfPanel 自带滚动与高度信息。

能帮助实现可视区域的精确定位,特别是跨年场景下显著提升用户体验。


112-118: CalendarQuarterInfoOfPanel 同步季度面板逻辑。

与月面板的数据结构一致,延续了相同的滚动与渲染思路。

src/packages/calendar/utils.ts (9)

1-1: 建议检查这些外部工具函数的兼容性

在此处统一导入 isEqualdate2StrgetNumTwoBit 非常简洁。但请确认其他依赖模块是否也都已同步更新,以避免意外引用冲突。


12-12: 多选判断逻辑

使用 isEqual(item, day) 来判断多选逻辑,简洁易懂。若后续需要更复杂的对比逻辑(如时区或时分秒处理),可在调用方或上层做更精细的封装。


18-20: 注意日期格式一致性

这里使用 '/' 作为分隔符并与 date2Str(new Date(), '/') 进行相等性判断,保持了 YYYY/MM/DD 的格式统一。请确保其他地方也始终如一地处理日期,以免在跨文件或跨模块时出现格式不一致的问题。


28-28: 数组安全性检查

isEqual(days[0], day) 默认假设 days[0] 存在。若存在空数组或 days 长度不足的情况,可能导致越界错误。建议在函数开头检查 days.length


44-56: 函数 getPreMonths 的跨年处理

此函数生成从 1 到 month - 1 的月份数组,对同一年内的前置月份场景可行。如果需要在 month = 1 时获取前一年 12 月的数据,需再行处理跨年的逻辑。请根据业务需求决定是否补充。


77-79: formatMonth 的简洁性

formatMonthyear-month 形式返回,操作简单直观,满足常规场景。若后续有多语言或自定义格式需求,可适当拓展。


85-99: 函数 getQuarter 的边界检查

通过抛出异常来处理非法月份,并根据 (month - 1) / 3 + 1 计算季度,逻辑清晰无歧义。


101-122: 函数 getQuarters 逻辑

以步长 3 遍历,推算出一年内或指定范围内的季度数组,简洁易读。若需支持跨年或不规则季度,不妨在外层加以灵活封装。


124-139: 函数 getPreQuarters 确保业务合理性

month <= 3 时,(month - 3) 会导致循环区间为空,返回值将为空数组。请确认这是否符合“获取之前季度”功能的预期,或考虑处理跨年场景。

src/packages/calendaritem/utils.ts (3)

1-7: 按需引入日期工具

@/utils/date 中分别引入多种方法,能减小耦合度。请确保与上层组件的日期格式、时区等使用方式统一。


38-68: 函数 getPreMonthDates

计算上个月最后几天以填充当前月空白,思路简洁。若实际需求包含跨年或更复杂的月份计算(比如农历),可在外围扩展。


108-151: 函数 getWeekOfYearByYMD 的正确性

该函数结合 ISO 8601 与 firstDayOfWeek,处理了 weekNo === 0 时延续上一年周数、weekNo === 53 时判断天数等多种边界,十分全面。建议增加单元测试覆盖跨年与临界值情况,确保函数在所有年份均正常工作。

src/utils/date.ts (5)

1-11: 函数 isLeapYear

判断闰年的逻辑符合国际通用规则,对公历日期的正确性足够。后续若需支持更多历法或复杂场景,可在外层进行扩展。


71-77: 函数 getNumTwoBit

对数值小于 10 时前置补零,满足常规日期格式化场景。若后期需处理大于 99 的数字,需在外层做更多限制或扩展。


95-99: 函数 getDateString

通过偏移天数来生成未来或过去的日期字符串,适合简单的相对日期需求。若需跨月或跨年精确计算,尤其考虑时区差异,可在外层做更严格的校验或处理。


105-109: 函数 compareDate

以替换 -/ 来兼容不同平台的日期解析方式,并通过 startTime < endTime 比较先后日期,思路简单明快。


115-119: 函数 isEqual

通过比较毫秒值来判断日期是否完全相同,逻辑高效。若需考虑时区或只比较年月日字段,可在业务层再行定制。

src/packages/calendaritem/calendaritem.taro.tsx (14)

3-3: 引入 ScrollView 依赖的适配性检查
在 Taro 环境下使用 ScrollView 十分常见,但需要留意各端的兼容情况。请确认所有目标平台均正常支持此组件,避免在部分小程序端出现渲染问题。


8-14: 按需引入日期工具函数,优化可维护性
将原先整合在 Utils 中的函数拆分为独立的日期工具方法,可读性和可测性更好,改动方向值得肯定。需要验证这些函数是否在各个调用处都正确替换,特别要注意返回值类型是否保持一致。


24-24: useConfig 用于获取国际化上下文
使用配置上下文的方式生成多语言文案合理,但需要确认此上下文在所有需要多语言的日历组件中都能一致应用,避免出现部分文案无法正确切换的情况。


65-65: 新增 showMonthNumber 属性
该布尔值属性用于控制是否展示月视图对应的周号或月份数字,适配更多业务场景。但需确保其与 type(如多选、范围、周视图等)能够兼容,避免逻辑冲突。


85-86: 默认开始与结束日期改用 getDateString
以字符串形式设置默认的开始和结束,替代以前的工具方法,提高整体一致性。值得注意的是,getDateString(365) 表示默认结束日期是当前日期向后 365 天,是否符合业务场景需要二次确认。


164-165: 兼容 startDate / endDate 空值
在空值时使用 getDateString(0) 默认处理,避免报错。开发者应在文档或注释中明确说明该默认行为,方便他人理解组件的日期起止逻辑。


431-432: 初始化滚动位置
通过 getMonthsRef().scrollTop = currTop 手动赋值初始滚动距离来定位当前月份,思路清晰。若在多端场景下存在差异,可封装更通用的定位方式。


439-446: getMonthNum 计算总月数
对【开始年份、结束年份】做差,再加上月份差值,逻辑正确。注意若 endDate < startDate,此处会将 monthNum 最终重置为 1,需要确认此行为是否符合实际业务。


474-474: 监听 defaultValue 变更后触发 setCurrentDate
此写法能保持组件内部状态与外部属性同步,实用性强。但要确保外部快速连续更新 defaultValue 时不会触发过多的 DOM 重绘,可通过节流或校验减少不必要的刷新。


549-555: isDisable 函数
此函数会将所有非 active 类型的日期都视为禁用,并结合开始与结束日期范围进行判断,逻辑合理。但仍依赖外部的 disableDate 做二次校验,最好在文档中明确两者的优先级与关系。


747-790: 渲染单元格时分别处理顶部信息/底部信息
此段将组件渲染细分为「开始提示」「结束提示」「自定义顶部/底部区域」和「今日标识」。可读性较高,但也导致每个条件分支过于依赖全局 type。若后续支持新模式(如季度或自定义类型),需谨慎扩展此逻辑。


827-828: 日历渲染内容容器
ScrollView 包裹里增加了一个内层容器 monthsPanel 以及 viewAreaRef,并在其中进行 translateY 来控制可视范围。此多层容器的渲染有助于分段加载,但实现复杂度较高,须防止事件冒泡或滚动冲突。

Also applies to: 835-835, 837-837


845-845: 底部区域:自定义按钮及默认确认按钮
提供多种自定义钩子,如 renderBottomButton 优先渲染,否则展示默认的确认按钮。实现灵活性较高,能适配多种交互需求。

Also applies to: 847-847, 851-851, 853-853, 855-855


861-861: 外层容器的渲染与弹窗逻辑
整段在非弹窗模式下不渲染底部按钮,与 autoBackfill 结合后,可使组件在不同使用场景时呈现出不同的交互流程。对接下游业务时,需提前在文档中说明此差异。

Also applies to: 865-865

Comment on lines 533 to 560
const getClasses = (day: CalendarDay, month: CalendarMonthInfo) => {
const dateStr = getCurrDate(day, month)
if (isDisable(day, month)) return `${dayPrefix}-disabled`
const activeCls = `${dayPrefix}-active`
if (type === 'range' || type === 'week') {
if (isStart(dateStr, currentDate as string[]))
return `${activeCls} active-start`
if (isEnd(dateStr, currentDate as string[])) {
return `${activeCls} active-end`
}

if (type === 'range' || type === 'week') {
if (
isStart(dateStr, currentDate as string[]) ||
isEnd(dateStr, currentDate as string[])
) {
return `${dayPrefix}-active ${
isStart(dateStr, currentDate as string[]) ? 'active-start' : ''
} ${isEnd(dateStr, currentDate as string[]) ? 'active-end' : ''}`
}
if (
Array.isArray(currentDate) &&
Object.values(currentDate).length === 2 &&
Utils.compareDate(currentDate[0], dateStr) &&
Utils.compareDate(dateStr, currentDate[1])
) {
if (disableDate(day)) {
return `${dayPrefix}-choose-disabled`
}
return `${dayPrefix}-choose`
}
} else if (
(type === 'multiple' && isMultiple(dateStr, currentDate as string[])) ||
(!Array.isArray(currentDate) &&
Utils.isEqual(currentDate as string, dateStr))
if (
currentDate.length === 2 &&
compareDate(currentDate[0], dateStr) &&
compareDate(dateStr, currentDate[1])
) {
return `${dayPrefix}-active`
}

if (disableDate(day)) {
return `${dayPrefix}-disabled`
return disableDate(day)
? `${dayPrefix}-choose-disabled`
: `${dayPrefix}-choose`
}

return null
} else if (
(type === 'multiple' && isMultiple(dateStr, currentDate as string[])) ||
(type === 'single' && isEqual(currentDate as string, dateStr))
) {
return activeCls
}

return `${dayPrefix}-disabled`
if (disableDate(day)) return `${dayPrefix}-disabled`
return null
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

getClasses 函数分支较多。

范围、多选、单选等模式逻辑都在这里处理,建议拆分或使用枚举映射来减少 if-else 层级,从而提高可维护性。

Comment on lines +562 to 633
days[4] = getWhatDay(+days[0], +days[1], +days[2])
const newDate = days[3]

if (type === 'multiple') {
if (currentDate.length > 0) {
let hasIndex: any = ''
;(currentDate as string[]).forEach((item: any, index: number) => {
if (item === days[3]) {
hasIndex = index
if (Array.isArray(currentDate)) {
if (currentDate.length > 0) {
const hasIndex = currentDate.findIndex((item) => item === newDate)
if (isFirst) {
state.currDateArray.push([...days])
} else if (hasIndex > -1) {
currentDate.splice(hasIndex, 1)
state.currDateArray.splice(hasIndex, 1)
} else {
currentDate.push(newDate)
state.currDateArray.push([...days])
}
})
if (isFirst) {
state.currDateArray.push([...days])
} else if (hasIndex !== '') {
;(currentDate as string[]).splice(hasIndex, 1)
state.currDateArray.splice(hasIndex, 1)
} else {
;(currentDate as string[]).push(days[3])
state.currDateArray.push([...days])
currentDate.push(newDate)
state.currDateArray = [[...days]]
}
} else {
;(currentDate as string[]).push(days[3])
state.currDateArray = [[...days]]
}
} else if (type === 'range') {
const curDataLength = Object.values(currentDate).length
if (curDataLength === 2 || curDataLength === 0) {
Array.isArray(currentDate) &&
currentDate.splice(0) &&
currentDate.push(days[3])
state.currDateArray = [[...days]]
} else if (Utils.compareDate(currentDate[0], days[3])) {
Array.isArray(currentDate) && currentDate.push(days[3])
state.currDateArray = [...state.currDateArray, [...days]]
} else {
Array.isArray(currentDate) && currentDate.unshift(days[3])
state.currDateArray = [[...days], ...state.currDateArray]
if (Array.isArray(currentDate)) {
if (currentDate.length === 2 || currentDate.length === 0) {
currentDate.splice(0, currentDate.length, newDate)
state.currDateArray = [[...days]]
} else if (compareDate(currentDate[0], newDate)) {
currentDate.push(newDate)
state.currDateArray = [...state.currDateArray, [...days]]
} else {
currentDate.unshift(newDate)
state.currDateArray = [[...days], ...state.currDateArray]
}
}
} else if (type === 'week') {
const weekArr = Utils.getWeekDate(y, m, `${day.day}`, firstDayOfWeek)
if (propStartDate && Utils.compareDate(weekArr[0], propStartDate)) {
weekArr.splice(0, 1, propStartDate)
const weekArr = getWeekDate(y, m, `${day.day}`, firstDayOfWeek)
if (compareDate(weekArr[0], propStartDate)) {
weekArr[0] = propStartDate
}
if (propEndDate && Utils.compareDate(propEndDate, weekArr[1])) {
weekArr.splice(1, 1, propEndDate)
if (compareDate(propEndDate, weekArr[1])) {
weekArr[1] = propEndDate
}
Array.isArray(currentDate) &&
currentDate.splice(0) &&
currentDate.push(...weekArr)
;(currentDate as string[]).splice(0, currentDate.length, ...weekArr)
state.currDateArray = [
Utils.formatResultDate(weekArr[0]),
Utils.formatResultDate(weekArr[1]),
formatResultDate(weekArr[0]),
formatResultDate(weekArr[1]),
]
} else {
setCurrentDate(days[3])
state.currDateArray = [...days]
}

if (!isFirst) {
onDayClick && onDayClick(state.currDateArray)
onDayClick?.(state.currDateArray)
if (autoBackfill || !popup) {
confirm()
}
}

setMonthsData(monthsData.slice())
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

handleDayClick 分支冗长。

不同类型的选中操作(multiple、range、week 等)混合在一个函数中,建议进一步提取子函数,无论是可读性还是测试覆盖都更易维护。

}

export const isEnd = (day: string, days: string[]) => {
return Utils.isEqual(days[1], day)
return isEqual(days[1], day)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

同理数组越界风险

isEqual(days[1], day) 依赖 days[1],在极端情况下仍可能越界。可在调用方或此处增加相应的边界判断,避免异常。

Comment on lines +153 to +177
export const getWeekNosOfYear = (
year: number,
month: number,
firstDayOfWeek: number
) => {
const startWeekNo = getWeekOfYearByYMD(year, month, 1, firstDayOfWeek)
const endWeekNo = getWeekOfYearByYMD(
year,
month,
getMonthDays(`${year}`, `${month}`),
firstDayOfWeek
)
return Array.from(
{
length:
(endWeekNo === 1 ? 53 : endWeekNo) -
(startWeekNo === 53 || startWeekNo === 52 ? 0 : startWeekNo) +
1,
},
(_, i) => {
const lastIndex = (endWeekNo === 1 ? 53 : endWeekNo) - startWeekNo
return `${endWeekNo === 1 && i === lastIndex ? 1 : ((startWeekNo === 53 || startWeekNo === 52) && i !== 0 ? 0 : startWeekNo) + i}`
}
)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

函数 getWeekNosOfYear 的可读性

通过 startWeekNoendWeekNo 的差值生成周序列,概念清晰。但对 endWeekNo === 1startWeekNo 为 52/53 时的处理逻辑略显复杂,建议提炼为独立辅助函数或在注释中详细说明条件判断过程。

Comment on lines 274 to +339
!Utils.compareDate(propEndDate, item)
) {
if (!Object.hasOwnProperty.call(obj, item)) {
defaultArr.push(item)
obj[item] = item
}
}
})
currentDate.splice(0) && currentDate.push(...defaultArr)
defaultData = [...splitDate(defaultArr[0])]
if (compareDate(currentDate, propStartDate)) {
defaultData = [...splitDate(propStartDate)]
} else if (!compareDate(currentDate, propEndDate)) {
defaultData = [...splitDate(propEndDate)]
} else {
defaultData = [...splitDate(currentDate)]
}
} else if (type === 'week' && Array.isArray(currentDate)) {
if (currentDate.length > 0) {
const [y, m, d] = splitDate(currentDate[0])
const weekArr = Utils.getWeekDate(y, m, d, firstDayOfWeek)
currentDate.splice(0) && currentDate.push(...weekArr)
if (propStartDate && Utils.compareDate(currentDate[0], propStartDate)) {
currentDate.splice(0, 1, propStartDate)
return defaultData
}
if (Array.isArray(currentDate) && currentDate.length) {
switch (type) {
case 'range': {
if (compareDate(currentDate[0], propStartDate)) {
currentDate[0] = propStartDate
}
if (compareDate(propEndDate, currentDate[1])) {
currentDate[1] = propEndDate
}
defaultData = [
...splitDate(currentDate[0]),
...splitDate(currentDate[1]),
]
break
}
if (propEndDate && Utils.compareDate(propEndDate, currentDate[1])) {
currentDate.splice(1, 1, propEndDate)
case 'multiple': {
const defaultArr = [] as string[]
const obj: Record<string, unknown> = {}
currentDate.forEach((item: string) => {
if (
!compareDate(item, propStartDate) &&
!compareDate(propEndDate, item)
) {
if (!Object.hasOwnProperty.call(obj, item)) {
defaultArr.push(item)
obj[item] = item
}
}
})
currentDate.splice(0, currentDate.length, ...defaultArr)
defaultData = [...splitDate(defaultArr[0])]
break
}
defaultData = [
...splitDate(currentDate[0]),
...splitDate(currentDate[1]),
]
}
} else if (currentDate) {
if (currentDate.length > 0) {
if (
propStartDate &&
Utils.compareDate(currentDate as string, propStartDate)
) {
defaultData = [...splitDate(propStartDate as string)]
} else if (
propEndDate &&
!Utils.compareDate(currentDate as string, propEndDate)
) {
defaultData = [...splitDate(propEndDate as string)]
} else {
defaultData = [...splitDate(currentDate as string)]
case 'week': {
const [y, m, d] = splitDate(currentDate[0])
const weekArr = getWeekDate(y, m, d, firstDayOfWeek)
currentDate.splice(0, currentDate.length, ...weekArr)
if (compareDate(currentDate[0], propStartDate)) {
currentDate.splice(0, 1, propStartDate)
}
if (compareDate(propEndDate, currentDate[1])) {
currentDate.splice(1, 1, propEndDate)
}
defaultData = [
...splitDate(currentDate[0]),
...splitDate(currentDate[1]),
]
break
}
} else {
defaultData = []
default:
break
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

setDefaultDate 对多类型选择的处理
此处对 single、range、multiple、week 都做了初始值处理,逻辑复杂度较高。为减少维护成本,可考虑将各类型初始值分拆成独立的小函数,或封装策略模式来简化判断结构。

Comment on lines +586 to 663
state.currDateArray.splice(hasIndex, 1)
} else {
currentDate.push(newDate)
state.currDateArray.push([...days])
}
} else {
currentDate.push(newDate)
state.currDateArray = [[...days]]
}
})
if (isFirst) {
state.currDateArray.push([...days])
} else if (hasIndex !== '') {
;(currentDate as string[]).splice(hasIndex, 1)
state.currDateArray.splice(hasIndex, 1)
} else {
;(currentDate as string[]).push(days[3])
state.currDateArray.push([...days])
}
} else {
;(currentDate as string[]).push(days[3])
state.currDateArray = [[...days]]
break
}
} else if (type === 'range') {
const curDataLength = Object.values(currentDate).length
if (curDataLength === 2 || curDataLength === 0) {
Array.isArray(currentDate) &&
currentDate.splice(0) &&
currentDate.push(days[3])
state.currDateArray = [[...days]]
} else if (Utils.compareDate(currentDate[0], days[3])) {
Array.isArray(currentDate) && currentDate.push(days[3])
state.currDateArray = [...state.currDateArray, [...days]]
} else {
Array.isArray(currentDate) && currentDate.unshift(days[3])
state.currDateArray = [[...days], ...state.currDateArray]
case 'range': {
if (Array.isArray(currentDate)) {
if (currentDate.length === 2 || currentDate.length === 0) {
currentDate.splice(0, currentDate.length, newDate)
state.currDateArray = [[...days]]
} else if (compareDate(currentDate[0], newDate)) {
currentDate.push(newDate)
state.currDateArray = [...state.currDateArray, [...days]]
} else {
currentDate.unshift(newDate)
state.currDateArray = [[...days], ...state.currDateArray]
}
}
break
}
} else if (type === 'week') {
const weekArr = Utils.getWeekDate(y, m, `${day.day}`, firstDayOfWeek)
if (propStartDate && Utils.compareDate(weekArr[0], propStartDate)) {
weekArr.splice(0, 1, propStartDate)
case 'week': {
const weekArr = getWeekDate(y, m, `${day.day}`, firstDayOfWeek)
if (compareDate(weekArr[0], propStartDate)) {
weekArr[0] = propStartDate
}
if (compareDate(propEndDate, weekArr[1])) {
weekArr[1] = propEndDate
}
;(currentDate as string[]).splice(0, currentDate.length, ...weekArr)
state.currDateArray = [
formatResultDate(weekArr[0]),
formatResultDate(weekArr[1]),
]
break
}
if (propEndDate && Utils.compareDate(propEndDate, weekArr[1])) {
weekArr.splice(1, 1, propEndDate)
default: {
setCurrentDate(newDate)
state.currDateArray = [...days]
break
}
Array.isArray(currentDate) &&
currentDate.splice(0) &&
currentDate.push(...weekArr)
state.currDateArray = [
Utils.formatResultDate(weekArr[0]),
Utils.formatResultDate(weekArr[1]),
]
} else {
setCurrentDate(days[3])
state.currDateArray = [...days]
}

if (!isFirst) {
onDayClick && onDayClick(state.currDateArray)
onDayClick?.(state.currDateArray)
if (autoBackfill || !popup) {
confirm()
}
}

setMonthsData(monthsData.slice())
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

handleDayClick 处理不同类型的选中逻辑
此函数内部依赖全局的 currentDatestate.currDateArraytype 等多处状态,代码量较多且分支复杂。强烈建议拆分单选、多选、范围等不同模式的操作,以单一函数实现单一逻辑,避免后期维护困难。

Copy link

codecov bot commented Mar 17, 2025

Codecov Report

Attention: Patch coverage is 94.63918% with 52 lines in your changes missing coverage. Please review.

Project coverage is 88.62%. Comparing base (c56941d) to head (a98c830).
Report is 2 commits behind head on feat_v3.x.

Files with missing lines Patch % Lines
src/packages/calendaritem/calendaritem.tsx 89.92% 27 Missing ⚠️
src/packages/calendar/calendarviewmodeitem.tsx 96.49% 11 Missing ⚠️
src/packages/calendar/utils.ts 90.38% 10 Missing ⚠️
src/packages/calendaritem/utils.ts 97.10% 4 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##           feat_v3.x    #3091      +/-   ##
=============================================
+ Coverage      86.95%   88.62%   +1.66%     
=============================================
  Files            280      282       +2     
  Lines          18456    18864     +408     
  Branches        2786     2920     +134     
=============================================
+ Hits           16049    16718     +669     
+ Misses          2402     2143     -259     
+ Partials           5        3       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
src/packages/calendar/calendar.tsx (1)

113-164: 实现条件渲染支持多种视图模式

重构了 renderItem 函数,根据 viewMode 属性条件渲染不同的组件。当 viewMode 不为 'day' 时,渲染 CalendarViewModeItem;否则渲染 CalendarItem。这种实现方式使组件能够灵活地支持多种显示模式。

然而,在 CalendarItem 的属性传递中使用了 children 属性,这不是 React 传递子元素的标准方式。

-          <CalendarItem
-            ref={calendarRef}
-            style={style}
-            className={className}
-            children={children}
+          <CalendarItem
+            ref={calendarRef}
+            style={style}
+            className={className}
+          >
+            {children}
+          </CalendarItem>
🧰 Tools
🪛 Biome (1.9.4)

[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

src/packages/calendar/calendar.taro.tsx (1)

113-164: 实现条件渲染支持多种视图模式

重构了 renderItem 函数,根据 viewMode 属性条件渲染不同的组件。当 viewMode 不为 'day' 时,渲染 CalendarViewModeItem;否则渲染 CalendarItem。这种实现方式使组件能够灵活地支持多种显示模式。

然而,在 CalendarItem 的属性传递中使用了 children 属性,这不是 React 传递子元素的标准方式。

-          <CalendarItem
-            ref={calendarRef}
-            style={style}
-            className={className}
-            children={children}
+          <CalendarItem
+            ref={calendarRef}
+            style={style}
+            className={className}
+          >
+            {children}
+          </CalendarItem>
🧰 Tools
🪛 Biome (1.9.4)

[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

src/packages/calendar/calendarviewmodeitem.tsx (2)

44-44: scrollAnimation 属性未在后续逻辑中使用
建议在滚动或跳转到指定日期时,结合该属性实现平滑过渡,或移除无用属性以保持代码简洁。


285-295: 避免嵌套三元运算以提升可读性
当前 initData 函数通过多层三元运算判断 viewMode,可读性降低。建议使用更直观的 if/else 或抽取辅助方法来分支处理,提升代码可维护性。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 293-293: src/packages/calendar/calendarviewmodeitem.tsx#L293
Added line #L293 was not covered by tests

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 26a1d5f and 6c68ea2.

📒 Files selected for processing (5)
  • src/packages/calendar/calendar.taro.tsx (6 hunks)
  • src/packages/calendar/calendar.tsx (6 hunks)
  • src/packages/calendar/calendarviewmodeitem.taro.tsx (1 hunks)
  • src/packages/calendar/calendarviewmodeitem.tsx (1 hunks)
  • src/packages/calendar/demos/taro/demo2.tsx (2 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/packages/calendar/calendar.tsx

[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

src/packages/calendar/calendar.taro.tsx

[error] 136-136: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

🪛 GitHub Check: codecov/patch
src/packages/calendar/calendarviewmodeitem.tsx

[warning] 124-125: src/packages/calendar/calendarviewmodeitem.tsx#L124-L125
Added lines #L124 - L125 were not covered by tests


[warning] 168-168: src/packages/calendar/calendarviewmodeitem.tsx#L168
Added line #L168 was not covered by tests


[warning] 293-293: src/packages/calendar/calendarviewmodeitem.tsx#L293
Added line #L293 was not covered by tests


[warning] 308-308: src/packages/calendar/calendarviewmodeitem.tsx#L308
Added line #L308 was not covered by tests


[warning] 310-313: src/packages/calendar/calendarviewmodeitem.tsx#L310-L313
Added lines #L310 - L313 were not covered by tests


[warning] 331-332: src/packages/calendar/calendarviewmodeitem.tsx#L331-L332
Added lines #L331 - L332 were not covered by tests

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (26)
src/packages/calendar/demos/taro/demo2.tsx (3)

4-6: 组件重命名和日期动态计算的实现

组件名称从 Demo2 更改为 Demo,并加入了动态年份计算功能。使用当前年份创建日期范围使示例更加实用和有意义。


36-37: 优化日期范围设置

使用动态计算的年份变量来设置日期范围,提升了示例的灵活性和实用性。这样的实现可以确保日历示例总是显示相对于当前年份的合理日期范围。


45-45: 保持一致的导出命名

将导出组件名从 Demo2 改为 Demo,与函数声明保持一致,符合代码规范。

src/packages/calendar/calendar.tsx (6)

4-5: 引入新组件和更新工具函数导入

引入了新的 CalendarViewModeItem 组件和 getDateString 函数,为支持月视图和季度视图模式做准备。这种模块化的方法有助于代码组织和维护。


13-14: 添加新的默认属性支持多视图模式

添加了 viewMode(默认为'day')、valueshowMonthNumberonItemClick 属性,扩展了日历组件的功能,使其支持不同的视图模式和交互方式。

Also applies to: 18-19, 28-29, 39-40


20-22: 更新日期处理方法

startDateendDate 的默认值生成方式从 Utils.getDay 更改为 getDateString,保持与工具函数的一致性,简化了日期处理逻辑。


55-56: 更新组件属性解构

将新增的 viewModevalueshowMonthNumberonItemClick 属性添加到解构列表中,确保这些属性可以正确地传递给子组件。

Also applies to: 58-59, 68-69, 81-82


88-89: 使用可选链简化回调函数调用

使用可选链操作符 ?. 简化回调函数的调用,提高代码的健壮性,防止在回调函数未定义时出现错误。

Also applies to: 93-94, 104-105


170-170: 优化弹窗显示逻辑

更新了弹窗条件,仅在 popup 为 true 且 viewMode 为 'day' 时显示弹窗,确保在不同视图模式下有正确的展示行为。

src/packages/calendar/calendarviewmodeitem.taro.tsx (8)

1-67: 新增组件支持月视图和季度视图

实现了新的 CalendarViewModeItem 组件,支持 'month' 和 'quarter' 视图模式,定义了详细的接口和默认属性。该组件丰富了日历的显示方式,使用户可以在不同的时间维度查看日期。


68-126: 初始化组件状态和引用

组件使用 useStateuseRef 钩子来管理面板日期、滚动位置和DOM引用。合理的状态设计使组件能够正确处理复杂的日期显示逻辑,同时支持滚动功能。


127-176: 实现动画帧请求和滚动位置计算

通过 requestAniFrameFunc 函数实现了滚动动画和位置计算,针对月视图和季度视图分别处理。这种实现确保了在不同视图模式下都能有平滑的滚动体验。


177-284: 月份和季度数据计算逻辑

实现了 getMonthsDatagetQuartersData 函数来计算可用的月份和季度数据,处理了年份跨度和边界情况。这些函数保证了在不同日期范围和视图模式下都能正确显示数据。


285-323: 数据初始化和项目点击处理

通过 initData 函数初始化面板数据,并实现了 handleItemClick 函数处理项目点击事件。这些函数确保了组件的交互性和数据一致性。


324-345: 项目状态判断逻辑

实现了 isDisableisActivegetClasses 函数来判断项目的状态和应用的样式类。这些函数使组件能够正确显示项目的选中和禁用状态。


346-416: 渲染函数的实现

实现了 renderHeaderrenderItemrenderPanelrenderContent 函数来构建组件的UI结构。这种模块化的渲染方法使代码更易于理解和维护。


417-427: 组件返回和导出

组件返回了完整的DOM结构,并正确设置了显示名称和默认导出。这确保了组件能够在外部正确引用和使用。

src/packages/calendar/calendar.taro.tsx (6)

4-5: 引入新组件和更新工具函数导入

引入了 Taro 版本的 CalendarViewModeItem 组件和 getDateString 函数,为支持多视图模式做准备。这与 Web 版本保持一致,确保了跨平台的功能一致性。


13-14: 添加新的默认属性支持多视图模式

添加了 viewMode(默认为'day')、valueshowMonthNumberonItemClick 属性,扩展了日历组件在 Taro 环境下的功能,使其支持不同的视图模式和交互方式。

Also applies to: 18-19, 28-29, 39-40


20-22: 更新日期处理方法

startDateendDate 的默认值生成方式从原来的方法更改为 getDateString,保持与工具函数的一致性,简化了日期处理逻辑。


55-56: 更新组件属性解构

将新增的 viewModevalueshowMonthNumberonItemClick 属性添加到解构列表中,确保这些属性可以正确地传递给子组件。

Also applies to: 58-59, 68-69, 81-82


88-89: 使用可选链简化回调函数调用

使用可选链操作符 ?. 简化回调函数的调用,提高代码的健壮性,防止在回调函数未定义时出现错误。

Also applies to: 93-94, 104-105


170-178: 优化弹窗显示逻辑和关闭图标

更新了弹窗条件,仅在 popup 为 true 且 viewMode 为 'day' 时显示弹窗,确保在不同视图模式下有正确的展示行为。同时正确传递了 closeIcon 属性。

src/packages/calendar/calendarviewmodeitem.tsx (3)

1-15: 导入与类型定义整体可接受
当前各个依赖与类型定义逻辑相对清晰,命名也比较易读,未发现明显问题。


310-313: 补充点击选中测试覆盖
此处更新 innerValue 并回调 onItemClick,容易影响组件行为。为稳定性与回归准确,建议在测试用例中补充对该逻辑的验证,确保点击行为、选中状态都能符合预期。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 310-313: src/packages/calendar/calendarviewmodeitem.tsx#L310-L313
Added lines #L310 - L313 were not covered by tests


331-332: 为激活状态添加测试场景
res.push('active') 的逻辑目前在测试覆盖报告中缺失,建议在测试用例中验证激活状态渲染的效果与正确性,确保视觉与交互均符合预期。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 331-332: src/packages/calendar/calendarviewmodeitem.tsx#L331-L332
Added lines #L331 - L332 were not covered by tests

Comment on lines +130 to +169
switch (viewMode) {
case 'month':
{
const lastItem = panelDate.months[panelDate.months.length - 1]
const containerHeight = lastItem.cssHeight + lastItem.scrollTop
const currentIndex = panelDate.months.findIndex(
(item) => item.currYear === true
)
requestAniFrame(() => {
// 初始化 日历位置
if (monthsRef && monthsPanel && viewAreaRef) {
viewHeight = getMonthsRef().clientHeight
getMonthsPanel().style.height = `${containerHeight}px`
getMonthsRef().scrollTop =
panelDate.months[currentIndex].scrollTop
}
})
}
break
case 'quarter':
{
const lastItem = panelDate.quarters[panelDate.quarters.length - 1]
const containerHeight = lastItem.cssHeight + lastItem.scrollTop
const currentIndex = panelDate.quarters.findIndex(
(item) => item.currYear === true
)
requestAniFrame(() => {
// 初始化 日历位置
if (monthsRef && monthsPanel && viewAreaRef) {
viewHeight = getMonthsRef().clientHeight
getMonthsPanel().style.height = `${containerHeight}px`
getMonthsRef().scrollTop =
panelDate.quarters[currentIndex].scrollTop
}
})
}
break
default:
break
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

提取重复逻辑,减少分支重复代码
方法 requestAniFrameFunc 内对 monthquarter 的处理逻辑部分雷同,且都涉及索引查找与容器高度设置,建议抽取公共部分,并将仅差异部分保留在分支逻辑中,以减少重复并提高可维护性。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 168-168: src/packages/calendar/calendarviewmodeitem.tsx#L168
Added line #L168 was not covered by tests

Comment on lines +174 to +228
const getMonthsData = () => {
// 获取区间范围内可用的月数,包括边界值所在的月份
const startYear = Number(startDates[0])
const startMonth = Number(startDates[1])
const endYear = Number(endDates[0])
const endMonth = Number(endDates[1])
const panelData: CalendarMonthInfoOfPanel[] = []
// 第某年的scrollTop:年面板高度 * (第某年数-1)
const addPanelData = (
year: number,
months: CalendarMonth[],
scrollTop: number
) => {
panelData.push({
year,
months,
scrollTop,
cssHeight: YearMonthPanelHeight,
currYear: isCurrYear(year),
})
}
// 在同一年时
if (startYear === endYear) {
addPanelData(
startYear,
[
...getPreMonths('prev', startYear, startMonth),
...getMonths('curr', startYear, startMonth, endMonth),
...getMonths('next', endYear, endMonth + 1),
],
0
)
} else {
let scrollTop = panelData.length * YearMonthPanelHeight
const startMonths = [
...getPreMonths('prev', startYear, startMonth),
...getMonths('curr', startYear, startMonth),
]
addPanelData(startYear, startMonths, scrollTop)
// 不同年份时,注意可能跨多个年
for (let i = startYear + 1; i < endYear; i++) {
scrollTop = panelData.length * YearMonthPanelHeight
const midMonths = [...getMonths('curr', i, 1)]
addPanelData(i, midMonths, scrollTop)
}
const lastMonths = [
...getPreMonths('curr', endYear, endMonth + 1),
...getMonths('next', endYear, endMonth + 1),
]

scrollTop = panelData.length * YearMonthPanelHeight
addPanelData(endYear, lastMonths, scrollTop)
}
return panelData
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

getMonthsData 代码体量较大,可考虑拆分或复用公共逻辑
此方法功能明确,但内部逻辑较多且与 getQuartersData 类似,建议将计算年度滚动、组装范围数据等逻辑抽离为通用方法,以便在月面板与季面板间复用。

Comment on lines +229 to +279
const getQuartersData = () => {
// 获取区间范围内可用的季度数,包括边界值所在的季度数
const startYear = Number(startDates[0])
const startMonth = Number(startDates[1])
const endYear = Number(endDates[0])
const endMonth = Number(endDates[1])
const panelData: CalendarQuarterInfoOfPanel[] = []
// 第某年的scrollTop:年面板高度 * (第某年数-1)
const addPanelData = (
year: number,
quarters: CalendarQuarter[],
scrollTop: number
) => {
panelData.push({
year,
quarters,
scrollTop,
cssHeight: YearQuarterPanelHeight,
currYear: isCurrYear(year),
})
}
// 在同一年时
if (startYear === endYear) {
const quarters = [
...getPreQuarters('prev', startYear, startMonth),
...getQuarters('curr', startYear, startMonth, endMonth),
...getNextQuarters('next', endYear, endMonth),
]
addPanelData(startYear, quarters, 0)
} else {
let scrollTop = panelData.length * YearQuarterPanelHeight
const startQuarters = [
...getPreQuarters('prev', startYear, startMonth),
...getQuarters('curr', startYear, startMonth),
]
addPanelData(startYear, startQuarters, scrollTop)
// 不同年份时,注意可能跨多个年
for (let i = startYear + 1; i < endYear; i++) {
scrollTop = panelData.length * YearQuarterPanelHeight
const midQuarters = [...getQuarters('curr', i, 1)]
addPanelData(i, midQuarters, scrollTop)
}
const lastQuarters = [
...getQuarters('curr', endYear, 1, endMonth),
...getNextQuarters('next', endYear, endMonth),
]
scrollTop = panelData.length * YearQuarterPanelHeight
addPanelData(endYear, lastQuarters, scrollTop)
}
return panelData
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

getQuartersDatagetMonthsData 存在重复思路
季度与月份的处理整体较为相似,建议考虑统一处理逻辑,再根据区分点为月或季做分类处理,从而减少重复代码并提高可维护性。

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
src/packages/calendar/calendar.scss (1)

274-295: ⚠️ Potential issue

需注意RTL支持的更新

此段代码中的选择器仍然使用了&-day,但前面已将&-day更新为&-item。如果需要支持RTL(从右到左的语言),应当同步更新这里的选择器名称,以确保样式能正确应用。

建议修改为:

[dir='rtl'] .nut-calendar,
.nut-rtl .nut-calendar {
-  &-day {
+  &-item {
    float: right;

    &-active {
      &.active-start {
        border-top-left-radius: 0;
        border-top-right-radius: $calendar-day-active-border-radius;
        border-bottom-left-radius: 0;
        border-bottom-right-radius: $calendar-day-active-border-radius;
      }

      &.active-end {
        border-top-right-radius: 0;
        border-top-left-radius: $calendar-day-active-border-radius;
        border-bottom-right-radius: 0;
        border-bottom-left-radius: $calendar-day-active-border-radius;
      }
    }
  }
}
♻️ Duplicate comments (1)
src/packages/calendaritem/calendaritem.taro.tsx (1)

586-663: 🛠️ Refactor suggestion

handleDayClick 代码结构仍然复杂

尽管做了一些优化,但 handleDayClick 函数仍然过于庞大,包含了多种日期类型的处理逻辑,代码量大且分支复杂。

建议将不同类型的选择处理逻辑抽离为单独的函数:

- const handleDayClick = (day: CalendarDay, month: CalendarMonthInfo, isFirst: boolean = true) => {
+ const handleSingleTypeClick = (days: any[], newDate: string, isFirst: boolean) => {
+   setCurrentDate(newDate)
+   state.currDateArray = [...days]
+   return true
+ }
+
+ const handleMultipleTypeClick = (days: any[], newDate: string, isFirst: boolean) => {
+   // 多选处理逻辑
+ }
+
+ const handleRangeTypeClick = (days: any[], newDate: string, isFirst: boolean) => {
+   // 范围选择处理逻辑
+ }
+
+ const handleWeekTypeClick = (days: any[], y: string, m: string, day: CalendarDay, isFirst: boolean) => {
+   // 周选择处理逻辑
+ }
+
+ const handleDayClick = (day: CalendarDay, month: CalendarMonthInfo, isFirst: boolean = true) => {
    if (isDisable(day, month) || disableDate(day)) return
    const days = [...month.curData]
    const [y, m] = month.curData
    days[2] = typeof day.day === 'number' ? getNumTwoBit(day.day) : day.day
    days[3] = `${days[0]}/${days[1]}/${days[2]}`
    days[4] = getWhatDay(+days[0], +days[1], +days[2])
    const newDate = days[3]

    let handled = false
    switch (type) {
      case 'multiple': {
-       // 多选逻辑
+       handled = handleMultipleTypeClick(days, newDate, isFirst)
        break
      }
      case 'range': {
-       // 范围选择逻辑
+       handled = handleRangeTypeClick(days, newDate, isFirst)
        break
      }
      case 'week': {
-       // 周选择逻辑
+       handled = handleWeekTypeClick(days, y, m, day, isFirst)
        break
      }
      default: {
-       // 单选逻辑
+       handled = handleSingleTypeClick(days, newDate, isFirst)
        break
      }
    }
    
    if (!isFirst && handled) {
      onDayClick?.(state.currDateArray)
      if (autoBackfill || !popup) {
        confirm()
      }
    }
    setMonthsData(monthsData.slice())
  }
🧹 Nitpick comments (9)
src/packages/calendar/calendarviewmodeitem.taro.tsx (3)

54-55: 建议将默认的日期范围参数化或使用可配置常量
默认为 365 天可能并不适用于所有业务场景,建议提供更灵活的配置方式,以便后续维护和扩展。


130-169: 提取公共逻辑以减少重复分支
requestAniFrameFunc 内,对于 'month''quarter' 的分支共有相似的滚动和容器高度设置逻辑,建议抽取公共函数或进行条件差异化处理,以便减少重复、提升可维护性。


315-323: 添加可点击判断前的类型保护
函数 handleItemClick 中先判断 item.type 是否为 'curr',再进行状态更新,但并未对回调参数 item 做更严格的类型约束。若后续扩展新类型,可能需要更完备的判断逻辑或类型保护,以避免潜在的类型错误。

src/packages/calendar/calendarviewmodeitem.tsx (3)

130-169: 与 Taro 版本内容高度重复,建议抽象公共函数
requestAniFrameFunc 的逻辑与 calendarviewmodeitem.taro.tsx 类似,可考虑将两者公共部分提炼到一个共享模块,避免代码重复并减少维护开销。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 168-168: src/packages/calendar/calendarviewmodeitem.tsx#L168
Added line #L168 was not covered by tests


308-308: 测试覆盖缺失提醒
静态分析提示此行尚未有对应测试用例,建议添加测试以确保对无效或超出范围点击的处理逻辑正确无误。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 308-308: src/packages/calendar/calendarviewmodeitem.tsx#L308
Added line #L308 was not covered by tests


343-345: 无需复杂判断时可简化条件表达式
若对于单一属性验证无多层逻辑时,可使用可选链运算符或简单判空以取代嵌套的条件判断,提升可读性与可维护性。

src/packages/calendaritem/calendaritem.tsx (3)

460-464: 滚动到指定日期时的边界校验
scrollToDate 函数中,若检测到输入日期小于 propStartDate 或大于 propEndDate,则替换为边界日期。请确认业务是否需要抛出异常或提示信息,以提高用户可感知度。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 460-460: src/packages/calendaritem/calendaritem.tsx#L460
Added line #L460 was not covered by tests


[warning] 462-462: src/packages/calendaritem/calendaritem.tsx#L462
Added line #L462 was not covered by tests


505-509: 滚动计算逻辑可适当精简
monthsViewScroll 中,对 scrollTop 与数个面板高度做多重判断。可以考虑将面板区间的查找抽象成辅助函数,以减轻嵌套与冗余判断,提升可读性。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 505-505: src/packages/calendaritem/calendaritem.tsx#L505
Added line #L505 was not covered by tests


[warning] 507-508: src/packages/calendaritem/calendaritem.tsx#L507-L508
Added lines #L507 - L508 were not covered by tests


525-531: 禁用日期的规则需与业务场景同步
当前判断逻辑仅检查 day.type 是否为 'active' 以及对 propStartDatepropEndDate 的比较。若实际需求需要更多自定义禁用规则(如节假日等),可考虑在 isDisable 中或其上游扩展更多可插拔的验证方式。

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 838b9d0 and eb8737a.

⛔ Files ignored due to path filters (1)
  • src/packages/calendar/__tests__/__snapshots__/calendar.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (7)
  • src/packages/calendar/__tests__/calendar.spec.tsx (1 hunks)
  • src/packages/calendar/calendar.scss (7 hunks)
  • src/packages/calendar/calendarviewmodeitem.taro.tsx (1 hunks)
  • src/packages/calendar/calendarviewmodeitem.tsx (1 hunks)
  • src/packages/calendaritem/calendaritem.taro.tsx (16 hunks)
  • src/packages/calendaritem/calendaritem.tsx (19 hunks)
  • src/packages/configprovider/types.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
src/packages/calendaritem/calendaritem.tsx (8)
src/utils/date.ts (6) (6)
  • getDateString (95:99)
  • compareDate (105:109)
  • getMonthDays (48:69)
  • isEqual (115:119)
  • getNumTwoBit (75:77)
  • getWhatDay (17:33)
src/types/spec/calendar/base.ts (2) (2)
  • CalendarDay (5:8)
  • CalendarMonthInfo (10:17)
src/utils/date.ts (6) (6)
  • getDateString (95:99)
  • compareDate (105:109)
  • getMonthDays (48:69)
  • isEqual (115:119)
  • getNumTwoBit (75:77)
  • getWhatDay (17:33)
src/types/spec/calendar/base.ts (2) (2)
  • CalendarDay (5:8)
  • CalendarMonthInfo (10:17)
src/utils/date.ts (6) (6)
  • getDateString (95:99)
  • compareDate (105:109)
  • getMonthDays (48:69)
  • isEqual (115:119)
  • getNumTwoBit (75:77)
  • getWhatDay (17:33)
src/types/spec/calendar/base.ts (2) (2)
  • CalendarDay (5:8)
  • CalendarMonthInfo (10:17)
src/utils/date.ts (6) (6)
  • getDateString (95:99)
  • compareDate (105:109)
  • getMonthDays (48:69)
  • isEqual (115:119)
  • getNumTwoBit (75:77)
  • getWhatDay (17:33)
src/types/spec/calendar/base.ts (2) (2)
  • CalendarDay (5:8)
  • CalendarMonthInfo (10:17)
🪛 GitHub Check: codecov/patch
src/packages/calendar/calendarviewmodeitem.tsx

[warning] 124-125: src/packages/calendar/calendarviewmodeitem.tsx#L124-L125
Added lines #L124 - L125 were not covered by tests


[warning] 168-168: src/packages/calendar/calendarviewmodeitem.tsx#L168
Added line #L168 was not covered by tests


[warning] 293-293: src/packages/calendar/calendarviewmodeitem.tsx#L293
Added line #L293 was not covered by tests


[warning] 308-308: src/packages/calendar/calendarviewmodeitem.tsx#L308
Added line #L308 was not covered by tests


[warning] 310-313: src/packages/calendar/calendarviewmodeitem.tsx#L310-L313
Added lines #L310 - L313 were not covered by tests


[warning] 331-332: src/packages/calendar/calendarviewmodeitem.tsx#L331-L332
Added lines #L331 - L332 were not covered by tests

src/packages/calendaritem/calendaritem.tsx

[warning] 274-275: src/packages/calendaritem/calendaritem.tsx#L274-L275
Added lines #L274 - L275 were not covered by tests


[warning] 277-277: src/packages/calendaritem/calendaritem.tsx#L277
Added line #L277 was not covered by tests


[warning] 279-279: src/packages/calendaritem/calendaritem.tsx#L279
Added line #L279 was not covered by tests


[warning] 395-396: src/packages/calendaritem/calendaritem.tsx#L395-L396
Added lines #L395 - L396 were not covered by tests


[warning] 460-460: src/packages/calendaritem/calendaritem.tsx#L460
Added line #L460 was not covered by tests


[warning] 462-462: src/packages/calendaritem/calendaritem.tsx#L462
Added line #L462 was not covered by tests


[warning] 505-505: src/packages/calendaritem/calendaritem.tsx#L505
Added line #L505 was not covered by tests


[warning] 507-508: src/packages/calendaritem/calendaritem.tsx#L507-L508
Added lines #L507 - L508 were not covered by tests


[warning] 549-549: src/packages/calendaritem/calendaritem.tsx#L549
Added line #L549 was not covered by tests


[warning] 584-585: src/packages/calendaritem/calendaritem.tsx#L584-L585
Added lines #L584 - L585 were not covered by tests


[warning] 591-592: src/packages/calendaritem/calendaritem.tsx#L591-L592
Added lines #L591 - L592 were not covered by tests


[warning] 604-606: src/packages/calendaritem/calendaritem.tsx#L604-L606
Added lines #L604 - L606 were not covered by tests


[warning] 768-774: src/packages/calendaritem/calendaritem.tsx#L768-L774
Added lines #L768 - L774 were not covered by tests

🔇 Additional comments (43)
src/packages/calendar/calendarviewmodeitem.taro.tsx (1)

331-332: 覆盖测试建议
静态分析显示此处尚无相应单测。建议在测试用例里补充对选中逻辑的覆盖,以确保激活状态正确持久。

src/packages/calendar/calendarviewmodeitem.tsx (1)

294-294: 确保空判断后再解构数据
setPanelDate((prev) => ({ ...prev, ... })) 操作时,应确认 data 不为 null 后再执行解构赋值,否则可能导致不可预期的错误。请考虑在赋值前增加非空判断。

src/packages/calendaritem/calendaritem.tsx (2)

274-275: 确认单日期模式下边界处理的正确性
type === 'single' 分支内,对起止时间进行比较后将 defaultData 赋为 propStartDatepropEndDate。若用户的实际日期不在这个范围内,逻辑将强制限定至边界值。建议确认此逻辑符合业务预期,并在单测中覆盖相关场景。

Also applies to: 277-279

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 274-275: src/packages/calendaritem/calendaritem.tsx#L274-L275
Added lines #L274 - L275 were not covered by tests


768-774: 增加对周号渲染的测试覆盖
静态分析发现此处渲染 weekNo 缺少测试覆盖。若此功能是新需求,建议编写测试用例验证周号的正确显示以及边界表现(如跨年周号)。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 768-774: src/packages/calendaritem/calendaritem.tsx#L768-L774
Added lines #L768 - L774 were not covered by tests

src/packages/configprovider/types.ts (1)

341-341: 新增的CSS变量类型符合命名规范

此处为Calendar组件增加了'nutuiCalendarPanelItemWidth'类型,用于支持面板项的宽度定义,与PR目标一致。此变更保持了NutUI的命名规范,有助于实现月面板和季面板的展示功能。

src/packages/calendar/calendar.scss (10)

3-4: 选择器更新符合组件扩展需求

将选择器从单一的.nut-calendar扩展为包含.nut-calendar-viewmode,实现了样式共享,减少了代码重复,为支持月面板和季面板提供了基础样式支持。


66-68: 添加收缩模式支持周号显示

添加的&-weeks-shrink类用于在显示周号时为日历头部提供左侧填充,使周号与日历内容对齐,这是支持展示周号功能的必要样式。


118-132: 周号显示区域样式定义完善

新增的&-weeknumber类及其子类&-index提供了周号显示所需的样式,包括宽度、对齐方式、字体大小和颜色等。样式定义合理,与现有日历项样式保持一致的视觉风格。


138-138: 将day更改为item增强了组件的通用性

将选择器从&-day更改为&-item,使命名更加通用,能够适应日、月、季度等多种时间单位的展示需求,符合本次PR的功能扩展目标。


193-193: 类名更新保持一致性

.nut-calendar-day-info更改为.nut-calendar-item-info,保持与选择器变更的一致性,确保样式正确应用于不同时间粒度的日历项。


201-201: 保持命名一致性

.nut-calendar-day-info-curr更改为.nut-calendar-item-info-curr,与前面的命名变更保持一致,确保样式系统的连贯性。


214-214: 命名一致性更新

将另一处.nut-calendar-day-info-curr更新为.nut-calendar-item-info-curr,确保所有相关类名都得到了统一更新,避免样式错误。


221-223: 添加flex布局支持

新增的.shrink类设置display: flex,为在启用周号显示时的布局调整提供支持,使周号和日历内容能够以flex方式并排展示。


225-234: 面板布局样式实现合理

新增的&-panel类及其子类&-panel-title为月面板和季面板提供了布局和标题样式,布局方式与现有的月份显示保持一致,确保了视觉风格的统一性。


256-268: 视图模式样式完善

新增的.nut-calendar-viewmode类及其子类为视图模式下的日历项提供了专门的样式,包括宽度控制和前一个/后一个月份项的特殊样式处理。使用了变量$calendar-panel-item-width来控制项宽度,增强了样式的可配置性。

src/packages/calendar/__tests__/calendar.spec.tsx (15)

4-4: 添加了必要的类型导入

新增了 CalendarDayCalendarType 类型导入,这对于测试新增的月面板、季面板和周号显示功能很必要,保证了类型安全。


7-53: 重命名并增强了单选日期测试用例

测试用例从 "show-title prop" 改名为 "single prop",更好地反映了测试内容。新增了点击确认按钮的测试,确保 onConfirm 回调被正确触发。

代码结构清晰,覆盖了单选模式下的关键功能点,包括标题显示/隐藏、副标题显示/隐藏以及确认按钮功能。


55-71: 重命名并完善了周视图测试用例

测试用例从 "show-sub-title prop" 改名为 "week prop",更准确地反映了测试内容。现在测试了周视图模式的关键功能,包括 firstDayOfWeek 参数。使用快照测试验证了渲染结果,有效确保了视图的稳定性。


73-89: 新增了日期范围选择模式的测试

新增了 "range prop" 测试用例,验证了日期范围选择功能。这对于确保用户可以正确选择日期范围非常重要。用例设置了合理的默认值和日期范围,并使用快照测试验证渲染结果。


91-106: 新增了季度视图模式的测试

新增了 "viewmode prop" 测试用例,验证了季度视图的正确渲染和交互。测试中模拟了点击事件,确保 onItemClick 回调正常工作。这是对新增的季度面板功能的重要测试覆盖。


108-121: 新增了带扩展日期范围的季度视图测试

这个测试用例验证了季度视图在跨多年的扩展日期范围下的正确渲染。通过对比快照确保组件在不同日期范围下保持一致的渲染结果,增强了组件的可靠性。


123-138: 新增了带点击事件的月视图测试

测试确保月视图模式下能正确渲染并响应点击事件。通过监视 onItemClick 回调函数验证交互功能,是对新增月面板功能的有效测试。


140-155: 新增了带扩展日期范围的月视图测试

该测试验证了月视图在跨多年的扩展日期范围下的渲染效果。这确保了日历组件在处理更大范围的日期时能够正确显示,提高了组件的稳健性。


157-168: 重命名并优化了弹出层属性测试

测试用例从 "show-today prop" 改名为 "popup prop",更准确地反映了测试内容。测试验证当 popup 设置为 false 时,弹出层元素不会被渲染,这对于组件可配置性的测试很重要。


170-199: 完善了插槽渲染测试

更新了自定义插槽的测试,包括 renderHeaderButtons、renderDay、renderDayTop 和 renderDayBottom 插槽的验证。这些更改确保了组件的自定义渲染功能正常工作,提高了组件的灵活性。


201-228: 新增了测试点击事件的辅助函数

添加了 testClickEvent 辅助函数,封装了日期点击测试的通用逻辑。这减少了代码重复,提高了测试代码的可维护性和可读性。函数设计合理,参数完整,可以适应不同类型的日历选择模式测试。


230-232: 重构单选事件测试

使用新的 testClickEvent 辅助函数重构了单选事件测试,使代码更加简洁和可维护。


234-238: 新增周选择事件测试

新增了周选择模式的测试用例,验证了不同场景下的周选择功能。测试包含了多个用例,覆盖了不同的初始值和点击位置,确保周选择功能在各种情况下都能正常工作。


240-273: 新增多选事件测试

新增了多选模式的测试用例,验证了用户可以选择多个独立的日期。测试步骤清晰,验证了初始选中状态和连续选择多个日期的行为,确保多选功能正确实现。


275-301: 重命名并优化了范围选择事件测试

测试用例从 "choose event when click item" 改名为 "range select event when click item",更准确地描述了测试内容。测试验证了范围选择的开始和结束日期功能,确保用户可以正确选择日期范围。

src/packages/calendaritem/calendaritem.taro.tsx (13)

1-14: 优化导入结构,精细化日期工具函数

代码已将之前的通用 Utils 导入替换为特定的日期工具函数,如 getDateStringcompareDate 等。这种变更有助于代码的可维护性和树摇优化。


65-65: 新增周号显示功能支持

成功添加了 showMonthNumber 属性,并设置默认值为 false,这个属性用于控制是否显示月面板中的周号。属性定义、传递和使用一致。

Also applies to: 93-93, 131-131


164-166: 优化初始日期处理方式

使用 getDateString 替代之前的 Utils.getDay 函数来设置默认的开始和结束日期,保持了与其他日期工具函数的一致性。


200-236: 优化月份数据生成函数

getMonthData 函数中,修改了引用日期工具函数的方式,并添加了周号信息 getWeekNosOfYear,以支持新的周号显示功能。


274-343: setDefaultDate 代码仍然较为复杂

该函数处理了多种选择类型(单选、范围、多选、周选择),逻辑复杂且代码量大。虽已优化,但仍可进一步重构。

建议将不同类型的日期处理逻辑抽离为单独的函数,例如:

- const setDefaultDate = () => {
+ const handleSingleDate = () => {
+   // 处理单选逻辑
+ }
+ 
+ const handleRangeDate = () => {
+   // 处理范围选择逻辑
+ }
+
+ const handleMultipleDate = () => {
+   // 处理多选逻辑
+ }
+
+ const handleWeekDate = () => {
+   // 处理周选择逻辑
+ }
+
+ const setDefaultDate = () => {
    let defaultData: CalendarValue = []
    if (type === 'single' && typeof currentDate === 'string') {
-     // 单选逻辑
+     return handleSingleDate()
    }
    if (Array.isArray(currentDate) && currentDate.length) {
      switch (type) {
        case 'range': {
-         // 范围选择逻辑
+         return handleRangeDate()
        }
        case 'multiple': {
-         // 多选逻辑
+         return handleMultipleDate()
        }
        case 'week': {
-         // 周选择逻辑
+         return handleWeekDate()
        }
        default:
          break
      }
    }
    return defaultData
  }

376-412: 优化了当前日期渲染函数

重构后的 renderCurrentDate 函数接受明确的参数 defaultDatacurrent,并使用 switch 结构处理不同类型的日期选择,提高了代码可读性。


414-420: 封装面板引用获取函数

新增的 getMonthsPanelgetMonthsRef 辅助函数封装了 DOM 引用的获取,提高了代码复用性和可维护性。


439-446: 添加月份数量计算独立函数

抽离 getMonthNum 函数处理月份数量计算,使逻辑更清晰,有利于代码复用和后续维护。


549-555: 封装日期禁用状态判断

新添加的 isDisable 函数集中处理日期禁用逻辑,使代码更加清晰,且便于后续维护和扩展。


727-736: 支持周号显示的UI优化

巧妙地通过条件类名 ${showMonthNumber ? ${classPrefix}-weeks-shrink : ''},根据是否展示周号来调整周标题的样式。


741-790: 抽离日期项渲染逻辑为独立函数

将日期项的渲染逻辑抽离为 renderItem 函数,使渲染流程更加清晰,代码更易维护。


792-813: 新增月面板渲染函数

新增的 renderPanel 函数封装了月面板渲染逻辑,并包含了新的周号显示功能。当 showMonthNumber 为 true 时,会显示周号列表。


861-865: 简化了根容器渲染

使用 div 元素替代了之前的自定义容器,使代码更简洁,同时保持了一致的类名和样式。

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/packages/calendaritem/calendaritem.tsx (1)

562-633: 🛠️ Refactor suggestion

handleDayClick函数逻辑优化,但分支仍然较多。

函数实现了对不同日期选择类型的处理,同时添加了isFirst参数控制是否为首次点击。但函数仍然包含了过多的分支处理不同类型的选择逻辑。

建议进一步拆分这个函数,将不同类型的日期选择处理逻辑提取到单独的函数中,以提高代码的可读性和可维护性。

推荐的重构方式:

-const handleDayClick = (day, month, isFirst = true) => {
+const handleDayClick = (day, month, isFirst = true) => {
+  if (getClasses(day, month) === `${dayPrefix}-disabled`) {
+    return
+  }
+  
+  const days = [...month.curData];
+  const [y, m] = month.curData;
+  days[2] = typeof day.day === 'number' ? getNumTwoBit(day.day) : day.day;
+  days[3] = `${days[0]}/${days[1]}/${days[2]}`;
+  days[4] = getWhatDay(+days[0], +days[1], +days[2]);
+  const newDate = days[3];
+  
+  // 使用策略模式处理不同类型
+  const typeHandlers = {
+    multiple: () => handleMultipleClick(newDate, days, isFirst),
+    range: () => handleRangeClick(newDate, days),
+    week: () => handleWeekClick(y, m, day.day),
+    single: () => handleSingleClick(days),
+  };
+  
+  (typeHandlers[type] || typeHandlers.single)();
+  
+  if (!isFirst) {
+    onDayClick?.(state.currDateArray);
+    if (autoBackfill || !popup) {
+      confirm();
+    }
+  }
+  setMonthsData(monthsData.slice());
+}
+
+const handleMultipleClick = (newDate, days, isFirst) => {
+  // 多选类型的逻辑
+}
+
+const handleRangeClick = (newDate, days) => {
+  // 范围选择类型的逻辑
+}
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 584-585: src/packages/calendaritem/calendaritem.tsx#L584-L585
Added lines #L584 - L585 were not covered by tests


[warning] 591-592: src/packages/calendaritem/calendaritem.tsx#L591-L592
Added lines #L591 - L592 were not covered by tests


[warning] 604-606: src/packages/calendaritem/calendaritem.tsx#L604-L606
Added lines #L604 - L606 were not covered by tests

🧹 Nitpick comments (5)
src/packages/calendar/demo.taro.tsx (1)

51-75: 繁体中文翻译完善

为新增功能提供了繁体中文翻译支持,保持了国际化的一致性。但注意部分翻译(如第57-58行)仍使用简体中文,建议统一为繁体中文表述。

-      '8dab2f67': '请选择起始时间',
-      '8dab2f68': '请选择截止时间',
+      '8dab2f67': '請選擇起始時間',
+      '8dab2f68': '請選擇截止時間',
src/packages/calendar/demos/taro/demo11.tsx (1)

19-25: 修改日历容器高度
将高度从原先的 613px 调整为 400px,可适配不同屏幕需求,但需注意小屏场景下的可滚动性。

src/packages/calendar/calendarviewmodeitem.taro.tsx (1)

337-408: 分层渲染提升可读性
renderHeaderrenderPanelrenderContent 分工明确,清晰构造日历结构;可进一步考虑将多处重复样式使用常量或封装组件以保持代码整洁。

src/packages/calendar/calendarviewmodeitem.tsx (1)

337-408: 多层渲染结构
通过 renderHeaderrenderPanelrenderContent 分拆 UI,结构更具可读性。可以考虑在子组件中进一步拆分块状,这样更易维护。

src/packages/calendar/calendar.scss (1)

122-143: 新增周号显示相关的样式。

添加了&-weeknumber相关样式,支持周号的显示,包括不同环境下的宽度适配以及对齐方式,布局结构清晰。但条件编译注释可能会增加样式维护的复杂性。

考虑使用SCSS变量或mixin来替代条件编译注释,以提高可维护性:

$weeknumber-width-harmony: 25%;
$weeknumber-width-other: 35%;

&-weeknumber {
  width: $weeknumber-width-other; // 默认值
  flex: 1;
  
  // 可以使用自定义属性在运行时切换
  // 或者构建时通过SCSS变量配置
  
  &-index {
    // 其他样式保持不变
  }
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eb8737a and e9d5905.

⛔ Files ignored due to path filters (2)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • src/packages/calendar/__tests__/__snapshots__/calendar.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (14)
  • scripts/harmony/update-taro-entry.js (1 hunks)
  • src/config.json (1 hunks)
  • src/packages/calendar/calendar.scss (9 hunks)
  • src/packages/calendar/calendarviewmodeitem.taro.tsx (1 hunks)
  • src/packages/calendar/calendarviewmodeitem.tsx (1 hunks)
  • src/packages/calendar/demo.scss (1 hunks)
  • src/packages/calendar/demo.taro.tsx (3 hunks)
  • src/packages/calendar/demos/taro/demo101.tsx (1 hunks)
  • src/packages/calendar/demos/taro/demo102.tsx (1 hunks)
  • src/packages/calendar/demos/taro/demo103.tsx (1 hunks)
  • src/packages/calendar/demos/taro/demo11.tsx (2 hunks)
  • src/packages/calendar/demos/taro/demo5.tsx (3 hunks)
  • src/packages/calendaritem/calendaritem.taro.tsx (17 hunks)
  • src/packages/calendaritem/calendaritem.tsx (19 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/packages/calendar/demos/taro/demo103.tsx
  • src/packages/calendar/demos/taro/demo102.tsx
  • src/packages/calendar/demos/taro/demo101.tsx
🧰 Additional context used
🧬 Code Definitions (3)
src/packages/calendar/demos/taro/demo11.tsx (2)
src/packages/calendar/calendar.taro.tsx (1) (1)
  • Calendar (43:190)
src/packages/calendar/calendar.tsx (1) (1)
  • Calendar (43:190)
src/packages/calendaritem/calendaritem.tsx (2)
src/utils/date.ts (6) (6)
  • getDateString (95:99)
  • compareDate (105:109)
  • getMonthDays (48:69)
  • isEqual (115:119)
  • getNumTwoBit (75:77)
  • getWhatDay (17:33)
src/types/spec/calendar/base.ts (2) (2)
  • CalendarDay (5:8)
  • CalendarMonthInfo (10:17)
src/packages/calendaritem/calendaritem.taro.tsx (4)
src/utils/date.ts (6) (6)
  • getDateString (95:99)
  • compareDate (105:109)
  • getMonthDays (48:69)
  • isEqual (115:119)
  • getNumTwoBit (75:77)
  • getWhatDay (17:33)
src/packages/calendaritem/utils.ts (6) (6)
  • getPreMonthDates (39:68)
  • getDaysStatus (22:36)
  • getWeekNosOfYear (153:177)
  • getCurrMonthData (10:19)
  • getWeekDate (70:98)
  • formatResultDate (100:106)
src/types/spec/calendar/base.ts (2) (2)
  • CalendarDay (5:8)
  • CalendarMonthInfo (10:17)
src/packages/calendar/utils.ts (7) (7)
  • splitDate (4:7)
  • getCurrDate (23:25)
  • isStart (27:29)
  • isEnd (31:33)
  • isMultiple (9:16)
  • isCurrDay (18:21)
  • isStartAndEnd (36:38)
🪛 GitHub Check: codecov/patch
src/packages/calendaritem/calendaritem.tsx

[warning] 274-275: src/packages/calendaritem/calendaritem.tsx#L274-L275
Added lines #L274 - L275 were not covered by tests


[warning] 277-277: src/packages/calendaritem/calendaritem.tsx#L277
Added line #L277 was not covered by tests


[warning] 279-279: src/packages/calendaritem/calendaritem.tsx#L279
Added line #L279 was not covered by tests


[warning] 395-396: src/packages/calendaritem/calendaritem.tsx#L395-L396
Added lines #L395 - L396 were not covered by tests


[warning] 460-460: src/packages/calendaritem/calendaritem.tsx#L460
Added line #L460 was not covered by tests


[warning] 462-462: src/packages/calendaritem/calendaritem.tsx#L462
Added line #L462 was not covered by tests


[warning] 505-505: src/packages/calendaritem/calendaritem.tsx#L505
Added line #L505 was not covered by tests


[warning] 507-508: src/packages/calendaritem/calendaritem.tsx#L507-L508
Added lines #L507 - L508 were not covered by tests


[warning] 549-549: src/packages/calendaritem/calendaritem.tsx#L549
Added line #L549 was not covered by tests


[warning] 584-585: src/packages/calendaritem/calendaritem.tsx#L584-L585
Added lines #L584 - L585 were not covered by tests


[warning] 591-592: src/packages/calendaritem/calendaritem.tsx#L591-L592
Added lines #L591 - L592 were not covered by tests


[warning] 604-606: src/packages/calendaritem/calendaritem.tsx#L604-L606
Added lines #L604 - L606 were not covered by tests


[warning] 768-769: src/packages/calendaritem/calendaritem.tsx#L768-L769
Added lines #L768 - L769 were not covered by tests


[warning] 771-776: src/packages/calendaritem/calendaritem.tsx#L771-L776
Added lines #L771 - L776 were not covered by tests

src/packages/calendar/calendarviewmodeitem.tsx

[warning] 124-125: src/packages/calendar/calendarviewmodeitem.tsx#L124-L125
Added lines #L124 - L125 were not covered by tests


[warning] 168-168: src/packages/calendar/calendarviewmodeitem.tsx#L168
Added line #L168 was not covered by tests


[warning] 293-293: src/packages/calendar/calendarviewmodeitem.tsx#L293
Added line #L293 was not covered by tests


[warning] 308-308: src/packages/calendar/calendarviewmodeitem.tsx#L308
Added line #L308 was not covered by tests


[warning] 310-313: src/packages/calendar/calendarviewmodeitem.tsx#L310-L313
Added lines #L310 - L313 were not covered by tests


[warning] 331-332: src/packages/calendar/calendarviewmodeitem.tsx#L331-L332
Added lines #L331 - L332 were not covered by tests

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (90)
src/packages/calendar/demo.scss (1)

43-43: 样式更改适当

.info 类添加居中对齐样式提升了日历信息的视觉展示效果,使文本内容更加整齐美观。

scripts/harmony/update-taro-entry.js (1)

49-50: 良好的排序处理

co.pages 数组进行排序是一个好的实践,这样可以确保页面列表的顺序保持一致,提高了配置的可预测性和可维护性。

src/packages/calendar/demos/taro/demo5.tsx (3)

4-6: 组件重命名和动态年份计算

将组件从 Demo5 重命名为 Demo 保持了命名一致性。引入动态年份变量 d 是一个好的改进,这样日期范围会随着当前年份自动更新。


37-38: 动态日期范围设置

使用动态计算的年份来设置 startDateendDate 属性,使示例更加通用和持久有效,避免了每年手动更新日期的需要。


47-47: 更新导出语句

导出语句已正确更新为新的组件名称,与组件声明保持一致。

src/packages/calendar/demo.taro.tsx (6)

1-20: 新功能导入和平台兼容性

引入 Suspenselazy 组件用于条件渲染,提高了代码的加载效率。添加了新的演示组件 Demo101Demo102Demo103 用于展示季度面板、月面板和周号显示功能,丰富了日历组件的功能展示。


23-23: 条件加载处理

针对不同平台环境对 Demo6 的加载进行了优化处理,使用 harmony() 函数判断当前环境,提高了代码的平台适配性。


30-50: 中文翻译完善

为新增的日历功能添加了完整的中文翻译,包括季度面板、月面板、展示周号等相关文案,翻译表述清晰准确。


76-102: 英文翻译完善

为所有新功能提供了对应的英文翻译,支持国际化需求,翻译准确专业。


115-115: 条件渲染优化

使用 Suspense 组件包装 Demo6,结合 harmony() 函数判断,实现了更优雅的条件渲染方式,提高了代码的可读性和维护性。


124-129: 新功能展示区域

添加了季度面板、月面板和周号显示的演示区域,使用适当的标题和对应的演示组件,清晰展示了新增功能,结构组织合理。

src/config.json (3)

480-481: 更新作者信息并激活 dd 属性
你将作者改为 hanyuxinting 并将 dd 设置为 true,从配置角度看并无冲突,能正常激活指定功能。


484-484: 确认版本升级对外部依赖的影响
版本号从 2.0.0 升级至 3.0.0 后,需确保在上层依赖或文档中同步更新,避免不兼容问题。


491-491: 启用 Taro 平台支持
taro 设置为 true,请确认对应平台的编译和特性已在项目中正常启用,以防构建时出现意外。

src/packages/calendar/demos/taro/demo11.tsx (5)

3-3: 在 Taro 中引入 ViewText 组件
此处替换原生标签为 Taro 组件,能保证在多端环境下正常渲染。


5-7: 初始化组件名及日期状态
命名 Demo 更具可读性,你使用 useState 动态生成基于当年年份的日期范围,逻辑清晰。


32-36: 动态设置起止日期与起始文案
采用模板字符拼接 d - 1d + 1,使如去年、未来的范围更灵活;<Text> 标签包裹文案时请留意样式及对比度。


42-42: 闭合容器标签
额外的 </View> 标签位置正确,结构清晰,无明显问题。


46-46: 默认导出 Demo
保持导出简洁一致,与组件命名对齐,方便在其他模块中引入。

src/packages/calendar/calendarviewmodeitem.taro.tsx (6)

1-16: 导入与类型定义
引入了 React, useState, useEffect, useRef 以及相关工具类,能够满足组件的基本需求与交互。类型定义如 CalendarRef 可提高可读性与健壮性。


22-66: 解构属性并应用默认值
将默认属性与 props 合并,便于统一管理;通过 React.forwardRef 使父组件可获取内部方法。请确保对必要属性(如 startDate, endDate)的校验已在上层或此处完善。


129-176: 提取公共动画逻辑
requestAniFrameFunc 内对 monthquarter 类型进行类似逻辑操作,重复率高,建议将公共部分抽离处理,降低分支代码重复度。


174-228: 月面板与季面板通用逻辑重复
getMonthsData 函数较长且与季度逻辑类似,可考虑抽离年份滚动与范围数据组装的公共代码,提升可维护性和拓展性。


229-279: 季度面板计算与月面板高度近似
getQuartersDatagetMonthsData 思路雷同,若后续再新增周或年面板,可考虑统一处理策略后按维度区分,防止多个类似方法散落难维护。


305-335: 点击处理与状态更新
handleItemClick 函数区分 type !== 'curr' 以外直接返回,简单易懂;更新选中值后同时触发 onItemClick 回调,满足业务场景。

src/packages/calendar/calendarviewmodeitem.tsx (6)

1-25: 导入与类型声明
借助 classNames, usePropsValue 等工具可简化样式合并与数据管理;请确保项目打包及 Tree Shaking 正常避免冗余体积。


26-61: 默认属性与 forwardRef 结构
将默认值合并到使用者传入的 props 操作简单直观;合理运用 forwardRef 便于父组件调用内部方法,增进组件扩展性。


129-169: 相似 month / quarter 逻辑可提炼
与上一文件类似,requestAniFrameFunc 内存在分支重复代码,可考虑统一处理核心逻辑,减少维护负担。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 168-168: src/packages/calendar/calendarviewmodeitem.tsx#L168
Added line #L168 was not covered by tests


174-228: 月数据计算重复度高
getMonthsData 函数较为庞大,且与季度逻辑有相当部分相似,希望后续能抽象公共逻辑,减少代码量。


229-279: 季度数据与月数据的通用性
getQuartersData 在处理年度间跨越或面板高度时与月数据相近,建议通用封装后再根据季度或月份做分支细化。


305-335: 点击逻辑与 innerValue 更新
若用户点击非当前可选类型,函数立即返回,简洁明了;更新值后触发回调有助于在外层同步状态,整体无安全漏洞。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 308-308: src/packages/calendar/calendarviewmodeitem.tsx#L308
Added line #L308 was not covered by tests


[warning] 310-313: src/packages/calendar/calendarviewmodeitem.tsx#L310-L313
Added lines #L310 - L313 were not covered by tests


[warning] 331-332: src/packages/calendar/calendarviewmodeitem.tsx#L331-L332
Added lines #L331 - L332 were not covered by tests

src/packages/calendaritem/calendaritem.tsx (16)

7-13: 优化了工具函数的导入方式,提高了代码可维护性。

Utils整体导入改为按需导入具体函数,这种变更使代码依赖更加明确,并且可以更好地支持Tree Shaking优化。


14-21: 导入了更多工具函数,扩展了日历功能。

新导入的函数如getWeekDateformatResultDategetDaysStatusgetWeekNosOfYear,为新增的月面板、季面板及周号展示功能提供了支持。


64-64: 新增showMonthNumber属性提供周号展示能力。

这个属性允许日历组件显示周号,增强了日期上下文信息的可视化,对于需要按周规划的场景很有帮助。


84-86: 使用新的日期工具函数替换了旧实现。

startDateendDate的默认值实现改为使用getDateString函数,保持了代码一致性,与其他地方的修改保持同步。


92-93: 为新增的showMonthNumber属性设置默认值为false

良好的默认值设置可以确保API的向后兼容性,新用户可以选择性启用此功能。


196-236: getMonthData函数重构,优化了日期计算和判断逻辑。

函数移除了type参数,简化了签名。使用新的比较函数compareDate替换了旧的比较方式,同时增加了对周号(weekNo)的支持。代码更加清晰,逻辑更加集中。


270-284: 单选模式下的日期验证逻辑优化。

改进了对单选模式下日期范围验证的处理,使用compareDate函数替代了之前的实现,逻辑更加清晰。

然而,这个函数处理了多种选择类型(单选、范围、多选、周选择),逻辑较为复杂。

考虑将不同选择类型的处理逻辑拆分为单独的函数,以提高代码的可读性和可维护性:

-const setDefaultDate = () => {
+const setDefaultDate = () => {
+  return type === 'single' ? setSingleTypeDefault() : setMultipleTypeDefault();
+}
+
+const setSingleTypeDefault = () => {
   let defaultData: CalendarValue = []
   if (type === 'single' && typeof currentDate === 'string') {
     if (!currentDate.length) {
       return defaultData
     }
     if (compareDate(currentDate, propStartDate)) {
       defaultData = [...splitDate(propStartDate)]
     } else if (!compareDate(currentDate, propEndDate)) {
       defaultData = [...splitDate(propEndDate)]
     } else {
       defaultData = [...splitDate(currentDate)]
     }
     return defaultData
   }
+  return defaultData;
+}
+
+const setMultipleTypeDefault = () => {
+  let defaultData: CalendarValue = []
   // 其他类型的处理逻辑...
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 274-275: src/packages/calendaritem/calendaritem.tsx#L274-L275
Added lines #L274 - L275 were not covered by tests


[warning] 277-277: src/packages/calendaritem/calendaritem.tsx#L277
Added line #L277 was not covered by tests


[warning] 279-279: src/packages/calendaritem/calendaritem.tsx#L279
Added line #L279 was not covered by tests


365-392: renderCurrentDate函数重构,提高了灵活性。

函数现在接受参数,并根据不同的日期类型进行处理,增加了代码的可复用性。这种设计使得函数能够处理各种不同的日期选择场景。


394-400: 新增了辅助函数获取DOM元素。

getMonthsPanelgetMonthsRef函数封装了DOM引用的获取逻辑,提高了代码的可读性和可维护性,减少了重复代码。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 395-396: src/packages/calendaritem/calendaritem.tsx#L395-L396
Added lines #L395 - L396 were not covered by tests


416-423: 月份数计算逻辑独立为函数,提高了代码结构。

将月份数计算逻辑提取为单独的getMonthNum函数,使代码更加清晰和可维护,也便于测试。


525-531: 封装了日期禁用逻辑为isDisable函数。

新增了isDisable函数,集中处理日期禁用的判断逻辑,使代码更加清晰且便于维护。


533-560: 重构getClasses函数,使用了新的禁用判断逻辑。

使用新的isDisable函数优化了类名判断逻辑,同时保持了函数的主要功能。代码更加结构化,逻辑更清晰。

不过,函数中包含了过多的条件判断,可能影响可读性和维护性。

建议使用策略模式或Map对象将不同类型的类名判断逻辑分离,以减少if-else嵌套:

const typeToClassStrategy = {
  'range': (dateStr) => {
    // 范围选择的类名逻辑
  },
  'week': (dateStr) => {
    // 周选择的类名逻辑
  },
  'multiple': (dateStr) => {
    // 多选的类名逻辑
  },
  'single': (dateStr) => {
    // 单选的类名逻辑
  }
};

// 使用策略
const getClasses = (day, month) => {
  if (isDisable(day, month)) return `${dayPrefix}-disabled`;
  return typeToClassStrategy[type](getCurrDate(day, month)) || null;
};
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 549-549: src/packages/calendaritem/calendaritem.tsx#L549
Added line #L549 was not covered by tests


697-707: 更新了周号展示相关的类名和样式。

为支持周号展示功能,添加了条件类名${classPrefix}-weeks-shrink,确保在显示周号时有正确的样式应用。


711-790: 添加了renderItem函数,提升了代码可复用性。

renderItem函数封装了日历项的渲染逻辑,包括各种提示信息和状态的渲染,使代码更加模块化,提高了可维护性。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 768-769: src/packages/calendaritem/calendaritem.tsx#L768-L769
Added lines #L768 - L769 were not covered by tests


[warning] 771-776: src/packages/calendaritem/calendaritem.tsx#L771-L776
Added lines #L771 - L776 were not covered by tests


762-786: 添加了renderPanel函数,整合了月面板渲染逻辑。

renderPanel函数整合了月面板的渲染,包括标题、周号和日期部分,同时支持了新增的周号显示功能。这种模块化的渲染方式使代码更加清晰。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 768-769: src/packages/calendaritem/calendaritem.tsx#L768-L769
Added lines #L768 - L769 were not covered by tests


[warning] 771-776: src/packages/calendaritem/calendaritem.tsx#L771-L776
Added lines #L771 - L776 were not covered by tests


803-804: 简化了渲染方式,使用新的函数组件化的方式。

将原来的内联渲染逻辑改为使用renderPanel函数,提高了代码的可读性和可维护性。

src/packages/calendar/calendar.scss (15)

3-4: 扩展了日历组件样式的使用范围。

.nut-calendar-viewmode新增为共享样式的选择器,这种方式允许多种视图模式共享基础样式,减少了代码重复。


51-52: 统一了文本对齐方式,提高UI一致性。

增加了明确的text-align: center样式,确保各处标题和内容对齐方式一致,提高了UI的一致性和美观度。

Also applies to: 58-59, 118-119


68-71: 添加了周视图的收缩模式支持。

通过&-weeks-shrink类添加了左侧padding,为周号显示留出空间,确保在显示周号时整体布局协调。


84-86: 优化日历内容区域的布局方式。

display: block改为display: flex并添加flex-wrap: wrap,使得内容区域可以更灵活地适应不同的布局需求,特别是对于不同的视图模式。


145-148: 为Web环境添加特殊的周号样式。

通过&-weeknumber-web类为Web环境提供了特定的样式,确保在不同平台上都有良好的表现。


152-157: 优化日期显示区域的布局。

添加了flex布局支持,以及&-days-shrink类来处理周号显示时的布局调整,提高了布局的灵活性。


159-159: 统一命名从&-day改为&-item,保持一致性。

将类名从&-day更改为&-item,保持了组件内部命名的一致性,有助于维护和理解代码。


176-179: 统一了字体大小和文本对齐样式。

明确指定font-sizetext-align属性,确保UI表现的一致性,提高了用户体验。


208-217: 更新了激活状态的样式选择器。

.nut-calendar-day-*相关选择器更新为.nut-calendar-item-*.nut-calendar-viewmode-item-*,适应新的命名规范,同时保持了样式功能的一致性。


220-238: 更新了禁用状态的样式选择器。

与激活状态类似,更新了禁用、上个月、下个月日期的样式选择器,使其与新的命名规范一致。


248-261: 更新了选中状态下禁用项的样式选择器。

更新了复合状态(选中且禁用)的样式选择器,确保在所有状态组合下视觉表现一致。


265-268: 添加新的布局辅助类。

添加.shrink类支持弹性布局,用于周号显示时优化整体布局结构。


269-279: 新增面板相关样式。

添加&-panel及相关样式,为新增的面板视图模式提供样式支持,布局结构清晰。


301-308: 补充日历项特殊日的颜色样式。

为周末(第7天和第1天)添加特殊颜色样式,提高日历的可读性和用户体验。


310-314: 添加视图模式特有的样式。

.nut-calendar-viewmode下的项目设置了固定宽度,确保在不同视图模式下的一致表现。

src/packages/calendaritem/calendaritem.taro.tsx (28)

7-14: 优化了工具函数的导入方式,提高了代码可维护性。

从整体导入Utils改为按需导入具体函数,使代码依赖更加明确,并且可以更好地支持Tree Shaking优化。


15-22: 导入了更多工具函数,扩展了日历功能。

新导入的函数如getWeekDateformatResultDategetDaysStatusgetWeekNosOfYear,为新增的月面板、季面板及周号展示功能提供了支持。


65-65: 新增showMonthNumber属性提供周号展示能力。

这个属性允许日历组件显示周号,增强了日期上下文信息的可视化,对于需要按周规划的场景很有帮助。


85-86: 使用新的日期工具函数替换了旧实现。

startDateendDate的默认值实现改为使用getDateString函数,保持了代码一致性。


93-94: 为新增的showMonthNumber属性设置默认值为false

良好的默认值设置可以确保API的向后兼容性,新用户可以选择性启用此功能。


146-148: 统一了类名前缀变量。

添加了classPrefixdayPrefix变量,使得类名引用更加一致,减少了硬编码字符串,提高了可维护性。


200-236: getMonthData函数重构,优化了日期计算和判断逻辑。

使用新的比较函数compareDate替换了旧的比较方式,增加了对周号的支持。代码逻辑更加清晰。


274-288: 单选模式下的日期验证逻辑优化。

改进了对单选模式下日期范围验证的处理,使用compareDate函数替代了之前的实现,逻辑更加清晰。


290-340: 使用switch语句重构了多种选择类型的逻辑。

将if-else链改为switch结构,每种选择类型的处理通过case分支清晰区分,增加了代码的可读性。这是比Web版本更好的实现方式。


365-368: 优化了对月份查找的代码实现。

使用箭头函数改进了findIndex的可读性,同时确保了类型的正确比较。


376-412: renderCurrentDate函数使用switch语句重构,提高了可读性。

setDefaultDate类似,使用switch结构替代if-else链,使不同类型的处理逻辑更加清晰。


414-420: 新增了辅助函数获取DOM元素。

getMonthsPanelgetMonthsRef函数封装了DOM引用的获取逻辑,减少了重复代码。


430-436: 优化了滚动初始化逻辑。

添加了setScrollTop调用,确保滚动位置状态与实际DOM一致,在Taro环境中更加必要。


439-446: 月份数计算逻辑独立为函数,提高了代码结构。

将月份数计算逻辑提取为单独的getMonthNum函数,使代码更加清晰和可维护。


452-462: 优化了初始化流程,提高了代码可读性。

添加了注释说明每个步骤的作用,使初始化流程更加清晰。


483-486: 使用新的日期比较函数优化了API实现。

scrollToDate函数中使用compareDate替换了旧的比较逻辑,保持了一致性。


506-507: 增加了滚动状态同步,确保状态一致性。

在滚动操作完成后添加了setScrollTop调用,确保组件状态与实际DOM保持同步。

Also applies to: 512-513


520-520: 优化了边界条件检查,提高代码健壮性。

添加了提前返回的条件检查,避免在monthsData长度不足时执行不必要的计算。


529-533: 优化了当前月份计算逻辑,修复了潜在问题。

改进了滚动位置基于月份计算的逻辑,确保正确计算当前显示的月份。


549-555: 封装了日期禁用逻辑为isDisable函数。

新增了isDisable函数,集中处理日期禁用的判断逻辑,使代码更加清晰。


557-584: 重构getClasses函数,使用了新的禁用判断逻辑。

使用新的isDisable函数优化了类名判断逻辑,条件判断更加清晰。


591-591: 优化了点击禁用日期的处理逻辑。

合并了禁用条件判断,同时检查isDisabledisableDate的结果,提高了代码的健壮性。


599-655: 使用switch语句重构了点击处理逻辑,提高了可读性。

将if-else链改为switch结构,每种选择类型的处理通过case分支清晰区分,增加了代码的可读性和可维护性。


727-730: 更新了周号展示相关的类名和样式。

添加了条件类名${classPrefix}-weeks-shrink,确保在显示周号时有正确的样式应用。


741-790: 添加了renderItem函数,提升了代码可复用性。

renderItem函数封装了日历项的渲染逻辑,包括各种提示信息和状态的渲染,与Web版本保持一致,提高了可维护性。


792-816: 添加了renderPanel函数,整合了月面板渲染逻辑。

renderPanel函数整合了月面板的渲染,包括标题、周号和日期部分,同时使用Taro的View组件替代了Web版本的div元素。


796-813: 增加了对周号显示的支持与样式控制。

renderPanel中添加了条件渲染周号的逻辑,以及对应的样式类名控制,确保在启用周号显示时有正确的布局。


837-838: 简化了渲染方式,使用新的函数组件化的方式。

将原来的内联渲染逻辑改为使用renderPanel函数,提高了代码的可读性和可维护性。

@xiaoyatong xiaoyatong changed the title feat(Calendar): 合并2.x功能,支持月面板、季面板,支持展示周号 feat(Calendar): 合并2.x功能,支持月面板、季面板,支持展示周号,鸿蒙适配 Mar 19, 2025
@oasis-cloud
Copy link
Collaborator

oasis-cloud commented Mar 19, 2025

鸿蒙下样式问题,周日和周六没有高亮
image

鸿蒙下单个日期高度比其他端高
image

展示周号的 demo 只能滑动到 24年1月,与其他端不一致。其他 demo 也存在类似问题

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/packages/calendaritem/calendaritem.tsx (1)

733-782: 提取渲染逻辑提高可维护性

将日期项渲染逻辑抽取为单独的renderItem函数,使主渲染逻辑更加清晰。

不过,这个函数有些长,处理了多种不同的条件渲染情况,依然可以进一步优化。

考虑将renderItem进一步拆分为更小的函数,例如:

  • renderDayContent - 渲染日期内容
  • renderDayTopInfo - 渲染顶部信息
  • renderDayBottomInfo - 渲染底部信息
  • renderDayTips - 渲染提示信息
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e9d5905 and 98e0ff2.

⛔ Files ignored due to path filters (1)
  • src/packages/calendar/__tests__/__snapshots__/calendar.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (5)
  • src/packages/calendar/__tests__/calendar.spec.tsx (1 hunks)
  • src/packages/calendar/calendar.scss (9 hunks)
  • src/packages/calendar/calendar.taro.tsx (6 hunks)
  • src/packages/calendaritem/calendaritem.taro.tsx (17 hunks)
  • src/packages/calendaritem/calendaritem.tsx (19 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/packages/calendar/calendar.scss
🧰 Additional context used
🧬 Code Definitions (4)
src/packages/calendaritem/calendaritem.taro.tsx (3)
src/utils/date.ts (6)
  • getDateString (95-99)
  • compareDate (105-109)
  • getMonthDays (48-69)
  • isEqual (115-119)
  • getNumTwoBit (75-77)
  • getWhatDay (17-33)
src/packages/calendaritem/utils.ts (6)
  • getPreMonthDates (39-68)
  • getDaysStatus (22-36)
  • getWeekNosOfYear (153-177)
  • getCurrMonthData (10-19)
  • getWeekDate (70-98)
  • formatResultDate (100-106)
src/types/spec/calendar/base.ts (2)
  • CalendarDay (5-8)
  • CalendarMonthInfo (10-17)
src/packages/calendar/__tests__/calendar.spec.tsx (1)
src/packages/calendar/calendar.taro.tsx (1)
  • Calendar (45-199)
src/packages/calendaritem/calendaritem.tsx (4)
src/utils/date.ts (5)
  • getDateString (95-99)
  • compareDate (105-109)
  • getMonthDays (48-69)
  • isEqual (115-119)
  • getNumTwoBit (75-77)
src/packages/calendaritem/utils.ts (2)
  • getCurrMonthData (10-19)
  • getWeekDate (70-98)
src/types/spec/calendar/base.ts (2)
  • CalendarDay (5-8)
  • CalendarMonthInfo (10-17)
src/packages/calendar/utils.ts (1)
  • splitDate (4-7)
src/packages/calendar/calendar.taro.tsx (3)
src/utils/date.ts (1)
  • getDateString (95-99)
src/packages/calendar/calendarviewmodeitem.taro.tsx (1)
  • CalendarViewModeItem (63-424)
src/packages/calendaritem/calendaritem.taro.tsx (1)
  • CalendarItem (107-888)
🪛 GitHub Check: build
src/packages/calendaritem/calendaritem.taro.tsx

[failure] 723-723:
Argument of type 'SimpleValue' is not assignable to parameter of type 'number | undefined'.


[failure] 723-723:
Property 'month' does not exist on type 'CalendarDay'.


[failure] 723-723:
Property 'year' does not exist on type 'CalendarDay'.

src/packages/calendaritem/calendaritem.tsx

[failure] 696-696:
Argument of type 'SimpleValue' is not assignable to parameter of type 'number | undefined'.


[failure] 696-696:
Property 'month' does not exist on type 'CalendarDay'.


[failure] 696-696:
Property 'year' does not exist on type 'CalendarDay'.

🪛 GitHub Actions: CI
src/packages/calendaritem/calendaritem.taro.tsx

[error] 723-723: error TS2339: Property 'year' does not exist on type 'CalendarDay'.

🪛 GitHub Check: codecov/patch
src/packages/calendaritem/calendaritem.tsx

[warning] 281-282: src/packages/calendaritem/calendaritem.tsx#L281-L282
Added lines #L281 - L282 were not covered by tests


[warning] 284-284: src/packages/calendaritem/calendaritem.tsx#L284
Added line #L284 was not covered by tests


[warning] 286-286: src/packages/calendaritem/calendaritem.tsx#L286
Added line #L286 was not covered by tests


[warning] 402-403: src/packages/calendaritem/calendaritem.tsx#L402-L403
Added lines #L402 - L403 were not covered by tests


[warning] 467-467: src/packages/calendaritem/calendaritem.tsx#L467
Added line #L467 was not covered by tests


[warning] 469-469: src/packages/calendaritem/calendaritem.tsx#L469
Added line #L469 was not covered by tests


[warning] 512-512: src/packages/calendaritem/calendaritem.tsx#L512
Added line #L512 was not covered by tests


[warning] 514-515: src/packages/calendaritem/calendaritem.tsx#L514-L515
Added lines #L514 - L515 were not covered by tests


[warning] 574-574: src/packages/calendaritem/calendaritem.tsx#L574
Added line #L574 was not covered by tests


[warning] 599-600: src/packages/calendaritem/calendaritem.tsx#L599-L600
Added lines #L599 - L600 were not covered by tests


[warning] 606-607: src/packages/calendaritem/calendaritem.tsx#L606-L607
Added lines #L606 - L607 were not covered by tests


[warning] 619-621: src/packages/calendaritem/calendaritem.tsx#L619-L621
Added lines #L619 - L621 were not covered by tests


[warning] 790-791: src/packages/calendaritem/calendaritem.tsx#L790-L791
Added lines #L790 - L791 were not covered by tests


[warning] 793-798: src/packages/calendaritem/calendaritem.tsx#L793-L798
Added lines #L793 - L798 were not covered by tests

🪛 Biome (1.9.4)
src/packages/calendar/calendar.taro.tsx

[error] 145-145: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (26)
src/packages/calendar/calendar.taro.tsx (6)

2-2: 导入方式优化明显

用具名导入替代了整体Utils对象导入,增强了代码可读性和可维护性,同时有利于打包工具进行tree-shaking优化。

Also applies to: 5-6, 10-10


15-15: 新增功能相关默认属性合理

增加了viewModevalueshowMonthNumber属性,并设置了合理的默认值,使组件更加灵活,符合PR目标支持不同视图模式。

Also applies to: 20-20, 30-30, 41-41


89-94: 良好的平台适配处理

新增了对harmony平台的样式适配,通过类名动态添加提高了跨平台兼容性。这与PR评论中提到的HarmonyOS平台样式问题相关,是一个好的改进。


97-97: 使用可选链更简洁

建议改为 "onDayClick?.(param)" 提升空值安全性和可读性。

Also applies to: 102-102


122-172: 视图模式渲染逻辑清晰

根据viewMode属性条件渲染不同的组件,结构清晰。CalendarViewModeItemCalendarItem组件传递了合适的属性。

不过,当切换视图模式时,onDayClick事件处理有差异,可能导致使用者困惑。

建议确认在不同视图模式下(月、季度视图),点击事件的回调行为是否一致。如果onItemClickonDayClick的调用方式和参数不同,应在文档中明确说明。

🧰 Tools
🪛 Biome (1.9.4)

[error] 145-145: Avoid passing children using a prop

The canonical way to pass children in React is to use JSX elements

(lint/correctness/noChildrenProp)


179-179: 弹窗条件逻辑优化

将弹窗显示与视图模式关联,确保只在日视图下才显示弹窗。这是一个很好的用户体验改进,避免了在月/季度视图中不必要的弹窗。

src/packages/calendaritem/calendaritem.tsx (8)

1-22: 导入优化提高了代码组织性

将通用的Utils导入改为具名导入,并按功能分组,提高了代码可读性和可维护性。


64-64: 新增周号显示属性

添加了showMonthNumber属性,并设置默认为false,这与PR目标支持周号显示相符。

Also applies to: 92-92


145-158: 优化了星期头部渲染

使用useMemo优化了星期头部的计算逻辑,并支持自定义每周起始日,增强了组件的灵活性。


203-243: 简化了月份数据获取逻辑

getMonthData函数签名简化,移除了不必要的type参数,并优化了内部实现,使用新的比较函数。


277-339: setDefaultDate 对多类型选择的处理

此处对 single、range、multiple、week 都做了初始值处理,逻辑复杂度较高。为减少维护成本,可考虑将各类型初始值分拆成独立的小函数,或封装策略模式来简化判断结构。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 281-282: src/packages/calendaritem/calendaritem.tsx#L281-L282
Added lines #L281 - L282 were not covered by tests


[warning] 284-284: src/packages/calendaritem/calendaritem.tsx#L284
Added line #L284 was not covered by tests


[warning] 286-286: src/packages/calendaritem/calendaritem.tsx#L286
Added line #L286 was not covered by tests


532-538: 抽取通用逻辑提高可维护性

将日期禁用状态判断抽取为独立函数isDisable,增强了代码的可读性和可维护性。


784-808: Panel渲染结构清晰

将月面板渲染逻辑提取为renderPanel函数,提高了代码组织性,并添加了周号显示相关的逻辑和样式。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 790-791: src/packages/calendaritem/calendaritem.tsx#L790-L791
Added lines #L790 - L791 were not covered by tests


[warning] 793-798: src/packages/calendaritem/calendaritem.tsx#L793-L798
Added lines #L793 - L798 were not covered by tests


577-648: handleDayClick 分支冗长。

不同类型的选中操作(multiple、range、week 等)混合在一个函数中,建议进一步提取子函数,无论是可读性还是测试覆盖都更易维护。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 599-600: src/packages/calendaritem/calendaritem.tsx#L599-L600
Added lines #L599 - L600 were not covered by tests


[warning] 606-607: src/packages/calendaritem/calendaritem.tsx#L606-L607
Added lines #L606 - L607 were not covered by tests


[warning] 619-621: src/packages/calendaritem/calendaritem.tsx#L619-L621
Added lines #L619 - L621 were not covered by tests

src/packages/calendar/__tests__/calendar.spec.tsx (5)

7-53: 测试用例更新合理

将"show-title prop"测试重命名为"single prop",更加准确地反映了测试内容,并添加了对点击确认按钮事件的测试。

测试代码结构清晰,验证了组件在不同prop配置下的行为。


55-71: 周模式测试用例完善

添加了周选择模式的测试,验证了firstDayOfWeek等新增属性的功能。测试用例中使用快照测试来确保UI渲染一致性。


91-155: 视图模式测试全面

为新增的视图模式(季度和月份)添加了完整的测试用例,并验证了不同日期范围下的行为,覆盖了PR引入的核心功能。

测试用例内容全面,同时测试了不同属性组合的情况,确保功能稳定性。


201-228: 测试代码复用优化

引入testClickEvent辅助函数,减少了测试代码中的重复部分,提高了测试代码的可维护性。函数参数设计合理,支持不同类型的日期选择测试。


234-273: 多选和周选择测试完善

为不同选择模式(周选择、多选)添加了专门的测试用例,验证了日期选择的交互行为。测试用例覆盖全面,确保了各种选择模式下的正确性。

src/packages/calendaritem/calendaritem.taro.tsx (7)

65-65: 新增周号显示属性

添加了showMonthNumber属性,并设置默认为false,与非Taro版本保持一致,确保了组件API的一致性。

Also applies to: 93-93


149-160: 使用useMemo优化星期头部渲染

与非Taro版本相同,使用useMemo优化了星期头部的计算,避免不必要的重复计算。


383-419: 优化日期渲染逻辑

使用switch语句重构了renderCurrentDate函数,使代码更加清晰和易于维护,各种选择模式的处理逻辑分离。


556-562: 抽取禁用逻辑为独立函数

与非Taro版本一致,抽取了日期禁用判断逻辑为isDisable函数,提高了代码复用性。


598-667: 使用switch优化选择逻辑

handleDayClick函数中,使用switch语句替代了if-else链,使代码结构更加清晰,每种选择类型的处理逻辑分离。这是对非Taro版本的改进。


760-809: 抽取渲染逻辑提高可维护性

将日期项和面板渲染逻辑抽取为独立函数,提高了代码清晰度。特别是添加了对周号显示的支持,与PR目标一致。

Also applies to: 811-835


825-831: 周号显示样式兼容性

PR评论中提到HarmonyOS平台上周号显示有问题。虽然添加了harmony样式类,但可能需要进一步调整样式以解决跨平台一致性问题。

建议验证此实现在HarmonyOS平台上的显示效果,特别是周六日高亮和日期高度问题。可能需要添加特定的平台样式覆盖。

Comment on lines 695 to 698
const isWeekend = (day: CalendarDay) => {
const d = new Date(day.year, day.month - 1, day.day).getDay()
return d === 0 || d === 6
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

修复类型错误问题

isWeekend函数存在类型错误。CalendarDay接口中没有定义yearmonthday属性,但在此处被使用,会导致编译错误。

建议修改为:

const isWeekend = (day: CalendarDay) => {
-  const d = new Date(day.year, day.month - 1, day.day).getDay()
+  // 使用可靠的方式从day对象中获取日期信息
+  const dayValue = typeof day.day === 'number' ? day.day : parseInt(day.day as string, 10)
+  // 使用当前月份的某一天来判断是否是周末
+  const d = new Date(new Date().getFullYear(), new Date().getMonth(), dayValue).getDay()
  return d === 0 || d === 6
}

或者更新CalendarDay接口,添加这些属性。

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isWeekend = (day: CalendarDay) => {
const d = new Date(day.year, day.month - 1, day.day).getDay()
return d === 0 || d === 6
}
const isWeekend = (day: CalendarDay) => {
// 使用可靠的方式从day对象中获取日期信息
const dayValue = typeof day.day === 'number' ? day.day : parseInt(day.day as string, 10)
// 使用当前月份的某一天来判断是否是周末
const d = new Date(new Date().getFullYear(), new Date().getMonth(), dayValue).getDay()
return d === 0 || d === 6
}
🧰 Tools
🪛 GitHub Check: build

[failure] 696-696:
Argument of type 'SimpleValue' is not assignable to parameter of type 'number | undefined'.


[failure] 696-696:
Property 'month' does not exist on type 'CalendarDay'.


[failure] 696-696:
Property 'year' does not exist on type 'CalendarDay'.

Comment on lines 722 to 725
const isWeekend = (day: CalendarDay) => {
const d = new Date(day.year, day.month - 1, day.day).getDay()
return d === 0 || d === 6
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

修复类型错误问题

isWeekend函数存在与非Taro版本相同的类型错误。CalendarDay接口中没有定义yearmonthday属性。

建议使用与非Taro版本相同的修复方案:

const isWeekend = (day: CalendarDay) => {
-  const d = new Date(day.year, day.month - 1, day.day).getDay()
+  // 使用可靠的方式从day对象中获取日期信息
+  const dayValue = typeof day.day === 'number' ? day.day : parseInt(day.day as string, 10)
+  // 使用当前月份的某一天来判断是否是周末
+  const d = new Date(new Date().getFullYear(), new Date().getMonth(), dayValue).getDay()
  return d === 0 || d === 6
}

或者更新CalendarDay接口,添加这些属性。这个错误导致了CI构建失败,需要优先修复。

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isWeekend = (day: CalendarDay) => {
const d = new Date(day.year, day.month - 1, day.day).getDay()
return d === 0 || d === 6
}
const isWeekend = (day: CalendarDay) => {
// 使用可靠的方式从day对象中获取日期信息
const dayValue = typeof day.day === 'number' ? day.day : parseInt(day.day as string, 10)
// 使用当前月份的某一天来判断是否是周末
const d = new Date(new Date().getFullYear(), new Date().getMonth(), dayValue).getDay()
return d === 0 || d === 6
}
🧰 Tools
🪛 GitHub Check: build

[failure] 723-723:
Argument of type 'SimpleValue' is not assignable to parameter of type 'number | undefined'.


[failure] 723-723:
Property 'month' does not exist on type 'CalendarDay'.


[failure] 723-723:
Property 'year' does not exist on type 'CalendarDay'.

🪛 GitHub Actions: CI

[error] 723-723: error TS2339: Property 'year' does not exist on type 'CalendarDay'.

@xiaoyatong
Copy link
Collaborator Author

样式问题已修订;鸿蒙下无法滚动问题,待跟进。

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
src/packages/calendaritem/calendaritem.tsx (2)

64-64: 新增属性:showMonthNumber
通过此布尔值控制是否在日历中展示月份编号,功能直观且富有弹性。建议在文档中说明此属性的用途及示例。


281-282: 单测覆盖不足
根据静态分析提示,这两行新增逻辑尚未被测试覆盖。建议补充测试用例,以提高代码稳定性和可维护性。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 281-282: src/packages/calendaritem/calendaritem.tsx#L281-L282
Added lines #L281 - L282 were not covered by tests

src/packages/calendaritem/utils.ts (1)

9-19: getCurrMonthData 方法可读性
当前逻辑清晰,但建议在 if (type === 'prev') / else if (type === 'next') 中添加注释,说明转换月份和年度的原因,方便后续接手者理解。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 12-13: src/packages/calendaritem/utils.ts#L12-L13
Added lines #L12 - L13 were not covered by tests

src/packages/calendaritem/calendaritem.taro.tsx (1)

85-86: 默认起止日期设置
使用 getDateString(0)getDateString(365) 作为默认时间区间,与普通版实现保持一致。可在文档中标注此默认值的意图,避免用户误解。

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 98e0ff2 and f410ba6.

📒 Files selected for processing (4)
  • src/packages/calendaritem/calendaritem.taro.tsx (17 hunks)
  • src/packages/calendaritem/calendaritem.tsx (19 hunks)
  • src/packages/calendaritem/utils.ts (1 hunks)
  • src/types/spec/calendar/base.ts (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/types/spec/calendar/base.ts
🧰 Additional context used
🧬 Code Definitions (3)
src/packages/calendaritem/calendaritem.tsx (4)
src/utils/date.ts (6)
  • getDateString (95-99)
  • compareDate (105-109)
  • getMonthDays (48-69)
  • isEqual (115-119)
  • getNumTwoBit (75-77)
  • getWhatDay (17-33)
src/packages/calendaritem/utils.ts (6)
  • getPreMonthDates (39-68)
  • getDaysStatus (22-36)
  • getWeekNosOfYear (153-177)
  • getCurrMonthData (10-19)
  • getWeekDate (70-98)
  • formatResultDate (100-106)
src/types/spec/calendar/base.ts (2)
  • CalendarDay (5-10)
  • CalendarMonthInfo (12-19)
src/packages/calendar/utils.ts (7)
  • splitDate (4-7)
  • getCurrDate (23-25)
  • isStart (27-29)
  • isEnd (31-33)
  • isMultiple (9-16)
  • isCurrDay (18-21)
  • isStartAndEnd (36-38)
src/packages/calendaritem/utils.ts (1)
src/utils/date.ts (5)
  • getNumTwoBit (75-77)
  • getMonthDays (48-69)
  • getMonthPreDay (39-42)
  • date2Str (83-88)
  • getWhatDay (17-33)
src/packages/calendaritem/calendaritem.taro.tsx (3)
src/utils/date.ts (6)
  • getDateString (95-99)
  • compareDate (105-109)
  • getMonthDays (48-69)
  • isEqual (115-119)
  • getNumTwoBit (75-77)
  • getWhatDay (17-33)
src/packages/calendaritem/utils.ts (6)
  • getPreMonthDates (39-68)
  • getDaysStatus (22-36)
  • getWeekNosOfYear (153-177)
  • getCurrMonthData (10-19)
  • getWeekDate (70-98)
  • formatResultDate (100-106)
src/types/spec/calendar/base.ts (2)
  • CalendarDay (5-10)
  • CalendarMonthInfo (12-19)
🪛 GitHub Check: codecov/patch
src/packages/calendaritem/calendaritem.tsx

[warning] 281-282: src/packages/calendaritem/calendaritem.tsx#L281-L282
Added lines #L281 - L282 were not covered by tests


[warning] 284-284: src/packages/calendaritem/calendaritem.tsx#L284
Added line #L284 was not covered by tests


[warning] 286-286: src/packages/calendaritem/calendaritem.tsx#L286
Added line #L286 was not covered by tests


[warning] 402-403: src/packages/calendaritem/calendaritem.tsx#L402-L403
Added lines #L402 - L403 were not covered by tests


[warning] 467-467: src/packages/calendaritem/calendaritem.tsx#L467
Added line #L467 was not covered by tests


[warning] 469-469: src/packages/calendaritem/calendaritem.tsx#L469
Added line #L469 was not covered by tests


[warning] 512-512: src/packages/calendaritem/calendaritem.tsx#L512
Added line #L512 was not covered by tests


[warning] 514-515: src/packages/calendaritem/calendaritem.tsx#L514-L515
Added lines #L514 - L515 were not covered by tests


[warning] 574-574: src/packages/calendaritem/calendaritem.tsx#L574
Added line #L574 was not covered by tests


[warning] 599-600: src/packages/calendaritem/calendaritem.tsx#L599-L600
Added lines #L599 - L600 were not covered by tests


[warning] 606-607: src/packages/calendaritem/calendaritem.tsx#L606-L607
Added lines #L606 - L607 were not covered by tests


[warning] 619-621: src/packages/calendaritem/calendaritem.tsx#L619-L621
Added lines #L619 - L621 were not covered by tests


[warning] 790-791: src/packages/calendaritem/calendaritem.tsx#L790-L791
Added lines #L790 - L791 were not covered by tests


[warning] 793-798: src/packages/calendaritem/calendaritem.tsx#L793-L798
Added lines #L793 - L798 were not covered by tests

src/packages/calendaritem/utils.ts

[warning] 12-13: src/packages/calendaritem/utils.ts#L12-L13
Added lines #L12 - L13 were not covered by tests


[warning] 26-27: src/packages/calendaritem/utils.ts#L26-L27
Added lines #L26 - L27 were not covered by tests

🪛 GitHub Check: build
src/packages/calendaritem/calendaritem.tsx

[failure] 696-696:
'day.month' is possibly 'undefined'.


[failure] 696-696:
Argument of type 'number | undefined' is not assignable to parameter of type 'number'.

src/packages/calendaritem/calendaritem.taro.tsx

[failure] 723-723:
'day.month' is possibly 'undefined'.


[failure] 723-723:
Argument of type 'number | undefined' is not assignable to parameter of type 'number'.

🪛 GitHub Actions: CI
src/packages/calendaritem/calendaritem.taro.tsx

[error] 723-723: error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'.

🔇 Additional comments (7)
src/packages/calendaritem/calendaritem.tsx (4)

1-13: 没有发现明显问题
该段引入了多个拆分后的日期工具函数,逻辑清晰无冲突,暂无需进一步调整。


84-85: 默认起止时间使用 getDateString
此处利用 getDateString(0)getDateString(365) 设置默认开始/结束日期。若用户有更灵活的日期范围需求,可能需要特殊处理。请确认是否符合产品设计。


92-92: 默认 showMonthNumber = false
此项设置与需求一致,未发现功能性问题。


147-158: weekHeader 的国际化处理
通过 locale.calendaritem.weekdays 来映射星期标题,能适应多语言场景,代码可读性较好。

src/packages/calendaritem/utils.ts (2)

1-7: 拆分后的日期工具函数
导入 getNumTwoBitgetMonthDaysgetWhatDay 等方法增强了模块化,对维护和测试有益。


153-177: getWeekNosOfYear 逻辑较为复杂
此前已有相似的重构建议,可将其拆分成更小的子函数,并配合注释解释不同条件判断,提升可读性与可维护性。

src/packages/calendaritem/calendaritem.taro.tsx (1)

65-65: 新增属性:showMonthNumber
Taro 端同样增设此属性,用法与 Web 端保持一致。未发现冲突,建议在 Demo 中提供更多示例。

Comment on lines 695 to 698
const isWeekend = (day: CalendarDay) => {
const d = new Date(day.year, day.month - 1, Number(day.day)).getDay()
return d === 0 || d === 6
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

潜在空值问题:isWeekend 函数
day.month 可能为 undefined,直接计算 day.month - 1 会导致 TS 类型冲突或运行期错误。需在此处进行空值校验或保证 yearmonth 一定存在。

可参考以下修正:

- const d = new Date(day.year, day.month - 1, Number(day.day)).getDay()
+ const { year, month, day: dayVal } = day
+ if (year == null || month == null) {
+   return false // 或根据业务逻辑处理
+ }
+ const d = new Date(year, month - 1, Number(dayVal)).getDay()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isWeekend = (day: CalendarDay) => {
const d = new Date(day.year, day.month - 1, Number(day.day)).getDay()
return d === 0 || d === 6
}
const isWeekend = (day: CalendarDay) => {
- const d = new Date(day.year, day.month - 1, Number(day.day)).getDay()
- return d === 0 || d === 6
+ const { year, month, day: dayVal } = day
+ if (year == null || month == null) {
+ return false // 或根据业务逻辑处理
+ }
+ const d = new Date(year, month - 1, Number(dayVal)).getDay()
+ return d === 0 || d === 6
}
🧰 Tools
🪛 GitHub Check: build

[failure] 696-696:
'day.month' is possibly 'undefined'.


[failure] 696-696:
Argument of type 'number | undefined' is not assignable to parameter of type 'number'.

Comment on lines 723 to 725
const d = new Date(day.year, day.month - 1, Number(day.day)).getDay()
return d === 0 || d === 6
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

可能的空值引用:isWeekend 函数
day.month 若为 undefined,则 new Date(day.year, day.month - 1, ...) 可能抛出错误。需补充空值保护或在接口层面强制定义必填字段。

- const d = new Date(day.year, day.month - 1, Number(day.day)).getDay()
+ if (!day.year || !day.month) {
+   return false
+ }
+ const d = new Date(day.year, day.month - 1, Number(day.day)).getDay()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const d = new Date(day.year, day.month - 1, Number(day.day)).getDay()
return d === 0 || d === 6
}
if (!day.year || !day.month) {
return false
}
const d = new Date(day.year, day.month - 1, Number(day.day)).getDay()
return d === 0 || d === 6
}
🧰 Tools
🪛 GitHub Check: build

[failure] 723-723:
'day.month' is possibly 'undefined'.


[failure] 723-723:
Argument of type 'number | undefined' is not assignable to parameter of type 'number'.

🪛 GitHub Actions: CI

[error] 723-723: error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
src/packages/calendaritem/calendaritem.tsx (1)

607-684: 🛠️ Refactor suggestion

拆分 handleDayClick 函数以减少复杂度

handleDayClick 同时处理多种选择模式分支(multiple、range、week、default),且依赖多处状态。建议拆分为更细的子函数,增强可读性与可维护性。

-const handleDayClick = (...) => {
-  // 多个 if-else 逻辑
-}
+const handleMultipleClick = (...) => { ... }
+const handleRangeClick = (...) => { ... }
+const handleWeekClick = (...) => { ... }
+const handleSingleClick = (...) => { ... }
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 619-621: src/packages/calendaritem/calendaritem.tsx#L619-L621
Added lines #L619 - L621 were not covered by tests

🧹 Nitpick comments (5)
src/packages/calendaritem/calendaritem.tsx (4)

64-64: 请确保在文档中标明新属性的用途

CalendarItemProps 中新增的 showMonthNumber 属性需要在相应的文档或注释中告知开发者它的使用场景与默认行为,方便快速上手。


84-85: 预设日期范围合理性

这里将 startDateendDate 默认为 getDateString(0)getDateString(365), 意味着默认起始日期是今天,结束日期是一年后。若日历仅用于短期选择场景,可视需求将范围适当缩短,以避免无意义的月份渲染开销。

Also applies to: 92-92


564-572: 判断周末的潜在类型风险

isWeekend 函数通过解析 month.curData 以及 day.day 获取具体时间后进行 getDay()。请注意若 curData 不符合 [year, month, dayCount] 的结构,可能引发潜在错误,需确保调用时一定传递了完整数据。


490-524: 滚动动画的性能考虑

scrollToDate 函数中通过 setInterval 来平滑滚动,如果定位月份较远,可能会触发较多 DOM 更新,影响性能。可考虑使用更优的动画方式(如 requestAnimationFrame)或缩短间隔减少抖动。

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 512-512: src/packages/calendaritem/calendaritem.tsx#L512
Added line #L512 was not covered by tests


[warning] 514-515: src/packages/calendaritem/calendaritem.tsx#L514-L515
Added lines #L514 - L515 were not covered by tests

src/packages/calendaritem/calendaritem.taro.tsx (1)

85-86: 默认日期范围是否合乎小程序使用场景

与非 Taro 版本相同,这里默认起始日期为今日,结束日期为一年后。请确认这对大多数移动端/小程序使用场景是否合理,若过大可能导致性能隐患或超出预期滚动范围。

Also applies to: 93-93

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f410ba6 and 2df6e09.

📒 Files selected for processing (3)
  • src/packages/calendaritem/calendaritem.taro.tsx (16 hunks)
  • src/packages/calendaritem/calendaritem.tsx (19 hunks)
  • src/types/spec/calendar/base.ts (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/types/spec/calendar/base.ts
🧰 Additional context used
🧬 Code Definitions (2)
src/packages/calendaritem/calendaritem.tsx (4)
src/utils/date.ts (6)
  • getDateString (95-99)
  • compareDate (105-109)
  • getMonthDays (48-69)
  • isEqual (115-119)
  • getNumTwoBit (75-77)
  • getWhatDay (17-33)
src/packages/calendaritem/utils.ts (6)
  • getPreMonthDates (39-68)
  • getDaysStatus (22-36)
  • getWeekNosOfYear (153-177)
  • getCurrMonthData (10-19)
  • getWeekDate (70-98)
  • formatResultDate (100-106)
src/types/spec/calendar/base.ts (2)
  • CalendarDay (5-8)
  • CalendarMonthInfo (10-17)
src/packages/calendar/utils.ts (2)
  • splitDate (4-7)
  • getCurrDate (23-25)
src/packages/calendaritem/calendaritem.taro.tsx (3)
src/utils/date.ts (6)
  • getDateString (95-99)
  • compareDate (105-109)
  • getMonthDays (48-69)
  • isEqual (115-119)
  • getNumTwoBit (75-77)
  • getWhatDay (17-33)
src/packages/calendaritem/utils.ts (6)
  • getPreMonthDates (39-68)
  • getDaysStatus (22-36)
  • getWeekNosOfYear (153-177)
  • getCurrMonthData (10-19)
  • getWeekDate (70-98)
  • formatResultDate (100-106)
src/types/spec/calendar/base.ts (2)
  • CalendarDay (5-8)
  • CalendarMonthInfo (10-17)
🪛 GitHub Check: codecov/patch
src/packages/calendaritem/calendaritem.tsx

[warning] 281-282: src/packages/calendaritem/calendaritem.tsx#L281-L282
Added lines #L281 - L282 were not covered by tests


[warning] 284-284: src/packages/calendaritem/calendaritem.tsx#L284
Added line #L284 was not covered by tests


[warning] 286-286: src/packages/calendaritem/calendaritem.tsx#L286
Added line #L286 was not covered by tests


[warning] 402-403: src/packages/calendaritem/calendaritem.tsx#L402-L403
Added lines #L402 - L403 were not covered by tests


[warning] 467-467: src/packages/calendaritem/calendaritem.tsx#L467
Added line #L467 was not covered by tests


[warning] 469-469: src/packages/calendaritem/calendaritem.tsx#L469
Added line #L469 was not covered by tests


[warning] 512-512: src/packages/calendaritem/calendaritem.tsx#L512
Added line #L512 was not covered by tests


[warning] 514-515: src/packages/calendaritem/calendaritem.tsx#L514-L515
Added lines #L514 - L515 were not covered by tests


[warning] 574-574: src/packages/calendaritem/calendaritem.tsx#L574
Added line #L574 was not covered by tests


[warning] 599-600: src/packages/calendaritem/calendaritem.tsx#L599-L600
Added lines #L599 - L600 were not covered by tests


[warning] 606-607: src/packages/calendaritem/calendaritem.tsx#L606-L607
Added lines #L606 - L607 were not covered by tests


[warning] 619-621: src/packages/calendaritem/calendaritem.tsx#L619-L621
Added lines #L619 - L621 were not covered by tests


[warning] 794-795: src/packages/calendaritem/calendaritem.tsx#L794-L795
Added lines #L794 - L795 were not covered by tests


[warning] 797-802: src/packages/calendaritem/calendaritem.tsx#L797-L802
Added lines #L797 - L802 were not covered by tests

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (5)
src/packages/calendaritem/calendaritem.tsx (2)

147-158: 基于 firstDayOfWeek 生成星期标题

通过切片方式动态重排 weekdays 功能实现清晰易懂,如需兼容更多本地化或自定义工作日定义,建议在组件使用文档中对 firstDayOfWeek 提示更多示例。


556-562: 禁用日期判断逻辑

新增的 isDisable 函数将 day.type !== 'active' 作为立即返回条件,后续对比 propStartDatepropEndDate。请确认业务需求:如果 day.type 为其他类型(如 prev/next),是否一定需要被禁用?

src/packages/calendaritem/calendaritem.taro.tsx (3)

65-65: 在 Taro 环境下新增 showMonthNumber

与非 Taro 版保持一致功能的同时,需要在文档里注明小程序端是否存在额外限制。若有平台差异,应在注释或文档中加以说明。


556-562: 统一禁用逻辑与 disableDate 回调

isDisable 函数与外层的 disableDate 回调在实际调用时可能产生冲突。当前写法优先级不明确,建议在文档上明确二者逻辑的覆盖或层级关系,以免使用者混淆。


608-684: handleDayClick 逻辑分支较多

同非 Taro 版,handleDayClick 中包括 range、multiple 等多模式处理,建议按模式拆分为独立函数,以减低圈复杂度并提高后续可重用性。

Comment on lines +564 to +571
const isWeekend = (day: CalendarDay, month: CalendarMonthInfo) => {
const d = new Date(
Number(month.curData[0]),
Number(month.curData[1]) - 1,
Number(day.day)
).getDay()
return d === 0 || d === 6
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

isWeekend 需防御性校验

此处使用 Number(day.day)month.curData 推算周末,若 day.daymonth.curData 不合预期,可能产生错误结果。考虑在取值前校验,或在接口层强制约定必要字段不为空。

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (20)
src/packages/calendar/doc.en-US.md (5)

101-124: 新增演示示例区块: 文档中新增了“Quarter ModeView”、“Month ModeView”以及“show the Week Number”的演示示例,代码引用了对应的 demo 文件。建议补充对各展示模式的详细说明,比如解释各模式的使用场景和界面差异,以便用户快速区分和应用这些新功能。


133-133: 新增属性 viewMode: 已在 Props 表中新增 viewMode 属性,支持 'day' | 'month' | 'quarter' 三种模式。建议在描述中增加各模式对应的界面变化说明,使用户对该属性的用途有更直观的理解。


146-146: 新增属性 showMonthNumber: 新增的 showMonthNumber 属性用于控制是否展示月面板中的数字(或周号)。说明较为简洁,建议补充默认行为及实际应用场景,帮助开发者更好地选择是否启用此功能。


157-157: 新增属性 onItemClick: 文档中引入了 onItemClick 属性,用于在季度或月面板中点击某项时触发事件。建议详细说明事件触发时返回的数据结构和可能的回调场景,以便用户在开发过程中快速上手。


200-200: 新增 CSS 变量 --nutui-calendar-panel-item-width: 添加的 CSS 变量用于设置月面板和季度面板中每个元素的宽度(默认值为 24.85%)。建议在文档中明确说明单位、默认行为以及如何根据需求进行自定义调整。

src/packages/calendar/doc.zh-TW.md (5)

101-124: 新增演示示例區塊: 繁體中文文檔中新增了“季度面板”、“月面板”以及“顯示周號”的示例,引用了相應的 demo 文件。建議補充對各展示模式特點與使用場合的說明,以便使用者更好理解新功能。


133-133: 新增屬性 viewMode: 在屬性表中添加了 viewMode 屬性,支持 'day' | 'month' | 'quarter' 模式。建議擴充說明,詳細描述每個模式下的視圖差異和適用情境。


146-146: 新增屬性 showMonthNumber: 新加入的 showMonthNumber 屬性用於控制是否展示周號。建議補充更多使用細節,例如默認值、示例場合等,來提升文檔的可讀性。


157-157: 新增屬性 onItemClick: 添加了 onItemClick 屬性,用於在月面板或季度面板中響應項目點擊事件。建議在文檔中補充事件的參數信息和觸發時機,以便開發者更好地使用該回調。


200-200: 新增 CSS 變量 --nutui-calendar-panel-item-width: 此 CSS 變量用於設置月面板和季度面板中每個元素的寬度(預設為 24.85%)。建議在說明中標明使用的單位和如何根據需要進行樣式定制。

src/packages/calendar/doc.taro.md (5)

101-124: 新增演示示例區塊: Taro 文檔中新增了季度面板、月面板和顯示周號的示例,引用了相應的 demo 文件。建議補充說明各模式的優勢與使用場景,幫助用戶更快理解新功能的實際應用。


133-133: 新增屬性 viewMode: 已在 Taro 文檔中添加 viewMode 屬性,允許選擇 'day' | 'month' | 'quarter' 模式。建議增加對各模式間顯示差異的說明,從而便於開發者選擇合適的模式。


146-146: 新增屬性 showMonthNumber: 新增的 showMonthNumber 屬性用於控制是否展示周號。建議在屬性描述中加入默認值和具體使用案例說明,以便更好地指導使用者。


157-157: 新增屬性 onItemClick: 添加的 onItemClick 屬性支持月面板/季度面板項目的點擊事件,建議文檔中進一步說明觸發機制及回調參數,以增強文檔的完整性。


200-200: 新增 CSS 變量 --nutui-calendar-panel-item-width: 用於設定月面板和季度面板每個項目寬度的 CSS 變量已被引入。建議說明該變量的設置單位(例如百分比)及自定義調整方式,方便用戶靈活應用。

src/packages/calendar/doc.md (5)

101-124: 新增示例演示區塊: 中文文檔中新增了“季度面板”、“月面板”與“顯示周號”的示例,並引用了相應的 demo 文件。建議補充對每種展示模式功能與適用場景的詳細描述,以提升用戶的理解與使用體驗。


133-133: 新增屬性 viewMode: 在 Props 表中添加的 viewMode 屬性支持 daymonthquarter 模式。建議擴充屬性描述,具體說明各模式的界面差異,幫助用戶根據需求進行選擇。


146-146: 新增屬性 showMonthNumber: 新增的 showMonthNumber 屬性用於決定是否展示周號。文檔說明簡潔,但建議補充默認值及應用場景說明,讓用戶可以更清楚其用途。


157-157: 新增屬性 onItemClick: 文檔中新增了 onItemClick 屬性,以處理月面板或季度面板中項目的點擊事件。建議補充關於事件參數及觸發時機的詳細說明,以便更好地指導開發者。


200-200: 新增 CSS 變量 --nutui-calendar-panel-item-width: 添加的 CSS 變量用於控制月面板和季度面板每個元素的寬度(默認為 24.85%)。建議在文檔中進一步說明其單位和調整方法,方便用戶根據需求進行自定義樣式設定。

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23156e9 and a98c830.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • src/packages/calendar/doc.en-US.md (5 hunks)
  • src/packages/calendar/doc.md (6 hunks)
  • src/packages/calendar/doc.taro.md (6 hunks)
  • src/packages/calendar/doc.zh-TW.md (6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test

@xiaoyatong xiaoyatong changed the title feat(Calendar): 合并2.x功能,支持月面板、季面板,支持展示周号,鸿蒙适配 feat(calendar): 合并2.x功能,支持月面板、季面板,支持展示周号,鸿蒙适配 Apr 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.x Target branch 3.x action:review This PR needs more reviews (less than 2 approvals) size/XXL
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants