antd-mobile 5.19.0 → 5.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/2x/bundle/antd-mobile.cjs.js +11 -11
- package/2x/bundle/antd-mobile.compatible.umd.js +2997 -2934
- package/2x/bundle/antd-mobile.es.js +2020 -1975
- package/2x/bundle/antd-mobile.umd.js +11 -11
- package/2x/bundle/style.css +1 -0
- package/2x/cjs/components/form/context.d.ts +1 -1
- package/2x/cjs/components/form/form-item.js +3 -0
- package/2x/cjs/components/image/test/image.test.js +57 -8
- package/2x/cjs/components/rate/rate.css +1 -0
- package/2x/cjs/components/rate/rate.js +32 -4
- package/2x/cjs/components/swipe-action/swipe-action.d.ts +2 -0
- package/2x/cjs/components/swipe-action/swipe-action.js +34 -6
- package/2x/cjs/components/swiper/swiper.js +14 -0
- package/2x/cjs/locales/id-ID.js +13 -0
- package/2x/cjs/utils/use-resize-effect.js +3 -1
- package/2x/es/components/form/context.d.ts +1 -1
- package/2x/es/components/form/form-item.js +3 -0
- package/2x/es/components/image/test/image.test.js +54 -8
- package/2x/es/components/rate/rate.css +1 -0
- package/2x/es/components/rate/rate.js +26 -4
- package/2x/es/components/swipe-action/swipe-action.d.ts +2 -0
- package/2x/es/components/swipe-action/swipe-action.js +34 -6
- package/2x/es/components/swiper/swiper.js +14 -0
- package/2x/es/locales/id-ID.js +13 -0
- package/2x/es/utils/use-resize-effect.js +3 -1
- package/2x/package.json +4 -4
- package/2x/umd/antd-mobile.js +2997 -2934
- package/bundle/antd-mobile.cjs.js +11 -11
- package/bundle/antd-mobile.compatible.umd.js +2997 -2934
- package/bundle/antd-mobile.es.js +2020 -1975
- package/bundle/antd-mobile.umd.js +11 -11
- package/bundle/style.css +1 -1
- package/cjs/components/form/context.d.ts +1 -1
- package/cjs/components/form/form-item.js +3 -0
- package/cjs/components/image/test/image.test.js +57 -8
- package/cjs/components/rate/rate.css +1 -0
- package/cjs/components/rate/rate.js +32 -4
- package/cjs/components/swipe-action/swipe-action.d.ts +2 -0
- package/cjs/components/swipe-action/swipe-action.js +34 -6
- package/cjs/components/swiper/swiper.js +14 -0
- package/cjs/locales/id-ID.js +13 -0
- package/cjs/utils/use-resize-effect.js +3 -1
- package/es/components/form/context.d.ts +1 -1
- package/es/components/form/form-item.js +3 -0
- package/es/components/image/test/image.test.js +54 -8
- package/es/components/rate/rate.css +1 -0
- package/es/components/rate/rate.js +26 -4
- package/es/components/swipe-action/swipe-action.d.ts +2 -0
- package/es/components/swipe-action/swipe-action.js +34 -6
- package/es/components/swiper/swiper.js +14 -0
- package/es/locales/id-ID.js +13 -0
- package/es/utils/use-resize-effect.js +3 -1
- package/package.json +4 -4
- package/umd/antd-mobile.js +1 -1
package/2x/bundle/style.css
CHANGED
|
@@ -5,7 +5,7 @@ export declare type FormContextType = {
|
|
|
5
5
|
name?: string;
|
|
6
6
|
hasFeedback: boolean;
|
|
7
7
|
layout: FormLayout;
|
|
8
|
-
requiredMarkStyle: 'asterisk' | 'text-required' | 'text-optional';
|
|
8
|
+
requiredMarkStyle: 'asterisk' | 'text-required' | 'text-optional' | 'none';
|
|
9
9
|
disabled: boolean;
|
|
10
10
|
};
|
|
11
11
|
export declare const defaultFormContext: FormContextType;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var _tslib = require("tslib");
|
|
4
|
-
|
|
5
3
|
var _react = _interopRequireDefault(require("react"));
|
|
6
4
|
|
|
7
5
|
var _testing = require("testing");
|
|
@@ -10,13 +8,9 @@ var _index = _interopRequireDefault(require("../index"));
|
|
|
10
8
|
|
|
11
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
10
|
|
|
11
|
+
const classPrefix = `adm-image`;
|
|
13
12
|
const demoSrc = 'https://images.unsplash.com/photo-1567945716310-4745a6b7844b?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=60';
|
|
14
|
-
describe('
|
|
15
|
-
test('a11y', () => (0, _tslib.__awaiter)(void 0, void 0, void 0, function* () {
|
|
16
|
-
yield (0, _testing.testA11y)(_react.default.createElement(_index.default, {
|
|
17
|
-
src: demoSrc
|
|
18
|
-
}));
|
|
19
|
-
}));
|
|
13
|
+
describe('Image', () => {
|
|
20
14
|
test('onContainerClick can work', () => {
|
|
21
15
|
const onContainerClick = jest.fn();
|
|
22
16
|
const {
|
|
@@ -31,4 +25,59 @@ describe('image', () => {
|
|
|
31
25
|
|
|
32
26
|
expect(onContainerClick).toBeCalledTimes(1);
|
|
33
27
|
});
|
|
28
|
+
test('load successfully', () => {
|
|
29
|
+
(0, _testing.render)(_react.default.createElement(_index.default, {
|
|
30
|
+
src: demoSrc
|
|
31
|
+
}));
|
|
32
|
+
const img = document.querySelectorAll(`.${classPrefix}-img`)[0];
|
|
33
|
+
|
|
34
|
+
_testing.fireEvent.load(img);
|
|
35
|
+
|
|
36
|
+
expect(img).toHaveAttribute('src', demoSrc);
|
|
37
|
+
});
|
|
38
|
+
test('load failed', () => {
|
|
39
|
+
(0, _testing.render)(_react.default.createElement(_index.default, {
|
|
40
|
+
src: '404'
|
|
41
|
+
}));
|
|
42
|
+
const img = document.querySelectorAll(`.${classPrefix}-img`)[0];
|
|
43
|
+
|
|
44
|
+
_testing.fireEvent.error(img);
|
|
45
|
+
|
|
46
|
+
expect(img).not.toBeInTheDocument();
|
|
47
|
+
expect(document.querySelectorAll(`.${classPrefix}-tip`)[0]).toBeInTheDocument();
|
|
48
|
+
});
|
|
49
|
+
test('lazy load should be work', () => {
|
|
50
|
+
// mock useInViewport
|
|
51
|
+
// https://github.com/alibaba/hooks/blob/master/packages/hooks/src/useInViewport/__tests__/index.test.ts
|
|
52
|
+
const mockIntersectionObserver = jest.fn().mockReturnValue({
|
|
53
|
+
observe: () => null,
|
|
54
|
+
disconnect: () => null
|
|
55
|
+
});
|
|
56
|
+
window.IntersectionObserver = mockIntersectionObserver;
|
|
57
|
+
(0, _testing.render)(_react.default.createElement(_index.default, {
|
|
58
|
+
src: demoSrc,
|
|
59
|
+
lazy: true
|
|
60
|
+
}));
|
|
61
|
+
const img = document.querySelectorAll(`.${classPrefix}-img`)[0];
|
|
62
|
+
expect(img).not.toHaveAttribute('src');
|
|
63
|
+
const calls = mockIntersectionObserver.mock.calls;
|
|
64
|
+
const [onChange] = calls[calls.length - 1];
|
|
65
|
+
(0, _testing.act)(() => {
|
|
66
|
+
onChange([{
|
|
67
|
+
isIntersecting: true
|
|
68
|
+
}]);
|
|
69
|
+
});
|
|
70
|
+
expect(img).toHaveAttribute('src', demoSrc);
|
|
71
|
+
});
|
|
72
|
+
test('renders with width and height', () => {
|
|
73
|
+
const {
|
|
74
|
+
getByTestId
|
|
75
|
+
} = (0, _testing.render)(_react.default.createElement(_index.default, {
|
|
76
|
+
src: demoSrc,
|
|
77
|
+
width: 100,
|
|
78
|
+
height: 100,
|
|
79
|
+
"data-testid": 'image'
|
|
80
|
+
}));
|
|
81
|
+
expect(getByTestId('image')).toHaveStyle('--width: 100px;--height: 100px');
|
|
82
|
+
});
|
|
34
83
|
});
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.Rate = void 0;
|
|
7
7
|
|
|
8
|
-
var _react =
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
9
|
|
|
10
10
|
var _classnames = _interopRequireDefault(require("classnames"));
|
|
11
11
|
|
|
@@ -17,8 +17,16 @@ var _usePropsValue = require("../../utils/use-props-value");
|
|
|
17
17
|
|
|
18
18
|
var _star = require("./star");
|
|
19
19
|
|
|
20
|
+
var _react2 = require("@use-gesture/react");
|
|
21
|
+
|
|
22
|
+
var _bound = require("../../utils/bound");
|
|
23
|
+
|
|
20
24
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
25
|
|
|
26
|
+
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); }
|
|
27
|
+
|
|
28
|
+
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; }
|
|
29
|
+
|
|
22
30
|
const classPrefix = `adm-rate`;
|
|
23
31
|
const defaultProps = {
|
|
24
32
|
count: 5,
|
|
@@ -32,6 +40,7 @@ const defaultProps = {
|
|
|
32
40
|
const Rate = p => {
|
|
33
41
|
const props = (0, _withDefaultProps.mergeProps)(defaultProps, p);
|
|
34
42
|
const [value, setValue] = (0, _usePropsValue.usePropsValue)(props);
|
|
43
|
+
const containerRef = (0, _react.useRef)(null);
|
|
35
44
|
const starList = Array(props.count).fill(null);
|
|
36
45
|
|
|
37
46
|
function renderStar(v, half) {
|
|
@@ -56,11 +65,30 @@ const Rate = p => {
|
|
|
56
65
|
}, props.character);
|
|
57
66
|
}
|
|
58
67
|
|
|
59
|
-
|
|
68
|
+
const bind = (0, _react2.useDrag)(state => {
|
|
69
|
+
if (props.readOnly) return;
|
|
70
|
+
const {
|
|
71
|
+
xy: [clientX]
|
|
72
|
+
} = state;
|
|
73
|
+
const container = containerRef.current;
|
|
74
|
+
if (!container) return;
|
|
75
|
+
const rect = container.getBoundingClientRect();
|
|
76
|
+
const rawValue = (clientX - rect.left) / rect.width * props.count;
|
|
77
|
+
const roundedValue = props.allowHalf ? Math.round(rawValue * 2) / 2 : Math.round(rawValue);
|
|
78
|
+
setValue((0, _bound.bound)(roundedValue, 0, props.count));
|
|
79
|
+
}, {
|
|
80
|
+
axis: 'x',
|
|
81
|
+
preventScroll: true,
|
|
82
|
+
pointer: {
|
|
83
|
+
touch: true
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
return (0, _nativeProps.withNativeProps)(props, _react.default.createElement("div", Object.assign({
|
|
60
87
|
className: classPrefix,
|
|
61
88
|
role: 'radiogroup',
|
|
62
|
-
"aria-readonly": props.readOnly
|
|
63
|
-
|
|
89
|
+
"aria-readonly": props.readOnly,
|
|
90
|
+
ref: containerRef
|
|
91
|
+
}, bind()), starList.map((_, i) => _react.default.createElement("div", {
|
|
64
92
|
key: i,
|
|
65
93
|
className: (0, _classnames.default)(`${classPrefix}-box`)
|
|
66
94
|
}, props.allowHalf && renderStar(i + 0.5, true), renderStar(i + 1, false)))));
|
|
@@ -20,6 +20,7 @@ export declare type SwipeActionProps = {
|
|
|
20
20
|
closeOnAction?: boolean;
|
|
21
21
|
children: ReactNode;
|
|
22
22
|
stopPropagation?: PropagationEvent[];
|
|
23
|
+
onActionsReveal?: (side: 'left' | 'right') => void;
|
|
23
24
|
} & NativeProps<'--background'>;
|
|
24
25
|
export declare const SwipeAction: React.ForwardRefExoticComponent<{
|
|
25
26
|
rightActions?: Action[] | undefined;
|
|
@@ -29,6 +30,7 @@ export declare const SwipeAction: React.ForwardRefExoticComponent<{
|
|
|
29
30
|
closeOnAction?: boolean | undefined;
|
|
30
31
|
children: ReactNode;
|
|
31
32
|
stopPropagation?: "click"[] | undefined;
|
|
33
|
+
onActionsReveal?: ((side: 'left' | 'right') => void) | undefined;
|
|
32
34
|
} & {
|
|
33
35
|
className?: string | undefined;
|
|
34
36
|
style?: (React.CSSProperties & Partial<Record<"--background", string>>) | undefined;
|
|
@@ -65,8 +65,26 @@ const SwipeAction = (0, _react.forwardRef)((p, ref) => {
|
|
|
65
65
|
}
|
|
66
66
|
}), []);
|
|
67
67
|
const draggingRef = (0, _react.useRef)(false);
|
|
68
|
+
const dragCancelRef = (0, _react.useRef)(null);
|
|
69
|
+
|
|
70
|
+
function forceCancelDrag() {
|
|
71
|
+
var _a;
|
|
72
|
+
|
|
73
|
+
(_a = dragCancelRef.current) === null || _a === void 0 ? void 0 : _a.call(dragCancelRef);
|
|
74
|
+
draggingRef.current = false;
|
|
75
|
+
}
|
|
76
|
+
|
|
68
77
|
const bind = (0, _react2.useDrag)(state => {
|
|
69
|
-
|
|
78
|
+
var _a;
|
|
79
|
+
|
|
80
|
+
dragCancelRef.current = state.cancel;
|
|
81
|
+
if (!state.intentional) return;
|
|
82
|
+
|
|
83
|
+
if (state.down) {
|
|
84
|
+
draggingRef.current = true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!draggingRef.current) return;
|
|
70
88
|
const [offsetX] = state.offset;
|
|
71
89
|
|
|
72
90
|
if (state.last) {
|
|
@@ -82,9 +100,15 @@ const SwipeAction = (0, _react.forwardRef)((p, ref) => {
|
|
|
82
100
|
position = 0;
|
|
83
101
|
}
|
|
84
102
|
|
|
103
|
+
const targetX = (0, _nearest.nearest)([-rightWidth, 0, leftWidth], position);
|
|
85
104
|
api.start({
|
|
86
|
-
x:
|
|
105
|
+
x: targetX
|
|
87
106
|
});
|
|
107
|
+
|
|
108
|
+
if (targetX !== 0) {
|
|
109
|
+
(_a = p.onActionsReveal) === null || _a === void 0 ? void 0 : _a.call(p, targetX > 0 ? 'left' : 'right');
|
|
110
|
+
}
|
|
111
|
+
|
|
88
112
|
window.setTimeout(() => {
|
|
89
113
|
draggingRef.current = false;
|
|
90
114
|
});
|
|
@@ -109,17 +133,21 @@ const SwipeAction = (0, _react.forwardRef)((p, ref) => {
|
|
|
109
133
|
preventScroll: true,
|
|
110
134
|
pointer: {
|
|
111
135
|
touch: true
|
|
112
|
-
}
|
|
136
|
+
},
|
|
137
|
+
triggerAllEvents: true
|
|
113
138
|
});
|
|
114
139
|
|
|
115
140
|
function close() {
|
|
116
141
|
api.start({
|
|
117
142
|
x: 0
|
|
118
143
|
});
|
|
144
|
+
forceCancelDrag();
|
|
119
145
|
}
|
|
120
146
|
|
|
121
147
|
(0, _react.useImperativeHandle)(ref, () => ({
|
|
122
148
|
show: (side = 'right') => {
|
|
149
|
+
var _a;
|
|
150
|
+
|
|
123
151
|
if (side === 'right') {
|
|
124
152
|
api.start({
|
|
125
153
|
x: -getRightWidth()
|
|
@@ -129,6 +157,8 @@ const SwipeAction = (0, _react.forwardRef)((p, ref) => {
|
|
|
129
157
|
x: getLeftWidth()
|
|
130
158
|
});
|
|
131
159
|
}
|
|
160
|
+
|
|
161
|
+
(_a = p.onActionsReveal) === null || _a === void 0 ? void 0 : _a.call(p, side);
|
|
132
162
|
},
|
|
133
163
|
close
|
|
134
164
|
}));
|
|
@@ -200,9 +230,7 @@ const SwipeAction = (0, _react.forwardRef)((p, ref) => {
|
|
|
200
230
|
if (x.goal !== 0) {
|
|
201
231
|
e.preventDefault();
|
|
202
232
|
e.stopPropagation();
|
|
203
|
-
|
|
204
|
-
x: 0
|
|
205
|
-
});
|
|
233
|
+
close();
|
|
206
234
|
}
|
|
207
235
|
}
|
|
208
236
|
}, _react.default.createElement(_web.animated.div, {
|
|
@@ -141,7 +141,18 @@ const Swiper = (0, _react.forwardRef)((0, _stagedComponents.staged)((p, ref) =>
|
|
|
141
141
|
});
|
|
142
142
|
}
|
|
143
143
|
}), [count]);
|
|
144
|
+
const dragCancelRef = (0, _react.useRef)(null);
|
|
145
|
+
|
|
146
|
+
function forceCancelDrag() {
|
|
147
|
+
var _a;
|
|
148
|
+
|
|
149
|
+
(_a = dragCancelRef.current) === null || _a === void 0 ? void 0 : _a.call(dragCancelRef);
|
|
150
|
+
draggingRef.current = false;
|
|
151
|
+
}
|
|
152
|
+
|
|
144
153
|
const bind = (0, _react2.useDrag)(state => {
|
|
154
|
+
dragCancelRef.current = state.cancel;
|
|
155
|
+
if (!state.intentional) return;
|
|
145
156
|
const slidePixels = getSlidePixels();
|
|
146
157
|
if (!slidePixels) return;
|
|
147
158
|
const paramIndex = isVertical ? 1 : 0;
|
|
@@ -170,6 +181,7 @@ const Swiper = (0, _react.forwardRef)((0, _stagedComponents.staged)((p, ref) =>
|
|
|
170
181
|
const slidePixels = getSlidePixels();
|
|
171
182
|
return [position.get() / 100 * slidePixels, position.get() / 100 * slidePixels];
|
|
172
183
|
},
|
|
184
|
+
triggerAllEvents: true,
|
|
173
185
|
bounds: () => {
|
|
174
186
|
if (loop) return {};
|
|
175
187
|
const slidePixels = getSlidePixels();
|
|
@@ -284,6 +296,8 @@ const Swiper = (0, _react.forwardRef)((0, _stagedComponents.staged)((p, ref) =>
|
|
|
284
296
|
if (draggingRef.current) {
|
|
285
297
|
e.stopPropagation();
|
|
286
298
|
}
|
|
299
|
+
|
|
300
|
+
forceCancelDrag();
|
|
287
301
|
}
|
|
288
302
|
}, props.allowTouchMove ? bind() : {}), renderTrackInner()), props.indicator === undefined ? _react.default.createElement("div", {
|
|
289
303
|
className: `${classPrefix}-indicator`
|
package/2x/cjs/locales/id-ID.js
CHANGED
|
@@ -115,6 +115,19 @@ const idID = (0, _mergeLocale.mergeLocale)(_base.base, {
|
|
|
115
115
|
pulling: 'Tarik ke bawah untuk menyegarkan',
|
|
116
116
|
canRelease: 'Lepaskan untuk menyegarkan segera',
|
|
117
117
|
complete: 'Segarkan berhasil'
|
|
118
|
+
},
|
|
119
|
+
SearchBar: {
|
|
120
|
+
name: 'Bilah Pencarian'
|
|
121
|
+
},
|
|
122
|
+
Slider: {
|
|
123
|
+
name: 'Penggeser'
|
|
124
|
+
},
|
|
125
|
+
Stepper: {
|
|
126
|
+
decrease: 'mengurangi',
|
|
127
|
+
increase: 'meningkat'
|
|
128
|
+
},
|
|
129
|
+
Switch: {
|
|
130
|
+
name: 'Mengalihkan'
|
|
118
131
|
}
|
|
119
132
|
});
|
|
120
133
|
var _default = idID;
|
|
@@ -14,11 +14,13 @@ function useResizeEffect(effect, targetRef) {
|
|
|
14
14
|
if (!target) return;
|
|
15
15
|
|
|
16
16
|
if (window.ResizeObserver) {
|
|
17
|
+
let animationFrame;
|
|
17
18
|
const observer = new ResizeObserver(() => {
|
|
18
|
-
fn(target);
|
|
19
|
+
animationFrame = window.requestAnimationFrame(() => fn(target));
|
|
19
20
|
});
|
|
20
21
|
observer.observe(target);
|
|
21
22
|
return () => {
|
|
23
|
+
window.cancelAnimationFrame(animationFrame);
|
|
22
24
|
observer.disconnect();
|
|
23
25
|
};
|
|
24
26
|
} else {
|
|
@@ -5,7 +5,7 @@ export declare type FormContextType = {
|
|
|
5
5
|
name?: string;
|
|
6
6
|
hasFeedback: boolean;
|
|
7
7
|
layout: FormLayout;
|
|
8
|
-
requiredMarkStyle: 'asterisk' | 'text-required' | 'text-optional';
|
|
8
|
+
requiredMarkStyle: 'asterisk' | 'text-required' | 'text-optional' | 'none';
|
|
9
9
|
disabled: boolean;
|
|
10
10
|
};
|
|
11
11
|
export declare const defaultFormContext: FormContextType;
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import { __awaiter } from "tslib";
|
|
2
1
|
import React from 'react';
|
|
3
|
-
import { fireEvent, render,
|
|
2
|
+
import { fireEvent, render, act } from 'testing';
|
|
4
3
|
import Image from '../index';
|
|
4
|
+
const classPrefix = `adm-image`;
|
|
5
5
|
const demoSrc = 'https://images.unsplash.com/photo-1567945716310-4745a6b7844b?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=60';
|
|
6
|
-
describe('
|
|
7
|
-
test('a11y', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
8
|
-
yield testA11y(React.createElement(Image, {
|
|
9
|
-
src: demoSrc
|
|
10
|
-
}));
|
|
11
|
-
}));
|
|
6
|
+
describe('Image', () => {
|
|
12
7
|
test('onContainerClick can work', () => {
|
|
13
8
|
const onContainerClick = jest.fn();
|
|
14
9
|
const {
|
|
@@ -21,4 +16,55 @@ describe('image', () => {
|
|
|
21
16
|
fireEvent.click(getByTestId('img'));
|
|
22
17
|
expect(onContainerClick).toBeCalledTimes(1);
|
|
23
18
|
});
|
|
19
|
+
test('load successfully', () => {
|
|
20
|
+
render(React.createElement(Image, {
|
|
21
|
+
src: demoSrc
|
|
22
|
+
}));
|
|
23
|
+
const img = document.querySelectorAll(`.${classPrefix}-img`)[0];
|
|
24
|
+
fireEvent.load(img);
|
|
25
|
+
expect(img).toHaveAttribute('src', demoSrc);
|
|
26
|
+
});
|
|
27
|
+
test('load failed', () => {
|
|
28
|
+
render(React.createElement(Image, {
|
|
29
|
+
src: '404'
|
|
30
|
+
}));
|
|
31
|
+
const img = document.querySelectorAll(`.${classPrefix}-img`)[0];
|
|
32
|
+
fireEvent.error(img);
|
|
33
|
+
expect(img).not.toBeInTheDocument();
|
|
34
|
+
expect(document.querySelectorAll(`.${classPrefix}-tip`)[0]).toBeInTheDocument();
|
|
35
|
+
});
|
|
36
|
+
test('lazy load should be work', () => {
|
|
37
|
+
// mock useInViewport
|
|
38
|
+
// https://github.com/alibaba/hooks/blob/master/packages/hooks/src/useInViewport/__tests__/index.test.ts
|
|
39
|
+
const mockIntersectionObserver = jest.fn().mockReturnValue({
|
|
40
|
+
observe: () => null,
|
|
41
|
+
disconnect: () => null
|
|
42
|
+
});
|
|
43
|
+
window.IntersectionObserver = mockIntersectionObserver;
|
|
44
|
+
render(React.createElement(Image, {
|
|
45
|
+
src: demoSrc,
|
|
46
|
+
lazy: true
|
|
47
|
+
}));
|
|
48
|
+
const img = document.querySelectorAll(`.${classPrefix}-img`)[0];
|
|
49
|
+
expect(img).not.toHaveAttribute('src');
|
|
50
|
+
const calls = mockIntersectionObserver.mock.calls;
|
|
51
|
+
const [onChange] = calls[calls.length - 1];
|
|
52
|
+
act(() => {
|
|
53
|
+
onChange([{
|
|
54
|
+
isIntersecting: true
|
|
55
|
+
}]);
|
|
56
|
+
});
|
|
57
|
+
expect(img).toHaveAttribute('src', demoSrc);
|
|
58
|
+
});
|
|
59
|
+
test('renders with width and height', () => {
|
|
60
|
+
const {
|
|
61
|
+
getByTestId
|
|
62
|
+
} = render(React.createElement(Image, {
|
|
63
|
+
src: demoSrc,
|
|
64
|
+
width: 100,
|
|
65
|
+
height: 100,
|
|
66
|
+
"data-testid": 'image'
|
|
67
|
+
}));
|
|
68
|
+
expect(getByTestId('image')).toHaveStyle('--width: 100px;--height: 100px');
|
|
69
|
+
});
|
|
24
70
|
});
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useRef } from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import { withNativeProps } from '../../utils/native-props';
|
|
4
4
|
import { mergeProps } from '../../utils/with-default-props';
|
|
5
5
|
import { usePropsValue } from '../../utils/use-props-value';
|
|
6
6
|
import { Star } from './star';
|
|
7
|
+
import { useDrag } from '@use-gesture/react';
|
|
8
|
+
import { bound } from '../../utils/bound';
|
|
7
9
|
const classPrefix = `adm-rate`;
|
|
8
10
|
const defaultProps = {
|
|
9
11
|
count: 5,
|
|
@@ -16,6 +18,7 @@ const defaultProps = {
|
|
|
16
18
|
export const Rate = p => {
|
|
17
19
|
const props = mergeProps(defaultProps, p);
|
|
18
20
|
const [value, setValue] = usePropsValue(props);
|
|
21
|
+
const containerRef = useRef(null);
|
|
19
22
|
const starList = Array(props.count).fill(null);
|
|
20
23
|
|
|
21
24
|
function renderStar(v, half) {
|
|
@@ -40,11 +43,30 @@ export const Rate = p => {
|
|
|
40
43
|
}, props.character);
|
|
41
44
|
}
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
const bind = useDrag(state => {
|
|
47
|
+
if (props.readOnly) return;
|
|
48
|
+
const {
|
|
49
|
+
xy: [clientX]
|
|
50
|
+
} = state;
|
|
51
|
+
const container = containerRef.current;
|
|
52
|
+
if (!container) return;
|
|
53
|
+
const rect = container.getBoundingClientRect();
|
|
54
|
+
const rawValue = (clientX - rect.left) / rect.width * props.count;
|
|
55
|
+
const roundedValue = props.allowHalf ? Math.round(rawValue * 2) / 2 : Math.round(rawValue);
|
|
56
|
+
setValue(bound(roundedValue, 0, props.count));
|
|
57
|
+
}, {
|
|
58
|
+
axis: 'x',
|
|
59
|
+
preventScroll: true,
|
|
60
|
+
pointer: {
|
|
61
|
+
touch: true
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return withNativeProps(props, React.createElement("div", Object.assign({
|
|
44
65
|
className: classPrefix,
|
|
45
66
|
role: 'radiogroup',
|
|
46
|
-
"aria-readonly": props.readOnly
|
|
47
|
-
|
|
67
|
+
"aria-readonly": props.readOnly,
|
|
68
|
+
ref: containerRef
|
|
69
|
+
}, bind()), starList.map((_, i) => React.createElement("div", {
|
|
48
70
|
key: i,
|
|
49
71
|
className: classNames(`${classPrefix}-box`)
|
|
50
72
|
}, props.allowHalf && renderStar(i + 0.5, true), renderStar(i + 1, false)))));
|
|
@@ -20,6 +20,7 @@ export declare type SwipeActionProps = {
|
|
|
20
20
|
closeOnAction?: boolean;
|
|
21
21
|
children: ReactNode;
|
|
22
22
|
stopPropagation?: PropagationEvent[];
|
|
23
|
+
onActionsReveal?: (side: 'left' | 'right') => void;
|
|
23
24
|
} & NativeProps<'--background'>;
|
|
24
25
|
export declare const SwipeAction: React.ForwardRefExoticComponent<{
|
|
25
26
|
rightActions?: Action[] | undefined;
|
|
@@ -29,6 +30,7 @@ export declare const SwipeAction: React.ForwardRefExoticComponent<{
|
|
|
29
30
|
closeOnAction?: boolean | undefined;
|
|
30
31
|
children: ReactNode;
|
|
31
32
|
stopPropagation?: "click"[] | undefined;
|
|
33
|
+
onActionsReveal?: ((side: 'left' | 'right') => void) | undefined;
|
|
32
34
|
} & {
|
|
33
35
|
className?: string | undefined;
|
|
34
36
|
style?: (React.CSSProperties & Partial<Record<"--background", string>>) | undefined;
|
|
@@ -44,8 +44,26 @@ export const SwipeAction = forwardRef((p, ref) => {
|
|
|
44
44
|
}
|
|
45
45
|
}), []);
|
|
46
46
|
const draggingRef = useRef(false);
|
|
47
|
+
const dragCancelRef = useRef(null);
|
|
48
|
+
|
|
49
|
+
function forceCancelDrag() {
|
|
50
|
+
var _a;
|
|
51
|
+
|
|
52
|
+
(_a = dragCancelRef.current) === null || _a === void 0 ? void 0 : _a.call(dragCancelRef);
|
|
53
|
+
draggingRef.current = false;
|
|
54
|
+
}
|
|
55
|
+
|
|
47
56
|
const bind = useDrag(state => {
|
|
48
|
-
|
|
57
|
+
var _a;
|
|
58
|
+
|
|
59
|
+
dragCancelRef.current = state.cancel;
|
|
60
|
+
if (!state.intentional) return;
|
|
61
|
+
|
|
62
|
+
if (state.down) {
|
|
63
|
+
draggingRef.current = true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!draggingRef.current) return;
|
|
49
67
|
const [offsetX] = state.offset;
|
|
50
68
|
|
|
51
69
|
if (state.last) {
|
|
@@ -61,9 +79,15 @@ export const SwipeAction = forwardRef((p, ref) => {
|
|
|
61
79
|
position = 0;
|
|
62
80
|
}
|
|
63
81
|
|
|
82
|
+
const targetX = nearest([-rightWidth, 0, leftWidth], position);
|
|
64
83
|
api.start({
|
|
65
|
-
x:
|
|
84
|
+
x: targetX
|
|
66
85
|
});
|
|
86
|
+
|
|
87
|
+
if (targetX !== 0) {
|
|
88
|
+
(_a = p.onActionsReveal) === null || _a === void 0 ? void 0 : _a.call(p, targetX > 0 ? 'left' : 'right');
|
|
89
|
+
}
|
|
90
|
+
|
|
67
91
|
window.setTimeout(() => {
|
|
68
92
|
draggingRef.current = false;
|
|
69
93
|
});
|
|
@@ -88,17 +112,21 @@ export const SwipeAction = forwardRef((p, ref) => {
|
|
|
88
112
|
preventScroll: true,
|
|
89
113
|
pointer: {
|
|
90
114
|
touch: true
|
|
91
|
-
}
|
|
115
|
+
},
|
|
116
|
+
triggerAllEvents: true
|
|
92
117
|
});
|
|
93
118
|
|
|
94
119
|
function close() {
|
|
95
120
|
api.start({
|
|
96
121
|
x: 0
|
|
97
122
|
});
|
|
123
|
+
forceCancelDrag();
|
|
98
124
|
}
|
|
99
125
|
|
|
100
126
|
useImperativeHandle(ref, () => ({
|
|
101
127
|
show: (side = 'right') => {
|
|
128
|
+
var _a;
|
|
129
|
+
|
|
102
130
|
if (side === 'right') {
|
|
103
131
|
api.start({
|
|
104
132
|
x: -getRightWidth()
|
|
@@ -108,6 +136,8 @@ export const SwipeAction = forwardRef((p, ref) => {
|
|
|
108
136
|
x: getLeftWidth()
|
|
109
137
|
});
|
|
110
138
|
}
|
|
139
|
+
|
|
140
|
+
(_a = p.onActionsReveal) === null || _a === void 0 ? void 0 : _a.call(p, side);
|
|
111
141
|
},
|
|
112
142
|
close
|
|
113
143
|
}));
|
|
@@ -179,9 +209,7 @@ export const SwipeAction = forwardRef((p, ref) => {
|
|
|
179
209
|
if (x.goal !== 0) {
|
|
180
210
|
e.preventDefault();
|
|
181
211
|
e.stopPropagation();
|
|
182
|
-
|
|
183
|
-
x: 0
|
|
184
|
-
});
|
|
212
|
+
close();
|
|
185
213
|
}
|
|
186
214
|
}
|
|
187
215
|
}, React.createElement(animated.div, {
|
|
@@ -113,7 +113,18 @@ export const Swiper = forwardRef(staged((p, ref) => {
|
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
115
|
}), [count]);
|
|
116
|
+
const dragCancelRef = useRef(null);
|
|
117
|
+
|
|
118
|
+
function forceCancelDrag() {
|
|
119
|
+
var _a;
|
|
120
|
+
|
|
121
|
+
(_a = dragCancelRef.current) === null || _a === void 0 ? void 0 : _a.call(dragCancelRef);
|
|
122
|
+
draggingRef.current = false;
|
|
123
|
+
}
|
|
124
|
+
|
|
116
125
|
const bind = useDrag(state => {
|
|
126
|
+
dragCancelRef.current = state.cancel;
|
|
127
|
+
if (!state.intentional) return;
|
|
117
128
|
const slidePixels = getSlidePixels();
|
|
118
129
|
if (!slidePixels) return;
|
|
119
130
|
const paramIndex = isVertical ? 1 : 0;
|
|
@@ -142,6 +153,7 @@ export const Swiper = forwardRef(staged((p, ref) => {
|
|
|
142
153
|
const slidePixels = getSlidePixels();
|
|
143
154
|
return [position.get() / 100 * slidePixels, position.get() / 100 * slidePixels];
|
|
144
155
|
},
|
|
156
|
+
triggerAllEvents: true,
|
|
145
157
|
bounds: () => {
|
|
146
158
|
if (loop) return {};
|
|
147
159
|
const slidePixels = getSlidePixels();
|
|
@@ -256,6 +268,8 @@ export const Swiper = forwardRef(staged((p, ref) => {
|
|
|
256
268
|
if (draggingRef.current) {
|
|
257
269
|
e.stopPropagation();
|
|
258
270
|
}
|
|
271
|
+
|
|
272
|
+
forceCancelDrag();
|
|
259
273
|
}
|
|
260
274
|
}, props.allowTouchMove ? bind() : {}), renderTrackInner()), props.indicator === undefined ? React.createElement("div", {
|
|
261
275
|
className: `${classPrefix}-indicator`
|