@rc-component/drawer 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,6 +49,8 @@ ReactDom.render(
49
49
  | prefixCls | string | 'drawer' | prefix class |
50
50
  | width | string \| number | null | drawer content wrapper width, drawer level transition width |
51
51
  | height | string \| number | null | drawer content wrapper height, drawer level transition height |
52
+ | defaultWidth | string \| number | null | default width for uncontrolled resizable drawer |
53
+ | defaultHeight | string \| number | null | default height for uncontrolled resizable drawer |
52
54
  | open | boolean | false | open or close menu |
53
55
  | defaultOpen | boolean | false | default open menu |
54
56
  | placement | string | `left` | `left` `top` `right` `bottom` |
@@ -64,6 +66,7 @@ ReactDom.render(
64
66
  | onClose | func | null | close click function |
65
67
  | keyboard | boolean | true | Whether support press esc to close |
66
68
  | autoFocus | boolean | true | Whether focusing on the drawer after it opened |
69
+ | resizable | { onResize?: (size: number) => void; onResizeStart?: () => void; onResizeEnd?: () => void; } | - | Resizable configuration with optional callbacks |
67
70
  | onMouseEnter | React.MouseEventHandler\<HTMLDivElement\> | - | Trigger when mouse enter drawer panel |
68
71
  | onMouseOver | React.MouseEventHandler\<HTMLDivElement\> | - | Trigger when mouse over drawer panel |
69
72
  | onMouseLeave | React.MouseEventHandler\<HTMLDivElement\> | - | Trigger when mouse leave drawer panel |
package/assets/index.css CHANGED
@@ -17,7 +17,6 @@
17
17
  .rc-drawer-content-wrapper {
18
18
  position: absolute;
19
19
  z-index: 1050;
20
- overflow: hidden;
21
20
  transition: transform 0.3s;
22
21
  }
23
22
  .rc-drawer-content-wrapper-hidden {
@@ -40,3 +39,234 @@
40
39
  background: #fff;
41
40
  pointer-events: auto;
42
41
  }
42
+ .rc-drawer-resizable-dragger {
43
+ position: absolute;
44
+ z-index: 2;
45
+ pointer-events: auto;
46
+ }
47
+ .rc-drawer-resizable-dragger:hover {
48
+ background-color: #1890ff !important;
49
+ }
50
+ .rc-drawer-resizable-dragger-dragging {
51
+ background-color: #1890ff !important;
52
+ }
53
+ .rc-drawer-resizable-dragger-left {
54
+ top: 0;
55
+ bottom: 0;
56
+ right: -3px;
57
+ width: 6px;
58
+ cursor: ew-resize;
59
+ }
60
+ .rc-drawer-resizable-dragger-right {
61
+ top: 0;
62
+ bottom: 0;
63
+ left: -3px;
64
+ width: 6px;
65
+ cursor: ew-resize;
66
+ }
67
+ .rc-drawer-resizable-dragger-top {
68
+ left: 0;
69
+ right: 0;
70
+ bottom: -3px;
71
+ height: 6px;
72
+ cursor: ns-resize;
73
+ }
74
+ .rc-drawer-resizable-dragger-bottom {
75
+ left: 0;
76
+ right: 0;
77
+ top: -3px;
78
+ height: 6px;
79
+ cursor: ns-resize;
80
+ }
81
+ .rc-drawer {
82
+ overflow: hidden;
83
+ z-index: 9999;
84
+ transition: width 0s ease 0.3s, height 0s ease 0.3s, transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
85
+ }
86
+ .rc-drawer > * {
87
+ transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86), opacity 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86), box-shadow 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
88
+ }
89
+ .rc-drawer.rc-drawer-open {
90
+ transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
91
+ }
92
+ .rc-drawer .rc-drawer-mask {
93
+ background: #000;
94
+ opacity: 0;
95
+ width: 100%;
96
+ height: 0;
97
+ position: absolute;
98
+ top: 0;
99
+ left: 0;
100
+ transition: opacity 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86), height 0s ease 0.3s;
101
+ }
102
+ .rc-drawer-content-wrapper {
103
+ position: absolute;
104
+ background: #fff;
105
+ }
106
+ .rc-drawer-content {
107
+ overflow: auto;
108
+ z-index: 1;
109
+ position: relative;
110
+ }
111
+ .rc-drawer-handle {
112
+ position: absolute;
113
+ top: 72px;
114
+ width: 41px;
115
+ height: 40px;
116
+ cursor: pointer;
117
+ z-index: 0;
118
+ text-align: center;
119
+ line-height: 40px;
120
+ font-size: 16px;
121
+ display: flex;
122
+ justify-content: center;
123
+ align-items: center;
124
+ background: #fff;
125
+ }
126
+ .rc-drawer-handle-icon {
127
+ width: 14px;
128
+ height: 2px;
129
+ background: #333;
130
+ position: relative;
131
+ transition: background 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
132
+ }
133
+ .rc-drawer-handle-icon::before,
134
+ .rc-drawer-handle-icon::after {
135
+ content: '';
136
+ display: block;
137
+ position: absolute;
138
+ background: #333;
139
+ width: 100%;
140
+ height: 2px;
141
+ transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
142
+ }
143
+ .rc-drawer-handle-icon::before {
144
+ top: -5px;
145
+ }
146
+ .rc-drawer-handle-icon::after {
147
+ top: 5px;
148
+ }
149
+ .rc-drawer-left,
150
+ .rc-drawer-right {
151
+ width: 0%;
152
+ height: 100%;
153
+ }
154
+ .rc-drawer-left .rc-drawer-content-wrapper,
155
+ .rc-drawer-right .rc-drawer-content-wrapper,
156
+ .rc-drawer-left .rc-drawer-content,
157
+ .rc-drawer-right .rc-drawer-content {
158
+ height: 100%;
159
+ }
160
+ .rc-drawer-left.rc-drawer-open,
161
+ .rc-drawer-right.rc-drawer-open {
162
+ width: 100%;
163
+ }
164
+ .rc-drawer-left.rc-drawer-open.no-mask,
165
+ .rc-drawer-right.rc-drawer-open.no-mask {
166
+ width: 0%;
167
+ }
168
+ .rc-drawer-left {
169
+ top: 0;
170
+ left: 0;
171
+ }
172
+ .rc-drawer-left .rc-drawer-handle {
173
+ right: -40px;
174
+ box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
175
+ border-radius: 0 4px 4px 0;
176
+ }
177
+ .rc-drawer-left.rc-drawer-open .rc-drawer-content-wrapper {
178
+ box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
179
+ }
180
+ .rc-drawer-right {
181
+ top: 0;
182
+ right: 0;
183
+ }
184
+ .rc-drawer-right .rc-drawer-content-wrapper {
185
+ right: 0;
186
+ }
187
+ .rc-drawer-right .rc-drawer-handle {
188
+ left: -40px;
189
+ box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
190
+ border-radius: 4px 0 0 4px;
191
+ }
192
+ .rc-drawer-right.rc-drawer-open .rc-drawer-content-wrapper {
193
+ box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
194
+ }
195
+ .rc-drawer-right.rc-drawer-open.no-mask {
196
+ right: 1px;
197
+ transform: translateX(1px);
198
+ }
199
+ .rc-drawer-top,
200
+ .rc-drawer-bottom {
201
+ width: 100%;
202
+ height: 0%;
203
+ }
204
+ .rc-drawer-top .rc-drawer-content-wrapper,
205
+ .rc-drawer-bottom .rc-drawer-content-wrapper,
206
+ .rc-drawer-top .rc-drawer-content,
207
+ .rc-drawer-bottom .rc-drawer-content {
208
+ width: 100%;
209
+ }
210
+ .rc-drawer-top .rc-drawer-content,
211
+ .rc-drawer-bottom .rc-drawer-content {
212
+ height: 100%;
213
+ }
214
+ .rc-drawer-top.rc-drawer-open,
215
+ .rc-drawer-bottom.rc-drawer-open {
216
+ height: 100%;
217
+ }
218
+ .rc-drawer-top.rc-drawer-open.no-mask,
219
+ .rc-drawer-bottom.rc-drawer-open.no-mask {
220
+ height: 0%;
221
+ }
222
+ .rc-drawer-top .rc-drawer-handle,
223
+ .rc-drawer-bottom .rc-drawer-handle {
224
+ left: 50%;
225
+ margin-left: -20px;
226
+ }
227
+ .rc-drawer-top {
228
+ top: 0;
229
+ left: 0;
230
+ }
231
+ .rc-drawer-top .rc-drawer-handle {
232
+ top: auto;
233
+ bottom: -40px;
234
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
235
+ border-radius: 0 0 4px 4px;
236
+ }
237
+ .rc-drawer-top.rc-drawer-open .rc-drawer-content-wrapper {
238
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
239
+ }
240
+ .rc-drawer-bottom {
241
+ bottom: 0;
242
+ left: 0;
243
+ }
244
+ .rc-drawer-bottom .rc-drawer-content-wrapper {
245
+ bottom: 0;
246
+ }
247
+ .rc-drawer-bottom .rc-drawer-handle {
248
+ top: -40px;
249
+ box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);
250
+ border-radius: 4px 4px 0 0;
251
+ }
252
+ .rc-drawer-bottom.rc-drawer-open .rc-drawer-content-wrapper {
253
+ box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);
254
+ }
255
+ .rc-drawer-bottom.rc-drawer-open.no-mask {
256
+ bottom: 1px;
257
+ transform: translateY(1px);
258
+ }
259
+ .rc-drawer.rc-drawer-open .rc-drawer-mask {
260
+ opacity: 0.3;
261
+ height: 100%;
262
+ transition: opacity 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
263
+ }
264
+ .rc-drawer.rc-drawer-open .rc-drawer-handle-icon {
265
+ background: transparent;
266
+ }
267
+ .rc-drawer.rc-drawer-open .rc-drawer-handle-icon::before {
268
+ transform: translateY(5px) rotate(45deg);
269
+ }
270
+ .rc-drawer.rc-drawer-open .rc-drawer-handle-icon::after {
271
+ transform: translateY(-5px) rotate(-45deg);
272
+ }
package/es/Drawer.d.ts CHANGED
@@ -8,11 +8,31 @@ export interface DrawerProps extends Omit<DrawerPopupProps, 'prefixCls' | 'inlin
8
8
  prefixCls?: string;
