@diwauhris/ui 1.7.25 → 1.7.27
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 +6 -0
- package/lib/index.cjs +30 -11
- package/lib/index.mjs +31 -12
- package/package.json +1 -1
package/lib/assets/ui.css
CHANGED
|
@@ -4442,6 +4442,12 @@ body {
|
|
|
4442
4442
|
animation: datepickerIn 0.2s cubic-bezier(0.16, 1, 0.3, 1);
|
|
4443
4443
|
overflow: hidden;
|
|
4444
4444
|
}
|
|
4445
|
+
/* Hidden during initial measurement — no animation until final position is set */
|
|
4446
|
+
.pis-datepicker-popover--measuring {
|
|
4447
|
+
opacity: 0;
|
|
4448
|
+
pointer-events: none;
|
|
4449
|
+
animation: none;
|
|
4450
|
+
}
|
|
4445
4451
|
@keyframes datepickerIn {
|
|
4446
4452
|
from { opacity: 0; transform: translateY(6px) scale(0.97); }
|
|
4447
4453
|
to { opacity: 1; transform: translateY(0) scale(1); }
|
package/lib/index.cjs
CHANGED
|
@@ -1417,6 +1417,7 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
|
|
|
1417
1417
|
const [uncontrolledOpen, setUncontrolledOpen] = (0, react.useState)(defaultOpen);
|
|
1418
1418
|
const isOpen = isControlled ? open : uncontrolledOpen;
|
|
1419
1419
|
const [popupStyle, setPopupStyle] = (0, react.useState)({});
|
|
1420
|
+
const [positioned, setPositioned] = (0, react.useState)(false);
|
|
1420
1421
|
const wrapperRef = (0, react.useRef)(null);
|
|
1421
1422
|
const popoverRef = (0, react.useRef)(null);
|
|
1422
1423
|
const inputRef = (0, react.useRef)(null);
|
|
@@ -1456,6 +1457,7 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
|
|
|
1456
1457
|
if (!wrapperRef.current) return;
|
|
1457
1458
|
const style = computePopupStyle(wrapperRef.current.getBoundingClientRect(), placement);
|
|
1458
1459
|
setPopupStyle(style);
|
|
1460
|
+
setPositioned(false);
|
|
1459
1461
|
setIsOpen(true);
|
|
1460
1462
|
});
|
|
1461
1463
|
}, 50);
|
|
@@ -1465,11 +1467,16 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
|
|
|
1465
1467
|
placement,
|
|
1466
1468
|
setIsOpen
|
|
1467
1469
|
]);
|
|
1468
|
-
(0, react.
|
|
1469
|
-
if (!isOpen
|
|
1470
|
+
(0, react.useLayoutEffect)(() => {
|
|
1471
|
+
if (!isOpen) {
|
|
1472
|
+
setPositioned(false);
|
|
1473
|
+
return;
|
|
1474
|
+
}
|
|
1475
|
+
if (!popoverRef.current || !wrapperRef.current) return;
|
|
1470
1476
|
const measuredHeight = popoverRef.current.offsetHeight;
|
|
1471
1477
|
const rect = wrapperRef.current.getBoundingClientRect();
|
|
1472
1478
|
setPopupStyle(computePopupStyle(rect, placement, measuredHeight));
|
|
1479
|
+
setPositioned(true);
|
|
1473
1480
|
}, [isOpen, placement]);
|
|
1474
1481
|
(0, react.useEffect)(() => {
|
|
1475
1482
|
function handleClickOutside(e) {
|
|
@@ -1478,23 +1485,35 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
|
|
|
1478
1485
|
}
|
|
1479
1486
|
document.addEventListener("mousedown", handleClickOutside);
|
|
1480
1487
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1481
|
-
}, []);
|
|
1488
|
+
}, [setIsOpen]);
|
|
1482
1489
|
(0, react.useEffect)(() => {
|
|
1483
|
-
if (!isOpen) return;
|
|
1490
|
+
if (!isOpen || !positioned) return;
|
|
1491
|
+
let armed = false;
|
|
1492
|
+
const armTimer = window.setTimeout(() => {
|
|
1493
|
+
armed = true;
|
|
1494
|
+
}, 150);
|
|
1484
1495
|
const close = () => setIsOpen(false);
|
|
1496
|
+
const onScroll = () => {
|
|
1497
|
+
if (armed) setIsOpen(false);
|
|
1498
|
+
};
|
|
1485
1499
|
const scrollParent = getScrollParent(wrapperRef.current?.parentElement ?? null);
|
|
1486
|
-
if (scrollParent) scrollParent.addEventListener("scroll",
|
|
1487
|
-
window.addEventListener("scroll",
|
|
1500
|
+
if (scrollParent) scrollParent.addEventListener("scroll", onScroll, { passive: true });
|
|
1501
|
+
window.addEventListener("scroll", onScroll, {
|
|
1488
1502
|
capture: true,
|
|
1489
1503
|
passive: true
|
|
1490
1504
|
});
|
|
1491
1505
|
window.addEventListener("resize", close);
|
|
1492
1506
|
return () => {
|
|
1493
|
-
|
|
1494
|
-
|
|
1507
|
+
window.clearTimeout(armTimer);
|
|
1508
|
+
if (scrollParent) scrollParent.removeEventListener("scroll", onScroll);
|
|
1509
|
+
window.removeEventListener("scroll", onScroll, { capture: true });
|
|
1495
1510
|
window.removeEventListener("resize", close);
|
|
1496
1511
|
};
|
|
1497
|
-
}, [
|
|
1512
|
+
}, [
|
|
1513
|
+
isOpen,
|
|
1514
|
+
positioned,
|
|
1515
|
+
setIsOpen
|
|
1516
|
+
]);
|
|
1498
1517
|
(0, react.useEffect)(() => {
|
|
1499
1518
|
if (!isOpen) return;
|
|
1500
1519
|
function handleFocusOut(e) {
|
|
@@ -1505,7 +1524,7 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
|
|
|
1505
1524
|
const wrapper = wrapperRef.current;
|
|
1506
1525
|
wrapper?.addEventListener("focusout", handleFocusOut);
|
|
1507
1526
|
return () => wrapper?.removeEventListener("focusout", handleFocusOut);
|
|
1508
|
-
}, [isOpen]);
|
|
1527
|
+
}, [isOpen, setIsOpen]);
|
|
1509
1528
|
function handleKeyDown(e) {
|
|
1510
1529
|
if (e.key === "Escape") {
|
|
1511
1530
|
e.preventDefault();
|
|
@@ -1568,7 +1587,7 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
|
|
|
1568
1587
|
})]
|
|
1569
1588
|
}), isOpen && !disabled && !readOnly && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1570
1589
|
ref: popoverRef,
|
|
1571
|
-
className: "pis-datepicker-popover",
|
|
1590
|
+
className: cn("pis-datepicker-popover", !positioned && "pis-datepicker-popover--measuring"),
|
|
1572
1591
|
style: popupStyle,
|
|
1573
1592
|
role: "dialog",
|
|
1574
1593
|
"aria-label": ariaLabel ? `${ariaLabel} calendar` : "Date picker",
|
package/lib/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { clsx } from "clsx";
|
|
2
2
|
import { twMerge } from "tailwind-merge";
|
|
3
3
|
import * as React$1 from "react";
|
|
4
|
-
import React, { cloneElement, createContext, createElement, isValidElement, use, useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
4
|
+
import React, { cloneElement, createContext, createElement, isValidElement, use, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { createPortal } from "react-dom";
|
|
7
7
|
import { AlertCircle, AlertTriangle, Archive, ArchiveRestore, ArrowDown, Ban, CalendarDays, Check, CheckCircle2, ChevronDown, ChevronLeft, ChevronRight, Clock, Command, File, Home, Info, Minus, RotateCcw, Search as Search$1, ShieldCheck, TrendingDown, TrendingUp, UploadCloud, X, ZoomIn, ZoomOut } from "lucide-react";
|
|
@@ -1393,6 +1393,7 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
|
|
|
1393
1393
|
const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
|
|
1394
1394
|
const isOpen = isControlled ? open : uncontrolledOpen;
|
|
1395
1395
|
const [popupStyle, setPopupStyle] = useState({});
|
|
1396
|
+
const [positioned, setPositioned] = useState(false);
|
|
1396
1397
|
const wrapperRef = useRef(null);
|
|
1397
1398
|
const popoverRef = useRef(null);
|
|
1398
1399
|
const inputRef = useRef(null);
|
|
@@ -1432,6 +1433,7 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
|
|
|
1432
1433
|
if (!wrapperRef.current) return;
|
|
1433
1434
|
const style = computePopupStyle(wrapperRef.current.getBoundingClientRect(), placement);
|
|
1434
1435
|
setPopupStyle(style);
|
|
1436
|
+
setPositioned(false);
|
|
1435
1437
|
setIsOpen(true);
|
|
1436
1438
|
});
|
|
1437
1439
|
}, 50);
|
|
@@ -1441,11 +1443,16 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
|
|
|
1441
1443
|
placement,
|
|
1442
1444
|
setIsOpen
|
|
1443
1445
|
]);
|
|
1444
|
-
|
|
1445
|
-
if (!isOpen
|
|
1446
|
+
useLayoutEffect(() => {
|
|
1447
|
+
if (!isOpen) {
|
|
1448
|
+
setPositioned(false);
|
|
1449
|
+
return;
|
|
1450
|
+
}
|
|
1451
|
+
if (!popoverRef.current || !wrapperRef.current) return;
|
|
1446
1452
|
const measuredHeight = popoverRef.current.offsetHeight;
|
|
1447
1453
|
const rect = wrapperRef.current.getBoundingClientRect();
|
|
1448
1454
|
setPopupStyle(computePopupStyle(rect, placement, measuredHeight));
|
|
1455
|
+
setPositioned(true);
|
|
1449
1456
|
}, [isOpen, placement]);
|
|
1450
1457
|
useEffect(() => {
|
|
1451
1458
|
function handleClickOutside(e) {
|
|
@@ -1454,23 +1461,35 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
|
|
|
1454
1461
|
}
|
|
1455
1462
|
document.addEventListener("mousedown", handleClickOutside);
|
|
1456
1463
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1457
|
-
}, []);
|
|
1464
|
+
}, [setIsOpen]);
|
|
1458
1465
|
useEffect(() => {
|
|
1459
|
-
if (!isOpen) return;
|
|
1466
|
+
if (!isOpen || !positioned) return;
|
|
1467
|
+
let armed = false;
|
|
1468
|
+
const armTimer = window.setTimeout(() => {
|
|
1469
|
+
armed = true;
|
|
1470
|
+
}, 150);
|
|
1460
1471
|
const close = () => setIsOpen(false);
|
|
1472
|
+
const onScroll = () => {
|
|
1473
|
+
if (armed) setIsOpen(false);
|
|
1474
|
+
};
|
|
1461
1475
|
const scrollParent = getScrollParent(wrapperRef.current?.parentElement ?? null);
|
|
1462
|
-
if (scrollParent) scrollParent.addEventListener("scroll",
|
|
1463
|
-
window.addEventListener("scroll",
|
|
1476
|
+
if (scrollParent) scrollParent.addEventListener("scroll", onScroll, { passive: true });
|
|
1477
|
+
window.addEventListener("scroll", onScroll, {
|
|
1464
1478
|
capture: true,
|
|
1465
1479
|
passive: true
|
|
1466
1480
|
});
|
|
1467
1481
|
window.addEventListener("resize", close);
|
|
1468
1482
|
return () => {
|
|
1469
|
-
|
|
1470
|
-
|
|
1483
|
+
window.clearTimeout(armTimer);
|
|
1484
|
+
if (scrollParent) scrollParent.removeEventListener("scroll", onScroll);
|
|
1485
|
+
window.removeEventListener("scroll", onScroll, { capture: true });
|
|
1471
1486
|
window.removeEventListener("resize", close);
|
|
1472
1487
|
};
|
|
1473
|
-
}, [
|
|
1488
|
+
}, [
|
|
1489
|
+
isOpen,
|
|
1490
|
+
positioned,
|
|
1491
|
+
setIsOpen
|
|
1492
|
+
]);
|
|
1474
1493
|
useEffect(() => {
|
|
1475
1494
|
if (!isOpen) return;
|
|
1476
1495
|
function handleFocusOut(e) {
|
|
@@ -1481,7 +1500,7 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
|
|
|
1481
1500
|
const wrapper = wrapperRef.current;
|
|
1482
1501
|
wrapper?.addEventListener("focusout", handleFocusOut);
|
|
1483
1502
|
return () => wrapper?.removeEventListener("focusout", handleFocusOut);
|
|
1484
|
-
}, [isOpen]);
|
|
1503
|
+
}, [isOpen, setIsOpen]);
|
|
1485
1504
|
function handleKeyDown(e) {
|
|
1486
1505
|
if (e.key === "Escape") {
|
|
1487
1506
|
e.preventDefault();
|
|
@@ -1544,7 +1563,7 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
|
|
|
1544
1563
|
})]
|
|
1545
1564
|
}), isOpen && !disabled && !readOnly && createPortal(/* @__PURE__ */ jsx("div", {
|
|
1546
1565
|
ref: popoverRef,
|
|
1547
|
-
className: "pis-datepicker-popover",
|
|
1566
|
+
className: cn("pis-datepicker-popover", !positioned && "pis-datepicker-popover--measuring"),
|
|
1548
1567
|
style: popupStyle,
|
|
1549
1568
|
role: "dialog",
|
|
1550
1569
|
"aria-label": ariaLabel ? `${ariaLabel} calendar` : "Date picker",
|