antd-mobile 5.40.0 → 5.41.0-alpha.1

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 (66) hide show
  1. package/2x/bundle/antd-mobile.cjs.development.js +225 -85
  2. package/2x/bundle/antd-mobile.cjs.js +6 -6
  3. package/2x/bundle/antd-mobile.es.development.js +225 -85
  4. package/2x/bundle/antd-mobile.es.js +2218 -2144
  5. package/2x/bundle/antd-mobile.umd.development.js +225 -85
  6. package/2x/bundle/antd-mobile.umd.js +7 -7
  7. package/2x/bundle/style.css +4 -1
  8. package/2x/cjs/components/calendar/calendar.d.ts +4 -1
  9. package/2x/cjs/components/calendar/calendar.js +18 -11
  10. package/2x/cjs/components/date-picker/date-picker-week-utils.js +2 -1
  11. package/2x/cjs/components/ellipsis/ellipsis.d.ts +3 -0
  12. package/2x/cjs/components/ellipsis/ellipsis.js +10 -2
  13. package/2x/cjs/components/swiper/swiper.js +1 -1
  14. package/2x/cjs/components/tabs/tabs.js +45 -13
  15. package/2x/cjs/components/virtual-input/virtual-input.css +4 -1
  16. package/2x/cjs/components/virtual-input/virtual-input.d.ts +6 -0
  17. package/2x/cjs/components/virtual-input/virtual-input.js +105 -8
  18. package/2x/es/components/calendar/calendar.d.ts +4 -1
  19. package/2x/es/components/calendar/calendar.js +19 -12
  20. package/2x/es/components/date-picker/date-picker-week-utils.js +2 -1
  21. package/2x/es/components/ellipsis/ellipsis.d.ts +3 -0
  22. package/2x/es/components/ellipsis/ellipsis.js +10 -2
  23. package/2x/es/components/swiper/swiper.js +1 -1
  24. package/2x/es/components/tabs/tabs.js +44 -12
  25. package/2x/es/components/virtual-input/virtual-input.css +4 -1
  26. package/2x/es/components/virtual-input/virtual-input.d.ts +6 -0
  27. package/2x/es/components/virtual-input/virtual-input.js +105 -8
  28. package/2x/package.json +3 -3
  29. package/bundle/antd-mobile.cjs.development.js +225 -85
  30. package/bundle/antd-mobile.cjs.js +6 -6
  31. package/bundle/antd-mobile.compatible.umd.js +1 -1
  32. package/bundle/antd-mobile.es.development.js +225 -85
  33. package/bundle/antd-mobile.es.js +2218 -2144
  34. package/bundle/antd-mobile.umd.development.js +225 -85
  35. package/bundle/antd-mobile.umd.js +7 -7
  36. package/bundle/style.css +1 -1
  37. package/cjs/components/calendar/calendar.d.ts +4 -1
  38. package/cjs/components/calendar/calendar.js +18 -11
  39. package/cjs/components/date-picker/date-picker-week-utils.js +2 -1
  40. package/cjs/components/ellipsis/ellipsis.d.ts +3 -0
  41. package/cjs/components/ellipsis/ellipsis.js +10 -2
  42. package/cjs/components/swiper/swiper.js +1 -1
  43. package/cjs/components/tabs/tabs.js +45 -13
  44. package/cjs/components/virtual-input/virtual-input.css +3 -1
  45. package/cjs/components/virtual-input/virtual-input.d.ts +6 -0
  46. package/cjs/components/virtual-input/virtual-input.js +105 -8
  47. package/es/components/calendar/calendar.d.ts +4 -1
  48. package/es/components/calendar/calendar.js +19 -12
  49. package/es/components/date-picker/date-picker-week-utils.js +2 -1
  50. package/es/components/ellipsis/ellipsis.d.ts +3 -0
  51. package/es/components/ellipsis/ellipsis.js +10 -2
  52. package/es/components/swiper/swiper.js +1 -1
  53. package/es/components/tabs/tabs.js +44 -12
  54. package/es/components/virtual-input/virtual-input.css +3 -1
  55. package/es/components/virtual-input/virtual-input.d.ts +6 -0
  56. package/es/components/virtual-input/virtual-input.js +105 -8
  57. package/package.json +3 -3
  58. package/umd/antd-mobile.js +1 -1
  59. package/2x/cjs/components/ellipsis/~ellipsis.d.ts +0 -15
  60. package/2x/cjs/components/ellipsis/~ellipsis.js +0 -161
  61. package/2x/es/components/ellipsis/~ellipsis.d.ts +0 -15
  62. package/2x/es/components/ellipsis/~ellipsis.js +0 -151
  63. package/cjs/components/ellipsis/~ellipsis.d.ts +0 -15
  64. package/cjs/components/ellipsis/~ellipsis.js +0 -161
  65. package/es/components/ellipsis/~ellipsis.d.ts +0 -15
  66. package/es/components/ellipsis/~ellipsis.js +0 -151
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { ReactNode } from 'react';
2
2
  import { NativeProps } from '../../utils/native-props';
