@diwauhris/ui 1.7.15 → 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,27 +1424,20 @@ 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
- requestAnimationFrame(() => {
1432
+ setTimeout(() => {
1414
1433
  if (!wrapperRef.current) return;
1415
- const rect = wrapperRef.current.getBoundingClientRect();
1416
- const spaceBelow = window.innerHeight - rect.bottom;
1417
- const spaceAbove = rect.top;
1418
- const isNarrow = window.innerWidth < 368;
1419
- const style = {
1420
- position: "fixed",
1421
- left: isNarrow ? 8 : Math.max(8, Math.min(rect.left, window.innerWidth - POPOVER_WIDTH - 8)),
1422
- width: isNarrow ? `calc(100vw - 16px)` : void 0
1423
- };
1424
- if (spaceBelow >= CALENDAR_HEIGHT || spaceBelow >= spaceAbove) style.top = rect.bottom + 6;
1425
- else style.top = Math.max(8, rect.top - CALENDAR_HEIGHT - 6);
1426
- setPopupStyle(style);
1427
- setIsOpen(true);
1428
- });
1434
+ requestAnimationFrame(() => {
1435
+ if (!wrapperRef.current) return;
1436
+ const style = computePopupStyle(wrapperRef.current.getBoundingClientRect());
1437
+ setPopupStyle(style);
1438
+ setIsOpen(true);
1439
+ });
1440
+ }, 50);
1429
1441
  }, [disabled]);
1430
1442
  (0, react.useEffect)(() => {
1431
1443
  function handleClickOutside(e) {
@@ -1437,32 +1449,18 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
1437
1449
  }, []);
1438
1450
  (0, react.useEffect)(() => {
1439
1451
  if (!isOpen) return;
1440
- function getScrollParent(el) {
1441
- if (!el || el === document.body) return null;
1442
- const style = getComputedStyle(el);
1443
- if (["auto", "scroll"].includes(style.overflowY) || ["auto", "scroll"].includes(style.overflow)) return el;
1444
- return getScrollParent(el.parentElement);
1445
- }
1452
+ const close = () => setIsOpen(false);
1446
1453
  const scrollParent = getScrollParent(wrapperRef.current?.parentElement ?? null);
1447
- let scrollHandler = null;
1448
- let resizeHandler = null;
1449
- const frameId = requestAnimationFrame(() => {
1450
- scrollHandler = () => setIsOpen(false);
1451
- resizeHandler = () => setIsOpen(false);
1452
- if (scrollParent) scrollParent.addEventListener("scroll", scrollHandler, { passive: true });
1453
- window.addEventListener("scroll", scrollHandler, {
1454
- capture: true,
1455
- passive: true
1456
- });
1457
- window.addEventListener("resize", resizeHandler);
1454
+ if (scrollParent) scrollParent.addEventListener("scroll", close, { passive: true });
1455
+ window.addEventListener("scroll", close, {
1456
+ capture: true,
1457
+ passive: true
1458
1458
  });
1459
+ window.addEventListener("resize", close);
1459
1460
  return () => {
1460
- cancelAnimationFrame(frameId);
1461
- if (scrollHandler) {
1462
- if (scrollParent) scrollParent.removeEventListener("scroll", scrollHandler);
1463
- window.removeEventListener("scroll", scrollHandler, { capture: true });
1464
- }
1465
- 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);
1466
1464
  };
1467
1465
  }, [isOpen]);
1468
1466
  (0, react.useEffect)(() => {
@@ -2333,7 +2331,17 @@ function Modal({ isOpen, onClose, title, children, icon, subtitle, headerMeta, f
2333
2331
  onOpenAutoFocus,
2334
2332
  onCloseAutoFocus,
2335
2333
  onEscapeKeyDown: preventClose ? (e) => e.preventDefault() : onEscapeKeyDown,
2336
- 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
+ },
2337
2345
  children: [
2338
2346
  !preventClose && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_dialog.Close, {
2339
2347
  asChild: true,
@@ -2447,7 +2455,17 @@ function Dialog({ open, onClose, title, description, preventClose = false, size
2447
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, {
2448
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"),
2449
2457
  onEscapeKeyDown: preventClose ? (e) => e.preventDefault() : onEscapeKeyDown,
2450
- 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
+ },
2451
2469
  onOpenAutoFocus,
2452
2470
  onCloseAutoFocus,
2453
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,27 +1400,20 @@ 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
- requestAnimationFrame(() => {
1408
+ setTimeout(() => {
1390
1409
  if (!wrapperRef.current) return;
1391
- const rect = wrapperRef.current.getBoundingClientRect();
1392
- const spaceBelow = window.innerHeight - rect.bottom;
1393
- const spaceAbove = rect.top;
1394
- const isNarrow = window.innerWidth < 368;
1395
- const style = {
1396
- position: "fixed",
1397
- left: isNarrow ? 8 : Math.max(8, Math.min(rect.left, window.innerWidth - POPOVER_WIDTH - 8)),
1398
- width: isNarrow ? `calc(100vw - 16px)` : void 0
1399
- };
1400
- if (spaceBelow >= CALENDAR_HEIGHT || spaceBelow >= spaceAbove) style.top = rect.bottom + 6;
1401
- else style.top = Math.max(8, rect.top - CALENDAR_HEIGHT - 6);
1402
- setPopupStyle(style);
1403
- setIsOpen(true);
1404
- });
1410
+ requestAnimationFrame(() => {
1411
+ if (!wrapperRef.current) return;
1412
+ const style = computePopupStyle(wrapperRef.current.getBoundingClientRect());
1413
+ setPopupStyle(style);
1414
+ setIsOpen(true);
1415
+ });
1416
+ }, 50);
1405
1417
  }, [disabled]);
1406
1418
  useEffect(() => {
1407
1419
  function handleClickOutside(e) {
@@ -1413,32 +1425,18 @@ function DatePicker({ value, onChange, placeholder, className, disabled, error,
1413
1425
  }, []);
1414
1426
  useEffect(() => {
1415
1427
  if (!isOpen) return;
1416
- function getScrollParent(el) {
1417
- if (!el || el === document.body) return null;
1418
- const style = getComputedStyle(el);
1419
- if (["auto", "scroll"].includes(style.overflowY) || ["auto", "scroll"].includes(style.overflow)) return el;
1420
- return getScrollParent(el.parentElement);
1421
- }
1428
+ const close = () => setIsOpen(false);
1422
1429
  const scrollParent = getScrollParent(wrapperRef.current?.parentElement ?? null);
1423
- let scrollHandler = null;
1424
- let resizeHandler = null;
1425
- const frameId = requestAnimationFrame(() => {
1426
- scrollHandler = () => setIsOpen(false);
1427
- resizeHandler = () => setIsOpen(false);
1428
- if (scrollParent) scrollParent.addEventListener("scroll", scrollHandler, { passive: true });
1429
- window.addEventListener("scroll", scrollHandler, {
1430
- capture: true,
1431
- passive: true
1432
- });
1433
- window.addEventListener("resize", resizeHandler);
1430
+ if (scrollParent) scrollParent.addEventListener("scroll", close, { passive: true });
1431
+ window.addEventListener("scroll", close, {
1432
+ capture: true,
1433
+ passive: true
1434
1434
  });
1435
+ window.addEventListener("resize", close);
1435
1436
  return () => {
1436
- cancelAnimationFrame(frameId);
1437
- if (scrollHandler) {
1438
- if (scrollParent) scrollParent.removeEventListener("scroll", scrollHandler);
1439
- window.removeEventListener("scroll", scrollHandler, { capture: true });
1440
- }
1441
- 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);
1442
1440
  };
1443
1441
  }, [isOpen]);
1444
1442
  useEffect(() => {
@@ -2309,7 +2307,17 @@ function Modal({ isOpen, onClose, title, children, icon, subtitle, headerMeta, f
2309
2307
  onOpenAutoFocus,
2310
2308
  onCloseAutoFocus,
2311
2309
  onEscapeKeyDown: preventClose ? (e) => e.preventDefault() : onEscapeKeyDown,
2312
- 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
+ },
2313
2321
  children: [
2314
2322
  !preventClose && /* @__PURE__ */ jsx(DialogPrimitive.Close, {
2315
2323
  asChild: true,
@@ -2423,7 +2431,17 @@ function Dialog({ open, onClose, title, description, preventClose = false, size
2423
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, {
2424
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"),
2425
2433
  onEscapeKeyDown: preventClose ? (e) => e.preventDefault() : onEscapeKeyDown,
2426
- 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
+ },
2427
2445
  onOpenAutoFocus,
2428
2446
  onCloseAutoFocus,
2429
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.15",
4
+ "version": "1.7.17",
5
5
  "type": "module",
6
6
  "description": "DIWA UHRIS UI component library — React + Tailwind CSS",
7
7
  "keywords": [