@diwauhris/ui 1.7.16 → 1.7.17

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 CHANGED
@@ -4410,8 +4410,8 @@ body {
4410
4410
 
4411
4411
  /* ── Date Picker (react-calendar DIWA theme) ─────────────────────────────── */
4412
4412
  .pis-datepicker-popover {
4413
- position: absolute;
4414
4413
  z-index: 1050;
4414
+ pointer-events: auto;
4415
4415
  margin-top: 6px;
4416
4416
  background: #fff;
4417
4417
  border: 1px solid #dde3ec;
package/lib/index.cjs CHANGED
@@ -1384,6 +1384,25 @@ function Combobox({ value: controlledValue, defaultValue = "", onChange, options
1384
1384
  */
1385
1385
  var POPOVER_WIDTH = 352;
1386
1386
  var CALENDAR_HEIGHT = 360;
1387
+ function getScrollParent(el) {
1388
+ if (!el || el === document.body) return null;
1389
+ const { overflowY, overflow } = getComputedStyle(el);
1390
+ if (["auto", "scroll"].includes(overflowY) || ["auto", "scroll"].includes(overflow)) return el;
1391
+ return getScrollParent(el.parentElement);
1392
+ }
1393
+ function computePopupStyle(rect) {
1394
+ const spaceBelow = window.innerHeight - rect.bottom;
1395
+ const spaceAbove = rect.top;
1396
+ const isNarrow = window.innerWidth < 368;
1397
+ const style = {
1398
+ position: "fixed",
1399
+ left: isNarrow ? 8 : Math.max(8, Math.min(rect.left, window.innerWidth - POPOVER_WIDTH - 8)),
1400
+ width: isNarrow ? `calc(100vw - 16px)` : void 0
1401
+ };
1402
+ if (spaceAbove > spaceBelow && spaceBelow < CALENDAR_HEIGHT / 3) style.top = Math.max(8, rect.top - CALENDAR_HEIGHT - 6);
1403
+ else style.top = rect.bottom + 6;
1404
+ return style;
1405
+ }
1387
1406
  function DatePicker({ value, onChange, placeholder, className, disabled, error, minDate, maxDate, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, required }) {
1388
1407
  const [isOpen, setIsOpen] = (0, react.useState)(false);
1389
1408
  const [popupStyle, setPopupStyle] = (0, react.useState)({});
@@ -1405,46 +1424,21 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
1405
1424
  const displayValue = selectedDate ? (0, date_fns.format)(selectedDate, "MMM d, yyyy") : "";
1406
1425
  const skipNextOpen = (0, react.useRef)(false);
1407
1426
  const openPopup = (0, react.useCallback)(() => {
1408
- if (disabled || !wrapperRef.current) return;
1427
+ if (disabled) return;
1409
1428
  if (skipNextOpen.current) {
1410
1429
  skipNextOpen.current = false;
1411
1430
  return;
1412
1431
  }
1413
- setPopupStyle({
1414
- position: "fixed",
1415
- top: -9999,
1416
- left: -9999,
1417
- visibility: "hidden"
1418
- });
1419
- setIsOpen(true);
1420
- }, [disabled]);
1421
- (0, react.useEffect)(() => {
1422
- if (!isOpen || !wrapperRef.current) return;
1423
- let frameId1;
1424
- let frameId2;
1425
- frameId1 = requestAnimationFrame(() => {
1426
- frameId2 = requestAnimationFrame(() => {
1432
+ setTimeout(() => {
1433
+ if (!wrapperRef.current) return;
1434
+ requestAnimationFrame(() => {
1427
1435
  if (!wrapperRef.current) return;
1428
- const rect = wrapperRef.current.getBoundingClientRect();
1429
- const spaceBelow = window.innerHeight - rect.bottom;
1430
- const spaceAbove = rect.top;
1431
- const isNarrow = window.innerWidth < 368;
1432
- const style = {
1433
- position: "fixed",
1434
- visibility: "visible",
1435
- left: isNarrow ? 8 : Math.max(8, Math.min(rect.left, window.innerWidth - POPOVER_WIDTH - 8)),
1436
- width: isNarrow ? `calc(100vw - 16px)` : void 0
1437
- };
1438
- if (spaceBelow >= CALENDAR_HEIGHT || spaceBelow >= spaceAbove) style.top = rect.bottom + 6;
1439
- else style.top = Math.max(8, rect.top - CALENDAR_HEIGHT - 6);
1436
+ const style = computePopupStyle(wrapperRef.current.getBoundingClientRect());
1440
1437
  setPopupStyle(style);
1438
+ setIsOpen(true);
1441
1439
  });
1442
- });
1443
- return () => {
1444
- cancelAnimationFrame(frameId1);
1445
- cancelAnimationFrame(frameId2);
1446
- };
1447
- }, [isOpen]);
1440
+ }, 50);
1441
+ }, [disabled]);
1448
1442
  (0, react.useEffect)(() => {
1449
1443
  function handleClickOutside(e) {
1450
1444
  const target = e.target;
@@ -1455,32 +1449,18 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
1455
1449
  }, []);
1456
1450
  (0, react.useEffect)(() => {
1457
1451
  if (!isOpen) return;
1458
- function getScrollParent(el) {
1459
- if (!el || el === document.body) return null;
1460
- const style = getComputedStyle(el);
1461
- if (["auto", "scroll"].includes(style.overflowY) || ["auto", "scroll"].includes(style.overflow)) return el;
1462
- return getScrollParent(el.parentElement);
1463
- }
1452
+ const close = () => setIsOpen(false);
1464
1453
  const scrollParent = getScrollParent(wrapperRef.current?.parentElement ?? null);
1465
- let scrollHandler = null;
1466
- let resizeHandler = null;
1467
- const frameId = requestAnimationFrame(() => {
1468
- scrollHandler = () => setIsOpen(false);
1469
- resizeHandler = () => setIsOpen(false);
1470
- if (scrollParent) scrollParent.addEventListener("scroll", scrollHandler, { passive: true });
1471
- window.addEventListener("scroll", scrollHandler, {
1472
- capture: true,
1473
- passive: true
1474
- });
1475
- window.addEventListener("resize", resizeHandler);
1454
+ if (scrollParent) scrollParent.addEventListener("scroll", close, { passive: true });
1455
+ window.addEventListener("scroll", close, {
1456
+ capture: true,
1457
+ passive: true
1476
1458
  });
1459
+ window.addEventListener("resize", close);
1477
1460
  return () => {
1478
- cancelAnimationFrame(frameId);
1479
- if (scrollHandler) {
1480
- if (scrollParent) scrollParent.removeEventListener("scroll", scrollHandler);
1481
- window.removeEventListener("scroll", scrollHandler, { capture: true });
1482
- }
1483
- if (resizeHandler) window.removeEventListener("resize", resizeHandler);
1461
+ if (scrollParent) scrollParent.removeEventListener("scroll", close);
1462
+ window.removeEventListener("scroll", close, { capture: true });
1463
+ window.removeEventListener("resize", close);
1484
1464
  };
1485
1465
  }, [isOpen]);
1486
1466
  (0, react.useEffect)(() => {
@@ -2351,7 +2331,17 @@ function Modal({ isOpen, onClose, title, children, icon, subtitle, headerMeta, f
2351
2331
  onOpenAutoFocus,
2352
2332
  onCloseAutoFocus,
2353
2333
  onEscapeKeyDown: preventClose ? (e) => e.preventDefault() : onEscapeKeyDown,
2354
- onInteractOutside: preventClose ? (e) => e.preventDefault() : onInteractOutside,
2334
+ onInteractOutside: (e) => {
2335
+ if (e.target?.closest(".pis-datepicker-popover")) {
2336
+ e.preventDefault();
2337
+ return;
2338
+ }
2339
+ if (preventClose) {
2340
+ e.preventDefault();
2341
+ return;
2342
+ }
2343
+ onInteractOutside?.(e);
2344
+ },
2355
2345
  children: [
2356
2346
  !preventClose && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_dialog.Close, {
2357
2347
  asChild: true,
@@ -2465,7 +2455,17 @@ function Dialog({ open, onClose, title, description, preventClose = false, size
2465
2455
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_radix_ui_react_dialog.Portal, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_dialog.Overlay, { className: "fixed inset-0 z-50 bg-brand-navy/50 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0 duration-200" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_radix_ui_react_dialog.Content, {
2466
2456
  className: cn("fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2", "flex w-full flex-col overflow-hidden", "rounded-lg bg-white shadow-xl", "max-h-[90vh] outline-none", SIZE_CLASS[size], "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0", "data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95", "duration-200"),
2467
2457
  onEscapeKeyDown: preventClose ? (e) => e.preventDefault() : onEscapeKeyDown,
2468
- onInteractOutside: preventClose ? (e) => e.preventDefault() : onInteractOutside,
2458
+ onInteractOutside: (e) => {
2459
+ if (e.target?.closest(".pis-datepicker-popover")) {
2460
+ e.preventDefault();
2461
+ return;
2462
+ }
2463
+ if (preventClose) {
2464
+ e.preventDefault();
2465
+ return;
2466
+ }
2467
+ onInteractOutside?.(e);
2468
+ },
2469
2469
  onOpenAutoFocus,
2470
2470
  onCloseAutoFocus,
2471
2471
  style: { padding: 0 },
package/lib/index.mjs CHANGED
@@ -1360,6 +1360,25 @@ function Combobox({ value: controlledValue, defaultValue = "", onChange, options
1360
1360
  */
1361
1361
  var POPOVER_WIDTH = 352;
1362
1362
  var CALENDAR_HEIGHT = 360;
1363
+ function getScrollParent(el) {
1364
+ if (!el || el === document.body) return null;
1365
+ const { overflowY, overflow } = getComputedStyle(el);
1366
+ if (["auto", "scroll"].includes(overflowY) || ["auto", "scroll"].includes(overflow)) return el;
1367
+ return getScrollParent(el.parentElement);
1368
+ }
1369
+ function computePopupStyle(rect) {
1370
+ const spaceBelow = window.innerHeight - rect.bottom;
1371
+ const spaceAbove = rect.top;
1372
+ const isNarrow = window.innerWidth < 368;
1373
+ const style = {
1374
+ position: "fixed",
1375
+ left: isNarrow ? 8 : Math.max(8, Math.min(rect.left, window.innerWidth - POPOVER_WIDTH - 8)),
1376
+ width: isNarrow ? `calc(100vw - 16px)` : void 0
1377
+ };
1378
+ if (spaceAbove > spaceBelow && spaceBelow < CALENDAR_HEIGHT / 3) style.top = Math.max(8, rect.top - CALENDAR_HEIGHT - 6);
1379
+ else style.top = rect.bottom + 6;
1380
+ return style;
1381
+ }
1363
1382
  function DatePicker({ value, onChange, placeholder, className, disabled, error, minDate, maxDate, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, required }) {
1364
1383
  const [isOpen, setIsOpen] = useState(false);
1365
1384
  const [popupStyle, setPopupStyle] = useState({});
@@ -1381,46 +1400,21 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
1381
1400
  const displayValue = selectedDate ? format(selectedDate, "MMM d, yyyy") : "";
1382
1401
  const skipNextOpen = useRef(false);
1383
1402
  const openPopup = useCallback(() => {
1384
- if (disabled || !wrapperRef.current) return;
1403
+ if (disabled) return;
1385
1404
  if (skipNextOpen.current) {
1386
1405
  skipNextOpen.current = false;
1387
1406
  return;
1388
1407
  }
1389
- setPopupStyle({
1390
- position: "fixed",
1391
- top: -9999,
1392
- left: -9999,
1393
- visibility: "hidden"
1394
- });
1395
- setIsOpen(true);
1396
- }, [disabled]);
1397
- useEffect(() => {
1398
- if (!isOpen || !wrapperRef.current) return;
1399
- let frameId1;
1400
- let frameId2;
1401
- frameId1 = requestAnimationFrame(() => {
1402
- frameId2 = requestAnimationFrame(() => {
1408
+ setTimeout(() => {
1409
+ if (!wrapperRef.current) return;
1410
+ requestAnimationFrame(() => {
1403
1411
  if (!wrapperRef.current) return;
1404
- const rect = wrapperRef.current.getBoundingClientRect();
1405
- const spaceBelow = window.innerHeight - rect.bottom;
1406
- const spaceAbove = rect.top;
1407
- const isNarrow = window.innerWidth < 368;
1408
- const style = {
1409
- position: "fixed",
1410
- visibility: "visible",
1411
- left: isNarrow ? 8 : Math.max(8, Math.min(rect.left, window.innerWidth - POPOVER_WIDTH - 8)),
1412
- width: isNarrow ? `calc(100vw - 16px)` : void 0
1413
- };
1414
- if (spaceBelow >= CALENDAR_HEIGHT || spaceBelow >= spaceAbove) style.top = rect.bottom + 6;
1415
- else style.top = Math.max(8, rect.top - CALENDAR_HEIGHT - 6);
1412
+ const style = computePopupStyle(wrapperRef.current.getBoundingClientRect());
1416
1413
  setPopupStyle(style);
1414
+ setIsOpen(true);
1417
1415
  });
1418
- });
1419
- return () => {
1420
- cancelAnimationFrame(frameId1);
1421
- cancelAnimationFrame(frameId2);
1422
- };
1423
- }, [isOpen]);
1416
+ }, 50);
1417
+ }, [disabled]);
1424
1418
  useEffect(() => {
1425
1419
  function handleClickOutside(e) {
1426
1420
  const target = e.target;
@@ -1431,32 +1425,18 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
1431
1425
  }, []);
1432
1426
  useEffect(() => {
1433
1427
  if (!isOpen) return;
1434
- function getScrollParent(el) {
1435
- if (!el || el === document.body) return null;
1436
- const style = getComputedStyle(el);
1437
- if (["auto", "scroll"].includes(style.overflowY) || ["auto", "scroll"].includes(style.overflow)) return el;
1438
- return getScrollParent(el.parentElement);
1439
- }
1428
+ const close = () => setIsOpen(false);
1440
1429
  const scrollParent = getScrollParent(wrapperRef.current?.parentElement ?? null);
1441
- let scrollHandler = null;
1442
- let resizeHandler = null;
1443
- const frameId = requestAnimationFrame(() => {
1444
- scrollHandler = () => setIsOpen(false);
1445
- resizeHandler = () => setIsOpen(false);
1446
- if (scrollParent) scrollParent.addEventListener("scroll", scrollHandler, { passive: true });
1447
- window.addEventListener("scroll", scrollHandler, {
1448
- capture: true,
1449
- passive: true
1450
- });
1451
- window.addEventListener("resize", resizeHandler);
1430
+ if (scrollParent) scrollParent.addEventListener("scroll", close, { passive: true });
1431
+ window.addEventListener("scroll", close, {
1432
+ capture: true,
1433
+ passive: true
1452
1434
  });
1435
+ window.addEventListener("resize", close);
1453
1436
  return () => {
1454
- cancelAnimationFrame(frameId);
1455
- if (scrollHandler) {
1456
- if (scrollParent) scrollParent.removeEventListener("scroll", scrollHandler);
1457
- window.removeEventListener("scroll", scrollHandler, { capture: true });
1458
- }
1459
- if (resizeHandler) window.removeEventListener("resize", resizeHandler);
1437
+ if (scrollParent) scrollParent.removeEventListener("scroll", close);
1438
+ window.removeEventListener("scroll", close, { capture: true });
1439
+ window.removeEventListener("resize", close);
1460
1440
  };
1461
1441
  }, [isOpen]);
1462
1442
  useEffect(() => {
@@ -2327,7 +2307,17 @@ function Modal({ isOpen, onClose, title, children, icon, subtitle, headerMeta, f
2327
2307
  onOpenAutoFocus,
2328
2308
  onCloseAutoFocus,
2329
2309
  onEscapeKeyDown: preventClose ? (e) => e.preventDefault() : onEscapeKeyDown,
2330
- onInteractOutside: preventClose ? (e) => e.preventDefault() : onInteractOutside,
2310
+ onInteractOutside: (e) => {
2311
+ if (e.target?.closest(".pis-datepicker-popover")) {
2312
+ e.preventDefault();
2313
+ return;
2314
+ }
2315
+ if (preventClose) {
2316
+ e.preventDefault();
2317
+ return;
2318
+ }
2319
+ onInteractOutside?.(e);
2320
+ },
2331
2321
  children: [
2332
2322
  !preventClose && /* @__PURE__ */ jsx(DialogPrimitive.Close, {
2333
2323
  asChild: true,
@@ -2441,7 +2431,17 @@ function Dialog({ open, onClose, title, description, preventClose = false, size
2441
2431
  children: /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [/* @__PURE__ */ jsx(DialogPrimitive.Overlay, { className: "fixed inset-0 z-50 bg-brand-navy/50 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0 duration-200" }), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
2442
2432
  className: cn("fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2", "flex w-full flex-col overflow-hidden", "rounded-lg bg-white shadow-xl", "max-h-[90vh] outline-none", SIZE_CLASS[size], "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0", "data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95", "duration-200"),
2443
2433
  onEscapeKeyDown: preventClose ? (e) => e.preventDefault() : onEscapeKeyDown,
2444
- onInteractOutside: preventClose ? (e) => e.preventDefault() : onInteractOutside,
2434
+ onInteractOutside: (e) => {
2435
+ if (e.target?.closest(".pis-datepicker-popover")) {
2436
+ e.preventDefault();
2437
+ return;
2438
+ }
2439
+ if (preventClose) {
2440
+ e.preventDefault();
2441
+ return;
2442
+ }
2443
+ onInteractOutside?.(e);
2444
+ },
2445
2445
  onOpenAutoFocus,
2446
2446
  onCloseAutoFocus,
2447
2447
  style: { padding: 0 },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@diwauhris/ui",
3
3
  "private": false,
4
- "version": "1.7.16",
4
+ "version": "1.7.17",
5
5
  "type": "module",
6
6
  "description": "DIWA UHRIS UI component library — React + Tailwind CSS",
7
7
  "keywords": [