@laser-ui/components 0.0.4 → 0.1.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 +8 -0
- package/affix/Affix.js +35 -25
- package/anchor/Anchor.js +14 -21
- package/cascader/Cascader.js +12 -11
- package/date-picker/DatePicker.js +13 -12
- package/dropdown/Dropdown.js +18 -15
- package/dropdown/internal/DropdownSub.js +16 -15
- package/hooks/index.d.ts +1 -0
- package/hooks/index.js +1 -0
- package/hooks/useJSS.d.ts +1 -0
- package/hooks/useJSS.js +15 -0
- package/menu/internal/MenuSub.js +16 -15
- package/package.json +6 -4
- package/popover/Popover.js +20 -17
- package/select/Select.js +18 -13
- package/textarea/Textarea.js +12 -5
- package/time-picker/TimePicker.js +13 -12
- package/tooltip/Tooltip.js +24 -21
- package/tree-select/TreeSelect.js +12 -11
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
# [0.1.0](https://github.com/laser-ui/laser-ui/compare/v0.0.5...v0.1.0) (2023-09-12)
|
|
6
|
+
|
|
7
|
+
**Note:** Version bump only for package @laser-ui/components
|
|
8
|
+
|
|
9
|
+
## [0.0.5](https://github.com/laser-ui/laser-ui/compare/v0.0.4...v0.0.5) (2023-09-11)
|
|
10
|
+
|
|
11
|
+
**Note:** Version bump only for package @laser-ui/components
|
|
12
|
+
|
|
5
13
|
## [0.0.4](https://github.com/laser-ui/laser-ui/compare/v0.0.3...v0.0.4) (2023-09-11)
|
|
6
14
|
|
|
7
15
|
**Note:** Version bump only for package @laser-ui/components
|
package/affix/Affix.js
CHANGED
|
@@ -1,55 +1,65 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEvent, useEventCallback,
|
|
2
|
+
import { useEvent, useEventCallback, useMount, useRefExtra, useResize } from '@laser-ui/hooks';
|
|
3
3
|
import { getOffsetToRoot, toPx } from '@laser-ui/utils';
|
|
4
4
|
import { isFunction, isString, isUndefined } from 'lodash';
|
|
5
5
|
import { cloneElement, forwardRef, useId, useImperativeHandle, useState } from 'react';
|
|
6
|
-
import { useComponentProps, useLayout, useListenGlobalScrolling, useNamespace } from '../hooks';
|
|
6
|
+
import { useComponentProps, useJSS, useLayout, useListenGlobalScrolling, useNamespace } from '../hooks';
|
|
7
7
|
export const Affix = forwardRef((props, ref) => {
|
|
8
8
|
const { children, top = 0, target, zIndex } = useComponentProps('Affix', props);
|
|
9
9
|
const namespace = useNamespace();
|
|
10
|
+
const sheet = useJSS();
|
|
10
11
|
const { pageScrollRef, contentResizeRef } = useLayout();
|
|
11
12
|
const uniqueId = useId();
|
|
12
13
|
const affixRef = useRefExtra(() => document.querySelector(`[data-l-affix="${uniqueId}"]`));
|
|
13
|
-
const
|
|
14
|
+
const placeholderRef = useRefExtra(() => document.querySelector(`[data-l-affix-placeholder="${uniqueId}"]`));
|
|
14
15
|
const targetRef = useRefExtra(isUndefined(target) ? () => pageScrollRef.current : target);
|
|
15
16
|
const [sticky, setSticky] = useState(false);
|
|
16
|
-
const [positionStyle, setPositionStyle] = useState();
|
|
17
17
|
const updatePosition = useEventCallback(() => {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
if (affixRef.current && placeholderRef.current && targetRef.current) {
|
|
19
|
+
const offsetEl = sticky ? placeholderRef.current : affixRef.current;
|
|
20
20
|
const offsetRect = offsetEl.getBoundingClientRect();
|
|
21
21
|
const targetTop = getOffsetToRoot(targetRef.current);
|
|
22
22
|
const distance = isString(top) ? toPx(top, true) : top;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
const newSticky = Math.ceil(targetRef.current.scrollTop) + distance >= getOffsetToRoot(offsetEl) - targetTop;
|
|
24
|
+
setSticky(newSticky);
|
|
25
|
+
if (sheet.classes.position) {
|
|
26
|
+
affixRef.current.classList.toggle(sheet.classes.position, false);
|
|
27
|
+
}
|
|
28
|
+
if (newSticky) {
|
|
29
|
+
sheet.replaceRule('position', {
|
|
30
|
+
width: offsetRect.width,
|
|
31
|
+
height: offsetRect.height,
|
|
32
|
+
position: 'fixed',
|
|
33
|
+
top: (isUndefined(target) ? targetTop : targetRef.current.getBoundingClientRect().top) + distance,
|
|
34
|
+
left: offsetRect.left,
|
|
35
|
+
zIndex: zIndex !== null && zIndex !== void 0 ? zIndex : `var(--${namespace}-zindex-sticky)`,
|
|
36
|
+
});
|
|
37
|
+
affixRef.current.classList.toggle(sheet.classes.position, true);
|
|
38
|
+
placeholderRef.current.style.display = '';
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
sheet.deleteRule('position');
|
|
42
|
+
placeholderRef.current.style.display = 'none';
|
|
43
|
+
}
|
|
30
44
|
}
|
|
31
45
|
});
|
|
32
|
-
|
|
46
|
+
useMount(() => {
|
|
33
47
|
updatePosition();
|
|
34
|
-
|
|
35
|
-
}, []);
|
|
48
|
+
});
|
|
36
49
|
const listenGlobalScrolling = useListenGlobalScrolling(updatePosition);
|
|
37
50
|
useEvent(pageScrollRef, 'scroll', updatePosition, { passive: true }, listenGlobalScrolling);
|
|
38
51
|
useEvent(targetRef, 'scroll', updatePosition, { passive: true }, listenGlobalScrolling || isUndefined(target));
|
|
39
|
-
useResize(sticky ?
|
|
52
|
+
useResize(sticky ? placeholderRef : affixRef, updatePosition);
|
|
40
53
|
useResize(contentResizeRef, updatePosition);
|
|
41
54
|
useImperativeHandle(ref, () => ({
|
|
42
55
|
sticky,
|
|
43
56
|
updatePosition,
|
|
44
57
|
}), [sticky, updatePosition]);
|
|
45
|
-
const render = (el) => (_jsxs(_Fragment, { children: [
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}), cloneElement(el, {
|
|
51
|
-
style: sticky
|
|
52
|
-
? Object.assign(Object.assign(Object.assign({}, el.props.style), positionStyle), { position: 'fixed', zIndex: zIndex !== null && zIndex !== void 0 ? zIndex : `var(--${namespace}-zindex-sticky)` }) : el.props.style,
|
|
58
|
+
const render = (el) => (_jsxs(_Fragment, { children: [cloneElement(el, {
|
|
59
|
+
style: Object.assign(Object.assign({}, el.props.style), { visibility: 'hidden' }),
|
|
60
|
+
'aria-hidden': true,
|
|
61
|
+
'data-l-affix-placeholder': uniqueId,
|
|
62
|
+
}), cloneElement(el, {
|
|
53
63
|
'data-l-affix': uniqueId,
|
|
54
64
|
})] }));
|
|
55
65
|
return isFunction(children) ? children(render) : render(children);
|
package/anchor/Anchor.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 { useEvent, useEventCallback,
|
|
3
|
+
import { useEvent, useEventCallback, useMount, useRefExtra, useResize } from '@laser-ui/hooks';
|
|
4
4
|
import { getOffsetToRoot, scrollTo, toPx } from '@laser-ui/utils';
|
|
5
5
|
import { isArray, isString, isUndefined } from 'lodash';
|
|
6
|
-
import { Fragment, forwardRef,
|
|
6
|
+
import { Fragment, forwardRef, useImperativeHandle, useRef, useState } from 'react';
|
|
7
7
|
import { CLASSES, DOT_INDICATOR, LINE_INDICATOR } from './vars';
|
|
8
8
|
import { useComponentProps, useLayout, useListenGlobalScrolling, useStyled } from '../hooks';
|
|
9
9
|
import { mergeCS } from '../utils';
|
|
@@ -11,14 +11,13 @@ function AnchorFC(props, ref) {
|
|
|
11
11
|
const _a = useComponentProps('Anchor', props), { styleOverrides, styleProvider, list, page, distance: distanceProp = 0, scrollBehavior = 'instant', indicator = DOT_INDICATOR, onClick } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "list", "page", "distance", "scrollBehavior", "indicator", "onClick"]);
|
|
12
12
|
const styled = useStyled(CLASSES, { anchor: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.anchor }, styleOverrides);
|
|
13
13
|
const { pageScrollRef, contentResizeRef } = useLayout();
|
|
14
|
+
const pageRef = useRefExtra(page !== null && page !== void 0 ? page : (() => pageScrollRef.current));
|
|
14
15
|
const anchorRef = useRef(null);
|
|
15
16
|
const indicatorRef = useRef(null);
|
|
16
|
-
const activeLinkRef = useRef(null);
|
|
17
|
-
const pageRef = useRefExtra(page !== null && page !== void 0 ? page : (() => pageScrollRef.current));
|
|
18
17
|
const dataRef = useRef({});
|
|
19
18
|
const [active, setActive] = useState(null);
|
|
20
19
|
const updateAnchor = useEventCallback(() => {
|
|
21
|
-
if (pageRef.current) {
|
|
20
|
+
if (pageRef.current && anchorRef.current && indicatorRef.current) {
|
|
22
21
|
const pageTop = getOffsetToRoot(pageRef.current);
|
|
23
22
|
let nearestEl;
|
|
24
23
|
const reduceLinks = (arr) => {
|
|
@@ -44,19 +43,8 @@ function AnchorFC(props, ref) {
|
|
|
44
43
|
reduceLinks(list);
|
|
45
44
|
const href = nearestEl ? nearestEl[0] : null;
|
|
46
45
|
setActive(href);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
useIsomorphicLayoutEffect(() => {
|
|
50
|
-
updateAnchor();
|
|
51
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
|
-
}, []);
|
|
53
|
-
const listenGlobalScrolling = useListenGlobalScrolling(updateAnchor);
|
|
54
|
-
useEvent(pageRef, 'scroll', updateAnchor, { passive: true }, listenGlobalScrolling);
|
|
55
|
-
useResize(contentResizeRef, updateAnchor);
|
|
56
|
-
useEffect(() => {
|
|
57
|
-
if (anchorRef.current && indicatorRef.current) {
|
|
58
|
-
if (activeLinkRef.current) {
|
|
59
|
-
const rect = activeLinkRef.current.getBoundingClientRect();
|
|
46
|
+
if (href) {
|
|
47
|
+
const rect = anchorRef.current.querySelector(`[data-l-href="${href}"]`).getBoundingClientRect();
|
|
60
48
|
const top = rect.top - anchorRef.current.getBoundingClientRect().top + rect.height / 2;
|
|
61
49
|
indicatorRef.current.style.cssText = `opacity:1;top:${top}px;`;
|
|
62
50
|
}
|
|
@@ -65,6 +53,12 @@ function AnchorFC(props, ref) {
|
|
|
65
53
|
}
|
|
66
54
|
}
|
|
67
55
|
});
|
|
56
|
+
useMount(() => {
|
|
57
|
+
updateAnchor();
|
|
58
|
+
});
|
|
59
|
+
const listenGlobalScrolling = useListenGlobalScrolling(updateAnchor);
|
|
60
|
+
useEvent(pageRef, 'scroll', updateAnchor, { passive: true }, listenGlobalScrolling);
|
|
61
|
+
useResize(contentResizeRef, updateAnchor);
|
|
68
62
|
useImperativeHandle(ref, () => ({
|
|
69
63
|
active,
|
|
70
64
|
updateAnchor,
|
|
@@ -91,10 +85,9 @@ function AnchorFC(props, ref) {
|
|
|
91
85
|
const linkNodes = (() => {
|
|
92
86
|
const getNodes = (arr, level = 0) => arr.map((link) => {
|
|
93
87
|
const { title: linkTitle, href: linkHref, target: linkTarget, children } = link;
|
|
94
|
-
const isActive = linkHref === active;
|
|
95
88
|
return (_jsxs(Fragment, { children: [_jsx("li", Object.assign({}, styled('anchor__link', {
|
|
96
|
-
'anchor__link.is-active':
|
|
97
|
-
}), {
|
|
89
|
+
'anchor__link.is-active': linkHref === active,
|
|
90
|
+
}), { "data-l-href": linkHref, children: _jsx("a", { style: { paddingLeft: 16 + level * 16 }, href: `#${linkHref}`, target: linkTarget, onClick: (e) => {
|
|
98
91
|
e.preventDefault();
|
|
99
92
|
handleLinkClick(linkHref);
|
|
100
93
|
onClick === null || onClick === void 0 ? void 0 : onClick(linkHref, link);
|
package/cascader/Cascader.js
CHANGED
|
@@ -12,7 +12,7 @@ import { CascaderPanel } from './internal/CascaderPanel';
|
|
|
12
12
|
import { CascaderSearchPanel } from './internal/CascaderSearchPanel';
|
|
13
13
|
import { CLASSES } from './vars';
|
|
14
14
|
import { Dropdown } from '../dropdown';
|
|
15
|
-
import { useComponentProps, useControlled, useDesign, useFocusVisible, useLayout, useListenGlobalScrolling, useMaxIndex, useNamespace, useScopedProps, useStyled, useTranslation, } from '../hooks';
|
|
15
|
+
import { useComponentProps, useControlled, useDesign, useFocusVisible, useJSS, useLayout, useListenGlobalScrolling, useMaxIndex, useNamespace, useScopedProps, useStyled, useTranslation, } from '../hooks';
|
|
16
16
|
import { Icon } from '../icon';
|
|
17
17
|
import { CircularProgress } from '../internal/circular-progress';
|
|
18
18
|
import { Portal } from '../internal/portal';
|
|
@@ -29,6 +29,7 @@ function CascaderFC(props, ref) {
|
|
|
29
29
|
const _a = useComponentProps('Cascader', props), { styleOverrides, styleProvider, formControl, list, model, defaultModel, visible: visibleProp, defaultVisible, placeholder, multiple = false, searchable = false, searchValue: searchValueProp, defaultSearchValue, onlyLeafSelectable = true, clearable: clearableProp = false, loading = false, size: sizeProp, disabled: disabledProp = false, virtual = false, escClosable = true, customItem, customSelected, customSearch, inputRef: inputRefProp, inputRender, onModelChange, onVisibleChange, onSearch, onClear, onFirstFocus, afterVisibleChange } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "formControl", "list", "model", "defaultModel", "visible", "defaultVisible", "placeholder", "multiple", "searchable", "searchValue", "defaultSearchValue", "onlyLeafSelectable", "clearable", "loading", "size", "disabled", "virtual", "escClosable", "customItem", "customSelected", "customSearch", "inputRef", "inputRender", "onModelChange", "onVisibleChange", "onSearch", "onClear", "onFirstFocus", "afterVisibleChange"]);
|
|
30
30
|
const namespace = useNamespace();
|
|
31
31
|
const styled = useStyled(CLASSES, { cascader: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.cascader, 'cascader-popup': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['cascader-popup'] }, styleOverrides);
|
|
32
|
+
const sheet = useJSS();
|
|
32
33
|
const { t } = useTranslation();
|
|
33
34
|
const uniqueId = useId();
|
|
34
35
|
const listId = `${namespace}-cascader-list-${uniqueId}`;
|
|
@@ -178,11 +179,7 @@ function CascaderFC(props, ref) {
|
|
|
178
179
|
})();
|
|
179
180
|
const maxZIndex = useMaxIndex(visible);
|
|
180
181
|
const zIndex = `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})`;
|
|
181
|
-
const
|
|
182
|
-
const [popupPositionStyle, setPopupPositionStyle] = useState({
|
|
183
|
-
top: '-200vh',
|
|
184
|
-
left: '-200vw',
|
|
185
|
-
});
|
|
182
|
+
const transformOrigin = useRef();
|
|
186
183
|
const updatePosition = useEventCallback(() => {
|
|
187
184
|
if (visible && boxRef.current && popupRef.current) {
|
|
188
185
|
const height = popupRef.current.offsetHeight;
|
|
@@ -192,12 +189,16 @@ function CascaderFC(props, ref) {
|
|
|
192
189
|
placement: 'bottom-left',
|
|
193
190
|
inWindow: WINDOW_SPACE,
|
|
194
191
|
});
|
|
195
|
-
|
|
196
|
-
|
|
192
|
+
transformOrigin.current = position.transformOrigin;
|
|
193
|
+
if (sheet.classes.position) {
|
|
194
|
+
popupRef.current.classList.toggle(sheet.classes.position, false);
|
|
195
|
+
}
|
|
196
|
+
sheet.replaceRule('position', {
|
|
197
197
|
top: position.top,
|
|
198
198
|
left: position.left,
|
|
199
199
|
maxWidth,
|
|
200
200
|
});
|
|
201
|
+
popupRef.current.classList.toggle(sheet.classes.position, true);
|
|
201
202
|
}
|
|
202
203
|
});
|
|
203
204
|
const listenGlobalScrolling = useListenGlobalScrolling(updatePosition, !visible);
|
|
@@ -453,7 +454,7 @@ function CascaderFC(props, ref) {
|
|
|
453
454
|
case 'entering':
|
|
454
455
|
transitionStyle = {
|
|
455
456
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-out`).join(', '),
|
|
456
|
-
transformOrigin,
|
|
457
|
+
transformOrigin: transformOrigin.current,
|
|
457
458
|
};
|
|
458
459
|
break;
|
|
459
460
|
case 'leaving':
|
|
@@ -461,7 +462,7 @@ function CascaderFC(props, ref) {
|
|
|
461
462
|
transform: 'scaleY(0.7)',
|
|
462
463
|
opacity: 0,
|
|
463
464
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-in`).join(', '),
|
|
464
|
-
transformOrigin,
|
|
465
|
+
transformOrigin: transformOrigin.current,
|
|
465
466
|
};
|
|
466
467
|
break;
|
|
467
468
|
case 'leaved':
|
|
@@ -471,7 +472,7 @@ function CascaderFC(props, ref) {
|
|
|
471
472
|
break;
|
|
472
473
|
}
|
|
473
474
|
return (_jsxs("div", Object.assign({}, mergeCS(styled('cascader-popup'), {
|
|
474
|
-
style: Object.assign(
|
|
475
|
+
style: Object.assign({ zIndex }, transitionStyle),
|
|
475
476
|
}), { ref: popupRef, onMouseDown: (e) => {
|
|
476
477
|
preventBlur(e);
|
|
477
478
|
}, onMouseUp: (e) => {
|
|
@@ -6,12 +6,12 @@ import { ReactComponent as CancelFilled } from '@material-design-icons/svg/fille
|
|
|
6
6
|
import { ReactComponent as CalendarTodayOutlined } from '@material-design-icons/svg/outlined/calendar_today.svg';
|
|
7
7
|
import { ReactComponent as SwapHorizOutlined } from '@material-design-icons/svg/outlined/swap_horiz.svg';
|
|
8
8
|
import { isArray, isBoolean, isNull, isUndefined } from 'lodash';
|
|
9
|
-
import { forwardRef, useEffect, useImperativeHandle, useRef
|
|
9
|
+
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
|
|
10
10
|
import { DatePickerPanel } from './internal/DatePickerPanel';
|
|
11
11
|
import { CLASSES } from './vars';
|
|
12
12
|
import { Button } from '../button';
|
|
13
13
|
import dayjs from '../dayjs';
|
|
14
|
-
import { useComponentProps, useControlled, useDesign, useLayout, useListenGlobalScrolling, useMaxIndex, useNamespace, useScopedProps, useStyled, useTranslation, } from '../hooks';
|
|
14
|
+
import { useComponentProps, useControlled, useDesign, useJSS, useLayout, useListenGlobalScrolling, useMaxIndex, useNamespace, useScopedProps, useStyled, useTranslation, } from '../hooks';
|
|
15
15
|
import { Icon } from '../icon';
|
|
16
16
|
import { Portal } from '../internal/portal';
|
|
17
17
|
import { Transition } from '../internal/transition';
|
|
@@ -29,6 +29,7 @@ export const DatePicker = forwardRef((props, ref) => {
|
|
|
29
29
|
'time-picker': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['time-picker'],
|
|
30
30
|
'date-picker-popup': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['date-picker-popup'],
|
|
31
31
|
}, styleOverrides);
|
|
32
|
+
const sheet = useJSS();
|
|
32
33
|
const { t } = useTranslation();
|
|
33
34
|
const forceUpdate = useForceUpdate();
|
|
34
35
|
const async = useAsync();
|
|
@@ -117,11 +118,7 @@ export const DatePicker = forwardRef((props, ref) => {
|
|
|
117
118
|
const { size, disabled } = useScopedProps({ size: sizeProp, disabled: disabledProp || (formControl === null || formControl === void 0 ? void 0 : formControl.control.disabled) });
|
|
118
119
|
const maxZIndex = useMaxIndex(visible);
|
|
119
120
|
const zIndex = `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})`;
|
|
120
|
-
const
|
|
121
|
-
const [popupPositionStyle, setPopupPositionStyle] = useState({
|
|
122
|
-
top: '-200vh',
|
|
123
|
-
left: '-200vw',
|
|
124
|
-
});
|
|
121
|
+
const transformOrigin = useRef();
|
|
125
122
|
const updatePosition = useEventCallback(() => {
|
|
126
123
|
if (visible && boxRef.current && popupRef.current) {
|
|
127
124
|
const height = popupRef.current.offsetHeight;
|
|
@@ -131,12 +128,16 @@ export const DatePicker = forwardRef((props, ref) => {
|
|
|
131
128
|
placement: 'bottom-left',
|
|
132
129
|
inWindow: WINDOW_SPACE,
|
|
133
130
|
});
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
transformOrigin.current = position.transformOrigin;
|
|
132
|
+
if (sheet.classes.position) {
|
|
133
|
+
popupRef.current.classList.toggle(sheet.classes.position, false);
|
|
134
|
+
}
|
|
135
|
+
sheet.replaceRule('position', {
|
|
136
136
|
top: position.top,
|
|
137
137
|
left: position.left,
|
|
138
138
|
maxWidth,
|
|
139
139
|
});
|
|
140
|
+
popupRef.current.classList.toggle(sheet.classes.position, true);
|
|
140
141
|
}
|
|
141
142
|
});
|
|
142
143
|
const listenGlobalScrolling = useListenGlobalScrolling(updatePosition, !visible);
|
|
@@ -314,7 +315,7 @@ export const DatePicker = forwardRef((props, ref) => {
|
|
|
314
315
|
case 'entering':
|
|
315
316
|
transitionStyle = {
|
|
316
317
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-out`).join(', '),
|
|
317
|
-
transformOrigin,
|
|
318
|
+
transformOrigin: transformOrigin.current,
|
|
318
319
|
};
|
|
319
320
|
break;
|
|
320
321
|
case 'leaving':
|
|
@@ -322,7 +323,7 @@ export const DatePicker = forwardRef((props, ref) => {
|
|
|
322
323
|
transform: 'scaleY(0.7)',
|
|
323
324
|
opacity: 0,
|
|
324
325
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-in`).join(', '),
|
|
325
|
-
transformOrigin,
|
|
326
|
+
transformOrigin: transformOrigin.current,
|
|
326
327
|
};
|
|
327
328
|
break;
|
|
328
329
|
case 'leaved':
|
|
@@ -332,7 +333,7 @@ export const DatePicker = forwardRef((props, ref) => {
|
|
|
332
333
|
break;
|
|
333
334
|
}
|
|
334
335
|
return (_jsxs("div", Object.assign({}, mergeCS(styled('date-picker-popup'), {
|
|
335
|
-
style: Object.assign(
|
|
336
|
+
style: Object.assign({ zIndex }, transitionStyle),
|
|
336
337
|
}), { ref: popupRef, onMouseDown: (e) => {
|
|
337
338
|
preventBlur(e);
|
|
338
339
|
}, onMouseUp: (e) => {
|
package/dropdown/Dropdown.js
CHANGED
|
@@ -9,7 +9,7 @@ import { DropdownItem as DropdownItemFC } from './internal/DropdownItem';
|
|
|
9
9
|
import { DropdownSub } from './internal/DropdownSub';
|
|
10
10
|
import { checkEnableItem, getSameLevelEnableItems } from './utils';
|
|
11
11
|
import { CLASSES } from './vars';
|
|
12
|
-
import { useComponentProps, useControlled, useFocusVisible, useMaxIndex, useNamespace, useNestedPopup, useStyled, useTranslation, } from '../hooks';
|
|
12
|
+
import { useComponentProps, useControlled, useFocusVisible, useJSS, useMaxIndex, useNamespace, useNestedPopup, useStyled, useTranslation, } from '../hooks';
|
|
13
13
|
import { Popup } from '../internal/popup';
|
|
14
14
|
import { Portal } from '../internal/portal';
|
|
15
15
|
import { Transition } from '../internal/transition';
|
|
@@ -22,6 +22,7 @@ function DropdownFC(props, ref) {
|
|
|
22
22
|
const namespace = useNamespace();
|
|
23
23
|
const { t } = useTranslation();
|
|
24
24
|
const styled = useStyled(CLASSES, { dropdown: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.dropdown, 'dropdown-popup': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['dropdown-popup'] }, styleOverrides);
|
|
25
|
+
const sheet = useJSS();
|
|
25
26
|
const uniqueId = useId();
|
|
26
27
|
const id = (_a = restProps.id) !== null && _a !== void 0 ? _a : `${namespace}-dropdown-${uniqueId}`;
|
|
27
28
|
let triggerId;
|
|
@@ -91,26 +92,28 @@ function DropdownFC(props, ref) {
|
|
|
91
92
|
};
|
|
92
93
|
const maxZIndex = useMaxIndex(visible);
|
|
93
94
|
const zIndex = !isUndefined(zIndexProp) ? zIndexProp : `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})`;
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
top: '-200vh',
|
|
97
|
-
left: '-200vw',
|
|
98
|
-
});
|
|
99
|
-
const [placement, setPlacement] = useState(placementProp);
|
|
95
|
+
const transformOrigin = useRef();
|
|
96
|
+
const placement = useRef(placementProp);
|
|
100
97
|
const updatePosition = useEventCallback(() => {
|
|
101
|
-
if (visible && triggerRef.current && popupRef.current) {
|
|
98
|
+
if (visible && triggerRef.current && dropdownRef.current && popupRef.current) {
|
|
102
99
|
const [width, height] = [popupRef.current.offsetWidth, popupRef.current.offsetHeight];
|
|
103
100
|
const position = getVerticalSidePosition(triggerRef.current, { width, height }, {
|
|
104
101
|
placement: placementProp,
|
|
105
102
|
placementFixed,
|
|
106
103
|
inWindow: WINDOW_SPACE,
|
|
107
104
|
});
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
transformOrigin.current = position.transformOrigin;
|
|
106
|
+
dropdownRef.current.classList.toggle(`${namespace}-dropdown--${placement.current}`, false);
|
|
107
|
+
placement.current = position.placement;
|
|
108
|
+
dropdownRef.current.classList.toggle(`${namespace}-dropdown--${placement.current}`, true);
|
|
109
|
+
if (sheet.classes.position) {
|
|
110
|
+
popupRef.current.classList.toggle(sheet.classes.position, false);
|
|
111
|
+
}
|
|
112
|
+
sheet.replaceRule('position', {
|
|
110
113
|
top: position.top,
|
|
111
114
|
left: position.left,
|
|
112
115
|
});
|
|
113
|
-
|
|
116
|
+
popupRef.current.classList.toggle(sheet.classes.position, true);
|
|
114
117
|
}
|
|
115
118
|
});
|
|
116
119
|
const preventBlur = (e) => {
|
|
@@ -339,7 +342,7 @@ function DropdownFC(props, ref) {
|
|
|
339
342
|
case 'entering':
|
|
340
343
|
transitionStyle = {
|
|
341
344
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-out`).join(', '),
|
|
342
|
-
transformOrigin,
|
|
345
|
+
transformOrigin: transformOrigin.current,
|
|
343
346
|
};
|
|
344
347
|
break;
|
|
345
348
|
case 'leaving':
|
|
@@ -347,7 +350,7 @@ function DropdownFC(props, ref) {
|
|
|
347
350
|
transform: 'scaleY(0.7)',
|
|
348
351
|
opacity: 0,
|
|
349
352
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-in`).join(', '),
|
|
350
|
-
transformOrigin,
|
|
353
|
+
transformOrigin: transformOrigin.current,
|
|
351
354
|
};
|
|
352
355
|
break;
|
|
353
356
|
case 'leaved':
|
|
@@ -356,7 +359,7 @@ function DropdownFC(props, ref) {
|
|
|
356
359
|
default:
|
|
357
360
|
break;
|
|
358
361
|
}
|
|
359
|
-
return (_jsx("div", Object.assign({}, restProps, mergeCS(styled('dropdown'
|
|
362
|
+
return (_jsx("div", Object.assign({}, restProps, mergeCS(styled('dropdown'), {
|
|
360
363
|
className: restProps.className,
|
|
361
364
|
style: restProps.style,
|
|
362
365
|
}), { ref: dropdownRef, onMouseDown: (e) => {
|
|
@@ -368,7 +371,7 @@ function DropdownFC(props, ref) {
|
|
|
368
371
|
(_a = restProps.onMouseUp) === null || _a === void 0 ? void 0 : _a.call(restProps, e);
|
|
369
372
|
preventBlur(e);
|
|
370
373
|
}, children: renderPopup(_jsxs("div", Object.assign({}, mergeCS(styled('dropdown-popup'), {
|
|
371
|
-
style: Object.assign(
|
|
374
|
+
style: Object.assign({ zIndex }, transitionStyle),
|
|
372
375
|
}), { ref: popupRef, children: [_jsx("ul", Object.assign({}, styled('dropdown__list'), { ref: ulRef, id: id, tabIndex: -1, role: "menu", "aria-labelledby": triggerId, "aria-activedescendant": isUndefined(focusId) ? undefined : getItemId(focusId), children: list.length === 0 ? _jsx("div", Object.assign({}, styled('dropdown__empty'), { children: t('No Data') })) : nodes })), arrow && _jsx("div", Object.assign({}, styled('dropdown__arrow')))] }))) })));
|
|
373
376
|
} }) })] }));
|
|
374
377
|
} }));
|
|
@@ -3,8 +3,8 @@ import { useEventCallback } from '@laser-ui/hooks';
|
|
|
3
3
|
import { checkNodeExist } from '@laser-ui/utils';
|
|
4
4
|
import { ReactComponent as KeyboardArrowRightOutlined } from '@material-design-icons/svg/outlined/keyboard_arrow_right.svg';
|
|
5
5
|
import { isUndefined } from 'lodash';
|
|
6
|
-
import { forwardRef, useImperativeHandle, useRef
|
|
7
|
-
import { useTranslation } from '../../hooks';
|
|
6
|
+
import { forwardRef, useImperativeHandle, useRef } from 'react';
|
|
7
|
+
import { useJSS, useTranslation } from '../../hooks';
|
|
8
8
|
import { Icon } from '../../icon';
|
|
9
9
|
import { Popup } from '../../internal/popup';
|
|
10
10
|
import { Portal } from '../../internal/portal';
|
|
@@ -13,27 +13,28 @@ import { getHorizontalSidePosition, mergeCS } from '../../utils';
|
|
|
13
13
|
import { TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../../vars';
|
|
14
14
|
export const DropdownSub = forwardRef((props, ref) => {
|
|
15
15
|
const { children, namespace, styled, dropdownRef, id, level, icon, list, popupState, trigger, empty, focus, disabled, zIndex, onVisibleChange, } = props;
|
|
16
|
+
const sheet = useJSS();
|
|
16
17
|
const triggerRef = useRef(null);
|
|
17
18
|
const popupRef = useRef(null);
|
|
18
19
|
const { t } = useTranslation();
|
|
19
20
|
const visible = !isUndefined(popupState);
|
|
20
|
-
const
|
|
21
|
-
const [popupPositionStyle, setPopupPositionStyle] = useState({
|
|
22
|
-
top: '-200vh',
|
|
23
|
-
left: '-200vw',
|
|
24
|
-
});
|
|
21
|
+
const transformOrigin = useRef();
|
|
25
22
|
const updatePosition = useEventCallback(() => {
|
|
26
23
|
if (visible && popupRef.current && triggerRef.current) {
|
|
27
24
|
const [width, height] = [popupRef.current.offsetWidth, popupRef.current.offsetHeight];
|
|
28
|
-
const
|
|
25
|
+
const position = getHorizontalSidePosition(triggerRef.current, { width, height }, {
|
|
29
26
|
placement: 'right',
|
|
30
27
|
inWindow: WINDOW_SPACE,
|
|
31
28
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
transformOrigin.current = position.transformOrigin;
|
|
30
|
+
if (sheet.classes.position) {
|
|
31
|
+
popupRef.current.classList.toggle(sheet.classes.position, false);
|
|
32
|
+
}
|
|
33
|
+
sheet.replaceRule('position', {
|
|
34
|
+
top: position.top,
|
|
35
|
+
left: position.left,
|
|
35
36
|
});
|
|
36
|
-
|
|
37
|
+
popupRef.current.classList.toggle(sheet.classes.position, true);
|
|
37
38
|
}
|
|
38
39
|
});
|
|
39
40
|
useImperativeHandle(ref, () => updatePosition, [updatePosition]);
|
|
@@ -54,7 +55,7 @@ export const DropdownSub = forwardRef((props, ref) => {
|
|
|
54
55
|
case 'entering':
|
|
55
56
|
transitionStyle = {
|
|
56
57
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-out`).join(', '),
|
|
57
|
-
transformOrigin,
|
|
58
|
+
transformOrigin: transformOrigin.current,
|
|
58
59
|
};
|
|
59
60
|
break;
|
|
60
61
|
case 'leaving':
|
|
@@ -62,7 +63,7 @@ export const DropdownSub = forwardRef((props, ref) => {
|
|
|
62
63
|
transform: 'scale(0)',
|
|
63
64
|
opacity: 0,
|
|
64
65
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-in`).join(', '),
|
|
65
|
-
transformOrigin,
|
|
66
|
+
transformOrigin: transformOrigin.current,
|
|
66
67
|
};
|
|
67
68
|
break;
|
|
68
69
|
case 'leaved':
|
|
@@ -72,7 +73,7 @@ export const DropdownSub = forwardRef((props, ref) => {
|
|
|
72
73
|
break;
|
|
73
74
|
}
|
|
74
75
|
return renderPopup(_jsx("div", Object.assign({}, mergeCS(styled('dropdown-popup'), {
|
|
75
|
-
style: Object.assign(
|
|
76
|
+
style: Object.assign({ zIndex }, transitionStyle),
|
|
76
77
|
}), { ref: popupRef, children: _jsx("ul", Object.assign({}, styled('dropdown__list'), { role: "menu", "aria-labelledby": id, children: empty ? (_jsx("div", Object.assign({}, mergeCS(styled('dropdown__empty'), { style: { paddingLeft: 12 + level * 16 } }), { children: t('No Data') }))) : (list) })) })));
|
|
77
78
|
} }) })] })) }));
|
|
78
79
|
});
|
package/hooks/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { useComponentProps } from './useComponentProps';
|
|
|
2
2
|
export { useControlled } from './useControlled';
|
|
3
3
|
export { useDesign } from './useDesign';
|
|
4
4
|
export { useFocusVisible } from './useFocusVisible';
|
|
5
|
+
export { useJSS } from './useJSS';
|
|
5
6
|
export { useLayout } from './useLayout';
|
|
6
7
|
export { useListenGlobalScrolling } from './useListenGlobalScrolling';
|
|
7
8
|
export { useLockScroll } from './useLockScroll';
|
package/hooks/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export { useComponentProps } from './useComponentProps';
|
|
|
2
2
|
export { useControlled } from './useControlled';
|
|
3
3
|
export { useDesign } from './useDesign';
|
|
4
4
|
export { useFocusVisible } from './useFocusVisible';
|
|
5
|
+
export { useJSS } from './useJSS';
|
|
5
6
|
export { useLayout } from './useLayout';
|
|
6
7
|
export { useListenGlobalScrolling } from './useListenGlobalScrolling';
|
|
7
8
|
export { useLockScroll } from './useLockScroll';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useJSS<T extends string | number | symbol>(): import("jss").StyleSheet<T>;
|
package/hooks/useJSS.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { create } from 'jss';
|
|
2
|
+
import preset from 'jss-preset-default';
|
|
3
|
+
import { useEffect, useMemo } from 'react';
|
|
4
|
+
const jss = create();
|
|
5
|
+
jss.setup(preset());
|
|
6
|
+
export function useJSS() {
|
|
7
|
+
const sheet = useMemo(() => jss.createStyleSheet({}), []);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
sheet.attach();
|
|
10
|
+
return () => {
|
|
11
|
+
sheet.detach();
|
|
12
|
+
};
|
|
13
|
+
}, [sheet]);
|
|
14
|
+
return sheet;
|
|
15
|
+
}
|
package/menu/internal/MenuSub.js
CHANGED
|
@@ -2,8 +2,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { useEventCallback } from '@laser-ui/hooks';
|
|
3
3
|
import { checkNodeExist } from '@laser-ui/utils';
|
|
4
4
|
import { isUndefined } from 'lodash';
|
|
5
|
-
import { cloneElement, forwardRef, useImperativeHandle, useRef
|
|
6
|
-
import { useMaxIndex, useTranslation } from '../../hooks';
|
|
5
|
+
import { cloneElement, forwardRef, useImperativeHandle, useRef } from 'react';
|
|
6
|
+
import { useJSS, useMaxIndex, useTranslation } from '../../hooks';
|
|
7
7
|
import { Popup } from '../../internal/popup';
|
|
8
8
|
import { Portal } from '../../internal/portal';
|
|
9
9
|
import { CollapseTransition, Transition } from '../../internal/transition';
|
|
@@ -11,6 +11,7 @@ import { getHorizontalSidePosition, getVerticalSidePosition, mergeCS } from '../
|
|
|
11
11
|
import { TTANSITION_DURING_BASE, TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../../vars';
|
|
12
12
|
export const MenuSub = forwardRef((props, ref) => {
|
|
13
13
|
const { children, namespace, styled, menuRef, id, level, space, step, icon, list, popupState, trigger, posinset, mode, inNav, active, includeActive, expand, empty, focus, disabled, onVisibleChange, onClick, } = props;
|
|
14
|
+
const sheet = useJSS();
|
|
14
15
|
const triggerRef = useRef(null);
|
|
15
16
|
const popupRef = useRef(null);
|
|
16
17
|
const dataRef = useRef({});
|
|
@@ -18,11 +19,7 @@ export const MenuSub = forwardRef((props, ref) => {
|
|
|
18
19
|
const visible = !isUndefined(popupState);
|
|
19
20
|
const inHorizontalNav = mode === 'horizontal' && inNav;
|
|
20
21
|
const iconMode = mode === 'icon' && inNav;
|
|
21
|
-
const
|
|
22
|
-
top: '-200vh',
|
|
23
|
-
left: '-200vw',
|
|
24
|
-
});
|
|
25
|
-
const [transformOrigin, setTransformOrigin] = useState();
|
|
22
|
+
const transformOrigin = useRef();
|
|
26
23
|
const updatePosition = useEventCallback(() => {
|
|
27
24
|
if (visible && popupRef.current && triggerRef.current) {
|
|
28
25
|
const height = popupRef.current.offsetHeight;
|
|
@@ -30,7 +27,7 @@ export const MenuSub = forwardRef((props, ref) => {
|
|
|
30
27
|
if (inHorizontalNav) {
|
|
31
28
|
width = triggerRef.current.offsetWidth - 32;
|
|
32
29
|
}
|
|
33
|
-
const
|
|
30
|
+
const position = inHorizontalNav
|
|
34
31
|
? getVerticalSidePosition(triggerRef.current, { width, height }, {
|
|
35
32
|
placement: 'bottom',
|
|
36
33
|
gap: 12,
|
|
@@ -41,12 +38,16 @@ export const MenuSub = forwardRef((props, ref) => {
|
|
|
41
38
|
gap: inNav ? 10 : 14,
|
|
42
39
|
inWindow: WINDOW_SPACE,
|
|
43
40
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
transformOrigin.current = position.transformOrigin;
|
|
42
|
+
if (sheet.classes.position) {
|
|
43
|
+
popupRef.current.classList.toggle(sheet.classes.position, false);
|
|
44
|
+
}
|
|
45
|
+
sheet.replaceRule('position', {
|
|
46
|
+
top: position.top,
|
|
47
|
+
left: position.left,
|
|
47
48
|
width: inHorizontalNav ? width : undefined,
|
|
48
49
|
});
|
|
49
|
-
|
|
50
|
+
popupRef.current.classList.toggle(sheet.classes.position, true);
|
|
50
51
|
}
|
|
51
52
|
});
|
|
52
53
|
const maxZIndex = useMaxIndex(visible);
|
|
@@ -79,7 +80,7 @@ export const MenuSub = forwardRef((props, ref) => {
|
|
|
79
80
|
case 'entering':
|
|
80
81
|
transitionStyle = {
|
|
81
82
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-out`).join(', '),
|
|
82
|
-
transformOrigin,
|
|
83
|
+
transformOrigin: transformOrigin.current,
|
|
83
84
|
};
|
|
84
85
|
break;
|
|
85
86
|
case 'leaving':
|
|
@@ -87,7 +88,7 @@ export const MenuSub = forwardRef((props, ref) => {
|
|
|
87
88
|
transform: inHorizontalNav ? 'scaleY(0.7)' : 'scale(0)',
|
|
88
89
|
opacity: 0,
|
|
89
90
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-in`).join(', '),
|
|
90
|
-
transformOrigin,
|
|
91
|
+
transformOrigin: transformOrigin.current,
|
|
91
92
|
};
|
|
92
93
|
break;
|
|
93
94
|
case 'leaved':
|
|
@@ -97,7 +98,7 @@ export const MenuSub = forwardRef((props, ref) => {
|
|
|
97
98
|
break;
|
|
98
99
|
}
|
|
99
100
|
return renderPopup(_jsx("div", Object.assign({}, mergeCS(styled('menu-popup'), {
|
|
100
|
-
style: Object.assign(
|
|
101
|
+
style: Object.assign({ minWidth: inHorizontalNav ? undefined : 160, zIndex: `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})` }, transitionStyle),
|
|
101
102
|
}), { ref: popupRef, children: _jsx("ul", Object.assign({}, styled('menu__sub-list'), { role: "menu", "aria-labelledby": id, children: empty ? (_jsx("div", Object.assign({}, mergeCS(styled('menu__empty'), { style: { paddingLeft: space + level * step } }), { children: t('No Data') }))) : (list) })) })));
|
|
102
103
|
} }) }))] })) }), _jsx(CollapseTransition, { originalSize: {
|
|
103
104
|
height: 'auto',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@laser-ui/components",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "React components.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ui",
|
|
@@ -26,9 +26,11 @@
|
|
|
26
26
|
"module": "./index.js",
|
|
27
27
|
"types": "./index.d.ts",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@laser-ui/hooks": "0.0
|
|
30
|
-
"@laser-ui/utils": "0.0
|
|
29
|
+
"@laser-ui/hooks": "0.1.0",
|
|
30
|
+
"@laser-ui/utils": "0.1.0",
|
|
31
31
|
"@material-design-icons/svg": "^0.14.9",
|
|
32
|
+
"jss": "^10.10.0",
|
|
33
|
+
"jss-preset-default": "^10.10.0",
|
|
32
34
|
"lodash": "^4.17.21",
|
|
33
35
|
"rcl-store": "^2.1.0",
|
|
34
36
|
"rxjs": "^7.8.1"
|
|
@@ -43,5 +45,5 @@
|
|
|
43
45
|
"access": "public",
|
|
44
46
|
"directory": "../../dist/libs/components"
|
|
45
47
|
},
|
|
46
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "2bb2f60dbb5d6b4f853132fe488d22c2843b6a17"
|
|
47
49
|
}
|
package/popover/Popover.js
CHANGED
|
@@ -2,11 +2,11 @@ import { __rest } from "tslib";
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useEventCallback, useRefExtra } from '@laser-ui/hooks';
|
|
4
4
|
import { isFunction, isString, isUndefined } from 'lodash';
|
|
5
|
-
import { cloneElement, forwardRef, useId, useImperativeHandle, useRef
|
|
5
|
+
import { cloneElement, forwardRef, useId, useImperativeHandle, useRef } from 'react';
|
|
6
6
|
import { PopoverFooter } from './PopoverFooter';
|
|
7
7
|
import { PopoverHeader } from './PopoverHeader';
|
|
8
8
|
import { CLASSES, TTANSITION_DURING } from './vars';
|
|
9
|
-
import { useComponentProps, useControlled, useLockScroll, useMaxIndex, useNamespace, useStyled } from '../hooks';
|
|
9
|
+
import { useComponentProps, useControlled, useJSS, useLockScroll, useMaxIndex, useNamespace, useStyled } from '../hooks';
|
|
10
10
|
import { Popup } from '../internal/popup';
|
|
11
11
|
import { Portal } from '../internal/portal';
|
|
12
12
|
import { Transition } from '../internal/transition';
|
|
@@ -16,6 +16,7 @@ function PopoverFC(props, ref) {
|
|
|
16
16
|
const trigger = modal ? 'click' : triggerProp;
|
|
17
17
|
const namespace = useNamespace();
|
|
18
18
|
const styled = useStyled(CLASSES, { popover: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.popover }, styleOverrides);
|
|
19
|
+
const sheet = useJSS();
|
|
19
20
|
const uniqueId = useId();
|
|
20
21
|
let triggerId;
|
|
21
22
|
const titleId = `${namespace}-popover-title-${uniqueId}`;
|
|
@@ -30,27 +31,29 @@ function PopoverFC(props, ref) {
|
|
|
30
31
|
const [visible, changeVisible] = useControlled(defaultVisible !== null && defaultVisible !== void 0 ? defaultVisible : false, visibleProp, onVisibleChange);
|
|
31
32
|
const maxZIndex = useMaxIndex(visible);
|
|
32
33
|
const zIndex = !isUndefined(zIndexProp) ? zIndexProp : `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})`;
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
left: '-200vw',
|
|
36
|
-
});
|
|
37
|
-
const [transformOrigin, setTransformOrigin] = useState();
|
|
38
|
-
const [placement, setPlacement] = useState(placementProp);
|
|
34
|
+
const transformOrigin = useRef();
|
|
35
|
+
const placement = useRef(placementProp);
|
|
39
36
|
const updatePosition = useEventCallback(() => {
|
|
40
|
-
if (visible && triggerRef.current && popupRef.current) {
|
|
37
|
+
if (visible && triggerRef.current && popoverRef.current && popupRef.current) {
|
|
41
38
|
const position = getPopupPosition(triggerRef.current, { width: popupRef.current.offsetWidth, height: popupRef.current.offsetHeight }, {
|
|
42
39
|
placement: placementProp,
|
|
43
|
-
placementFallback: placement,
|
|
40
|
+
placementFallback: placement.current,
|
|
44
41
|
placementFixed,
|
|
45
42
|
gap,
|
|
46
43
|
inWindow,
|
|
47
44
|
});
|
|
48
|
-
|
|
45
|
+
transformOrigin.current = position.transformOrigin;
|
|
46
|
+
popoverRef.current.classList.toggle(`${namespace}-popover--${placement.current}`, false);
|
|
47
|
+
placement.current = position.placement;
|
|
48
|
+
popoverRef.current.classList.toggle(`${namespace}-popover--${placement.current}`, true);
|
|
49
|
+
if (sheet.classes.position) {
|
|
50
|
+
popupRef.current.classList.toggle(sheet.classes.position, false);
|
|
51
|
+
}
|
|
52
|
+
sheet.replaceRule('position', {
|
|
49
53
|
top: position.top,
|
|
50
54
|
left: position.left,
|
|
51
55
|
});
|
|
52
|
-
|
|
53
|
-
setPlacement(position.placement);
|
|
56
|
+
popupRef.current.classList.toggle(sheet.classes.position, true);
|
|
54
57
|
}
|
|
55
58
|
});
|
|
56
59
|
useLockScroll(modal && visible);
|
|
@@ -125,7 +128,7 @@ function PopoverFC(props, ref) {
|
|
|
125
128
|
case 'entering':
|
|
126
129
|
transitionStyle = {
|
|
127
130
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING.enter}ms ease-out`).join(', '),
|
|
128
|
-
transformOrigin,
|
|
131
|
+
transformOrigin: transformOrigin.current,
|
|
129
132
|
};
|
|
130
133
|
break;
|
|
131
134
|
case 'leaving':
|
|
@@ -133,13 +136,13 @@ function PopoverFC(props, ref) {
|
|
|
133
136
|
transform: 'scale(0.3)',
|
|
134
137
|
opacity: 0,
|
|
135
138
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING.leave}ms ease-in`).join(', '),
|
|
136
|
-
transformOrigin,
|
|
139
|
+
transformOrigin: transformOrigin.current,
|
|
137
140
|
};
|
|
138
141
|
break;
|
|
139
142
|
default:
|
|
140
143
|
break;
|
|
141
144
|
}
|
|
142
|
-
return (_jsxs("div", Object.assign({}, restProps, mergeCS(styled('popover'
|
|
145
|
+
return (_jsxs("div", Object.assign({}, restProps, mergeCS(styled('popover'), {
|
|
143
146
|
className: restProps.className,
|
|
144
147
|
style: Object.assign(Object.assign({}, restProps.style), { zIndex, display: state === 'leaved' ? 'none' : undefined }),
|
|
145
148
|
}), { ref: popoverRef, tabIndex: -1, role: ((_a = restProps.role) !== null && _a !== void 0 ? _a : modal) ? 'alertdialog' : 'dialog', "aria-modal": modal, "aria-labelledby": headerNode ? titleId : undefined, "aria-describedby": bodyId, onKeyDown: (e) => {
|
|
@@ -158,7 +161,7 @@ function PopoverFC(props, ref) {
|
|
|
158
161
|
}, children: [modal && (_jsx("div", Object.assign({}, styled('popover__mask'), { onClick: () => {
|
|
159
162
|
changeVisible(false);
|
|
160
163
|
} }))), renderPopup(_jsxs("div", Object.assign({ ref: popupRef }, mergeCS(styled('popover__content'), {
|
|
161
|
-
style:
|
|
164
|
+
style: transitionStyle,
|
|
162
165
|
}), { children: [arrow && _jsx("div", Object.assign({}, styled('popover__arrow'))), headerNode, _jsx("div", Object.assign({}, styled('popover__body'), { id: bodyId, children: content })), footer &&
|
|
163
166
|
cloneElement(footer, {
|
|
164
167
|
_onClose: () => {
|
package/select/Select.js
CHANGED
|
@@ -14,7 +14,7 @@ import { CLASSES, IS_CREATED } from './vars';
|
|
|
14
14
|
import { Checkbox } from '../checkbox';
|
|
15
15
|
import { Dropdown } from '../dropdown';
|
|
16
16
|
import { Empty } from '../empty';
|
|
17
|
-
import { useComponentProps, useControlled, useDesign, useFocusVisible, useLayout, useListenGlobalScrolling, useMaxIndex, useNamespace, useScopedProps, useStyled, useTranslation, } from '../hooks';
|
|
17
|
+
import { useComponentProps, useControlled, useDesign, useFocusVisible, useJSS, useLayout, useListenGlobalScrolling, useMaxIndex, useNamespace, useScopedProps, useStyled, useTranslation, } from '../hooks';
|
|
18
18
|
import { Icon } from '../icon';
|
|
19
19
|
import { CircularProgress } from '../internal/circular-progress';
|
|
20
20
|
import { Portal } from '../internal/portal';
|
|
@@ -28,6 +28,7 @@ function SelectFC(props, ref) {
|
|
|
28
28
|
const _a = useComponentProps('Select', props), { styleOverrides, styleProvider, formControl, list: listProp, model, defaultModel, visible: visibleProp, defaultVisible, placeholder, multiple = false, searchable = false, searchValue: searchValueProp, defaultSearchValue, clearable: clearableProp = false, loading = false, size: sizeProp, disabled: disabledProp = false, monospaced = true, virtual = false, escClosable = true, customItem, customSelected, customSearch, createItem, inputRef: inputRefProp, inputRender, onModelChange, onVisibleChange, onSearch, onClear, onCreateItem, onScrollBottom, afterVisibleChange } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "formControl", "list", "model", "defaultModel", "visible", "defaultVisible", "placeholder", "multiple", "searchable", "searchValue", "defaultSearchValue", "clearable", "loading", "size", "disabled", "monospaced", "virtual", "escClosable", "customItem", "customSelected", "customSearch", "createItem", "inputRef", "inputRender", "onModelChange", "onVisibleChange", "onSearch", "onClear", "onCreateItem", "onScrollBottom", "afterVisibleChange"]);
|
|
29
29
|
const namespace = useNamespace();
|
|
30
30
|
const styled = useStyled(CLASSES, { select: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.select, 'select-popup': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['select-popup'] }, styleOverrides);
|
|
31
|
+
const sheet = useJSS();
|
|
31
32
|
const { t } = useTranslation();
|
|
32
33
|
const uniqueId = useId();
|
|
33
34
|
const listId = `${namespace}-select-list-${uniqueId}`;
|
|
@@ -171,11 +172,7 @@ function SelectFC(props, ref) {
|
|
|
171
172
|
};
|
|
172
173
|
const maxZIndex = useMaxIndex(visible);
|
|
173
174
|
const zIndex = `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})`;
|
|
174
|
-
const
|
|
175
|
-
const [popupPositionStyle, setPopupPositionStyle] = useState({
|
|
176
|
-
top: '-200vh',
|
|
177
|
-
left: '-200vw',
|
|
178
|
-
});
|
|
175
|
+
const transformOrigin = useRef();
|
|
179
176
|
const updatePosition = useEventCallback(() => {
|
|
180
177
|
if (visible && boxRef.current && popupRef.current) {
|
|
181
178
|
if (monospaced) {
|
|
@@ -185,12 +182,16 @@ function SelectFC(props, ref) {
|
|
|
185
182
|
placement: 'bottom',
|
|
186
183
|
inWindow: WINDOW_SPACE,
|
|
187
184
|
});
|
|
188
|
-
|
|
189
|
-
|
|
185
|
+
transformOrigin.current = position.transformOrigin;
|
|
186
|
+
if (sheet.classes.position) {
|
|
187
|
+
popupRef.current.classList.toggle(sheet.classes.position, false);
|
|
188
|
+
}
|
|
189
|
+
sheet.replaceRule('position', {
|
|
190
190
|
top: position.top,
|
|
191
191
|
left: position.left,
|
|
192
192
|
width,
|
|
193
193
|
});
|
|
194
|
+
popupRef.current.classList.toggle(sheet.classes.position, true);
|
|
194
195
|
}
|
|
195
196
|
else {
|
|
196
197
|
const boxWidth = boxRef.current.offsetWidth;
|
|
@@ -201,13 +202,17 @@ function SelectFC(props, ref) {
|
|
|
201
202
|
placement: 'bottom-left',
|
|
202
203
|
inWindow: WINDOW_SPACE,
|
|
203
204
|
});
|
|
204
|
-
|
|
205
|
-
|
|
205
|
+
transformOrigin.current = position.transformOrigin;
|
|
206
|
+
if (sheet.classes.position) {
|
|
207
|
+
popupRef.current.classList.toggle(sheet.classes.position, false);
|
|
208
|
+
}
|
|
209
|
+
sheet.replaceRule('position', {
|
|
206
210
|
top: position.top,
|
|
207
211
|
left: position.left,
|
|
208
212
|
minWidth: Math.min(boxWidth, maxWidth),
|
|
209
213
|
maxWidth,
|
|
210
214
|
});
|
|
215
|
+
popupRef.current.classList.toggle(sheet.classes.position, true);
|
|
211
216
|
}
|
|
212
217
|
}
|
|
213
218
|
});
|
|
@@ -468,7 +473,7 @@ function SelectFC(props, ref) {
|
|
|
468
473
|
case 'entering':
|
|
469
474
|
transitionStyle = {
|
|
470
475
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-out`).join(', '),
|
|
471
|
-
transformOrigin,
|
|
476
|
+
transformOrigin: transformOrigin.current,
|
|
472
477
|
};
|
|
473
478
|
break;
|
|
474
479
|
case 'leaving':
|
|
@@ -476,7 +481,7 @@ function SelectFC(props, ref) {
|
|
|
476
481
|
transform: 'scaleY(0.7)',
|
|
477
482
|
opacity: 0,
|
|
478
483
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-in`).join(', '),
|
|
479
|
-
transformOrigin,
|
|
484
|
+
transformOrigin: transformOrigin.current,
|
|
480
485
|
};
|
|
481
486
|
break;
|
|
482
487
|
case 'leaved':
|
|
@@ -486,7 +491,7 @@ function SelectFC(props, ref) {
|
|
|
486
491
|
break;
|
|
487
492
|
}
|
|
488
493
|
return (_jsxs("div", Object.assign({}, mergeCS(styled('select-popup'), {
|
|
489
|
-
style: Object.assign(
|
|
494
|
+
style: Object.assign({ zIndex }, transitionStyle),
|
|
490
495
|
}), { ref: popupRef, onMouseDown: (e) => {
|
|
491
496
|
preventBlur(e);
|
|
492
497
|
}, onMouseUp: (e) => {
|
package/textarea/Textarea.js
CHANGED
|
@@ -4,11 +4,12 @@ import { useForkRef } from '@laser-ui/hooks';
|
|
|
4
4
|
import { isFunction, isNumber, isUndefined } from 'lodash';
|
|
5
5
|
import { forwardRef, useEffect, useRef } from 'react';
|
|
6
6
|
import { CLASSES } from './vars';
|
|
7
|
-
import { useComponentProps, useControlled, useDesign, useScopedProps, useStyled } from '../hooks';
|
|
7
|
+
import { useComponentProps, useControlled, useDesign, useJSS, useScopedProps, useStyled } from '../hooks';
|
|
8
8
|
import { mergeCS } from '../utils';
|
|
9
9
|
export const Textarea = forwardRef((props, ref) => {
|
|
10
10
|
const _a = useComponentProps('Textarea', props), { styleOverrides, styleProvider, formControl, model, defaultModel, autoRows = false, resizable = true, showCount = false, size: sizeProp, onModelChange } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "formControl", "model", "defaultModel", "autoRows", "resizable", "showCount", "size", "onModelChange"]);
|
|
11
11
|
const styled = useStyled(CLASSES, { textarea: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.textarea }, styleOverrides);
|
|
12
|
+
const sheet = useJSS();
|
|
12
13
|
const textareaRef = useRef(null);
|
|
13
14
|
const combineTextareaRef = useForkRef(textareaRef, ref);
|
|
14
15
|
const [value, changeValue] = useControlled(defaultModel !== null && defaultModel !== void 0 ? defaultModel : '', model, onModelChange, undefined, formControl === null || formControl === void 0 ? void 0 : formControl.control);
|
|
@@ -50,10 +51,16 @@ export const Textarea = forwardRef((props, ref) => {
|
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
if (sheet.classes.rows) {
|
|
55
|
+
textareaRef.current.classList.toggle(sheet.classes.rows, false);
|
|
56
|
+
}
|
|
57
|
+
sheet.replaceRule('rows', {
|
|
58
|
+
height: isUndefined(height) ? undefined : height + outerSize,
|
|
59
|
+
overflow: isUndefined(overflow) ? undefined : 'hidden',
|
|
60
|
+
minHeight: isUndefined(minHeight) ? undefined : minHeight + outerSize,
|
|
61
|
+
maxHeight: isUndefined(maxHeight) ? undefined : maxHeight + outerSize,
|
|
62
|
+
});
|
|
63
|
+
textareaRef.current.classList.toggle(sheet.classes.rows, true);
|
|
57
64
|
}
|
|
58
65
|
});
|
|
59
66
|
const designProps = useDesign({ form: formControl });
|
|
@@ -5,13 +5,13 @@ import { ReactComponent as CancelFilled } from '@material-design-icons/svg/fille
|
|
|
5
5
|
import { ReactComponent as AccessTimeOutlined } from '@material-design-icons/svg/outlined/access_time.svg';
|
|
6
6
|
import { ReactComponent as SwapHorizOutlined } from '@material-design-icons/svg/outlined/swap_horiz.svg';
|
|
7
7
|
import { isNull, isUndefined } from 'lodash';
|
|
8
|
-
import { forwardRef, useEffect, useImperativeHandle, useRef
|
|
8
|
+
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
|
|
9
9
|
import { TimePickerPanel } from './internal/TimePickerPanel';
|
|
10
10
|
import { deepCompareDate, orderTime } from './utils';
|
|
11
11
|
import { CLASSES } from './vars';
|
|
12
12
|
import { Button } from '../button';
|
|
13
13
|
import dayjs from '../dayjs';
|
|
14
|
-
import { useComponentProps, useControlled, useDesign, useLayout, useListenGlobalScrolling, useMaxIndex, useNamespace, useScopedProps, useStyled, useTranslation, } from '../hooks';
|
|
14
|
+
import { useComponentProps, useControlled, useDesign, useJSS, useLayout, useListenGlobalScrolling, useMaxIndex, useNamespace, useScopedProps, useStyled, useTranslation, } from '../hooks';
|
|
15
15
|
import { Icon } from '../icon';
|
|
16
16
|
import { Portal } from '../internal/portal';
|
|
17
17
|
import { Transition } from '../internal/transition';
|
|
@@ -23,6 +23,7 @@ export const TimePicker = forwardRef((props, ref) => {
|
|
|
23
23
|
const _c = useComponentProps('TimePicker', props), { styleOverrides, styleProvider, formControl, model, defaultModel, visible: visibleProp, defaultVisible, placeholder, range = false, format = 'HH:mm:ss', order: orderProp = 'ascend', clearable: clearableProp = false, size: sizeProp, disabled: disabledProp = false, config, escClosable = true, inputRef, inputRender, onModelChange, onVisibleChange, onClear, afterVisibleChange } = _c, restProps = __rest(_c, ["styleOverrides", "styleProvider", "formControl", "model", "defaultModel", "visible", "defaultVisible", "placeholder", "range", "format", "order", "clearable", "size", "disabled", "config", "escClosable", "inputRef", "inputRender", "onModelChange", "onVisibleChange", "onClear", "afterVisibleChange"]);
|
|
24
24
|
const namespace = useNamespace();
|
|
25
25
|
const styled = useStyled(CLASSES, { 'time-picker': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['time-picker'], 'time-picker-popup': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['time-picker-popup'] }, styleOverrides);
|
|
26
|
+
const sheet = useJSS();
|
|
26
27
|
const { t } = useTranslation();
|
|
27
28
|
const forceUpdate = useForceUpdate();
|
|
28
29
|
const async = useAsync();
|
|
@@ -104,11 +105,7 @@ export const TimePicker = forwardRef((props, ref) => {
|
|
|
104
105
|
const { size, disabled } = useScopedProps({ size: sizeProp, disabled: disabledProp || (formControl === null || formControl === void 0 ? void 0 : formControl.control.disabled) });
|
|
105
106
|
const maxZIndex = useMaxIndex(visible);
|
|
106
107
|
const zIndex = `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})`;
|
|
107
|
-
const
|
|
108
|
-
const [popupPositionStyle, setPopupPositionStyle] = useState({
|
|
109
|
-
top: '-200vh',
|
|
110
|
-
left: '-200vw',
|
|
111
|
-
});
|
|
108
|
+
const transformOrigin = useRef();
|
|
112
109
|
const updatePosition = useEventCallback(() => {
|
|
113
110
|
if (visible && boxRef.current && popupRef.current) {
|
|
114
111
|
const height = popupRef.current.offsetHeight;
|
|
@@ -118,12 +115,16 @@ export const TimePicker = forwardRef((props, ref) => {
|
|
|
118
115
|
placement: 'bottom-left',
|
|
119
116
|
inWindow: WINDOW_SPACE,
|
|
120
117
|
});
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
transformOrigin.current = position.transformOrigin;
|
|
119
|
+
if (sheet.classes.position) {
|
|
120
|
+
popupRef.current.classList.toggle(sheet.classes.position, false);
|
|
121
|
+
}
|
|
122
|
+
sheet.replaceRule('position', {
|
|
123
123
|
top: position.top,
|
|
124
124
|
left: position.left,
|
|
125
125
|
maxWidth,
|
|
126
126
|
});
|
|
127
|
+
popupRef.current.classList.toggle(sheet.classes.position, true);
|
|
127
128
|
}
|
|
128
129
|
});
|
|
129
130
|
const listenGlobalScrolling = useListenGlobalScrolling(updatePosition, !visible);
|
|
@@ -304,7 +305,7 @@ export const TimePicker = forwardRef((props, ref) => {
|
|
|
304
305
|
case 'entering':
|
|
305
306
|
transitionStyle = {
|
|
306
307
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-out`).join(', '),
|
|
307
|
-
transformOrigin,
|
|
308
|
+
transformOrigin: transformOrigin.current,
|
|
308
309
|
};
|
|
309
310
|
break;
|
|
310
311
|
case 'leaving':
|
|
@@ -312,7 +313,7 @@ export const TimePicker = forwardRef((props, ref) => {
|
|
|
312
313
|
transform: 'scaleY(0.7)',
|
|
313
314
|
opacity: 0,
|
|
314
315
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-in`).join(', '),
|
|
315
|
-
transformOrigin,
|
|
316
|
+
transformOrigin: transformOrigin.current,
|
|
316
317
|
};
|
|
317
318
|
break;
|
|
318
319
|
case 'leaved':
|
|
@@ -322,7 +323,7 @@ export const TimePicker = forwardRef((props, ref) => {
|
|
|
322
323
|
break;
|
|
323
324
|
}
|
|
324
325
|
return (_jsxs("div", Object.assign({}, mergeCS(styled('time-picker-popup'), {
|
|
325
|
-
style: Object.assign(
|
|
326
|
+
style: Object.assign({ zIndex }, transitionStyle),
|
|
326
327
|
}), { ref: popupRef, onMouseDown: (e) => {
|
|
327
328
|
preventBlur(e);
|
|
328
329
|
}, onMouseUp: (e) => {
|
package/tooltip/Tooltip.js
CHANGED
|
@@ -2,9 +2,9 @@ import { __rest } from "tslib";
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useEventCallback, useRefExtra } from '@laser-ui/hooks';
|
|
4
4
|
import { isFunction, isUndefined } from 'lodash';
|
|
5
|
-
import { cloneElement, forwardRef, useId, useImperativeHandle, useRef
|
|
5
|
+
import { cloneElement, forwardRef, useId, useImperativeHandle, useRef } from 'react';
|
|
6
6
|
import { CLASSES, TTANSITION_DURING } from './vars';
|
|
7
|
-
import { useComponentProps, useControlled, useMaxIndex, useNamespace, useStyled } from '../hooks';
|
|
7
|
+
import { useComponentProps, useControlled, useJSS, useMaxIndex, useNamespace, useStyled } from '../hooks';
|
|
8
8
|
import { Popup } from '../internal/popup';
|
|
9
9
|
import { Portal } from '../internal/portal';
|
|
10
10
|
import { Transition } from '../internal/transition';
|
|
@@ -14,35 +14,38 @@ export const Tooltip = forwardRef((props, ref) => {
|
|
|
14
14
|
const _b = useComponentProps('Tooltip', props), { children, styleOverrides, styleProvider, title, visible: visibleProp, defaultVisible, trigger = 'hover', placement: placementProp = 'top', placementFixed = false, arrow = true, escClosable = true, gap = 10, inWindow = false, mouseEnterDelay = 150, mouseLeaveDelay = 200, skipFirstTransition = true, destroyAfterClose = true, zIndex: zIndexProp, scrolling, onVisibleChange, afterVisibleChange } = _b, restProps = __rest(_b, ["children", "styleOverrides", "styleProvider", "title", "visible", "defaultVisible", "trigger", "placement", "placementFixed", "arrow", "escClosable", "gap", "inWindow", "mouseEnterDelay", "mouseLeaveDelay", "skipFirstTransition", "destroyAfterClose", "zIndex", "scrolling", "onVisibleChange", "afterVisibleChange"]);
|
|
15
15
|
const namespace = useNamespace();
|
|
16
16
|
const styled = useStyled(CLASSES, { tooltip: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.tooltip }, styleOverrides);
|
|
17
|
+
const sheet = useJSS();
|
|
17
18
|
const uniqueId = useId();
|
|
18
19
|
const id = (_a = restProps.id) !== null && _a !== void 0 ? _a : `${namespace}-tooltip-${uniqueId}`;
|
|
19
20
|
const triggerRef = useRefExtra(() => document.querySelector(`[aria-describedby="${id}"]`));
|
|
20
|
-
const
|
|
21
|
+
const tooltipRef = useRef(null);
|
|
21
22
|
const scrollingRef = useRefExtra(scrolling);
|
|
22
23
|
const [visible, changeVisible] = useControlled(defaultVisible !== null && defaultVisible !== void 0 ? defaultVisible : false, visibleProp, onVisibleChange);
|
|
23
24
|
const maxZIndex = useMaxIndex(visible);
|
|
24
25
|
const zIndex = !isUndefined(zIndexProp) ? zIndexProp : `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})`;
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
left: '-200vw',
|
|
28
|
-
});
|
|
29
|
-
const [transformOrigin, setTransformOrigin] = useState();
|
|
30
|
-
const [placement, setPlacement] = useState(placementProp);
|
|
26
|
+
const transformOrigin = useRef();
|
|
27
|
+
const placement = useRef(placementProp);
|
|
31
28
|
const updatePosition = useEventCallback(() => {
|
|
32
|
-
if (visible && triggerRef.current &&
|
|
33
|
-
const position = getPopupPosition(triggerRef.current, { width:
|
|
29
|
+
if (visible && triggerRef.current && tooltipRef.current) {
|
|
30
|
+
const position = getPopupPosition(triggerRef.current, { width: tooltipRef.current.offsetWidth, height: tooltipRef.current.offsetHeight }, {
|
|
34
31
|
placement: placementProp,
|
|
35
|
-
placementFallback: placement,
|
|
32
|
+
placementFallback: placement.current,
|
|
36
33
|
placementFixed,
|
|
37
34
|
gap,
|
|
38
35
|
inWindow,
|
|
39
36
|
});
|
|
40
|
-
|
|
37
|
+
transformOrigin.current = position.transformOrigin;
|
|
38
|
+
tooltipRef.current.classList.toggle(`${namespace}-tooltip--${placement.current}`, false);
|
|
39
|
+
placement.current = position.placement;
|
|
40
|
+
tooltipRef.current.classList.toggle(`${namespace}-tooltip--${placement.current}`, true);
|
|
41
|
+
if (sheet.classes.position) {
|
|
42
|
+
tooltipRef.current.classList.toggle(sheet.classes.position, false);
|
|
43
|
+
}
|
|
44
|
+
sheet.replaceRule('position', {
|
|
41
45
|
top: position.top,
|
|
42
46
|
left: position.left,
|
|
43
47
|
});
|
|
44
|
-
|
|
45
|
-
setPlacement(position.placement);
|
|
48
|
+
tooltipRef.current.classList.toggle(sheet.classes.position, true);
|
|
46
49
|
}
|
|
47
50
|
});
|
|
48
51
|
useImperativeHandle(ref, () => ({
|
|
@@ -51,7 +54,7 @@ export const Tooltip = forwardRef((props, ref) => {
|
|
|
51
54
|
return (_jsx(Popup, { visible: visible, trigger: trigger, mouseEnterDelay: mouseEnterDelay, mouseLeaveDelay: mouseLeaveDelay, updatePosition: {
|
|
52
55
|
fn: updatePosition,
|
|
53
56
|
triggerRef,
|
|
54
|
-
popupRef,
|
|
57
|
+
popupRef: tooltipRef,
|
|
55
58
|
containerRefs: [scrollingRef],
|
|
56
59
|
}, onVisibleChange: changeVisible, children: ({ renderTrigger, renderPopup }) => {
|
|
57
60
|
const render = (el) => renderTrigger(cloneElement(el, {
|
|
@@ -87,7 +90,7 @@ export const Tooltip = forwardRef((props, ref) => {
|
|
|
87
90
|
case 'entering':
|
|
88
91
|
transitionStyle = {
|
|
89
92
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING.enter}ms ease-out`).join(', '),
|
|
90
|
-
transformOrigin,
|
|
93
|
+
transformOrigin: transformOrigin.current,
|
|
91
94
|
};
|
|
92
95
|
break;
|
|
93
96
|
case 'leaving':
|
|
@@ -95,7 +98,7 @@ export const Tooltip = forwardRef((props, ref) => {
|
|
|
95
98
|
transform: 'scale(0.3)',
|
|
96
99
|
opacity: 0,
|
|
97
100
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING.leave}ms ease-in`).join(', '),
|
|
98
|
-
transformOrigin,
|
|
101
|
+
transformOrigin: transformOrigin.current,
|
|
99
102
|
};
|
|
100
103
|
break;
|
|
101
104
|
case 'leaved':
|
|
@@ -104,10 +107,10 @@ export const Tooltip = forwardRef((props, ref) => {
|
|
|
104
107
|
default:
|
|
105
108
|
break;
|
|
106
109
|
}
|
|
107
|
-
return renderPopup(_jsxs("div", Object.assign({}, restProps, mergeCS(styled('tooltip'
|
|
110
|
+
return renderPopup(_jsxs("div", Object.assign({}, restProps, mergeCS(styled('tooltip'), {
|
|
108
111
|
className: restProps.className,
|
|
109
|
-
style: Object.assign(Object.assign(Object.assign(
|
|
110
|
-
}), { ref:
|
|
112
|
+
style: Object.assign(Object.assign(Object.assign({}, restProps.style), { zIndex }), transitionStyle),
|
|
113
|
+
}), { ref: tooltipRef, id: id, role: "tooltip", children: [arrow && _jsx("div", Object.assign({}, styled('tooltip__arrow'))), title] })));
|
|
111
114
|
} }) })] }));
|
|
112
115
|
} }));
|
|
113
116
|
});
|
|
@@ -11,7 +11,7 @@ import { createElement, forwardRef, useId, useImperativeHandle, useMemo, useRef,
|
|
|
11
11
|
import { TreeSelectSearchPanel } from './internal/TreeSelectSearchPanel';
|
|
12
12
|
import { CLASSES } from './vars';
|
|
13
13
|
import { Dropdown } from '../dropdown';
|
|
14
|
-
import { useComponentProps, useControlled, useDesign, useFocusVisible, useLayout, useListenGlobalScrolling, useMaxIndex, useNamespace, useScopedProps, useStyled, useTranslation, } from '../hooks';
|
|
14
|
+
import { useComponentProps, useControlled, useDesign, useFocusVisible, useJSS, useLayout, useListenGlobalScrolling, useMaxIndex, useNamespace, useScopedProps, useStyled, useTranslation, } from '../hooks';
|
|
15
15
|
import { Icon } from '../icon';
|
|
16
16
|
import { CircularProgress } from '../internal/circular-progress';
|
|
17
17
|
import { Portal } from '../internal/portal';
|
|
@@ -33,6 +33,7 @@ function TreeSelectFC(props, ref) {
|
|
|
33
33
|
tree: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.tree,
|
|
34
34
|
'tree-select-popup': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['tree-select-popup'],
|
|
35
35
|
}, styleOverrides);
|
|
36
|
+
const sheet = useJSS();
|
|
36
37
|
const dataRef = useRef({
|
|
37
38
|
expands: new Set(),
|
|
38
39
|
});
|
|
@@ -179,11 +180,7 @@ function TreeSelectFC(props, ref) {
|
|
|
179
180
|
})();
|
|
180
181
|
const maxZIndex = useMaxIndex(visible);
|
|
181
182
|
const zIndex = `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})`;
|
|
182
|
-
const
|
|
183
|
-
const [popupPositionStyle, setPopupPositionStyle] = useState({
|
|
184
|
-
top: '-200vh',
|
|
185
|
-
left: '-200vw',
|
|
186
|
-
});
|
|
183
|
+
const transformOrigin = useRef();
|
|
187
184
|
const updatePosition = useEventCallback(() => {
|
|
188
185
|
if (visible && boxRef.current && popupRef.current) {
|
|
189
186
|
const boxWidth = boxRef.current.offsetWidth;
|
|
@@ -194,13 +191,17 @@ function TreeSelectFC(props, ref) {
|
|
|
194
191
|
placement: 'bottom-left',
|
|
195
192
|
inWindow: WINDOW_SPACE,
|
|
196
193
|
});
|
|
197
|
-
|
|
198
|
-
|
|
194
|
+
transformOrigin.current = position.transformOrigin;
|
|
195
|
+
if (sheet.classes.position) {
|
|
196
|
+
popupRef.current.classList.toggle(sheet.classes.position, false);
|
|
197
|
+
}
|
|
198
|
+
sheet.replaceRule('position', {
|
|
199
199
|
top: position.top,
|
|
200
200
|
left: position.left,
|
|
201
201
|
minWidth: Math.min(boxWidth, maxWidth),
|
|
202
202
|
maxWidth,
|
|
203
203
|
});
|
|
204
|
+
popupRef.current.classList.toggle(sheet.classes.position, true);
|
|
204
205
|
}
|
|
205
206
|
});
|
|
206
207
|
const listenGlobalScrolling = useListenGlobalScrolling(updatePosition, !visible);
|
|
@@ -475,7 +476,7 @@ function TreeSelectFC(props, ref) {
|
|
|
475
476
|
case 'entering':
|
|
476
477
|
transitionStyle = {
|
|
477
478
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-out`).join(', '),
|
|
478
|
-
transformOrigin,
|
|
479
|
+
transformOrigin: transformOrigin.current,
|
|
479
480
|
};
|
|
480
481
|
break;
|
|
481
482
|
case 'leaving':
|
|
@@ -483,7 +484,7 @@ function TreeSelectFC(props, ref) {
|
|
|
483
484
|
transform: 'scaleY(0.7)',
|
|
484
485
|
opacity: 0,
|
|
485
486
|
transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-in`).join(', '),
|
|
486
|
-
transformOrigin,
|
|
487
|
+
transformOrigin: transformOrigin.current,
|
|
487
488
|
};
|
|
488
489
|
break;
|
|
489
490
|
case 'leaved':
|
|
@@ -493,7 +494,7 @@ function TreeSelectFC(props, ref) {
|
|
|
493
494
|
break;
|
|
494
495
|
}
|
|
495
496
|
return (_jsxs("div", Object.assign({}, mergeCS(styled('tree-select-popup'), {
|
|
496
|
-
style: Object.assign(
|
|
497
|
+
style: Object.assign({ zIndex }, transitionStyle),
|
|
497
498
|
}), { ref: popupRef, onMouseDown: (e) => {
|
|
498
499
|
preventBlur(e);
|
|
499
500
|
}, onMouseUp: (e) => {
|