@rainbow-oh/yee-c 0.14.3 → 0.14.5

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.
Files changed (38) hide show
  1. package/dist/cjs/Form/form-store.js +3 -3
  2. package/dist/cjs/Splitter/demo/animation.d.ts +3 -0
  3. package/dist/cjs/Splitter/demo/animation.js +43 -0
  4. package/dist/cjs/Splitter/hooks/useMove.d.ts +1 -1
  5. package/dist/cjs/Splitter/hooks/useMove.js +3 -1
  6. package/dist/cjs/Splitter/interface.d.ts +6 -0
  7. package/dist/cjs/Splitter/splitter-handler.d.ts +3 -1
  8. package/dist/cjs/Splitter/splitter-handler.js +3 -2
  9. package/dist/cjs/Splitter/splitter.js +73 -7
  10. package/dist/cjs/style/themes.css +1 -1
  11. package/dist/cjs/style/variables.css +1 -1
  12. package/dist/cjs/version.d.ts +1 -1
  13. package/dist/cjs/version.js +1 -1
  14. package/dist/esm/Form/form-store.js +7 -3
  15. package/dist/esm/Splitter/demo/animation.d.ts +3 -0
  16. package/dist/esm/Splitter/demo/animation.js +51 -0
  17. package/dist/esm/Splitter/hooks/useMove.d.ts +1 -1
  18. package/dist/esm/Splitter/hooks/useMove.js +3 -1
  19. package/dist/esm/Splitter/interface.d.ts +6 -0
  20. package/dist/esm/Splitter/splitter-handler.d.ts +3 -1
  21. package/dist/esm/Splitter/splitter-handler.js +3 -2
  22. package/dist/esm/Splitter/splitter.js +96 -10
  23. package/dist/esm/style/themes.css +1 -1
  24. package/dist/esm/style/variables.css +1 -1
  25. package/dist/esm/version.d.ts +1 -1
  26. package/dist/esm/version.js +1 -1
  27. package/dist/umd/yee-c.min.js +1 -1
  28. package/package.json +1 -1
  29. package/src/Form/form-store.test.ts +19 -0
  30. package/src/Form/form-store.ts +7 -3
  31. package/src/Splitter/demo/animation.tsx +29 -0
  32. package/src/Splitter/hooks/useMove.ts +3 -0
  33. package/src/Splitter/index.en-US.md +2 -0
  34. package/src/Splitter/index.zh-CN.md +2 -0
  35. package/src/Splitter/interface.ts +6 -0
  36. package/src/Splitter/splitter-handler.tsx +4 -1
  37. package/src/Splitter/splitter.tsx +81 -2
  38. package/src/version.ts +1 -1
