antd-mobile 5.25.1 → 5.26.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.development.js +188 -121
- package/2x/bundle/antd-mobile.cjs.js +8 -8
- package/2x/bundle/antd-mobile.es.development.js +188 -121
- package/2x/bundle/antd-mobile.es.js +3936 -3910
- package/2x/bundle/antd-mobile.umd.development.js +188 -121
- package/2x/bundle/antd-mobile.umd.js +8 -8
- package/2x/bundle/style.css +29 -5
- package/2x/cjs/components/calendar/calendar.js +9 -1
- package/2x/cjs/components/floating-bubble/floating-bubble.d.ts +8 -0
- package/2x/cjs/components/floating-bubble/floating-bubble.js +25 -5
- package/2x/cjs/components/form/form.d.ts +1 -1
- package/2x/cjs/components/image-uploader/image-uploader.css +16 -1
- package/2x/cjs/components/image-uploader/image-uploader.d.ts +4 -1
- package/2x/cjs/components/image-uploader/image-uploader.js +46 -9
- package/2x/cjs/components/image-uploader/preview-item.d.ts +2 -1
- package/2x/cjs/components/image-uploader/preview-item.js +5 -7
- package/2x/cjs/components/mask/mask.d.ts +1 -1
- package/2x/cjs/components/mask/mask.js +6 -2
- package/2x/cjs/components/notice-bar/notice-bar.css +13 -4
- package/2x/cjs/components/notice-bar/notice-bar.d.ts +10 -8
- package/2x/cjs/components/notice-bar/notice-bar.js +5 -2
- package/2x/cjs/components/stepper/stepper.d.ts +2 -0
- package/2x/cjs/components/stepper/stepper.js +55 -32
- package/2x/cjs/components/water-mark/water-mark.d.ts +1 -1
- package/2x/cjs/components/water-mark/water-mark.js +5 -1
- package/2x/es/components/calendar/calendar.js +9 -1
- package/2x/es/components/floating-bubble/floating-bubble.d.ts +8 -0
- package/2x/es/components/floating-bubble/floating-bubble.js +26 -6
- package/2x/es/components/form/form.d.ts +1 -1
- package/2x/es/components/image-uploader/image-uploader.css +16 -1
- package/2x/es/components/image-uploader/image-uploader.d.ts +4 -1
- package/2x/es/components/image-uploader/image-uploader.js +48 -11
- package/2x/es/components/image-uploader/preview-item.d.ts +2 -1
- package/2x/es/components/image-uploader/preview-item.js +6 -8
- package/2x/es/components/mask/mask.d.ts +1 -1
- package/2x/es/components/mask/mask.js +6 -2
- package/2x/es/components/notice-bar/notice-bar.css +13 -4
- package/2x/es/components/notice-bar/notice-bar.d.ts +10 -8
- package/2x/es/components/notice-bar/notice-bar.js +5 -2
- package/2x/es/components/stepper/stepper.d.ts +2 -0
- package/2x/es/components/stepper/stepper.js +55 -32
- package/2x/es/components/water-mark/water-mark.d.ts +1 -1
- package/2x/es/components/water-mark/water-mark.js +5 -1
- package/2x/package.json +9 -9
- package/bundle/antd-mobile.cjs.development.js +188 -121
- package/bundle/antd-mobile.cjs.js +8 -8
- package/bundle/antd-mobile.compatible.umd.js +1 -1
- package/bundle/antd-mobile.es.development.js +188 -121
- package/bundle/antd-mobile.es.js +3936 -3910
- package/bundle/antd-mobile.umd.development.js +188 -121
- package/bundle/antd-mobile.umd.js +8 -8
- package/bundle/style.css +1 -1
- package/cjs/components/calendar/calendar.js +9 -1
- package/cjs/components/floating-bubble/floating-bubble.d.ts +8 -0
- package/cjs/components/floating-bubble/floating-bubble.js +25 -5
- package/cjs/components/form/form.d.ts +1 -1
- package/cjs/components/image-uploader/image-uploader.css +15 -1
- package/cjs/components/image-uploader/image-uploader.d.ts +4 -1
- package/cjs/components/image-uploader/image-uploader.js +46 -9
- package/cjs/components/image-uploader/preview-item.d.ts +2 -1
- package/cjs/components/image-uploader/preview-item.js +5 -7
- package/cjs/components/mask/mask.d.ts +1 -1
- package/cjs/components/mask/mask.js +6 -2
- package/cjs/components/notice-bar/notice-bar.css +11 -4
- package/cjs/components/notice-bar/notice-bar.d.ts +10 -8
- package/cjs/components/notice-bar/notice-bar.js +5 -2
- package/cjs/components/stepper/stepper.d.ts +2 -0
- package/cjs/components/stepper/stepper.js +55 -32
- package/cjs/components/water-mark/water-mark.d.ts +1 -1
- package/cjs/components/water-mark/water-mark.js +5 -1
- package/es/components/calendar/calendar.js +9 -1
- package/es/components/floating-bubble/floating-bubble.d.ts +8 -0
- package/es/components/floating-bubble/floating-bubble.js +26 -6
- package/es/components/form/form.d.ts +1 -1
- package/es/components/image-uploader/image-uploader.css +15 -1
- package/es/components/image-uploader/image-uploader.d.ts +4 -1
- package/es/components/image-uploader/image-uploader.js +48 -11
- package/es/components/image-uploader/preview-item.d.ts +2 -1
- package/es/components/image-uploader/preview-item.js +6 -8
- package/es/components/mask/mask.d.ts +1 -1
- package/es/components/mask/mask.js +6 -2
- package/es/components/notice-bar/notice-bar.css +11 -4
- package/es/components/notice-bar/notice-bar.d.ts +10 -8
- package/es/components/notice-bar/notice-bar.js +5 -2
- package/es/components/stepper/stepper.d.ts +2 -0
- package/es/components/stepper/stepper.js +55 -32
- package/es/components/water-mark/water-mark.d.ts +1 -1
- package/es/components/water-mark/water-mark.js +5 -1
- package/package.json +9 -9
- package/umd/antd-mobile.js +1 -1
- package/2x/cjs/components/image/test/image.test.d.ts +0 -1
- package/2x/cjs/components/image/test/image.test.js +0 -73
- package/2x/es/components/image/test/image.test.d.ts +0 -1
- package/2x/es/components/image/test/image.test.js +0 -70
- package/cjs/components/image/test/image.test.d.ts +0 -1
- package/cjs/components/image/test/image.test.js +0 -73
- package/es/components/image/test/image.test.d.ts +0 -1
- package/es/components/image/test/image.test.js +0 -70
|
@@ -32,35 +32,45 @@ const Stepper = p => {
|
|
|
32
32
|
step,
|
|
33
33
|
max,
|
|
34
34
|
min,
|
|
35
|
-
inputReadOnly
|
|
35
|
+
inputReadOnly,
|
|
36
|
+
digits,
|
|
37
|
+
formatter,
|
|
38
|
+
parser
|
|
36
39
|
} = props;
|
|
37
40
|
const {
|
|
38
41
|
locale
|
|
39
42
|
} = (0, _configProvider.useConfig)();
|
|
43
|
+
// ========================== Parse / Format ==========================
|
|
44
|
+
const parseValue = text => {
|
|
45
|
+
if (text === '') return null;
|
|
46
|
+
return parser ? parser(text) : parseFloat(text);
|
|
47
|
+
};
|
|
48
|
+
const formatValue = value => {
|
|
49
|
+
if (value === null) return '';
|
|
50
|
+
if (formatter) {
|
|
51
|
+
return formatter(value);
|
|
52
|
+
} else if (digits !== undefined) {
|
|
53
|
+
return value.toFixed(digits);
|
|
54
|
+
} else {
|
|
55
|
+
return value.toString();
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
// ======================== Value & InputValue ========================
|
|
40
59
|
const [value, setValue] = (0, _usePropsValue.usePropsValue)(props);
|
|
41
|
-
const [inputValue, setInputValue] = (0, _react.useState)(() =>
|
|
60
|
+
const [inputValue, setInputValue] = (0, _react.useState)(() => formatValue(value));
|
|
61
|
+
// >>>>> Value
|
|
42
62
|
function setValueWithCheck(v) {
|
|
43
63
|
if (isNaN(v)) return;
|
|
44
64
|
let target = (0, _bound.bound)(v, props.min, props.max);
|
|
45
|
-
if (
|
|
46
|
-
target = parseFloat(target.toFixed(
|
|
65
|
+
if (digits !== undefined) {
|
|
66
|
+
target = parseFloat(target.toFixed(digits));
|
|
47
67
|
}
|
|
48
68
|
setValue(target);
|
|
49
69
|
}
|
|
50
|
-
|
|
51
|
-
(0, _react.useEffect)(() => {
|
|
52
|
-
if (!hasFocus) {
|
|
53
|
-
setInputValue(convertValueToText(value, props.digits));
|
|
54
|
-
}
|
|
55
|
-
}, [hasFocus]);
|
|
56
|
-
(0, _react.useEffect)(() => {
|
|
57
|
-
if (!hasFocus) {
|
|
58
|
-
setInputValue(convertValueToText(value, props.digits));
|
|
59
|
-
}
|
|
60
|
-
}, [value, props.digits]);
|
|
70
|
+
// >>>>> Input
|
|
61
71
|
const handleInputChange = v => {
|
|
62
72
|
setInputValue(v);
|
|
63
|
-
const value =
|
|
73
|
+
const value = parseValue(v);
|
|
64
74
|
if (value === null) {
|
|
65
75
|
if (props.allowEmpty) {
|
|
66
76
|
setValue(null);
|
|
@@ -71,6 +81,29 @@ const Stepper = p => {
|
|
|
71
81
|
setValueWithCheck(value);
|
|
72
82
|
}
|
|
73
83
|
};
|
|
84
|
+
// ============================== Focus ===============================
|
|
85
|
+
const [focused, setFocused] = (0, _react.useState)(false);
|
|
86
|
+
const inputRef = _react.default.useRef(null);
|
|
87
|
+
function triggerFocus(nextFocus) {
|
|
88
|
+
setFocused(nextFocus);
|
|
89
|
+
// We will convert value to original text when focus
|
|
90
|
+
if (nextFocus) {
|
|
91
|
+
setInputValue(typeof value === 'number' ? String(value) : '');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
(0, _react.useEffect)(() => {
|
|
95
|
+
var _a, _b, _c;
|
|
96
|
+
if (focused) {
|
|
97
|
+
(_c = (_b = (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.nativeElement) === null || _b === void 0 ? void 0 : _b.select) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
98
|
+
}
|
|
99
|
+
}, [focused]);
|
|
100
|
+
// Focus change to format value
|
|
101
|
+
(0, _react.useEffect)(() => {
|
|
102
|
+
if (!focused) {
|
|
103
|
+
setInputValue(formatValue(value));
|
|
104
|
+
}
|
|
105
|
+
}, [focused, value, digits]);
|
|
106
|
+
// ============================ Operations ============================
|
|
74
107
|
const handleMinus = () => {
|
|
75
108
|
setValueWithCheck((0, _big.default)(value !== null && value !== void 0 ? value : 0).minus(step).toNumber());
|
|
76
109
|
};
|
|
@@ -93,9 +126,10 @@ const Stepper = p => {
|
|
|
93
126
|
}
|
|
94
127
|
return false;
|
|
95
128
|
};
|
|
129
|
+
// ============================== Render ==============================
|
|
96
130
|
return (0, _nativeProps.withNativeProps)(props, _react.default.createElement("div", {
|
|
97
131
|
className: (0, _classnames.default)(classPrefix, {
|
|
98
|
-
[`${classPrefix}-active`]:
|
|
132
|
+
[`${classPrefix}-active`]: focused
|
|
99
133
|
})
|
|
100
134
|
}, _react.default.createElement(_button.default, {
|
|
101
135
|
className: `${classPrefix}-minus`,
|
|
@@ -108,10 +142,11 @@ const Stepper = p => {
|
|
|
108
142
|
}, _react.default.createElement(_antdMobileIcons.MinusOutline, null)), _react.default.createElement("div", {
|
|
109
143
|
className: `${classPrefix}-middle`
|
|
110
144
|
}, _react.default.createElement(_input.default, {
|
|
145
|
+
ref: inputRef,
|
|
111
146
|
className: `${classPrefix}-input`,
|
|
112
147
|
onFocus: e => {
|
|
113
148
|
var _a;
|
|
114
|
-
|
|
149
|
+
triggerFocus(true);
|
|
115
150
|
(_a = props.onFocus) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
116
151
|
},
|
|
117
152
|
value: inputValue,
|
|
@@ -121,7 +156,7 @@ const Stepper = p => {
|
|
|
121
156
|
disabled: disabled,
|
|
122
157
|
onBlur: e => {
|
|
123
158
|
var _a;
|
|
124
|
-
|
|
159
|
+
triggerFocus(false);
|
|
125
160
|
(_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
126
161
|
},
|
|
127
162
|
readOnly: inputReadOnly,
|
|
@@ -140,16 +175,4 @@ const Stepper = p => {
|
|
|
140
175
|
"aria-label": locale.Stepper.increase
|
|
141
176
|
}, _react.default.createElement(_antdMobileIcons.AddOutline, null))));
|
|
142
177
|
};
|
|
143
|
-
exports.Stepper = Stepper;
|
|
144
|
-
function convertValueToText(value, digits) {
|
|
145
|
-
if (value === null) return '';
|
|
146
|
-
if (digits !== undefined) {
|
|
147
|
-
return value.toFixed(digits);
|
|
148
|
-
} else {
|
|
149
|
-
return value.toString();
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
function convertTextToValue(text) {
|
|
153
|
-
if (text === '') return null;
|
|
154
|
-
return parseFloat(text);
|
|
155
|
-
}
|
|
178
|
+
exports.Stepper = Stepper;
|
|
@@ -10,7 +10,7 @@ export declare type WaterMarkProps = {
|
|
|
10
10
|
image?: string;
|
|
11
11
|
imageWidth?: number;
|
|
12
12
|
imageHeight?: number;
|
|
13
|
-
content?: string;
|
|
13
|
+
content?: string | string[];
|
|
14
14
|
fontColor?: string;
|
|
15
15
|
fontStyle?: 'none' | 'normal' | 'italic' | 'oblique';
|
|
16
16
|
fontFamily?: string;
|
|
@@ -67,7 +67,11 @@ const WaterMark = p => {
|
|
|
67
67
|
const markSize = Number(fontSize) * ratio;
|
|
68
68
|
ctx.font = `${fontStyle} normal ${fontWeight} ${markSize}px/${markHeight}px ${fontFamily}`;
|
|
69
69
|
ctx.fillStyle = fontColor;
|
|
70
|
-
|
|
70
|
+
if (Array.isArray(content)) {
|
|
71
|
+
content.forEach((item, index) => ctx.fillText(item, 0, index * markSize));
|
|
72
|
+
} else {
|
|
73
|
+
ctx.fillText(content, 0, 0);
|
|
74
|
+
}
|
|
71
75
|
ctx.restore();
|
|
72
76
|
setBase64Url(canvas.toDataURL());
|
|
73
77
|
}
|
|
@@ -122,11 +122,17 @@ export const Calendar = forwardRef((p, ref) => {
|
|
|
122
122
|
let isSelect = false;
|
|
123
123
|
let isBegin = false;
|
|
124
124
|
let isEnd = false;
|
|
125
|
+
let isSelectRowBegin = false;
|
|
126
|
+
let isSelectRowEnd = false;
|
|
125
127
|
if (dateRange) {
|
|
126
128
|
const [begin, end] = dateRange;
|
|
127
129
|
isBegin = d.isSame(begin, 'day');
|
|
128
130
|
isEnd = d.isSame(end, 'day');
|
|
129
131
|
isSelect = isBegin || isEnd || d.isAfter(begin, 'day') && d.isBefore(end, 'day');
|
|
132
|
+
if (isSelect) {
|
|
133
|
+
isSelectRowBegin = (cells.length % 7 === 0 || d.isSame(d.startOf('month'), 'day')) && !isBegin;
|
|
134
|
+
isSelectRowEnd = (cells.length % 7 === 6 || d.isSame(d.endOf('month'), 'day')) && !isEnd;
|
|
135
|
+
}
|
|
130
136
|
}
|
|
131
137
|
const inThisMonth = d.month() === current.month();
|
|
132
138
|
const disabled = props.shouldDisableDate ? props.shouldDisableDate(d.toDate()) : maxDay && d.isAfter(maxDay, 'day') || minDay && d.isBefore(minDay, 'day');
|
|
@@ -136,7 +142,9 @@ export const Calendar = forwardRef((p, ref) => {
|
|
|
136
142
|
[`${classPrefix}-cell-today`]: d.isSame(today, 'day'),
|
|
137
143
|
[`${classPrefix}-cell-selected`]: isSelect,
|
|
138
144
|
[`${classPrefix}-cell-selected-begin`]: isBegin,
|
|
139
|
-
[`${classPrefix}-cell-selected-end`]: isEnd
|
|
145
|
+
[`${classPrefix}-cell-selected-end`]: isEnd,
|
|
146
|
+
[`${classPrefix}-cell-selected-row-begin`]: isSelectRowBegin,
|
|
147
|
+
[`${classPrefix}-cell-selected-row-end`]: isSelectRowEnd
|
|
140
148
|
}),
|
|
141
149
|
onClick: () => {
|
|
142
150
|
if (!props.selectionMode) return;
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import React, { FC } from 'react';
|
|
2
2
|
import { NativeProps } from '../../utils/native-props';
|
|
3
|
+
declare type Offset = {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
};
|
|
3
7
|
export declare type FloatingBubbleProps = {
|
|
4
8
|
onClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
|
5
9
|
axis?: 'x' | 'y' | 'xy' | 'lock';
|
|
6
10
|
magnetic?: 'x' | 'y';
|
|
7
11
|
children?: React.ReactNode;
|
|
12
|
+
offset?: Offset;
|
|
13
|
+
defaultOffset?: Offset;
|
|
14
|
+
onOffsetChange?: (offset: Offset) => void;
|
|
8
15
|
} & NativeProps<'--initial-position-left' | '--initial-position-right' | '--initial-position-top' | '--initial-position-bottom' | '--z-index' | '--edge-distance' | '--size' | '--border-radius' | '--background'>;
|
|
9
16
|
export declare const FloatingBubble: FC<FloatingBubbleProps>;
|
|
17
|
+
export {};
|
|
@@ -1,16 +1,28 @@
|
|
|
1
|
-
import React, { useRef } from 'react';
|
|
1
|
+
import React, { useRef, useEffect, useState } from 'react';
|
|
2
2
|
import { useSpring, animated, to } from '@react-spring/web';
|
|
3
3
|
import { useDrag } from '@use-gesture/react';
|
|
4
4
|
import { mergeProps } from '../../utils/with-default-props';
|
|
5
5
|
import { withNativeProps } from '../../utils/native-props';
|
|
6
6
|
const classPrefix = `adm-floating-bubble`;
|
|
7
7
|
const defaultProps = {
|
|
8
|
-
axis: 'y'
|
|
8
|
+
axis: 'y',
|
|
9
|
+
defaultOffset: {
|
|
10
|
+
x: 0,
|
|
11
|
+
y: 0
|
|
12
|
+
}
|
|
9
13
|
};
|
|
10
14
|
export const FloatingBubble = p => {
|
|
11
15
|
const props = mergeProps(defaultProps, p);
|
|
12
16
|
const boundaryRef = useRef(null);
|
|
13
17
|
const buttonRef = useRef(null);
|
|
18
|
+
const [innerValue, setInnerValue] = useState(props.offset === undefined ? props.defaultOffset : props.offset);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (props.offset === undefined) return;
|
|
21
|
+
api.start({
|
|
22
|
+
x: props.offset.x,
|
|
23
|
+
y: props.offset.y
|
|
24
|
+
});
|
|
25
|
+
}, [props.offset]);
|
|
14
26
|
/**
|
|
15
27
|
* memoize the `to` function
|
|
16
28
|
* inside a component that renders frequently
|
|
@@ -21,11 +33,12 @@ export const FloatingBubble = p => {
|
|
|
21
33
|
y,
|
|
22
34
|
opacity
|
|
23
35
|
}, api] = useSpring(() => ({
|
|
24
|
-
x:
|
|
25
|
-
y:
|
|
36
|
+
x: innerValue.x,
|
|
37
|
+
y: innerValue.y,
|
|
26
38
|
opacity: 1
|
|
27
39
|
}));
|
|
28
40
|
const bind = useDrag(state => {
|
|
41
|
+
var _a;
|
|
29
42
|
let nextX = state.offset[0];
|
|
30
43
|
let nextY = state.offset[1];
|
|
31
44
|
if (state.last && props.magnetic) {
|
|
@@ -54,10 +67,17 @@ export const FloatingBubble = p => {
|
|
|
54
67
|
}
|
|
55
68
|
}
|
|
56
69
|
}
|
|
57
|
-
|
|
70
|
+
const nextOffest = {
|
|
58
71
|
x: nextX,
|
|
59
72
|
y: nextY
|
|
60
|
-
}
|
|
73
|
+
};
|
|
74
|
+
if (props.offset === undefined) {
|
|
75
|
+
// Uncontrolled mode
|
|
76
|
+
api.start(nextOffest);
|
|
77
|
+
} else {
|
|
78
|
+
setInnerValue(nextOffest);
|
|
79
|
+
}
|
|
80
|
+
(_a = props.onOffsetChange) === null || _a === void 0 ? void 0 : _a.call(props, nextOffest);
|
|
61
81
|
// active status
|
|
62
82
|
api.start({
|
|
63
83
|
opacity: state.active ? 0.8 : 1
|
|
@@ -3,7 +3,7 @@ import { NativeProps } from '../../utils/native-props';
|
|
|
3
3
|
import { ListProps } from '../list';
|
|
4
4
|
import type { FormProps as RcFormProps, FormInstance as RCFormInstance } from 'rc-field-form';
|
|
5
5
|
import { FormContextType } from './context';
|
|
6
|
-
export declare type FormInstance = Pick<RCFormInstance, 'getFieldValue' | 'getFieldsValue' | 'getFieldError' | 'getFieldsError' | 'isFieldTouched' | 'isFieldsTouched' | 'resetFields' | 'setFields' | 'setFieldsValue' | 'submit' | 'validateFields'>;
|
|
6
|
+
export declare type FormInstance = Pick<RCFormInstance, 'getFieldValue' | 'getFieldsValue' | 'getFieldError' | 'getFieldsError' | 'isFieldTouched' | 'isFieldsTouched' | 'resetFields' | 'setFields' | 'setFieldValue' | 'setFieldsValue' | 'submit' | 'validateFields'>;
|
|
7
7
|
export declare type FormProps = Pick<RcFormProps, 'form' | 'initialValues' | 'name' | 'preserve' | 'validateMessages' | 'validateTrigger' | 'onFieldsChange' | 'onFinish' | 'onFinishFailed' | 'onValuesChange' | 'children'> & NativeProps<'--border-inner' | '--border-top' | '--border-bottom' | '--prefix-width'> & Partial<FormContextType> & {
|
|
8
8
|
footer?: ReactNode;
|
|
9
9
|
mode?: ListProps['mode'];
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
.adm-image-uploader {
|
|
2
2
|
--cell-size: 160px;
|
|
3
|
+
--gap: 24px;
|
|
4
|
+
---gap: var(--gap);
|
|
5
|
+
---gap-horizontal: var(--gap-horizontal, var(--gap));
|
|
6
|
+
---gap-vertical: var(--gap-vertical, var(--gap));
|
|
3
7
|
}
|
|
4
8
|
|
|
9
|
+
.adm-image-uploader-grid,
|
|
5
10
|
.adm-image-uploader-space {
|
|
6
|
-
--gap:
|
|
11
|
+
--gap: var(---gap);
|
|
12
|
+
--gap-horizontal: var(---gap-horizontal);
|
|
13
|
+
--gap-vertical: var(---gap-vertical);
|
|
7
14
|
}
|
|
8
15
|
|
|
9
16
|
.adm-image-uploader-cell {
|
|
@@ -94,4 +101,12 @@
|
|
|
94
101
|
width: 100%;
|
|
95
102
|
height: 100%;
|
|
96
103
|
border-radius: 8px;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.adm-image-uploader .adm-image-uploader-gap-measure {
|
|
107
|
+
position: absolute;
|
|
108
|
+
left: 0;
|
|
109
|
+
top: 0;
|
|
110
|
+
height: var(--gap-horizontal);
|
|
111
|
+
width: 0;
|
|
97
112
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { FC, InputHTMLAttributes } from 'react';
|
|
2
2
|
import { NativeProps } from '../../utils/native-props';
|
|
3
3
|
import type { ImageProps } from '../image';
|
|
4
|
+
import { GridProps } from '../grid';
|
|
4
5
|
export declare type TaskStatus = 'pending' | 'fail' | 'success';
|
|
5
6
|
export interface ImageUploadItem {
|
|
6
7
|
key?: string | number;
|
|
@@ -18,6 +19,7 @@ export declare type UploadTask = Pick<Task, 'id' | 'status'>;
|
|
|
18
19
|
export declare type ImageUploaderProps = {
|
|
19
20
|
defaultValue?: ImageUploadItem[];
|
|
20
21
|
value?: ImageUploadItem[];
|
|
22
|
+
columns?: GridProps['columns'];
|
|
21
23
|
onChange?: (items: ImageUploadItem[]) => void;
|
|
22
24
|
onUploadQueueChange?: (tasks: UploadTask[]) => void;
|
|
23
25
|
accept?: string;
|
|
@@ -27,6 +29,7 @@ export declare type ImageUploaderProps = {
|
|
|
27
29
|
disableUpload?: boolean;
|
|
28
30
|
showUpload?: boolean;
|
|
29
31
|
deletable?: boolean;
|
|
32
|
+
deleteIcon?: React.ReactNode;
|
|
30
33
|
capture?: InputHTMLAttributes<unknown>['capture'];
|
|
31
34
|
onPreview?: (index: number, item: ImageUploadItem) => void;
|
|
32
35
|
beforeUpload?: (file: File, files: File[]) => Promise<File | null> | File | null;
|
|
@@ -37,6 +40,6 @@ export declare type ImageUploaderProps = {
|
|
|
37
40
|
imageFit?: ImageProps['fit'];
|
|
38
41
|
children?: React.ReactNode;
|
|
39
42
|
renderItem?: (originNode: React.ReactElement, file: ImageUploadItem, fileList: ImageUploadItem[]) => React.ReactNode;
|
|
40
|
-
} & NativeProps<'--cell-size'>;
|
|
43
|
+
} & NativeProps<'--cell-size' | '--gap' | '--gap-vertical' | '--gap-horizontal'>;
|
|
41
44
|
export declare const ImageUploader: FC<ImageUploaderProps>;
|
|
42
45
|
export {};
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { __awaiter } from "tslib";
|
|
2
2
|
import React, { useRef, useState } from 'react';
|
|
3
|
-
import { AddOutline } from 'antd-mobile-icons';
|
|
3
|
+
import { AddOutline, CloseOutline } from 'antd-mobile-icons';
|
|
4
4
|
import { mergeProps } from '../../utils/with-default-props';
|
|
5
5
|
import ImageViewer from '../image-viewer';
|
|
6
6
|
import PreviewItem from './preview-item';
|
|
7
7
|
import { usePropsValue } from '../../utils/use-props-value';
|
|
8
|
-
import { useIsomorphicLayoutEffect, useUnmount } from 'ahooks';
|
|
8
|
+
import { useIsomorphicLayoutEffect, useUnmount, useSize } from 'ahooks';
|
|
9
9
|
import Space from '../space';
|
|
10
10
|
import { withNativeProps } from '../../utils/native-props';
|
|
11
|
+
import { measureCSSLength } from '../../utils/measure-css-length';
|
|
11
12
|
import { useConfig } from '../config-provider';
|
|
13
|
+
import Grid from '../grid';
|
|
12
14
|
const classPrefix = `adm-image-uploader`;
|
|
13
15
|
const defaultProps = {
|
|
14
16
|
disableUpload: false,
|
|
15
17
|
deletable: true,
|
|
18
|
+
deleteIcon: React.createElement(CloseOutline, {
|
|
19
|
+
className: `${classPrefix}-cell-delete-icon`
|
|
20
|
+
}),
|
|
16
21
|
showUpload: true,
|
|
17
22
|
multiple: false,
|
|
18
23
|
maxCount: 0,
|
|
@@ -27,8 +32,26 @@ export const ImageUploader = p => {
|
|
|
27
32
|
locale
|
|
28
33
|
} = useConfig();
|
|
29
34
|
const props = mergeProps(defaultProps, p);
|
|
35
|
+
const {
|
|
36
|
+
columns
|
|
37
|
+
} = props;
|
|
30
38
|
const [value, setValue] = usePropsValue(props);
|
|
31
39
|
const [tasks, setTasks] = useState([]);
|
|
40
|
+
const containerRef = useRef(null);
|
|
41
|
+
const containerSize = useSize(containerRef);
|
|
42
|
+
const gapMeasureRef = useRef(null);
|
|
43
|
+
const [cellSize, setCellSize] = useState(80);
|
|
44
|
+
useIsomorphicLayoutEffect(() => {
|
|
45
|
+
const gapMeasure = gapMeasureRef.current;
|
|
46
|
+
if (columns && containerSize && gapMeasure) {
|
|
47
|
+
const width = containerSize.width;
|
|
48
|
+
const gap = measureCSSLength(window.getComputedStyle(gapMeasure).getPropertyValue('height'));
|
|
49
|
+
setCellSize((width - gap * (columns - 1)) / columns);
|
|
50
|
+
}
|
|
51
|
+
}, [containerSize === null || containerSize === void 0 ? void 0 : containerSize.width]);
|
|
52
|
+
const style = {
|
|
53
|
+
'--cell-size': cellSize + 'px'
|
|
54
|
+
};
|
|
32
55
|
useIsomorphicLayoutEffect(() => {
|
|
33
56
|
setTasks(prev => prev.filter(task => {
|
|
34
57
|
if (task.url === undefined) return true;
|
|
@@ -152,6 +175,7 @@ export const ImageUploader = p => {
|
|
|
152
175
|
key: (_a = fileItem.key) !== null && _a !== void 0 ? _a : index,
|
|
153
176
|
url: (_b = fileItem.thumbnailUrl) !== null && _b !== void 0 ? _b : fileItem.url,
|
|
154
177
|
deletable: props.deletable,
|
|
178
|
+
deleteIcon: props.deleteIcon,
|
|
155
179
|
imageFit: props.imageFit,
|
|
156
180
|
onClick: () => {
|
|
157
181
|
if (props.preview) {
|
|
@@ -169,21 +193,19 @@ export const ImageUploader = p => {
|
|
|
169
193
|
return renderItem ? renderItem(originNode, fileItem, value) : originNode;
|
|
170
194
|
});
|
|
171
195
|
};
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
wrap: true,
|
|
177
|
-
block: true
|
|
178
|
-
}, renderImages(), finalTasks.map(task => {
|
|
196
|
+
const contentNode = React.createElement(React.Fragment, null, renderImages(), tasks.map(task => {
|
|
197
|
+
if (!props.showFailed && task.status === 'fail') {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
179
200
|
return React.createElement(PreviewItem, {
|
|
180
201
|
key: task.id,
|
|
181
202
|
file: task.file,
|
|
182
203
|
deletable: task.status !== 'pending',
|
|
204
|
+
deleteIcon: props.deleteIcon,
|
|
183
205
|
status: task.status,
|
|
184
206
|
imageFit: props.imageFit,
|
|
185
207
|
onDelete: () => {
|
|
186
|
-
setTasks(
|
|
208
|
+
setTasks(tasks.filter(x => x.id !== task.id));
|
|
187
209
|
}
|
|
188
210
|
});
|
|
189
211
|
}), showUpload && React.createElement("div", {
|
|
@@ -202,5 +224,20 @@ export const ImageUploader = p => {
|
|
|
202
224
|
className: `${classPrefix}-input`,
|
|
203
225
|
onChange: onChange,
|
|
204
226
|
"aria-hidden": true
|
|
205
|
-
})))
|
|
227
|
+
})));
|
|
228
|
+
return withNativeProps(props, React.createElement("div", {
|
|
229
|
+
className: classPrefix,
|
|
230
|
+
ref: containerRef
|
|
231
|
+
}, columns ? React.createElement(Grid, {
|
|
232
|
+
className: `${classPrefix}-grid`,
|
|
233
|
+
columns: columns,
|
|
234
|
+
style: style
|
|
235
|
+
}, React.createElement("div", {
|
|
236
|
+
className: `${classPrefix}-gap-measure`,
|
|
237
|
+
ref: gapMeasureRef
|
|
238
|
+
}), contentNode.props.children) : React.createElement(Space, {
|
|
239
|
+
className: `${classPrefix}-space`,
|
|
240
|
+
wrap: true,
|
|
241
|
+
block: true
|
|
242
|
+
}, contentNode.props.children)));
|
|
206
243
|
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { FC } from 'react';
|
|
1
|
+
import React, { FC } from 'react';
|
|
2
2
|
import { TaskStatus } from './image-uploader';
|
|
3
3
|
import type { ImageProps } from '../image';
|
|
4
4
|
declare type Props = {
|
|
5
5
|
onClick?: () => void;
|
|
6
6
|
onDelete?: () => void;
|
|
7
7
|
deletable: boolean;
|
|
8
|
+
deleteIcon: React.ReactNode;
|
|
8
9
|
url?: string;
|
|
9
10
|
file?: File;
|
|
10
11
|
status?: TaskStatus;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
import { CloseOutline } from 'antd-mobile-icons';
|
|
1
|
+
import React, { useEffect, useMemo } from 'react';
|
|
3
2
|
import classNames from 'classnames';
|
|
4
3
|
import Image from '../image';
|
|
5
4
|
import SpinLoading from '../spin-loading';
|
|
@@ -13,6 +12,7 @@ const PreviewItem = props => {
|
|
|
13
12
|
url,
|
|
14
13
|
file,
|
|
15
14
|
deletable,
|
|
15
|
+
deleteIcon,
|
|
16
16
|
onDelete,
|
|
17
17
|
imageFit
|
|
18
18
|
} = props;
|
|
@@ -25,11 +25,11 @@ const PreviewItem = props => {
|
|
|
25
25
|
}
|
|
26
26
|
return '';
|
|
27
27
|
}, [url, file]);
|
|
28
|
-
|
|
28
|
+
useEffect(() => {
|
|
29
29
|
return () => {
|
|
30
|
-
URL.revokeObjectURL(src);
|
|
30
|
+
if (file) URL.revokeObjectURL(src);
|
|
31
31
|
};
|
|
32
|
-
}, [src]);
|
|
32
|
+
}, [src, file]);
|
|
33
33
|
function renderLoading() {
|
|
34
34
|
return props.status === 'pending' && React.createElement("div", {
|
|
35
35
|
className: `${classPrefix}-cell-mask`
|
|
@@ -45,9 +45,7 @@ const PreviewItem = props => {
|
|
|
45
45
|
return deletable && React.createElement("span", {
|
|
46
46
|
className: `${classPrefix}-cell-delete`,
|
|
47
47
|
onClick: onDelete
|
|
48
|
-
},
|
|
49
|
-
className: `${classPrefix}-cell-delete-icon`
|
|
50
|
-
}));
|
|
48
|
+
}, deleteIcon);
|
|
51
49
|
}
|
|
52
50
|
return React.createElement("div", {
|
|
53
51
|
className: classNames(`${classPrefix}-cell`, props.status === 'fail' && `${classPrefix}-cell-fail`)
|
|
@@ -8,7 +8,7 @@ export declare type MaskProps = {
|
|
|
8
8
|
destroyOnClose?: boolean;
|
|
9
9
|
forceRender?: boolean;
|
|
10
10
|
disableBodyScroll?: boolean;
|
|
11
|
-
color?: '
|
|
11
|
+
color?: 'white' | 'black' | (string & {});
|
|
12
12
|
opacity?: 'default' | 'thin' | 'thick' | number;
|
|
13
13
|
getContainer?: GetContainer;
|
|
14
14
|
afterShow?: () => void;
|
|
@@ -14,6 +14,10 @@ const opacityRecord = {
|
|
|
14
14
|
thin: 0.35,
|
|
15
15
|
thick: 0.75
|
|
16
16
|
};
|
|
17
|
+
const colorRecord = {
|
|
18
|
+
black: '0, 0, 0',
|
|
19
|
+
white: '255, 255, 255'
|
|
20
|
+
};
|
|
17
21
|
const defaultProps = {
|
|
18
22
|
visible: true,
|
|
19
23
|
destroyOnClose: false,
|
|
@@ -34,8 +38,8 @@ export const Mask = p => {
|
|
|
34
38
|
const background = useMemo(() => {
|
|
35
39
|
var _a;
|
|
36
40
|
const opacity = (_a = opacityRecord[props.opacity]) !== null && _a !== void 0 ? _a : props.opacity;
|
|
37
|
-
const rgb = props.color
|
|
38
|
-
return `rgba(${rgb}, ${opacity})
|
|
41
|
+
const rgb = colorRecord[props.color];
|
|
42
|
+
return rgb ? `rgba(${rgb}, ${opacity})` : props.color;
|
|
39
43
|
}, [props.color, props.opacity]);
|
|
40
44
|
const [active, setActive] = useState(props.visible);
|
|
41
45
|
const unmountedRef = useUnmountedRef();
|
|
@@ -4,11 +4,10 @@
|
|
|
4
4
|
--text-color: var(--adm-color-white);
|
|
5
5
|
--font-size: var(--adm-font-size-7);
|
|
6
6
|
--icon-font-size: var(--adm-font-size-10);
|
|
7
|
-
--height:
|
|
7
|
+
--height: 80px;
|
|
8
8
|
height: var(--height);
|
|
9
9
|
box-sizing: border-box;
|
|
10
10
|
font-size: var(--font-size);
|
|
11
|
-
line-height: var(--height);
|
|
12
11
|
padding: 0 24px;
|
|
13
12
|
display: flex;
|
|
14
13
|
align-items: center;
|
|
@@ -46,7 +45,6 @@
|
|
|
46
45
|
flex-shrink: 0;
|
|
47
46
|
margin-right: 16px;
|
|
48
47
|
font-size: var(--icon-font-size);
|
|
49
|
-
line-height: var(--height);
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
.adm-notice-bar .adm-notice-bar-content {
|
|
@@ -61,10 +59,13 @@
|
|
|
61
59
|
.adm-notice-bar .adm-notice-bar-content .adm-notice-bar-content-inner {
|
|
62
60
|
width: auto;
|
|
63
61
|
transition-timing-function: linear;
|
|
64
|
-
position: absolute;
|
|
65
62
|
white-space: nowrap;
|
|
66
63
|
}
|
|
67
64
|
|
|
65
|
+
.adm-notice-bar-wrap.adm-notice-bar .adm-notice-bar-content .adm-notice-bar-content-inner {
|
|
66
|
+
white-space: normal;
|
|
67
|
+
}
|
|
68
|
+
|
|
68
69
|
.adm-notice-bar .adm-notice-bar-right {
|
|
69
70
|
flex-shrink: 0;
|
|
70
71
|
margin-left: 24px;
|
|
@@ -81,4 +82,12 @@
|
|
|
81
82
|
|
|
82
83
|
.adm-notice-bar-close-icon {
|
|
83
84
|
font-size: var(--adm-font-size-10);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.adm-notice-bar-wrap {
|
|
88
|
+
height: auto;
|
|
89
|
+
align-items: flex-start;
|
|
90
|
+
padding-top: 16px;
|
|
91
|
+
padding-bottom: 16px;
|
|
92
|
+
line-height: 44px;
|
|
84
93
|
}
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { NativeProps } from '../../utils/native-props';
|
|
3
3
|
export declare type NoticeBarProps = {
|
|
4
|
-
/**
|
|
4
|
+
/** The type of the NoticeBar */
|
|
5
5
|
color?: 'default' | 'alert' | 'error' | 'info';
|
|
6
|
-
/**
|
|
6
|
+
/** TDelay to start scrolling, unit ms */
|
|
7
7
|
delay?: number;
|
|
8
|
-
/**
|
|
8
|
+
/** Scroll speed, unit px/s */
|
|
9
9
|
speed?: number;
|
|
10
|
-
/**
|
|
10
|
+
/** The content of the NoticeBar */
|
|
11
11
|
content: React.ReactNode;
|
|
12
|
-
/**
|
|
12
|
+
/** Whether it can be closed */
|
|
13
13
|
closeable?: boolean;
|
|
14
|
-
/**
|
|
14
|
+
/** Callback when closed */
|
|
15
15
|
onClose?: () => void;
|
|
16
|
-
/**
|
|
16
|
+
/** Additional operating area, displayed to the left of the close button */
|
|
17
17
|
extra?: React.ReactNode;
|
|
18
|
-
/**
|
|
18
|
+
/** Radio icon on the left */
|
|
19
19
|
icon?: React.ReactNode;
|
|
20
|
+
/** Whether to display multiple lines */
|
|
21
|
+
wrap?: boolean;
|
|
20
22
|
} & NativeProps<'--background-color' | '--border-color' | '--text-color' | '--font-size' | '--icon-font-size' | '--height'>;
|
|
21
23
|
export declare const NoticeBar: React.NamedExoticComponent<NoticeBarProps>;
|
|
@@ -11,6 +11,7 @@ const defaultProps = {
|
|
|
11
11
|
color: 'default',
|
|
12
12
|
delay: 2000,
|
|
13
13
|
speed: 50,
|
|
14
|
+
wrap: false,
|
|
14
15
|
icon: React.createElement(SoundOutline, null)
|
|
15
16
|
};
|
|
16
17
|
export const NoticeBar = memo(p => {
|
|
@@ -22,7 +23,7 @@ export const NoticeBar = memo(p => {
|
|
|
22
23
|
const delayLockRef = useRef(true);
|
|
23
24
|
const animatingRef = useRef(false);
|
|
24
25
|
function start() {
|
|
25
|
-
if (delayLockRef.current) return;
|
|
26
|
+
if (delayLockRef.current || props.wrap) return;
|
|
26
27
|
const container = containerRef.current;
|
|
27
28
|
const text = textRef.current;
|
|
28
29
|
if (!container || !text) return;
|
|
@@ -61,7 +62,9 @@ export const NoticeBar = memo(p => {
|
|
|
61
62
|
});
|
|
62
63
|
if (!visible) return null;
|
|
63
64
|
return withNativeProps(props, React.createElement("div", {
|
|
64
|
-
className: classNames(classPrefix, `${classPrefix}-${props.color}
|
|
65
|
+
className: classNames(classPrefix, `${classPrefix}-${props.color}`, {
|
|
66
|
+
[`${classPrefix}-wrap`]: props.wrap
|
|
67
|
+
})
|
|
65
68
|
}, props.icon && React.createElement("span", {
|
|
66
69
|
className: `${classPrefix}-left`
|
|
67
70
|
}, props.icon), React.createElement("span", {
|
|
@@ -20,6 +20,8 @@ export declare type StepperProps = Pick<InputProps, 'onFocus' | 'onBlur'> & (Val
|
|
|
20
20
|
digits?: number;
|
|
21
21
|
disabled?: boolean;
|
|
22
22
|
inputReadOnly?: boolean;
|
|
23
|
+
parser?: (text: string) => number;
|
|
24
|
+
formatter?: (value?: number) => string;
|
|
23
25
|
} & NativeProps<'--height' | '--input-width' | '--input-font-size' | '--input-background-color' | '--border-radius' | '--border' | '--border-inner' | '--active-border' | '--button-font-size' | '--button-background-color' | '--button-width' | '--input-font-color' | '--button-text-color'>;
|
|
24
26
|
export declare const Stepper: FC<StepperProps>;
|
|
25
27
|
export {};
|