9
9
  open?: boolean;
10
10
  onClose?: (e: React.MouseEvent | React.KeyboardEvent) => void;
11
- destroyOnClose?: boolean;
11
+ destroyOnHidden?: boolean;
12
12
  getContainer?: PortalProps['getContainer'];
13
13
  panelRef?: React.Ref<HTMLDivElement>;
14
14
  classNames?: DrawerClassNames;
15
15
  styles?: DrawerStyles;
16
+ /**
17
+ * @deprecated Use `size` instead. Will be removed in next major version.
18
+ */
19
+ width?: number | string;
20
+ /**
21
+ * @deprecated Use `size` instead. Will be removed in next major version.
22
+ */
23
+ height?: number | string;
24
+ /** Size of the drawer (width for left/right placement, height for top/bottom placement) */
25
+ size?: number | string;
26
+ /** Maximum size of the drawer */
27
+ maxSize?: number;
28
+ /** Default size for uncontrolled resizable drawer */
29
+ defaultSize?: number | string;
30
+ /** Resizable configuration - object with optional callbacks */
31
+ resizable?: {
32
+ onResize?: (size: number) => void;
33
+ onResizeStart?: () => void;
34
+ onResizeEnd?: () => void;
35
+ };
16
36
  }
17
37
  declare const Drawer: React.FC<DrawerProps>;
18
38
  export default Drawer;
package/es/Drawer.js CHANGED
@@ -11,19 +11,24 @@ const Drawer = props => {
11
11
  placement = 'right',
12
12
  autoFocus = true,
13
13
  keyboard = true,
14
- width = 378,
14
+ width,
15
+ height,
16
+ size,
17
+ maxSize,
15
18
  mask = true,
16
19
  maskClosable = true,
17
20
  getContainer,
18
21
  forceRender,
19
22
  afterOpenChange,
20
- destroyOnClose,
23
+ destroyOnHidden,
21
24
  onMouseEnter,
22
25
  onMouseOver,
23
26
  onMouseLeave,
24
27
  onClick,
25
28
  onKeyDown,
26
29
  onKeyUp,
30
+ resizable,
31
+ defaultSize,
27
32
  // Refs
28
33
  panelRef
29
34
  } = props;
@@ -67,7 +72,7 @@ const Drawer = props => {
67
72
  }), [panelRef]);
