@diwauhris/ui 1.7.38 → 1.7.39
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/lib/assets/ui.css +4 -0
- package/lib/index.cjs +30 -6
- package/lib/index.mjs +30 -6
- package/package.json +1 -1
package/lib/assets/ui.css
CHANGED
package/lib/index.cjs
CHANGED
|
@@ -3989,26 +3989,44 @@ function SidebarItem({ href, onClick, active = false, icon, badge, disabled = fa
|
|
|
3989
3989
|
*/
|
|
3990
3990
|
function Dropdown({ trigger, isOpen, onToggle, onClose, children, triggerClassName = "", panelClassName = "" }) {
|
|
3991
3991
|
const ref = (0, react.useRef)(null);
|
|
3992
|
+
const panelRef = (0, react.useRef)(null);
|
|
3992
3993
|
const triggerRef = (0, react.useRef)(null);
|
|
3993
3994
|
const panelId = `${(0, react.useId)().replace(/:/g, "")}-panel`;
|
|
3994
3995
|
const [panelStyle, setPanelStyle] = (0, react.useState)({});
|
|
3996
|
+
const [positioned, setPositioned] = (0, react.useState)(false);
|
|
3995
3997
|
(0, react.useEffect)(() => {
|
|
3996
|
-
if (!isOpen || !triggerRef.current)
|
|
3998
|
+
if (!isOpen || !triggerRef.current) {
|
|
3999
|
+
setPositioned(false);
|
|
4000
|
+
return;
|
|
4001
|
+
}
|
|
4002
|
+
const GAP = 4;
|
|
4003
|
+
const MARGIN = 8;
|
|
3997
4004
|
const updatePosition = () => {
|
|
3998
4005
|
if (!triggerRef.current) return;
|
|
3999
4006
|
const rect = triggerRef.current.getBoundingClientRect();
|
|
4007
|
+
const panelHeight = panelRef.current?.offsetHeight ?? 280;
|
|
4008
|
+
const panelWidth = panelRef.current?.offsetWidth ?? Math.max(rect.width, 180);
|
|
4009
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
4010
|
+
const spaceAbove = rect.top;
|
|
4011
|
+
const top = spaceBelow >= panelHeight + GAP + MARGIN || spaceBelow >= spaceAbove ? Math.min(rect.bottom + GAP, window.innerHeight - panelHeight - MARGIN) : Math.max(rect.top - panelHeight - GAP, MARGIN);
|
|
4012
|
+
const left = Math.max(MARGIN, Math.min(rect.left, window.innerWidth - panelWidth - MARGIN));
|
|
4000
4013
|
setPanelStyle({
|
|
4001
4014
|
position: "fixed",
|
|
4002
|
-
top:
|
|
4003
|
-
left
|
|
4004
|
-
zIndex:
|
|
4015
|
+
top: Math.max(MARGIN, top),
|
|
4016
|
+
left,
|
|
4017
|
+
zIndex: 1e3,
|
|
4005
4018
|
minWidth: Math.max(rect.width, 180)
|
|
4006
4019
|
});
|
|
4007
4020
|
};
|
|
4008
4021
|
updatePosition();
|
|
4022
|
+
const raf = requestAnimationFrame(() => {
|
|
4023
|
+
updatePosition();
|
|
4024
|
+
setPositioned(true);
|
|
4025
|
+
});
|
|
4009
4026
|
window.addEventListener("scroll", updatePosition, true);
|
|
4010
4027
|
window.addEventListener("resize", updatePosition);
|
|
4011
4028
|
return () => {
|
|
4029
|
+
cancelAnimationFrame(raf);
|
|
4012
4030
|
window.removeEventListener("scroll", updatePosition, true);
|
|
4013
4031
|
window.removeEventListener("resize", updatePosition);
|
|
4014
4032
|
};
|
|
@@ -4017,6 +4035,8 @@ function Dropdown({ trigger, isOpen, onToggle, onClose, children, triggerClassNa
|
|
|
4017
4035
|
if (!isOpen) return;
|
|
4018
4036
|
const handlePointerDown = (e) => {
|
|
4019
4037
|
const target = e.target;
|
|
4038
|
+
if (panelRef.current?.contains(target)) return;
|
|
4039
|
+
if (target.closest?.(".pis-datepicker-popover")) return;
|
|
4020
4040
|
if (ref.current && !ref.current.contains(target)) {
|
|
4021
4041
|
onClose();
|
|
4022
4042
|
triggerRef.current?.focus();
|
|
@@ -4051,8 +4071,12 @@ function Dropdown({ trigger, isOpen, onToggle, onClose, children, triggerClassNa
|
|
|
4051
4071
|
children: trigger
|
|
4052
4072
|
}), isOpen && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4053
4073
|
id: panelId,
|
|
4054
|
-
|
|
4055
|
-
|
|
4074
|
+
ref: panelRef,
|
|
4075
|
+
style: {
|
|
4076
|
+
...panelStyle,
|
|
4077
|
+
visibility: positioned ? "visible" : "hidden"
|
|
4078
|
+
},
|
|
4079
|
+
className: cn("w-max max-w-[calc(100vw-16px)] max-h-[280px] overflow-y-auto", "rounded-xl border border-slate-200 bg-white shadow-lg", panelClassName),
|
|
4056
4080
|
children
|
|
4057
4081
|
}), document.body)]
|
|
4058
4082
|
});
|
package/lib/index.mjs
CHANGED
|
@@ -3965,26 +3965,44 @@ function SidebarItem({ href, onClick, active = false, icon, badge, disabled = fa
|
|
|
3965
3965
|
*/
|
|
3966
3966
|
function Dropdown({ trigger, isOpen, onToggle, onClose, children, triggerClassName = "", panelClassName = "" }) {
|
|
3967
3967
|
const ref = useRef(null);
|
|
3968
|
+
const panelRef = useRef(null);
|
|
3968
3969
|
const triggerRef = useRef(null);
|
|
3969
3970
|
const panelId = `${useId().replace(/:/g, "")}-panel`;
|
|
3970
3971
|
const [panelStyle, setPanelStyle] = useState({});
|
|
3972
|
+
const [positioned, setPositioned] = useState(false);
|
|
3971
3973
|
useEffect(() => {
|
|
3972
|
-
if (!isOpen || !triggerRef.current)
|
|
3974
|
+
if (!isOpen || !triggerRef.current) {
|
|
3975
|
+
setPositioned(false);
|
|
3976
|
+
return;
|
|
3977
|
+
}
|
|
3978
|
+
const GAP = 4;
|
|
3979
|
+
const MARGIN = 8;
|
|
3973
3980
|
const updatePosition = () => {
|
|
3974
3981
|
if (!triggerRef.current) return;
|
|
3975
3982
|
const rect = triggerRef.current.getBoundingClientRect();
|
|
3983
|
+
const panelHeight = panelRef.current?.offsetHeight ?? 280;
|
|
3984
|
+
const panelWidth = panelRef.current?.offsetWidth ?? Math.max(rect.width, 180);
|
|
3985
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
3986
|
+
const spaceAbove = rect.top;
|
|
3987
|
+
const top = spaceBelow >= panelHeight + GAP + MARGIN || spaceBelow >= spaceAbove ? Math.min(rect.bottom + GAP, window.innerHeight - panelHeight - MARGIN) : Math.max(rect.top - panelHeight - GAP, MARGIN);
|
|
3988
|
+
const left = Math.max(MARGIN, Math.min(rect.left, window.innerWidth - panelWidth - MARGIN));
|
|
3976
3989
|
setPanelStyle({
|
|
3977
3990
|
position: "fixed",
|
|
3978
|
-
top:
|
|
3979
|
-
left
|
|
3980
|
-
zIndex:
|
|
3991
|
+
top: Math.max(MARGIN, top),
|
|
3992
|
+
left,
|
|
3993
|
+
zIndex: 1e3,
|
|
3981
3994
|
minWidth: Math.max(rect.width, 180)
|
|
3982
3995
|
});
|
|
3983
3996
|
};
|
|
3984
3997
|
updatePosition();
|
|
3998
|
+
const raf = requestAnimationFrame(() => {
|
|
3999
|
+
updatePosition();
|
|
4000
|
+
setPositioned(true);
|
|
4001
|
+
});
|
|
3985
4002
|
window.addEventListener("scroll", updatePosition, true);
|
|
3986
4003
|
window.addEventListener("resize", updatePosition);
|
|
3987
4004
|
return () => {
|
|
4005
|
+
cancelAnimationFrame(raf);
|
|
3988
4006
|
window.removeEventListener("scroll", updatePosition, true);
|
|
3989
4007
|
window.removeEventListener("resize", updatePosition);
|
|
3990
4008
|
};
|
|
@@ -3993,6 +4011,8 @@ function Dropdown({ trigger, isOpen, onToggle, onClose, children, triggerClassNa
|
|
|
3993
4011
|
if (!isOpen) return;
|
|
3994
4012
|
const handlePointerDown = (e) => {
|
|
3995
4013
|
const target = e.target;
|
|
4014
|
+
if (panelRef.current?.contains(target)) return;
|
|
4015
|
+
if (target.closest?.(".pis-datepicker-popover")) return;
|
|
3996
4016
|
if (ref.current && !ref.current.contains(target)) {
|
|
3997
4017
|
onClose();
|
|
3998
4018
|
triggerRef.current?.focus();
|
|
@@ -4027,8 +4047,12 @@ function Dropdown({ trigger, isOpen, onToggle, onClose, children, triggerClassNa
|
|
|
4027
4047
|
children: trigger
|
|
4028
4048
|
}), isOpen && createPortal(/* @__PURE__ */ jsx("div", {
|
|
4029
4049
|
id: panelId,
|
|
4030
|
-
|
|
4031
|
-
|
|
4050
|
+
ref: panelRef,
|
|
4051
|
+
style: {
|
|
4052
|
+
...panelStyle,
|
|
4053
|
+
visibility: positioned ? "visible" : "hidden"
|
|
4054
|
+
},
|
|
4055
|
+
className: cn("w-max max-w-[calc(100vw-16px)] max-h-[280px] overflow-y-auto", "rounded-xl border border-slate-200 bg-white shadow-lg", panelClassName),
|
|
4032
4056
|
children
|
|
4033
4057
|
}), document.body)]
|
|
4034
4058
|
});
|