@@ -105,15 +105,15 @@ var FormStore = class {
105
105
  initialValues,
106
106
  callbacks
107
107
  }) => {
108
+ if (callbacks) {
109
+ this.setCallbacks(callbacks);
110
+ }
108
111
  if (!this.initialized) {
109
112
  this.initialized = true;
110
113
  if (initialValues) {
111
114
  this.store = __spreadValues(__spreadValues({}, this.store), initialValues);
112
115
  this.initialValues = JSON.parse(JSON.stringify(initialValues));
113
116
  }
114
- if (callbacks) {
115
- this.setCallbacks(callbacks);
116
- }
117
117
  this.fieldEntities.forEach((entity) => {
118
118
  entity == null ? void 0 : entity.onStoreChange();
119
119
  });
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const _default: () => React.JSX.Element;
3
+ export default _default;
@@ -0,0 +1,43 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/Splitter/demo/animation.tsx
30
+ var animation_exports = {};
31
+ __export(animation_exports, {
32
+ default: () => animation_default
33
+ });
34
+ module.exports = __toCommonJS(animation_exports);
35
+ var import_yee_c = require("../..");
36
+ var import_react = __toESM(require("react"));
37
+ var animation_default = () => {
38
+ const [open, setOpen] = import_react.default.useState(false);
39
+ return /* @__PURE__ */ import_react.default.createElement("div", null, /* @__PURE__ */ import_react.default.createElement("div", { style: { marginBottom: 8 } }, /* @__PURE__ */ import_react.default.createElement(import_yee_c.Button, { type: "primary", onClick: () => setOpen((v) => !v) }, open ? "Close Panel" : "Open Panel")), /* @__PURE__ */ import_react.default.createElement("div", { style: { height: 300 } }, /* @__PURE__ */ import_react.default.createElement(import_yee_c.Splitter, { animation: true }, /* @__PURE__ */ import_react.default.createElement(import_yee_c.Splitter.Item, { min: "30%" }, /* @__PURE__ */ import_react.default.createElement("div", { style: { padding: 16, backgroundColor: "#f0f0f0" } }, "Content Panel")), open ? (
40
+ // 条件渲染的面板:挂载时从 0 展开到目标尺寸,卸载时过渡收合到 0 后移除
41
+ /* @__PURE__ */ import_react.default.createElement(import_yee_c.Splitter.Item, { size: "40%", min: "200px", max: "60%" }, /* @__PURE__ */ import_react.default.createElement("div", { style: { padding: 16, backgroundColor: "#e0e0e0" } }, "Assistant Panel"))
42
+ ) : null)));
43
+ };
@@ -1,2 +1,2 @@
1
1
  import * as React from 'react';
2
- export default function useMove(handler: React.RefObject<HTMLDivElement | null>, direction: 'horizontal' | 'vertical', onMove: (dis: number) => void): boolean[];
2
+ export default function useMove(handler: React.RefObject<HTMLDivElement | null>, direction: 'horizontal' | 'vertical', onMove: (dis: number) => void, onMovingChange?: (moving: boolean) => void): boolean[];
@@ -34,7 +34,7 @@ __export(useMove_exports, {
34
34
  module.exports = __toCommonJS(useMove_exports);
35
35
  var React = __toESM(require("react"));
36
36
  var import_debounce = __toESM(require("../../utils/debounce"));
37
- function useMove(handler, direction, onMove) {
37
+ function useMove(handler, direction, onMove, onMovingChange) {
38
38
  const [moving, setMoving] = React.useState(false);
39
39
  const moveTarget = (distance) => {
40
40
  onMove(distance);
@@ -48,6 +48,7 @@ function useMove(handler, direction, onMove) {
48
48
  let x = e.pageX;
49
49
  let y = e.pageY;
50
50
  setMoving(true);
51
+ onMovingChange == null ? void 0 : onMovingChange(true);
51
52
  const onMouseMove = (0, import_debounce.default)((e2) => {
52
53
  document.body.style.userSelect = "none";
53
54
  document.body.style.cursor = direction === "horizontal" ? "col-resize" : "row-resize";
@@ -63,6 +64,7 @@ function useMove(handler, direction, onMove) {
63
64
  }, 5);
64
65
  const onMouseUp = () => {
65
66
  setMoving(false);
67
+ onMovingChange == null ? void 0 : onMovingChange(false);
66
68
  window.removeEventListener("mousemove", onMouseMove);
67
69
  window.removeEventListener("mouseup", onMouseUp);
68
70
  ele.removeEventListener("mouseup", onMouseUp);
@@ -83,4 +83,10 @@ export interface SplitterProps extends DataAttributeProps {
83
83
  * panel size change event
84
84
  * */
85
85
  onResize?: (sizes: PanelRect[]) => void;
86
+ /**
87
+ * animate programmatic size changes and panel mount/unmount with a
88
+ * flex-basis transition; dragging always tracks the pointer in real time
89
+ * @default false
90
+ */
91
+ animation?: boolean;
86
92
  }
@@ -17,6 +17,8 @@ interface SplitterHandlerProps {
17
17
  start: HTMLDivElement;
18
18
  end: HTMLDivElement;
19
19
  }) => void;
20
+ /** 拖拽开始/结束回调(animation 模式下拖拽期间需关闭 flex-basis 过渡) */
21
+ onDraggingChange?: (dragging: boolean) => void;
20
22
  }
21
- declare const SplitterHandler: ({ layout, resizable, collapsible, index, records, setRecords, onClick, }: SplitterHandlerProps) => React.JSX.Element;
23
+ declare const SplitterHandler: ({ layout, resizable, collapsible, index, records, setRecords, onClick, onDraggingChange, }: SplitterHandlerProps) => React.JSX.Element;
22
24
  export default SplitterHandler;
@@ -61,7 +61,8 @@ var SplitterHandler = ({
61
61
  index,
62
62
  records,
63
63
  setRecords,
64
- onClick
64
+ onClick,
65
+ onDraggingChange
65
66
  }) => {
66
67
  const { start, end } = collapsible ? typeof collapsible === "boolean" ? { start: true, end: true } : collapsible : {};
67
68
  const cref = (0, import_react.useRef)(null);
@@ -108,7 +109,7 @@ var SplitterHandler = ({
108
109
  return newState;
109
110
  });
110
111
  };
111
- (0, import_useMove.default)(handler, layout, onMove);
112
+ (0, import_useMove.default)(handler, layout, onMove, onDraggingChange);
112
113
  const handleClick = (action) => {
113
114
  const eles = refs.current;
114
115
  const { el: start2 } = eles[`item${index}`];
@@ -162,7 +162,21 @@ var getPanelSize = (children, {
162
162
  return panelsRect;
163
163
  };
164
164
  var Wrapper = (_a) => {
165
- var _b = _a, { children, itemsSize, onClick } = _b, props = __objRest(_b, ["children", "itemsSize", "onClick"]);
165
+ var _b = _a, {
166
+ children,
167
+ itemsSize,
168
+ itemTransition,
169
+ animation,
170
+ onDraggingChange,
171
+ onClick
172
+ } = _b, props = __objRest(_b, [
173
+ "children",
174
+ "itemsSize",
175
+ "itemTransition",
176
+ "animation",
177
+ "onDraggingChange",
178
+ "onClick"
179
+ ]);
166
180
  const wrappered = [];
167
181
  const refs = (0, import_react.useRef)({});
168
182
  const arr = import_react.default.Children.toArray(children);
@@ -181,7 +195,9 @@ var Wrapper = (_a) => {
181
195
  // @ts-ignore
182
196
  style: __spreadProps(__spreadValues({}, style), {
183
197
  // If there is a border or other size-related design, it may cause calculation issues
184
- flexBasis: currentSize
198
+ flexBasis: currentSize,
199
+ // animation 模式下受控尺寸变更走 flex-basis 过渡;拖拽期间为 undefined 保证跟手
200
+ transition: itemTransition
185
201
  }),
186
202
  min,
187
203
  max,
@@ -217,13 +233,43 @@ var Wrapper = (_a) => {
217
233
  flexable,
218
234
  expandable: _expandable,
219
235
  onClick,
236
+ onDraggingChange,
220
237
  key: `handler-${n}`
221
238
  })
222
239
  )
223
240
  );
224
241
  }
225
242
  });
226
- return /* @__PURE__ */ import_react.default.createElement(SplitterWrapperCtx.Provider, { value: { refs } }, wrappered);
243
+ const prevCountRef = import_react.default.useRef(arr.length);
244
+ const prevClonesRef = import_react.default.useRef([]);
245
+ const [exiting, setExiting] = import_react.default.useState([]);
246
+ import_react.default.useEffect(() => {
247
+ const prevCount = prevCountRef.current;
248
+ prevCountRef.current = arr.length;
249
+ if (!animation || arr.length >= prevCount) {
250
+ return;
251
+ }
252
+ const removed = prevClonesRef.current.slice(arr.length);
253
+ if (!removed.length) {
254
+ return;
255
+ }
256
+ setExiting(removed);
257
+ const raf = requestAnimationFrame(() => {
258
+ setExiting(
259
+ (list) => list.map((el) => import_react.default.cloneElement(el, { style: __spreadProps(__spreadValues({}, el.props.style), { flexBasis: 0 }) }))
260
+ );
261
+ });
262
+ const timer = window.setTimeout(() => setExiting([]), 320);
263
+ return () => {
264
+ cancelAnimationFrame(raf);
265
+ window.clearTimeout(timer);
266
+ setExiting([]);
267
+ };
268
+ }, [arr.length, animation]);
269
+ import_react.default.useEffect(() => {
270
+ prevClonesRef.current = wrappered;
271
+ });
272
+ return /* @__PURE__ */ import_react.default.createElement(SplitterWrapperCtx.Provider, { value: { refs } }, wrappered, exiting);
227
273
  };
228
274
  var Splitter = import_react.default.forwardRef(
229
275
  (baseprops, ref) => {
@@ -235,18 +281,22 @@ var Splitter = import_react.default.forwardRef(
235
281
  layout = "horizontal",
236
282
  children,
237
283
  bordered,
238
- onResize
284
+ onResize,
285
+ animation
239
286
  } = _a, rest = __objRest(_a, [
240
287
  "prefixCls",
241
288
  "className",
242
289
  "layout",
243
290
  "children",
244
291
  "bordered",
245
- "onResize"
292
+ "onResize",
293
+ "animation"
246
294
  ]);
247
295
  const internalRef = (0, import_react.useRef)(null);
248
296
  const componentRef = ref || internalRef;
249
297
  const [records, setRecords] = (0, import_react.useState)([]);
298
+ const [dragging, setDragging] = import_react.default.useState(false);
299
+ const itemTransition = animation ? dragging ? void 0 : "flex-basis 0.28s cubic-bezier(0.22, 0.61, 0.36, 1)" : void 0;
250
300
  const handleClick = (index, action) => {
251
301
  const c = index - 1;
252
302
  const newRecords = [...records];
@@ -296,15 +346,28 @@ var Splitter = import_react.default.forwardRef(
296
346
  };
297
347
  }
298
348
  }, [layout]);
349
+ const prevPanelCountRef = import_react.default.useRef(-1);
299
350
  import_react.default.useEffect(() => {
300
351
  if (totalSize) {
301
352
  const panelsSize = getPanelSize(children, {
302
353
  totalSize,
303
354
  layout
304
355
  });
356
+ const prevCount = prevPanelCountRef.current;
357
+ prevPanelCountRef.current = panelsSize.length;
358
+ if (animation && prevCount >= 0 && panelsSize.length > prevCount) {
359
+ panelsSize.slice(prevCount).forEach((item) => {
360
+ item.currentSize = 0;
361
+ });
362
+ setRecords(panelsSize);
363
+ const raf = requestAnimationFrame(() => {
364
+ setRecords(getPanelSize(children, { totalSize, layout }));
365
+ });
366
+ return () => cancelAnimationFrame(raf);
367
+ }
305
368
  setRecords(panelsSize);
306
369
  }
307
- }, [children, totalSize, layout]);
370
+ }, [children, totalSize, layout, animation]);
308
371
  return /* @__PURE__ */ import_react.default.createElement("div", __spreadProps(__spreadValues({ className: cls }, rest), { ref: componentRef }), /* @__PURE__ */ import_react.default.createElement(SplitterCtx.Provider, { value: { prefixCls, onResize } }, /* @__PURE__ */ import_react.default.createElement(
309
372
  Wrapper,
310
373
  {
@@ -313,7 +376,10 @@ var Splitter = import_react.default.forwardRef(
313
376
  setRecords,
314
377
  totalSize,
315
378
  itemsSize: records,
316
- onClick: handleClick
379
+ onClick: handleClick,
380
+ animation,
381
+ itemTransition,
382
+ onDraggingChange: setDragging
317
383
  },
318
384
  children
319
385
  )));
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * @rainbow-oh/yee-c CSS Variables
3
3
  * Auto-generated, do not edit manually
4
- * Generated on 2026-09-21T06:47:43.665Z
4
+ * Generated on 2026-10-08T06:15:24.118Z
5
5
  */
6
6
 
7
7
  /* ========== color.blue.css ========== */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * @rainbow-oh/yee-c CSS Variables
3
3
  * Auto-generated, do not edit manually
4
- * Generated on 2026-09-21T06:47:43.665Z
4
+ * Generated on 2026-10-08T06:15:24.118Z
5
5
  */
6
6
 
7
7
  /* ========== color.css ========== */
@@ -3,4 +3,4 @@ declare global {
3
3
  __yee_c_version__: string;
4
4
  }
5
5
  }
6
- export declare const version = "0.14.3";
6
+ export declare const version = "0.14.5";
@@ -22,7 +22,7 @@ __export(version_exports, {
22
22
  version: () => version
23
23
  });
24
24
  module.exports = __toCommonJS(version_exports);
25
- var version = "0.14.3";
25
+ var version = "0.14.5";
26
26
  if (typeof window !== "undefined") {
27
27
  window.__yee_c_version__ = version;
28
28
  }
@@ -62,15 +62,19 @@ export var FormStore = /*#__PURE__*/function () {
62
62
  _defineProperty(this, "initialize", function (_ref) {
63
63
  var initialValues = _ref.initialValues,
64
64
  callbacks = _ref.callbacks;
65
+ // callbacks 每次挂载重绑:form 实例可由外层 useForm 持有、跨越 <Form> 卸载/重挂载存活,
66
+ // 若只在此处注册一次,重挂载后 store 仍持旧挂载的 useEvent 闭包,其 ref 已随旧实例
67
+ // 死亡(不再更新),onValuesChange 等会以过期闭包执行。
68
+ if (callbacks) {
69
+ _this.setCallbacks(callbacks);
70
+ }
65
71
  if (!_this.initialized) {
66
72
  _this.initialized = true;
67
73
  if (initialValues) {
68
74
  _this.store = _objectSpread(_objectSpread({}, _this.store), initialValues);
69
75
  _this.initialValues = JSON.parse(JSON.stringify(initialValues));
70
76
  }
71
- if (callbacks) {
72
- _this.setCallbacks(callbacks);
73
- }
77
+
74
78
  // Only refresh field entities, do not notify watchers (no value changes to watch during initialization)
75
79
  _this.fieldEntities.forEach(function (entity) {
76
80
  entity === null || entity === void 0 || entity.onStoreChange();
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const _default: () => React.JSX.Element;
3
+ export default _default;
@@ -0,0 +1,51 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import { Button, Splitter } from "../..";
8
+ import React from 'react';
9
+ export default (function () {
10
+ var _React$useState = React.useState(false),
11
+ _React$useState2 = _slicedToArray(_React$useState, 2),
12
+ open = _React$useState2[0],
13
+ setOpen = _React$useState2[1];
14
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
15
+ style: {
16
+ marginBottom: 8
17
+ }
18
+ }, /*#__PURE__*/React.createElement(Button, {
19
+ type: "primary",
20
+ onClick: function onClick() {
21
+ return setOpen(function (v) {
22
+ return !v;
23
+ });
24
+ }
25
+ }, open ? 'Close Panel' : 'Open Panel')), /*#__PURE__*/React.createElement("div", {
26
+ style: {
27
+ height: 300
28
+ }
29
+ }, /*#__PURE__*/React.createElement(Splitter, {
30
+ animation: true
31
+ }, /*#__PURE__*/React.createElement(Splitter.Item, {
32
+ min: "30%"
33
+ }, /*#__PURE__*/React.createElement("div", {
34
+ style: {
35
+ padding: 16,
36
+ backgroundColor: '#f0f0f0'
37
+ }
38
+ }, "Content Panel")), open ?
39
+ /*#__PURE__*/
40
+ // 条件渲染的面板:挂载时从 0 展开到目标尺寸,卸载时过渡收合到 0 后移除
41
+ React.createElement(Splitter.Item, {
42
+ size: "40%",
43
+ min: "200px",
44
+ max: "60%"
45
+ }, /*#__PURE__*/React.createElement("div", {
46
+ style: {
47
+ padding: 16,
48
+ backgroundColor: '#e0e0e0'
49
+ }
50
+ }, "Assistant Panel")) : null)));
51
+ });
@@ -1,2 +1,2 @@
1
1
  import * as React from 'react';
2
- export default function useMove(handler: React.RefObject<HTMLDivElement | null>, direction: 'horizontal' | 'vertical', onMove: (dis: number) => void): boolean[];
2
+ export default function useMove(handler: React.RefObject<HTMLDivElement | null>, direction: 'horizontal' | 'vertical', onMove: (dis: number) => void, onMovingChange?: (moving: boolean) => void): boolean[];
@@ -6,7 +6,7 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
6
6
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
7
  import * as React from 'react';
8
8
  import debounce from "../../utils/debounce";
9
- export default function useMove(handler, direction, onMove) {
9
+ export default function useMove(handler, direction, onMove, onMovingChange) {
10
10
  var _React$useState = React.useState(false),
11
11
  _React$useState2 = _slicedToArray(_React$useState, 2),
12
12
  moving = _React$useState2[0],
@@ -22,6 +22,7 @@ export default function useMove(handler, direction, onMove) {
22
22
  var x = e.pageX;
23
23
  var y = e.pageY;
24
24
  setMoving(true);
25
+ onMovingChange === null || onMovingChange === void 0 || onMovingChange(true);
25
26
  var onMouseMove = debounce(function (e) {
26
27
  document.body.style.userSelect = 'none';
27
28
  document.body.style.cursor = direction === 'horizontal' ? 'col-resize' : 'row-resize';
@@ -37,6 +38,7 @@ export default function useMove(handler, direction, onMove) {
37
38
  }, 5);
38
39
  var onMouseUp = function onMouseUp() {
39
40
  setMoving(false);
41
+ onMovingChange === null || onMovingChange === void 0 || onMovingChange(false);
40
42
  window.removeEventListener('mousemove', onMouseMove);
41
43
  window.removeEventListener('mouseup', onMouseUp);
42
44
  ele.removeEventListener('mouseup', onMouseUp);
@@ -83,4 +83,10 @@ export interface SplitterProps extends DataAttributeProps {
83
83
  * panel size change event
84
84
  * */
85
85
  onResize?: (sizes: PanelRect[]) => void;
86
+ /**
87
+ * animate programmatic size changes and panel mount/unmount with a
88
+ * flex-basis transition; dragging always tracks the pointer in real time
89
+ * @default false
90
+ */
91
+ animation?: boolean;
86
92
  }
@@ -17,6 +17,8 @@ interface SplitterHandlerProps {
17
17
  start: HTMLDivElement;
18
18
  end: HTMLDivElement;
19
19
  }) => void;
20
+ /** 拖拽开始/结束回调(animation 模式下拖拽期间需关闭 flex-basis 过渡) */
21
+ onDraggingChange?: (dragging: boolean) => void;
20
22
  }
21
- declare const SplitterHandler: ({ layout, resizable, collapsible, index, records, setRecords, onClick, }: SplitterHandlerProps) => React.JSX.Element;
23
+ declare const SplitterHandler: ({ layout, resizable, collapsible, index, records, setRecords, onClick, onDraggingChange, }: SplitterHandlerProps) => React.JSX.Element;
22
24
  export default SplitterHandler;
@@ -23,7 +23,8 @@ var SplitterHandler = function SplitterHandler(_ref) {
23
23
  index = _ref.index,
24
24
  records = _ref.records,
25
25
  setRecords = _ref.setRecords,
26
- onClick = _ref.onClick;
26
+ onClick = _ref.onClick,
27
+ onDraggingChange = _ref.onDraggingChange;
27
28
  // eslint-disable-line @typescript-eslint/no-unused-vars
28
29
  var _ref2 = collapsible ? typeof collapsible === 'boolean' ? {
29
30
  start: true,
@@ -85,7 +86,7 @@ var SplitterHandler = function SplitterHandler(_ref) {
85
86
  return newState;
86
87
  });
87
88
  };
88
- useMove(handler, layout, onMove);
89
+ useMove(handler, layout, onMove, onDraggingChange);
89
90
  var handleClick = function handleClick(action) {
90
91
  var eles = refs.current;
91
92
  var start = eles["item".concat(index)].el;
@@ -1,6 +1,6 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- var _excluded = ["children", "itemsSize", "onClick"],
3
- _excluded2 = ["prefixCls", "className", "layout", "children", "bordered", "onResize"];
2
+ var _excluded = ["children", "itemsSize", "itemTransition", "animation", "onDraggingChange", "onClick"],
3
+ _excluded2 = ["prefixCls", "className", "layout", "children", "bordered", "onResize", "animation"];
4
4
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
5
5
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
6
6
  function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
@@ -128,6 +128,9 @@ var getPanelSize = function getPanelSize(children, _ref) {
128
128
  var Wrapper = function Wrapper(_ref3) {
129
129
  var children = _ref3.children,
130
130
  itemsSize = _ref3.itemsSize,
131
+ itemTransition = _ref3.itemTransition,
132
+ animation = _ref3.animation,
133
+ onDraggingChange = _ref3.onDraggingChange,
131
134
  onClick = _ref3.onClick,
132
135
  props = _objectWithoutProperties(_ref3, _excluded);
133
136
  var wrappered = [];
@@ -152,7 +155,9 @@ var Wrapper = function Wrapper(_ref3) {
152
155
  // @ts-ignore
153
156
  style: _objectSpread(_objectSpread({}, style), {}, {
154
157
  // If there is a border or other size-related design, it may cause calculation issues
155
- flexBasis: currentSize
158
+ flexBasis: currentSize,
159
+ // animation 模式下受控尺寸变更走 flex-basis 过渡;拖拽期间为 undefined 保证跟手
160
+ transition: itemTransition
156
161
  }),
157
162
  min: min,
158
163
  max: max,
@@ -193,15 +198,64 @@ var Wrapper = function Wrapper(_ref3) {
193
198
  flexable: flexable,
194
199
  expandable: _expandable,
195
200
  onClick: onClick,
201
+ onDraggingChange: onDraggingChange,
196
202
  key: "handler-".concat(n)
197
203
  })));
198
204
  }
199
205
  });
206
+
207
+ // ── 出场动画:children 数量减少(条件渲染的面板卸载)时,保留上一次渲染的
208
+ // 尾部面板克隆,flex-basis 过渡到 0 后再真正移除,避免右栏瞬间消失导致跳变。
209
+ var prevCountRef = React.useRef(arr.length);
210
+ var prevClonesRef = React.useRef([]);
211
+ var _React$useState = React.useState([]),
212
+ _React$useState2 = _slicedToArray(_React$useState, 2),
213
+ exiting = _React$useState2[0],
214
+ setExiting = _React$useState2[1];
215
+ React.useEffect(function () {
216
+ var prevCount = prevCountRef.current;
217
+ prevCountRef.current = arr.length;
218
+ if (!animation || arr.length >= prevCount) {
219
+ return;
220
+ }
221
+ // 上一帧克隆里已带原 flex-basis(本帧 records 已不含被移除面板)
222
+ var removed = prevClonesRef.current.slice(arr.length);
223
+ if (!removed.length) {
224
+ return;
225
+ }
226
+ setExiting(removed);
227
+ // 第二阶段:下一帧 flex-basis 归 0,触发过渡
228
+ var raf = requestAnimationFrame(function () {
229
+ setExiting(function (list) {
230
+ return list.map(function (el) {
231
+ return /*#__PURE__*/React.cloneElement(el, {
232
+ style: _objectSpread(_objectSpread({}, el.props.style), {}, {
233
+ flexBasis: 0
234
+ })
235
+ });
236
+ });
237
+ });
238
+ });
239
+ var timer = window.setTimeout(function () {
240
+ return setExiting([]);
241
+ }, 320);
242
+ return function () {
243
+ // 过渡期间面板重新打开:立即丢弃残留克隆
244
+ cancelAnimationFrame(raf);
245
+ window.clearTimeout(timer);
246
+ setExiting([]);
247
+ };
248
+ }, [arr.length, animation]);
249
+
250
+ // 记录本帧克隆,供下一次渲染的移除检测读取(声明在其后:上方 effect 读到的是旧值)
251
+ React.useEffect(function () {
252
+ prevClonesRef.current = wrappered;
253
+ });
200
254
  return /*#__PURE__*/React.createElement(SplitterWrapperCtx.Provider, {
201
255
  value: {
202
256
  refs: refs
203
257
  }
204
- }, wrappered);
258
+ }, wrappered, exiting);
205
259
  };
206
260
  var Splitter = /*#__PURE__*/React.forwardRef(function (baseprops, ref) {
207
261
  var _useContext = useContext(GlobalContext),
@@ -215,6 +269,7 @@ var Splitter = /*#__PURE__*/React.forwardRef(function (baseprops, ref) {
215
269
  children = props.children,
216
270
  bordered = props.bordered,
217
271
  onResize = props.onResize,
272
+ animation = props.animation,
218
273
  rest = _objectWithoutProperties(props, _excluded2);
219
274
  var internalRef = useRef(null);
220
275
  var componentRef = ref || internalRef;
@@ -222,6 +277,14 @@ var Splitter = /*#__PURE__*/React.forwardRef(function (baseprops, ref) {
222
277
  _useState2 = _slicedToArray(_useState, 2),
223
278
  records = _useState2[0],
224
279
  setRecords = _useState2[1];
280
+
281
+ // animation 模式:拖拽期间关掉面板的 flex-basis 过渡(onMove 直接写 DOM,过渡会导致跟不
282
+ // 上鼠标);其余程序性尺寸变更(受控 size、collapsible 收展、面板增减)都走过渡。
283
+ var _React$useState3 = React.useState(false),
284
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
285
+ dragging = _React$useState4[0],
286
+ setDragging = _React$useState4[1];
287
+ var itemTransition = animation ? dragging ? undefined : 'flex-basis 0.28s cubic-bezier(0.22, 0.61, 0.36, 1)' : undefined;
225
288
  var handleClick = function handleClick(index, action) {
226
289
  var c = index - 1;
227
290
  var newRecords = _toConsumableArray(records);
@@ -239,10 +302,10 @@ var Splitter = /*#__PURE__*/React.forwardRef(function (baseprops, ref) {
239
302
  setRecords(newRecords);
240
303
  };
241
304
  var cls = clsx(prefixCls, ["".concat(prefixCls, "-").concat(layout)], _defineProperty({}, "".concat(prefixCls, "-bordered"), bordered), className);
242
- var _React$useState = React.useState(0),
243
- _React$useState2 = _slicedToArray(_React$useState, 2),
244
- totalSize = _React$useState2[0],
245
- setTotalSize = _React$useState2[1];
305
+ var _React$useState5 = React.useState(0),
306
+ _React$useState6 = _slicedToArray(_React$useState5, 2),
307
+ totalSize = _React$useState6[0],
308
+ setTotalSize = _React$useState6[1];
246
309
  var updateTotalSize = function updateTotalSize(ele) {
247
310
  if (layout === 'horizontal') {
248
311
  setTotalSize(ele.offsetWidth);
@@ -267,15 +330,35 @@ var Splitter = /*#__PURE__*/React.forwardRef(function (baseprops, ref) {
267
330
  };
268
331
  }
269
332
  }, [layout]);
333
+ var prevPanelCountRef = React.useRef(-1);
270
334
  React.useEffect(function () {
271
335
  if (totalSize) {
272
336
  var panelsSize = getPanelSize(children, {
273
337
  totalSize: totalSize,
274
338
  layout: layout
275
339
  });
340
+ // animation 模式下面板新增(条件渲染的面板挂载)时先以 0 尺寸入库,下一帧再落到
341
+ // 目标尺寸,配合 flex-basis 过渡播放入场动画;否则新面板瞬间撑开、旧面板瞬间收窄。
342
+ var prevCount = prevPanelCountRef.current;
343
+ prevPanelCountRef.current = panelsSize.length;
344
+ if (animation && prevCount >= 0 && panelsSize.length > prevCount) {
345
+ panelsSize.slice(prevCount).forEach(function (item) {
346
+ item.currentSize = 0;
347
+ });
348
+ setRecords(panelsSize);
349
+ var raf = requestAnimationFrame(function () {
350
+ setRecords(getPanelSize(children, {
351
+ totalSize: totalSize,
352
+ layout: layout
353
+ }));
354
+ });
355
+ return function () {
356
+ return cancelAnimationFrame(raf);
357
+ };
358
+ }
276
359
  setRecords(panelsSize);
277
360
  }
278
- }, [children, totalSize, layout]);
361
+ }, [children, totalSize, layout, animation]);
279
362
  return /*#__PURE__*/React.createElement("div", _extends({
280
363
  className: cls
281
364
  }, rest, {
@@ -291,7 +374,10 @@ var Splitter = /*#__PURE__*/React.forwardRef(function (baseprops, ref) {
291
374
  setRecords: setRecords,
292
375
  totalSize: totalSize,
293
376
  itemsSize: records,
294
- onClick: handleClick
377
+ onClick: handleClick,
378
+ animation: animation,
379
+ itemTransition: itemTransition,
380
+ onDraggingChange: setDragging
295
381
  }, children)));
296
382
  });
297
383
  Splitter.displayName = 'Splitter';