Skip to content

feat: add resizable drawer feature #528

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

QdabuliuQ
Copy link

@QdabuliuQ QdabuliuQ commented Aug 13, 2025

🤔 This is a ...

  • 🆕 New feature
  • 🐞 Bug fix
  • 📝 Site / documentation improvement
  • 📽️ Demo improvement
  • 💄 Component style improvement
  • 🤖 TypeScript definition improvement
  • 📦 Bundle size optimization
  • ⚡️ Performance optimization
  • ⭐️ Feature enhancement
  • 🌐 Internationalization
  • 🛠 Refactoring
  • 🎨 Code style optimization
  • ✅ Test Case
  • 🔀 Branch merge
  • ⏩ Workflow
  • ⌨️ Accessibility improvement
  • ❓ Other (about what?)

🔗 Related Issues

feat: ant-design/ant-design#54597

💡 Background and Solution

add resizable feature to Drawer component
add ResizableLine component to control the size of drawer

📝 Change Log

Language Changelog
🇺🇸 English add resizable feature to Drawer component
🇨🇳 Chinese Drawer 组件添加 resizable 属性

Summary by CodeRabbit

  • 新功能

    • 抽屉支持可拖拽调整尺寸(resizable),并新增 onResize / onResizeStart / onResizeEnd 回调
    • 导出 Placement 类型;新增 useDrag 钩子以支持拖拽交互,暴露相关配置与返回值
  • 文档

    • README API 表格更新:新增 resizable、重命名 onMaskClick 为 onClose 并添加 maskClosable
    • 新增“Resizable”示例页与示例代码
  • 样式

    • 增加拖拽手柄样式、悬停/拖拽态与四向边缘变体,调整遮罩与内容布局,默认不强制裁剪内容
  • 测试

    • 新增水平/垂直拖拽与最小/最大尺寸约束相关测试

Copy link

vercel bot commented Aug 13, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
drawer Ready Ready Preview Comment Aug 16, 2025 6:36am

Copy link

coderabbitai bot commented Aug 13, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

为 Drawer 引入可调尺寸功能:新增 resizable 与相关回调、useDrag 拖拽 Hook、DrawerPopup 的尺寸管理与拖拽手柄、样式前缀化与拖拽样式、示例文档与测试覆盖,并导出 Placement 类型与文档中 onMaskClick 重命名为 onClose 及新增 maskClosable。

Changes

Cohort / File(s) Summary
核心 API 与组件逻辑
src/Drawer.tsx, src/DrawerPopup.tsx, src/index.ts, src/inter.ts, src/hooks/useDrag.ts
新增 resizable?: boolean 与回调 onResize/onResizeStart/onResizeEnd(DrawerProps/DrawerPopupProps);Drawer 将回调下发至 DrawerPopup;DrawerPopup 集成 useDrag 管理 currentSize/maxSize、wrapperRef、拖拽态并在拖拽时抑制 motion;index 导出 Placementinter 接口新增 dragger class/style;新增 useDrag Hook 实现拖拽逻辑与文档化接口。
样式与动效
assets/index.less, docs/examples/assets/motion.less
样式命名由旧命名迁移到 .@{prefixCls}(rc-drawer);新增 .rc-drawer-resizable-dragger 与四向变体与拖拽态;重构 mask/content-wrapper/content/handle 等样式并移除旧大块注释样式;motion.less 增加 top/bottom 方向动画。
示例与文档
README.md, docs/demo/resizable.md, docs/examples/resizable.tsx, docs/examples/getContainer-false.tsx
README API 表格新增 resizable 与相关回调,文档中将 onMaskClick 重命名为 onClose 并新增 maskClosable;添加 resizable demo 页面与交互示例 resizable.tsx;在 getContainer-false.tsx 启用 resizable 示例。
测试
tests/index.spec.tsx
新增测试覆盖:水平/垂直可调尺寸场景与 minSize/maxSize 约束,模拟 mousedown/mousemove/mouseup 并断言内容 wrapper 的宽/高变化。

Sequence Diagram(s)

sequenceDiagram
  participant U as 用户
  participant D as Drawer (props)
  participant P as DrawerPopup
  participant H as useDrag Hook
  participant Doc as document

  U->>D: 打开 Drawer (包含 resizable, onResize*)
  D->>P: 传入 props (resizable, onResize*, placement, size)
  P->>H: 初始化 useDrag({ direction, containerRef, callbacks })
  U->>P: 在 dragger 上 mousedown
  P->>H: onMouseDown -> H 进入 dragging,记录 startSize
  H->>Doc: 绑定 mousemove/mouseup 监听
  loop 拖拽中
    U->>Doc: mousemove
    Doc->>H: 计算 delta -> newSize
    H->>P: 调用 onResize(newSize)
    P->>P: 更新 currentSize(宽/高),抑制 motion
  end
  U->>Doc: mouseup
  Doc->>H: onMouseUp -> H 调用 onResizeEnd,移除监听
  H->>P: 通知结束
  P->>D: 冒泡 onResizeEnd()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Suggested reviewers

  • zombieJ

Poem

我是小兔拉一线,抽屉长短随心变;
左右上下皆可控,尺寸轻移笑声传。
拖拽轻点不费力,组件更新乐无边。 🐰🎋

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between eb6caef and 0134a9a.

📒 Files selected for processing (1)
  • tests/index.spec.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/index.spec.tsx
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @QdabuliuQ, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant new feature to the Drawer component, allowing it to be resizable. Users can now dynamically adjust the width or height of the drawer by dragging its edges, providing greater flexibility in UI layouts. This enhancement includes new properties to enable the feature and provides callbacks for managing the resizing process, along with dedicated styling and a new internal component to handle the drag interactions. The changes are fully documented and include a new example for easy adoption.

