@canvas-components/react-components 0.3.6 → 0.3.7

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.d.cts CHANGED
@@ -565,6 +565,8 @@ interface PopupAnchorRect {
565
565
  height: number;
566
566
  }
567
567
  interface ReactPopupProps {
568
+ /** 将面板高度限制在视口内,超出部分在面板内部滚动。 */
569
+ constrainHeight?: boolean;
568
570
  /**
569
571
  * 是否显示弹层。
570
572
  */
package/dist/index.d.ts CHANGED
@@ -565,6 +565,8 @@ interface PopupAnchorRect {
565
565
  height: number;
566
566
  }
567
567
  interface ReactPopupProps {
568
+ /** 将面板高度限制在视口内,超出部分在面板内部滚动。 */
569
+ constrainHeight?: boolean;
568
570
  /**
569
571
  * 是否显示弹层。
570
572
  */
package/dist/index.js CHANGED
@@ -298,6 +298,7 @@ function ReactPopup(props) {
298
298
  style,
299
299
  surfaceClassName,
300
300
  surfaceStyle,
301
+ constrainHeight = false,
301
302
  zIndex = 1200
302
303
  } = props;
303
304
  const { scale: contentScale } = useReactContentScale();
@@ -319,6 +320,7 @@ function ReactPopup(props) {
319
320
  return;
320
321
  }
321
322
  const nextPosition = resolvePopupPosition({
323
+ constrainHeight,
322
324
  anchor: nextAnchor,
323
325
  contentScale,
324
326
  matchAnchorWidth,
@@ -328,7 +330,7 @@ function ReactPopup(props) {
328
330
  popupRect: resolvePopupSurfaceRect(surfaceRef.current, contentScale)
329
331
  });
330
332
  setPosition((prev) => {
331
- if (prev?.placement === nextPosition.placement && prev?.style.left === nextPosition.style.left && prev?.style.top === nextPosition.style.top && prev?.style.width === nextPosition.style.width && prev?.style.minWidth === nextPosition.style.minWidth) {
333
+ if (prev?.placement === nextPosition.placement && prev?.style.left === nextPosition.style.left && prev?.style.top === nextPosition.style.top && prev?.style.width === nextPosition.style.width && prev?.style.minWidth === nextPosition.style.minWidth && prev?.style.maxHeight === nextPosition.style.maxHeight) {
332
334
  return prev;
333
335
  }
334
336
  return nextPosition;
@@ -355,6 +357,7 @@ function ReactPopup(props) {
355
357
  anchorRect,
356
358
  anchorRef,
357
359
  contentScale,
360
+ constrainHeight,
358
361
  matchAnchorWidth,
359
362
  minWidth,
360
363
  offset,
@@ -371,6 +374,7 @@ function ReactPopup(props) {
371
374
  return;
372
375
  }
373
376
  const nextPosition = resolvePopupPosition({
377
+ constrainHeight,
374
378
  anchor: nextAnchor,
375
379
  contentScale,
376
380
  matchAnchorWidth,
@@ -380,7 +384,7 @@ function ReactPopup(props) {
380
384
  popupRect: resolvePopupSurfaceRect(surfaceRef.current, contentScale)
381
385
  });
382
386
  setPosition((prev) => {
383
- if (prev?.placement === nextPosition.placement && prev?.style.left === nextPosition.style.left && prev?.style.top === nextPosition.style.top && prev?.style.width === nextPosition.style.width && prev?.style.minWidth === nextPosition.style.minWidth) {
387
+ if (prev?.placement === nextPosition.placement && prev?.style.left === nextPosition.style.left && prev?.style.top === nextPosition.style.top && prev?.style.width === nextPosition.style.width && prev?.style.minWidth === nextPosition.style.minWidth && prev?.style.maxHeight === nextPosition.style.maxHeight) {
384
388
  return prev;
385
389
  }
386
390
  return nextPosition;
@@ -398,6 +402,7 @@ function ReactPopup(props) {
398
402
  anchorRect,
399
403
  anchorRef,
400
404
  contentScale,
405
+ constrainHeight,
401
406
  matchAnchorWidth,
402
407
  minWidth,
403
408
  offset,
@@ -463,7 +468,7 @@ function ReactPopup(props) {
463
468
  transition.className,
464
469
  surfaceClassName
465
470
  ),
466
- style: surfaceStyle,
471
+ style: resolvePopupSurfaceStyle(surfaceStyle, position.style.maxHeight),
467
472
  children
468
473
  }
469
474
  )
@@ -492,7 +497,8 @@ function resolvePopupPosition(params) {
492
497
  matchAnchorWidth ? anchor.width : 0
493
498
  );
494
499
  const popupWidth = preferredVisualWidth;
495
- const popupHeight = popupRect?.height ?? 0;
500
+ const maxVisualHeight = Math.max(0, viewportHeight - margin * 2);
501
+ const popupHeight = params.constrainHeight ? Math.min(popupRect?.height ?? 0, maxVisualHeight) : popupRect?.height ?? 0;
496
502
  const isHorizontalPlacement = placement.startsWith("left") || placement.startsWith("right");
497
503
  const preferredVertical = placement.startsWith("top") ? "top" : placement.endsWith("Top") ? "top" : "bottom";
498
504
  const preferredTop = resolveRawTop({
@@ -537,6 +543,7 @@ function resolvePopupPosition(params) {
537
543
  vertical: resolvedVertical
538
544
  }),
539
545
  style: {
546
+ ...params.constrainHeight ? { maxHeight: toContentLayoutSize(maxVisualHeight, contentScale) } : {},
540
547
  left,
541
548
  top,
542
549
  width: matchAnchorWidth ? layoutAnchorWidth : void 0,
@@ -544,6 +551,19 @@ function resolvePopupPosition(params) {
544
551
  }
545
552
  };
546
553
  }
554
+ function resolvePopupSurfaceStyle(style, viewportMaxHeight) {
555
+ if (typeof viewportMaxHeight !== "number") return style;
556
+ const custom = style?.maxHeight;
557
+ const maxHeight = typeof custom === "number" ? Math.min(custom, viewportMaxHeight) : typeof custom === "string" && custom !== "none" ? `min(${custom}, ${viewportMaxHeight}px)` : viewportMaxHeight;
558
+ return {
559
+ ...style,
560
+ boxSizing: "border-box",
561
+ minHeight: 0,
562
+ maxHeight,
563
+ overflowY: "auto",
564
+ overscrollBehaviorY: "contain"
565
+ };
566
+ }
547
567
  function resolvePlacement(params) {
548
568
  const { horizontal, isHorizontalPlacement, vertical } = params;
549
569
  if (isHorizontalPlacement) {