infinity-ui-elements 1.14.16 → 1.14.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.
@@ -105,6 +105,11 @@ export interface DropdownProps extends Omit<React.HTMLAttributes<HTMLDivElement>
105
105
  * Whether to show footer actions (overrides disableFooter)
106
106
  */
107
107
  showFooter?: boolean;
108
+ /**
109
+ * Whether to use React portal for rendering dropdown menu (useful to avoid overflow clipping)
110
+ * @default true
111
+ */
112
+ usePortal?: boolean;
108
113
  }
109
114
  export declare const Dropdown: React.ForwardRefExoticComponent<DropdownProps & React.RefAttributes<HTMLDivElement>>;
110
115
  export { dropdownVariants };
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.d.ts","sourceRoot":"","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGrE,QAAA,MAAM,gBAAgB;;mFAcrB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAE5C,MAAM,WAAW,aACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC9D;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;OAEG;IACH,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB;;OAEG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,QAAQ,sFA0RpB,CAAC;AAIF,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"Dropdown.d.ts","sourceRoot":"","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIrE,QAAA,MAAM,gBAAgB;;mFAcrB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAE5C,MAAM,WAAW,aACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC9D;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;OAEG;IACH,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB;;OAEG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,QAAQ,sFAuRpB,CAAC;AAIF,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -36,6 +36,7 @@ declare const meta: {
36
36
  emptyIcon?: React.ReactNode;
37
37
  disableFooter?: boolean | undefined;
38
38
  showFooter?: boolean | undefined;
39
+ usePortal?: boolean | undefined;
39
40
  dangerouslySetInnerHTML?: {
40
41
  __html: string | TrustedHTML;
41
42
  } | undefined | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.stories.d.ts","sourceRoot":"","sources":["../../../src/components/Dropdown/Dropdown.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CuB,CAAC;AAElC,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AA0FnC,eAAO,MAAM,OAAO,EAAE,KASrB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAgC9B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAW5B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAQ1B,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,KAQnC,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAQ3B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAQ1B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KA6C/B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KA8B3B,CAAC;AAGF,eAAO,MAAM,WAAW,EAAE,KAyEzB,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,KAwDxB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,OAAO,QAAQ,CAuE1D,CAAC"}
1
+ {"version":3,"file":"Dropdown.stories.d.ts","sourceRoot":"","sources":["../../../src/components/Dropdown/Dropdown.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CuB,CAAC;AAElC,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AA0FnC,eAAO,MAAM,OAAO,EAAE,KASrB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAgC9B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAW5B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAQ1B,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,KAQnC,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAQ3B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAQ1B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KA6C/B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KA8B3B,CAAC;AAGF,eAAO,MAAM,WAAW,EAAE,KAyEzB,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,KAwDxB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,OAAO,QAAQ,CAuE1D,CAAC"}
package/dist/index.esm.js CHANGED
@@ -3153,17 +3153,17 @@ const dropdownVariants = cva("bg-surface-fill-primary-normal border border-surfa
3153
3153
  size: "medium",
3154
3154
  },
3155
3155
  });
