@flytedan/flytebot-design-system 0.11.0 → 0.11.2

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/dist/index.cjs CHANGED
@@ -106,6 +106,7 @@ __export(index_exports, {
106
106
  ModeSwitch: () => ModeSwitch,
107
107
  ModelControls: () => ModelControls,
108
108
  NumberInput: () => NumberInput,
109
+ POPOVER_BODY_MIN: () => POPOVER_BODY_MIN,
109
110
  PacketCard: () => PacketCard,
110
111
  Pagination: () => Pagination,
111
112
  PermissionDenied: () => PermissionDenied,
@@ -287,16 +288,24 @@ var parsePlacement = (p) => {
287
288
  };
288
289
  var samePosition = (a, b) => {
289
290
  if (!a || !b) return a === b;
290
- return a.left === b.left && a.top === b.top && a.bottom === b.bottom && a.width === b.width && a.minWidth === b.minWidth && a.maxH === b.maxH && a.side === b.side && a.anchorWidth === b.anchorWidth;
291
+ return a.left === b.left && a.top === b.top && a.bottom === b.bottom && a.width === b.width && a.minWidth === b.minWidth && a.maxH === b.maxH && a.maxW === b.maxW && a.side === b.side && a.anchorWidth === b.anchorWidth;
291
292
  };
292
293
  var SCROLL_REGIONS = ".fd-pop-body, .fd-pop-list";
294
+ var PINNED_REGIONS = ":scope > .fd-pop-header, :scope > .fd-pop-footer";
295
+ var POPOVER_BODY_MIN = 96;
293
296
  function measureLayer(el) {
294
- if (!el) return { width: 0, height: 0 };
297
+ if (!el || !el.offsetHeight) return { width: el ? el.offsetWidth : 0, height: 0, pinned: 0 };
295
298
  let hidden = 0;
296
299
  el.querySelectorAll(SCROLL_REGIONS).forEach((r) => {
297
300
  hidden += Math.max(0, r.scrollHeight - r.clientHeight);
298
301
  });
299
- return { width: el.offsetWidth, height: el.offsetHeight ? el.offsetHeight + hidden : 0 };
302
+ let pinned = 0;
303
+ el.querySelectorAll(PINNED_REGIONS).forEach((r) => {
304
+ pinned += r.offsetHeight;
305
+ });
306
+ const border = Math.max(0, el.offsetHeight - el.clientHeight);
307
+ const content = Math.max(el.scrollHeight, el.clientHeight);
308
+ return { width: el.offsetWidth, height: content + border + hidden, pinned: pinned + border };
300
309
  }
301
310
  function usePopoverPosition(open, anchorRef, opts) {
302
311
  const o = opts || {};
@@ -318,25 +327,38 @@ function usePopoverPosition(open, anchorRef, opts) {
318
327
  const r = el.getBoundingClientRect();
319
328
  const offset = o.offset == null ? 8 : o.offset;
320
329
  const layer = measureLayer(layerRef ? layerRef.current : null);
330
+ const vh = window.innerHeight;
321
331
  const need = layer.height || Math.min(o.estHeight || 300, 180);
322
- const below = window.innerHeight - r.bottom - offset - MARGIN;
332
+ const below = vh - r.bottom - offset - MARGIN;
323
333
  const above = r.top - offset - MARGIN;
324
334
  let side = wantSide;
325
335
  if (side === "bottom" && below < need && above > below) side = "top";
326
336
  else if (side === "top" && above < need && below > above) side = "bottom";
337
+ const ceiling = Math.min(vh - 2 * MARGIN, o.maxHeight != null ? o.maxHeight : Infinity);
338
+ const floor = Math.min(
339
+ ceiling,
340
+ layer.height ? layer.pinned + Math.min(POPOVER_BODY_MIN, layer.height - layer.pinned) : Math.min(need, 140)
341
+ );
342
+ const room = side === "top" ? above : below;
343
+ const beside = room >= floor;
344
+ const edge = beside ? 0 : Math.max(MARGIN, vh - MARGIN - Math.min(need, ceiling));
345
+ const top = side === "bottom" ? beside ? r.bottom + offset : edge : null;
346
+ const bottom = side === "top" ? beside ? vh - r.top + offset : edge : null;
347
+ const maxH = beside ? room : vh - MARGIN - edge;
348
+ const maxW = Math.max(0, window.innerWidth - 2 * MARGIN);
327
349
  const exact = o.matchWidth === true;
328
350
  const width = exact ? r.width : Math.max(o.width || 0, o.minWidth || 0, o.matchWidth === "min" ? r.width : 0);
329
- const w = exact || o.width ? width : Math.max(layer.width, width) || o.estWidth || 260;
351
+ const w = Math.min(maxW, exact || o.width ? width : Math.max(layer.width, width) || o.estWidth || 260);
330
352
  let left = align === "end" ? r.right - w : align === "center" ? r.left + r.width / 2 - w / 2 : r.left;
331
353
  left = Math.max(MARGIN, Math.min(left, window.innerWidth - w - MARGIN));
332
- const maxH = Math.max(140, side === "top" ? above : below);
333
354
  const next = {
334
355
  left,
335
356
  width: exact ? r.width : void 0,
336
357
  minWidth: o.minWidth,
337
- top: side === "bottom" ? r.bottom + offset : null,
338
- bottom: side === "top" ? window.innerHeight - r.top + offset : null,
358
+ top,
359
+ bottom,
339
360
  maxH,
361
+ maxW,
340
362
  side,
341
363
  anchorWidth: r.width
342
364
  };
@@ -358,9 +380,10 @@ function usePopoverPosition(open, anchorRef, opts) {
358
380
  };
359
381
  raf = requestAnimationFrame(tick);
360
382
  return () => cancelAnimationFrame(raf);
361
- }, [open, o.placement, o.offset, o.matchWidth, o.width, o.minWidth, o.estHeight]);
383
+ }, [open, o.placement, o.offset, o.matchWidth, o.width, o.minWidth, o.maxHeight, o.estHeight]);
362
384
  return pos;
