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