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
@@ -5718,6 +5718,13 @@ a.adm-list-item:active:not(.adm-list-item-disabled):after {
5718
5718
  display: none;
5719
5719
  }
5720
5720
 
5721
+ .adm-virtual-input-trap {
5722
+ width: 20px;
5723
+ height: 20px;
5724
+ position: absolute;
5725
+ opacity: 0;
5726
+ }
5727
+
5721
5728
  .adm-virtual-input-placeholder {
5722
5729
  display: block;
5723
5730
  position: absolute;
@@ -5751,11 +5758,11 @@ a.adm-list-item:active:not(.adm-list-item-disabled):after {
5751
5758
  z-index: 1;
5752
5759
  }
5753
5760
 
5754
- .adm-virtual-input:focus {
5761
+ .adm-virtual-input-focused {
5755
5762
  outline: none;
5756
5763
  }
5757
5764
 
5758
- .adm-virtual-input:focus .adm-virtual-input-caret {
5765
+ .adm-virtual-input-focused .adm-virtual-input-caret {
5759
5766
  animation-name: adm-caret-blink;
5760
5767
  animation-duration: 1s;
5761
5768
  animation-timing-function: linear;
@@ -1,7 +1,7 @@
1
1
  import type { FC, ReactNode } from 'react';
2
- import { Action } from './dialog-action-button';
3
2
  import { NativeProps } from '../../utils/native-props';
4
3
  import { CenterPopupProps } from '../center-popup';
4
+ import { Action } from './dialog-action-button';
5
5
  export declare type DialogProps = Pick<CenterPopupProps, 'afterClose' | 'afterShow' | 'bodyClassName' | 'bodyStyle' | 'destroyOnClose' | 'disableBodyScroll' | 'forceRender' | 'getContainer' | 'maskClassName' | 'maskStyle' | 'stopPropagation' | 'visible'> & {
6
6
  image?: string;
7
7
  header?: ReactNode;
@@ -12,5 +12,5 @@ export declare type DialogProps = Pick<CenterPopupProps, 'afterClose' | 'afterSh
12
12
  onClose?: () => void;
13
13
  closeOnAction?: boolean;
14
14
  closeOnMaskClick?: boolean;
15
- } & NativeProps;
15
+ } & NativeProps<'--background-color' | '--border-radius' | '--max-width' | '--min-width' | '--z-index'>;
16
16
  export declare const Dialog: FC<DialogProps>;
@@ -5,13 +5,13 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.Dialog = void 0;
7
7
  var _tslib = require("tslib");
8
+ var _classnames = _interopRequireDefault(require("classnames"));
8
9
  var _react = _interopRequireDefault(require("react"));
9
10
  var _withDefaultProps = require("../../utils/with-default-props");
10
- var _classnames = _interopRequireDefault(require("classnames"));
11
- var _dialogActionButton = require("./dialog-action-button");
12
- var _image = _interopRequireDefault(require("../image"));
13
11
  var _autoCenter = _interopRequireDefault(require("../auto-center"));
14
12
  var _centerPopup = _interopRequireDefault(require("../center-popup"));
13
+ var _image = _interopRequireDefault(require("../image"));
14
+ var _dialogActionButton = require("./dialog-action-button");
15
15
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
16
  const defaultProps = {
17
17
  actions: [],
@@ -1,7 +1,7 @@
1
1
  import type { FC, ReactNode } from 'react';
2
- import { Action } from './modal-action-button';
3
2
  import { NativeProps } from '../../utils/native-props';
4
3
  import { CenterPopupProps } from '../center-popup';
4
+ import { Action } from './modal-action-button';
5
5
  export declare type ModalProps = Pick<CenterPopupProps, 'afterClose' | 'afterShow' | 'bodyClassName' | 'bodyStyle' | 'destroyOnClose' | 'disableBodyScroll' | 'forceRender' | 'getContainer' | 'maskClassName' | 'maskStyle' | 'stopPropagation' | 'visible'> & {
6
6
  image?: string;
7
7
  header?: ReactNode;
@@ -13,5 +13,5 @@ export declare type ModalProps = Pick<CenterPopupProps, 'afterClose' | 'afterSho
13
13
  closeOnAction?: boolean;
14
14
  closeOnMaskClick?: boolean;
15
15
  showCloseButton?: boolean;
16
- } & NativeProps;
16
+ } & NativeProps<'--background-color' | '--border-radius' | '--max-width' | '--min-width' | '--z-index'>;
17
17
  export declare const Modal: FC<ModalProps>;
@@ -5,14 +5,14 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.Modal = void 0;
7
7
  var _tslib = require("tslib");
8
+ var _classnames = _interopRequireDefault(require("classnames"));
8
9
  var _react = _interopRequireDefault(require("react"));
9
10
  var _withDefaultProps = require("../../utils/with-default-props");
10
- var _classnames = _interopRequireDefault(require("classnames"));
11
- var _modalActionButton = require("./modal-action-button");
12
- var _image = _interopRequireDefault(require("../image"));
13
- var _space = _interopRequireDefault(require("../space"));
14
11
  var _autoCenter = _interopRequireDefault(require("../auto-center"));
15
12
  var _centerPopup = _interopRequireDefault(require("../center-popup"));
13
+ var _image = _interopRequireDefault(require("../image"));
14
+ var _space = _interopRequireDefault(require("../space"));
15
+ var _modalActionButton = require("./modal-action-button");
16
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
17
  const defaultProps = {
18
18
  actions: [],
@@ -78,7 +78,6 @@ const NumberKeyboard = p => {
78
78
  };
79
79
  const onKeyPress = (e, key) => {
80
80
  var _a, _b;
81
- e.preventDefault();
82
81
  switch (key) {
83
82
  case 'BACKSPACE':
84
83
  onDelete === null || onDelete === void 0 ? void 0 : onDelete();
@@ -115,6 +114,15 @@ const NumberKeyboard = p => {
115
114
  tabIndex: -1
116
115
  }, _react.default.createElement(_antdMobileIcons.DownOutline, null)));
117
116
  };
117
+ const onBackspaceTouchStart = () => {
118
+ stopContinueClear();
119
+ startContinueClear();
120
+ };
121
+ const onBackspaceTouchEnd = e => {
122
+ e.preventDefault(); // 短按时,touchend 会阻止后续 click 事件触发,防止删除两次
123
+ stopContinueClear();
124
+ onKeyPress(e, 'BACKSPACE');
125
+ };
118
126
  const renderKey = (key, index) => {
119
127
  const isNumberKey = /^\d$/.test(key);
120
128
  const isBackspace = key === 'BACKSPACE';
@@ -132,17 +140,13 @@ const NumberKeyboard = p => {
132
140
  key: key,
133
141
  className: className,
134
142
  // 仅为 backspace 绑定,支持长按快速删除
135
- onTouchStart: isBackspace ? () => {
136
- stopContinueClear();
137
- startContinueClear();
138
- } : undefined,
139
- onTouchEnd: isBackspace ? e => {
140
- stopContinueClear();
141
- onKeyPress(e, key);
142
- } : undefined,
143
+ onTouchStart: isBackspace ? onBackspaceTouchStart : undefined,
144
+ onTouchEnd: isBackspace ? onBackspaceTouchEnd : undefined,
145
+ onTouchCancel: isBackspace ? stopContinueClear : undefined,
143
146
  // <div role="button" title="1" onTouchEnd={e => {}}>1</div> 安卓上 talback 可读不可点
144
147
  // see https://ua-gilded-eef7f9.netlify.app/grid-button-bug.html
145
- // 所以还是绑定 click,通过 touchEnd preventDefault 防重复触发
148
+ // 所以普通按钮绑定 click 事件,而 backspace 仍然额外绑定 touch 事件支持长按删除
149
+ // backspace touchend 时会 preventDefault 阻止其后续 click 事件
146
150
  onClick: e => {
147
151
  stopContinueClear();
148
152
  onKeyPress(e, key);
@@ -161,10 +165,7 @@ const NumberKeyboard = p => {
161
165
  forceRender: props.forceRender
162
166
  }, (0, _nativeProps.withNativeProps)(props, _react.default.createElement("div", {
163
167
  ref: keyboardRef,
164
- className: classPrefix,
165
- onMouseDown: e => {
166
- e.preventDefault();
167
- }
168
+ className: classPrefix
168
169
  }, renderHeader(), _react.default.createElement("div", {
169
170
  className: `${classPrefix}-wrapper`
170
171
  }, _react.default.createElement("div", {
@@ -175,13 +176,9 @@ const NumberKeyboard = p => {
175
176
  className: `${classPrefix}-confirm`
176
177
  }, _react.default.createElement("div", {
177
178
  className: `${classPrefix}-key ${classPrefix}-key-extra ${classPrefix}-key-bs`,
178
- onTouchStart: () => {
179
- startContinueClear();
180
- },
181
- onTouchEnd: e => {
182
- stopContinueClear();
183
- onKeyPress(e, 'BACKSPACE');
184
- },
179
+ onTouchStart: onBackspaceTouchStart,
180
+ onTouchEnd: onBackspaceTouchEnd,
181
+ onTouchCancel: stopContinueClear,
185
182
  onClick: e => {
186
183
  stopContinueClear();
187
184
  onKeyPress(e, 'BACKSPACE');
@@ -0,0 +1,2 @@
1
+ declare function useClickOutside(handler: (event: MouseEvent) => void, ref: React.RefObject<HTMLElement>): void;
2
+ export default useClickOutside;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = require("react");
8
+ // 监听点击组件外部的事件
9
+ function useClickOutside(handler, ref) {
10
+ (0, _react.useEffect)(() => {
11
+ function handleClick(event) {
12
+ if (!ref.current || ref.current.contains(event.target)) {
13
+ return;
14
+ }
15
+ handler(event);
16
+ }
17
+ // 在捕获阶段监听,以确保在事件被阻止传播之前触发
18
+ document.addEventListener('click', handleClick, true);
19
+ return () => {
20
+ document.removeEventListener('click', handleClick, true);
21
+ };
22
+ }, [handler, ref]);
23
+ }
24
+ var _default = useClickOutside;
25
+ exports.default = _default;
@@ -40,6 +40,13 @@
40
40
  display: none;
41
41
  }
42
42
 
43
+ .adm-virtual-input-trap {
44
+ width: 20px;
45
+ height: 20px;
46
+ position: absolute;
47
+ opacity: 0;
48
+ }
49
+
43
50
  .adm-virtual-input-placeholder {
44
51
  display: block;
45
52
  position: absolute;
@@ -73,11 +80,11 @@
73
80
  z-index: 1;
74
81
  }
75
82
 
76
- .adm-virtual-input:focus {
83
+ .adm-virtual-input-focused {
77
84
  outline: none;
78
85
  }
79
86
 
80
- .adm-virtual-input:focus .adm-virtual-input-caret {
87
+ .adm-virtual-input-focused .adm-virtual-input-caret {
81
88
  animation-name: adm-caret-blink;
82
89
  animation-duration: 1s;
83
90
  animation-timing-function: linear;
@@ -12,6 +12,7 @@ var _nativeProps = require("../../utils/native-props");
12
12
  var _usePropsValue = require("../../utils/use-props-value");
13
13
  var _withDefaultProps = require("../../utils/with-default-props");
14
14
  var _configProvider = require("../config-provider");
15
+ var _useClickOutside = _interopRequireDefault(require("./use-click-outside"));
15
16
  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); }
16
17
  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; }
17
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -42,13 +43,10 @@ const VirtualInput = (0, _react.forwardRef)((props, ref) => {
42
43
  const touchMoveTimeoutRef = (0, _react.useRef)();
43
44
  const clearIcon = (0, _withDefaultProps.mergeProp)(_react.default.createElement(_antdMobileIcons.CloseCircleFill, null), componentConfig.clearIcon, props.clearIcon);
44
45
  function scrollToEnd() {
45
- const root = rootRef.current;
46
- if (!root) return;
47
- if (document.activeElement !== root) {
46
+ const content = contentRef.current;
47
+ if (!content) {
48
48
  return;
49
49
  }
50
- const content = contentRef.current;
51
- if (!content) return;
52
50
  content.scrollLeft = content.clientWidth;
53
51
  }
54
52
  (0, _react.useEffect)(() => {
@@ -80,23 +78,29 @@ const VirtualInput = (0, _react.forwardRef)((props, ref) => {
80
78
  (0, _react.useImperativeHandle)(ref, () => ({
81
79
  focus: () => {
82
80
  var _a;
83
- (_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.focus();
81
+ (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.focus();
84
82
  },
85
83
  blur: () => {
86
84
  var _a;
87
- (_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.blur();
85
+ (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.blur();
86
+ setBlur();
88
87
  }
89
88
  }));
90
- function onFocus() {
89
+ function setFocus() {
91
90
  var _a;
91
+ if (hasFocus) return;
92
92
  setHasFocus(true);
93
93
  (_a = mergedProps.onFocus) === null || _a === void 0 ? void 0 : _a.call(mergedProps);
94
94
  }
95
- function onBlur() {
95
+ function setBlur() {
96
96
  var _a;
97
+ if (!hasFocus) return;
97
98
  setHasFocus(false);
98
99
  (_a = mergedProps.onBlur) === null || _a === void 0 ? void 0 : _a.call(mergedProps);
99
100
  }
101
+ (0, _useClickOutside.default)(() => {
102
+ setBlur();
103
+ }, rootRef);
100
104
  const keyboard = mergedProps.keyboard;
101
105
  const keyboardElement = keyboard && _react.default.cloneElement(keyboard, {
102
106
  onInput: v => {
@@ -124,26 +128,20 @@ const VirtualInput = (0, _react.forwardRef)((props, ref) => {
124
128
  },
125
129
  visible: hasFocus,
126
130
  onClose: () => {
127
- var _a, _b, _c, _d;
128
- const activeElement = document.activeElement;
129
- // Long press makes `activeElement` to be the child of rootRef
130
- // We will trigger blur on the child element instead
131
- if (activeElement && ((_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.contains(activeElement))) {
132
- activeElement.blur();
133
- } else {
134
- (_b = rootRef.current) === null || _b === void 0 ? void 0 : _b.blur();
135
- }
136
- (_d = (_c = keyboard.props).onClose) === null || _d === void 0 ? void 0 : _d.call(_c);
131
+ var _a, _b;
132
+ setBlur();
133
+ (_b = (_a = keyboard.props).onClose) === null || _b === void 0 ? void 0 : _b.call(_a);
137
134
  },
138
135
  getContainer: null
139
136
  });
140
137
  // 点击输入框时,将光标置于最后
141
- const setCaretPositionToEnd = () => {
142
- var _a, _b;
138
+ const setCaretPositionToEnd = e => {
139
+ var _a, _b, _c;
143
140
  if (caretPosition !== value.length) {
144
141
  setCaretPosition(value.length);
145
142
  (_b = (_a = mergedProps.cursor) === null || _a === void 0 ? void 0 : _a.onMove) === null || _b === void 0 ? void 0 : _b.call(_a, value.length);
146
143
  }
144
+ (_c = mergedProps.onClick) === null || _c === void 0 ? void 0 : _c.call(mergedProps, e);
147
145
  };
148
146
  // 点击单个字符时,根据点击位置置于字符前或后
149
147
  const changeCaretPosition = index => e => {
@@ -212,23 +210,27 @@ const VirtualInput = (0, _react.forwardRef)((props, ref) => {
212
210
  ref: rootRef,
213
211
  className: (0, _classnames.default)(classPrefix, {
214
212
  [`${classPrefix}-disabled`]: mergedProps.disabled,
215
- [`${classPrefix}-caret-dragging`]: isCaretDragging
216
- }),
217
- tabIndex: mergedProps.disabled ? undefined : 0,
218
- role: 'textbox',
219
- onFocus: onFocus,
220
- onBlur: onBlur,
221
- onClick: mergedProps.onClick
213
+ [`${classPrefix}-caret-dragging`]: isCaretDragging,
214
+ [`${classPrefix}-focused`]: hasFocus
215
+ })
222
216
  }, _react.default.createElement("div", {
223
217
  className: `${classPrefix}-content`,
224
218
  ref: contentRef,
225
219
  "aria-disabled": mergedProps.disabled,
226
- "aria-label": mergedProps.placeholder,
220
+ "aria-label": value || mergedProps.placeholder,
221
+ role: 'textbox',
222
+ tabIndex: mergedProps.disabled ? undefined : 0,
223
+ // note: 这里增加 onFocus 有两个目的:
224
+ // 1. 在安卓 talkback 模式下,role=textbox 的元素双击后只会触发 focus 而非 click
225
+ // 2. 处理 content 框点击、单个字符点击时,不用再额外处理 focus 逻辑,因为 focus 事件会先触发
226
+ onFocus: setFocus,
227
227
  onClick: setCaretPositionToEnd,
228
228
  onTouchStart: handleTouchStart,
229
229
  onTouchMove: handleTouchMove,
230
230
  onTouchEnd: handleTouchEnd
231
- }, chars.slice(0, caretPosition).map((i, index) => _react.default.createElement("span", {
231
+ }, _react.default.createElement("span", {
232
+ className: `${classPrefix}-trap`
233
+ }), chars.slice(0, caretPosition).map((i, index) => _react.default.createElement("span", {
232
234
  ref: index === 0 ? charRef : undefined,
233
235
  key: index,
234
236
  onClick: changeCaretPosition(index)
@@ -1,7 +1,7 @@
1
1
  import type { FC, ReactNode } from 'react';
2
- import { Action } from './dialog-action-button';
3
2
  import { NativeProps } from '../../utils/native-props';
4
3
  import { CenterPopupProps } from '../center-popup';
4
+ import { Action } from './dialog-action-button';
5
5
  export declare type DialogProps = Pick<CenterPopupProps, 'afterClose' | 'afterShow' | 'bodyClassName' | 'bodyStyle' | 'destroyOnClose' | 'disableBodyScroll' | 'forceRender' | 'getContainer' | 'maskClassName' | 'maskStyle' | 'stopPropagation' | 'visible'> & {
6
6
  image?: string;
7
7
  header?: ReactNode;
@@ -12,5 +12,5 @@ export declare type DialogProps = Pick<CenterPopupProps, 'afterClose' | 'afterSh
12
12
  onClose?: () => void;
13
13
  closeOnAction?: boolean;
14
14
  closeOnMaskClick?: boolean;
15
- } & NativeProps;
15
+ } & NativeProps<'--background-color' | '--border-radius' | '--max-width' | '--min-width' | '--z-index'>;
16
16
  export declare const Dialog: FC<DialogProps>;
@@ -1,11 +1,11 @@
1
1
  import { __awaiter } from "tslib";
2
+ import classNames from 'classnames';
2
3
  import React from 'react';
3
4
  import { mergeProps } from '../../utils/with-default-props';
4
- import classNames from 'classnames';
5
- import { DialogActionButton } from './dialog-action-button';
6
- import Image from '../image';
7
5
  import AutoCenter from '../auto-center';
8
6
  import CenterPopup from '../center-popup';
7
+ import Image from '../image';
8
+ import { DialogActionButton } from './dialog-action-button';
9
9
  const defaultProps = {
10
10
  actions: [],
11
11
  closeOnAction: false,
@@ -1,7 +1,7 @@
1
1
  import type { FC, ReactNode } from 'react';
2
- import { Action } from './modal-action-button';
3
2
  import { NativeProps } from '../../utils/native-props';
4
3
  import { CenterPopupProps } from '../center-popup';
4
+ import { Action } from './modal-action-button';
5
5
  export declare type ModalProps = Pick<CenterPopupProps, 'afterClose' | 'afterShow' | 'bodyClassName' | 'bodyStyle' | 'destroyOnClose' | 'disableBodyScroll' | 'forceRender' | 'getContainer' | 'maskClassName' | 'maskStyle' | 'stopPropagation' | 'visible'> & {
6
6
  image?: string;
7
7
  header?: ReactNode;
@@ -13,5 +13,5 @@ export declare type ModalProps = Pick<CenterPopupProps, 'afterClose' | 'afterSho
13
13
  closeOnAction?: boolean;
14
14
  closeOnMaskClick?: boolean;
15
15
  showCloseButton?: boolean;
16
- } & NativeProps;
16
+ } & NativeProps<'--background-color' | '--border-radius' | '--max-width' | '--min-width' | '--z-index'>;
17
17
  export declare const Modal: FC<ModalProps>;
@@ -1,12 +1,12 @@
1
1
  import { __awaiter } from "tslib";
2
+ import classNames from 'classnames';
2
3
  import React from 'react';
3
4
  import { mergeProps } from '../../utils/with-default-props';
4
- import classNames from 'classnames';
5
- import { ModalActionButton } from './modal-action-button';
6
- import Image from '../image';
7
- import Space from '../space';
8
5
  import AutoCenter from '../auto-center';
9
6
  import CenterPopup from '../center-popup';
7
+ import Image from '../image';
8
+ import Space from '../space';
9
+ import { ModalActionButton } from './modal-action-button';
10
10
  const defaultProps = {
11
11
  actions: [],
12
12
  closeOnAction: false,
@@ -69,7 +69,6 @@ export const NumberKeyboard = p => {
69
69
  };
70
70
  const onKeyPress = (e, key) => {
71
71
  var _a, _b;
72
- e.preventDefault();
73
72
  switch (key) {
74
73
  case 'BACKSPACE':
75
74
  onDelete === null || onDelete === void 0 ? void 0 : onDelete();
@@ -106,6 +105,15 @@ export const NumberKeyboard = p => {
106
105
  tabIndex: -1
107
106
  }, React.createElement(DownOutline, null)));
108
107
  };
108
+ const onBackspaceTouchStart = () => {
109
+ stopContinueClear();
110
+ startContinueClear();
111
+ };
112
+ const onBackspaceTouchEnd = e => {
113
+ e.preventDefault(); // 短按时,touchend 会阻止后续 click 事件触发,防止删除两次
114
+ stopContinueClear();
115
+ onKeyPress(e, 'BACKSPACE');
116
+ };
109
117
  const renderKey = (key, index) => {
110
118
  const isNumberKey = /^\d$/.test(key);
111
119
  const isBackspace = key === 'BACKSPACE';
@@ -123,17 +131,13 @@ export const NumberKeyboard = p => {
123
131
  key: key,
124
132
  className: className,
125
133
  // 仅为 backspace 绑定,支持长按快速删除
126
- onTouchStart: isBackspace ? () => {
127
- stopContinueClear();
128
- startContinueClear();
129
- } : undefined,
130
- onTouchEnd: isBackspace ? e => {
131
- stopContinueClear();
132
- onKeyPress(e, key);
133
- } : undefined,
134
+ onTouchStart: isBackspace ? onBackspaceTouchStart : undefined,
135
+ onTouchEnd: isBackspace ? onBackspaceTouchEnd : undefined,
136
+ onTouchCancel: isBackspace ? stopContinueClear : undefined,
134
137
  // <div role="button" title="1" onTouchEnd={e => {}}>1</div> 安卓上 talback 可读不可点
135
138
  // see https://ua-gilded-eef7f9.netlify.app/grid-button-bug.html
136
- // 所以还是绑定 click,通过 touchEnd preventDefault 防重复触发
139
+ // 所以普通按钮绑定 click 事件,而 backspace 仍然额外绑定 touch 事件支持长按删除
140
+ // backspace touchend 时会 preventDefault 阻止其后续 click 事件
137
141
  onClick: e => {
138
142
  stopContinueClear();
139
143
  onKeyPress(e, key);
@@ -152,10 +156,7 @@ export const NumberKeyboard = p => {
152
156
  forceRender: props.forceRender
153
157
  }, withNativeProps(props, React.createElement("div", {
154
158
  ref: keyboardRef,
155
- className: classPrefix,
156
- onMouseDown: e => {
157
- e.preventDefault();
158
- }
159
+ className: classPrefix
159
160
  }, renderHeader(), React.createElement("div", {
160
161
  className: `${classPrefix}-wrapper`
161
162
  }, React.createElement("div", {
@@ -166,13 +167,9 @@ export const NumberKeyboard = p => {
166
167
  className: `${classPrefix}-confirm`
167
168
  }, React.createElement("div", {
168
169
  className: `${classPrefix}-key ${classPrefix}-key-extra ${classPrefix}-key-bs`,
169
- onTouchStart: () => {
170
- startContinueClear();
171
- },
172
- onTouchEnd: e => {
173
- stopContinueClear();
174
- onKeyPress(e, 'BACKSPACE');
175
- },
170
+ onTouchStart: onBackspaceTouchStart,
171
+ onTouchEnd: onBackspaceTouchEnd,
172
+ onTouchCancel: stopContinueClear,
176
173
  onClick: e => {
177
174
  stopContinueClear();
178
175
  onKeyPress(e, 'BACKSPACE');
@@ -0,0 +1,2 @@
1
+ declare function useClickOutside(handler: (event: MouseEvent) => void, ref: React.RefObject<HTMLElement>): void;
2
+ export default useClickOutside;
@@ -0,0 +1,18 @@
1
+ import { useEffect } from 'react';
2
+ // 监听点击组件外部的事件
3
+ function useClickOutside(handler, ref) {
4
+ useEffect(() => {
5
+ function handleClick(event) {
6
+ if (!ref.current || ref.current.contains(event.target)) {
7
+ return;
8
+ }
9
+ handler(event);
10
+ }
11
+ // 在捕获阶段监听,以确保在事件被阻止传播之前触发
12
+ document.addEventListener('click', handleClick, true);
13
+ return () => {
14
+ document.removeEventListener('click', handleClick, true);
15
+ };
16
+ }, [handler, ref]);
17
+ }
18
+ export default useClickOutside;
@@ -40,6 +40,13 @@
40
40
  display: none;
41
41
  }
42
42
 
43
+ .adm-virtual-input-trap {
44
+ width: 20px;
45
+ height: 20px;
46
+ position: absolute;
47
+ opacity: 0;
48
+ }
49
+
43
50
  .adm-virtual-input-placeholder {
44
51
  display: block;
45
52
  position: absolute;
@@ -73,11 +80,11 @@
73
80
  z-index: 1;
74
81
  }
75
82
 
76
- .adm-virtual-input:focus {
83
+ .adm-virtual-input-focused {
77
84
  outline: none;
78
85
  }
79
86
 
80
- .adm-virtual-input:focus .adm-virtual-input-caret {
87
+ .adm-virtual-input-focused .adm-virtual-input-caret {
81
88
  animation-name: adm-caret-blink;
82
89
  animation-duration: 1s;
83
90
  animation-timing-function: linear;