@andreagiugni/tailwind-dashboard-ui 0.5.17 → 0.5.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/README.md CHANGED
@@ -167,7 +167,7 @@ Legend: **(+native)** = also extends the element's native HTML attributes.
167
167
  | `Alert` | `variant` (success/error/warning/info), `title`, `message`, `showLink`, `linkHref`, `linkText`, `icon?` (override icon), (+native div) |
168
168
  | `Avatar` | `src`, `alt`, `size` (xsmall…xxlarge), `status` (online/offline/busy/none), `statusColor?`, (+native img) |
169
169
  | `AvatarText` | `children`, `className`, (+native div) |
170
- | `Dropdown` | `isOpen`, `onClose`, `children`, `portal?` (default `true`, prevents clipping inside tables/overflow containers), (+native div) |
170
+ | `Dropdown` | `isOpen`, `onClose`, `children`, `portal?` (default `true`, prevents clipping inside cards/tables/overflow containers), `triggerRef?` (optional custom trigger anchor), (+native div) |
171
171
  | `DropdownItem` | `variant` (default/primary/outline, like Button), `icon?`, `bgColor`/`textColor`/`borderColor` overrides, `tag` (a/button), `href`, `onClick`, `onItemClick`, `baseClassName` (full override) |
172
172
  | `Modal` | `isOpen`, `onClose`, `title?` (wrapping header aligned with close button), `showCloseButton`, `isFullscreen`, `closeOnBackdrop?`, `closeOnEsc?`; **alert preset** → `variant` (`success`/`info`/`warning`/`danger`) + `title`, `description`, `actionText?`, `onAction?`; (+native div) |
173
173
  | `Table` (composable) | `TableHeader` / `TableBody` / `TableRow` / `TableCell` with `children`, `isHeader` (cell), (+native table elements; `onClick` / `onDoubleClick` on rows & cells) |
package/dist/index.cjs CHANGED
@@ -416,12 +416,20 @@ var AvatarText = ({
416
416
  }
417
417
  );
418
418
  };
419
+ function getTriggerElement(anchor, triggerRef) {
420
+ if (triggerRef?.current) return triggerRef.current;
421
+ if (!anchor) return null;
422
+ const previous = anchor.previousElementSibling;
423
+ const adjacentTrigger = previous?.matches(".dropdown-toggle, button, [aria-haspopup='menu']") ? previous : previous?.querySelector(".dropdown-toggle, button, [aria-haspopup='menu']");
424
+ return adjacentTrigger ?? anchor.parentElement?.querySelector(".dropdown-toggle");
425
+ }
419
426
  var Dropdown = ({
420
427
  isOpen,
421
428
  onClose,
422
429
  children,
423
430
  className,
424
431
  portal = true,
432
+ triggerRef,
425
433
  style,
426
434
  ...rest
427
435
  }) => {
@@ -430,7 +438,8 @@ var Dropdown = ({
430
438
  const [position, setPosition] = React5.useState();
431
439
  React5.useEffect(() => {
432
440
  const handleClickOutside = (event) => {
433
- if (dropdownRef.current && !dropdownRef.current.contains(event.target) && !event.target.closest(".dropdown-toggle")) {
441
+ const trigger = getTriggerElement(anchorRef.current, triggerRef);
442
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target) && !trigger?.contains(event.target)) {
434
443
  onClose();
435
444
  }
436
445
  };
@@ -438,13 +447,13 @@ var Dropdown = ({
438
447
  return () => {
439
448
  document.removeEventListener("mousedown", handleClickOutside);
440
449
  };
441
- }, [onClose]);
450
+ }, [onClose, triggerRef]);
442
451
  React5.useLayoutEffect(() => {
443
452
  if (!isOpen || !portal) return;
444
453
  const updatePosition = () => {
445
454
  const anchor = anchorRef.current;
446
455
  const menu2 = dropdownRef.current;
447
- const trigger = anchor?.parentElement?.querySelector(".dropdown-toggle");
456
+ const trigger = getTriggerElement(anchor, triggerRef);
448
457
  if (!anchor || !menu2) return;
449
458
  const triggerRect = (trigger ?? anchor).getBoundingClientRect();
450
459
  const menuRect = menu2.getBoundingClientRect();
@@ -465,7 +474,7 @@ var Dropdown = ({
465
474
  window.removeEventListener("resize", updatePosition);
466
475
  window.removeEventListener("scroll", updatePosition, true);
467
476
  };
468
- }, [isOpen, portal]);
477
+ }, [isOpen, portal, triggerRef]);
469
478
  if (!isOpen) return null;
470
479
  const menu = /* @__PURE__ */ jsxRuntime.jsx(
471
480
  "div",