Highlights

  • Resizable Drawer Feature: The Drawer component now supports a resizable prop, which when set to true, allows users to change the drawer's size by dragging its edges. This enhances user interaction and flexibility.
  • New Resize Event Callbacks: Three new callback functions, onResize, onResizeStart, and onResizeEnd, have been added to the Drawer component. These provide developers with hooks to execute custom logic during different stages of the resizing process, such as updating state or performing validations.
  • Introduction of ResizableLine Component: A dedicated ResizableLine component has been introduced to encapsulate the logic for handling mouse events (mousedown, mousemove, mouseup) and calculating the new size of the drawer during a drag operation. This modular approach keeps the core Drawer component cleaner.
  • Styling for Resizable Handles: New CSS rules have been added to style the resizable line, including visual feedback for hover and dragging states. This ensures a clear and intuitive user experience when interacting with the resize handles.
  • Documentation and Example Updates: Comprehensive updates to the documentation and a new interactive example have been provided. This allows other developers to quickly understand how to implement and utilize the new resizable drawer feature in their applications.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@QdabuliuQ QdabuliuQ mentioned this pull request Aug 13, 2025
17 tasks
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a resizable drawer feature, which is a great addition. The implementation is mostly solid, with a new ResizableLine component handling the drag logic and updates to the Drawer and DrawerPopup components to support it. I've found a few issues: an incorrect CSS value for overflow, a bug in the animation styles for top/bottom placements, and an API inconsistency in the new resize event handlers. The documentation and examples have been updated accordingly. My review includes suggestions to fix these issues.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🔭 Outside diff range comments (1)
src/inter.ts (1)

1-13: 命名不一致:接口使用 section,文档与样式使用 content,建议新增别名并标注弃用

DrawerClassNames/DrawerStyles 中是 section,但 README 与样式体系(如 -content)更贴近 “content”。为避免使用者困惑与类型不匹配,建议在类型上新增 content,并将 section 标注为 deprecated,保证向后兼容。

建议变更:

 export interface DrawerClassNames {
   mask?: string;
   wrapper?: string;
-  section?: string;
+  /** @deprecated 请使用 `content` */
+  section?: string;
+  content?: string;
   resizableLine?: string;
 }

 export interface DrawerStyles {
-  mask?: React.CSSProperties;
-  wrapper?: React.CSSProperties;
-  section?: React.CSSProperties;
+  mask?: React.CSSProperties;
+  wrapper?: React.CSSProperties;
+  /** @deprecated 请使用 `content` */
+  section?: React.CSSProperties;
+  content?: React.CSSProperties;
   resizableLine?: React.CSSProperties;
 }

(如代码中有读取 section 的实现,建议同时支持 content ?? section。)

🧹 Nitpick comments (18)
tsconfig.json (1)

16-16: 明确排除 .dumi 目录,避免被通配重新包含

当前 include 使用 "/*.ts"、"/*.tsx" 会再次把 .dumi 目录纳入编译范围。若期望排除 .dumi(以及构建产物),建议补充 exclude,提高 ts 编译性能并避免噪音类型报错。

建议变更:

-  "include": [".dumirc.ts", "**/*.ts", "**/*.tsx"]
+  "include": [".dumirc.ts", "**/*.ts", "**/*.tsx"],
+  "exclude": [".dumi", "node_modules", "dist"]
src/inter.ts (1)

5-5: 新增 resizableLine 类型后请同步 README 的 classNames/styles 说明

接口已增加 resizableLine?: stringresizableLine?: React.CSSProperties,但 README 的 API 表格中 classNamesstyles 的对象结构未包含该键,文档与实现不一致,建议同步更新文档。

我可以附带一段 README 的表格更新 diff,是否需要我起一个跟进 PR?

Also applies to: 12-12

README.md (3)

47-48: 补充 resizableLine 的类型说明,保持与代码一致

classNames/styles 的类型签名未包含 resizableLine,与 src/inter.ts 定义不一致,建议补上:

建议变更(文档示意):

-| classNames      | { mask?: string; content?: string; wrapper?: string; }                      | -                                      | pass className to target area                                                 |
-| styles          | { mask?: CSSProperties; content?: CSSProperties; wrapper?: CSSProperties; } | -                                      | pass style to target area                                                     |
+| classNames      | { mask?: string; content?: string; wrapper?: string; resizableLine?: string; }                      | - | pass className to target area |
+| styles          | { mask?: CSSProperties; content?: CSSProperties; wrapper?: CSSProperties; resizableLine?: CSSProperties; } | - | pass style to target area |

55-55: 文档类型更精确:placement 可标注为联合类型

代码侧已导出 Placement 类型(如 PR 摘要所述),文档仍是 string。建议文档同步为更精确的联合类型('left' | 'right' | 'top' | 'bottom' 或引用 Placement),提升消费者可读性。


59-59: 拼写错误:React.createElement

React.creactElement 应为 React.createElement

建议变更:

- | getContainer    | string \| func \| HTMLElement                                               | `body`                                 | Return the mount node for Drawer. if is `null` use React.creactElement        |
+ | getContainer    | string \| func \| HTMLElement                                               | `body`                                 | Return the mount node for Drawer. If it is `null`, use React.createElement    |
assets/index.less (3)

62-107: 提升可用性:防止拖拽时选中文本与多指缩放干扰

建议为可拖拽线增加 user-select: nonetouch-action: none,在移动端和触摸板上会更稳。