68
73
 
69
74
  // ============================ Render ============================
70
- if (!forceRender && !animatedVisible && !mergedOpen && destroyOnClose) {
75
+ if (!forceRender && !animatedVisible && !mergedOpen && destroyOnHidden) {
71
76
  return null;
72
77
  }
73
78
  const eventHandlers = {
@@ -86,11 +91,16 @@ const Drawer = props => {
86
91
  autoFocus,
87
92
  keyboard,
88
93
  width,
94
+ height,
95
+ size,
96
+ maxSize,
97
+ defaultSize,
89
98
  mask,
90
99
  maskClosable,
91
100
  inline: getContainer === false,
92
101
  afterOpenChange: internalAfterOpenChange,
93
102
  ref: popupRef,
103
+ resizable,
94
104
  ...eventHandlers
95
105
  };
96
106
  return /*#__PURE__*/React.createElement(RefContext.Provider, {
@@ -19,8 +19,5 @@ export interface DrawerPanelProps extends DrawerPanelEvents, DrawerPanelAccessib
19
19
  children?: React.ReactNode;
20
20
  containerRef?: React.Ref<HTMLDivElement>;
21
21
  }
22
- declare const DrawerPanel: {
23
- (props: DrawerPanelProps): React.JSX.Element;
24
- displayName: string;
25
- };
22
+ declare const DrawerPanel: React.FC<Readonly<DrawerPanelProps>>;
26
23
  export default DrawerPanel;
@@ -24,6 +24,10 @@ export interface DrawerPopupProps extends DrawerPanelEvents, DrawerPanelAccessib
24
24
  children?: React.ReactNode;
25
25
  width?: number | string;
26
26
  height?: number | string;
27
+ /** Size of the drawer (width for left/right placement, height for top/bottom placement) */
28
+ size?: number | string;
29
+ /** Maximum size of the drawer */
30
+ maxSize?: number;
27
31
  mask?: boolean;
28
32
  maskClosable?: boolean;
29
33
  maskClassName?: string;
@@ -35,6 +39,13 @@ export interface DrawerPopupProps extends DrawerPanelEvents, DrawerPanelAccessib
35
39
  classNames?: DrawerClassNames;
36
40
  styles?: DrawerStyles;
37
41
  drawerRender?: (node: React.ReactNode) => React.ReactNode;
42
+ /** Default size for uncontrolled resizable drawer */
43
+ defaultSize?: number | string;
44
+ resizable?: {
45
+ onResize?: (size: number) => void;
46
+ onResizeStart?: () => void;
47
+ onResizeEnd?: () => void;
48
+ };
38
49
  }
39
50
  declare const RefDrawerPopup: React.ForwardRefExoticComponent<DrawerPopupProps & React.RefAttributes<HTMLDivElement>>;
40
51
  export default RefDrawerPopup;
package/es/DrawerPopup.js CHANGED
@@ -6,7 +6,9 @@ import pickAttrs from "@rc-component/util/es/pickAttrs";
6
6
  import * as React from 'react';
7
7
  import DrawerContext from "./context";
8
8
  import DrawerPanel from "./DrawerPanel";
9
+ import useDrag from "./hooks/useDrag";
9
10
  import { parseWidthHeight } from "./util";
11
+ import { useEvent } from '@rc-component/util';
10
12
  const sentinelStyle = {
11
13
  width: 0,
12
14
  height: 0,
@@ -14,7 +16,7 @@ const sentinelStyle = {
14
16
  outline: 'none',
15
17
  position: 'absolute'
16
18
  };
17
- function DrawerPopup(props, ref) {
19
+ const DrawerPopup = (props, ref) => {
18
20
  const {
19
21
  prefixCls,
20
22
  open,
@@ -37,6 +39,8 @@ function DrawerPopup(props, ref) {
37
39
  motion,
38
40
  width,
39
41
  height,
42
+ size,
43
+ maxSize,
40
44
  children,
41
45
  // Mask
42
46
  mask,
@@ -54,7 +58,9 @@ function DrawerPopup(props, ref) {
54
58
  onKeyDown,
55
59
  onKeyUp,
56
60
  styles,
57
- drawerRender
61
+ drawerRender,
62
+ resizable,
63
+ defaultSize
58
64
  } = props;
59
65
 
60
66
  // ================================ Refs ================================
@@ -147,10 +153,10 @@ function DrawerPopup(props, ref) {
147
153
  }, []);
148
154
 
149
155
  // ============================ Mask ============================
150
- const maskNode = mask && /*#__PURE__*/React.createElement(CSSMotion, _extends({
156
+ const maskNode = /*#__PURE__*/React.createElement(CSSMotion, _extends({
151
157
  key: "mask"
152
158
  }, maskMotion, {
153
- visible: open
159
+ visible: mask && open
154
160
  }), ({
155
161
  className: motionMaskClassName,
156
162
  style: motionMaskStyle
@@ -167,28 +173,68 @@ function DrawerPopup(props, ref) {
167
173
 
168
174
  // =========================== Panel ============================
169
175
  const motionProps = typeof motion === 'function' ? motion(placement) : motion;
170
- const wrapperStyle = {};
171
- if (pushed && pushDistance) {
172
- switch (placement) {
173
- case 'top':
174
- wrapperStyle.transform = `translateY(${pushDistance}px)`;
175
- break;
176
- case 'bottom':
177
- wrapperStyle.transform = `translateY(${-pushDistance}px)`;
178
- break;
179
- case 'left':
180
- wrapperStyle.transform = `translateX(${pushDistance}px)`;
181
- break;
182
- default:
183
- wrapperStyle.transform = `translateX(${-pushDistance}px)`;
184
- break;
176
+
177
+ // ============================ Size ============================
178
+ const [currentSize, setCurrentSize] = React.useState();
179
+ const isHorizontal = placement === 'left' || placement === 'right';
180
+
181
+ // Aggregate size logic with backward compatibility using useMemo
182
+ const mergedSize = React.useMemo(() => {
183
+ const legacySize = isHorizontal ? width : height;
184
+ const nextMergedSize = size ?? legacySize ?? currentSize ?? defaultSize ?? (isHorizontal ? 378 : undefined);
185
+ return parseWidthHeight(nextMergedSize);
186
+ }, [size, width, height, defaultSize, isHorizontal, currentSize]);
187
+
188
+ // >>> Style
189
+ const wrapperStyle = React.useMemo(() => {
190
+ const nextWrapperStyle = {};
191
+ if (pushed && pushDistance) {
192
+ switch (placement) {
193
+ case 'top':
194
+ nextWrapperStyle.transform = `translateY(${pushDistance}px)`;
195
+ break;
196
+ case 'bottom':
197
+ nextWrapperStyle.transform = `translateY(${-pushDistance}px)`;
198
+ break;
199
+ case 'left':
200
+ nextWrapperStyle.transform = `translateX(${pushDistance}px)`;
201
+ break;
202
+ default:
203
+ nextWrapperStyle.transform = `translateX(${-pushDistance}px)`;
204
+ break;
205
+ }
185
206
  }
186
- }
187
- if (placement === 'left' || placement === 'right') {
188
- wrapperStyle.width = parseWidthHeight(width);
189
- } else {
190
- wrapperStyle.height = parseWidthHeight(height);
191
- }
207
+ if (isHorizontal) {
208
+ nextWrapperStyle.width = parseWidthHeight(mergedSize);
209
+ } else {
210
+ nextWrapperStyle.height = parseWidthHeight(mergedSize);
211
+ }
212
+ return nextWrapperStyle;
213
+ }, [pushed, pushDistance, placement, isHorizontal, mergedSize]);
214
+
215
+ // =========================== Resize ===========================
216
+ const wrapperRef = React.useRef(null);
217
+ const onInternalResize = useEvent(size => {
218
+ setCurrentSize(size);
219
+ resizable?.onResize?.(size);
220
+ });
221
+ const {
222
+ dragElementProps,
223
+ isDragging
224
+ } = useDrag({
225
+ prefixCls: `${prefixCls}-resizable`,
226
+ direction: placement,
227
+ className: drawerClassNames?.dragger,
228
+ style: styles?.dragger,
229
+ maxSize,
230
+ containerRef: wrapperRef,
231
+ currentSize: mergedSize,
232
+ onResize: onInternalResize,
233
+ onResizeStart: resizable?.onResizeStart,
234
+ onResizeEnd: resizable?.onResizeEnd
235
+ });
236
+
237
+ // =========================== Events ===========================
192
238
  const eventHandlers = {
193
239
  onMouseEnter,
194
240
  onMouseOver,
@@ -197,6 +243,9 @@ function DrawerPopup(props, ref) {
197
243
  onKeyDown,
198
244
  onKeyUp
199
245
  };
246
+
247
+ // =========================== Render ==========================
248
+ // >>>>> Panel
200
249
  const panelNode = /*#__PURE__*/React.createElement(CSSMotion, _extends({
201
250
  key: "panel"
202
251
  }, motionProps, {
@@ -224,18 +273,19 @@ function DrawerPopup(props, ref) {
224
273
  aria: true
225
274
  }), eventHandlers), children);
226
275
  return /*#__PURE__*/React.createElement("div", _extends({
227
- className: classNames(`${prefixCls}-content-wrapper`, drawerClassNames?.wrapper, motionClassName),
276
+ ref: wrapperRef,
277
+ className: classNames(`${prefixCls}-content-wrapper`, isDragging && `${prefixCls}-content-wrapper-dragging`, drawerClassNames?.wrapper, !isDragging && motionClassName),
228
278
  style: {
229
- ...wrapperStyle,
230
279
  ...motionStyle,
280
+ ...wrapperStyle,
231
281
  ...styles?.wrapper
232
282
  }
233
283
  }, pickAttrs(props, {
234
284
  data: true
235
- })), drawerRender ? drawerRender(content) : content);
285
+ })), resizable && /*#__PURE__*/React.createElement("div", dragElementProps), drawerRender ? drawerRender(content) : content);
236
286
  });
237
287
 
238
- // =========================== Render ===========================
288
+ // >>>>> Container
239
289
  const containerStyle = {
240
290
  ...rootStyle
241
291
  };
@@ -266,7 +316,7 @@ function DrawerPopup(props, ref) {
266
316
  "aria-hidden": "true",
267
317
  "data-sentinel": "end"
268
318
  })));
269
- }
319
+ };
270
320
  const RefDrawerPopup = /*#__PURE__*/React.forwardRef(DrawerPopup);
271
321
  if (process.env.NODE_ENV !== 'production') {
272
322
  RefDrawerPopup.displayName = 'DrawerPopup';
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+ import type { Placement } from '../Drawer';
3
+ export interface UseDragOptions {
4
+ prefixCls: string;
5
+ direction: Placement;
6
+ className?: string;
7
+ style?: React.CSSProperties;
8
+ maxSize?: number;
9
+ containerRef?: React.RefObject<HTMLElement>;
10
+ currentSize?: number | string;
11
+ onResize?: (size: number) => void;
12
+ onResizeEnd?: (size: number) => void;
13
+ onResizeStart?: (size: number) => void;
14
+ }
15
+ export interface UseDragReturn {
16
+ dragElementProps: {
17
+ className: string;
18
+ style: React.CSSProperties;
19
+ onMouseDown: (e: React.MouseEvent) => void;
20
+ };
21
+ isDragging: boolean;
22
+ }
23
+ export default function useDrag(options: UseDragOptions): UseDragReturn;
@@ -0,0 +1,98 @@
1
+ import * as React from 'react';
2
+ import classNames from 'classnames';
3
+ import { useEvent } from '@rc-component/util';
4
+ export default function useDrag(options) {
5
+ const {
6
+ prefixCls,
7
+ direction,
8
+ className,
9
+ style,
10
+ maxSize,
11
+ containerRef,
12
+ currentSize,
13
+ onResize,
14
+ onResizeEnd,
15
+ onResizeStart
16
+ } = options;
17
+ const [isDragging, setIsDragging] = React.useState(false);
18
+ const [startPos, setStartPos] = React.useState(0);
19
+ const [startSize, setStartSize] = React.useState(0);
20
+ const isHorizontal = direction === 'left' || direction === 'right';
21
+ const handleMouseDown = useEvent(e => {
22
+ e.preventDefault();
23
+ e.stopPropagation();
24
+ setIsDragging(true);
25
+ if (isHorizontal) {
26
+ setStartPos(e.clientX);
27
+ } else {
28
+ setStartPos(e.clientY);
29
+ }
30
+
31
+ // Use provided currentSize, or fallback to container size
32
+ let startSize;
33
+ if (typeof currentSize === 'number') {
34
+ startSize = currentSize;
35
+ } else if (containerRef?.current) {
36
+ const rect = containerRef.current.getBoundingClientRect();
37
+ startSize = isHorizontal ? rect.width : rect.height;
38
+ }
39
+ setStartSize(startSize);
40
+ onResizeStart?.(startSize);
41
+ });
42
+ const handleMouseMove = useEvent(e => {
43
+ if (!isDragging) return;
44
+ const currentPos = isHorizontal ? e.clientX : e.clientY;
45
+ let delta = currentPos - startPos;
46
+
47
+ // Adjust delta direction based on placement
48
+ if (direction === 'right' || direction === 'bottom') {
49
+ delta = -delta;
50
+ }
51
+ let newSize = startSize + delta;
52
+
53
+ // Apply min/max size limits
54
+ if (newSize < 0) {
55
+ newSize = 0;
56
+ }
57
+ // Only apply maxSize if it's a valid positive number
58
+ if (maxSize && newSize > maxSize) {
59
+ newSize = maxSize;
60
+ }
61
+ onResize?.(newSize);
62
+ });
63
+ const handleMouseUp = React.useCallback(() => {
64
+ if (isDragging) {
65
+ setIsDragging(false);
66
+
67
+ // Get the final size after resize
68
+ if (containerRef?.current) {
69
+ const rect = containerRef.current.getBoundingClientRect();
70
+ const finalSize = isHorizontal ? rect.width : rect.height;
71
+ onResizeEnd?.(finalSize);
72
+ }
73
+ }
74
+ }, [isDragging, containerRef, onResizeEnd, isHorizontal]);
75
+ React.useEffect(() => {
76
+ if (isDragging) {
77
+ document.addEventListener('mousemove', handleMouseMove);
78
+ document.addEventListener('mouseup', handleMouseUp);
79
+ return () => {
80
+ document.removeEventListener('mousemove', handleMouseMove);
81
+ document.removeEventListener('mouseup', handleMouseUp);
82
+ };
83
+ }
84
+ }, [isDragging, handleMouseMove, handleMouseUp]);
85
+ const dragElementClassName = classNames(`${prefixCls}-dragger`, `${prefixCls}-dragger-${direction}`, {
86
+ [`${prefixCls}-dragger-dragging`]: isDragging,
87
+ [`${prefixCls}-dragger-horizontal`]: isHorizontal,
88
+ [`${prefixCls}-dragger-vertical`]: !isHorizontal
89
+ }, className);
90
+ return {
91
+ dragElementProps: {
92
+ className: dragElementClassName,
93
+ style,
94
+ onMouseDown: handleMouseDown
95
+ },
96
+ isDragging
97
+ };
98
+ }
package/es/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import Drawer from './Drawer';
2
- import type { DrawerProps } from './Drawer';
3
- export type { DrawerProps };
2
+ import type { DrawerProps, Placement } from './Drawer';
3
+ export type { DrawerProps, Placement };
4
4
  export default Drawer;
package/es/inter.d.ts CHANGED
@@ -3,9 +3,11 @@ export interface DrawerClassNames {
3
3
  mask?: string;
4
4
  wrapper?: string;
5
5
  section?: string;
6
+ dragger?: string;
6
7
  }
7
8
  export interface DrawerStyles {
8
9
  mask?: React.CSSProperties;
9
10
  wrapper?: React.CSSProperties;
10
11
  section?: React.CSSProperties;
12
+ dragger?: React.CSSProperties;
11
13
  }
package/es/util.js CHANGED
@@ -1,9 +1,15 @@
1
1
  import warning from "@rc-component/util/es/warning";
2
2
  import canUseDom from "@rc-component/util/es/Dom/canUseDom";
3
3
  export function parseWidthHeight(value) {
4
- if (typeof value === 'string' && String(Number(value)) === value) {
5
- warning(false, 'Invalid value type of `width` or `height` which should be number type instead.');
6
- return Number(value);
4
+ if (typeof value === 'string') {
5
+ const num = Number(value.replace(/px$/i, ''));
6
+ const floatNum = parseFloat(value);
7
+ if (floatNum === num) {
8
+ warning(false, 'Invalid value type of `width` or `height` which should be number type instead.');
9
+ }
10
+ if (!Number.isNaN(num)) {
11
+ return num;
12
+ }
7
13
  }
8
14
  return value;
9
15
  }
package/lib/Drawer.d.ts CHANGED
@@ -8,11 +8,31 @@ export interface DrawerProps extends Omit<DrawerPopupProps, 'prefixCls' | 'inlin
8
8
  prefixCls?: string;
9
9
  open?: boolean;
10
10
  onClose?: (e: React.MouseEvent | React.KeyboardEvent) => void;
11
- destroyOnClose?: boolean;
11
+ destroyOnHidden?: boolean;
12
12
  getContainer?: PortalProps['getContainer'];
13
13
  panelRef?: React.Ref<HTMLDivElement>;
14
14
  classNames?: DrawerClassNames;
15
15
  styles?: DrawerStyles;
16
+ /**
17
+ * @deprecated Use `size` instead. Will be removed in next major version.
18
+ */
19
+ width?: number | string;
20
+ /**
21
+ * @deprecated Use `size` instead. Will be removed in next major version.
22
+ */
23
+ height?: number | string;
24
+ /** Size of the drawer (width for left/right placement, height for top/bottom placement) */
25
+ size?: number | string;
26
+ /** Maximum size of the drawer */
27
+ maxSize?: number;
28
+ /** Default size for uncontrolled resizable drawer */
29
+ defaultSize?: number | string;
30
+ /** Resizable configuration - object with optional callbacks */
31
+ resizable?: {
32
+ onResize?: (size: number) => void;
33
+ onResizeStart?: () => void;
34
+ onResizeEnd?: () => void;
35
+ };
16
36
  }
17
37
  declare const Drawer: React.FC<DrawerProps>;
18
38
  export default Drawer;
package/lib/Drawer.js CHANGED
@@ -20,19 +20,24 @@ const Drawer = props => {
20
20
  placement = 'right',
21
21
  autoFocus = true,
22
22
  keyboard = true,
23
- width = 378,
23
+ width,
24
+ height,
25
+ size,
26
+ maxSize,
24
27
  mask = true,
25
28
  maskClosable = true,
26
29
  getContainer,
27
30
  forceRender,
28
31
  afterOpenChange,
29
- destroyOnClose,
32
+ destroyOnHidden,
30
33
  onMouseEnter,
31
34
  onMouseOver,
32
35
  onMouseLeave,
33
36
  onClick,
34
37
  onKeyDown,
35
38
  onKeyUp,
39
+ resizable,
40
+ defaultSize,
36
41
  // Refs
37
42
  panelRef
38
43
  } = props;
@@ -76,7 +81,7 @@ const Drawer = props => {
76
81
  }), [panelRef]);
77
82
 
78
83
  // ============================ Render ============================
79
- if (!forceRender && !animatedVisible && !mergedOpen && destroyOnClose) {
84
+ if (!forceRender && !animatedVisible && !mergedOpen && destroyOnHidden) {
80
85
  return null;
81
86
  }
82
87
  const eventHandlers = {
@@ -95,11 +100,16 @@ const Drawer = props => {
95
100
  autoFocus,
96
101
  keyboard,
97
102
  width,
103
+ height,
104
+ size,
105
+ maxSize,
106
+ defaultSize,
98
107
  mask,
99
108
  maskClosable,
100
109
  inline: getContainer === false,
101
110
  afterOpenChange: internalAfterOpenChange,
102
111
  ref: popupRef,
112
+ resizable,
103
113
  ...eventHandlers
104
114
  };
105
115
  return /*#__PURE__*/React.createElement(_context.RefContext.Provider, {
@@ -19,8 +19,5 @@ export interface DrawerPanelProps extends DrawerPanelEvents, DrawerPanelAccessib
19
19
  children?: React.ReactNode;
20
20
  containerRef?: React.Ref<HTMLDivElement>;
21
21
  }
22
- declare const DrawerPanel: {
23
- (props: DrawerPanelProps): React.JSX.Element;
24
- displayName: string;
25
- };
22
+ declare const DrawerPanel: React.FC<Readonly<DrawerPanelProps>>;
26
23
  export default DrawerPanel;
@@ -24,6 +24,10 @@ export interface DrawerPopupProps extends DrawerPanelEvents, DrawerPanelAccessib
24
24
  children?: React.ReactNode;
25
25
  width?: number | string;
26
26
  height?: number | string;
27
+ /** Size of the drawer (width for left/right placement, height for top/bottom placement) */
28
+ size?: number | string;
29
+ /** Maximum size of the drawer */
30
+ maxSize?: number;
27
31
  mask?: boolean;
28
32
  maskClosable?: boolean;
29
33
  maskClassName?: string;
@@ -35,6 +39,13 @@ export interface DrawerPopupProps extends DrawerPanelEvents, DrawerPanelAccessib
35
39
  classNames?: DrawerClassNames;
36
40
  styles?: DrawerStyles;
37
41
  drawerRender?: (node: React.ReactNode) => React.ReactNode;
42
+ /** Default size for uncontrolled resizable drawer */
43
+ defaultSize?: number | string;
44
+ resizable?: {
45
+ onResize?: (size: number) => void;
46
+ onResizeStart?: () => void;
47
+ onResizeEnd?: () => void;
48
+ };
38
49
  }
39
50
  declare const RefDrawerPopup: React.ForwardRefExoticComponent<DrawerPopupProps & React.RefAttributes<HTMLDivElement>>;
40
51
  export default RefDrawerPopup;
@@ -11,7 +11,9 @@ var _pickAttrs = _interopRequireDefault(require("@rc-component/util/lib/pickAttr
11
11
  var React = _interopRequireWildcard(require("react"));
12
12
  var _context = _interopRequireDefault(require("./context"));
13
13
  var _DrawerPanel = _interopRequireDefault(require("./DrawerPanel"));
14
+ var _useDrag = _interopRequireDefault(require("./hooks/useDrag"));
14
15
  var _util = require("./util");
16
+ var _util2 = require("@rc-component/util");
15
17
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
16
18
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
17
19
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -23,7 +25,7 @@ const sentinelStyle = {
23
25
  outline: 'none',
24
26
  position: 'absolute'
25
27
  };
26
- function DrawerPopup(props, ref) {
28
+ const DrawerPopup = (props, ref) => {
27
29
  const {
28
30
  prefixCls,
29
31
  open,
@@ -46,6 +48,8 @@ function DrawerPopup(props, ref) {
46
48
  motion,
47
49
  width,
48
50
  height,
51
+ size,
52
+ maxSize,
49
53
  children,
50
54
  // Mask
51
55
  mask,
@@ -63,7 +67,9 @@ function DrawerPopup(props, ref) {
63
67
  onKeyDown,
64
68
  onKeyUp,
65
69
  styles,
66
- drawerRender
70
+ drawerRender,
71
+ resizable,
72
+ defaultSize
67
73
  } = props;
68
74
 
69
75
  // ================================ Refs ================================
@@ -156,10 +162,10 @@ function DrawerPopup(props, ref) {
156
162
  }, []);
157
163
 
158
164
  // ============================ Mask ============================
159
- const maskNode = mask && /*#__PURE__*/React.createElement(_motion.default, _extends({
165
+ const maskNode = /*#__PURE__*/React.createElement(_motion.default, _extends({
160
166
  key: "mask"
161
167
  }, maskMotion, {
162
- visible: open
168
+ visible: mask && open
163
169
  }), ({
164
170
  className: motionMaskClassName,
165
171
  style: motionMaskStyle
@@ -176,28 +182,68 @@ function DrawerPopup(props, ref) {
176
182
 
177
183
  // =========================== Panel ============================
178
184
  const motionProps = typeof motion === 'function' ? motion(placement) : motion;
179
- const wrapperStyle = {};
180
- if (pushed && pushDistance) {
181
- switch (placement) {
182
- case 'top':
183
- wrapperStyle.transform = `translateY(${pushDistance}px)`;
184
- break;
185
- case 'bottom':
186
- wrapperStyle.transform = `translateY(${-pushDistance}px)`;
187
- break;
188
- case 'left':
189
- wrapperStyle.transform = `translateX(${pushDistance}px)`;
190
- break;
191
- default:
192
- wrapperStyle.transform = `translateX(${-pushDistance}px)`;
193
- break;
185
+
186
+ // ============================ Size ============================
187
+ const [currentSize, setCurrentSize] = React.useState();
188
+ const isHorizontal = placement === 'left' || placement === 'right';
189
+
190
+ // Aggregate size logic with backward compatibility using useMemo
191
+ const mergedSize = React.useMemo(() => {
192
+ const legacySize = isHorizontal ? width : height;
193
+ const nextMergedSize = size ?? legacySize ?? currentSize ?? defaultSize ?? (isHorizontal ? 378 : undefined);
194
+ return (0, _util.parseWidthHeight)(nextMergedSize);
195
+ }, [size, width, height, defaultSize, isHorizontal, currentSize]);
196
+
197
+ // >>> Style
198
+ const wrapperStyle = React.useMemo(() => {
199
+ const nextWrapperStyle = {};
200
+ if (pushed && pushDistance) {
201
+ switch (placement) {
202
+ case 'top':
203
+ nextWrapperStyle.transform = `translateY(${pushDistance}px)`;
204
+ break;
205
+ case 'bottom':
206
+ nextWrapperStyle.transform = `translateY(${-pushDistance}px)`;
207
+ break;
208
+ case 'left':
209
+ nextWrapperStyle.transform = `translateX(${pushDistance}px)`;
210
+ break;
211
+ default:
212
+ nextWrapperStyle.transform = `translateX(${-pushDistance}px)`;
213
+ break;
214
+ }
194
215
  }
195
- }
196
- if (placement === 'left' || placement === 'right') {
197
- wrapperStyle.width = (0, _util.parseWidthHeight)(width);
198
- } else {
199
- wrapperStyle.height = (0, _util.parseWidthHeight)(height);
200
- }
216
+ if (isHorizontal) {
217
+ nextWrapperStyle.width = (0, _util.parseWidthHeight)(mergedSize);
218
+ } else {
219
+ nextWrapperStyle.height = (0, _util.parseWidthHeight)(mergedSize);
220
+ }
221
+ return nextWrapperStyle;
222
+ }, [pushed, pushDistance, placement, isHorizontal, mergedSize]);
223
+
224
+ // =========================== Resize ===========================
225
+ const wrapperRef = React.useRef(null);
226
+ const onInternalResize = (0, _util2.useEvent)(size => {
227
+ setCurrentSize(size);
228
+ resizable?.onResize?.(size);
229
+ });
230
+ const {
231
+ dragElementProps,
232
+ isDragging
233
+ } = (0, _useDrag.default)({
234
+ prefixCls: `${prefixCls}-resizable`,
235
+ direction: placement,
236
+ className: drawerClassNames?.dragger,
237
+ style: styles?.dragger,
238
+ maxSize,
239
+ containerRef: wrapperRef,
240
+ currentSize: mergedSize,
241
+ onResize: onInternalResize,
242
+ onResizeStart: resizable?.onResizeStart,
243
+ onResizeEnd: resizable?.onResizeEnd
244
+ });
245
+
246
+ // =========================== Events ===========================
201
247
  const eventHandlers = {
202
248
  onMouseEnter,
203
249
  onMouseOver,
@@ -206,6 +252,9 @@ function DrawerPopup(props, ref) {
206
252
  onKeyDown,
207
253
  onKeyUp
208
254
  };
255
+
256
+ // =========================== Render ==========================
257
+ // >>>>> Panel
209
258
  const panelNode = /*#__PURE__*/React.createElement(_motion.default, _extends({
210
259
  key: "panel"
211
260
  }, motionProps, {
@@ -233,18 +282,19 @@ function DrawerPopup(props, ref) {
233
282
  aria: true
234
283
  }), eventHandlers), children);
235
284
  return /*#__PURE__*/React.createElement("div", _extends({
236
- className: (0, _classnames.default)(`${prefixCls}-content-wrapper`, drawerClassNames?.wrapper, motionClassName),
285
+ ref: wrapperRef,
286
+ className: (0, _classnames.default)(`${prefixCls}-content-wrapper`, isDragging && `${prefixCls}-content-wrapper-dragging`, drawerClassNames?.wrapper, !isDragging && motionClassName),
237
287
  style: {
238
- ...wrapperStyle,
239
288
  ...motionStyle,
289
+ ...wrapperStyle,
240
290
  ...styles?.wrapper
241
291
  }
242
292
  }, (0, _pickAttrs.default)(props, {
243
293
  data: true
244
- })), drawerRender ? drawerRender(content) : content);
294
+ })), resizable && /*#__PURE__*/React.createElement("div", dragElementProps), drawerRender ? drawerRender(content) : content);
245
295
  });
246
296
 
247
- // =========================== Render ===========================
297
+ // >>>>> Container
248
298
  const containerStyle = {
249
299
  ...rootStyle
250
300
  };
@@ -275,7 +325,7 @@ function DrawerPopup(props, ref) {
275
325
  "aria-hidden": "true",
276
326
  "data-sentinel": "end"
277
327
  })));
278
- }
328
+ };
279
329
  const RefDrawerPopup = /*#__PURE__*/React.forwardRef(DrawerPopup);
280
330
  if (process.env.NODE_ENV !== 'production') {
281
331
  RefDrawerPopup.displayName = 'DrawerPopup';
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+ import type { Placement } from '../Drawer';
3
+ export interface UseDragOptions {
4
+ prefixCls: string;
5
+ direction: Placement;
6
+ className?: string;
7
+ style?: React.CSSProperties;
8
+ maxSize?: number;
9
+ containerRef?: React.RefObject<HTMLElement>;
10
+ currentSize?: number | string;
11
+ onResize?: (size: number) => void;
12
+ onResizeEnd?: (size: number) => void;
13
+ onResizeStart?: (size: number) => void;
14
+ }
15
+ export interface UseDragReturn {
16
+ dragElementProps: {
17
+ className: string;
18
+ style: React.CSSProperties;
19
+ onMouseDown: (e: React.MouseEvent) => void;
20
+ };
21
+ isDragging: boolean;
22
+ }
23
+ export default function useDrag(options: UseDragOptions): UseDragReturn;
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = useDrag;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _classnames = _interopRequireDefault(require("classnames"));
9
+ var _util = require("@rc-component/util");
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
12
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
13
+ function useDrag(options) {
14
+ const {
15
+ prefixCls,
16
+ direction,
17
+ className,
18
+ style,
19
+ maxSize,
20
+ containerRef,
21
+ currentSize,
22
+ onResize,
23
+ onResizeEnd,
24
+ onResizeStart
25
+ } = options;
26
+ const [isDragging, setIsDragging] = React.useState(false);
27
+ const [startPos, setStartPos] = React.useState(0);
28
+ const [startSize, setStartSize] = React.useState(0);
29
+ const isHorizontal = direction === 'left' || direction === 'right';
30
+ const handleMouseDown = (0, _util.useEvent)(e => {
31
+ e.preventDefault();
32
+ e.stopPropagation();
33
+ setIsDragging(true);
34
+ if (isHorizontal) {
35
+ setStartPos(e.clientX);
36
+ } else {
37
+ setStartPos(e.clientY);
38
+ }
39
+
40
+ // Use provided currentSize, or fallback to container size
41
+ let startSize;
42
+ if (typeof currentSize === 'number') {
43
+ startSize = currentSize;
44
+ } else if (containerRef?.current) {
45
+ const rect = containerRef.current.getBoundingClientRect();
46
+ startSize = isHorizontal ? rect.width : rect.height;
47
+ }
48
+ setStartSize(startSize);
49
+ onResizeStart?.(startSize);
50
+ });
51
+ const handleMouseMove = (0, _util.useEvent)(e => {
52
+ if (!isDragging) return;
53
+ const currentPos = isHorizontal ? e.clientX : e.clientY;
54
+ let delta = currentPos - startPos;
55
+
56
+ // Adjust delta direction based on placement
57
+ if (direction === 'right' || direction === 'bottom') {
58
+ delta = -delta;
59
+ }
60
+ let newSize = startSize + delta;
61
+
62
+ // Apply min/max size limits
63
+ if (newSize < 0) {
64
+ newSize = 0;
65
+ }
66
+ // Only apply maxSize if it's a valid positive number
67
+ if (maxSize && newSize > maxSize) {
68
+ newSize = maxSize;
69
+ }
70
+ onResize?.(newSize);
71
+ });
72
+ const handleMouseUp = React.useCallback(() => {
73
+ if (isDragging) {
74
+ setIsDragging(false);
75
+
76
+ // Get the final size after resize
77
+ if (containerRef?.current) {
78
+ const rect = containerRef.current.getBoundingClientRect();
79
+ const finalSize = isHorizontal ? rect.width : rect.height;
80
+ onResizeEnd?.(finalSize);
81
+ }
82
+ }
83
+ }, [isDragging, containerRef, onResizeEnd, isHorizontal]);
84
+ React.useEffect(() => {
85
+ if (isDragging) {
86
+ document.addEventListener('mousemove', handleMouseMove);
87
+ document.addEventListener('mouseup', handleMouseUp);
88
+ return () => {
89
+ document.removeEventListener('mousemove', handleMouseMove);
90
+ document.removeEventListener('mouseup', handleMouseUp);
91
+ };
92
+ }
93
+ }, [isDragging, handleMouseMove, handleMouseUp]);
94
+ const dragElementClassName = (0, _classnames.default)(`${prefixCls}-dragger`, `${prefixCls}-dragger-${direction}`, {
95
+ [`${prefixCls}-dragger-dragging`]: isDragging,
96
+ [`${prefixCls}-dragger-horizontal`]: isHorizontal,
97
+ [`${prefixCls}-dragger-vertical`]: !isHorizontal
98
+ }, className);
99
+ return {
100
+ dragElementProps: {
101
+ className: dragElementClassName,
102
+ style,
103
+ onMouseDown: handleMouseDown
104
+ },
105
+ isDragging
106
+ };
107
+ }
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import Drawer from './Drawer';
2
- import type { DrawerProps } from './Drawer';
3
- export type { DrawerProps };
2
+ import type { DrawerProps, Placement } from './Drawer';
3
+ export type { DrawerProps, Placement };
4
4
  export default Drawer;
package/lib/inter.d.ts CHANGED
@@ -3,9 +3,11 @@ export interface DrawerClassNames {
3
3
  mask?: string;
4
4
  wrapper?: string;
5
5
  section?: string;
6
+ dragger?: string;
6
7
  }
7
8
  export interface DrawerStyles {
8
9
  mask?: React.CSSProperties;
9
10
  wrapper?: React.CSSProperties;
10
11
  section?: React.CSSProperties;
12
+ dragger?: React.CSSProperties;
11
13
  }
package/lib/util.js CHANGED
@@ -9,9 +9,15 @@ var _warning = _interopRequireDefault(require("@rc-component/util/lib/warning"))
9
9
  var _canUseDom = _interopRequireDefault(require("@rc-component/util/lib/Dom/canUseDom"));
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
11
  function parseWidthHeight(value) {
12
- if (typeof value === 'string' && String(Number(value)) === value) {
13
- (0, _warning.default)(false, 'Invalid value type of `width` or `height` which should be number type instead.');
14
- return Number(value);
12
+ if (typeof value === 'string') {
13
+ const num = Number(value.replace(/px$/i, ''));
14
+ const floatNum = parseFloat(value);
15
+ if (floatNum === num) {
16
+ (0, _warning.default)(false, 'Invalid value type of `width` or `height` which should be number type instead.');
17
+ }
18
+ if (!Number.isNaN(num)) {
19
+ return num;
20
+ }
15
21
  }
16
22
  return value;
17
23
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rc-component/drawer",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "drawer component for react",
5
5
  "keywords": [
6
6
  "react",
@@ -53,9 +53,10 @@
53
53
  "@rc-component/father-plugin": "^2.0.2",
54
54
  "@rc-component/np": "^1.0.0",
55
55
  "@testing-library/jest-dom": "^6.2.0",
56
- "@testing-library/react": "^14.0.0",
56
+ "@testing-library/react": "^16.3.0",
57
57
  "@types/classnames": "^2.2.9",
58
58
  "@types/jest": "^29.5.11",
59
+ "@types/node": "^24.3.0",
59
60
  "@types/raf": "^3.4.0",
60
61
  "@types/react": "^19.0.0",
61
62
  "@types/react-dom": "^19.0.0",
@@ -69,7 +70,7 @@
69
70
  "glob": "^10.3.10",
70
71
  "husky": "^9.0.10",
71
72
  "less": "^4.2.0",
72
- "lint-staged": "^15.2.2",
73
+ "lint-staged": "^16.1.5",
73
74
  "prettier": "^3.0.0",
74
75
  "rc-test": "^7.0.9",
75
76
  "react": "^19.0.0",