3156
- const Dropdown = React.forwardRef(({ className, trigger, items = [], customContent, customContentClassName, sectionHeading, isLoading = false, isEmpty = false, emptyTitle = "No Search Results Found", emptyDescription = "Add description of what the user can search for here.", emptyLinkText = "Link to support site", onEmptyLinkClick, primaryButtonText = "Primary", secondaryButtonText = "Secondary", onPrimaryClick, onSecondaryClick, size = "medium", open: controlledOpen, defaultOpen = false, onOpenChange, containerClassName, menuClassName, showChevron = false, emptyIcon, disableFooter = false, showFooter, ...props }, ref) => {
3156
+ const Dropdown = React.forwardRef(({ className, trigger, items = [], customContent, customContentClassName, sectionHeading, isLoading = false, isEmpty = false, emptyTitle = "No Search Results Found", emptyDescription = "Add description of what the user can search for here.", emptyLinkText = "Link to support site", onEmptyLinkClick, primaryButtonText = "Primary", secondaryButtonText = "Secondary", onPrimaryClick, onSecondaryClick, size = "medium", open: controlledOpen, defaultOpen = false, onOpenChange, containerClassName, menuClassName, showChevron = false, emptyIcon, disableFooter = false, showFooter, usePortal = true, ...props }, ref) => {
3157
3157
  const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);
3158
3158
  const isOpen = controlledOpen !== undefined ? controlledOpen : uncontrolledOpen;
3159
3159
  const dropdownRef = React.useRef(null);
3160
3160
  const menuRef = React.useRef(null);
3161
3161
  const [menuPosition, setMenuPosition] = React.useState({
3162
- top: "100%",
3163
- bottom: "auto",
3164
- left: "0",
3165
- right: "auto",
3162
+ top: 0,
3163
+ left: 0,
3164
+ width: 0,
3166
3165
  maxHeight: "400px",
3166
+ position: "below",
3167
3167
  });
3168
3168
  // Detect if we're on mobile (< 768px)
3169
3169
  const [isMobile, setIsMobile] = React.useState(false);
@@ -3217,62 +3217,36 @@ const Dropdown = React.forwardRef(({ className, trigger, items = [], customConte
3217
3217
  }, [isOpen]);
3218
3218
  // Calculate and adjust dropdown position to keep it within viewport
3219
3219
  React.useEffect(() => {
3220
- if (!isOpen || !dropdownRef.current || !menuRef.current)
3220
+ if (!isOpen || !dropdownRef.current)
3221
3221
  return;
3222
3222
  const calculatePosition = () => {
3223
3223
  const triggerRect = dropdownRef.current.getBoundingClientRect();
3224
3224
  const menuElement = menuRef.current;
3225
- // Get menu dimensions (use a temporary measurement if needed)
3226
- const menuRect = menuElement.getBoundingClientRect();
3227
- const menuHeight = menuRect.height || 400; // fallback to max-height
3228
- const menuWidth = menuRect.width;
3225
+ // Get menu dimensions
3226
+ const menuHeight = menuElement?.getBoundingClientRect().height || 400;
3227
+ triggerRect.width; // Match trigger width or use size variant
3229
3228
  const viewportHeight = window.innerHeight;
3230
- const viewportWidth = window.innerWidth;
3231
3229
  const spaceBelow = viewportHeight - triggerRect.bottom;
3232
3230
  const spaceAbove = triggerRect.top;
3233
- const spaceRight = viewportWidth - triggerRect.left;
3234
- const spaceLeft = triggerRect.right;
3235
3231
  const position = {
3236
- top: "auto",
3237
- bottom: "auto",
3238
- left: "auto",
3239
- right: "auto",
3232
+ top: 0,
3233
+ left: triggerRect.left + window.scrollX,
3234
+ width: triggerRect.width,
3240
3235
  maxHeight: "400px",
3236
+ position: "below",
3241
3237
  };
3242
3238
  // Vertical positioning
3243
3239
  if (spaceBelow >= menuHeight || spaceBelow >= spaceAbove) {
3244
3240
  // Position below trigger
3245
- position.top = "100%";
3246
- position.bottom = "auto";
3241
+ position.top = triggerRect.bottom + window.scrollY + 8; // 8px gap
3247
3242
  position.maxHeight = `${Math.min(400, spaceBelow - 16)}px`;
3243
+ position.position = "below";
3248
3244
  }
3249
3245
  else {
3250
3246
  // Position above trigger
3251
- position.top = "auto";
3252
- position.bottom = "100%";
3247
+ position.top = triggerRect.top + window.scrollY - menuHeight - 8; // 8px gap
3253
3248
  position.maxHeight = `${Math.min(400, spaceAbove - 16)}px`;
3254
- }
3255
- // Horizontal positioning
3256
- if (spaceRight >= menuWidth) {
3257
- // Align to left edge of trigger
3258
- position.left = "0";
3259
- position.right = "auto";
3260
- }
3261
- else if (spaceLeft >= menuWidth) {
3262
- // Align to right edge of trigger
3263
- position.left = "auto";
3264
- position.right = "0";
3265
- }
3266
- else {
3267
- // Not enough space on either side, try to center or align based on available space
3268
- if (triggerRect.left + menuWidth > viewportWidth) {
3269
- position.left = "auto";
3270
- position.right = "0";
3271
- }
3272
- else {
3273
- position.left = "0";
3274
- position.right = "auto";
3275
- }
3249
+ position.position = "above";
3276
3250
  }
3277
3251
  setMenuPosition(position);
3278
3252
  };
@@ -3295,16 +3269,29 @@ const Dropdown = React.forwardRef(({ className, trigger, items = [], customConte
3295
3269
  };
3296
3270
  // Render dropdown menu content wrapped in BottomSheet for mobile
3297
3271
  const renderDropdownContent = () => (jsx(DropdownMenu, { ref: ref, items: items, customContent: customContent, customContentClassName: customContentClassName, sectionHeading: sectionHeading, isLoading: isLoading, isEmpty: isEmpty, emptyTitle: emptyTitle, emptyDescription: emptyDescription, emptyLinkText: emptyLinkText, onEmptyLinkClick: onEmptyLinkClick, primaryButtonText: primaryButtonText, secondaryButtonText: secondaryButtonText, onPrimaryClick: onPrimaryClick, onSecondaryClick: onSecondaryClick, showChevron: showChevron, emptyIcon: emptyIcon, disableFooter: disableFooter, showFooter: showFooter, onClose: () => handleOpenChange(false), className: className, width: isMobile ? "full" : sizeMap[size], maxHeight: menuPosition.maxHeight, unstyled: isMobile }));
3272
+ // Render the dropdown menu for desktop
3273
+ const renderDesktopDropdown = () => {
3274
+ if (!isOpen)
3275
+ return null;
3276
+ const dropdownMenu = (jsx("div", { ref: menuRef, className: cn("fixed z-[1000]", menuClassName), style: {
3277
+ top: `${menuPosition.top}px`,
3278
+ left: `${menuPosition.left}px`,
3279
+ width: `${menuPosition.width}px`,
3280
+ }, children: renderDropdownContent() }));
3281
+ // Use portal if enabled, otherwise render inline
3282
+ return usePortal && typeof document !== 'undefined'
3283
+ ? createPortal(dropdownMenu, document.body)
3284
+ : (jsx("div", { ref: menuRef, className: cn("absolute z-[1000]", menuClassName), style: {
3285
+ top: menuPosition.position === "below" ? "100%" : "auto",
3286
+ bottom: menuPosition.position === "above" ? "100%" : "auto",
3287
+ left: "0",
3288
+ marginTop: menuPosition.position === "below" ? "0.5rem" : "0",
3289
+ marginBottom: menuPosition.position === "above" ? "0.5rem" : "0",
3290
+ }, children: renderDropdownContent() }));
3291
+ };
3298
3292
  return (jsxs("div", { ref: dropdownRef, className: cn("relative inline-block", containerClassName), ...props, children: [trigger && (jsx("div", { onClick: toggleOpen, className: "cursor-pointer", children: trigger })), isMobile ? (jsx(BottomSheet, { isOpen: isOpen, onClose: () => handleOpenChange(false), title: sectionHeading, variant: "default", showDragHandle: true, closeOnOverlayClick: true, closeOnEscape: true, closeOnSwipeDown: true, children: renderDropdownContent() })) : (
3299
- /* Desktop: Regular Dropdown Menu */
3300
- isOpen && (jsx("div", { ref: menuRef, className: cn("absolute z-[1000]", menuClassName), style: {
3301
- top: menuPosition.top,
3302
- bottom: menuPosition.bottom,
3303
- left: menuPosition.left,
3304
- right: menuPosition.right,
3305
- marginTop: menuPosition.top === "100%" ? "0.5rem" : "0",
3306
- marginBottom: menuPosition.bottom === "100%" ? "0.5rem" : "0",
3307
- }, children: renderDropdownContent() })))] }));
3293
+ /* Desktop: Regular Dropdown Menu with Portal */
3294
+ renderDesktopDropdown())] }));
3308
3295
  });
3309
3296
  Dropdown.displayName = "Dropdown";
3310
3297