3
3
  import { Page } from './convert';
4
4
  export declare type CalendarRef = {
@@ -14,6 +14,9 @@ export declare type CalendarProps = {
14
14
  weekStartsOn?: 'Monday' | 'Sunday';
15
15
  renderLabel?: (date: Date) => React.ReactNode;
16
16
  renderDate?: (date: Date) => React.ReactNode;
17
+ cellRender?: (oriNode: React.ReactElement, info: {
18
+ date: Date;
19
+ }) => ReactNode;
17
20
  allowClear?: boolean;
18
21
  max?: Date;
19
22
  min?: Date;
@@ -4,23 +4,23 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Calendar = void 0;
7
+ var _ahooks = require("ahooks");
8
+ var _classnames = _interopRequireDefault(require("classnames"));
9
+ var _dayjs = _interopRequireDefault(require("dayjs"));
10
+ var _isoWeek = _interopRequireDefault(require("dayjs/plugin/isoWeek"));
7
11
  var _react = _interopRequireWildcard(require("react"));
12
+ var _devLog = require("../../utils/dev-log");
8
13
  var _nativeProps = require("../../utils/native-props");
9
- var _dayjs = _interopRequireDefault(require("dayjs"));
10
- var _classnames = _interopRequireDefault(require("classnames"));
14
+ var _replaceMessage = require("../../utils/replace-message");
15
+ var _usePropsValue = require("../../utils/use-props-value");
11
16
  var _withDefaultProps = require("../../utils/with-default-props");
17
+ var _configProvider = require("../config-provider");
12
18
  var _arrowLeft = require("./arrow-left");
13
19
  var _arrowLeftDouble = require("./arrow-left-double");
14
- var _configProvider = require("../config-provider");
15
- var _isoWeek = _interopRequireDefault(require("dayjs/plugin/isoWeek"));
16
- var _ahooks = require("ahooks");
17
- var _usePropsValue = require("../../utils/use-props-value");
18
- var _replaceMessage = require("../../utils/replace-message");
19
- var _devLog = require("../../utils/dev-log");
20
20
  var _convert = require("./convert");
21
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
21
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
23
22
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
23
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24
24
  _dayjs.default.extend(_isoWeek.default);
25
25
  const classPrefix = 'adm-calendar';
26
26
  const defaultProps = {
@@ -150,7 +150,7 @@ const Calendar = (0, _react.forwardRef)((p, ref) => {
150
150
  }
151
151
  const inThisMonth = d.month() === current.month();
152
152
  const disabled = props.shouldDisableDate ? props.shouldDisableDate(d.toDate()) : maxDay && d.isAfter(maxDay, 'day') || minDay && d.isBefore(minDay, 'day');
153
- cells.push(_react.default.createElement("div", {
153
+ const originalCell = _react.default.createElement("div", {
154
154
  key: d.valueOf(),
155
155
  className: (0, _classnames.default)(`${classPrefix}-cell`, (disabled || !inThisMonth) && `${classPrefix}-cell-disabled`, inThisMonth && {
156
156
  [`${classPrefix}-cell-today`]: d.isSame(today, 'day'),
@@ -204,7 +204,14 @@ const Calendar = (0, _react.forwardRef)((p, ref) => {
204
204
  className: `${classPrefix}-cell-top`
205
205
  }, props.renderDate ? props.renderDate(d.toDate()) : d.date()), _react.default.createElement("div", {
206
206
  className: `${classPrefix}-cell-bottom`
207
- }, (_a = props.renderLabel) === null || _a === void 0 ? void 0 : _a.call(props, d.toDate()))));
207
+ }, (_a = props.renderLabel) === null || _a === void 0 ? void 0 : _a.call(props, d.toDate())));
208
+ // Wrap with Fragment to ensure key is properly set
209
+ const cellWithKey = props.cellRender ? _react.default.createElement(_react.default.Fragment, {
210
+ key: d.valueOf()
211
+ }, props.cellRender(originalCell, {
212
+ date: d.toDate()
213
+ })) : originalCell;
214
+ cells.push(cellWithKey);
208
215
  iterator = iterator.add(1, 'day');
209
216
  }
210
217
  return cells;
@@ -100,6 +100,7 @@ function convertStringArrayToDate(value) {
100
100
  const yearString = (_a = value[0]) !== null && _a !== void 0 ? _a : '1900';
101
101
  const weekString = (_b = value[1]) !== null && _b !== void 0 ? _b : '1';
102
102
  const weekdayString = (_c = value[2]) !== null && _c !== void 0 ? _c : '1';
103
- const day = (0, _dayjs.default)(`${parseInt(yearString)}-01-01`).isoWeek(parseInt(weekString)).isoWeekday(parseInt(weekdayString)).hour(0).minute(0).second(0);
103
+ // See https://github.com/ant-design/ant-design-mobile/issues/6905
104
+ const day = (0, _dayjs.default)(`${parseInt(yearString)}-01-04`).isoWeek(parseInt(weekString)).isoWeekday(parseInt(weekdayString)).hour(0).minute(0).second(0);
104
105
  return day.toDate();
105
106
  }
@@ -11,5 +11,8 @@ export declare type EllipsisProps = {
11
11
  stopPropagationForActionButtons?: PropagationEvent[];
12
12
  onContentClick?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
13
13
  defaultExpanded?: boolean;
14
+ onExpand?: (expanded: boolean, info: {
15
+ event: React.MouseEvent<HTMLAnchorElement, MouseEvent>;
16
+ }) => void;
14
17
  } & NativeProps;
15
18
  export declare const Ellipsis: FC<EllipsisProps>;
@@ -39,13 +39,21 @@ const Ellipsis = p => {
39
39
  // ========================== Expanded ==========================
40
40
  const [expanded, setExpanded] = _react.default.useState(defaultExpanded);
41
41
  const expandNode = expandText ? (0, _withStopPropagation.withStopPropagation)(stopPropagationForActionButtons, _react.default.createElement("a", {
42
- onClick: () => {
42
+ onClick: e => {
43
+ var _a;
43
44
  setExpanded(true);
45
+ (_a = props.onExpand) === null || _a === void 0 ? void 0 : _a.call(props, true, {
46
+ event: e
47
+ });
44
48
  }
45
49
  }, expandText)) : null;
46
50
  const collapseNode = collapseText ? (0, _withStopPropagation.withStopPropagation)(stopPropagationForActionButtons, _react.default.createElement("a", {
47
- onClick: () => {
51
+ onClick: e => {
52
+ var _a;
48
53
  setExpanded(false);
54
+ (_a = props.onExpand) === null || _a === void 0 ? void 0 : _a.call(props, false, {
55
+ event: e
56
+ });
49
57
  }
50
58
  }, collapseText)) : null;
51
59
  // ========================== Ellipsis ==========================
@@ -279,7 +279,7 @@ const Swiper = (0, _react.forwardRef)((0, _stagedComponents.staged)((p, ref) =>
279
279
  return _react.default.createElement(_react.default.Fragment, null, _react.default.createElement("div", {
280
280
  className: `${classPrefix}-slide-placeholder`,
281
281
  style: {
282
- width: `${startIndex * 100}%`
282
+ [isVertical ? 'height' : 'width']: `${startIndex * 100}%`
283
283
  }
284
284
  }), items);
285
285
  }
@@ -4,22 +4,22 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Tabs = exports.Tab = void 0;
7
- var _react = _interopRequireWildcard(require("react"));
8
- var _classnames = _interopRequireDefault(require("classnames"));
9
7
  var _web = require("@react-spring/web");
10
- var _nativeProps = require("../../utils/native-props");
11
- var _usePropsValue = require("../../utils/use-props-value");
12
- var _bound = require("../../utils/bound");
13
8
  var _ahooks = require("ahooks");
9
+ var _classnames = _interopRequireDefault(require("classnames"));
10
+ var _react = _interopRequireWildcard(require("react"));
11
+ var _bound = require("../../utils/bound");
12
+ var _nativeProps = require("../../utils/native-props");
13
+ var _shouldRender = require("../../utils/should-render");
14
+ var _traverseReactNode = require("../../utils/traverse-react-node");
15
+ var _useIsomorphicUpdateLayoutEffect = require("../../utils/use-isomorphic-update-layout-effect");
14
16
  var _useMutationEffect = require("../../utils/use-mutation-effect");
17
+ var _usePropsValue = require("../../utils/use-props-value");
15
18
  var _useResizeEffect = require("../../utils/use-resize-effect");
16
19
  var _withDefaultProps = require("../../utils/with-default-props");
17
- var _useIsomorphicUpdateLayoutEffect = require("../../utils/use-isomorphic-update-layout-effect");
18
- var _shouldRender = require("../../utils/should-render");
19
- var _traverseReactNode = require("../../utils/traverse-react-node");
20
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
20
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
22
21
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
22
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
23
  const classPrefix = `adm-tabs`;
24
24
  const Tab = () => {
25
25
  return null;
@@ -35,6 +35,7 @@ const Tabs = p => {
35
35
  const props = (0, _withDefaultProps.mergeProps)(defaultProps, p);
36
36
  const tabListContainerRef = (0, _react.useRef)(null);
37
37
  const activeLineRef = (0, _react.useRef)(null);
38
+ const tabRefs = (0, _react.useRef)({});
38
39
  const keyToIndexRecord = {};
39
40
  let firstActiveKey = null;
40
41
  const panes = [];
@@ -176,7 +177,7 @@ const Tabs = p => {
176
177
  });
177
178
  const {
178
179
  run: updateMask
179
- } = (0, _ahooks.useThrottleFn)((immediate = false) => {
180
+ } = (0, _ahooks.useThrottleFn)(immediate => {
180
181
  const container = tabListContainerRef.current;
181
182
  if (!container) return;
182
183
  const scrollLeft = container.scrollLeft;
@@ -207,6 +208,34 @@ const Tabs = p => {
207
208
  (0, _ahooks.useIsomorphicLayoutEffect)(() => {
208
209
  updateMask(true);
209
210
  }, []);
211
+ const handleKeyDown = e => {
212
+ const keys = Object.keys(keyToIndexRecord);
213
+ const currentIndex = keyToIndexRecord[activeKey];
214
+ const isNext = isRTL ? e.key === 'ArrowLeft' : e.key === 'ArrowRight';
215
+ const isPrev = isRTL ? e.key === 'ArrowRight' : e.key === 'ArrowLeft';
216
+ const offsetDirection = isNext ? 1 : -1;
217
+ const findNextEnabledTab = (startIndex, direction) => {
218
+ const length = keys.length;
219
+ for (let i = 0; i < length; i++) {
220
+ const index = (startIndex + direction * (i + 1) + length) % length;
221
+ const key = keys[index];
222
+ const pane = panes.find(p => p.key === key);
223
+ if (!(pane === null || pane === void 0 ? void 0 : pane.props.disabled)) return key;
224
+ }
225
+ return keys[startIndex];
226
+ };
227
+ const currentKey = findNextEnabledTab(currentIndex, offsetDirection);
228
+ if (isNext || isPrev) {
229
+ e.preventDefault();
230
+ setActiveKey(currentKey);
231
+ }
232
+ };
233
+ (0, _react.useEffect)(() => {
234
+ var _a;
235
+ if (activeKey && tabRefs.current[activeKey]) {
236
+ (_a = tabRefs.current[activeKey]) === null || _a === void 0 ? void 0 : _a.focus();
237
+ }
238
+ }, [activeKey]);
210
239
  return (0, _nativeProps.withNativeProps)(props, _react.default.createElement("div", {
211
240
  className: classPrefix,
212
241
  style: {
@@ -229,6 +258,7 @@ const Tabs = p => {
229
258
  ref: tabListContainerRef,
230
259
  scrollLeft: scrollLeft,
231
260
  onScroll: updateMask,
261
+ onKeyDown: handleKeyDown,
232
262
  role: 'tablist'
233
263
  }, _react.default.createElement(_web.animated.div, {
234
264
  ref: activeLineRef,
@@ -243,6 +273,10 @@ const Tabs = p => {
243
273
  [`${classPrefix}-tab-wrapper-stretch`]: props.stretch
244
274
  })
245
275
  }, _react.default.createElement("div", {
276
+ role: 'tab',
277
+ "aria-selected": pane.key === activeKey,
278
+ tabIndex: pane.key === activeKey ? 0 : -1,
279
+ ref: el => tabRefs.current[pane.key] = el,
246
280
  onClick: () => {
247
281
  const {
248
282
  key
@@ -256,9 +290,7 @@ const Tabs = p => {
256
290
  className: (0, _classnames.default)(`${classPrefix}-tab`, {
257
291
  [`${classPrefix}-tab-active`]: pane.key === activeKey,
258
292
  [`${classPrefix}-tab-disabled`]: pane.props.disabled
259
- }),
260
- role: 'tab',
261
- "aria-selected": pane.key === activeKey
293
+ })
262
294
  }, pane.props.title)))))), panes.map(pane => {
263
295
  if (pane.props.children === undefined) {
264
296
  return null;
@@ -65,7 +65,6 @@
65
65
  outline: none;
66
66
  }
67
67
  .adm-virtual-input:focus .adm-virtual-input-caret {
68
- display: block;
69
68
  animation-name: adm-caret-blink;
70
69
  animation-duration: 1s;
71
70
  animation-timing-function: linear;
@@ -74,6 +73,9 @@
74
73
  .adm-virtual-input-disabled {
75
74
  color: var(--disabled-color);
76
75
  }
76
+ .adm-virtual-input-caret-dragging .adm-virtual-input-caret {
77
+ animation: none !important;
78
+ }
77
79
  @keyframes adm-caret-blink {
78
80
  from {
79
81
  opacity: 1;
@@ -3,6 +3,10 @@ import React from 'react';
3
3
  import { NativeProps } from '../../utils/native-props';
4
4
  import type { InputProps } from '../input';
5
5
  import { NumberKeyboardProps } from '../number-keyboard';
6
+ export declare type Cursor = {
7
+ movable?: boolean;
8
+ onMove?: (position: number) => void;
9
+ };
6
10
  export declare type VirtualInputProps = {
7
11
  onFocus?: () => void;
8
12
  onBlur?: () => void;
@@ -10,6 +14,7 @@ export declare type VirtualInputProps = {
10
14
  keyboard?: ReactElement<NumberKeyboardProps>;
11
15
  clearable?: boolean;
12
16
  onClear?: () => void;
17
+ cursor?: Cursor;
13
18
  } & Pick<InputProps, 'value' | 'onChange' | 'placeholder' | 'disabled' | 'clearIcon'> & NativeProps<'--font-size' | '--color' | '--placeholder-color' | '--disabled-color' | '--text-align' | '--caret-width' | '--caret-color'>;
14
19
  export declare type VirtualInputRef = {
15
20
  focus: () => void;
@@ -22,6 +27,7 @@ export declare const VirtualInput: React.ForwardRefExoticComponent<{
22
27
  keyboard?: ReactElement<NumberKeyboardProps, string | React.JSXElementConstructor<any>> | undefined;
23
28
  clearable?: boolean | undefined;
24
29
  onClear?: (() => void) | undefined;
30
+ cursor?: Cursor | undefined;
25
31
  } & Pick<InputProps, "value" | "onChange" | "disabled" | "placeholder" | "clearIcon"> & {
26
32
  className?: string | undefined;
27
33
  style?: (React.CSSProperties & Partial<Record<"--color" | "--font-size" | "--placeholder-color" | "--text-align" | "--disabled-color" | "--caret-width" | "--caret-color", string>>) | undefined;
@@ -17,7 +17,10 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
17
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
18
  const classPrefix = 'adm-virtual-input';
19
19
  const defaultProps = {
20
- defaultValue: ''
20
+ defaultValue: '',
21
+ cursor: {
22
+ movable: false
23
+ }
21
24
  };
22
25
  const VirtualInput = (0, _react.forwardRef)((props, ref) => {
23
26
  const {
@@ -30,6 +33,13 @@ const VirtualInput = (0, _react.forwardRef)((props, ref) => {
30
33
  const contentRef = (0, _react.useRef)(null);
31
34
  const [hasFocus, setHasFocus] = (0, _react.useState)(false);
32
35
  const [caretPosition, setCaretPosition] = (0, _react.useState)(value.length); // 光标位置,从 0 开始,如值是 2 则表示光标在顺序下标为 2 的数字之前
36
+ const keyboardDataRef = (0, _react.useRef)({}); // 临时记录虚拟键盘输入,在下次更新时用于判断光标位置如何调整
37
+ const touchDataRef = (0, _react.useRef)(); // 记录上一次 touch 时的坐标位置
38
+ const charRef = (0, _react.useRef)(null); // 第一个字符的 DOM
39
+ const charWidthRef = (0, _react.useRef)(0); // 单个字符宽度
40
+ const caretRef = (0, _react.useRef)(null); // 光标的 DOM
41
+ const [isCaretDragging, setIsCaretDragging] = (0, _react.useState)(false);
42
+ const touchMoveTimeoutRef = (0, _react.useRef)();
33
43
  const clearIcon = (0, _withDefaultProps.mergeProp)(_react.default.createElement(_antdMobileIcons.CloseCircleFill, null), componentConfig.clearIcon, props.clearIcon);
34
44
  function scrollToEnd() {
35
45
  const root = rootRef.current;
@@ -41,6 +51,24 @@ const VirtualInput = (0, _react.forwardRef)((props, ref) => {
41
51
  if (!content) return;
42
52
  content.scrollLeft = content.clientWidth;
43
53
  }
54
+ (0, _react.useEffect)(() => {
55
+ // 记录单个字符的宽度,用于光标移动时的计算
56
+ if (charRef.current) {
57
+ charWidthRef.current = charRef.current.getBoundingClientRect().width;
58
+ }
59
+ }, [value]);
60
+ (0, _react.useEffect)(() => {
61
+ // 经过外部受控逻辑后,再调整光标位置,如果受控逻辑改动了值则光标放到最后
62
+ if (value === keyboardDataRef.current.newValue) {
63
+ if (keyboardDataRef.current.mode === 'input') {
64
+ setCaretPosition(c => c + 1);
65
+ } else if (keyboardDataRef.current.mode === 'delete') {
66
+ setCaretPosition(c => c - 1);
67
+ }
68
+ } else {
69
+ setCaretPosition(value.length);
70
+ }
71
+ }, [value]);
44
72
  (0, _ahooks.useIsomorphicLayoutEffect)(() => {
45
73
  scrollToEnd();
46
74
  }, [value]);
@@ -74,16 +102,24 @@ const VirtualInput = (0, _react.forwardRef)((props, ref) => {
74
102
  onInput: v => {
75
103
  var _a, _b;
76
104
  const newValue = value.substring(0, caretPosition) + v + value.substring(caretPosition);
105
+ // 临时记录,用于后续光标位置
106
+ keyboardDataRef.current = {
107
+ newValue,
108
+ mode: 'input'
109
+ };
77
110
  setValue(newValue);
78
- setCaretPosition(c => c + 1);
79
111
  (_b = (_a = keyboard.props).onInput) === null || _b === void 0 ? void 0 : _b.call(_a, v);
80
112
  },
81
113
  onDelete: () => {
82
114
  var _a, _b;
83
115
  if (caretPosition === 0) return;
84
116
  const newValue = value.substring(0, caretPosition - 1) + value.substring(caretPosition);
117
+ // 临时记录,用于后续光标位置
118
+ keyboardDataRef.current = {
119
+ newValue,
120
+ mode: 'delete'
121
+ };
85
122
  setValue(newValue);
86
- setCaretPosition(caretPosition - 1);
87
123
  (_b = (_a = keyboard.props).onDelete) === null || _b === void 0 ? void 0 : _b.call(_a);
88
124
  },
89
125
  visible: hasFocus,
@@ -103,23 +139,80 @@ const VirtualInput = (0, _react.forwardRef)((props, ref) => {
103
139
  });
104
140
  // 点击输入框时,将光标置于最后
105
141
  const setCaretPositionToEnd = () => {
106
- setCaretPosition(value.length);
142
+ var _a, _b;
143
+ if (caretPosition !== value.length) {
144
+ setCaretPosition(value.length);
145
+ (_b = (_a = mergedProps.cursor) === null || _a === void 0 ? void 0 : _a.onMove) === null || _b === void 0 ? void 0 : _b.call(_a, value.length);
146
+ }
107
147
  };
108
148
  // 点击单个字符时,根据点击位置置于字符前或后
109
149
  const changeCaretPosition = index => e => {
150
+ var _a, _b, _c;
151
+ if (mergedProps.disabled || !((_a = mergedProps.cursor) === null || _a === void 0 ? void 0 : _a.movable)) return;
110
152
  e.stopPropagation();
111
153
  const rect = e.target.getBoundingClientRect();
112
154
  const midX = rect.left + rect.width / 2;
113
155
  const clickX = e.clientX;
114
156
  // 点击区域是否偏右
115
157
  const isRight = clickX > midX;
116
- setCaretPosition(isRight ? index + 1 : index);
158
+ const newCaretPosition = isRight ? index + 1 : index;
159
+ setCaretPosition(newCaretPosition);
160
+ (_c = (_b = mergedProps.cursor) === null || _b === void 0 ? void 0 : _b.onMove) === null || _c === void 0 ? void 0 : _c.call(_b, newCaretPosition);
161
+ };
162
+ // 在光标附近 touchmove 时也可以调整光标位置
163
+ const handleTouchStart = e => {
164
+ var _a;
165
+ if (mergedProps.disabled || !((_a = mergedProps.cursor) === null || _a === void 0 ? void 0 : _a.movable)) return;
166
+ if (!caretRef.current) return;
167
+ const touch = e.touches[0];
168
+ const caretRect = caretRef.current.getBoundingClientRect();
169
+ const distance = Math.abs(touch.clientX - (caretRect.left + caretRect.width / 2));
170
+ if (distance < 20) {
171
+ // 20px 阈值可调整
172
+ touchDataRef.current = {
173
+ startX: touch.clientX,
174
+ startCaretPosition: caretPosition
175
+ };
176
+ } else {
177
+ touchDataRef.current = null;
178
+ }
179
+ };
180
+ const handleTouchMove = e => {
181
+ var _a, _b, _c;
182
+ if (!touchDataRef.current || !((_a = mergedProps.cursor) === null || _a === void 0 ? void 0 : _a.movable)) return;
183
+ setIsCaretDragging(true);
184
+ const touch = e.touches[0];
185
+ const deltaX = touch.clientX - touchDataRef.current.startX;
186
+ const charWidth = charWidthRef.current;
187
+ const moveChars = Math.round(deltaX / charWidth);
188
+ let newCaretPosition = touchDataRef.current.startCaretPosition + moveChars;
189
+ // 边界处理
190
+ newCaretPosition = Math.max(0, Math.min(newCaretPosition, value.length));
191
+ setCaretPosition(newCaretPosition);
192
+ (_c = (_b = mergedProps.cursor) === null || _b === void 0 ? void 0 : _b.onMove) === null || _c === void 0 ? void 0 : _c.call(_b, newCaretPosition);
193
+ // 防止 touchend 不触发
194
+ if (touchMoveTimeoutRef.current) {
195
+ clearTimeout(touchMoveTimeoutRef.current);
196
+ }
197
+ touchMoveTimeoutRef.current = setTimeout(() => {
198
+ setIsCaretDragging(false);
199
+ touchMoveTimeoutRef.current = null;
200
+ }, 500);
201
+ };
202
+ const handleTouchEnd = () => {
203
+ touchDataRef.current = null;
204
+ setIsCaretDragging(false);
205
+ if (touchMoveTimeoutRef.current) {
206
+ clearTimeout(touchMoveTimeoutRef.current);
207
+ touchMoveTimeoutRef.current = null;
208
+ }
117
209
  };
118
210
  const chars = (value + '').split('');
119
211
  return (0, _nativeProps.withNativeProps)(mergedProps, _react.default.createElement("div", {
120
212
  ref: rootRef,
121
213
  className: (0, _classnames.default)(classPrefix, {
122
- [`${classPrefix}-disabled`]: mergedProps.disabled
214
+ [`${classPrefix}-disabled`]: mergedProps.disabled,
215
+ [`${classPrefix}-caret-dragging`]: isCaretDragging
123
216
  }),
124
217
  tabIndex: mergedProps.disabled ? undefined : 0,
125
218
  role: 'textbox',
@@ -131,13 +224,18 @@ const VirtualInput = (0, _react.forwardRef)((props, ref) => {
131
224
  ref: contentRef,
132
225
  "aria-disabled": mergedProps.disabled,
133
226
  "aria-label": mergedProps.placeholder,
134
- onClick: setCaretPositionToEnd
227
+ onClick: setCaretPositionToEnd,
228
+ onTouchStart: handleTouchStart,
229
+ onTouchMove: handleTouchMove,
230
+ onTouchEnd: handleTouchEnd
135
231
  }, chars.slice(0, caretPosition).map((i, index) => _react.default.createElement("span", {
232
+ ref: index === 0 ? charRef : undefined,
136
233
  key: index,
137
234
  onClick: changeCaretPosition(index)
138
235
  }, i)), _react.default.createElement("div", {
139
236
  className: `${classPrefix}-caret-container`
140
237
  }, hasFocus && _react.default.createElement("div", {
238
+ ref: caretRef,
141
239
  className: `${classPrefix}-caret`
142
240
  })), chars.slice(caretPosition).map((i, index) => _react.default.createElement("span", {
143
241
  key: index,
@@ -148,7 +246,6 @@ const VirtualInput = (0, _react.forwardRef)((props, ref) => {
148
246
  var _a;
149
247
  e.stopPropagation();
150
248
  setValue('');
151
- setCaretPosition(0);
152
249
  (_a = mergedProps.onClear) === null || _a === void 0 ? void 0 : _a.call(mergedProps);
153
250
  },
154
251
  role: 'button',
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { ReactNode } from 'react';
2
2
  import { NativeProps } from '../../utils/native-props';
3
3
  import { Page } from './convert';
4
4
  export declare type CalendarRef = {
@@ -14,6 +14,9 @@ export declare type CalendarProps = {
14
14
  weekStartsOn?: 'Monday' | 'Sunday';
15
15
  renderLabel?: (date: Date) => React.ReactNode;
16
16
  renderDate?: (date: Date) => React.ReactNode;
17
+ cellRender?: (oriNode: React.ReactElement, info: {
18
+ date: Date;
19
+ }) => ReactNode;
17
20
  allowClear?: boolean;
18
21
  max?: Date;
19
22
  min?: Date;
@@ -1,17 +1,17 @@
1
- import React, { forwardRef, useState, useImperativeHandle, useMemo, useEffect } from 'react';
2
- import { withNativeProps } from '../../utils/native-props';
3
- import dayjs from 'dayjs';
1
+ import { useUpdateEffect } from 'ahooks';
4
2
  import classNames from 'classnames';
3
+ import dayjs from 'dayjs';
4
+ import isoWeek from 'dayjs/plugin/isoWeek';
5
+ import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react';
6
+ import { devWarning } from '../../utils/dev-log';
7
+ import { withNativeProps } from '../../utils/native-props';
8
+ import { replaceMessage } from '../../utils/replace-message';
9
+ import { usePropsValue } from '../../utils/use-props-value';
5
10
  import { mergeProps } from '../../utils/with-default-props';
11
+ import { useConfig } from '../config-provider';
6
12
  import { ArrowLeft } from './arrow-left';
7
13
  import { ArrowLeftDouble } from './arrow-left-double';
8
- import { useConfig } from '../config-provider';
9
- import isoWeek from 'dayjs/plugin/isoWeek';
10
- import { useUpdateEffect } from 'ahooks';
11
- import { usePropsValue } from '../../utils/use-props-value';
12
- import { replaceMessage } from '../../utils/replace-message';
13
- import { devWarning } from '../../utils/dev-log';
14
- import { convertValueToRange, convertPageToDayjs } from './convert';
14
+ import { convertPageToDayjs, convertValueToRange } from './convert';
15
15
  dayjs.extend(isoWeek);
16
16
  const classPrefix = 'adm-calendar';
17
17
  const defaultProps = {
@@ -141,7 +141,7 @@ export const Calendar = forwardRef((p, ref) => {
141
141
  }
142
142
  const inThisMonth = d.month() === current.month();
143
143
  const disabled = props.shouldDisableDate ? props.shouldDisableDate(d.toDate()) : maxDay && d.isAfter(maxDay, 'day') || minDay && d.isBefore(minDay, 'day');
144
- cells.push(React.createElement("div", {
144
+ const originalCell = React.createElement("div", {
145
145
  key: d.valueOf(),
146
146
  className: classNames(`${classPrefix}-cell`, (disabled || !inThisMonth) && `${classPrefix}-cell-disabled`, inThisMonth && {
147
147
  [`${classPrefix}-cell-today`]: d.isSame(today, 'day'),
@@ -195,7 +195,14 @@ export const Calendar = forwardRef((p, ref) => {
195
195
  className: `${classPrefix}-cell-top`
196
196
  }, props.renderDate ? props.renderDate(d.toDate()) : d.date()), React.createElement("div", {
197
197
  className: `${classPrefix}-cell-bottom`
198
- }, (_a = props.renderLabel) === null || _a === void 0 ? void 0 : _a.call(props, d.toDate()))));
198
+ }, (_a = props.renderLabel) === null || _a === void 0 ? void 0 : _a.call(props, d.toDate())));
199
+ // Wrap with Fragment to ensure key is properly set
200
+ const cellWithKey = props.cellRender ? React.createElement(React.Fragment, {
201
+ key: d.valueOf()
202
+ }, props.cellRender(originalCell, {
203
+ date: d.toDate()
204
+ })) : originalCell;
205
+ cells.push(cellWithKey);
199
206
  iterator = iterator.add(1, 'day');
200
207
  }
201
208
  return cells;
@@ -91,6 +91,7 @@ export function convertStringArrayToDate(value) {
91
91
  const yearString = (_a = value[0]) !== null && _a !== void 0 ? _a : '1900';
92
92
  const weekString = (_b = value[1]) !== null && _b !== void 0 ? _b : '1';
93
93
  const weekdayString = (_c = value[2]) !== null && _c !== void 0 ? _c : '1';
94
- const day = dayjs(`${parseInt(yearString)}-01-01`).isoWeek(parseInt(weekString)).isoWeekday(parseInt(weekdayString)).hour(0).minute(0).second(0);
94
+ // See https://github.com/ant-design/ant-design-mobile/issues/6905
95
+ const day = dayjs(`${parseInt(yearString)}-01-04`).isoWeek(parseInt(weekString)).isoWeekday(parseInt(weekdayString)).hour(0).minute(0).second(0);
95
96
  return day.toDate();
96
97
  }
@@ -11,5 +11,8 @@ export declare type EllipsisProps = {
11
11
  stopPropagationForActionButtons?: PropagationEvent[];
12
12
  onContentClick?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
13
13
  defaultExpanded?: boolean;
14
+ onExpand?: (expanded: boolean, info: {
15
+ event: React.MouseEvent<HTMLAnchorElement, MouseEvent>;
16
+ }) => void;
14
17
  } & NativeProps;
15
18
  export declare const Ellipsis: FC<EllipsisProps>;
@@ -32,13 +32,21 @@ export const Ellipsis = p => {
32
32
  // ========================== Expanded ==========================
33
33
  const [expanded, setExpanded] = React.useState(defaultExpanded);
34
34
  const expandNode = expandText ? withStopPropagation(stopPropagationForActionButtons, React.createElement("a", {
35
- onClick: () => {
35
+ onClick: e => {
36
+ var _a;
36
37
  setExpanded(true);
38
+ (_a = props.onExpand) === null || _a === void 0 ? void 0 : _a.call(props, true, {
39
+ event: e
40
+ });
37
41
  }
38
42
  }, expandText)) : null;
39
43
  const collapseNode = collapseText ? withStopPropagation(stopPropagationForActionButtons, React.createElement("a", {
40
- onClick: () => {
44
+ onClick: e => {
45
+ var _a;
41
46
  setExpanded(false);
47
+ (_a = props.onExpand) === null || _a === void 0 ? void 0 : _a.call(props, false, {
48
+ event: e
49
+ });
42
50
  }
43
51
  }, collapseText)) : null;
44
52
  // ========================== Ellipsis ==========================
@@ -270,7 +270,7 @@ export const Swiper = forwardRef(staged((p, ref) => {
270
270
  return React.createElement(React.Fragment, null, React.createElement("div", {
271
271
  className: `${classPrefix}-slide-placeholder`,
272
272
  style: {
273
- width: `${startIndex * 100}%`
273
+ [isVertical ? 'height' : 'width']: `${startIndex * 100}%`
274
274
  }
275
275
  }), items);
276
276
  }