Skip to content
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

feat(date-range): [date-panel,date-range,date-picker] DatePicker support using only date range panel #2833

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

discreted66
Copy link
Collaborator

@discreted66 discreted66 commented Jan 21, 2025

PR

支持直接使用时间区间面板。

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our Commit Message Guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Summary by CodeRabbit

Release Notes: Date Range Picker Enhancement

  • New Features

    • Added a new date range picker component with advanced configuration options.
    • Introduced support for date range selection with customizable formatting.
    • Added shortcut options for quick date range selection.
    • Implemented unlinking functionality for independent date range panels.
  • Improvements

    • Enhanced date picker with new properties like readonly, unlink-panels, and custom formatting.
    • Improved panel interaction and date selection flexibility.
    • Added more granular control over date range display and behavior.
    • Enhanced handling of state and properties for better integration.
  • Bug Fixes

    • Resolved issues with date range selection and panel rendering.
    • Improved viewport handling for time panel positioning.

Copy link

coderabbitai bot commented Jan 21, 2025

Warning

Rate limit exceeded

@discreted66 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 14 minutes and 53 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 0c82d78 and 6c94197.

📒 Files selected for processing (37)
  • examples/sites/demos/apis/date-panel.js (1 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-week.spec.ts (2 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-weeks-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-weeks.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/event-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/event.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/event.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/webdoc/date-panel.js (1 hunks)
  • examples/sites/demos/pc/app/date-picker/webdoc/date-picker.js (1 hunks)
  • packages/renderless/src/date-range/index.ts (7 hunks)
  • packages/renderless/src/date-range/vue.ts (7 hunks)
  • packages/renderless/src/date-table/index.ts (1 hunks)
  • packages/renderless/src/time/index.ts (1 hunks)
  • packages/vue/src/date-range/__tests__/date-range.test.tsx (1 hunks)
  • packages/vue/src/date-range/src/index.ts (1 hunks)
  • packages/vue/src/date-range/src/mobile-first.vue (1 hunks)
  • packages/vue/src/date-range/src/pc.vue (8 hunks)
  • packages/vue/src/date-table/src/index.ts (1 hunks)
  • packages/vue/src/date-table/src/pc.vue (1 hunks)

Walkthrough

This pull request introduces a comprehensive enhancement to the date panel functionality by adding a new date-range component across multiple files. The changes span various aspects of the date selection process, including adding new properties like modelValue, type, unlink-panels, and readonly. The implementation introduces more flexible date range selection, improved formatting options, and enhanced component configurability across different demo files and core component implementations.

Changes

File Path Change Summary
examples/sites/demos/apis/date-panel.js Introduced new date-range component with enhanced properties and events.
examples/sites/demos/pc/app/date-panel/* Added date range functionality to multiple demo files, including new value1 variables and TinyDateRange component.
packages/renderless/src/date-range/index.ts Updated date range handling functions, added watchModelValue.
packages/vue/src/date-range/src/index.ts Added new props like type, modelValue, format, readonly.
packages/vue/src/date-range/src/pc.vue Modified template and script to support new date range features.

Sequence Diagram

sequenceDiagram
    participant User
    participant DateRangeComponent
    participant DateRangeAPI

    User->>DateRangeComponent: Select Date Range
    DateRangeComponent->>DateRangeAPI: handleRangePick()
    DateRangeAPI-->>DateRangeComponent: Update Model Value
    DateRangeComponent->>User: Display Selected Range
Loading

Possibly related PRs

Suggested Reviewers

  • zzcr
  • kagol

Poem

🐰 Dates dancing in a range so bright,
Panels linked with coding might,
From single pick to dual delight,
Our date component takes its flight!
Hop, hop, hooray for code so tight! 🗓️


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @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.

@github-actions github-actions bot added the enhancement New feature or request (功能增强) label Jan 21, 2025
Copy link

Walkthrough

此PR为DatePicker组件引入了仅使用日期范围面板的支持,添加了新的组件属性和事件处理逻辑,并更新了相关的测试和示例。

Changes

文件 概要
examples/sites/demos/apis/date-panel.js 移除旧的接口定义,添加新的组件属性和事件定义。
examples/sites/demos/pc/app/date-panel/* 更新了多个示例文件,展示新的日期范围选择功能。
packages/renderless/src/date-range/index.ts 添加了对只读属性的处理逻辑,更新了快捷选项和范围选择的处理函数。
packages/renderless/src/date-range/vue.ts 引入了新的属性和观察者,调整了初始化和API设置逻辑。
packages/renderless/src/date-table/index.ts 添加了对只读属性的处理。
packages/renderless/src/time/index.ts 修改了时间面板的位置调整逻辑。
packages/vue/src/date-range/tests/date-range.test.tsx 添加了新的测试用例以验证日期范围选择功能。
packages/vue/src/date-range/src/index.ts 添加了新的组件属性定义。
packages/vue/src/date-range/src/pc.vue 更新了模板和属性定义,支持新的日期范围选择功能。
packages/vue/src/date-table/src/index.ts 添加了只读属性定义。
packages/vue/src/date-table/src/pc.vue 更新了组件属性列表,支持只读属性。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


Walkthrough

This PR introduces support for date range-only panels to the DatePicker component, adds new component properties and event handling logic, and updates related tests and examples.

Changes

Documentation Summary
examples/sites/demos/apis/date-panel.js Remove old interface definitions and add new component properties and event definitions.
examples/sites/demos/pc/app/date-panel/* Updated several example files to demonstrate the new date range selection functionality.
packages/renderless/src/date-range/index.ts Added processing logic for read-only attributes, updated shortcut options and range selection processing functions.
packages/renderless/src/date-range/vue.ts Introduced new properties and observers, adjusted initialization and API setting logic.
packages/renderless/src/date-table/index.ts Added handling of read-only attributes.
packages/renderless/src/time/index.ts Modified the position adjustment logic of the time panel.
packages/vue/src/date-range/tests/date-range.test.tsx Added new test case to verify date range selection functionality.
packages/vue/src/date-range/src/index.ts New component property definitions added.
packages/vue/src/date-range/src/pc.vue Updated templates and attribute definitions to support the new date range selection function.
packages/vue/src/date-table/src/index.ts Added read-only property definition.
packages/vue/src/date-table/src/pc.vue Updated component property list to support read-only properties.

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: 17

🔭 Outside diff range comments (1)
examples/sites/demos/pc/app/date-panel/event-composition-api.vue (1)

Line range hint 1-35: Consider reducing code duplication with event.vue.

This file is nearly identical to event.vue. Consider extracting common logic into a shared composable function.

Example implementation:

// useDatePanelEvents.ts
import { ref } from 'vue'
import { TinyModal } from '@opentiny/vue'

export function useDatePanelEvents() {
  const value = ref('2025-01-15')
  const value1 = ref(['2025-01-15', '2025-02-15'])

  const handleSelectChange = (value) => {
    TinyModal.message({
      message: `Date selected: ${value}`,
      status: 'info'
    })
  }

  const handleSelectChange1 = (value) => {
    try {
      const [startDate, endDate] = value
      TinyModal.message({
        message: `Date range selected: ${startDate} to ${endDate}`,
        status: 'info'
      })
    } catch (error) {
      TinyModal.message({
        message: 'Invalid date range selected',
        status: 'error'
      })
    }
  }

  return {
    value,
    value1,
    handleSelectChange,
    handleSelectChange1
  }
}

Then both components can use this shared logic:

 <script setup>
-import { ref } from 'vue'
-import { TinyDatePanel, TinyDateRange, TinyModal } from '@opentiny/vue'
+import { TinyDatePanel, TinyDateRange } from '@opentiny/vue'
+import { useDatePanelEvents } from './useDatePanelEvents'

-const value = ref('2025-01-15')
-const value1 = ref(['2025-01-15', '2025-02-15'])
-
-const handleSelectChange = (value) => {
-  TinyModal.message({ message: '触发 面板选中 事件,组件绑定值为:' + value, status: 'info' })
-}
-
-const handleSelectChange1 = (value) => {
-  TinyModal.message({ message: '触发 区间面板选中 事件,组件绑定值为:' + value, status: 'info' })
-}
+const { value, value1, handleSelectChange, handleSelectChange1 } = useDatePanelEvents()
 </script>
🧹 Nitpick comments (36)
examples/sites/demos/pc/app/date-panel/basic-usage-composition-api.vue (3)

5-6: Consider adding aria-label for accessibility

The new value display and date range picker should have appropriate ARIA labels for better accessibility.

-    <div class="value1">{{ value1 }}</div>
-    <tiny-date-range type="daterange" v-model="value1"></tiny-date-range>
+    <div class="value1" aria-label="Selected date range">{{ value1 }}</div>
+    <tiny-date-range type="daterange" v-model="value1" aria-label="Date range picker"></tiny-date-range>

14-15: Consider using dynamic default dates

The hardcoded future dates (2025) might not be the best default values. Consider using dynamic dates relative to the current date.

-const value = ref('2025-01-15')
-const value1 = ref(['2025-01-15', '2025-02-15'])
+const today = new Date()
+const nextMonth = new Date(today)
+nextMonth.setMonth(today.getMonth() + 1)
+const value = ref(today.toISOString().split('T')[0])
+const value1 = ref([
+  today.toISOString().split('T')[0],
+  nextMonth.toISOString().split('T')[0]
+])

25-27: Consider using CSS variables for consistent widths

The hardcoded width could be replaced with a CSS variable for better maintainability across different date picker instances.

-  tiny-date-range-picker {
-    width: 668px;
-  }
+  tiny-date-range-picker {
+    width: var(--tiny-date-range-picker-width, 668px);
+  }
examples/sites/demos/pc/app/date-panel/readonly.vue (1)

3-6: Consider implementing a consistent demo structure

The demo files show significant duplication. Consider implementing:

  1. A shared demo component structure
  2. Consistent naming conventions for CSS classes
  3. Documentation of common patterns

Example structure:

demos/
  components/
    BaseDateDemo.vue       # Shared demo component
    ReadonlyDateDemo.vue   # Specific demo extending base
  composables/
    useDatePanel.ts        # Shared date logic
  styles/
    _variables.less        # Shared CSS variables
    _mixins.less          # Shared styles

Also applies to: 14-15, 21-26

examples/sites/demos/pc/app/date-panel/format-composition-api.vue (2)

3-6: Consider adding aria-labels for accessibility.

The value display divs and date components would benefit from aria-labels to improve accessibility.

-    <div class="value">{{ value }}</div>
-    <tiny-date-panel v-model="value" format="yyyy/MM/dd"></tiny-date-panel>
-    <div class="value1">{{ value1 }}</div>
-    <tiny-date-range type="daterange" v-model="value1" format="yyyy/MM/dd"></tiny-date-range>
+    <div class="value" aria-label="Selected date">{{ value }}</div>
+    <tiny-date-panel v-model="value" format="yyyy/MM/dd" aria-label="Date selector"></tiny-date-panel>
+    <div class="value1" aria-label="Selected date range">{{ value1 }}</div>
+    <tiny-date-range type="daterange" v-model="value1" format="yyyy/MM/dd" aria-label="Date range selector"></tiny-date-range>

21-26: Consider responsive design for the date range picker.

The fixed width of 668px for the date range picker may not be optimal for all screen sizes.

   & > * {
     margin-top: 12px;
   }
   .tiny-date-range-picker {
-    width: 668px;
+    max-width: 668px;
+    width: 100%;
   }
examples/sites/demos/pc/app/date-panel/disabled-date-composition-api.vue (1)

16-18: Consider documenting the disabled date logic.

The disabledDate function would benefit from a JSDoc comment explaining the restriction logic.

+/**
+ * Disables dates before the year 2025
+ * @param {Date} val - The date to check
+ * @returns {boolean} - True if the date should be disabled
+ */
 const disabledDate = (val) => {
   return val.getFullYear() < 2025
 }
examples/sites/demos/pc/app/date-panel/disabled-date.vue (2)

5-6: Consider adding aria-label for accessibility.

The new date range value display and picker should have appropriate aria-labels for screen readers.

-    <div class="value1">{{ value1 }}</div>
-    <tiny-date-range type="daterange" v-model="value1" :disabledDate="disabledDate"></tiny-date-range>
+    <div class="value1" aria-label="Selected date range">{{ value1 }}</div>
+    <tiny-date-range type="daterange" v-model="value1" :disabledDate="disabledDate" aria-label="Date range picker"></tiny-date-range>

27-29: Consider responsive design for date range picker width.

The fixed width of 668px might cause issues on smaller screens. Consider using relative units or media queries.

   .tiny-date-range-picker {
-    width: 668px;
+    width: 100%;
+    max-width: 668px;
   }
examples/sites/demos/pc/app/date-panel/event.spec.ts (1)

7-13: Add test description comments for better clarity.

The test steps could be better documented with descriptive comments.

-  // datePanel
+  // Test date panel: Year > Month > Day selection flow
   await page.getByRole('button', { name: '2025 年' }).click()
   await expect(page.getByRole('cell', { name: '2025' })).toBeVisible()
   await page.getByText('2024').click()
   await page.getByText('七月').click()
   await page.locator('#event').getByText('17').first().click()
   await expect(page.getByText('触发 面板选中 事件,组件绑定值为:2024-07-')).toBeVisible()
examples/sites/demos/pc/app/date-panel/unlink-panels-composition-api.vue (2)

3-3: Consider i18n for text content.

The hardcoded Chinese text should be moved to localization files for better internationalization support.

-    <div class="value">默认启用面板联动:{{ value }}</div>
+    <div class="value">{{ t('datePanel.defaultLinkage') }}: {{ value }}</div>

-    <div class="value1">关闭面板联动:{{ value1 }}</div>
+    <div class="value1">{{ t('datePanel.unlinkPanels') }}: {{ value1 }}</div>

Also applies to: 10-10


21-22: Consider extracting initial date values.

The duplicate date range values could be extracted to a constant for better maintainability.

+const DEFAULT_DATE_RANGE = ['2025-01-15', '2025-02-15']
-const value = ref(['2025-01-15', '2025-02-15'])
-const value1 = ref(['2025-01-15', '2025-02-15'])
+const value = ref([...DEFAULT_DATE_RANGE])
+const value1 = ref([...DEFAULT_DATE_RANGE])
examples/sites/demos/pc/app/date-panel/unlink-panels.vue (3)

3-3: Consider internationalizing the hardcoded Chinese text.

The text "默认启用面板联动" and "关闭面板联动" should be internationalized for better maintainability and global accessibility.

-    <div class="value">默认启用面板联动:{{ value }}</div>
+    <div class="value">{{ t('datePanel.defaultLinked') }}: {{ value }}</div>
-    <div class="value1">关闭面板联动:{{ value1 }}</div>
+    <div class="value1">{{ t('datePanel.unlinkPanels') }}: {{ value1 }}</div>

Also applies to: 10-10


6-6: Consider adding aria-labels for accessibility.

The date range pickers should have descriptive aria-labels to improve accessibility.

-      <tiny-date-range v-model="value" type="daterange"></tiny-date-range>
+      <tiny-date-range v-model="value" type="daterange" aria-label="Linked date range picker"></tiny-date-range>
-      <tiny-date-range v-model="value1" type="daterange" unlink-panels></tiny-date-range>
+      <tiny-date-range v-model="value1" type="daterange" unlink-panels aria-label="Unlinked date range picker"></tiny-date-range>

Also applies to: 12-12


21-22: Consider using more descriptive variable names.

The variables value and value1 could be more descriptive to better indicate their purpose.

-const value = ref(['2025-01-15', '2025-02-15'])
-const value1 = ref(['2025-01-15', '2025-02-15'])
+const linkedDateRange = ref(['2025-01-15', '2025-02-15'])
+const unlinkedDateRange = ref(['2025-01-15', '2025-02-15'])
examples/sites/demos/pc/app/date-panel/event.vue (2)

21-23: Improve event handler implementation.

The event handler could be improved with better message formatting and error handling.

 const handleSelectChange1 = (value) => {
-  TinyModal.message({ message: '触发 区间面板选中 事件,组件绑定值为:' + value, status: 'info' })
+  try {
+    const [startDate, endDate] = value
+    TinyModal.message({
+      message: `Date range selected: ${startDate} to ${endDate}`,
+      status: 'info'
+    })
+  } catch (error) {
+    TinyModal.message({
+      message: 'Invalid date range selected',
+      status: 'error'
+    })
+  }
 }

32-34: Consider using CSS variables for consistent styling.

The hardcoded width value could be replaced with a CSS variable for better maintainability.

   .tiny-date-range-picker {
-    width: 668px;
+    width: var(--tiny-date-range-picker-width, 668px);
   }
examples/sites/demos/pc/app/date-panel/custom-weeks-composition-api.vue (3)

11-17: Consider extracting shared props into a common object.

The props :format-weeks, :show-week-number, and :first-day-of-week are duplicated between TinyDatePanel and TinyDateRange components.

+ const sharedProps = {
+   formatWeeks,
+   showWeekNumber: true,
+   firstDayOfWeek: 1
+ }

  <tiny-date-panel
    v-model="value"
-   :format-weeks="formatWeeks"
-   :show-week-number="true"
-   :first-day-of-week="1"
+   v-bind="sharedProps"
  ></tiny-date-panel>

  <tiny-date-range
    type="daterange"
    v-model="value1"
-   :format-weeks="formatWeeks"
-   :show-week-number="true"
-   :first-day-of-week="1"
+   v-bind="sharedProps"
  ></tiny-date-range>

25-26: Consider making the initial dates configurable.

The initial dates are hardcoded. Consider making them configurable through props or environment variables for better flexibility in different environments (e.g., demo, testing, production).


41-43: Avoid fixed width for date range picker.

Setting a fixed width might cause layout issues on different screen sizes. Consider using responsive units or letting the component adapt to its container.

- .tiny-date-range-picker {
-   width: 668px;
- }
+ .tiny-date-range-picker {
+   width: 100%;
+   max-width: 668px;
+ }
packages/vue/src/date-table/src/index.ts (1)

35-38: Add JSDoc documentation for the readonly prop.

The purpose and behavior of the readonly prop should be documented for better maintainability.

+  /**
+   * When true, prevents user interaction with the date table.
+   * Users cannot select or hover over dates in readonly mode.
+   * @default false
+   */
   readonly: {
     type: Boolean,
     default: () => false
   },
examples/sites/demos/pc/app/date-panel/custom-week.spec.ts (1)

19-21: Use more robust selectors.

Using first() and text matching for date selection could be fragile. Consider using data-testid attributes for more reliable selection.

- await page.getByText('23', { exact: true }).first().click()
+ await page.getByTestId('date-cell-23').click()
examples/sites/demos/pc/app/date-panel/basic-usage.spec.ts (2)

17-17: Improve test reliability with more specific selectors.

The test now uses .first() to ensure consistent element selection, which is good. However, consider using more specific selectors or data-testid attributes instead of relying on text content for better test maintainability.

-  await page.getByText('16').first().click()
+  await page.getByTestId('date-cell-16').click()

Also applies to: 20-21


23-27: Add assertions for intermediate states in date range test.

The date range test verifies the final state but doesn't validate the intermediate UI states. Consider adding assertions to verify the panel state after the first date selection.

   await page.locator('.tiny-date-range-picker__header > button:nth-child(2)').first().click()
   await page.locator('div').filter({ hasText: /^19$/ }).nth(1).click()
+  await expect(page.locator('.in-range')).toBeVisible()
   await page.getByRole('cell', { name: '28' }).nth(3).click()
   await expect(page.getByText('[ "2024-12-19", "2025-01-28" ]')).toBeVisible()
packages/vue/src/date-range/src/index.ts (1)

34-64: Add prop validation for critical properties.

While the prop types are correctly defined, consider adding validation for:

  1. type to restrict values to supported date range types
  2. format to ensure valid date format strings
  3. shortcuts to validate array structure
   type: {
     type: String,
-    default: () => 'daterange'
+    default: 'daterange',
+    validator: (value) => ['daterange', 'datetimerange', 'monthrange'].includes(value)
   },
   format: {
     type: String,
-    default: ''
+    default: '',
+    validator: (value) => !value || /^(yyyy|MM|dd|HH|mm|ss|W|w|A|a|SSS|X|x)([^A-Za-z]|$)/.test(value)
   },
examples/sites/demos/pc/app/date-panel/disabled-date.spec.ts (1)

7-14: Improve test organization with describe blocks.

Consider organizing the tests using describe blocks to separate date panel and date range tests for better readability.

+describe('DatePanel', () => {
+  test('single date selection with disabled dates', async ({ page }) => {
     // datePanel tests
+  })
+})

+describe('DateRange', () => {
+  test('date range selection with disabled dates', async ({ page }) => {
     // dateRange tests
+  })
+})
examples/sites/demos/pc/app/date-panel/shortcuts-composition-api.vue (3)

79-81: Consider using responsive width styling.

Instead of a fixed width, consider using relative units or max-width to ensure better responsiveness across different screen sizes.

 .tiny-date-range-picker {
-  width: 668px;
+  max-width: 668px;
+  width: 100%;
 }

45-45: Remove debug console.info statement.

Debug logging should be removed before merging to production.

-      console.info(picker)

41-70: Refactor date calculations using utility functions.

The date calculations are repeated across shortcuts. Consider extracting them into a utility function for better maintainability.

+const getDateRange = (days) => {
+  const end = new Date()
+  const start = new Date()
+  start.setTime(start.getTime() - 3600 * 1000 * 24 * days)
+  return [start, end]
+}

 const shortcuts1 = [
   {
     text: '最近一周',
     onClick(picker) {
-      const end = new Date()
-      const start = new Date()
-      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
+      const [start, end] = getDateRange(7)
       picker.$emit('pick', [start, end])
     }
   },
   {
     text: '最近一个月',
     onClick(picker) {
-      const end = new Date()
-      const start = new Date()
-      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
+      const [start, end] = getDateRange(30)
       picker.$emit('pick', [start, end])
     }
   },
   {
     text: '最近三个月',
     onClick(picker) {
-      const end = new Date()
-      const start = new Date()
-      start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
+      const [start, end] = getDateRange(90)
       picker.$emit('pick', [start, end])
     }
   }
 ]
packages/renderless/src/date-range/vue.ts (1)

Line range hint 155-199: Consider adding error handling for invalid date values.

The API initialization includes new props but lacks validation for invalid date inputs.

Consider adding date validation:

 watchModelValue: watchModelValue({ state, api }) =>
+  validateDateRange: (value) => {
+    if (!Array.isArray(value) || value.length !== 2) {
+      return false
+    }
+    return value.every(date => date instanceof Date && !isNaN(date))
+  }
packages/renderless/src/date-range/index.ts (1)

435-443: Consider adding error handling for invalid shortcut configurations.

The shortcut handling assumes valid date values but lacks error handling.

Add validation:

 if (props.shortcuts?.length) {
+  if (!isDate(start) || !isDate(end)) {
+    console.warn('Invalid date values in shortcut')
+    return
+  }
   state.value = [start, end]
examples/sites/demos/pc/app/date-panel/shortcuts.vue (5)

5-6: Consider improving the value display format for better readability.

The raw array display of value1 might not be user-friendly. Consider formatting the date range for better presentation.

-    <div class="value1">{{ value1 }}</div>
+    <div class="value1">{{ value1[0] }} to {{ value1[1] }}</div>

14-15: Consider using dynamic default values instead of hardcoded future dates.

The hardcoded dates set to 2025 might not be relevant when the component is actually used. Consider using dynamic dates relative to the current date.

-const value = ref('2025-01-15')
-const value1 = ref(['2025-01-15', '2025-02-15'])
+const today = new Date().toISOString().split('T')[0]
+const nextMonth = new Date()
+nextMonth.setMonth(nextMonth.getMonth() + 1)
+const nextMonthStr = nextMonth.toISOString().split('T')[0]
+const value = ref(today)
+const value1 = ref([today, nextMonthStr])

45-45: Remove debug console.log statement.

Debug logging should not be included in demo code.

-      console.info(picker)

41-70: Consider extracting time calculations into helper functions.

The shortcuts configuration contains repeated time calculation logic. Consider extracting these calculations into reusable helper functions.

+const calculateDateOffset = (days) => {
+  const end = new Date()
+  const start = new Date()
+  start.setTime(start.getTime() - 3600 * 1000 * 24 * days)
+  return [start, end]
+}

 const shortcuts1 = [
   {
     text: '最近一周',
     onClick(picker) {
-      const end = new Date()
-      const start = new Date()
-      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
+      const [start, end] = calculateDateOffset(7)
       picker.$emit('pick', [start, end])
     }
   },
   // Apply similar changes to other shortcuts
 ]

79-81: Consider using CSS variables for width values.

Hardcoded width values make it harder to maintain consistent sizing across components.

+:root {
+  --date-range-picker-width: 668px;
+}

 .tiny-date-range-picker {
-  width: 668px;
+  width: var(--date-range-picker-width);
 }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 917e120 and 7d91ce5.

📒 Files selected for processing (35)
  • examples/sites/demos/apis/date-panel.js (1 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-week.spec.ts (2 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-weeks-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-weeks.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/event-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/event.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/event.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/webdoc/date-panel.js (1 hunks)
  • packages/renderless/src/date-range/index.ts (7 hunks)
  • packages/renderless/src/date-range/vue.ts (7 hunks)
  • packages/renderless/src/date-table/index.ts (1 hunks)
  • packages/renderless/src/time/index.ts (1 hunks)
  • packages/vue/src/date-range/__tests__/date-range.test.tsx (1 hunks)
  • packages/vue/src/date-range/src/index.ts (1 hunks)
  • packages/vue/src/date-range/src/pc.vue (8 hunks)
  • packages/vue/src/date-table/src/index.ts (1 hunks)
  • packages/vue/src/date-table/src/pc.vue (1 hunks)
🧰 Additional context used
🪛 eslint
examples/sites/demos/pc/app/date-panel/basic-usage.vue

[error] 14-15: Delete

(prettier/prettier)

🔇 Additional comments (19)
examples/sites/demos/apis/date-panel.js (1)

298-307: Verify the select-change event parameter type

The select-change event's type has changed from (value: string) => void to (value: Date) => void. Please verify if this change is intentional and ensure it doesn't introduce breaking changes.

packages/vue/src/date-range/__tests__/date-range.test.tsx (1)

1-17: Test implementation is appropriate

The test correctly mounts the DateRange component with specified value and format props and checks for the existence of the picker panel.

examples/sites/demos/pc/app/date-panel/format.spec.ts (1)

6-13: Tests validate date formatting correctly

The test scenarios appropriately interact with the date panel and date range picker, selecting dates and asserting the formatted output.

examples/sites/demos/pc/app/date-panel/readonly-composition-api.vue (1)

4-4: Verify readonly behavior across different scenarios

The readonly prop is applied, but we should verify its behavior in different scenarios:

  1. Keyboard interactions
  2. Screen reader accessibility
  3. Mobile touch events

Also applies to: 6-6

✅ Verification successful

Readonly behavior is properly implemented

The readonly prop is consistently implemented across the component library, following standard Vue patterns for read-only form controls. The implementation:

  • Properly disables user interaction while maintaining visibility
  • Preserves accessibility with correct ARIA attributes
  • Integrates with the component's disabled and unselectable states
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for readonly prop tests and implementations
echo "Searching for readonly tests..."
rg -l "readonly.*test" --type ts

echo "Searching for readonly implementations..."
ast-grep --pattern 'readonly = $_'

Length of output: 237


Script:

#!/bin/bash
# Search for readonly prop definitions and usages
echo "Searching for readonly prop definitions..."
ast-grep --pattern 'props: {
  $$$
  readonly: $_
  $$$
}'

echo "Searching for readonly in template files..."
rg "readonly" --type vue -A 2 -B 2

echo "Searching for date panel test files..."
fd "date.*test" --type f

Length of output: 605


Script:

#!/bin/bash
# Check test file content for readonly testing
echo "Checking date panel test content..."
cat "packages/vue/src/date-panel/__tests__/date-panel.test.tsx"

echo "Searching for readonly in .vue files..."
rg "readonly" -g "*.vue" -A 2 -B 2

echo "Checking date panel component implementation..."
cat "packages/vue/src/date-panel/src/date-panel.vue" 2>/dev/null || cat "packages/vue/src/date-panel/date-panel.vue" 2>/dev/null

Length of output: 47227

examples/sites/demos/pc/app/date-panel/format-composition-api.vue (1)

14-15: LGTM! Initial values are well-formatted.

The initial values follow the correct format (yyyy/MM/dd) and provide good demo data.

examples/sites/demos/pc/app/date-panel/format.vue (1)

1-26: Implementation matches format-composition-api.vue.

The same suggestions regarding accessibility and responsive design from format-composition-api.vue apply here.

examples/sites/demos/pc/app/date-panel/disabled-date-composition-api.vue (1)

4-6: Consider edge cases in disabled date handling for ranges.

The same disabledDate function is used for both single date and range selection. For ranges, you might want to handle edge cases differently.

examples/sites/demos/pc/app/date-panel/disabled-date.vue (1)

14-15: Verify date initialization consistency.

Both initial dates are set to '2025-01-15', which is good for consistency. However, ensure that the end date '2025-02-15' in value1 isn't affected by the disabledDate function.

✅ Verification successful

Initial dates are correctly set and unaffected by disabled date logic

The disabledDate function only restricts dates before 2025, and both initial dates ('2025-01-15' and '2025-02-15') are within 2025, so they are valid and won't be affected by the disabled date logic.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the disabled date function affects the initial end date
ast-grep --pattern 'const disabledDate = ($params) => {
  $body
}'

Length of output: 68


Script:

#!/bin/bash
# Get the full content of the file to understand the component structure
cat examples/sites/demos/pc/app/date-panel/disabled-date.vue

# Search for any disabled date related patterns in the file
rg -l "disabled.*date" examples/sites/demos/pc/app/date-panel/disabled-date.vue

Length of output: 970

examples/sites/demos/pc/app/date-panel/custom-weeks.vue (1)

Line range hint 1-43: Apply the same improvements as custom-weeks-composition-api.vue.

This file has the same opportunities for improvement as its composition API counterpart:

  1. Extract shared props into a common object
  2. Make initial dates configurable
  3. Use responsive width for date range picker

See the detailed suggestions in the review of custom-weeks-composition-api.vue.

packages/vue/src/date-table/src/index.ts (1)

35-38: Verify readonly implementation in renderless logic.

The readonly prop is added but we need to verify its implementation in the renderless logic.

✅ Verification successful

Readonly prop is properly implemented in renderless logic

The readonly prop is correctly implemented in the handleClick event handler, preventing user interactions when readonly is true through an early return pattern.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for readonly prop usage in renderless logic
rg -A 5 "readonly" "packages/renderless/src/date-table"

Length of output: 432


Script:

#!/bin/bash
# Get more context around the readonly usage
rg -B 5 -A 10 "if \(props\.readonly\)" "packages/renderless/src/date-table/index.ts"

Length of output: 428

examples/sites/demos/pc/app/date-panel/shortcuts-composition-api.vue (1)

14-15: Review hardcoded future dates.

The initial dates are set to 2025, which might not be ideal for demo purposes. Consider using dynamic dates relative to the current date.

-const value = ref('2025-01-15')
-const value1 = ref(['2025-01-15', '2025-02-15'])
+const today = new Date()
+const nextMonth = new Date(today)
+nextMonth.setMonth(today.getMonth() + 1)
+const value = ref(today.toISOString().split('T')[0])
+const value1 = ref([
+  today.toISOString().split('T')[0],
+  nextMonth.toISOString().split('T')[0]
+])
packages/renderless/src/date-range/vue.ts (3)

53-54: LGTM: API exports properly updated.

The new watchModelValue function is correctly added to the imports and exports.

Also applies to: 81-82


143-144: LGTM: Watch setup for model value.

The watch for modelValue is correctly set up with immediate execution.


Line range hint 85-111: Verify prop initialization in state.

The state initialization now properly handles props, but there are potential issues to consider:

  1. Direct prop assignments without defensive checks
  2. Potential type mismatches for date values

Run this script to check prop types and usage:

✅ Verification successful

Prop initialization is properly implemented with defensive checks

The state initialization properly handles all props with appropriate fallback values and type handling:

  • All prop assignments include fallback values using the || operator
  • Date values are properly validated and parsed
  • Type-specific handling is implemented for different date picker modes
  • Props are watched for changes with proper validation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check prop types and their usage
rg -A 5 "props: \{" packages/vue/src/date-range/

Length of output: 399


Script:

#!/bin/bash
# Search for prop types and interfaces
ast-grep --pattern 'interface Props {
  $$$
}'

# Find prop definitions and validations
rg -g '*.{ts,tsx,vue}' -A 10 'export const \$props = {' packages/

# Look for type imports/definitions related to props
rg -g '*.{ts,tsx}' 'type.*Props'

Length of output: 31331


Script:

#!/bin/bash
# Find date-range prop definitions and types
rg -g '*.{ts,tsx}' -A 10 'date-range.*props' packages/

# Look for prop definitions in the date-range directory
fd -e ts -e tsx . packages/renderless/src/date-range/ -x cat {}

Length of output: 24043

packages/vue/src/date-range/src/pc.vue (2)

Line range hint 27-43: LGTM: Improved shortcuts rendering logic.

The change from v-show to v-if with optional chaining is more efficient and safer.


262-278: LGTM: Props and emits properly declared.

The component's interface is well-defined with appropriate props and events.

packages/renderless/src/date-table/index.ts (1)

451-453: LGTM: Proper readonly handling in click handler.

The early return when readonly is set prevents any interaction, maintaining the readonly contract.

packages/renderless/src/date-range/index.ts (2)

218-221: LGTM: Proper readonly check in range handler.

The handler correctly prevents range changes when in readonly mode.


374-378: LGTM: Consistent readonly handling in range picker.

The range pick handler properly respects the readonly state.

examples/sites/demos/apis/date-panel.js Outdated Show resolved Hide resolved
examples/sites/demos/apis/date-panel.js Outdated Show resolved Hide resolved
examples/sites/demos/apis/date-panel.js Outdated Show resolved Hide resolved
examples/sites/demos/apis/date-panel.js Outdated Show resolved Hide resolved
packages/vue/src/date-table/src/pc.vue Show resolved Hide resolved
packages/renderless/src/time/index.ts Show resolved Hide resolved
packages/vue/src/date-range/src/pc.vue Show resolved Hide resolved
packages/renderless/src/date-range/index.ts Show resolved Hide resolved
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

🔭 Outside diff range comments (3)
examples/sites/demos/pc/app/date-panel/webdoc/date-panel.js (3)

Line range hint 278-279: Fix incorrect English description for show-week-number prop.

The English description doesn't match the Chinese description and seems to be copied from a different property.

desc: {
  'zh-CN': '是否展示周次序号',
- 'en-US': 'Class name added to the DatePicker drop-down list box'
+ 'en-US': 'Whether to display week numbers'
},

Line range hint 314-315: Fix incorrect English description for clear method.

The English description doesn't match the Chinese description and seems to be describing a focus behavior instead of clearing selected time.

desc: {
  'zh-CN': '清除已选中的时间',
- 'en-US': 'Enable input to focus.'
+ 'en-US': 'Clear the selected time.'
},

Line range hint 325-465: Add missing English descriptions for date format options.

All format options are missing English descriptions which makes it difficult for English-speaking developers to understand their purpose.

Add English descriptions for all format options. For example:

desc: {
  'zh-CN': 'am/pm',
- 'en-US': ''
+ 'en-US': 'am/pm marker'
},

This should be applied to all format options from line 325 to 465.

♻️ Duplicate comments (8)
examples/sites/demos/pc/app/date-panel/readonly.spec.ts (2)

8-13: 🛠️ Refactor suggestion

Enhance test robustness with data-testid attributes.

Using text content and nth selectors for locators can be fragile. Consider adding data-testid attributes for more reliable selection.


15-18: ⚠️ Potential issue

Add assertions for readonly state.

The test name suggests testing readonly behavior, but it's not actually verifying that the components are readonly.

examples/sites/demos/pc/app/date-panel/custom-week.spec.ts (1)

24-29: 🛠️ Refactor suggestion

Improve test reliability with data-testid attributes.

The current selectors are brittle and hard to maintain. Consider using data-testid attributes for more reliable selection.

packages/vue/src/date-range/src/pc.vue (1)

66-66: 🛠️ Refactor suggestion

Standardize readonly condition handling across inputs.

The readonly conditions are implemented inconsistently across different inputs. Some use direct binding while others combine conditions.

Standardize the readonly logic:

-@focus="!readonly && (state.minTimePickerVisible = true)"
+@focus="state.minDate && !readonly && (state.minTimePickerVisible = true)"

-:readonly="!timeEditable || readonly"
+:readonly="readonly || !timeEditable"

-:readonly="!state.minDate || readonly"
+:readonly="readonly || !state.minDate"

-:readonly="!state.minDate || !timeEditable || readonly"
+:readonly="readonly || !timeEditable || !state.minDate"

-@focus="state.minDate && !readonly && (state.maxTimePickerVisible = true)"
+@focus="!readonly && state.minDate && (state.maxTimePickerVisible = true)"

Also applies to: 69-69, 91-91, 103-104

examples/sites/demos/apis/date-panel.js (4)

216-226: ⚠️ Potential issue

Fix incorrect type and description for disabled-date prop.

The type should be function, not boolean, and the English description is incorrect.

{
  name: 'disabled-date',
  typeAnchorName: 'disabledDate',
- type: 'boolean',
+ type: 'function',
  defaultValue: '',
  desc: {
    'zh-CN': '配置部分禁用',
-   'en-US': "Custom selector's rear icon"
+   'en-US': 'Configure dates to disable.'
  },
  mode: ['pc'],
  pcDemo: 'shortcuts'
},

240-249: 🛠️ Refactor suggestion

Add missing English description for name prop.

The name prop is missing its English description.

desc: {
  'zh-CN': '原生属性',
- 'en-US': ''
+ 'en-US': 'Native attribute for form submission.'
},

252-261: ⚠️ Potential issue

Fix incorrect English description for popper-class prop.

The English description appears to be copied from unlink-panels prop.

desc: {
  'zh-CN': '为 DatePicker 下拉弹框添加的 class 类名',
- 'en-US': 'Cancel the linkage between two date panels in the range selector.'
+ 'en-US': 'Class name added to the DatePicker dropdown panel.'
},

285-294: 🛠️ Refactor suggestion

Add missing English description for unlink-panels prop.

The unlink-panels prop is missing its English description.

desc: {
  'zh-CN': '在范围选择器里取消两个日期面板之间的联动',
- 'en-US': ''
+ 'en-US': 'Unlink the two date panels in the range selector.'
},
🧹 Nitpick comments (10)
examples/sites/demos/pc/app/date-panel/unlink-panels.vue (4)

3-3: Consider internationalizing the UI text.

The Chinese text should be moved to a localization system for better maintainability and internationalization support.

-    <div class="value">默认启用面板联动:{{ value }}</div>
+    <div class="value">{{ t('datePanel.defaultLinkPanels') }}: {{ value }}</div>

-    <div class="value1">关闭面板联动:{{ value1 }}</div>
+    <div class="value1">{{ t('datePanel.unlinkPanels') }}: {{ value1 }}</div>

Also applies to: 10-10


6-6: Add ARIA labels for accessibility.

The date range pickers should have appropriate ARIA labels to improve accessibility.

-      <tiny-date-range v-model="value" type="daterange"></tiny-date-range>
+      <tiny-date-range
+        v-model="value"
+        type="daterange"
+        aria-label="Linked date range picker"
+      ></tiny-date-range>

-      <tiny-date-range v-model="value1" type="daterange" unlink-panels></tiny-date-range>
+      <tiny-date-range
+        v-model="value1"
+        type="daterange"
+        unlink-panels
+        aria-label="Unlinked date range picker"
+      ></tiny-date-range>

Also applies to: 12-12


21-22: Consider using dynamic dates instead of hardcoded future dates.

The hardcoded dates set to 2025 might become outdated. Consider using dynamic dates relative to the current date.

-const value = ref(['2025-01-15', '2025-02-15'])
-const value1 = ref(['2025-01-15', '2025-02-15'])
+const today = new Date()
+const nextMonth = new Date(today)
+nextMonth.setMonth(today.getMonth() + 1)
+const formatDate = (date) => date.toISOString().split('T')[0]
+
+const value = ref([formatDate(today), formatDate(nextMonth)])
+const value1 = ref([formatDate(today), formatDate(nextMonth)])

Also, consider adding TypeScript type definitions for better type safety:

const value = ref<[string, string]>(['2025-01-15', '2025-02-15'])
const value1 = ref<[string, string]>(['2025-01-15', '2025-02-15'])

27-27: Consider using responsive units for better adaptability.

The fixed pixel widths might not provide the best experience across different screen sizes. Consider using relative units or responsive design patterns.

-.demo-date-panel-wrap {
-  width: 560px;
+.demo-date-panel-wrap {
+  width: 100%;
+  max-width: 560px;

-.tiny-date-range-picker {
-  width: 668px;
+.tiny-date-range-picker {
+  width: 100%;
+  max-width: 668px;

Also applies to: 32-32

examples/sites/demos/pc/app/date-panel/unlink-panels-composition-api.vue (1)

3-3: Consider internationalizing the Chinese text.

The hardcoded Chinese text should be moved to localization files for better maintainability and internationalization support.

Also applies to: 10-10

examples/sites/demos/pc/app/date-panel/event.vue (2)

21-23: Consider extracting message strings for internationalization.

The hardcoded Chinese messages should be moved to a localization system for better maintainability and internationalization support.

-  TinyModal.message({ message: '触发 区间面板选中 事件,组件绑定值为:' + value, status: 'info' })
+  TinyModal.message({ message: t('dateRange.eventTriggered', { value }), status: 'info' })

32-34: Consider using consistent widths for date components.

The date range picker is significantly wider (668px) than the parent container (560px), which could cause layout issues.

 .demo-date-panel-wrap {
   width: 560px;
   & > * {
     margin-top: 12px;
   }
   .tiny-date-range-picker {
-    width: 668px;
+    width: 100%;
   }
 }
examples/sites/demos/pc/app/date-panel/custom-weeks-composition-api.vue (1)

4-17: Consider extracting common props to avoid duplication.

The format-weeks, show-week-number, and first-day-of-week props are duplicated between components. Consider creating a common configuration object.

+const commonProps = {
+  formatWeeks,
+  showWeekNumber: true,
+  firstDayOfWeek: 1
+}

 <tiny-date-panel
   v-model="value"
-  :format-weeks="formatWeeks"
-  :show-week-number="true"
-  :first-day-of-week="1"
+  v-bind="commonProps"
 ></tiny-date-panel>

 <tiny-date-range
   type="daterange"
   v-model="value1"
-  :format-weeks="formatWeeks"
-  :show-week-number="true"
-  :first-day-of-week="1"
+  v-bind="commonProps"
 ></tiny-date-range>
examples/sites/demos/pc/app/date-panel/shortcuts.vue (2)

45-45: Remove debug console.info statement.

The console.info(picker) statement should be removed as it's not needed in production code.

-      console.info(picker)

79-81: Consider using responsive width for date range picker.

The width is hardcoded to 668px which might not be responsive on different screen sizes.

Consider using relative units or CSS Grid/Flexbox for better responsiveness:

-  .tiny-date-range-picker {
-    width: 668px;
-  }
+  .tiny-date-range-picker {
+    width: 100%;
+    max-width: 668px;
+  }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7d91ce5 and f5c9e60.

📒 Files selected for processing (36)
  • examples/sites/demos/apis/date-panel.js (1 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-week.spec.ts (2 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-weeks-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-weeks.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/event-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/event.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/event.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/webdoc/date-panel.js (1 hunks)
  • packages/renderless/src/date-range/index.ts (7 hunks)
  • packages/renderless/src/date-range/vue.ts (7 hunks)
  • packages/renderless/src/date-table/index.ts (1 hunks)
  • packages/renderless/src/time/index.ts (1 hunks)
  • packages/vue/src/date-range/__tests__/date-range.test.tsx (1 hunks)
  • packages/vue/src/date-range/src/index.ts (1 hunks)
  • packages/vue/src/date-range/src/mobile-first.vue (1 hunks)
  • packages/vue/src/date-range/src/pc.vue (8 hunks)
  • packages/vue/src/date-table/src/index.ts (1 hunks)
  • packages/vue/src/date-table/src/pc.vue (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (16)
  • packages/renderless/src/date-table/index.ts
  • examples/sites/demos/pc/app/date-panel/format.spec.ts
  • packages/renderless/src/time/index.ts
  • packages/vue/src/date-table/src/pc.vue
  • examples/sites/demos/pc/app/date-panel/event.spec.ts
  • examples/sites/demos/pc/app/date-panel/shortcuts.spec.ts
  • examples/sites/demos/pc/app/date-panel/unlink-panels.spec.ts
  • examples/sites/demos/pc/app/date-panel/basic-usage.spec.ts
  • packages/vue/src/date-table/src/index.ts
  • examples/sites/demos/pc/app/date-panel/readonly.vue
  • examples/sites/demos/pc/app/date-panel/basic-usage-composition-api.vue
  • packages/vue/src/date-range/tests/date-range.test.tsx
  • examples/sites/demos/pc/app/date-panel/custom-weeks.vue
  • packages/vue/src/date-range/src/index.ts
  • packages/renderless/src/date-range/vue.ts
  • packages/renderless/src/date-range/index.ts
🧰 Additional context used
🪛 eslint
examples/sites/demos/pc/app/date-panel/basic-usage.vue

[error] 14-15: Delete

(prettier/prettier)

🔇 Additional comments (18)
examples/sites/demos/pc/app/date-panel/unlink-panels.vue (1)

1-35: Overall implementation looks good!

The component is well-structured and demonstrates both linked and unlinked date range picker functionality effectively. The suggested improvements for internationalization, accessibility, dynamic dates, and responsive design are enhancements that can be addressed in future iterations.

packages/vue/src/date-range/src/mobile-first.vue (1)

11-16: Improved null safety and rendering logic

The optional chaining operator in state.shortcuts?.length adds robustness by preventing potential runtime errors when shortcuts is null/undefined, while also ensuring the div only renders when there are actual shortcuts to display.

examples/sites/demos/pc/app/date-panel/basic-usage.vue (3)

3-6: Consider extracting common code to a shared component

This file contains duplicate code patterns seen across other demo files (basic-usage-composition-api.vue, readonly-composition-api.vue, etc.). Consider creating shared components and composables to reduce duplication.

Also applies to: 15-16


25-27: Consistent width across date range pickers

The 668px width for .tiny-date-range-picker is consistently applied across demo files, which is good for maintaining visual uniformity.


15-16: Verify date initialization values

The hardcoded dates ('2025-01-15', '2025-02-15') are set in the future. Consider:

  1. Using dynamic dates relative to the current date
  2. Adding comments explaining why these specific dates were chosen
examples/sites/demos/pc/app/date-panel/readonly-composition-api.vue (1)

3-6: LGTM! Readonly implementation is correct

The readonly prop is properly applied to both date panel components.

examples/sites/demos/pc/app/date-panel/format-composition-api.vue (1)

4-4: Verify date format consistency

The format "yyyy/MM/dd" is correctly applied to both components, and the initial values match this format. However, let's verify format consistency across all date components.

Also applies to: 6-6, 14-15

✅ Verification successful

Format "yyyy/MM/dd" is consistently used

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for different date formats used across components
rg -A 1 "format=[\"'].*[\"']" examples/sites/demos/pc/app/date-panel/

Length of output: 986

examples/sites/demos/pc/app/date-panel/format.vue (1)

3-6: LGTM! Clean implementation of date range functionality.

The implementation follows Vue 3 composition API best practices with consistent date formatting.

examples/sites/demos/pc/app/date-panel/disabled-date-composition-api.vue (2)

14-15: LGTM! Consistent initial values.

The initial values are consistent with other implementations and follow the same date format.


6-6: Verify disabledDate behavior with date ranges.

The disabledDate function is reused from the single date picker. Ensure it works correctly when selecting date ranges, especially for the end date selection.

✅ Verification successful

DisabledDate implementation verified and working correctly

The disabledDate function is properly implemented and will work correctly with date ranges. The function's pure nature ensures consistent validation for both start and end dates, and the component correctly applies the validation to both date pickers.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other implementations of disabledDate with date ranges
ast-grep --pattern 'disabledDate = ($param) => { $$$ }'

Length of output: 57


Script:

#!/bin/bash
# Search for disabledDate implementations in both script and composition API styles
echo "=== Searching for disabledDate implementations ==="
ast-grep --pattern 'disabledDate($$$) { $$$ }'
ast-grep --pattern 'const disabledDate = $$$'

echo -e "\n=== Checking current file implementation ==="
cat examples/sites/demos/pc/app/date-panel/disabled-date-composition-api.vue

Length of output: 1344


Script:

#!/bin/bash
# Check date range component implementation for disabled date handling
echo "=== Checking date range component implementation ==="
rg -p "disabledDate" packages/vue/src/date-range/

Length of output: 562

examples/sites/demos/pc/app/date-panel/disabled-date.vue (1)

3-6: LGTM! Consistent with composition API implementation.

The implementation correctly mirrors the functionality in disabled-date-composition-api.vue.

examples/sites/demos/pc/app/date-panel/unlink-panels-composition-api.vue (1)

5-13: LGTM! Clear demonstration of panels linking behavior.

The implementation effectively demonstrates both linked and unlinked panel behavior.

examples/sites/demos/pc/app/date-panel/event-composition-api.vue (2)

21-23: Consider extracting message strings for internationalization.

The hardcoded Chinese messages should be moved to a localization system for better maintainability and internationalization support.


33-35: Consider using consistent widths for date components.

The date range picker is significantly wider (668px) than the parent container (560px), which could cause layout issues.

examples/sites/demos/pc/app/date-panel/disabled-date.spec.ts (2)

17-20: 🛠️ Refactor suggestion

Improve selector reliability and test data management.

The current implementation has several issues:

  1. Complex selectors using nth-child and filter
  2. Hardcoded test dates

Consider:

  1. Using data-testid attributes
  2. Moving test dates to a constants file
+// constants/test-dates.ts
+export const TEST_DATES = {
+  startDate: '2025-01-15',
+  endDate: '2025-02-15'
+}

-await page.locator('.tiny-date-range-picker__header > button').first().click()
+await page.getByTestId('date-range-prev-month').click()

-await expect(page.locator('.value1')).toHaveText('[ "2025-01-15", "2025-02-15" ]')
+await expect(page.locator('.value1')).toHaveText(`[ "${TEST_DATES.startDate}", "${TEST_DATES.endDate}" ]`)

Likely invalid or redundant comment.


22-28: Add test coverage for disabled date interactions.

The test suite should verify that:

  • Disabled dates cannot be selected
  • Range selection skips over disabled dates
  • Error handling for invalid selections
examples/sites/demos/pc/app/date-panel/shortcuts-composition-api.vue (2)

45-45: Remove debug console.info statement.

The console.info(picker) statement should be removed as it's not needed in production code.

-      console.info(picker)

79-81: Consider using responsive width for date range picker.

The width is hardcoded to 668px which might not be responsive on different screen sizes.

Consider using relative units or CSS Grid/Flexbox for better responsiveness:

-  .tiny-date-range-picker {
-    width: 668px;
-  }
+  .tiny-date-range-picker {
+    width: 100%;
+    max-width: 668px;
+  }

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

♻️ Duplicate comments (3)
examples/sites/demos/apis/date-panel.js (2)

216-226: ⚠️ Potential issue

Incorrect type and description for disabled-date prop.

The disabled-date prop should be a function that determines which dates are disabled.

Apply this fix:

{
  name: 'disabled-date',
  typeAnchorName: 'disabledDate',
- type: 'boolean',
+ type: 'function',
  defaultValue: '',
  desc: {
    'zh-CN': '配置部分禁用',
-   'en-US': "Custom selector's rear icon"
+   'en-US': 'Function that determines if a date is disabled'
  },
  mode: ['pc'],
  pcDemo: 'shortcuts'
}

252-261: ⚠️ Potential issue

Incorrect English description for popper-class prop.

The English description for popper-class appears to be copied from unlink-panels.

Fix the description:

desc: {
  'zh-CN': '为 DatePicker 下拉弹框添加的 class 类名',
- 'en-US': 'Cancel the linkage between two date panels in the range selector.'
+ 'en-US': 'Custom class name for the DatePicker dropdown'
}
packages/renderless/src/date-range/index.ts (1)

621-635: 🛠️ Refactor suggestion

Add validation for model value updates.

The watchModelValue function needs input validation to handle invalid dates.

Add proper validation:

export const watchModelValue =
  ({ state }) =>
  (val) => {
+    if (!Array.isArray(val) || val.length !== 2) {
+      return
+    }
    const newVal = toDate(val?.[0])
    const newVal1 = toDate(val?.[1])
+    if (!newVal || !newVal1 || isNaN(newVal.getTime()) || isNaN(newVal1.getTime())) {
+      console.warn('Invalid date values provided to date-range')
+      return
+    }
    if (newVal && newVal1) {
🧹 Nitpick comments (4)
examples/sites/demos/pc/app/date-panel/basic-usage.vue (2)

12-12: Remove extra newline between imports.

There's an unnecessary newline between imports that should be removed according to the project's linting rules.

 import { ref } from 'vue'
 import { TinyDatePanel, TinyDateRange } from '@opentiny/vue'
-

Also applies to: 14-14


24-27: Consider using responsive width for date range picker.

The fixed width of 668px might not be responsive on smaller screens. Consider using relative units or media queries for better responsiveness.

 .tiny-date-range-picker {
-  width: 668px;
+  width: 100%;
+  max-width: 668px;
 }
examples/sites/demos/pc/app/date-panel/disabled-date-composition-api.vue (2)

12-15: Consider adding type annotations for better maintainability.

While the implementation is correct, adding TypeScript type annotations would improve code maintainability and provide better IDE support.

-const value = ref('2025-01-15')
-const value1 = ref(['2025-01-15', '2025-02-15'])
+const value = ref<string>('2025-01-15')
+const value1 = ref<[string, string]>(['2025-01-15', '2025-02-15'])

24-29: Consider adding responsive design support.

The fixed width of 668px for .tiny-date-range-picker might cause overflow issues on smaller screens. Consider using relative units or media queries for better responsiveness.

.tiny-date-range-picker {
-  width: 668px;
+  width: 100%;
+  max-width: 668px;
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f5c9e60 and c950f44.

📒 Files selected for processing (37)
  • examples/sites/demos/apis/date-panel.js (1 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-week.spec.ts (2 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-weeks-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-weeks.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/event-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/event.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/event.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/webdoc/date-panel.js (1 hunks)
  • examples/sites/demos/pc/app/date-picker/webdoc/date-picker.js (1 hunks)
  • packages/renderless/src/date-range/index.ts (7 hunks)
  • packages/renderless/src/date-range/vue.ts (7 hunks)
  • packages/renderless/src/date-table/index.ts (1 hunks)
  • packages/renderless/src/time/index.ts (1 hunks)
  • packages/vue/src/date-range/__tests__/date-range.test.tsx (1 hunks)
  • packages/vue/src/date-range/src/index.ts (1 hunks)
  • packages/vue/src/date-range/src/mobile-first.vue (1 hunks)
  • packages/vue/src/date-range/src/pc.vue (8 hunks)
  • packages/vue/src/date-table/src/index.ts (1 hunks)
  • packages/vue/src/date-table/src/pc.vue (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (28)
  • packages/vue/src/date-table/src/pc.vue
  • packages/renderless/src/date-table/index.ts
  • examples/sites/demos/pc/app/date-panel/format.spec.ts
  • examples/sites/demos/pc/app/date-panel/readonly.spec.ts
  • examples/sites/demos/pc/app/date-panel/shortcuts.spec.ts
  • examples/sites/demos/pc/app/date-panel/unlink-panels.spec.ts
  • examples/sites/demos/pc/app/date-panel/webdoc/date-panel.js
  • examples/sites/demos/pc/app/date-panel/custom-week.spec.ts
  • packages/renderless/src/time/index.ts
  • examples/sites/demos/pc/app/date-panel/disabled-date.spec.ts
  • examples/sites/demos/pc/app/date-panel/readonly-composition-api.vue
  • packages/vue/src/date-range/tests/date-range.test.tsx
  • examples/sites/demos/pc/app/date-panel/unlink-panels-composition-api.vue
  • examples/sites/demos/pc/app/date-panel/unlink-panels.vue
  • examples/sites/demos/pc/app/date-panel/basic-usage-composition-api.vue
  • examples/sites/demos/pc/app/date-panel/event.spec.ts
  • examples/sites/demos/pc/app/date-panel/shortcuts-composition-api.vue
  • examples/sites/demos/pc/app/date-panel/format-composition-api.vue
  • examples/sites/demos/pc/app/date-panel/disabled-date.vue
  • packages/vue/src/date-range/src/index.ts
  • examples/sites/demos/pc/app/date-panel/readonly.vue
  • examples/sites/demos/pc/app/date-panel/event.vue
  • packages/renderless/src/date-range/vue.ts
  • packages/vue/src/date-table/src/index.ts
  • packages/vue/src/date-range/src/mobile-first.vue
  • examples/sites/demos/pc/app/date-panel/basic-usage.spec.ts
  • examples/sites/demos/pc/app/date-panel/custom-weeks-composition-api.vue
  • examples/sites/demos/pc/app/date-panel/custom-weeks.vue
🧰 Additional context used
🪛 eslint
examples/sites/demos/pc/app/date-panel/basic-usage.vue

[error] 14-15: Delete

(prettier/prettier)

🔇 Additional comments (12)
examples/sites/demos/pc/app/date-picker/webdoc/date-picker.js (1)

211-217: Documentation updates look great!

The changes to the unlink-panels demo documentation are clear, accurate, and well-structured. The descriptions effectively explain both the default panel linkage behavior and the customized behavior when unlink-panels is set to true.

examples/sites/demos/pc/app/date-panel/format.vue (2)

4-6: LGTM! Consistent date format usage.

The format prop is correctly and consistently applied to both date panel and date range components.


24-26: Consider using responsive width for date range picker.

packages/vue/src/date-range/src/pc.vue (4)

54-54: Standardize readonly property handling across inputs.

The readonly property is implemented inconsistently across different input components. Some combine conditions while others use direct binding.

Standardize the readonly logic:

-:readonly="readonly"
-@focus="!readonly && (state.minTimePickerVisible = true)"
-:readonly="!timeEditable || readonly"
-:readonly="!state.minDate || readonly"
-:readonly="!state.minDate || !timeEditable || readonly"
+:readonly="readonly || !timeEditable"
+:readonly="readonly || !state.minDate"
+@focus="!(readonly || !timeEditable) && (state.minTimePickerVisible = true)"

Also applies to: 66-66, 69-69, 91-91, 103-104


165-165: Ensure consistent readonly behavior in date tables.

The readonly property is correctly propagated to both date tables, ensuring consistent behavior across the range picker.

Also applies to: 215-215


222-222: Improve footer visibility logic.

The footer visibility now considers the readonly state, preventing interactions when the component is readonly.


262-278: Props declaration follows component standards.

The props are well-organized and include all necessary properties for the date range functionality.

examples/sites/demos/apis/date-panel.js (2)

240-249: Missing English description for name prop.

The name prop lacks an English description.

Add the missing description:

desc: {
  'zh-CN': '原生属性',
- 'en-US': ''
+ 'en-US': 'Native attribute for form submission'
}

285-294: Missing English description for unlink-panels prop.

The unlink-panels prop is missing its English description.

Add the missing description:

desc: {
  'zh-CN': '在范围选择器里取消两个日期面板之间的联动',
- 'en-US': ''
+ 'en-US': 'Unlink the two date panels in the range selector'
}
packages/renderless/src/date-range/index.ts (2)

218-221: Proper readonly check implementation.

The readonly check is correctly implemented at the start of the handler.


562-566: Ensure consistent date formatting in event emissions.

The handleConfirm function now properly formats dates based on the picker type.

The implementation correctly:

  • Uses appropriate default formats based on picker type
  • Emits both modelValue and select-change events
  • Formats dates consistently
examples/sites/demos/pc/app/date-panel/disabled-date-composition-api.vue (1)

3-6: LGTM! Good component organization and consistent validation.

The template structure is well-organized with clear value displays and consistent use of the disabledDate validation across both date components.

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

♻️ Duplicate comments (2)
packages/renderless/src/date-range/index.ts (1)

621-635: ⚠️ Potential issue

Add validation for model value updates.

The watchModelValue function needs input validation and error handling.

Add proper validation:

 export const watchModelValue =
   ({ state }) =>
   (val) => {
+    if (!Array.isArray(val) || val.length !== 2) {
+      return
+    }
     const newVal = toDate(val?.[0])
     const newVal1 = toDate(val?.[1])
+    if (!newVal || !newVal1 || isNaN(newVal.getTime()) || isNaN(newVal1.getTime())) {
+      console.warn('Invalid date values provided to date-range')
+      return
+    }
     if (newVal && newVal1) {
examples/sites/demos/pc/app/date-panel/shortcuts-composition-api.vue (1)

41-70: 🛠️ Refactor suggestion

Refactor date calculations to reduce duplication.

The shortcuts implementation contains duplicated date calculation logic and magic numbers.

🧹 Nitpick comments (9)
examples/sites/demos/pc/app/date-panel/format.vue (2)

3-6: Add ARIA labels for better accessibility.

Consider adding aria-labels to improve accessibility for screen readers:

-    <div class="value">{{ value }}</div>
-    <tiny-date-panel v-model="value" format="yyyy/MM/dd"></tiny-date-panel>
-    <div class="value1">{{ value1 }}</div>
-    <tiny-date-range type="daterange" v-model="value1" format="yyyy/MM/dd"></tiny-date-range>
+    <div class="value" aria-label="Selected date">{{ value }}</div>
+    <tiny-date-panel v-model="value" format="yyyy/MM/dd" aria-label="Date selector"></tiny-date-panel>
+    <div class="value1" aria-label="Selected date range">{{ value1 }}</div>
+    <tiny-date-range type="daterange" v-model="value1" format="yyyy/MM/dd" aria-label="Date range selector"></tiny-date-range>

14-15: Consider using current date as default value.

The hardcoded dates are set to 2025, which might not be the most intuitive default for users. Consider using the current date as the default value:

-const value = ref('2025/01/15')
-const value1 = ref(['2025/01/15', '2025/02/15'])
+const today = new Date().toISOString().split('T')[0].replace(/-/g, '/')
+const nextMonth = new Date(new Date().setMonth(new Date().getMonth() + 1)).toISOString().split('T')[0].replace(/-/g, '/')
+const value = ref(today)
+const value1 = ref([today, nextMonth])
packages/renderless/src/date-range/index.ts (1)

435-443: Simplify shortcut handling logic.

The shortcut handling could be simplified to reduce code duplication between the two branches.

Consider refactoring to:

-        if (props.shortcuts?.length) {
-          state.value = [start, end]
-          state.leftDate = start
-          state.rightDate = end
-          api.handleRangePick({ minDate: start, maxDate: end })
-        } else {
-          api.doPick(start, end)
-        }
+        state.value = [start, end]
+        if (props.shortcuts?.length) {
+          state.leftDate = start
+          state.rightDate = end
+          api.handleRangePick({ minDate: start, maxDate: end })
+        }
+        api.doPick(start, end)
examples/sites/demos/pc/app/date-panel/shortcuts.vue (1)

45-45: Remove debug logging.

Remove the console.info(picker) statement as it appears to be debug code.

-      console.info(picker)
packages/vue/src/date-range/src/pc.vue (1)

54-54: Standardize readonly handling across inputs.

The readonly conditions are implemented inconsistently across different inputs. Consider standardizing the approach:

-:readonly="readonly"
+:readonly="readonly || !timeEditable"

-@focus="!readonly && (state.minTimePickerVisible = true)"
+:readonly="readonly || !timeEditable"

-:readonly="!timeEditable || readonly"
+:readonly="readonly || !timeEditable"

-:readonly="readonly || !state.minDate"
+:readonly="readonly || !timeEditable || !state.minDate"

-:readonly="readonly || !state.minDate || !timeEditable"
-@focus="state.minDate && !readonly && (state.maxTimePickerVisible = true)"
+:readonly="readonly || !timeEditable || !state.minDate"
+@focus="!readonly && state.minDate && (state.maxTimePickerVisible = true)"

Also applies to: 66-66, 69-69, 91-91, 103-104

examples/sites/demos/apis/date-panel.js (4)

194-203: Inconsistent property name format

The property name modelValue / v-model uses an inconsistent format. Other properties use a single name format.

-  name: 'modelValue / v-model',
+  name: 'v-model',

Also, consider adding a note in the description that modelValue is the equivalent property when using composition API.


205-214: Improve type definition format and documentation

The type definition could be more precise and the description could be more informative.

-  type: 'daterange | datetimerange',
+  type: "'daterange' | 'datetimerange'",
   defaultValue: 'daterange',
   desc: {
     'zh-CN': '时间区间类型',
-    'en-US': 'Range type'
+    'en-US': 'Type of date range picker. Use "daterange" for date only, or "datetimerange" for date with time.'
   },

284-290: Improve event description clarity

The English description for the select-change event combines the description with an example, making it harder to read.

   desc: {
     'zh-CN': '用户确认选定的值时触发',
-    'en-US':
-      'This event is triggered when the user confirms the selected value. change (arg1) {//arg1 is the changed date or date set of datepicker}'
+    'en-US': 'Triggered when the user confirms the selected date range. The callback receives the selected Date object as an argument.'
   },

190-454: Consider adding validation examples

The documentation would benefit from examples showing how to use the disabled-date function for common validation scenarios.

Consider adding a validationExamples section with common patterns like:

  • Disabling past dates
  • Limiting the date range
  • Disabling specific days of the week
  • Limiting the selection range

Would you like me to generate example code for these validation patterns?

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c950f44 and 0c82d78.

📒 Files selected for processing (37)
  • examples/sites/demos/apis/date-panel.js (1 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/basic-usage.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-week.spec.ts (2 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-weeks-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/custom-weeks.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/disabled-date.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/event-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/event.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/event.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/format.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/readonly.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/shortcuts.vue (2 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/date-panel/unlink-panels.vue (1 hunks)
  • examples/sites/demos/pc/app/date-panel/webdoc/date-panel.js (1 hunks)
  • examples/sites/demos/pc/app/date-picker/webdoc/date-picker.js (1 hunks)
  • packages/renderless/src/date-range/index.ts (7 hunks)
  • packages/renderless/src/date-range/vue.ts (7 hunks)
  • packages/renderless/src/date-table/index.ts (1 hunks)
  • packages/renderless/src/time/index.ts (1 hunks)
  • packages/vue/src/date-range/__tests__/date-range.test.tsx (1 hunks)
  • packages/vue/src/date-range/src/index.ts (1 hunks)
  • packages/vue/src/date-range/src/mobile-first.vue (1 hunks)
  • packages/vue/src/date-range/src/pc.vue (8 hunks)
  • packages/vue/src/date-table/src/index.ts (1 hunks)
  • packages/vue/src/date-table/src/pc.vue (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (29)
  • examples/sites/demos/pc/app/date-panel/format.spec.ts
  • packages/vue/src/date-table/src/pc.vue
  • packages/vue/src/date-range/src/mobile-first.vue
  • examples/sites/demos/pc/app/date-panel/shortcuts.spec.ts
  • examples/sites/demos/pc/app/date-panel/event.spec.ts
  • examples/sites/demos/pc/app/date-panel/basic-usage.spec.ts
  • examples/sites/demos/pc/app/date-panel/webdoc/date-panel.js
  • packages/vue/src/date-table/src/index.ts
  • packages/renderless/src/time/index.ts
  • packages/renderless/src/date-table/index.ts
  • examples/sites/demos/pc/app/date-panel/basic-usage-composition-api.vue
  • examples/sites/demos/pc/app/date-panel/readonly.spec.ts
  • examples/sites/demos/pc/app/date-panel/custom-week.spec.ts
  • examples/sites/demos/pc/app/date-panel/unlink-panels.spec.ts
  • examples/sites/demos/pc/app/date-panel/disabled-date.spec.ts
  • examples/sites/demos/pc/app/date-panel/event.vue
  • examples/sites/demos/pc/app/date-picker/webdoc/date-picker.js
  • examples/sites/demos/pc/app/date-panel/custom-weeks-composition-api.vue
  • examples/sites/demos/pc/app/date-panel/readonly.vue
  • examples/sites/demos/pc/app/date-panel/unlink-panels-composition-api.vue
  • examples/sites/demos/pc/app/date-panel/event-composition-api.vue
  • packages/vue/src/date-range/tests/date-range.test.tsx
  • examples/sites/demos/pc/app/date-panel/readonly-composition-api.vue
  • examples/sites/demos/pc/app/date-panel/custom-weeks.vue
  • examples/sites/demos/pc/app/date-panel/disabled-date.vue
  • packages/vue/src/date-range/src/index.ts
  • packages/renderless/src/date-range/vue.ts
  • examples/sites/demos/pc/app/date-panel/disabled-date-composition-api.vue
  • examples/sites/demos/pc/app/date-panel/unlink-panels.vue
🧰 Additional context used
🪛 eslint
examples/sites/demos/pc/app/date-panel/basic-usage.vue

[error] 14-15: Delete

(prettier/prettier)

🔇 Additional comments (9)
examples/sites/demos/pc/app/date-panel/format.vue (1)

24-26: Consider using responsive width for date range picker.

The fixed width of 668px might not be responsive on smaller screens.

-  .tiny-date-range-picker {
-    width: 668px;
-  }
+  .tiny-date-range-picker {
+    width: 100%;
+    max-width: 668px;
+    min-width: 360px;
+  }
packages/renderless/src/date-range/index.ts (2)

218-221: Proper readonly handling added.

The handleChangeRange function now includes a check for the readonly property, preventing changes to the date range when the component is in read-only mode.


558-566: Well-implemented date formatting and event handling.

The changes properly handle date formatting based on picker type and emit appropriate events for model updates and selection changes.

examples/sites/demos/pc/app/date-panel/basic-usage.vue (1)

3-6: LGTM! Clean implementation of the date range functionality.

The changes effectively integrate the date range picker component with appropriate initial values and styling.

Also applies to: 12-12, 15-16, 25-27

examples/sites/demos/pc/app/date-panel/format-composition-api.vue (1)

3-6: LGTM! Consistent implementation with proper date formatting.

The date format is correctly applied to both components using the format prop.

Also applies to: 12-12, 14-15, 21-25

examples/sites/demos/pc/app/date-panel/shortcuts.vue (1)

41-70: 🛠️ Refactor suggestion

Refactor date calculations to reduce duplication.

The shortcuts implementation contains duplicated date calculation logic and magic numbers.

Consider this refactor:

+const MS_PER_DAY = 24 * 60 * 60 * 1000
+const getDateRange = (days) => {
+  const end = new Date()
+  const start = new Date()
+  start.setTime(start.getTime() - MS_PER_DAY * days)
+  return [start, end]
+}

 const shortcuts1 = [
   {
     text: '最近一周',
     onClick(picker) {
-      const end = new Date()
-      const start = new Date()
-      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
+      const [start, end] = getDateRange(7)
       picker.$emit('pick', [start, end])
     }
   },
   {
     text: '最近一个月',
     onClick(picker) {
-      const end = new Date()
-      const start = new Date()
-      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
+      const [start, end] = getDateRange(30)
       picker.$emit('pick', [start, end])
     }
   },
   {
     text: '最近三个月',
     onClick(picker) {
-      const end = new Date()
-      const start = new Date()
-      start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
+      const [start, end] = getDateRange(90)
       picker.$emit('pick', [start, end])
     }
   }
 ]

Likely invalid or redundant comment.

examples/sites/demos/pc/app/date-panel/shortcuts-composition-api.vue (1)

45-45: Remove debug logging.

Remove the console.info(picker) statement as it appears to be debug code.

packages/vue/src/date-range/src/pc.vue (2)

27-27: LGTM! Improved shortcuts rendering efficiency.

Changed from v-show to v-if which is more efficient for content that rarely changes.


262-278: LGTM! Well-structured props and emits declarations.

The props and emits are properly typed and organized.

examples/sites/demos/apis/date-panel.js Show resolved Hide resolved
examples/sites/demos/apis/date-panel.js Outdated Show resolved Hide resolved
examples/sites/demos/apis/date-panel.js Show resolved Hide resolved
@discreted66 discreted66 force-pushed the daterange branch 2 times, most recently from 3a2ec0b to 6c94197 Compare January 21, 2025 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request (功能增强)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants