Skip to content

Conversation

@skiyee
Copy link
Owner

@skiyee skiyee commented Nov 4, 2025

#39

Summary by CodeRabbit

新功能

  • 操作表单组件 - 新增底部操作表单(Action Sheet)组件,支持多选项列表、自定义标题和描述、破坏性操作样式、禁用状态、图标显示等功能
  • 示例代码 - 提供8个完整示例,包括基础用法、取消按钮定制、受控状态、自定义样式、选项描述、破坏性操作、禁用选项和图标等场景

@coderabbitai
Copy link

coderabbitai bot commented Nov 4, 2025

Walkthrough

添加了一个全新的ActionSheet底部抽屉组件至skiyee-uni-ui库,包括完整的Vue 3组件实现、样式系统支持和八个功能演示示例页面,展示了基础用法、取消按钮、受控状态、自定义样式、描述文本、破坏性操作、禁用选项和图标等多种场景。

Changes

cohort / File(s) Summary
示例演示页面
examples/uni/src/pages-feedback/action-sheet/base.vue, cancel.vue, controlled.vue, custom.vue, description.vue, destructive.vue, disabled.vue, icon.vue
新增8个Vue SFC组件演示ActionSheet的不同用法:基础用法、取消按钮处理、受控组件模式、自定义样式(无圆角/紧凑间距/层级)、选项描述、破坏性操作确认、禁用选项、带图标选项
页面路由配置
examples/uni/src/pages.json
新增8条页面路由条目对应ActionSheet示例文件
核心组件
packages/skiyee-uni-ui/src/components/sk-action-sheet.vue
新增ActionSheet底部抽屉组件,支持受控/非受控模式、自定义选项、事件回调、插槽扩展、多种配置属性(圆角、间距、z-index、安全区等)
样式模块
packages/skiyee-uni-ui/src/styles/sk-action-sheet.ts
新增自动生成的UCV样式组件,定义ActionSheet的多个变体(round、spacing、disabled等)和条件样式规则
样式导出
packages/skiyee-uni-ui/src/styles/index.ts
新增SkActionSheetUcv和SkActionSheetUcvProps的公开导出

Sequence Diagram

sequenceDiagram
    participant User as 用户
    participant Button as 按钮
    participant ActionSheet as ActionSheet组件
    participant Toast as Toast通知

    User->>Button: 点击打开
    activate Button
    Button->>ActionSheet: 设置 visible = true
    deactivate Button
    activate ActionSheet
    ActionSheet->>User: 显示底部抽屉
    User->>ActionSheet: 点击选项/取消
    alt 选择选项
        ActionSheet->>ActionSheet: 触发 `@select` 事件
        ActionSheet->>Toast: 显示选中内容
        activate Toast
        Toast-->>User: Toast提示
        deactivate Toast
    else 点击取消
        ActionSheet->>ActionSheet: 触发 `@cancel` 事件
        ActionSheet->>Toast: 显示取消提示
    end
    ActionSheet->>ActionSheet: 设置 visible = false
    ActionSheet-->>User: 关闭抽屉
    deactivate ActionSheet
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • 特别关注
    • sk-action-sheet.vue 中的事件处理逻辑和受控/非受控模式的实现细节
    • 8个示例文件中处理模态框确认的 destructive.vue 里的业务逻辑流程
    • sk-action-sheet.ts 中UCV样式变体的定义是否完整覆盖所有使用场景
    • 选项的禁用态、破坏性样式在各示例中的正确使用

Poem

🐰✨ ActionSheet降临,八般用法尽施展,

圆角扁平随意变,图标描述都齐全,

破坏确认保安全,禁用受控不简单,

底部抽屉更优雅,兔子欢呼庆新篇!🎉

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题准确地反映了主要改动——实现了ActionSheet动作面板组件。标题具体、简洁,清晰表达了核心功能。
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/action-sheet

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@netlify
Copy link

netlify bot commented Nov 4, 2025

Deploy Preview for skiyee-ui ready!

Name Link
🔨 Latest commit 2824658
🔍 Latest deploy log https://app.netlify.com/projects/skiyee-ui/deploys/690a0aa3ebc1930008d81156
😎 Deploy Preview https://deploy-preview-40--skiyee-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

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 (9)
packages/skiyee-uni-ui/src/styles/sk-action-sheet.ts (1)

84-86: 建议明确空值的语义

hasCancelfalse 时,root 使用空字符串。虽然这是有效的,但建议添加注释说明意图,或者使用更明确的类名(如 sk-unit:pb-0)以提高可读性。

     hasCancel: {
       true: {
         root: 'sk-unit:pb-0',
       },
       false: {
-        root: '',
+        root: '', // 无取消按钮时保持默认间距
       },
     },
examples/uni/src/pages-feedback/action-sheet/icon.vue (1)

1-27: 定义清晰,建议改进类型安全

