antd-mobile 5.41.1 → 5.42.0-alpha.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.
Files changed (54) hide show
  1. package/2x/bundle/antd-mobile.cjs.development.js +65 -51
  2. package/2x/bundle/antd-mobile.cjs.js +6 -6
  3. package/2x/bundle/antd-mobile.es.development.js +65 -51
  4. package/2x/bundle/antd-mobile.es.js +1534 -1524
  5. package/2x/bundle/antd-mobile.umd.development.js +65 -51
  6. package/2x/bundle/antd-mobile.umd.js +6 -6
  7. package/2x/bundle/style.css +9 -2
  8. package/2x/cjs/components/dialog/dialog.d.ts +2 -2
  9. package/2x/cjs/components/dialog/dialog.js +3 -3
  10. package/2x/cjs/components/modal/modal.d.ts +2 -2
  11. package/2x/cjs/components/modal/modal.js +4 -4
  12. package/2x/cjs/components/number-keyboard/number-keyboard.js +18 -21
  13. package/2x/cjs/components/virtual-input/use-click-outside.d.ts +2 -0
  14. package/2x/cjs/components/virtual-input/use-click-outside.js +25 -0
  15. package/2x/cjs/components/virtual-input/virtual-input.css +9 -2
  16. package/2x/cjs/components/virtual-input/virtual-input.js +32 -30
  17. package/2x/es/components/dialog/dialog.d.ts +2 -2
  18. package/2x/es/components/dialog/dialog.js +3 -3
  19. package/2x/es/components/modal/modal.d.ts +2 -2
  20. package/2x/es/components/modal/modal.js +4 -4
  21. package/2x/es/components/number-keyboard/number-keyboard.js +18 -21
  22. package/2x/es/components/virtual-input/use-click-outside.d.ts +2 -0
  23. package/2x/es/components/virtual-input/use-click-outside.js +18 -0
  24. package/2x/es/components/virtual-input/virtual-input.css +9 -2
  25. package/2x/es/components/virtual-input/virtual-input.js +32 -30
  26. package/2x/package.json +1 -1
  27. package/bundle/antd-mobile.cjs.development.js +65 -51
  28. package/bundle/antd-mobile.cjs.js +6 -6
  29. package/bundle/antd-mobile.compatible.umd.js +1 -1
  30. package/bundle/antd-mobile.es.development.js +65 -51
  31. package/bundle/antd-mobile.es.js +1534 -1524
  32. package/bundle/antd-mobile.umd.development.js +65 -51
  33. package/bundle/antd-mobile.umd.js +6 -6
  34. package/bundle/style.css +1 -1
  35. package/cjs/components/dialog/dialog.d.ts +2 -2
  36. package/cjs/components/dialog/dialog.js +3 -3
  37. package/cjs/components/modal/modal.d.ts +2 -2
  38. package/cjs/components/modal/modal.js +4 -4
  39. package/cjs/components/number-keyboard/number-keyboard.js +18 -21
  40. package/cjs/components/virtual-input/use-click-outside.d.ts +2 -0
  41. package/cjs/components/virtual-input/use-click-outside.js +25 -0
  42. package/cjs/components/virtual-input/virtual-input.css +8 -2
  43. package/cjs/components/virtual-input/virtual-input.js +32 -30
  44. package/es/components/dialog/dialog.d.ts +2 -2
  45. package/es/components/dialog/dialog.js +3 -3
  46. package/es/components/modal/modal.d.ts +2 -2
  47. package/es/components/modal/modal.js +4 -4
  48. package/es/components/number-keyboard/number-keyboard.js +18 -21
  49. package/es/components/virtual-input/use-click-outside.d.ts +2 -0
  50. package/es/components/virtual-input/use-click-outside.js +18 -0
  51. package/es/components/virtual-input/virtual-input.css +8 -2
  52. package/es/components/virtual-input/virtual-input.js +32 -30
  53. package/package.json +1 -1
  54. package/umd/antd-mobile.js +1 -1
@@ -6,6 +6,7 @@ import { withNativeProps } from '../../utils/native-props';
6
6
  import { usePropsValue } from '../../utils/use-props-value';
7
7
  import { mergeProp, mergeProps } from '../../utils/with-default-props';
8
8
  import { useConfig } from '../config-provider';
9
+ import useClickOutside from './use-click-outside';
9
10
  const classPrefix = 'adm-virtual-input';
10
11
  const defaultProps = {
11
12
  defaultValue: '',
@@ -33,13 +34,10 @@ export const VirtualInput = forwardRef((props, ref) => {
33
34
  const touchMoveTimeoutRef = useRef();
34
35
  const clearIcon = mergeProp(React.createElement(CloseCircleFill, null), componentConfig.clearIcon, props.clearIcon);
35
36
  function scrollToEnd() {
36
- const root = rootRef.current;
37
- if (!root) return;
38
- if (document.activeElement !== root) {
37
+ const content = contentRef.current;
38
+ if (!content) {
39
39
  return;
40
40
  }
41
- const content = contentRef.current;
42
- if (!content) return;
43
41
  content.scrollLeft = content.clientWidth;
44
42
  }
45
43
  useEffect(() => {
@@ -71,23 +69,29 @@ export const VirtualInput = forwardRef((props, ref) => {
71
69
  useImperativeHandle(ref, () => ({
72
70
  focus: () => {
73
71
  var _a;
74
- (_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.focus();
72
+ (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.focus();
75
73
  },
76
74
  blur: () => {
77
75
  var _a;
78
- (_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.blur();
76
+ (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.blur();
77
+ setBlur();
79
78
  }
80
79
  }));
81
- function onFocus() {
80
+ function setFocus() {
82
81
  var _a;
82
+ if (hasFocus) return;
83
83
  setHasFocus(true);
84
84
  (_a = mergedProps.onFocus) === null || _a === void 0 ? void 0 : _a.call(mergedProps);
85
85
  }
86
- function onBlur() {
86
+ function setBlur() {
87
87
  var _a;
88
+ if (!hasFocus) return;
88
89
  setHasFocus(false);
89
90
  (_a = mergedProps.onBlur) === null || _a === void 0 ? void 0 : _a.call(mergedProps);
90
91
  }
92
+ useClickOutside(() => {
93
+ setBlur();
94
+ }, rootRef);
91
95
  const keyboard = mergedProps.keyboard;
92
96
  const keyboardElement = keyboard && React.cloneElement(keyboard, {
93
97
  onInput: v => {
@@ -115,26 +119,20 @@ export const VirtualInput = forwardRef((props, ref) => {
115
119
  },
116
120
  visible: hasFocus,
117
121
  onClose: () => {
118
- var _a, _b, _c, _d;
119
- const activeElement = document.activeElement;
120
- // Long press makes `activeElement` to be the child of rootRef
121
- // We will trigger blur on the child element instead
122
- if (activeElement && ((_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.contains(activeElement))) {
123
- activeElement.blur();
124
- } else {
125
- (_b = rootRef.current) === null || _b === void 0 ? void 0 : _b.blur();
126
- }
127
- (_d = (_c = keyboard.props).onClose) === null || _d === void 0 ? void 0 : _d.call(_c);
122
+ var _a, _b;
123
+ setBlur();
124
+ (_b = (_a = keyboard.props).onClose) === null || _b === void 0 ? void 0 : _b.call(_a);
128
125
  },
129
126
  getContainer: null
130
127
  });
131
128
  // 点击输入框时,将光标置于最后
132
- const setCaretPositionToEnd = () => {
133
- var _a, _b;
129
+ const setCaretPositionToEnd = e => {
130
+ var _a, _b, _c;
134
131
  if (caretPosition !== value.length) {
135
132
  setCaretPosition(value.length);
136
133
  (_b = (_a = mergedProps.cursor) === null || _a === void 0 ? void 0 : _a.onMove) === null || _b === void 0 ? void 0 : _b.call(_a, value.length);
137
134
  }
135
+ (_c = mergedProps.onClick) === null || _c === void 0 ? void 0 : _c.call(mergedProps, e);
138
136
  };
139
137
  // 点击单个字符时,根据点击位置置于字符前或后
140
138
  const changeCaretPosition = index => e => {
@@ -203,23 +201,27 @@ export const VirtualInput = forwardRef((props, ref) => {
203
201
  ref: rootRef,
204
202
  className: classNames(classPrefix, {
205
203
  [`${classPrefix}-disabled`]: mergedProps.disabled,
206
- [`${classPrefix}-caret-dragging`]: isCaretDragging
207
- }),
208
- tabIndex: mergedProps.disabled ? undefined : 0,
209
- role: 'textbox',
210
- onFocus: onFocus,
211
- onBlur: onBlur,
212
- onClick: mergedProps.onClick
204
+ [`${classPrefix}-caret-dragging`]: isCaretDragging,
205
+ [`${classPrefix}-focused`]: hasFocus
206
+ })
213
207
  }, React.createElement("div", {
214
208
  className: `${classPrefix}-content`,
215
209
  ref: contentRef,
216
210
  "aria-disabled": mergedProps.disabled,
217
- "aria-label": mergedProps.placeholder,
211
+ "aria-label": value || mergedProps.placeholder,
212
+ role: 'textbox',
213
+ tabIndex: mergedProps.disabled ? undefined : 0,
214
+ // note: 这里增加 onFocus 有两个目的:
215
+ // 1. 在安卓 talkback 模式下,role=textbox 的元素双击后只会触发 focus 而非 click
216
+ // 2. 处理 content 框点击、单个字符点击时,不用再额外处理 focus 逻辑,因为 focus 事件会先触发
217
+ onFocus: setFocus,
218
218
  onClick: setCaretPositionToEnd,
219
219
  onTouchStart: handleTouchStart,
220
220
  onTouchMove: handleTouchMove,
221
221
  onTouchEnd: handleTouchEnd
222
- }, chars.slice(0, caretPosition).map((i, index) => React.createElement("span", {
222
+ }, React.createElement("span", {
223
+ className: `${classPrefix}-trap`
224
+ }), chars.slice(0, caretPosition).map((i, index) => React.createElement("span", {
223
225
  ref: index === 0 ? charRef : undefined,
224
226
  key: index,
225
227
  onClick: changeCaretPosition(index)
package/2x/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antd-mobile",
3
- "version": "5.41.1",
3
+ "version": "5.42.0-alpha.0",
4
4
  "homepage": "https://github.com/ant-design/ant-design-mobile#readme",
5
5
  "bugs": {
6
6
  "url": "https://github.com/ant-design/ant-design-mobile/issues"
@@ -23207,7 +23207,6 @@ const NumberKeyboard = (p) => {
23207
23207
  };
23208
23208
  const onKeyPress = (e2, key) => {
23209
23209
  var _a, _b;
23210
- e2.preventDefault();
23211
23210
  switch (key) {
23212
23211
  case "BACKSPACE":
23213
23212
  onDelete === null || onDelete === void 0 ? void 0 : onDelete();
@@ -23245,6 +23244,15 @@ const NumberKeyboard = (p) => {
23245
23244
  tabIndex: -1
23246
23245
  }, React$3.createElement(DownOutline, null)));
23247
23246
  };
23247
+ const onBackspaceTouchStart = () => {
23248
+ stopContinueClear();
23249
+ startContinueClear();
23250
+ };
23251
+ const onBackspaceTouchEnd = (e2) => {
23252
+ e2.preventDefault();
23253
+ stopContinueClear();
23254
+ onKeyPress(e2, "BACKSPACE");
23255
+ };
23248
23256
  const renderKey = (key, index2) => {
23249
23257
  const isNumberKey = /^\d$/.test(key);
23250
23258
  const isBackspace = key === "BACKSPACE";
@@ -23262,17 +23270,13 @@ const NumberKeyboard = (p) => {
23262
23270
  key,
23263
23271
  className,
23264
23272
  // 仅为 backspace 绑定,支持长按快速删除
23265
- onTouchStart: isBackspace ? () => {
23266
- stopContinueClear();
23267
- startContinueClear();
23268
- } : void 0,
23269
- onTouchEnd: isBackspace ? (e2) => {
23270
- stopContinueClear();
23271
- onKeyPress(e2, key);
23272
- } : void 0,
23273
+ onTouchStart: isBackspace ? onBackspaceTouchStart : void 0,
23274
+ onTouchEnd: isBackspace ? onBackspaceTouchEnd : void 0,
23275
+ onTouchCancel: isBackspace ? stopContinueClear : void 0,
23273
23276
  // <div role="button" title="1" onTouchEnd={e => {}}>1</div> 安卓上 talback 可读不可点
23274
23277
  // see https://ua-gilded-eef7f9.netlify.app/grid-button-bug.html
23275
- // 所以还是绑定 click,通过 touchEnd preventDefault 防重复触发
23278
+ // 所以普通按钮绑定 click 事件,而 backspace 仍然额外绑定 touch 事件支持长按删除
23279
+ // backspace touchend 时会 preventDefault 阻止其后续 click 事件
23276
23280
  onClick: (e2) => {
23277
23281
  stopContinueClear();
23278
23282
  onKeyPress(e2, key);
@@ -23291,10 +23295,7 @@ const NumberKeyboard = (p) => {
23291
23295
  forceRender: props.forceRender
23292
23296
  }, withNativeProps(props, React$3.createElement("div", {
23293
23297
  ref: keyboardRef,
23294
- className: classPrefix$x,
23295
- onMouseDown: (e2) => {
23296
- e2.preventDefault();
23297
- }
23298
+ className: classPrefix$x
23298
23299
  }, renderHeader(), React$3.createElement("div", {
23299
23300
  className: `${classPrefix$x}-wrapper`
23300
23301
  }, React$3.createElement("div", {
@@ -23305,13 +23306,9 @@ const NumberKeyboard = (p) => {
23305
23306
  className: `${classPrefix$x}-confirm`
23306
23307
  }, React$3.createElement("div", {
23307
23308
  className: `${classPrefix$x}-key ${classPrefix$x}-key-extra ${classPrefix$x}-key-bs`,
23308
- onTouchStart: () => {
23309
- startContinueClear();
23310
- },
23311
- onTouchEnd: (e2) => {
23312
- stopContinueClear();
23313
- onKeyPress(e2, "BACKSPACE");
23314
- },
23309
+ onTouchStart: onBackspaceTouchStart,
23310
+ onTouchEnd: onBackspaceTouchEnd,
23311
+ onTouchCancel: stopContinueClear,
23315
23312
  onClick: (e2) => {
23316
23313
  stopContinueClear();
23317
23314
  onKeyPress(e2, "BACKSPACE");
@@ -27595,6 +27592,20 @@ const Multiple = (p) => {
27595
27592
  const index = attachPropertiesToComponent(TreeSelect, {
27596
27593
  Multiple
27597
27594
  });
27595
+ function useClickOutside(handler, ref2) {
27596
+ React$3.useEffect(() => {
27597
+ function handleClick(event) {
27598
+ if (!ref2.current || ref2.current.contains(event.target)) {
27599
+ return;
27600
+ }
27601
+ handler(event);
27602
+ }
27603
+ document.addEventListener("click", handleClick, true);
27604
+ return () => {
27605
+ document.removeEventListener("click", handleClick, true);
27606
+ };
27607
+ }, [handler, ref2]);
27608
+ }
27598
27609
  const classPrefix$2 = "adm-virtual-input";
27599
27610
  const defaultProps$2 = {
27600
27611
  defaultValue: "",
@@ -27622,15 +27633,10 @@ const VirtualInput = React$3.forwardRef((props, ref2) => {
27622
27633
  const touchMoveTimeoutRef = React$3.useRef();
27623
27634
  const clearIcon = mergeProp(React$3.createElement(CloseCircleFill, null), componentConfig.clearIcon, props.clearIcon);
27624
27635
  function scrollToEnd() {
27625
- const root2 = rootRef.current;
27626
- if (!root2)
27627
- return;
27628
- if (document.activeElement !== root2) {
27629
- return;
27630
- }
27631
27636
  const content = contentRef.current;
27632
- if (!content)
27637
+ if (!content) {
27633
27638
  return;
27639
+ }
27634
27640
  content.scrollLeft = content.clientWidth;
27635
27641
  }
27636
27642
  React$3.useEffect(() => {
@@ -27660,23 +27666,31 @@ const VirtualInput = React$3.forwardRef((props, ref2) => {
27660
27666
  React$3.useImperativeHandle(ref2, () => ({
27661
27667
  focus: () => {
27662
27668
  var _a;
27663
- (_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.focus();
27669
+ (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.focus();
27664
27670
  },
27665
27671
  blur: () => {
27666
27672
  var _a;
27667
- (_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.blur();
27673
+ (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.blur();
27674
+ setBlur();
27668
27675
  }
27669
27676
  }));
27670
- function onFocus() {
27677
+ function setFocus() {
27671
27678
  var _a;
27679
+ if (hasFocus)
27680
+ return;
27672
27681
  setHasFocus(true);
27673
27682
  (_a = mergedProps.onFocus) === null || _a === void 0 ? void 0 : _a.call(mergedProps);
27674
27683
  }
27675
- function onBlur() {
27684
+ function setBlur() {
27676
27685
  var _a;
27686
+ if (!hasFocus)
27687
+ return;
27677
27688
  setHasFocus(false);
27678
27689
  (_a = mergedProps.onBlur) === null || _a === void 0 ? void 0 : _a.call(mergedProps);
27679
27690
  }
27691
+ useClickOutside(() => {
27692
+ setBlur();
27693
+ }, rootRef);
27680
27694
  const keyboard = mergedProps.keyboard;
27681
27695
  const keyboardElement = keyboard && React$3.cloneElement(keyboard, {
27682
27696
  onInput: (v) => {
@@ -27703,23 +27717,19 @@ const VirtualInput = React$3.forwardRef((props, ref2) => {
27703
27717
  },
27704
27718
  visible: hasFocus,
27705
27719
  onClose: () => {
27706
- var _a, _b, _c, _d;
27707
- const activeElement = document.activeElement;
27708
- if (activeElement && ((_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.contains(activeElement))) {
27709
- activeElement.blur();
27710
- } else {
27711
- (_b = rootRef.current) === null || _b === void 0 ? void 0 : _b.blur();
27712
- }
27713
- (_d = (_c = keyboard.props).onClose) === null || _d === void 0 ? void 0 : _d.call(_c);
27720
+ var _a, _b;
27721
+ setBlur();
27722
+ (_b = (_a = keyboard.props).onClose) === null || _b === void 0 ? void 0 : _b.call(_a);
27714
27723
  },
27715
27724
  getContainer: null
27716
27725
  });
27717
- const setCaretPositionToEnd = () => {
27718
- var _a, _b;
27726
+ const setCaretPositionToEnd = (e2) => {
27727
+ var _a, _b, _c;
27719
27728
  if (caretPosition !== value.length) {
27720
27729
  setCaretPosition(value.length);
27721
27730
  (_b = (_a = mergedProps.cursor) === null || _a === void 0 ? void 0 : _a.onMove) === null || _b === void 0 ? void 0 : _b.call(_a, value.length);
27722
27731
  }
27732
+ (_c = mergedProps.onClick) === null || _c === void 0 ? void 0 : _c.call(mergedProps, e2);
27723
27733
  };
27724
27734
  const changeCaretPosition = (index2) => (e2) => {
27725
27735
  var _a, _b, _c;
@@ -27786,23 +27796,27 @@ const VirtualInput = React$3.forwardRef((props, ref2) => {
27786
27796
  ref: rootRef,
27787
27797
  className: classNames(classPrefix$2, {
27788
27798
  [`${classPrefix$2}-disabled`]: mergedProps.disabled,
27789
- [`${classPrefix$2}-caret-dragging`]: isCaretDragging
27790
- }),
27791
- tabIndex: mergedProps.disabled ? void 0 : 0,
27792
- role: "textbox",
27793
- onFocus,
27794
- onBlur,
27795
- onClick: mergedProps.onClick
27799
+ [`${classPrefix$2}-caret-dragging`]: isCaretDragging,
27800
+ [`${classPrefix$2}-focused`]: hasFocus
27801
+ })
27796
27802
  }, React$3.createElement("div", {
27797
27803
  className: `${classPrefix$2}-content`,
27798
27804
  ref: contentRef,
27799
27805
  "aria-disabled": mergedProps.disabled,
27800
- "aria-label": mergedProps.placeholder,
27806
+ "aria-label": value || mergedProps.placeholder,
27807
+ role: "textbox",
27808
+ tabIndex: mergedProps.disabled ? void 0 : 0,
27809
+ // note: 这里增加 onFocus 有两个目的:
27810
+ // 1. 在安卓 talkback 模式下,role=textbox 的元素双击后只会触发 focus 而非 click
27811
+ // 2. 处理 content 框点击、单个字符点击时,不用再额外处理 focus 逻辑,因为 focus 事件会先触发
27812
+ onFocus: setFocus,
27801
27813
  onClick: setCaretPositionToEnd,
27802
27814
  onTouchStart: handleTouchStart,
27803
27815
  onTouchMove: handleTouchMove,
27804
27816
  onTouchEnd: handleTouchEnd
27805
- }, chars.slice(0, caretPosition).map((i2, index2) => React$3.createElement("span", {
27817
+ }, React$3.createElement("span", {
27818
+ className: `${classPrefix$2}-trap`
27819
+ }), chars.slice(0, caretPosition).map((i2, index2) => React$3.createElement("span", {
27806
27820
  ref: index2 === 0 ? charRef : void 0,
27807
27821
  key: index2,
27808
27822
  onClick: changeCaretPosition(index2)