建议变更:

   &-resizable-line {
     position: absolute;
     z-index: 2;
     pointer-events: auto;
+    user-select: none;
+    touch-action: none;

68-74: 避免硬编码品牌色,改为可配置变量

#1890ff 是 Ant Design v4 的主色,rc-drawer 作为独立库建议使用可配置变量,避免与主题脱钩。可新增局部变量,默认值保留原色以兼容。

建议变更:

+@resizer-active-color: #1890ff; // 可按需覆写
 ...
   &-resizable-line {
@@
-    &:hover {
-      background-color: #1890ff !important;
-    }
+    &:hover {
+      background-color: @resizer-active-color !important;
+    }
@@
-    &-dragging {
-      background-color: #1890ff !important;
-    }
+    &-dragging {
+      background-color: @resizer-active-color !important;
+    }

110-117: z-index 定义重复且数值不一致,建议统一

本文件前部 .@{prefixCls} 已设置 z-index: @zIndex(当前为 1050),此处再次设置为 9999。两处相同选择器的重复定义会以较晚出现者为准,建议统一到变量,避免维护困惑与潜在层级问题。

建议其一(更易维护):改为使用变量

-  z-index: 9999;
+  z-index: @zIndex;

建议其二(若确需抬高层级):统一在顶部提升变量值

-@zIndex: 1050;
+@zIndex: 9999;

请确认期望行为,并选择其一。

docs/demo/resizable.md (1)

2-2: 标题大小写与导航不一致,建议统一

Front matter 中的 title 为小写“resizable”,而 nav.title 为“Resizable”。为保持文档一致性与站点导航显示统一,建议首字母大写。

-title: resizable
+title: Resizable
tests/index.spec.tsx (1)

479-516: 增强用例稳定性并覆盖回调行为断言

  • 使用 getContainer={false},减少与 Portal/文档滚动相关的偶发性影响。
  • 将拖拽序列包裹在 act 中,避免 React 状态更新告警。
  • 覆盖 onResize/onResizeStart/onResizeEnd 回调是否触发及参数正确性的断言,提升行为验证完整性。
 it('should support resizable', () => {
-  const { unmount } = render(
-    <Drawer resizable open placement="left" width={200} />,
-  );
+  const onResizeStart = jest.fn();
+  const onResize = jest.fn();
+  const onResizeEnd = jest.fn();
+  const { unmount } = render(
+    <Drawer
+      resizable
+      open
+      placement="left"
+      width={200}
+      getContainer={false}
+      onResizeStart={onResizeStart}
+      onResize={onResize}
+      onResizeEnd={onResizeEnd}
+    />,
+  );

   // Mock getBoundingClientRect for the content wrapper to simulate real DOM dimensions
   const contentWrapper = document.querySelector(
     '.rc-drawer-content-wrapper',
   ) as HTMLElement;
   const mockGetBoundingClientRect = jest.fn(
     () =>
       ({
         width: 200,
         height: 400,
         top: 0,
         left: 0,
         bottom: 400,
         right: 200,
         x: 0,
         y: 0,
         toJSON: () => ({}),
       }) as DOMRect,
   );
   contentWrapper.getBoundingClientRect = mockGetBoundingClientRect;

   const resizableLine = document.querySelector('.rc-drawer-resizable-line');
   expect(resizableLine).toBeTruthy();

-  // Simulate drag from 200px to 100px (should reduce width by 100px)
-  fireEvent.mouseDown(resizableLine, { clientX: 200 });
-  fireEvent.mouseMove(document, { clientX: 100, clientY: 0 });
-  fireEvent.mouseUp(document, { clientX: 100, clientY: 0 });
+  // Simulate drag from 200px to 100px (should reduce width by 100px)
+  act(() => {
+    fireEvent.mouseDown(resizableLine!, { clientX: 200 });
+    fireEvent.mouseMove(document, { clientX: 100, clientY: 0 });
+    fireEvent.mouseUp(document, { clientX: 100, clientY: 0 });
+  });

   expect(document.querySelector('.rc-drawer-content-wrapper')).toHaveStyle({
     width: '100px',
   });
+  expect(onResizeStart).toHaveBeenCalledTimes(1);
+  expect(onResize).toHaveBeenCalled();
+  // 最后一笔应为 100 宽度(或高度,取决于 placement)
+  expect(onResize).toHaveBeenLastCalledWith(100);
+  expect(onResizeEnd).toHaveBeenCalledTimes(1);
   unmount();
 });
docs/examples/resizable.tsx (3)

8-8: 建议优化类型导入路径

从'@/index'导入类型可能导致构建路径解析问题。建议使用相对路径或明确的包名导入。

-import type { Placement } from '@/index';
+import type { Placement } from 'rc-drawer';

42-42: key属性可能导致不必要的重新挂载

使用placement作为key会在每次placement变化时强制重新挂载Drawer组件,这可能不是期望的行为。考虑移除key属性或使用更稳定的标识符。

-key={placement}

47-52: 改进示例文案的用户体验

文案可以更清晰地说明调整大小的操作方式。

-<p>
-  You can drag the drawer edge to resize (only works when
-  &quot;Resizable&quot; is checked).
-</p>
+<p>
+  拖拽抽屉边缘可调整大小(仅在勾选"Resizable"时有效)。
+</p>
src/ResizableLine.tsx (4)

24-24: 重新考虑minSize默认值

默认minSize为100可能过大,特别是对于移动端或小屏幕设备。建议设置更小的默认值或根据方向动态调整。

-minSize = 100,
+minSize = 48,

82-84: maxSize验证逻辑可以简化

当前的maxSize检查有些冗余,可以简化条件判断。

-// Only apply maxSize if it's a valid positive number
-if (maxSize !== undefined && maxSize > 0 && newSize > maxSize) {
+if (maxSize && newSize > maxSize) {

100-112: handleMouseUp中的重复代码

与handleMouseDown中的父元素获取逻辑重复,建议提取为共用函数。

+const getParentSize = React.useCallback(() => {
+  const parentElement = lineRef.current?.parentElement;
+  if (!parentElement) return 0;
+  const rect = parentElement.getBoundingClientRect();
+  return isHorizontal ? rect.width : rect.height;
+}, [isHorizontal]);

 const handleMouseUp = React.useCallback(() => {
   if (isDragging) {
     onDraggingChange?.(false);
-    // Get the final size after resize
-    const parentElement = lineRef.current?.parentElement;
-    if (parentElement) {
-      const rect = parentElement.getBoundingClientRect();
-      const finalSize = isHorizontal ? rect.width : rect.height;
+    const finalSize = getParentSize();
+    if (finalSize > 0) {
       onResizeEnd?.(finalSize);
-    }
   }
-}, [isDragging, onResizeEnd, isHorizontal, onDraggingChange]);
+}, [isDragging, onResizeEnd, onDraggingChange, getParentSize]);

135-140: resizeLineStyle可以优化

style对象的构建可以更高效,避免每次渲染时创建新对象。

-const resizeLineStyle: React.CSSProperties = {
-  position: 'absolute',
-  zIndex: 2,
-  cursor: isHorizontal ? 'col-resize' : 'row-resize',
-  ...style,
-};
+const resizeLineStyle = React.useMemo<React.CSSProperties>(() => ({
+  position: 'absolute',
+  zIndex: 2,
+  cursor: isHorizontal ? 'col-resize' : 'row-resize',
+  ...style,
+}), [isHorizontal, style]);
src/DrawerPopup.tsx (1)

297-301: 状态初始化可以优化

建议为currentSize提供更明确的初始值,而不是undefined。

-const [currentSize, setCurrentSize] = React.useState<number>();
+const [currentSize, setCurrentSize] = React.useState<number | undefined>(undefined);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2418e05 and 1545c74.

📒 Files selected for processing (13)
  • README.md (1 hunks)
  • assets/index.less (2 hunks)
  • docs/demo/resizable.md (1 hunks)
  • docs/examples/assets/motion.less (1 hunks)
  • docs/examples/getContainer-false.tsx (1 hunks)
  • docs/examples/resizable.tsx (1 hunks)
  • src/Drawer.tsx (3 hunks)
  • src/DrawerPopup.tsx (5 hunks)
  • src/ResizableLine.tsx (1 hunks)
  • src/index.ts (1 hunks)
  • src/inter.ts (1 hunks)
  • tests/index.spec.tsx (1 hunks)
  • tsconfig.json (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
docs/examples/resizable.tsx (4)
docs/examples/getContainer-false.tsx (1)
  • open (21-114)
src/index.ts (1)
  • Placement (5-5)
src/Drawer.tsx (1)
  • Placement (15-15)
src/DrawerPopup.tsx (1)
  • Placement (26-26)
src/ResizableLine.tsx (3)
src/index.ts (1)
  • Placement (5-5)
src/Drawer.tsx (1)
  • Placement (15-15)
src/DrawerPopup.tsx (1)
  • Placement (26-26)
🔇 Additional comments (11)
README.md (1)

67-76: LGTM:新增 resizable 与 resize 回调文档与实现一致

新文档项与 PR 目标一致,描述清晰。

assets/index.less (1)

33-35: 确认移除 overflow: hidden 的影响

content-wrapper 注释掉 overflow: hidden 能让拖拽线溢出 3px 可点,但同时也可能导致内容溢出时出现视觉残留。确认是否在拖拽中通过行内样式或状态条件控制 overflow,以避免滚动条/阴影露出。

docs/examples/getContainer-false.tsx (1)

55-56: 示例新增 resizable 用法,LGTM

在 getContainer={false} 的场景展示可拖拽调整尺寸是合理的,变更清晰可读。

src/index.ts (1)

3-5: 导出 Placement 类型,LGTM

类型面向外部暴露更完整,便于下游消费与类型提示。

src/Drawer.tsx (2)

56-59: 解构新增回调以便传递,LGTM

onResize/onResizeStart/onResizeEnd 在此解构后下传,符合预期的数据流。


120-123: 回调透传到 DrawerPopup,LGTM

事件处理集合中纳入 resize 系列回调,保持 API 一致性与集中传递,合理。

src/DrawerPopup.tsx (5)

80-84: LGTM!可调整尺寸相关的API设计合理

新增的resizable相关属性和回调函数API设计清晰,类型定义完整。


397-397: 动画类名条件逻辑很好

在拖拽时禁用动画类名是明智的设计,避免拖拽过程中的动画干扰。


406-420: ResizableLine组件集成正确

ResizableLine的属性传递和事件处理集成得很好,maxSize和isDragging状态管理恰当。


393-393: wrapperRef 使用验证通过

已在 src/DrawerPopup.tsx 中确认 wrapperRef 的定义与使用场景一致:

  • 定义为 React.useRef<HTMLDivElement>(null)
  • calculateMaxSize 回调及 JSX 中通过 ref={wrapperRef} 正确绑定至 DOM 元素

未发现引用不一致或遗漏,使用正常。


304-313: calculateMaxSize函数需要添加边界检查

函数缺少对rect的null检查,可能导致运行时错误。

 const calculateMaxSize = React.useCallback(() => {
   if (wrapperRef.current) {
     const rect = wrapperRef.current.parentElement?.getBoundingClientRect();
-    const newMaxSize =
+    if (!rect) return;
+    const newMaxSize =
       placement === 'left' || placement === 'right'
-        ? (rect?.width ?? 0)
-        : (rect?.height ?? 0);
+        ? rect.width
+        : rect.height;
     setMaxSize(newMaxSize);
   }
 }, [placement]);

Likely an incorrect or invalid review comment.

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 (1)
src/DrawerPopup.tsx (1)

358-362: overflow 设置为 'none' 是无效值,应按场景使用 'visible' 或 'hidden'

这里将 style.overflow 设为 'none',CSS 不支持该值。若要让拖拽手柄(有 -3px 偏移)在 wrapper 外可见,应在 resizable 时使用 'visible';而非 resizable 场景建议维持 'hidden'(与历史行为一致,避免 wrapper 出现滚动条)。

-    if (resizable) {
-      style.overflow = 'none';
-    } else {
-      style.overflow = 'auto';
-    }
+    if (resizable) {
+      style.overflow = 'visible';
+    } else {
+      style.overflow = 'hidden';
+    }
🧹 Nitpick comments (9)
assets/index.less (1)

62-107: 拖拽手柄建议增强可用性与可访问性(触控/选择/命中区域)

当前手柄宽高为 6px,hover/dragging 才着色,缺少移动端和防选中文本的样式,实际交互可能较难命中并与内容选择冲突。

建议增强:

  • 添加 touch-action: none; user-select: none; 避免移动端滚动/文本选择干扰。
  • 默认 background-color: transparent,hover/dragging 再显色。
  • 可考虑将热区扩大到 8–10px(按需)。

示例增补(可合入 &-resizable-dragger 基类内):

 &-resizable-dragger {
   position: absolute;
   z-index: 2;
   pointer-events: auto;
+  background-color: transparent;
+  touch-action: none;
+  user-select: none;
src/inter.ts (1)

1-13: 新增 dragger 自定义入口命名与定位合理,建议补充注释以稳定 API 语义

新增 dragger?: stringdragger?: React.CSSProperties 能覆盖拖拽线的 className 与 style,命名与现有讨论一致。为便于下游理解与避免误用(与 handle/section 概念混淆),建议在接口上补充 JSDoc 注释,说明其仅作用于“可调整尺寸的分隔线/热区”。

示例注释(非必须):

/** resizable 模式下的拖拽手柄(分隔线)容器样式/类名 */
dragger?: string;
dragger?: React.CSSProperties;
docs/examples/resizable.tsx (3)

14-19: 移除多余类型断言,直接类型化 buttons 数组

placement 的状态已是 Placement,此处对每一项使用 as Placement 属于冗余断言。直接在数组上声明类型更清晰安全。

-  const buttons = [
-    { placement: 'left' as Placement, label: 'Left Drawer' },
-    { placement: 'right' as Placement, label: 'Right Drawer' },
-    { placement: 'top' as Placement, label: 'Top Drawer' },
-    { placement: 'bottom' as Placement, label: 'Bottom Drawer' },
-  ];
+  const buttons: Array<{ placement: Placement; label: string }> = [
+    { placement: 'left', label: 'Left Drawer' },
+    { placement: 'right', label: 'Right Drawer' },
+    { placement: 'top', label: 'Top Drawer' },
+    { placement: 'bottom', label: 'Bottom Drawer' },
+  ];

42-42: 移除冗余断言

placement 已是 Placement 类型,无需再次断言。

-        placement={placement as Placement}
+        placement={placement}

30-36: 给按钮添加 type="button" 以避免在 Form 环境误触发提交

示例中按钮若被嵌入到 form 内,默认 type="submit" 可能触发表单提交。加上 type="button" 更稳妥。

-          <button
+          <button
+            type="button"
             key={placement}
             onClick={() => openDrawer(placement)}
             style={{ padding: '8px 16px' }}
           >
src/DrawerPopup.tsx (3)

347-366: 在拖拽时禁用过渡已处理,但建议对 width/height 的单位与数值混用做防御

当前在 currentSize 存在时用数值覆盖 width/height,与可能的字符串(如 '20vw')互斥,这符合预期。但在开启拖拽后从一个字符串单位切换为纯数值时,视觉上会突然以 px 为单位进行变化,这是可接受的设计权衡。若要更平滑,可以在开始拖拽时解析并固定为像素基准(可选)。


298-313: maxSize 计算仅依赖 parentElement 尺寸,嵌套/inline 场景需再确认

wrapperRef.current.parentElement?.getBoundingClientRect()getContainer={false} 或复杂嵌套下可能不是你期望的可用空间(例如父级有 padding/滚动容器)。建议后续结合实际容器(portal 容器或视口)确认,或暴露 maxSize/getMaxSize 参数以供高级用法覆盖。


416-417: 拖拽手柄无语义/无可访问性支持,建议增加角色与可见文本隐藏说明(可选)

可考虑为手柄添加 role="separator"aria-orientation,并通过 aria-labeltitle 提示“拖拽以调整尺寸”。键盘可达的可调整大小(如使用左右/上下箭头)属于更高阶改进,可择机迭代。

src/hooks/useDrag.ts (1)

1-26: 建议新增 Pointer 事件支持以兼容触屏设备(可选)

当前仅监听 mouse 事件。实际在移动端/触摸屏上会缺乏交互。可以使用 Pointer 事件统一处理(pointerdown/move/up),或补充 touch* 事件。

📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1545c74 and e16a142.

📒 Files selected for processing (6)
  • assets/index.less (2 hunks)
  • docs/examples/resizable.tsx (1 hunks)
  • src/DrawerPopup.tsx (5 hunks)
  • src/hooks/useDrag.ts (1 hunks)
  • src/inter.ts (1 hunks)
  • tests/index.spec.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/index.spec.tsx
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/hooks/useDrag.ts (1)
src/DrawerPopup.tsx (1)
  • Placement (26-26)
src/DrawerPopup.tsx (1)
src/hooks/useDrag.ts (1)
  • useDrag (28-161)
docs/examples/resizable.tsx (4)
docs/examples/getContainer-false.tsx (1)
  • open (21-114)
src/DrawerPopup.tsx (1)
  • Placement (26-26)
src/index.ts (1)
  • Placement (5-5)
src/Drawer.tsx (1)
  • Placement (15-15)
🔇 Additional comments (5)
assets/index.less (1)

30-35: content-wrapper 注释掉 overflow: hidden 的影响需要确认

这里将 overflow: hidden; 注释掉(Line 33)。结合下方第二块样式中顶层容器仍是 overflow: hidden;,以及组件运行时又通过内联样式动态设置 overflow,可能出现拖拽手柄被裁剪或滚动条出现的不一致行为。

建议:明确策略(例如“仅在 resizable 时让 wrapper overflow: visible,其余场景 hidden”),避免多个层级对 overflow 的相互覆盖造成视觉/命中异常。配合组件代码修正(参见 DrawerPopup.tsx 对 overflow 的设置问题)。

docs/examples/resizable.tsx (1)

8-8: 确认路径别名是否在示例构建环境中可用

import type { Placement } from '@/index'; 依赖 @ 路径别名。若 docs 示例单独构建或运行,需要确保 tsconfig/webpack 等已声明 paths/alias。

如需验证,请检查根目录下 tsconfig/构建配置是否有 @/* 的 alias 映射到 src/*

src/hooks/useDrag.ts (3)

28-41: 适配新签名,内部统一从 ref 读取容器

[ suggest_essential_refactor ]

 export default function useDrag(options: UseDragOptions): UseDragReturn {
   const {
     prefixCls = 'resizable',
     direction,
     className,
     style,
     minSize = 100,
     maxSize,
     disabled = false,
-    container,
+    containerRef,
     onResize,
     onResizeEnd,
     onResizeStart,
   } = options;

64-73: mousedown 时从 ref 读取容器并回调 startSize

[ suggest_essential_refactor ]

-      // Get the current size of the container
-      if (container) {
-        const rect = container.getBoundingClientRect();
+      // Get the current size of the container
+      const container = containerRef?.current;
+      if (container) {
+        const rect = container.getBoundingClientRect();
         const currentSize = isHorizontal ? rect.width : rect.height;
         setStartSize(currentSize);
         onResizeStart?.(currentSize);
       }
     },
-    [disabled, isHorizontal, container, onResizeStart],
+    [disabled, isHorizontal, containerRef, onResizeStart],

113-125: mouseup 时同样从 ref 读取容器最终尺寸

[ suggest_essential_refactor ]

-  const handleMouseUp = React.useCallback(() => {
+  const handleMouseUp = React.useCallback(() => {
     if (isDragging && !disabled) {
       setIsDragging(false);

       // Get the final size after resize
-      if (container) {
-        const rect = container.getBoundingClientRect();
+      const container = containerRef?.current;
+      if (container) {
+        const rect = container.getBoundingClientRect();
         const finalSize = isHorizontal ? rect.width : rect.height;
         onResizeEnd?.(finalSize);
       }
     }
-  }, [isDragging, disabled, container, onResizeEnd, isHorizontal]);
+  }, [isDragging, disabled, containerRef, onResizeEnd, isHorizontal]);

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/DrawerPopup.tsx (2)

358-362: overflow 样式设置逻辑可能需要调整

当前实现中,resizabletrue 时设置 overflow: 'visible',这可能会导致内容溢出。建议保持 overflow: 'hidden',因为内部内容区域已经有独立的滚动处理。

 if (resizable) {
-  style.overflow = 'visible';
+  style.overflow = 'hidden';
 } else {
   style.overflow = 'hidden';
 }

333-345: 容器引用传递问题会导致拖拽起始尺寸测量失败

当前通过 container: wrapperRef.current 传递的是值而非引用,首次渲染时 wrapperRef.currentnull,这会导致 useDrag hook 内部无法正确获取容器元素,进而影响拖拽尺寸的计算。

修改为传递 ref 引用:

 const { dragElementProps, isDragging } = useDrag({
   prefixCls: `${prefixCls}-resizable`,
   direction: placement,
   className: drawerClassNames?.dragger,
   style: styles?.dragger,
   minSize: 0,
   maxSize,
   disabled: !resizable,
-  container: wrapperRef.current,
+  containerRef: wrapperRef,
   onResize: handleResize,
   onResizeStart: handleResizeStart,
   onResizeEnd: handleResizeEnd,
 });

同时需要更新 useDrag hook 的接口定义,将 container 参数改为 containerRef: React.RefObject<HTMLElement>

🧹 Nitpick comments (3)
src/DrawerPopup.tsx (3)

302-312: calculateMaxSize 可能在父容器未渲染时计算不准确

calculateMaxSize 方法依赖于父容器的尺寸,但在某些情况下(如初始渲染或父容器尺寸变化)可能获取不到准确的尺寸。建议添加边界检查和重试机制。

 const calculateMaxSize = React.useCallback(() => {
   if (wrapperRef.current) {
     const rect = wrapperRef.current.parentElement?.getBoundingClientRect();
+    if (!rect || rect.width === 0 || rect.height === 0) {
+      // 延迟重试,等待容器渲染完成
+      requestAnimationFrame(() => calculateMaxSize());
+      return;
+    }
     const newMaxSize =
       placement === 'left' || placement === 'right'
         ? (rect?.width ?? 0)
         : (rect?.height ?? 0);
     setMaxSize(newMaxSize);
   }
 }, [placement]);

368-370: 需要监听容器尺寸变化

当前仅在初始化时计算 maxSize,如果容器尺寸发生变化(如窗口大小调整),maxSize 不会更新。建议添加 ResizeObserver 监听容器尺寸变化。

 // Initialize maxSize calculation
 React.useEffect(() => {
   calculateMaxSize();
+  
+  if (!wrapperRef.current?.parentElement) return;
+  
+  const resizeObserver = new ResizeObserver(() => {
+    calculateMaxSize();
+  });
+  
+  resizeObserver.observe(wrapperRef.current.parentElement);
+  
+  return () => {
+    resizeObserver.disconnect();
+  };
 }, [calculateMaxSize]);

416-416: 拖拽手柄需要添加无障碍属性

拖拽手柄缺少必要的无障碍属性,如 rolearia-label 等,这会影响屏幕阅读器用户的使用体验。

-{resizable && <div {...dragElementProps} />}
+{resizable && (
+  <div 
+    {...dragElementProps}
+    role="separator"
+    aria-label="调整抽屉大小"
+    aria-orientation={placement === 'left' || placement === 'right' ? 'vertical' : 'horizontal'}
+    aria-valuemin={0}
+    aria-valuemax={maxSize}
+    aria-valuenow={currentSize}
+    tabIndex={0}
+  />
+)}
📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e16a142 and dac7c38.

📒 Files selected for processing (2)
  • docs/examples/assets/motion.less (1 hunks)
  • src/DrawerPopup.tsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/examples/assets/motion.less
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/DrawerPopup.tsx (1)
src/hooks/useDrag.ts (1)
  • useDrag (28-161)

Copy link

codecov bot commented Aug 15, 2025

Codecov Report

❌ Patch coverage is 95.83333% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.31%. Comparing base (2418e05) to head (eb6caef).

Files with missing lines Patch % Lines
src/hooks/useDrag.ts 92.15% 4 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##            master     #528      +/-   ##
===========================================
- Coverage   100.00%   98.31%   -1.69%     
===========================================
  Files            5        6       +1     
  Lines          144      237      +93     
  Branches        53       82      +29     
===========================================
+ Hits           144      233      +89     
- Misses           0        4       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
README.md (1)

74-76: onResize/Start/End 描述存在误导,建议更正措辞并明确返回参数含义

  • onResize 的描述明显是从键盘事件复制而来,容易误解。
  • 建议明确 size 的语义(px,且随 placement 决定是宽度或高度),并统一三者的触发时机说明。

可在 README 中对这三行做如下修改:

-| onResize           | (size: number) => void                                                      | -                                      | Trigger when mouse keyup on drawer panel
+| onResize           | (size: number) => void                                                      | -                                      | Fires while resizing via dragging. size is current width/height in px depending on placement.
-| onResizeStart      | () => void                                                                  | -                                      | Trigger when resize starts
+| onResizeStart      | () => void                                                                  | -                                      | Fires when resizing starts (mouse/touch down on the dragger).
-| onResizeEnd        | () => void                                                                  | -                                      | Trigger when resize ends
+| onResizeEnd        | () => void                                                                  | -                                      | Fires when resizing ends (mouse/touch up). Use onResize for latest size.

如实现里希望在结束时也拿到最终尺寸,可考虑将 onResizeEnd 的签名扩展为 (size: number) => void(需与实现保持一致后再改文档)。

📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5341916 and 5592224.

📒 Files selected for processing (1)
  • README.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md

[grammar] ~68-~68: There might be a mistake here.
Context: ... | | onMouseOver | React.MouseEventH...

(QB_NEW_EN)

@@ -64,12 +64,16 @@ ReactDom.render(
| onClose | func | null | close click function |
| keyboard | boolean | true | Whether support press esc to close |
| autoFocus | boolean | true | Whether focusing on the drawer after it opened |
| resizable | boolean | false | Whether the drawer can be resized by dragging |
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

新增 resizable 文档项不错,但建议补充使用细节与相关属性

当前描述过于笼统,建议在 README 中补充:

  • 明确 size 的单位与维度:left/right 时代表宽度(px),top/bottom 时代表高度(px)。
  • 若实现里支持最小/最大尺寸约束(min/max),请在 API 表格中新增相应 props 并说明默认值与范围。
  • 在 classNames/styles 中补充 dragger 键(例如 classNames.dragger、styles.dragger),以便自定义拖拽手柄区域样式。
  • 简述触摸端支持与可访问性提示(例如“仅通过拖拽手柄进行尺寸调整,支持鼠标与触摸”)。

如需在本 PR 一并完善 README,可参考下方验证脚本先确认实现侧是否存在上述能力与键名。


🏁 Script executed:

#!/bin/bash
# 验证是否存在与文档匹配的 API 能力,便于补充 README

set -euo pipefail

echo "== 搜索是否存在最小/最大尺寸约束相关实现(min/max/limit 等) =="
rg -nP -C2 '(min(Size|Width|Height)|max(Size|Width|Height)|limit(Size|Width|Height)|min|max)' --type=ts --type=tsx

echo "== 搜索是否存在 dragger 相关的类名或样式键 =="
rg -nP -C3 '\bdragger\b' --type=ts --type=tsx --type=less --type=css

echo "== 搜索 DrawerProps 是否包含 resizable 相关字段与回调 =="
ast-grep --pattern $'export (interface|type) DrawerProps { $$$ resizable?: $_; $$$ onResize?: $_; $$$ onResizeStart?: $_; $$$ onResizeEnd?: $_; $$$ }'

Length of output: 259


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== 搜索 min/max 相关属性 (minSize/minWidth/minHeight/maxSize/maxWidth/maxHeight 等) =="
rg -nP -C2 '\b(min(Size|Width|Height)|max(Size|Width|Height)|minWidth|minHeight|maxWidth|maxHeight|minSize|maxSize)\b' || true

echo "== 搜索 dragger 相关关键字(类名 / styles / classNames) =="
rg -nP -C3 '\bdragger\b|\.dragger\b|classNames\.dragger|styles\.dragger' || true

echo "== 搜索 resizable 与回调(resizable/onResize/onResizeStart/onResizeEnd) =="
rg -nP -C3 '\bresizable\b|onResize\b|onResizeStart\b|onResizeEnd\b' || true

echo "== 搜索 DrawerProps 定义或导出 =="
rg -nP -C3 'export\s+(interface|type)\s+DrawerProps\b|type\s+DrawerProps\b|interface\s+DrawerProps\b' || true

Length of output: 24230


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== src/hooks/useDrag.ts (head) =="
sed -n '1,240p' src/hooks/useDrag.ts || true

echo
echo "== 搜索 touch/pointer 关键词 in src/hooks/useDrag.ts =="
rg -n 'touch|pointer|touchstart|touchmove|pointerdown|pointermove|pointerup' src/hooks/useDrag.ts || true

echo
echo "== src/DrawerPopup.tsx (useDrag 调用与渲染区域) =="
sed -n '1,220p' src/DrawerPopup.tsx || true
sed -n '320,460p' src/DrawerPopup.tsx || true

echo
echo "== src/Drawer.tsx (Props 定义) =="
sed -n '1,160p' src/Drawer.tsx || true

echo
echo "== src/inter.ts =="
sed -n '1,160p' src/inter.ts || true

echo
echo "== assets/index.less (dragger 样式) =="
sed -n '1,140p' assets/index.less || true

echo
echo "== README.md (resizable 相关行) =="
sed -n '60,90p' README.md || true

Length of output: 24828


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== 查找 parseWidthHeight 定义 =="
rg -n "parseWidthHeight" || true

echo
echo "== 打印 util 文件内容 =="
sed -n '1,240p' src/util.ts || sed -n '1,240p' src/util.tsx || true

Length of output: 1295


请完善 README:补充 resizable 的使用细节(已核验实现)

已核验代码实现,结论与建议如下——请按实现补充 README 中的 resizable 文档:

  • 单位与类型

    • 回调 onResize 接收的 size 为像素数(number)。width/height 可接 number 或数值字符串;纯数字字符串会被转为 number 并发出警告(见 src/util.ts: parseWidthHeight)。建议在 README 明确“size 单位为 px;width/height 可为 number 或数值字符串(字符串会被转换)”。
  • 最小 / 最大尺寸约束(行为说明)

    • 当前没有对外暴露 minSize/maxSize props。实现细节:DrawerPopup 在调用 useDrag 时传入 minSize: 0,maxSize 由 calculateMaxSize() 根据容器尺寸计算(见 src/DrawerPopup.tsx)。useDrag 本身支持 minSize/maxSize(见 src/hooks/useDrag.ts)。建议在文档中说明默认行为(min=0,max=受父容器宽/高限制),并说明若要暴露自定义 min/max 应新增 props 并在 README 标注默认值与范围。
  • classNames / styles 键(可自定义拖拽手柄)

    • 已存在键:DrawerClassNames.drawer?.dragger 与 DrawerStyles.dragger(见 src/inter.ts)。默认 CSS 类为 .rc-drawer-resizable-dragger 及其修饰符(-left/-right/-top/-bottom,-dragging,-horizontal/-vertical),样式位于 assets/index.less。请在 API 表格中新增 classNames.dragger 与 styles.dragger,并列出默认类名与常见修饰符,示例如何覆盖样式。
  • 触摸 / 指针 与可访问性

    • 当前实现仅使用鼠标事件(useDrag 通过 onMouseDown + document mousemove/mouseup,未绑定 touch/pointer 或键盘事件,见 src/hooks/useDrag.ts),移动端触摸与键盘调整未实现。建议在 README 标注“当前仅支持鼠标拖拽”,并给出可选项(例如实现 pointer/touch 事件、添加键盘交互与 ARIA 属性)的说明或待办。
  • 参考与示例位置(便于写文档)

    • 示例与测试: docs/examples/resizable.tsx、docs/demo/resizable.md、tests/index.spec.tsx(含 min/max 与 dragger 测试)。
    • 主要实现参考文件:src/DrawerPopup.tsx(useDrag 调用、min/max 计算、渲染 dragger)、src/hooks/useDrag.ts(drag 行为)、src/inter.ts(classNames/styles 定义)、assets/index.less(默认 dragger 样式)。
    • README 当前位置:README.md(resizable 条目在约第 67 行)。

请根据以上事实在 README 中补充说明(或把部分行为改为可配置后再文档化)。

🤖 Prompt for AI Agents
在 README.md 大约第 67 行,resizable 一项缺少使用细节;请按实现补充文档:说明 onResize 回调的 size 单位为
px,width/height 可为 number 或数值字符串(纯数字字符串会被转换并发出警告);说明当前没有对外 props 控制
minSize/maxSize,默认 min=0,max 由容器计算(受父容器宽/高限制),如需自定义应新增并文档化相应 props 和默认值/范围;在 API
表格中新增 classNames.dragger 与 styles.dragger,列出默认类名 rc-drawer-resizable-dragger
及其修饰符(-left/-right/-top/-bottom,-dragging,-horizontal/-vertical)并示例如何覆盖样式;明确当前仅支持鼠标拖拽(无
touch/pointer/键盘 无 ARIA),并给出可选改进(pointer/touch 事件、键盘交互与
ARIA)作为待办;在文档末附上参考示例和实现文件路径:docs/examples/resizable.tsx、docs/demo/resizable.md、tests/index.spec.tsx、src/DrawerPopup.tsx、src/hooks/useDrag.ts、src/inter.ts、assets/index.less。

@thinkasany
Copy link
Contributor

image

@QdabuliuQ
Copy link
Author

image

这个ci只要我提交代码就会自动触发吗?还是需要你们来触发?

@thinkasany
Copy link
Contributor

这个ci只要我提交代码就会自动触发吗?还是需要你们来触发?

害~ 首次提交好像限制了,必须人工 ap,我问问

@dmqweb
Copy link

dmqweb commented Aug 16, 2025

写的太棒了,把cursor滚动也考虑到了,不过目前resizable时由于是visiable可能会有点异常
image
index.less中将外层的pointer-events禁止了可能会造成内部元素事件失效,这一块为什么禁止有大佬告知下吗

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.

4 participants