选项数据结构清晰,包含了图标信息。不过 handleSelect 的参数类型使用了 any,建议定义明确的接口类型以提高类型安全性。

+interface ActionSheetOption {
+  name: string
+  icon: string
+  value: string
+}
+
-function handleSelect(option: any) {
+function handleSelect(option: ActionSheetOption) {
   uni.showToast({
     title: `分享到:${option.name}`,
     icon: 'none',
   })
 }
examples/uni/src/pages-feedback/action-sheet/description.vue (1)

1-30: 建议改进类型定义

代码实现清晰,但 handleSelect 参数使用了 any 类型。建议定义选项接口以提高类型安全性和代码可维护性。

+interface OptionWithDescription {
+  name: string
+  description: string
+  value: string
+}
+
-function handleSelect(option: any) {
+function handleSelect(option: OptionWithDescription) {
   uni.showToast({
     title: `选择了:${option.name}`,
     icon: 'none',
   })
 }
examples/uni/src/pages-feedback/action-sheet/cancel.vue (1)

13-25: 建议为事件处理器添加类型

事件处理逻辑正确,但参数使用了 any 类型。建议定义接口提高类型安全性。

+interface Option {
+  name: string
+  value: number
+}
+
-function handleSelect(option: any) {
+function handleSelect(option: Option) {
   uni.showToast({
     title: `选择了:${option.name}`,
     icon: 'none',
   })
 }
examples/uni/src/pages-feedback/action-sheet/disabled.vue (1)

6-18: 禁用选项数据结构完整,建议改进类型

选项中正确包含了 disabled 属性,但 handleSelect 参数应使用明确的类型定义。

+interface DisableableOption {
+  name: string
+  value: number
+  disabled?: boolean
+}
+
-function handleSelect(option: any) {
+function handleSelect(option: DisableableOption) {
   uni.showToast({
     title: `选择了:${option.name}`,
     icon: 'none',
   })
 }
examples/uni/src/pages-feedback/action-sheet/destructive.vue (1)

12-33: 建议添加类型定义以增强安全性

条件处理逻辑正确,对破坏性操作进行了二次确认。但参数类型为 any,建议定义明确的接口。

+interface ActionOption {
+  name: string
+  value: string
+  destructive?: boolean
+}
+
-function handleSelect(option: any) {
+function handleSelect(option: ActionOption) {
   if (option.destructive) {
     uni.showModal({
       title: '确认删除',
       content: '此操作不可恢复',
       success: (res) => {
         if (res.confirm) {
           uni.showToast({
             title: '已删除',
             icon: 'success',
           })
         }
       },
     })
   }
   else {
     uni.showToast({
       title: `选择了:${option.name}`,
       icon: 'none',
     })
   }
 }
examples/uni/src/pages-feedback/action-sheet/base.vue (1)

12-17: 建议为 option 参数添加明确类型。

虽然这是示例代码,但使用 any 类型会降低类型安全性。建议使用 ActionSheetOption 类型以获得更好的类型提示和编译时检查。

应用此修改以改善类型安全:

-function handleSelect(option: any) {
+import type { ActionSheetOption } from '@skiyee/uni-ui'
+
+function handleSelect(option: ActionSheetOption) {
   uni.showToast({
     title: `选择了:${option.name}`,
     icon: 'none',
   })
 }
examples/uni/src/pages-feedback/action-sheet/custom.vue (1)

14-19: 建议为 option 参数添加明确类型。

与 base.vue 类似,建议使用 ActionSheetOption 类型替代 any 以提高代码质量。

应用此修改:

-function handleSelect(option: any) {
+import type { ActionSheetOption } from '@skiyee/uni-ui'
+
+function handleSelect(option: ActionSheetOption) {
   uni.showToast({
     title: `选择了:${option.name}`,
     icon: 'none',
   })
 }
examples/uni/src/pages-feedback/action-sheet/controlled.vue (1)

13-17: 建议为 option 参数添加明确类型。

与其他示例文件一致,建议使用 ActionSheetOption 类型替代 any

应用此修改:

-function handleSelect(option: any) {
+import type { ActionSheetOption } from '@skiyee/uni-ui'
+
+function handleSelect(option: ActionSheetOption) {
   selectedOption.value = option.name
   // 手动控制关闭
   visible.value = false
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a1d5cd3 and 2824658.

📒 Files selected for processing (12)
  • examples/uni/src/pages-feedback/action-sheet/base.vue (1 hunks)
  • examples/uni/src/pages-feedback/action-sheet/cancel.vue (1 hunks)
  • examples/uni/src/pages-feedback/action-sheet/controlled.vue (1 hunks)
  • examples/uni/src/pages-feedback/action-sheet/custom.vue (1 hunks)
  • examples/uni/src/pages-feedback/action-sheet/description.vue (1 hunks)
  • examples/uni/src/pages-feedback/action-sheet/destructive.vue (1 hunks)
  • examples/uni/src/pages-feedback/action-sheet/disabled.vue (1 hunks)
  • examples/uni/src/pages-feedback/action-sheet/icon.vue (1 hunks)
  • examples/uni/src/pages.json (2 hunks)
  • packages/skiyee-uni-ui/src/components/sk-action-sheet.vue (1 hunks)
  • packages/skiyee-uni-ui/src/styles/index.ts (1 hunks)
  • packages/skiyee-uni-ui/src/styles/sk-action-sheet.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/skiyee-uni-ui/src/styles/sk-action-sheet.ts (1)
packages/skiyee-uni-ui/src/styles/index.ts (2)
  • SkActionSheetUcv (10-10)
  • SkActionSheetUcvProps (9-9)
🔇 Additional comments (19)
packages/skiyee-uni-ui/src/styles/sk-action-sheet.ts (2)

20-35: 元素定义结构清晰

元素映射定义完整,使用了合适的 Tailwind/UnoCSS 工具类,命名语义化,布局和样式合理。


113-125: 默认值配置完整

所有变体都正确设置了默认值,类型导出使用了 InferProps 进行类型推断,符合最佳实践。

examples/uni/src/pages.json (1)

640-671: 路由配置规范

新增的 8 个 action-sheet 示例页面路由配置符合现有模式,路径命名一致,放置位置合理(在 dialog 之前,符合字母顺序)。

examples/uni/src/pages-feedback/action-sheet/icon.vue (1)

37-50: 组件使用正确

SkActionSheet 组件的绑定和事件处理使用正确,v-model:visible 控制显示状态,事件处理符合预期。

examples/uni/src/pages-feedback/action-sheet/description.vue (1)

32-45: 模板结构合理

ActionSheet 组件的使用方式正确,带描述文字的选项展示符合预期。

packages/skiyee-uni-ui/src/styles/index.ts (1)

9-10: 导出声明规范

新增的 ActionSheet 样式导出遵循现有模式,位置正确(按字母顺序在 badge 之前),类型和值导出都已包含。

examples/uni/src/pages-feedback/action-sheet/cancel.vue (1)

28-53: 双实例演示清晰

通过两个 ActionSheet 实例清晰展示了默认取消按钮和自定义取消文本的用法,实现正确。

examples/uni/src/pages-feedback/action-sheet/disabled.vue (1)

21-34: 禁用状态演示正确

ActionSheet 组件正确处理了带禁用标志的选项,使用方式符合预期。

examples/uni/src/pages-feedback/action-sheet/destructive.vue (2)

6-10: 选项结构合理

破坏性操作选项定义清晰,通过 destructive 属性标识危险操作。


36-49: 组件使用正确

破坏性操作的展示和处理流程符合用户体验最佳实践。

examples/uni/src/pages-feedback/action-sheet/controlled.vue (2)

26-32: 生命周期处理函数实现正确。

这些空的生命周期处理函数很好地演示了组件的事件 API,对于示例代码来说是合适的。


49-57: 受控模式实现正确!

正确使用了 :close-on-click-action="false" 配合手动控制 visible.value 来实现受控模式,很好地展示了该功能的使用方式。

packages/skiyee-uni-ui/src/components/sk-action-sheet.vue (7)

20-45: 类型定义完善且文档齐全!

ActionSheetOption 接口设计合理,涵盖了所有必要的选项属性,JSDoc 注释完整清晰。


163-173: Props 配置和默认值设置合理!

所有属性的默认值都很合理,与类型定义中的文档一致。zIndex 默认 1100 适合遮罩层组件的层级需求。


175-184: v-model 和受控/非受控模式处理得当!

使用 defineModel API 实现 v-model 支持是 Vue 3 的最佳实践。非受控模式的初始化逻辑正确,适当地处理了 defaultVisible 属性。


186-207: 计算属性实现简洁高效!

使用计算属性来确定 UI 状态(如是否显示标题、图标等)是很好的做法,逻辑清晰且性能良好。


209-239: 事件处理逻辑严谨完善!

事件处理函数正确处理了禁用状态、自动关闭行为和事件传播,逻辑清晰且符合预期。特别是 handleOptionClick 中对禁用选项的早期返回处理很到位。


242-323: 模板结构清晰,实现完整!

模板布局合理,正确使用了 SkOverlay 作为容器,条件渲染逻辑准确,插槽设计灵活。各个区域(标题、选项列表、取消按钮、安全区域)的渲染都有适当的条件判断。


1-323: 整体实现优秀,代码质量高!

这是一个设计良好的 Vue 3 组件:

  • 使用了 Composition API 的现代特性(defineModeldefineOptions
  • 类型定义完整且文档齐全
  • 同时支持受控和非受控两种使用模式
  • 事件处理逻辑严谨,正确处理了禁用状态和各种关闭行为
  • 模板结构清晰,插槽设计灵活
  • 考虑了移动端的安全区域适配

组件实现符合生产环境标准,可以直接使用。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants