x-ui-design 0.8.16 → 0.8.18
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 +1 -1
- package/dist/esm/types/hooks/usePosition.d.ts +1 -1
- package/dist/esm/types/types/popover.d.ts +3 -3
- package/dist/index.esm.js +88 -34
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +87 -33
- package/dist/index.js.map +1 -1
- package/lib/components/Dropdown/Dropdown.tsx +3 -3
- package/lib/components/Dropdown/style.css +34 -0
- package/lib/components/Popover/Popover.tsx +52 -18
- package/lib/components/Popover/style.css +30 -7
- package/lib/hooks/usePosition.ts +55 -11
- package/lib/types/popover.ts +2 -2
- package/package.json +1 -1
- package/src/app/page.tsx +22 -10
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { PopoverProps } from "../../types/popover";
|
|
3
3
|
import './style.css';
|
|
4
|
-
declare const Popover: ({ prefixCls, content, children, trigger, placement, open, visible, title, overlayClassName, overlayStyle, onVisibleChange, getPopupContainer }: PopoverProps) => React.JSX.Element;
|
|
4
|
+
declare const Popover: ({ prefixCls, content, children, trigger, placement, open, visible, title, style, overlayClassName, overlayStyle, onVisibleChange, getPopupContainer }: PopoverProps) => React.JSX.Element;
|
|
5
5
|
export default Popover;
|
|
@@ -9,7 +9,7 @@ type TPosition = {
|
|
|
9
9
|
offset?: number;
|
|
10
10
|
};
|
|
11
11
|
export declare const usePosition: ({ isOpen, offset, popupRef, placement, triggerRef, getPopupContainer }: TPosition) => {
|
|
12
|
-
|
|
12
|
+
showPlacement: string;
|
|
13
13
|
dropdownPosition: CSSProperties;
|
|
14
14
|
};
|
|
15
15
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CSSProperties, ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { DefaultProps } from ".";
|
|
3
|
+
export type PopoverProps = DefaultProps & {
|
|
4
4
|
content: ReactNode;
|
|
5
5
|
children: ReactNode;
|
|
6
6
|
trigger?: "click" | "hover";
|
|
@@ -12,4 +12,4 @@ export interface PopoverProps {
|
|
|
12
12
|
visible?: boolean;
|
|
13
13
|
onVisibleChange?: ((open: boolean) => void) | undefined;
|
|
14
14
|
getPopupContainer?: ((node: HTMLElement) => HTMLElement) | undefined;
|
|
15
|
-
}
|
|
15
|
+
};
|
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import require$$1 from 'react/jsx-runtime';
|
|
2
|
-
import React, { useRef, useState, Children, isValidElement, Fragment, Suspense, useEffect, useContext, useMemo, useCallback, createContext, useImperativeHandle, useLayoutEffect } from 'react';
|
|
2
|
+
import React, { useRef, useState, Children, isValidElement, Fragment, Suspense, useEffect, useContext, useMemo, useCallback, createContext, useImperativeHandle, useLayoutEffect, cloneElement } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
4
|
import ReactDOMServer from 'react-dom/server';
|
|
5
5
|
|
|
@@ -2594,6 +2594,15 @@ function getScrollParent(el, includeSelf = false) {
|
|
|
2594
2594
|
}
|
|
2595
2595
|
return document.scrollingElement;
|
|
2596
2596
|
}
|
|
2597
|
+
const clampWithinContainer = (left, popupWidth, containerRect) => {
|
|
2598
|
+
const minLeft = containerRect.left + document.documentElement.scrollLeft;
|
|
2599
|
+
const maxLeft = containerRect.right + document.documentElement.scrollLeft - popupWidth;
|
|
2600
|
+
return {
|
|
2601
|
+
minLeft,
|
|
2602
|
+
maxLeft,
|
|
2603
|
+
leftPosition: Math.min(Math.max(left, minLeft), maxLeft)
|
|
2604
|
+
};
|
|
2605
|
+
};
|
|
2597
2606
|
const usePosition = ({
|
|
2598
2607
|
isOpen,
|
|
2599
2608
|
offset = 4,
|
|
@@ -2602,7 +2611,7 @@ const usePosition = ({
|
|
|
2602
2611
|
triggerRef,
|
|
2603
2612
|
getPopupContainer
|
|
2604
2613
|
}) => {
|
|
2605
|
-
const [
|
|
2614
|
+
const [showPlacement, setShowPlacement] = useState('');
|
|
2606
2615
|
const [_dropdownPosition, setDropdownPosition] = useState({});
|
|
2607
2616
|
const dropdownPosition = useCallback(() => {
|
|
2608
2617
|
if (!triggerRef.current) {
|
|
@@ -2615,9 +2624,14 @@ const usePosition = ({
|
|
|
2615
2624
|
const spaceBelow = containerRect.bottom - inputRect.bottom;
|
|
2616
2625
|
const _shouldShowAbove = spaceBelow < dropdownHeight && spaceAbove > dropdownHeight;
|
|
2617
2626
|
const hasRight = placement?.includes('Right');
|
|
2618
|
-
setShouldShowAbove(_shouldShowAbove);
|
|
2619
2627
|
if (getPopupContainer) {
|
|
2620
|
-
const
|
|
2628
|
+
const {
|
|
2629
|
+
minLeft,
|
|
2630
|
+
maxLeft,
|
|
2631
|
+
leftPosition
|
|
2632
|
+
} = clampWithinContainer(hasRight ? (inputRect.left || 0) + (triggerRef.current?.offsetWidth || 0) - (popupRef.current?.offsetWidth || 0) : (inputRect.left || 0) + document.documentElement.scrollLeft, popupRef.current?.offsetWidth || 0, containerRect);
|
|
2633
|
+
const _center = minLeft + maxLeft < (popupRef.current?.offsetWidth || 0) ? 'center' : '';
|
|
2634
|
+
setShowPlacement(_shouldShowAbove ? `bottom ${_center}` : `${_center}`);
|
|
2621
2635
|
const _top = (inputRect.top || 0) + document.documentElement.scrollTop;
|
|
2622
2636
|
if (_shouldShowAbove) {
|
|
2623
2637
|
setDropdownPosition({
|
|
@@ -2634,9 +2648,27 @@ const usePosition = ({
|
|
|
2634
2648
|
setDropdownPosition({
|
|
2635
2649
|
top: (_shouldShowAbove ? triggerRef.current.offsetTop - (popupRef.current?.offsetHeight || dropdownHeight) - offset * 2 : triggerRef.current.offsetTop + triggerRef.current?.offsetHeight) + offset,
|
|
2636
2650
|
...(hasRight ? {
|
|
2637
|
-
left:
|
|
2651
|
+
left: (() => {
|
|
2652
|
+
const {
|
|
2653
|
+
minLeft,
|
|
2654
|
+
maxLeft,
|
|
2655
|
+
leftPosition
|
|
2656
|
+
} = clampWithinContainer(triggerRef.current.offsetLeft + (triggerRef.current?.offsetWidth || 0) - (popupRef.current?.offsetWidth || dropdownHeight), popupRef.current?.offsetWidth || dropdownHeight, containerRect);
|
|
2657
|
+
const _center = minLeft + maxLeft < (popupRef.current?.offsetWidth || 0) ? 'center' : '';
|
|
2658
|
+
setShowPlacement(_shouldShowAbove ? `bottom ${_center}` : `${_center}`);
|
|
2659
|
+
return leftPosition;
|
|
2660
|
+
})()
|
|
2638
2661
|
} : {
|
|
2639
|
-
left:
|
|
2662
|
+
left: (() => {
|
|
2663
|
+
const {
|
|
2664
|
+
minLeft,
|
|
2665
|
+
maxLeft,
|
|
2666
|
+
leftPosition
|
|
2667
|
+
} = clampWithinContainer(triggerRef.current.offsetLeft, popupRef.current?.offsetWidth || dropdownHeight, containerRect);
|
|
2668
|
+
const _center = minLeft + maxLeft < (popupRef.current?.offsetWidth || 0) ? 'center' : '';
|
|
2669
|
+
setShowPlacement(_shouldShowAbove ? `bottom ${_center}` : `${_center}`);
|
|
2670
|
+
return leftPosition;
|
|
2671
|
+
})()
|
|
2640
2672
|
})
|
|
2641
2673
|
});
|
|
2642
2674
|
}
|
|
@@ -2663,7 +2695,7 @@ const usePosition = ({
|
|
|
2663
2695
|
};
|
|
2664
2696
|
}, [isOpen, triggerRef, getPopupContainer, dropdownPosition]);
|
|
2665
2697
|
return {
|
|
2666
|
-
|
|
2698
|
+
showPlacement,
|
|
2667
2699
|
dropdownPosition: {
|
|
2668
2700
|
..._dropdownPosition,
|
|
2669
2701
|
opacity: Object.keys(_dropdownPosition).length ? 1 : 0
|
|
@@ -5321,7 +5353,7 @@ var Menu$1 = /*#__PURE__*/Object.freeze({
|
|
|
5321
5353
|
default: Menu
|
|
5322
5354
|
});
|
|
5323
5355
|
|
|
5324
|
-
var css_248z$2 = ".xUi-dropdown-overlay{background:var(--xui-menu-inline-bg);border:1px solid var(--xui-border-color);border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,.08);min-width:160px;padding:4px 0;position:absolute;&:before{content:\"\";height:10px;position:absolute;top:-15px;width:100%;z-index:1}}.xUi-dropdown-overlay>div,.xUi-dropdown-overlay>select,.xUi-dropdown-overlay>ul{box-shadow:unset}.xUi-dropdown-overlay .xUi-dropdown-menu{margin:0;padding:0 4px;position:relative;&:before{content:\"\";height:10px;position:absolute;top:-15px;width:100%;z-index:1}}.xUi-dropdown-overlay .xUi-dropdown-item{border-radius:8px;color:var(--xui-text-color);cursor:pointer;font-size:14px;list-style:none;padding:8px 12px;user-select:none}.xUi-dropdown-overlay .xUi-dropdown-item:focus,.xUi-dropdown-overlay .xUi-dropdown-item:hover{background:var(--xui-color-hover);outline:none}.xUi-dropdown-overlay .xUi-dropdown-item.disabled{cursor:not-allowed;opacity:.5}.xUi-dropdown-overlay .xUi-dropdown-item.danger{color:var(--xui-error-color-light);&:hover{background-color:var(--xui-error-color-light);color:var(--xui-background-color)}}.xUi-dropdown-arrow{background:var(--xui-background-color);border-left:.5px solid var(--xui-border-color);border-top:.5px solid var(--xui-border-color);height:10px;left:12px;position:absolute;top:-6px;transform:rotate(45deg);width:10px}.xUi-dropdown-arrow.bottom{border-bottom:.5px solid var(--xui-border-color);border-left:unset;border-right:.5px solid var(--xui-border-color);border-top:unset;bottom:-6px;top:unset}";
|
|
5356
|
+
var css_248z$2 = ".xUi-dropdown-overlay{background:var(--xui-menu-inline-bg);border:1px solid var(--xui-border-color);border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,.08);min-width:160px;padding:4px 0;position:absolute;&:before{content:\"\";height:10px;position:absolute;top:-15px;width:100%;z-index:1}}.xUi-dropdown-overlay>div,.xUi-dropdown-overlay>select,.xUi-dropdown-overlay>ul{box-shadow:unset}.xUi-dropdown-overlay .xUi-dropdown-menu{margin:0;padding:0 4px;position:relative;&:before{content:\"\";height:10px;position:absolute;top:-15px;width:100%;z-index:1}}.xUi-dropdown-overlay .xUi-dropdown-item{border-radius:8px;color:var(--xui-text-color);cursor:pointer;font-size:14px;list-style:none;padding:8px 12px;user-select:none}.xUi-dropdown-overlay .xUi-dropdown-item:focus,.xUi-dropdown-overlay .xUi-dropdown-item:hover{background:var(--xui-color-hover);outline:none}.xUi-dropdown-overlay .xUi-dropdown-item.disabled{cursor:not-allowed;opacity:.5}.xUi-dropdown-overlay .xUi-dropdown-item.danger{color:var(--xui-error-color-light);&:hover{background-color:var(--xui-error-color-light);color:var(--xui-background-color)}}.xUi-dropdown-arrow{background:var(--xui-background-color);border-left:.5px solid var(--xui-border-color);border-top:.5px solid var(--xui-border-color);height:10px;left:12px;position:absolute;top:-6px;transform:rotate(45deg);width:10px}.xUi-dropdown-bottomRight .xUi-dropdown-arrow,.xUi-dropdown-right .xUi-dropdown-arrow,.xUi-dropdown-topRight .xUi-dropdown-arrow{left:unset;right:12px}.xUi-dropdown-arrow.bottom{border-bottom:.5px solid var(--xui-border-color);border-left:unset;border-right:.5px solid var(--xui-border-color);border-top:unset;bottom:-6px;top:unset}.xUi-dropdown-arrow.center{left:0;margin:0 auto;right:0}";
|
|
5325
5357
|
styleInject(css_248z$2);
|
|
5326
5358
|
|
|
5327
5359
|
const Dropdown = ({
|
|
@@ -5351,7 +5383,7 @@ const Dropdown = ({
|
|
|
5351
5383
|
const popupRef = useRef(null);
|
|
5352
5384
|
const menuRef = useRef(null);
|
|
5353
5385
|
const {
|
|
5354
|
-
|
|
5386
|
+
showPlacement,
|
|
5355
5387
|
dropdownPosition
|
|
5356
5388
|
} = usePosition({
|
|
5357
5389
|
popupRef,
|
|
@@ -5421,14 +5453,14 @@ const Dropdown = ({
|
|
|
5421
5453
|
wrapper: element => getPopupContainer ? /*#__PURE__*/createPortal(element, getPopupContainer(popupRef.current)) : /*#__PURE__*/React.createElement(React.Fragment, null, element)
|
|
5422
5454
|
}, /*#__PURE__*/React.createElement("div", {
|
|
5423
5455
|
ref: popupRef,
|
|
5424
|
-
className: `${prefixCls}-overlay ${overlayClassName}`,
|
|
5456
|
+
className: `${prefixCls}-overlay ${prefixCls}-${placement} ${overlayClassName}`,
|
|
5425
5457
|
style: {
|
|
5426
5458
|
zIndex: _hover ? 1000 : 0,
|
|
5427
5459
|
...overlayStyle,
|
|
5428
5460
|
...dropdownPosition
|
|
5429
5461
|
}
|
|
5430
5462
|
}, arrow && /*#__PURE__*/React.createElement("div", {
|
|
5431
|
-
className: `${prefixCls}-arrow ${
|
|
5463
|
+
className: `${prefixCls}-arrow ${showPlacement ? 'bottom' : ''}`
|
|
5432
5464
|
}), overlay ? typeof overlay === 'function' ? overlay() : overlay : popupRender ? popupRender(menu ? /*#__PURE__*/React.createElement(MenuInner, {
|
|
5433
5465
|
prefixCls: prefixCls,
|
|
5434
5466
|
items: menu.items,
|
|
@@ -5497,7 +5529,7 @@ var Dropdown$1 = /*#__PURE__*/Object.freeze({
|
|
|
5497
5529
|
default: Dropdown
|
|
5498
5530
|
});
|
|
5499
5531
|
|
|
5500
|
-
var css_248z$1 = ".xUi-popover{&:before{content:\"\";height:
|
|
5532
|
+
var css_248z$1 = ".xUi-popover{&:before{content:\"\";height:10px;left:0;position:absolute;top:-10px;width:100%;z-index:10000}}.xUi-popover-wrapper-content{cursor:pointer;max-width:fit-content;width:-webkit-fill-available}.xUi-popover{background:var(--xui-background-color);border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,.15);padding:8px 12px;width:max-content;z-index:1000}.xUi-popover-title{padding:4px}.xUi-popover-inner{color:var(--xui-text-color);font-size:14px}.xUi-popover-arrow{background:var(--xui-background-color);border-left:.5px solid var(--xui-border-color);border-top:.5px solid var(--xui-border-color);height:10px;left:12px;position:absolute;top:-6px;transform:rotate(45deg);width:10px}.xUi-popover-bottomRight .xUi-popover-arrow,.xUi-popover-right .xUi-popover-arrow,.xUi-popover-topRight .xUi-popover-arrow{left:unset;right:12px}.xUi-popover-arrow.bottom{border-bottom:.5px solid var(--xui-border-color);border-left:unset;border-right:.5px solid var(--xui-border-color);border-top:unset;bottom:-6px;top:unset}.xUi-popover-arrow.center{left:0;margin:0 auto;right:0}";
|
|
5501
5533
|
styleInject(css_248z$1);
|
|
5502
5534
|
|
|
5503
5535
|
const Popover = ({
|
|
@@ -5509,6 +5541,7 @@ const Popover = ({
|
|
|
5509
5541
|
open,
|
|
5510
5542
|
visible,
|
|
5511
5543
|
title,
|
|
5544
|
+
style = {},
|
|
5512
5545
|
overlayClassName = '',
|
|
5513
5546
|
overlayStyle = {},
|
|
5514
5547
|
onVisibleChange,
|
|
@@ -5521,7 +5554,7 @@ const Popover = ({
|
|
|
5521
5554
|
const isOpen = visible !== undefined ? visible : open !== undefined ? open : innerOpen;
|
|
5522
5555
|
const {
|
|
5523
5556
|
dropdownPosition,
|
|
5524
|
-
|
|
5557
|
+
showPlacement
|
|
5525
5558
|
} = usePosition({
|
|
5526
5559
|
isOpen,
|
|
5527
5560
|
offset: 10,
|
|
@@ -5530,41 +5563,62 @@ const Popover = ({
|
|
|
5530
5563
|
triggerRef,
|
|
5531
5564
|
getPopupContainer: getPopupContainer?.(triggerRef.current)
|
|
5532
5565
|
});
|
|
5533
|
-
|
|
5566
|
+
useEffect(() => {
|
|
5567
|
+
const handleClickOutside = e => {
|
|
5568
|
+
if (popupRef.current && !popupRef.current.contains(e.target) && triggerRef.current && !triggerRef.current.contains(e.target)) {
|
|
5569
|
+
setInnerOpen(false);
|
|
5570
|
+
onVisibleChange?.(false);
|
|
5571
|
+
}
|
|
5572
|
+
};
|
|
5573
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
5574
|
+
return () => {
|
|
5575
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
5576
|
+
};
|
|
5577
|
+
}, []);
|
|
5578
|
+
const handleOnClick = useCallback(() => {
|
|
5534
5579
|
const newState = !isOpen;
|
|
5535
5580
|
onVisibleChange?.(newState);
|
|
5536
5581
|
setInnerOpen(newState);
|
|
5537
|
-
};
|
|
5538
|
-
const
|
|
5582
|
+
}, [isOpen, trigger]);
|
|
5583
|
+
const handleOnMouseEnter = useCallback(() => {
|
|
5539
5584
|
setHover(true);
|
|
5540
5585
|
if (trigger === "hover") {
|
|
5541
5586
|
onVisibleChange?.(true);
|
|
5542
5587
|
setInnerOpen(true);
|
|
5543
5588
|
}
|
|
5544
|
-
};
|
|
5545
|
-
const
|
|
5589
|
+
}, [trigger]);
|
|
5590
|
+
const handleOnMouseLeave = useCallback(() => {
|
|
5546
5591
|
setHover(false);
|
|
5547
5592
|
if (trigger === "hover") {
|
|
5548
5593
|
onVisibleChange?.(false);
|
|
5549
5594
|
setInnerOpen(false);
|
|
5550
5595
|
}
|
|
5551
|
-
};
|
|
5552
|
-
const childProps = trigger === "click" ? {
|
|
5553
|
-
onClick:
|
|
5596
|
+
}, [trigger]);
|
|
5597
|
+
const childProps = useMemo(() => trigger === "click" ? {
|
|
5598
|
+
onClick: handleOnClick
|
|
5554
5599
|
} : {
|
|
5555
|
-
onMouseEnter:
|
|
5556
|
-
onMouseLeave:
|
|
5557
|
-
};
|
|
5558
|
-
return /*#__PURE__*/React.createElement(
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5600
|
+
onMouseEnter: handleOnMouseEnter,
|
|
5601
|
+
onMouseLeave: handleOnMouseLeave
|
|
5602
|
+
}, [trigger]);
|
|
5603
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, Children.map(children, (child, index) => {
|
|
5604
|
+
if (! /*#__PURE__*/isValidElement(child)) {
|
|
5605
|
+
child = /*#__PURE__*/React.createElement("div", null, child);
|
|
5606
|
+
}
|
|
5607
|
+
return /*#__PURE__*/cloneElement(child, {
|
|
5608
|
+
key: index,
|
|
5609
|
+
...childProps,
|
|
5610
|
+
...(index === 0 ? {
|
|
5611
|
+
ref: triggerRef,
|
|
5612
|
+
style,
|
|
5613
|
+
className: `${prefixCls}-wrapper-content`
|
|
5614
|
+
} : {})
|
|
5615
|
+
});
|
|
5616
|
+
}), isOpen && /*#__PURE__*/React.createElement(ConditionalWrapper, {
|
|
5564
5617
|
condition: !!getPopupContainer,
|
|
5565
5618
|
wrapper: element => getPopupContainer ? /*#__PURE__*/createPortal(element, getPopupContainer(popupRef.current)) : /*#__PURE__*/React.createElement(React.Fragment, null, element)
|
|
5566
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
5567
|
-
ref: popupRef
|
|
5619
|
+
}, /*#__PURE__*/React.createElement("div", _extends({
|
|
5620
|
+
ref: popupRef
|
|
5621
|
+
}, childProps, {
|
|
5568
5622
|
className: clsx(prefixCls, `${prefixCls}-${placement}`, overlayClassName),
|
|
5569
5623
|
style: {
|
|
5570
5624
|
zIndex: hover ? 1000 : 1,
|
|
@@ -5572,12 +5626,12 @@ const Popover = ({
|
|
|
5572
5626
|
...overlayStyle,
|
|
5573
5627
|
...dropdownPosition
|
|
5574
5628
|
}
|
|
5575
|
-
}, title && /*#__PURE__*/React.createElement("div", {
|
|
5629
|
+
}), title && /*#__PURE__*/React.createElement("div", {
|
|
5576
5630
|
className: `${prefixCls}-title`
|
|
5577
5631
|
}, title), /*#__PURE__*/React.createElement("div", {
|
|
5578
5632
|
className: `${prefixCls}-inner`
|
|
5579
5633
|
}, content), /*#__PURE__*/React.createElement("div", {
|
|
5580
|
-
className: `${prefixCls}-arrow ${
|
|
5634
|
+
className: `${prefixCls}-arrow ${showPlacement}`
|
|
5581
5635
|
}))));
|
|
5582
5636
|
};
|
|
5583
5637
|
|