infinity-ui-elements 1.9.25 → 1.9.26

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.
@@ -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;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,sFA4RpB,CAAC;AAIF,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
package/dist/index.esm.js CHANGED
@@ -3163,12 +3163,14 @@ const Dropdown = React.forwardRef(({ className, trigger, items = [], customConte
3163
3163
  const isOpen = controlledOpen !== undefined ? controlledOpen : uncontrolledOpen;
3164
3164
  const dropdownRef = React.useRef(null);
3165
3165
  const menuRef = React.useRef(null);
3166
+ const VIEWPORT_PADDING = 8;
3167
+ const MENU_MAX_HEIGHT = 400;
3166
3168
  const [menuPosition, setMenuPosition] = React.useState({
3167
3169
  top: "100%",
3168
3170
  bottom: "auto",
3169
3171
  left: "0",
3170
3172
  right: "auto",
3171
- maxHeight: "400px",
3173
+ maxHeight: `${MENU_MAX_HEIGHT}px`,
3172
3174
  });
3173
3175
  // Detect if we're on mobile (< 768px)
3174
3176
  const [isMobile, setIsMobile] = React.useState(false);
@@ -3227,68 +3229,56 @@ const Dropdown = React.forwardRef(({ className, trigger, items = [], customConte
3227
3229
  const calculatePosition = () => {
3228
3230
  const triggerRect = dropdownRef.current.getBoundingClientRect();
3229
3231
  const menuElement = menuRef.current;
3230
- // Get menu dimensions (use a temporary measurement if needed)
3232
+ const currentContainerRect = dropdownRef.current.getBoundingClientRect();
3231
3233
  const menuRect = menuElement.getBoundingClientRect();
3232
- const menuHeight = menuRect.height || 400; // fallback to max-height
3233
- const menuWidth = menuRect.width;
3234
+ const menuHeight = menuRect.height || MENU_MAX_HEIGHT;
3235
+ const menuWidth = menuRect.width || 320; // fallback for initial render (w-80 = 320px)
3234
3236
  const viewportHeight = window.innerHeight;
3235
3237
  const viewportWidth = window.innerWidth;
3236
- const spaceBelow = viewportHeight - triggerRect.bottom;
3237
- const spaceAbove = triggerRect.top;
3238
- const spaceRight = viewportWidth - triggerRect.left;
3239
- const spaceLeft = triggerRect.right;
3238
+ const spaceBelow = viewportHeight - triggerRect.bottom - VIEWPORT_PADDING;
3239
+ const spaceAbove = triggerRect.top - VIEWPORT_PADDING;
3240
3240
  const position = {
3241
- top: "auto",
3242
- bottom: "auto",
3243
- left: "auto",
3244
- right: "auto",
3245
- maxHeight: "400px",
3241
+ maxHeight: `${MENU_MAX_HEIGHT}px`,
3246
3242
  };
3247
- // Vertical positioning
3243
+ // Vertical positioning: prefer below, flip above if not enough space
3248
3244
  if (spaceBelow >= menuHeight || spaceBelow >= spaceAbove) {
3249
- // Position below trigger
3250
3245
  position.top = "100%";
3251
3246
  position.bottom = "auto";
3252
- position.maxHeight = `${Math.min(400, spaceBelow - 16)}px`;
3247
+ position.maxHeight = `${Math.min(MENU_MAX_HEIGHT, Math.max(0, spaceBelow))}px`;
3253
3248
  }
3254
3249
  else {
3255
- // Position above trigger
3256
3250
  position.top = "auto";
3257
3251
  position.bottom = "100%";
3258
- position.maxHeight = `${Math.min(400, spaceAbove - 16)}px`;
3259
- }
3260
- // Horizontal positioning
3261
- if (spaceRight >= menuWidth) {
3262
- // Align to left edge of trigger
3263
- position.left = "0";
3264
- position.right = "auto";
3265
- }
3266
- else if (spaceLeft >= menuWidth) {
3267
- // Align to right edge of trigger
3268
- position.left = "auto";
3269
- position.right = "0";
3270
- }
3271
- else {
3272
- // Not enough space on either side, try to center or align based on available space
3273
- if (triggerRect.left + menuWidth > viewportWidth) {
3274
- position.left = "auto";
3275
- position.right = "0";
3276
- }
3277
- else {
3278
- position.left = "0";
3279
- position.right = "auto";
3280
- }
3252
+ position.maxHeight = `${Math.min(MENU_MAX_HEIGHT, Math.max(0, spaceAbove))}px`;
3281
3253
  }
3254
+ // Horizontal: clamp menu left so it stays within viewport
3255
+ const minMenuLeft = VIEWPORT_PADDING;
3256
+ const maxMenuLeft = viewportWidth - menuWidth - VIEWPORT_PADDING;
3257
+ const desiredMenuLeft = Math.max(minMenuLeft, Math.min(maxMenuLeft, triggerRect.left));
3258
+ position.left = `${desiredMenuLeft - currentContainerRect.left}px`;
3259
+ position.right = "auto";
3282
3260
  setMenuPosition(position);
3283
3261
  };
3284
- // Calculate position after menu is rendered
3285
- calculatePosition();
3286
- // Recalculate on window resize or scroll
3287
- const handleResize = () => calculatePosition();
3288
- const handleScroll = () => calculatePosition();
3262
+ // Run after layout so menu dimensions are correct (double rAF for paint)
3263
+ let cancelled = false;
3264
+ const scheduleUpdate = () => {
3265
+ requestAnimationFrame(() => {
3266
+ requestAnimationFrame(() => {
3267
+ if (!cancelled &&
3268
+ dropdownRef.current &&
3269
+ menuRef.current) {
3270
+ calculatePosition();
3271
+ }
3272
+ });
3273
+ });
3274
+ };
3275
+ scheduleUpdate();
3276
+ const handleResize = () => scheduleUpdate();
3277
+ const handleScroll = () => scheduleUpdate();
3289
3278
  window.addEventListener("resize", handleResize);
3290
3279
  window.addEventListener("scroll", handleScroll, true);
3291
3280
  return () => {
3281
+ cancelled = true;
3292
3282
  window.removeEventListener("resize", handleResize);
3293
3283
  window.removeEventListener("scroll", handleScroll, true);
3294
3284
  };