@laser-ui/components 2.4.0 → 2.6.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/CHANGELOG.md +12 -0
- package/cascader/Cascader.js +6 -2
- package/cascader/internal/CascaderPanel.d.ts +1 -0
- package/cascader/internal/CascaderPanel.js +7 -3
- package/cascader/internal/CascaderSearchPanel.d.ts +1 -0
- package/cascader/internal/CascaderSearchPanel.js +2 -2
- package/cascader/types.d.ts +1 -0
- package/date-picker/DatePicker.js +176 -168
- package/dropdown/Dropdown.js +1 -5
- package/hooks/useNestedPopup.d.ts +3 -4
- package/hooks/useNestedPopup.js +7 -12
- package/image/Image.js +14 -20
- package/input/InputNumber.js +39 -35
- package/menu/Menu.js +1 -2
- package/package.json +2 -2
- package/spinner/Spinner.js +8 -10
- package/time-picker/TimePicker.js +173 -149
- package/transition/Transition.js +7 -9
package/dropdown/Dropdown.js
CHANGED
|
@@ -27,11 +27,7 @@ export function Dropdown(props) {
|
|
|
27
27
|
const updateSubPosition = useRef(new Map());
|
|
28
28
|
const [focusVisible, focusVisibleProps] = useFocusVisible((code) => code.startsWith('Arrow') || ['Home', 'End', 'Enter', 'Space'].includes(code));
|
|
29
29
|
const [visible, changeVisible] = useControlled(defaultVisible !== null && defaultVisible !== void 0 ? defaultVisible : false, visibleProp, onVisibleChange);
|
|
30
|
-
const {
|
|
31
|
-
if (!visible) {
|
|
32
|
-
popupIdsRef.current = [];
|
|
33
|
-
}
|
|
34
|
-
const popupIds = popupIdsRef.current;
|
|
30
|
+
const { popupIds, setPopupIds, addPopupId, removePopupId } = useNestedPopup(visible);
|
|
35
31
|
const [focusIds, setFocusIds] = useState([]);
|
|
36
32
|
const focusId = (() => {
|
|
37
33
|
var _a;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import type { DraftFunction } from '@laser-ui/hooks/useImmer';
|
|
2
1
|
interface PopupId<ID> {
|
|
3
2
|
id: ID;
|
|
4
3
|
visible: boolean;
|
|
5
4
|
}
|
|
6
|
-
export declare function useNestedPopup<ID>(): {
|
|
7
|
-
|
|
8
|
-
setPopupIds: (
|
|
5
|
+
export declare function useNestedPopup<ID>(visible?: boolean): {
|
|
6
|
+
popupIds: PopupId<ID>[];
|
|
7
|
+
setPopupIds: import("@laser-ui/hooks/useImmer").Updater<PopupId<ID>[]>;
|
|
9
8
|
addPopupId: (id: ID) => void;
|
|
10
9
|
removePopupId: (id: ID) => void;
|
|
11
10
|
};
|
package/hooks/useNestedPopup.js
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const popupIdsRef = useRef([]);
|
|
8
|
-
const setPopupIds = (value) => {
|
|
9
|
-
popupIdsRef.current = isFunction(value) ? produce(popupIdsRef.current, value) : freeze(value);
|
|
10
|
-
forceUpdate();
|
|
11
|
-
};
|
|
1
|
+
import { useImmer } from '@laser-ui/hooks';
|
|
2
|
+
export function useNestedPopup(visible = true) {
|
|
3
|
+
const [popupIds, setPopupIds] = useImmer([]);
|
|
4
|
+
if (!visible && popupIds.length > 0) {
|
|
5
|
+
setPopupIds([]);
|
|
6
|
+
}
|
|
12
7
|
return {
|
|
13
|
-
|
|
8
|
+
popupIds,
|
|
14
9
|
setPopupIds,
|
|
15
10
|
addPopupId: (id) => {
|
|
16
11
|
setPopupIds((draft) => {
|
package/image/Image.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useForceUpdate } from '@laser-ui/hooks';
|
|
4
3
|
import { checkNodeExist } from '@laser-ui/utils';
|
|
5
4
|
import { has } from 'lodash';
|
|
6
|
-
import { Fragment,
|
|
5
|
+
import { Fragment, useState } from 'react';
|
|
7
6
|
import { ImageAction } from './ImageAction';
|
|
8
7
|
import { ImageLoader } from './ImageLoader';
|
|
9
8
|
import { ImagePreview } from './ImagePreview';
|
|
@@ -13,42 +12,37 @@ import { mergeCS } from '../utils';
|
|
|
13
12
|
export const Image = (props) => {
|
|
14
13
|
const _a = useComponentProps('Image', props), { styleOverrides, styleProvider, loading, error, actions, imgProps } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "loading", "error", "actions", "imgProps"]);
|
|
15
14
|
const styled = useStyled(CLASSES, { image: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.image }, styleOverrides);
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
dataRef.current.isLoading = true;
|
|
24
|
-
dataRef.current.isError = false;
|
|
15
|
+
const [previousSrc, setPreviousSrc] = useState(imgProps.src);
|
|
16
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
17
|
+
const [isError, setIsError] = useState(false);
|
|
18
|
+
if (imgProps.src !== previousSrc) {
|
|
19
|
+
setPreviousSrc(imgProps.src);
|
|
20
|
+
setIsLoading(true);
|
|
21
|
+
setIsError(false);
|
|
25
22
|
}
|
|
26
23
|
return (_jsxs("div", Object.assign({}, restProps, mergeCS(styled('image'), {
|
|
27
24
|
className: restProps.className,
|
|
28
25
|
style: restProps.style,
|
|
29
|
-
}), { children: [
|
|
26
|
+
}), { children: [isLoading && checkNodeExist(loading) && loading, isError && checkNodeExist(error) && error, actions && (_jsx("div", Object.assign({}, styled('image__actions'), { children: actions.map((node, index) => {
|
|
30
27
|
const { id, action } = (has(node, ['id', 'action']) ? node : { id: index, action: node });
|
|
31
28
|
return _jsx(Fragment, { children: action }, id);
|
|
32
29
|
}) }))), _jsx("img", Object.assign({}, imgProps, mergeCS(styled('image__img'), {
|
|
33
30
|
className: imgProps === null || imgProps === void 0 ? void 0 : imgProps.className,
|
|
34
|
-
style: Object.assign(Object.assign({}, imgProps === null || imgProps === void 0 ? void 0 : imgProps.style), { display: (
|
|
31
|
+
style: Object.assign(Object.assign({}, imgProps === null || imgProps === void 0 ? void 0 : imgProps.style), { display: (isLoading && loading) || (isError && error) ? 'none' : undefined }),
|
|
35
32
|
}), { onLoadStart: (e) => {
|
|
36
33
|
var _a;
|
|
37
34
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=458851
|
|
38
35
|
(_a = imgProps === null || imgProps === void 0 ? void 0 : imgProps.onLoadStart) === null || _a === void 0 ? void 0 : _a.call(imgProps, e);
|
|
39
|
-
|
|
40
|
-
forceUpdate();
|
|
36
|
+
setIsLoading(true);
|
|
41
37
|
}, onLoad: (e) => {
|
|
42
38
|
var _a;
|
|
43
39
|
(_a = imgProps === null || imgProps === void 0 ? void 0 : imgProps.onLoad) === null || _a === void 0 ? void 0 : _a.call(imgProps, e);
|
|
44
|
-
|
|
45
|
-
forceUpdate();
|
|
40
|
+
setIsLoading(false);
|
|
46
41
|
}, onError: (e) => {
|
|
47
42
|
var _a;
|
|
48
43
|
(_a = imgProps === null || imgProps === void 0 ? void 0 : imgProps.onError) === null || _a === void 0 ? void 0 : _a.call(imgProps, e);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
forceUpdate();
|
|
44
|
+
setIsLoading(false);
|
|
45
|
+
setIsError(true);
|
|
52
46
|
} }))] })));
|
|
53
47
|
};
|
|
54
48
|
Image.Loader = ImageLoader;
|
package/input/InputNumber.js
CHANGED
|
@@ -1,46 +1,52 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useAsync, useEvent,
|
|
3
|
+
import { useAsync, useEvent, useRefExtra } from '@laser-ui/hooks';
|
|
4
4
|
import { checkNodeExist, setRef } from '@laser-ui/utils';
|
|
5
5
|
import CancelFilled from '@material-design-icons/svg/filled/cancel.svg?react';
|
|
6
6
|
import KeyboardArrowDownOutlined from '@material-design-icons/svg/outlined/keyboard_arrow_down.svg?react';
|
|
7
7
|
import KeyboardArrowUpOutlined from '@material-design-icons/svg/outlined/keyboard_arrow_up.svg?react';
|
|
8
8
|
import { isNull, isUndefined } from 'lodash';
|
|
9
|
-
import { useRef } from 'react';
|
|
9
|
+
import { useRef, useState } from 'react';
|
|
10
10
|
import { CLASSES } from './vars';
|
|
11
11
|
import { BaseInput } from '../base-input';
|
|
12
12
|
import { useComponentProps, useControlled, useDesign, useScopedProps, useStyled, useTranslation } from '../hooks';
|
|
13
13
|
import { Icon } from '../icon';
|
|
14
14
|
import { mergeCS } from '../utils';
|
|
15
|
+
function syncValueToPlaceholder(value, placeholder) {
|
|
16
|
+
if (isNull(value)) {
|
|
17
|
+
if (placeholder) {
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
if (value !== Number(placeholder)) {
|
|
23
|
+
return value.toString();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
15
27
|
export function InputNumber(props) {
|
|
16
28
|
const _a = useComponentProps('InputNumber', props), { styleOverrides, styleProvider, formControl, model, defaultModel, max, min, step = 1, integer = false, prefix, suffix, clearable, placeholder, size: sizeProp, numberButton = true, disabled: disabledProp = false, inputProps, onModelChange, onClear } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "formControl", "model", "defaultModel", "max", "min", "step", "integer", "prefix", "suffix", "clearable", "placeholder", "size", "numberButton", "disabled", "inputProps", "onModelChange", "onClear"]);
|
|
17
29
|
const styled = useStyled(CLASSES, { input: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.input }, styleOverrides);
|
|
18
30
|
const async = useAsync();
|
|
19
31
|
const { t } = useTranslation();
|
|
20
|
-
const
|
|
21
|
-
const dataRef = useRef({
|
|
22
|
-
inputFocused: false,
|
|
23
|
-
});
|
|
32
|
+
const dataRef = useRef({});
|
|
24
33
|
const windowRef = useRefExtra(() => window);
|
|
25
34
|
const inputRef = useRef(null);
|
|
26
35
|
const [value, _changeValue] = useControlled(defaultModel !== null && defaultModel !== void 0 ? defaultModel : null, model, onModelChange, undefined, formControl === null || formControl === void 0 ? void 0 : formControl.control);
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
const [placeholderValue, setPlaceholderValue] = useState(() => (isNull(value) ? '' : value.toString()));
|
|
37
|
+
const newPlaceholderValue = syncValueToPlaceholder(value, placeholderValue);
|
|
38
|
+
if (!isUndefined(newPlaceholderValue)) {
|
|
39
|
+
setPlaceholderValue(newPlaceholderValue);
|
|
40
|
+
}
|
|
32
41
|
const changeValue = (val) => {
|
|
33
|
-
if ((isNull(val) ? '' : val.toString()) !== inputValue) {
|
|
34
|
-
forceUpdate();
|
|
35
|
-
}
|
|
36
|
-
dataRef.current.inputValue = undefined;
|
|
37
42
|
_changeValue(val);
|
|
43
|
+
setPlaceholderValue(isNull(val) ? '' : val.toString());
|
|
38
44
|
};
|
|
39
45
|
const { size, disabled } = useScopedProps({ size: sizeProp, disabled: disabledProp || (formControl === null || formControl === void 0 ? void 0 : formControl.control.disabled) });
|
|
40
46
|
const getValue = (val) => { var _a, _b; return Number(Math.max(min !== null && min !== void 0 ? min : -Infinity, Math.min(max !== null && max !== void 0 ? max : Infinity, val)).toFixed((_b = (_a = step.toString().split('.')[1]) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0)); };
|
|
41
47
|
const handleNumberButtonMouseDown = (increase = true) => {
|
|
42
|
-
|
|
43
|
-
let val =
|
|
48
|
+
const val = getValue((() => {
|
|
49
|
+
let val = placeholderValue.length > 0 ? Number(placeholderValue) : null;
|
|
44
50
|
if (isNull(val)) {
|
|
45
51
|
return 0;
|
|
46
52
|
}
|
|
@@ -48,13 +54,14 @@ export function InputNumber(props) {
|
|
|
48
54
|
val = Math.round(val);
|
|
49
55
|
}
|
|
50
56
|
return increase ? val + step : val - step;
|
|
51
|
-
})())
|
|
57
|
+
})());
|
|
58
|
+
changeValue(val);
|
|
52
59
|
const loop = (prev) => {
|
|
53
60
|
const val = getValue(increase ? prev + step : prev - step);
|
|
54
61
|
changeValue(val);
|
|
55
62
|
dataRef.current.clearLoop = async.setTimeout(() => loop(val), 50);
|
|
56
63
|
};
|
|
57
|
-
dataRef.current.clearTid = async.setTimeout(() => loop(Number(
|
|
64
|
+
dataRef.current.clearTid = async.setTimeout(() => loop(Number(placeholderValue)), 400);
|
|
58
65
|
};
|
|
59
66
|
const handleNumberButtonMouseUp = () => {
|
|
60
67
|
var _a, _b, _c, _d;
|
|
@@ -95,32 +102,26 @@ export function InputNumber(props) {
|
|
|
95
102
|
inputRef.current = null;
|
|
96
103
|
ret();
|
|
97
104
|
};
|
|
98
|
-
}, value:
|
|
99
|
-
|
|
100
|
-
dataRef.current.inputValue = val;
|
|
105
|
+
}, value: placeholderValue, max: max, min: min, step: step, type: "number", placeholder: placeholder, disabled: disabled, onValueChange: (val) => {
|
|
106
|
+
setPlaceholderValue(val);
|
|
101
107
|
if (val.length === 0) {
|
|
102
|
-
|
|
108
|
+
_changeValue(null);
|
|
103
109
|
}
|
|
104
110
|
else {
|
|
105
111
|
const num = Number(val);
|
|
106
112
|
if ((isUndefined(max) || num <= max) && (isUndefined(min) || num >= min) && (!integer || Number.isInteger(num))) {
|
|
107
|
-
|
|
113
|
+
_changeValue(num);
|
|
108
114
|
}
|
|
109
115
|
}
|
|
110
|
-
}, onFocus: (e) => {
|
|
111
|
-
var _a;
|
|
112
|
-
(_a = inputProps === null || inputProps === void 0 ? void 0 : inputProps.onFocus) === null || _a === void 0 ? void 0 : _a.call(inputProps, e);
|
|
113
|
-
dataRef.current.inputFocused = true;
|
|
114
|
-
dataRef.current.inputValue = undefined;
|
|
115
116
|
}, onBlur: (e) => {
|
|
116
117
|
var _a;
|
|
117
118
|
(_a = inputProps === null || inputProps === void 0 ? void 0 : inputProps.onBlur) === null || _a === void 0 ? void 0 : _a.call(inputProps, e);
|
|
118
|
-
|
|
119
|
-
if (
|
|
120
|
-
|
|
119
|
+
let val = value;
|
|
120
|
+
if (placeholderValue.length === 0) {
|
|
121
|
+
val = null;
|
|
121
122
|
}
|
|
122
123
|
else {
|
|
123
|
-
let num = Number(
|
|
124
|
+
let num = Number(placeholderValue);
|
|
124
125
|
if (!isUndefined(max) && num > max) {
|
|
125
126
|
num = max;
|
|
126
127
|
}
|
|
@@ -130,9 +131,12 @@ export function InputNumber(props) {
|
|
|
130
131
|
if (integer && !Number.isInteger(num)) {
|
|
131
132
|
num = Math.round(num);
|
|
132
133
|
}
|
|
133
|
-
|
|
134
|
+
val = num;
|
|
135
|
+
}
|
|
136
|
+
if (val !== value) {
|
|
137
|
+
changeValue(val);
|
|
134
138
|
}
|
|
135
|
-
} })), clearable && !disabled && (_jsx("div", Object.assign({}, mergeCS(styled('input__clear'), { style: { opacity:
|
|
139
|
+
} })), clearable && !disabled && (_jsx("div", Object.assign({}, mergeCS(styled('input__clear'), { style: { opacity: placeholderValue.length > 0 ? 1 : 0 } }), { role: "button", "aria-label": t('Clear'), onClick: () => {
|
|
136
140
|
changeValue(null);
|
|
137
141
|
onClear === null || onClear === void 0 ? void 0 : onClear();
|
|
138
142
|
}, children: _jsx(Icon, { children: _jsx(CancelFilled, {}) }) }))), numberButton && !disabled && (_jsxs("div", Object.assign({}, styled('input__number-container'), { children: [_jsx("div", Object.assign({}, styled('input__number'), { role: "button", "aria-label": t('Input', 'Increase number'), onMouseDown: (e) => {
|
package/menu/Menu.js
CHANGED
|
@@ -73,8 +73,7 @@ export function Menu(props) {
|
|
|
73
73
|
onExpandsChange(ids, items);
|
|
74
74
|
}
|
|
75
75
|
});
|
|
76
|
-
const {
|
|
77
|
-
const popupIds = popupIdsRef.current;
|
|
76
|
+
const { popupIds, setPopupIds, addPopupId, removePopupId } = useNestedPopup();
|
|
78
77
|
const [focusIds, setFocusIds] = useState([]);
|
|
79
78
|
const focusId = (() => {
|
|
80
79
|
var _a;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@laser-ui/components",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "React components.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ui",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"access": "public",
|
|
38
38
|
"directory": "../../dist/libs/components"
|
|
39
39
|
},
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "10832372dcf8eb1ce1a71903333f7abb61325613"
|
|
41
41
|
}
|
package/spinner/Spinner.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useAsync
|
|
3
|
+
import { useAsync } from '@laser-ui/hooks';
|
|
4
4
|
import { checkNodeExist } from '@laser-ui/utils';
|
|
5
5
|
import { isNumber, isUndefined } from 'lodash';
|
|
6
|
-
import { useEffect, useRef } from 'react';
|
|
6
|
+
import { useEffect, useRef, useState } from 'react';
|
|
7
7
|
import { CLASSES } from './vars';
|
|
8
8
|
import { CircularProgress } from '../circular-progress';
|
|
9
9
|
import { useComponentProps, useNamespace, useStyled } from '../hooks';
|
|
@@ -16,24 +16,22 @@ export function Spinner(props) {
|
|
|
16
16
|
const namespace = useNamespace();
|
|
17
17
|
const styled = useStyled(CLASSES, { spinner: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.spinner }, styleOverrides);
|
|
18
18
|
const async = useAsync();
|
|
19
|
-
const forceUpdate = useForceUpdate();
|
|
20
19
|
const spinnerRef = useRef(null);
|
|
21
|
-
const
|
|
22
|
-
if (visibleProp
|
|
23
|
-
|
|
20
|
+
const [delayTimeout, setDelayTimeout] = useState(false);
|
|
21
|
+
if (!visibleProp && delayTimeout) {
|
|
22
|
+
setDelayTimeout(false);
|
|
24
23
|
}
|
|
25
|
-
const visible = isUndefined(delay) ? visibleProp :
|
|
24
|
+
const visible = isUndefined(delay) ? visibleProp : delayTimeout;
|
|
26
25
|
useEffect(() => {
|
|
27
26
|
if (isNumber(delay) && visibleProp) {
|
|
28
27
|
const clearTid = async.setTimeout(() => {
|
|
29
|
-
|
|
30
|
-
forceUpdate();
|
|
28
|
+
setDelayTimeout(true);
|
|
31
29
|
}, delay);
|
|
32
30
|
return () => {
|
|
33
31
|
clearTid();
|
|
34
32
|
};
|
|
35
33
|
}
|
|
36
|
-
}, [async, delay,
|
|
34
|
+
}, [async, delay, visibleProp]);
|
|
37
35
|
return (_jsx(Transition, { enter: visible, name: `${namespace}-fade`, duration: TTANSITION_DURING_BASE, onSkipEnter: () => {
|
|
38
36
|
if (spinnerRef.current) {
|
|
39
37
|
spinnerRef.current.style.setProperty('--spinner-container-height', `${spinnerRef.current.offsetHeight}px`);
|