react-better-html 1.1.286 → 1.1.287

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.mjs CHANGED
@@ -7263,73 +7263,38 @@ import {
7263
7263
  useImperativeHandle as useImperativeHandle3,
7264
7264
  useMemo as useMemo10
7265
7265
  } from "react";
7266
+ import { createPortal as createPortal2 } from "react-dom";
7266
7267
  import { useTheme as useTheme26 } from "react-better-core";
7267
7268
  import styled13, { css as css6 } from "styled-components";
7268
7269
  import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
7269
- var tooltipContainerStyle = (props) => ({
7270
+ var isStartAlign = (align) => align === "left" || align === "top";
7271
+ var tooltipClosedTransform = (props) => ({
7270
7272
  top: css6`
7271
- bottom: calc(100% + ${props.gap}px + ${props.arrowSize}px);
7272
- ${props.align === "center" ? "left: 50%;" : props.align === "left" ? "left: 0;" : "right: 0;"}
7273
+ transform: translateY(${props.theme.styles.gap}px);
7273
7274
  `,
7274
7275
  bottom: css6`
7275
- top: calc(100% + ${props.gap}px + ${props.arrowSize}px);
7276
- ${props.align === "center" ? "left: 50%;" : props.align === "left" ? "left: 0;" : "right: 0;"};
7276
+ transform: translateY(-${props.theme.styles.gap}px);
7277
7277
  `,
7278
7278
  left: css6`
7279
- ${props.align === "center" ? "top: 50%;" : props.align === "top" ? "top: 0;" : "bottom: 0;"};
7280
- right: calc(100% + ${props.gap}px + ${props.arrowSize}px);
7279
+ transform: translateX(${props.theme.styles.gap}px);
7281
7280
  `,
7282
7281
  right: css6`
7283
- ${props.align === "center" ? "top: 50%;" : props.align === "top" ? "top: 0;" : "bottom: 0;"};
7284
- left: calc(100% + ${props.gap}px + ${props.arrowSize}px);
7282
+ transform: translateX(-${props.theme.styles.gap}px);
7285
7283
  `
7286
7284
  });
7287
- var tooltipPositionStyle = (props) => ({
7288
- top: {
7289
- opened: css6`
7290
- transform: translateX(${props.align === "center" ? "-50%" : "0"});
7291
- `,
7292
- closed: css6`
7293
- transform: translateX(${props.align === "center" ? "-50%" : "0"}) translateY(${props.theme.styles.gap}px);
7294
- `
7295
- },
7296
- bottom: {
7297
- opened: css6`
7298
- transform: translateX(${props.align === "center" ? "-50%" : "0"});
7299
- `,
7300
- closed: css6`
7301
- transform: translateX(${props.align === "center" ? "-50%" : "0"}) translateY(-${props.theme.styles.gap}px);
7302
- `
7303
- },
7304
- left: {
7305
- opened: css6`
7306
- transform: translateY(${props.align === "center" ? "-50%" : "0"});
7307
- `,
7308
- closed: css6`
7309
- transform: translateX(${props.theme.styles.gap}px) translateY(${props.align === "center" ? "-50%" : "0"});
7310
- `
7311
- },
7312
- right: {
7313
- opened: css6`
7314
- transform: translateY(${props.align === "center" ? "-50%" : "0"});
7315
- `,
7316
- closed: css6`
7317
- transform: translateX(-${props.theme.styles.gap}px) translateY(${props.align === "center" ? "-50%" : "0"});
7318
- `
7319
- }
7320
- });
7321
7285
  var TooltipContainer = styled13.div.withConfig({
7322
- shouldForwardProp: (prop) => !["theme", "position", "align", "pointerEvents", "withArrow", "arrowSize", "isOpen", "gap"].includes(prop)
7286
+ shouldForwardProp: (prop) => !["theme", "position", "pointerEvents", "isOpen"].includes(prop)
7323
7287
  })`
7324
- position: absolute;
7288
+ position: fixed;
7289
+ top: 0;
7290
+ left: 0;
7325
7291
  opacity: ${(props) => props.isOpen ? 1 : 0};
7326
7292
  pointer-events: ${(props) => props.isOpen ? props.pointerEvents : "none"};
7327
7293
  transition: ${(props) => props.theme.styles.transition};
7294
+ transition-property: opacity, transform;
7328
7295
  z-index: 1000;
7329
7296
 
7330
- ${(props) => tooltipContainerStyle(props)[props.position]}
7331
-
7332
- ${(props) => props.isOpen ? tooltipPositionStyle(props)[props.position].opened : tooltipPositionStyle(props)[props.position].closed}
7297
+ ${(props) => props.isOpen ? "transform: none;" : tooltipClosedTransform(props)[props.position]}
7333
7298
  `;
7334
7299
  var arrowStyle = (props, borderWidth) => ({
7335
7300
  top: {
@@ -7425,6 +7390,7 @@ var TooltipComponent = forwardRef16(function Tooltip({
7425
7390
  const wrapperRef = useRef7(null);
7426
7391
  const triggerHolderRef = useRef7(null);
7427
7392
  const contentRef = useRef7(null);
7393
+ const tooltipContainerRef = useRef7(null);
7428
7394
  const closeTimerRef = useRef7(void 0);
7429
7395
  const [isOpen, setIsOpen] = useState12(false);
7430
7396
  const [isOpenLate, setIsOpenLate] = useState12(false);
@@ -7432,6 +7398,8 @@ var TooltipComponent = forwardRef16(function Tooltip({
7432
7398
  const gap = theme2.styles.gap / 2;
7433
7399
  const outsideScreenGap = theme2.styles.gap / 2;
7434
7400
  const totalGap = arrowSize + gap;
7401
+ const arrowSideSpace = theme2.styles.borderRadius;
7402
+ const arrowAnchorOffset = withArrow ? arrowSideSpace + arrowSize : 0;
7435
7403
  const openTooltip = useCallback16(() => {
7436
7404
  if (disabled) return;
7437
7405
  if (closeTimerRef.current) clearTimeout(closeTimerRef.current);
@@ -7469,19 +7437,25 @@ var TooltipComponent = forwardRef16(function Tooltip({
7469
7437
  },
7470
7438
  [trigger, isOpen, closeTooltip]
7471
7439
  );
7472
- const clampContentInsideViewport = useCallback16(() => {
7473
- if (!wrapperRef.current || !contentRef.current) return;
7440
+ const updateContainerPosition = useCallback16(() => {
7441
+ if (!wrapperRef.current || !contentRef.current || !tooltipContainerRef.current) return;
7474
7442
  const wrapperRect = wrapperRef.current.getBoundingClientRect();
7475
7443
  const contentWidth2 = contentRef.current.offsetWidth;
7476
7444
  const contentHeight = contentRef.current.offsetHeight;
7445
+ const getCrossAxisStart = (wrapperStart, wrapperSize, contentSize) => {
7446
+ const wrapperCenter = wrapperStart + wrapperSize / 2;
7447
+ if (align === "center") return wrapperCenter - contentSize / 2;
7448
+ if (isStartAlign(align)) return arrowAnchorOffset ? wrapperCenter - arrowAnchorOffset : wrapperStart;
7449
+ return arrowAnchorOffset ? wrapperCenter + arrowAnchorOffset - contentSize : wrapperStart + wrapperSize - contentSize;
7450
+ };
7477
7451
  let expectedLeft;
7478
7452
  let expectedTop;
7479
7453
  if (position === "top" || position === "bottom") {
7480
7454
  expectedTop = position === "top" ? wrapperRect.top - totalGap - contentHeight : wrapperRect.bottom + totalGap;
7481
- expectedLeft = align === "left" ? wrapperRect.left : align === "right" ? wrapperRect.right - contentWidth2 : wrapperRect.left + wrapperRect.width / 2 - contentWidth2 / 2;
7455
+ expectedLeft = getCrossAxisStart(wrapperRect.left, wrapperRect.width, contentWidth2);
7482
7456
  } else {
7483
7457
  expectedLeft = position === "left" ? wrapperRect.left - totalGap - contentWidth2 : wrapperRect.right + totalGap;
7484
- expectedTop = align === "top" ? wrapperRect.top : align === "bottom" ? wrapperRect.bottom - contentHeight : wrapperRect.top + wrapperRect.height / 2 - contentHeight / 2;
7458
+ expectedTop = getCrossAxisStart(wrapperRect.top, wrapperRect.height, contentHeight);
7485
7459
  }
7486
7460
  const getShift = (start, size, viewportSize) => {
7487
7461
  if (start < outsideScreenGap) return outsideScreenGap - start;
@@ -7490,8 +7464,9 @@ var TooltipComponent = forwardRef16(function Tooltip({
7490
7464
  };
7491
7465
  const shiftX = getShift(expectedLeft, contentWidth2, window.innerWidth);
7492
7466
  const shiftY = getShift(expectedTop, contentHeight, window.innerHeight);
7493
- contentRef.current.style.transform = shiftX || shiftY ? `translate(${shiftX}px, ${shiftY}px)` : "";
7494
- }, [position, align, totalGap, outsideScreenGap]);
7467
+ tooltipContainerRef.current.style.left = `${expectedLeft + shiftX}px`;
7468
+ tooltipContainerRef.current.style.top = `${expectedTop + shiftY}px`;
7469
+ }, [position, align, totalGap, outsideScreenGap, arrowAnchorOffset]);
7495
7470
  useEffect13(() => {
7496
7471
  if (trigger === "click") {
7497
7472
  document.addEventListener("mousedown", onClickOutside);
@@ -7505,8 +7480,15 @@ var TooltipComponent = forwardRef16(function Tooltip({
7505
7480
  closeTooltip();
7506
7481
  }, [disabled]);
7507
7482
  useLayoutEffect(() => {
7508
- if (isOpen) clampContentInsideViewport();
7509
- }, [isOpen, clampContentInsideViewport]);
7483
+ if (!isOpen) return;
7484
+ updateContainerPosition();
7485
+ window.addEventListener("scroll", updateContainerPosition, true);
7486
+ window.addEventListener("resize", updateContainerPosition);
7487
+ return () => {
7488
+ window.removeEventListener("scroll", updateContainerPosition, true);
7489
+ window.removeEventListener("resize", updateContainerPosition);
7490
+ };
7491
+ }, [isOpen, updateContainerPosition]);
7510
7492
  useImperativeHandle3(ref, () => {
7511
7493
  return {
7512
7494
  isOpen,
@@ -7535,60 +7517,60 @@ var TooltipComponent = forwardRef16(function Tooltip({
7535
7517
  children
7536
7518
  }
7537
7519
  ),
7538
- /* @__PURE__ */ jsx25(
7539
- TooltipContainer,
7540
- {
7541
- theme: theme2,
7542
- position,
7543
- align,
7544
- pointerEvents: contentPointerEvents,
7545
- withArrow,
7546
- arrowSize,
7547
- gap,
7548
- isOpen,
7549
- role: "tooltip",
7550
- children: (isOpen || isOpenLate) && /* @__PURE__ */ jsxs21(Div_default, { position: "relative", ref: contentRef, children: [
7551
- /* @__PURE__ */ jsx25(
7552
- Div_default.box,
7553
- {
7554
- position: "relative",
7555
- width: contentWidth,
7556
- minWidth: contentMinWidth,
7557
- backgroundColor: backgroundColor ?? theme2.colors.backgroundContent,
7558
- boxShadow: "0px 10px 20px #00000020",
7559
- paddingBlock: contentPaddingBlock ?? (isSmall ? theme2.styles.gap / 2 : theme2.styles.gap),
7560
- paddingInline: contentPaddingInline ?? (asContextMenu ? 0 : isSmall ? theme2.styles.space / 2 : theme2.styles.space),
7561
- overflow: asContextMenu ? "hidden" : void 0,
7562
- children: content
7563
- }
7564
- ),
7565
- /* @__PURE__ */ jsx25(
7566
- Div_default,
7567
- {
7568
- position: "absolute",
7569
- width: position === "left" || position === "right" ? totalGap : "100%",
7570
- height: position === "top" || position === "bottom" ? totalGap : "100%",
7571
- top: position === "top" ? "100%" : position === "bottom" ? void 0 : 0,
7572
- bottom: position === "bottom" ? "100%" : position === "top" ? void 0 : 0,
7573
- left: position === "left" ? "100%" : position === "right" ? void 0 : 0,
7574
- right: position === "right" ? "100%" : position === "left" ? void 0 : 0,
7575
- borderTopLeftRadius: 999,
7576
- borderTopRightRadius: 999
7577
- }
7578
- ),
7579
- withArrow && /* @__PURE__ */ jsx25(
7580
- Arrow,
7581
- {
7582
- position,
7583
- align,
7584
- sideSpace: theme2.styles.borderRadius,
7585
- size: arrowSize,
7586
- color: backgroundColor ?? theme2.colors.backgroundContent,
7587
- isOpen
7588
- }
7589
- )
7590
- ] })
7591
- }
7520
+ createPortal2(
7521
+ /* @__PURE__ */ jsx25(
7522
+ TooltipContainer,
7523
+ {
7524
+ theme: theme2,
7525
+ position,
7526
+ pointerEvents: contentPointerEvents,
7527
+ isOpen,
7528
+ role: "tooltip",
7529
+ ref: tooltipContainerRef,
7530
+ children: (isOpen || isOpenLate) && /* @__PURE__ */ jsxs21(Div_default, { position: "relative", ref: contentRef, children: [
7531
+ /* @__PURE__ */ jsx25(
7532
+ Div_default.box,
7533
+ {
7534
+ position: "relative",
7535
+ width: contentWidth,
7536
+ minWidth: contentMinWidth,
7537
+ backgroundColor: backgroundColor ?? theme2.colors.backgroundContent,
7538
+ boxShadow: "0px 10px 20px #00000020",
7539
+ paddingBlock: contentPaddingBlock ?? (isSmall ? theme2.styles.gap / 2 : theme2.styles.gap),
7540
+ paddingInline: contentPaddingInline ?? (asContextMenu ? 0 : isSmall ? theme2.styles.space / 2 : theme2.styles.space),
7541
+ overflow: asContextMenu ? "hidden" : void 0,
7542
+ children: content
7543
+ }
7544
+ ),
7545
+ /* @__PURE__ */ jsx25(
7546
+ Div_default,
7547
+ {
7548
+ position: "absolute",
7549
+ width: position === "left" || position === "right" ? totalGap : "100%",
7550
+ height: position === "top" || position === "bottom" ? totalGap : "100%",
7551
+ top: position === "top" ? "100%" : position === "bottom" ? void 0 : 0,
7552
+ bottom: position === "bottom" ? "100%" : position === "top" ? void 0 : 0,
7553
+ left: position === "left" ? "100%" : position === "right" ? void 0 : 0,
7554
+ right: position === "right" ? "100%" : position === "left" ? void 0 : 0,
7555
+ borderTopLeftRadius: 999,
7556
+ borderTopRightRadius: 999
7557
+ }
7558
+ ),
7559
+ withArrow && /* @__PURE__ */ jsx25(
7560
+ Arrow,
7561
+ {
7562
+ position,
7563
+ align,
7564
+ sideSpace: arrowSideSpace,
7565
+ size: arrowSize,
7566
+ color: backgroundColor ?? theme2.colors.backgroundContent,
7567
+ isOpen
7568
+ }
7569
+ )
7570
+ ] })
7571
+ }
7572
+ ),
7573
+ document.body
7592
7574
  )
7593
7575
  ]
7594
7576
  }