@laser-ui/components 0.0.5 → 0.1.1
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 +10 -0
- package/README.md +23 -24
- 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 +19 -16
- package/dropdown/internal/DropdownSub.d.ts +0 -1
- package/dropdown/internal/DropdownSub.js +26 -17
- 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/Menu.js +4 -4
- package/menu/internal/MenuSub.d.ts +0 -1
- package/menu/internal/MenuSub.js +26 -17
- package/package.json +8 -6
- 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,16 @@
|
|
|
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.1](https://github.com/laser-ui/laser-ui/compare/v0.1.0...v0.1.1) (2023-09-13)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **components:** fix `container` is null ([151da41](https://github.com/laser-ui/laser-ui/commit/151da41063f8e629ef18ece4d70c9a35cb38b2f8))
|
|
10
|
+
|
|
11
|
+
# [0.1.0](https://github.com/laser-ui/laser-ui/compare/v0.0.5...v0.1.0) (2023-09-12)
|
|
12
|
+
|
|
13
|
+
**Note:** Version bump only for package @laser-ui/components
|
|
14
|
+
|
|
5
15
|
## [0.0.5](https://github.com/laser-ui/laser-ui/compare/v0.0.4...v0.0.5) (2023-09-11)
|
|
6
16
|
|
|
7
17
|
**Note:** Version bump only for package @laser-ui/components
|
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<a href="//
|
|
2
|
+
<a href="//laser-ui.surge.sh/" rel="noopener" target="_blank"><img width="150" src="apps/site/public/logo.png" alt="logo"></a>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<h1 align="center">
|
|
5
|
+
<h1 align="center">Laser UI</h1>
|
|
6
6
|
|
|
7
7
|
<div align="center">
|
|
8
8
|
|
|
9
9
|
<!-- prettier-ignore-start -->
|
|
10
|
-
[](https://www.npmjs.com/package/@laser-ui/components)
|
|
11
|
+
[](https://bundlephobia.com/package/@laser-ui/components)
|
|
12
|
+
[](https://github.com/laser-ui/laser-ui/actions/workflows/main.yml)
|
|
13
13
|
<!-- prettier-ignore-end -->
|
|
14
14
|
|
|
15
15
|
</div>
|
|
@@ -23,49 +23,48 @@ English | [简体中文](README.zh-CN.md)
|
|
|
23
23
|
## Installation
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
|
|
26
|
+
npm install @laser-ui/components @laser-ui/hooks @laser-ui/themes @laser-ui/utils
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
## Getting Started
|
|
30
30
|
|
|
31
31
|
```tsx
|
|
32
|
-
import type {
|
|
32
|
+
import type { LContextIn } from '@laser-ui/components/context';
|
|
33
33
|
|
|
34
|
+
import { ConfigProvider, Root } from '@laser-ui/components';
|
|
34
35
|
import { useMemo } from 'react';
|
|
35
36
|
|
|
36
|
-
import { DRoot } from '@react-devui/ui';
|
|
37
|
-
|
|
38
37
|
export default function App() {
|
|
39
|
-
const
|
|
38
|
+
const lContext = useMemo<LContextIn>(
|
|
40
39
|
() => ({
|
|
41
|
-
|
|
40
|
+
layoutPageScrollEl: '#app-main',
|
|
41
|
+
layoutContentResizeEl: '#app-content',
|
|
42
42
|
}),
|
|
43
|
-
[]
|
|
43
|
+
[],
|
|
44
44
|
);
|
|
45
45
|
|
|
46
46
|
return (
|
|
47
|
-
<
|
|
48
|
-
<
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
<ConfigProvider context={lContext}>
|
|
48
|
+
<Root>
|
|
49
|
+
<main id="app-main" style={{ overflow: 'auto' }}>
|
|
50
|
+
<section id="app-content" style={{ height: '200vh' }}>
|
|
51
|
+
Some content...
|
|
52
|
+
</section>
|
|
53
|
+
</main>
|
|
54
|
+
</Root>
|
|
55
|
+
</ConfigProvider>
|
|
54
56
|
);
|
|
55
57
|
}
|
|
56
58
|
```
|
|
57
59
|
|
|
58
60
|
## Links
|
|
59
61
|
|
|
60
|
-
- [
|
|
61
|
-
- [admin.react-devui.com](//admin.react-devui.com)
|
|
62
|
+
- [laser-ui.surge.sh](//laser-ui.surge.sh)
|
|
62
63
|
|
|
63
64
|
## Contributing
|
|
64
65
|
|
|
65
66
|
Please read our [contributing guide](/CONTRIBUTING.md) first.
|
|
66
67
|
|
|
67
|
-
Need unit test support (Jest) 🤝.
|
|
68
|
-
|
|
69
68
|
## License
|
|
70
69
|
|
|
71
|
-
[](/LICENSE)
|
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) => {
|
|
@@ -231,7 +234,7 @@ function DropdownFC(props, ref) {
|
|
|
231
234
|
else {
|
|
232
235
|
dataRef.current.updatePosition.set(itemId, fn);
|
|
233
236
|
}
|
|
234
|
-
}, namespace: namespace, styled: styled,
|
|
237
|
+
}, namespace: namespace, styled: styled, id: id, level: level, icon: itemIcon, list: children && getNodes(children, 0, newSubParents), popupState: popupState === null || popupState === void 0 ? void 0 : popupState.visible, trigger: trigger, empty: isEmpty, focus: focusVisible && isFocus, disabled: itemDisabled, zIndex: isUndefined(zIndex)
|
|
235
238
|
? zIndex
|
|
236
239
|
: isNumber(zIndex)
|
|
237
240
|
? zIndex + 1 + subParents.length
|
|
@@ -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,7 +3,6 @@ import type { Styled } from '../../hooks/useStyled';
|
|
|
3
3
|
import type { CLASSES } from '../vars';
|
|
4
4
|
interface DropdownSubProps {
|
|
5
5
|
children: React.ReactNode;
|
|
6
|
-
dropdownRef: React.RefObject<HTMLDivElement>;
|
|
7
6
|
namespace: string;
|
|
8
7
|
styled: Styled<typeof CLASSES>;
|
|
9
8
|
id: string;
|