363
385
  }
386
+ var capWidth = (value, max) => value == null ? void 0 : Math.min(value, max);
364
387
  var portal = (node) => {
365
388
  if (typeof document !== "undefined") return (0, import_react_dom.createPortal)(node, document.body);
366
389
  return node;
@@ -395,6 +418,7 @@ function Popover({
395
418
  matchWidth,
396
419
  width,
397
420
  minWidth,
421
+ maxHeight,
398
422
  estHeight: maxHeight || 320,
399
423
  onDetach: onClose,
400
424
  layerRef: ref
@@ -451,7 +475,14 @@ function Popover({
451
475
  top: pos.top == null ? "auto" : pos.top,
452
476
  bottom: pos.bottom == null ? "auto" : pos.bottom,
453
477
  width: matchWidth === true ? pos.width : width,
454
- minWidth: matchWidth === "min" ? Math.max(pos.anchorWidth, minWidth || 0) : minWidth || (matchWidth ? void 0 : 200),
478
+ // CSS lets min-width win over max-width, so every minimum is capped to the viewport too.
479
+ minWidth: capWidth(
480
+ matchWidth === "min" ? Math.max(pos.anchorWidth, minWidth || 0) : minWidth || (matchWidth ? void 0 : 200),
481
+ pos.maxW
482
+ ),
483
+ // The surface never runs past the viewport edge, whatever fixed `width` a caller asked
484
+ // for: pos.maxW is the viewport less its margins, and `left` is clamped against it.
485
+ maxWidth: pos.maxW,
455
486
  // Size to content by default — cap only at real available room between the
456
487
  // anchor and the viewport edge (pos.maxH, computed by usePopoverPosition).
457
488
  // A caller-supplied `maxHeight` narrows that further (e.g. a long menu that
@@ -10623,6 +10654,7 @@ function createVersionStore(initialState, options) {
10623
10654
  ModeSwitch,
10624
10655
  ModelControls,
10625
10656
  NumberInput,
10657
+ POPOVER_BODY_MIN,
10626
10658
  PacketCard,
10627
10659
  Pagination,
10628
10660
  PermissionDenied,