x-ui-design 0.7.97 → 0.7.99
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/dist/esm/types/components/Popover/Popover.d.ts +5 -0
- package/dist/esm/types/components/Popover/index.d.ts +1 -0
- package/dist/esm/types/hooks/usePosition.d.ts +3 -3
- package/dist/esm/types/types/popover.d.ts +10 -0
- package/dist/esm/types/utils/index.d.ts +1 -0
- package/dist/index.esm.js +38 -37
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +38 -37
- package/dist/index.js.map +1 -1
- package/lib/components/DatePicker/DatePicker.tsx +9 -9
- package/lib/components/DatePicker/RangePicker/RangePicker.tsx +6 -6
- package/lib/components/DatePicker/TimePicker/TimePicker.tsx +2 -2
- package/lib/components/Dropdown/Dropdown.tsx +6 -6
- package/lib/components/Popover/Popover.tsx +85 -0
- package/lib/components/Popover/index.ts +1 -0
- package/lib/components/Popover/style.css +40 -0
- package/lib/components/Select/Select.tsx +4 -4
- package/lib/hooks/usePosition.ts +17 -20
- package/lib/types/popover.ts +10 -0
- package/lib/utils/index.ts +1 -0
- package/package.json +1 -1
- package/src/app/page.tsx +15 -170
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { PopoverProps } from "../../types/popover";
|
|
3
|
+
import './style.css';
|
|
4
|
+
declare const Popover: ({ prefixCls, content, children, trigger, placement, open, onOpenChange, getPopupContainer }: PopoverProps) => React.JSX.Element;
|
|
5
|
+
export default Popover;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Popover } from '../Popover/Popover';
|
|
@@ -3,12 +3,12 @@ import { CSSProperties, RefObject } from "react";
|
|
|
3
3
|
type TPosition = {
|
|
4
4
|
isOpen: boolean;
|
|
5
5
|
popupRef: RefObject<HTMLDivElement | null>;
|
|
6
|
-
|
|
7
|
-
getPopupContainer?:
|
|
6
|
+
triggerRef: RefObject<HTMLDivElement | null>;
|
|
7
|
+
getPopupContainer?: HTMLElement;
|
|
8
8
|
placement?: Placement;
|
|
9
9
|
addTop?: number;
|
|
10
10
|
};
|
|
11
|
-
export declare const usePosition: ({ isOpen, addTop, popupRef, placement,
|
|
11
|
+
export declare const usePosition: ({ isOpen, addTop, popupRef, placement, triggerRef, getPopupContainer }: TPosition) => {
|
|
12
12
|
shouldShowAbove: boolean;
|
|
13
13
|
dropdownPosition: CSSProperties;
|
|
14
14
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface PopoverProps {
|
|
2
|
+
prefixCls?: string;
|
|
3
|
+
content: React.ReactNode;
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
trigger?: "click" | "hover";
|
|
6
|
+
placement?: "top" | "bottom" | "left" | "right" | "topRight" | "bottomRight" | "topLeft" | "bottomLeft";
|
|
7
|
+
open?: boolean;
|
|
8
|
+
onOpenChange?: (open: boolean) => void;
|
|
9
|
+
getPopupContainer?: ((node: HTMLElement) => HTMLElement) | undefined;
|
|
10
|
+
}
|
|
@@ -15,6 +15,7 @@ export declare const prefixClsButton = "xUi-button";
|
|
|
15
15
|
export declare const prefixClsSkeleton = "xUi-skeleton";
|
|
16
16
|
export declare const prefixClsMenu = "xUi-menu";
|
|
17
17
|
export declare const prefixClsDropdown = "xUi-dropdown";
|
|
18
|
+
export declare const prefixClsPopover = "xUi-popover";
|
|
18
19
|
export declare const prefixClsFormV3 = "v3-form";
|
|
19
20
|
export declare const prefixClsFormItemV3 = "v3-form-item";
|
|
20
21
|
export declare const prefixClsEmptyV3 = "v3-empty";
|
package/dist/index.esm.js
CHANGED
|
@@ -1995,24 +1995,25 @@ const usePosition = ({
|
|
|
1995
1995
|
addTop = 4,
|
|
1996
1996
|
popupRef,
|
|
1997
1997
|
placement,
|
|
1998
|
-
|
|
1998
|
+
triggerRef,
|
|
1999
1999
|
getPopupContainer
|
|
2000
2000
|
}) => {
|
|
2001
2001
|
const [shouldShowAbove, setShouldShowAbove] = useState(false);
|
|
2002
2002
|
const [_dropdownPosition, setDropdownPosition] = useState({});
|
|
2003
2003
|
const dropdownPosition = useCallback(() => {
|
|
2004
|
-
if (!
|
|
2005
|
-
|
|
2004
|
+
if (!triggerRef.current) {
|
|
2005
|
+
return {};
|
|
2006
|
+
}
|
|
2007
|
+
const inputRect = triggerRef.current?.getBoundingClientRect();
|
|
2006
2008
|
const dropdownHeight = popupRef.current?.offsetHeight || popupRef.current?.offsetHeight || 0;
|
|
2007
|
-
const
|
|
2008
|
-
const containerRect = popupContainer.getBoundingClientRect();
|
|
2009
|
+
const containerRect = (getPopupContainer || getScrollParent(triggerRef.current, true) || document.body).getBoundingClientRect();
|
|
2009
2010
|
const spaceAbove = inputRect.top - containerRect.top;
|
|
2010
2011
|
const spaceBelow = containerRect.bottom - inputRect.bottom;
|
|
2011
2012
|
const _shouldShowAbove = spaceBelow < dropdownHeight && spaceAbove > dropdownHeight;
|
|
2012
2013
|
const hasRight = placement?.includes('Right');
|
|
2013
2014
|
setShouldShowAbove(_shouldShowAbove);
|
|
2014
2015
|
if (getPopupContainer) {
|
|
2015
|
-
const leftPosition = hasRight ? (inputRect.left || 0) + (
|
|
2016
|
+
const leftPosition = hasRight ? (inputRect.left || 0) + (triggerRef.current?.offsetWidth || 0) - (popupRef.current?.offsetWidth || 0) : (inputRect.left || 0) + document.documentElement.scrollLeft;
|
|
2016
2017
|
const _top = (inputRect.top || 0) + document.documentElement.scrollTop;
|
|
2017
2018
|
if (_shouldShowAbove) {
|
|
2018
2019
|
setDropdownPosition({
|
|
@@ -2021,27 +2022,27 @@ const usePosition = ({
|
|
|
2021
2022
|
});
|
|
2022
2023
|
} else {
|
|
2023
2024
|
setDropdownPosition({
|
|
2024
|
-
top: _top + (
|
|
2025
|
+
top: _top + (triggerRef.current?.offsetHeight || 0) + 4,
|
|
2025
2026
|
left: leftPosition
|
|
2026
2027
|
});
|
|
2027
2028
|
}
|
|
2028
2029
|
} else {
|
|
2029
2030
|
setDropdownPosition({
|
|
2030
|
-
top: (_shouldShowAbove ?
|
|
2031
|
+
top: (_shouldShowAbove ? triggerRef.current.offsetTop - (popupRef.current?.offsetHeight || dropdownHeight) - addTop * 2 : triggerRef.current.offsetTop + triggerRef.current?.offsetHeight) + addTop,
|
|
2031
2032
|
...(hasRight ? {
|
|
2032
|
-
left:
|
|
2033
|
+
left: triggerRef.current.offsetLeft + (triggerRef.current?.offsetWidth || 0) - (popupRef.current?.offsetWidth || 0)
|
|
2033
2034
|
} : {
|
|
2034
|
-
left:
|
|
2035
|
+
left: triggerRef.current.offsetLeft
|
|
2035
2036
|
})
|
|
2036
2037
|
});
|
|
2037
2038
|
}
|
|
2038
|
-
}, [addTop, popupRef, placement,
|
|
2039
|
+
}, [addTop, popupRef, placement, triggerRef, getPopupContainer]);
|
|
2039
2040
|
useEffect(() => {
|
|
2040
2041
|
if (!isOpen) return;
|
|
2041
2042
|
const _dropdownPosition = () => dropdownPosition();
|
|
2042
2043
|
_dropdownPosition();
|
|
2043
2044
|
const controller = new AbortController();
|
|
2044
|
-
const scrollableParents = getScrollParent(
|
|
2045
|
+
const scrollableParents = getScrollParent(triggerRef.current, true);
|
|
2045
2046
|
scrollableParents?.addEventListener('scroll', _dropdownPosition, {
|
|
2046
2047
|
passive: true,
|
|
2047
2048
|
signal: controller.signal
|
|
@@ -2056,7 +2057,7 @@ const usePosition = ({
|
|
|
2056
2057
|
return () => {
|
|
2057
2058
|
controller.abort();
|
|
2058
2059
|
};
|
|
2059
|
-
}, [isOpen,
|
|
2060
|
+
}, [isOpen, triggerRef, getPopupContainer, dropdownPosition]);
|
|
2060
2061
|
return {
|
|
2061
2062
|
shouldShowAbove,
|
|
2062
2063
|
dropdownPosition: _dropdownPosition
|
|
@@ -2099,11 +2100,11 @@ const DatePicker = ({
|
|
|
2099
2100
|
bordered = true,
|
|
2100
2101
|
defaultPickerValue
|
|
2101
2102
|
}) => {
|
|
2102
|
-
const
|
|
2103
|
+
const triggerRef = useRef(null);
|
|
2103
2104
|
const initialDate = value || defaultValue;
|
|
2104
2105
|
const initialPickerDate = defaultPickerValue || initialDate;
|
|
2105
2106
|
const popupRef = useRef(null);
|
|
2106
|
-
const
|
|
2107
|
+
const popuptriggerRef = useRef(null);
|
|
2107
2108
|
const DateNow = new Date();
|
|
2108
2109
|
const [selectedDate, setSelectedDate] = useState(initialDate);
|
|
2109
2110
|
const [selectedDatePlaceholder, setSelectedDatePlaceholder] = useState(initialDate ? formatDate(initialDate, format) : undefined);
|
|
@@ -2123,8 +2124,8 @@ const DatePicker = ({
|
|
|
2123
2124
|
isOpen,
|
|
2124
2125
|
popupRef,
|
|
2125
2126
|
placement,
|
|
2126
|
-
|
|
2127
|
-
getPopupContainer
|
|
2127
|
+
triggerRef,
|
|
2128
|
+
getPopupContainer: getPopupContainer?.(triggerRef.current)
|
|
2128
2129
|
});
|
|
2129
2130
|
useEffect(() => {
|
|
2130
2131
|
const _date = value || defaultValue;
|
|
@@ -2133,7 +2134,7 @@ const DatePicker = ({
|
|
|
2133
2134
|
}, [value]);
|
|
2134
2135
|
useEffect(() => {
|
|
2135
2136
|
const handleClickOutside = event => {
|
|
2136
|
-
if (popupRef.current && !popupRef.current.contains(event.target) &&
|
|
2137
|
+
if (popupRef.current && !popupRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
|
|
2137
2138
|
setIsOpen(false);
|
|
2138
2139
|
}
|
|
2139
2140
|
};
|
|
@@ -2148,8 +2149,8 @@ const DatePicker = ({
|
|
|
2148
2149
|
};
|
|
2149
2150
|
}, [isOpen]);
|
|
2150
2151
|
useEffect(() => {
|
|
2151
|
-
if (getPopupContainer &&
|
|
2152
|
-
|
|
2152
|
+
if (getPopupContainer && triggerRef.current) {
|
|
2153
|
+
popuptriggerRef.current = getPopupContainer(triggerRef.current);
|
|
2153
2154
|
}
|
|
2154
2155
|
}, [getPopupContainer]);
|
|
2155
2156
|
const daysInMonth = (year, month) => new Date(year, month + 1, 0).getDate();
|
|
@@ -2242,7 +2243,7 @@ const DatePicker = ({
|
|
|
2242
2243
|
}])
|
|
2243
2244
|
}, /*#__PURE__*/React.createElement("div", {
|
|
2244
2245
|
className: `${prefixCls}-input-wrapper`,
|
|
2245
|
-
ref:
|
|
2246
|
+
ref: triggerRef
|
|
2246
2247
|
}, /*#__PURE__*/React.createElement("button", {
|
|
2247
2248
|
type: "button",
|
|
2248
2249
|
className: clsx([`${prefixCls}-input ${className}`, {
|
|
@@ -2445,7 +2446,7 @@ const RangePicker = ({
|
|
|
2445
2446
|
getPopupContainer,
|
|
2446
2447
|
placement
|
|
2447
2448
|
}) => {
|
|
2448
|
-
const
|
|
2449
|
+
const triggerRef = useRef(null);
|
|
2449
2450
|
const [isOpen, setIsOpen] = useState(false);
|
|
2450
2451
|
const [selectedDates, setSelectedDates] = useState([value?.[0] || defaultValue?.[0] || null, value?.[1] || defaultValue?.[1] || null]);
|
|
2451
2452
|
useEffect(() => {
|
|
@@ -2462,8 +2463,8 @@ const RangePicker = ({
|
|
|
2462
2463
|
isOpen,
|
|
2463
2464
|
popupRef,
|
|
2464
2465
|
placement,
|
|
2465
|
-
|
|
2466
|
-
getPopupContainer
|
|
2466
|
+
triggerRef,
|
|
2467
|
+
getPopupContainer: getPopupContainer?.(triggerRef.current)
|
|
2467
2468
|
});
|
|
2468
2469
|
const localeMonths = locale?.shortMonths || Array.from({
|
|
2469
2470
|
length: 12
|
|
@@ -2473,7 +2474,7 @@ const RangePicker = ({
|
|
|
2473
2474
|
const localeWeekdays = locale?.shortWeekDays || ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
|
|
2474
2475
|
useEffect(() => {
|
|
2475
2476
|
const handleClickOutside = event => {
|
|
2476
|
-
if (popupRef.current && !popupRef.current.contains(event.target) &&
|
|
2477
|
+
if (popupRef.current && !popupRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
|
|
2477
2478
|
setIsOpen(false);
|
|
2478
2479
|
onOpenChange?.(false);
|
|
2479
2480
|
}
|
|
@@ -2682,7 +2683,7 @@ const RangePicker = ({
|
|
|
2682
2683
|
}])
|
|
2683
2684
|
}, /*#__PURE__*/React.createElement("div", {
|
|
2684
2685
|
className: `${prefixCls}-range-input-wrapper`,
|
|
2685
|
-
ref:
|
|
2686
|
+
ref: triggerRef
|
|
2686
2687
|
}, /*#__PURE__*/React.createElement("button", {
|
|
2687
2688
|
type: "button",
|
|
2688
2689
|
className: clsx([`${prefixCls}-input`, {
|
|
@@ -2781,8 +2782,8 @@ const TimePicker = ({
|
|
|
2781
2782
|
popupRef,
|
|
2782
2783
|
placement,
|
|
2783
2784
|
isOpen: open,
|
|
2784
|
-
|
|
2785
|
-
|
|
2785
|
+
triggerRef: inputRef,
|
|
2786
|
+
getPopupContainer: getPopupContainer?.(inputRef.current)
|
|
2786
2787
|
});
|
|
2787
2788
|
useEffect(() => {
|
|
2788
2789
|
setInnerValue(propValue || defaultValue ? new Date(propValue || defaultValue) : null);
|
|
@@ -3693,7 +3694,7 @@ const Select = ({
|
|
|
3693
3694
|
const [searchQuery, setSearchQuery] = useState(searchValue || '');
|
|
3694
3695
|
const [dropdownPosition, setDropdownPosition] = useState({});
|
|
3695
3696
|
const [lastTagWidth, setLastTagWidth] = useState(0);
|
|
3696
|
-
const
|
|
3697
|
+
const tagtriggerRef = useRef(null);
|
|
3697
3698
|
const searchInputRef = useRef(null);
|
|
3698
3699
|
const [responsiveTagCount, setResponsiveTagCount] = useState(null);
|
|
3699
3700
|
const [selected, setSelected] = useState(hasMode ? checkModeInitialValue : initialValue);
|
|
@@ -4004,7 +4005,7 @@ const Select = ({
|
|
|
4004
4005
|
}, typeof option === 'string' ? option : option?.children || option?.label || option?.value || null);
|
|
4005
4006
|
}, [extractedOptions, selected]) || selected || null;
|
|
4006
4007
|
const hasMaxTagCount = hasMode && (typeof maxTagCount === 'number' || maxTagCount === 'responsive');
|
|
4007
|
-
const container =
|
|
4008
|
+
const container = tagtriggerRef.current;
|
|
4008
4009
|
const selectedTags = hasMode ? selected : [];
|
|
4009
4010
|
const displayTagCount = maxTagCount === 'responsive' ? responsiveTagCount : maxTagCount;
|
|
4010
4011
|
const tagsToDisplay = hasMaxTagCount ? selectedTags.slice(0, displayTagCount || selectedTags.length) : selectedTags;
|
|
@@ -4055,7 +4056,7 @@ const Select = ({
|
|
|
4055
4056
|
onMouseLeave: handleMouseLeave,
|
|
4056
4057
|
className: `${prefixCls}-trigger ${prefixClsV3}-trigger`
|
|
4057
4058
|
}, showSearch || hasMode ? /*#__PURE__*/React.createElement("div", {
|
|
4058
|
-
ref:
|
|
4059
|
+
ref: tagtriggerRef,
|
|
4059
4060
|
style: {
|
|
4060
4061
|
...style,
|
|
4061
4062
|
...(isOpen ? {
|
|
@@ -4065,7 +4066,7 @@ const Select = ({
|
|
|
4065
4066
|
minWidth: `${searchInputWidth}px`
|
|
4066
4067
|
},
|
|
4067
4068
|
className: clsx([`${prefixCls}-tag-container ${prefixClsV3}-tag-container`, {
|
|
4068
|
-
[`${prefixCls}-tag-container-fixHeight ${prefixClsV3}-tag-container-fixHeight`]: !
|
|
4069
|
+
[`${prefixCls}-tag-container-fixHeight ${prefixClsV3}-tag-container-fixHeight`]: !tagtriggerRef.current
|
|
4069
4070
|
}])
|
|
4070
4071
|
}, hasMode ? /*#__PURE__*/React.createElement(React.Fragment, null, selectedTags.length ? /*#__PURE__*/React.createElement(React.Fragment, null, tagsToDisplay.map((tag, index) => tagRender ? /*#__PURE__*/React.createElement("div", {
|
|
4071
4072
|
key: `${index}_${tag}`
|
|
@@ -4750,7 +4751,7 @@ const Dropdown = ({
|
|
|
4750
4751
|
const [open, setOpen] = useState(controlledOpen ?? defaultOpen);
|
|
4751
4752
|
const [_hover, setHover] = useState(controlledOpen ?? defaultOpen);
|
|
4752
4753
|
const isControlled = controlledOpen !== undefined;
|
|
4753
|
-
const
|
|
4754
|
+
const triggerRef = useRef(null);
|
|
4754
4755
|
const popupRef = useRef(null);
|
|
4755
4756
|
const menuRef = useRef(null);
|
|
4756
4757
|
const {
|
|
@@ -4761,8 +4762,8 @@ const Dropdown = ({
|
|
|
4761
4762
|
placement,
|
|
4762
4763
|
addTop: 8,
|
|
4763
4764
|
isOpen: open,
|
|
4764
|
-
|
|
4765
|
-
getPopupContainer
|
|
4765
|
+
triggerRef,
|
|
4766
|
+
getPopupContainer: getPopupContainer?.(triggerRef.current)
|
|
4766
4767
|
});
|
|
4767
4768
|
useEffect(() => {
|
|
4768
4769
|
if (isControlled) {
|
|
@@ -4794,7 +4795,7 @@ const Dropdown = ({
|
|
|
4794
4795
|
return;
|
|
4795
4796
|
}
|
|
4796
4797
|
const target = e.target;
|
|
4797
|
-
if (
|
|
4798
|
+
if (triggerRef.current && !triggerRef.current.contains(target) && !popupRef.current?.contains(target)) {
|
|
4798
4799
|
setOpenInternal(false);
|
|
4799
4800
|
}
|
|
4800
4801
|
};
|
|
@@ -4853,7 +4854,7 @@ const Dropdown = ({
|
|
|
4853
4854
|
}
|
|
4854
4855
|
}, "Empty menu")));
|
|
4855
4856
|
return /*#__PURE__*/React.createElement("div", {
|
|
4856
|
-
ref:
|
|
4857
|
+
ref: triggerRef,
|
|
4857
4858
|
className: className
|
|
4858
4859
|
}, /*#__PURE__*/React.createElement("div", {
|
|
4859
4860
|
onClick: onTriggerClick,
|