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.js CHANGED
@@ -7294,73 +7294,38 @@ var Table_default = Table2;
7294
7294
 
7295
7295
  // src/components/Tooltip.tsx
7296
7296
  var import_react29 = require("react");
7297
+ var import_react_dom2 = require("react-dom");
7297
7298
  var import_react_better_core26 = require("react-better-core");
7298
7299
  var import_styled_components14 = __toESM(require("styled-components"));
7299
7300
  var import_jsx_runtime26 = require("react/jsx-runtime");
7300
- var tooltipContainerStyle = (props) => ({
7301
+ var isStartAlign = (align) => align === "left" || align === "top";
7302
+ var tooltipClosedTransform = (props) => ({
7301
7303
  top: import_styled_components14.css`
7302
- bottom: calc(100% + ${props.gap}px + ${props.arrowSize}px);
7303
- ${props.align === "center" ? "left: 50%;" : props.align === "left" ? "left: 0;" : "right: 0;"}
7304
+ transform: translateY(${props.theme.styles.gap}px);
7304
7305
  `,
7305
7306
  bottom: import_styled_components14.css`
7306
- top: calc(100% + ${props.gap}px + ${props.arrowSize}px);
7307
- ${props.align === "center" ? "left: 50%;" : props.align === "left" ? "left: 0;" : "right: 0;"};
7307
+ transform: translateY(-${props.theme.styles.gap}px);
7308
7308
  `,
7309
7309
  left: import_styled_components14.css`
7310
- ${props.align === "center" ? "top: 50%;" : props.align === "top" ? "top: 0;" : "bottom: 0;"};
7311
- right: calc(100% + ${props.gap}px + ${props.arrowSize}px);
7310
+ transform: translateX(${props.theme.styles.gap}px);
7312
7311
  `,
7313
7312
  right: import_styled_components14.css`
7314
- ${props.align === "center" ? "top: 50%;" : props.align === "top" ? "top: 0;" : "bottom: 0;"};
7315
- left: calc(100% + ${props.gap}px + ${props.arrowSize}px);
7313
+ transform: translateX(-${props.theme.styles.gap}px);
7316
7314
  `
7317
7315
  });
7318
- var tooltipPositionStyle = (props) => ({
7319
- top: {
7320
- opened: import_styled_components14.css`
7321
- transform: translateX(${props.align === "center" ? "-50%" : "0"});
7322
- `,
7323
- closed: import_styled_components14.css`
7324
- transform: translateX(${props.align === "center" ? "-50%" : "0"}) translateY(${props.theme.styles.gap}px);
7325
- `
7326
- },
7327
- bottom: {
7328
- opened: import_styled_components14.css`
7329
- transform: translateX(${props.align === "center" ? "-50%" : "0"});
7330
- `,
7331
- closed: import_styled_components14.css`
7332
- transform: translateX(${props.align === "center" ? "-50%" : "0"}) translateY(-${props.theme.styles.gap}px);
7333
- `
7334
- },
7335
- left: {
7336
- opened: import_styled_components14.css`
7337
- transform: translateY(${props.align === "center" ? "-50%" : "0"});
7338
- `,
7339
- closed: import_styled_components14.css`
7340
- transform: translateX(${props.theme.styles.gap}px) translateY(${props.align === "center" ? "-50%" : "0"});
7341
- `
7342
- },
7343
- right: {
7344
- opened: import_styled_components14.css`
7345
- transform: translateY(${props.align === "center" ? "-50%" : "0"});
7346
- `,
7347
- closed: import_styled_components14.css`
7348
- transform: translateX(-${props.theme.styles.gap}px) translateY(${props.align === "center" ? "-50%" : "0"});
7349
- `
7350
- }
7351
- });
7352
7316
  var TooltipContainer = import_styled_components14.default.div.withConfig({
7353
- shouldForwardProp: (prop) => !["theme", "position", "align", "pointerEvents", "withArrow", "arrowSize", "isOpen", "gap"].includes(prop)
7317
+ shouldForwardProp: (prop) => !["theme", "position", "pointerEvents", "isOpen"].includes(prop)
7354
7318
  })`
7355
- position: absolute;
7319
+ position: fixed;
7320
+ top: 0;
7321
+ left: 0;
7356
7322
  opacity: ${(props) => props.isOpen ? 1 : 0};
7357
7323
  pointer-events: ${(props) => props.isOpen ? props.pointerEvents : "none"};
7358
7324
  transition: ${(props) => props.theme.styles.transition};
7325
+ transition-property: opacity, transform;
7359
7326
  z-index: 1000;
7360
7327
 
7361
- ${(props) => tooltipContainerStyle(props)[props.position]}
7362
-
7363
- ${(props) => props.isOpen ? tooltipPositionStyle(props)[props.position].opened : tooltipPositionStyle(props)[props.position].closed}
7328
+ ${(props) => props.isOpen ? "transform: none;" : tooltipClosedTransform(props)[props.position]}
7364
7329
  `;
7365
7330
  var arrowStyle = (props, borderWidth) => ({
7366
7331
  top: {
@@ -7456,6 +7421,7 @@ var TooltipComponent = (0, import_react29.forwardRef)(function Tooltip({
7456
7421
  const wrapperRef = (0, import_react29.useRef)(null);
7457
7422
  const triggerHolderRef = (0, import_react29.useRef)(null);
7458
7423
  const contentRef = (0, import_react29.useRef)(null);
7424
+ const tooltipContainerRef = (0, import_react29.useRef)(null);
7459
7425
  const closeTimerRef = (0, import_react29.useRef)(void 0);
7460
7426
  const [isOpen, setIsOpen] = (0, import_react29.useState)(false);
7461
7427
  const [isOpenLate, setIsOpenLate] = (0, import_react29.useState)(false);
@@ -7463,6 +7429,8 @@ var TooltipComponent = (0, import_react29.forwardRef)(function Tooltip({
7463
7429
  const gap = theme2.styles.gap / 2;
7464
7430
  const outsideScreenGap = theme2.styles.gap / 2;
7465
7431
  const totalGap = arrowSize + gap;
7432
+ const arrowSideSpace = theme2.styles.borderRadius;
7433
+ const arrowAnchorOffset = withArrow ? arrowSideSpace + arrowSize : 0;
7466
7434
  const openTooltip = (0, import_react29.useCallback)(() => {
7467
7435
  if (disabled) return;
7468
7436
  if (closeTimerRef.current) clearTimeout(closeTimerRef.current);
@@ -7500,19 +7468,25 @@ var TooltipComponent = (0, import_react29.forwardRef)(function Tooltip({
7500
7468
  },
7501
7469
  [trigger, isOpen, closeTooltip]
7502
7470
  );
7503
- const clampContentInsideViewport = (0, import_react29.useCallback)(() => {
7504
- if (!wrapperRef.current || !contentRef.current) return;
7471
+ const updateContainerPosition = (0, import_react29.useCallback)(() => {
7472
+ if (!wrapperRef.current || !contentRef.current || !tooltipContainerRef.current) return;
7505
7473
  const wrapperRect = wrapperRef.current.getBoundingClientRect();
7506
7474
  const contentWidth2 = contentRef.current.offsetWidth;
7507
7475
  const contentHeight = contentRef.current.offsetHeight;
7476
+ const getCrossAxisStart = (wrapperStart, wrapperSize, contentSize) => {
7477
+ const wrapperCenter = wrapperStart + wrapperSize / 2;
7478
+ if (align === "center") return wrapperCenter - contentSize / 2;
7479
+ if (isStartAlign(align)) return arrowAnchorOffset ? wrapperCenter - arrowAnchorOffset : wrapperStart;
7480
+ return arrowAnchorOffset ? wrapperCenter + arrowAnchorOffset - contentSize : wrapperStart + wrapperSize - contentSize;
7481
+ };
7508
7482
  let expectedLeft;
7509
7483
  let expectedTop;
7510
7484
  if (position === "top" || position === "bottom") {
7511
7485
  expectedTop = position === "top" ? wrapperRect.top - totalGap - contentHeight : wrapperRect.bottom + totalGap;
7512
- expectedLeft = align === "left" ? wrapperRect.left : align === "right" ? wrapperRect.right - contentWidth2 : wrapperRect.left + wrapperRect.width / 2 - contentWidth2 / 2;
7486
+ expectedLeft = getCrossAxisStart(wrapperRect.left, wrapperRect.width, contentWidth2);
7513
7487
  } else {
7514
7488
  expectedLeft = position === "left" ? wrapperRect.left - totalGap - contentWidth2 : wrapperRect.right + totalGap;
7515
- expectedTop = align === "top" ? wrapperRect.top : align === "bottom" ? wrapperRect.bottom - contentHeight : wrapperRect.top + wrapperRect.height / 2 - contentHeight / 2;
7489
+ expectedTop = getCrossAxisStart(wrapperRect.top, wrapperRect.height, contentHeight);
7516
7490
  }
7517
7491
  const getShift = (start, size, viewportSize) => {
7518
7492
  if (start < outsideScreenGap) return outsideScreenGap - start;
@@ -7521,8 +7495,9 @@ var TooltipComponent = (0, import_react29.forwardRef)(function Tooltip({
7521
7495
  };
7522
7496
  const shiftX = getShift(expectedLeft, contentWidth2, window.innerWidth);
7523
7497
  const shiftY = getShift(expectedTop, contentHeight, window.innerHeight);
7524
- contentRef.current.style.transform = shiftX || shiftY ? `translate(${shiftX}px, ${shiftY}px)` : "";
7525
- }, [position, align, totalGap, outsideScreenGap]);
7498
+ tooltipContainerRef.current.style.left = `${expectedLeft + shiftX}px`;
7499
+ tooltipContainerRef.current.style.top = `${expectedTop + shiftY}px`;
7500
+ }, [position, align, totalGap, outsideScreenGap, arrowAnchorOffset]);
7526
7501
  (0, import_react29.useEffect)(() => {
7527
7502
  if (trigger === "click") {
7528
7503
  document.addEventListener("mousedown", onClickOutside);
@@ -7536,8 +7511,15 @@ var TooltipComponent = (0, import_react29.forwardRef)(function Tooltip({
7536
7511
  closeTooltip();
7537
7512
  }, [disabled]);
7538
7513
  (0, import_react29.useLayoutEffect)(() => {
7539
- if (isOpen) clampContentInsideViewport();
7540
- }, [isOpen, clampContentInsideViewport]);
7514
+ if (!isOpen) return;
7515
+ updateContainerPosition();
7516
+ window.addEventListener("scroll", updateContainerPosition, true);
7517
+ window.addEventListener("resize", updateContainerPosition);
7518
+ return () => {
7519
+ window.removeEventListener("scroll", updateContainerPosition, true);
7520
+ window.removeEventListener("resize", updateContainerPosition);
7521
+ };
7522
+ }, [isOpen, updateContainerPosition]);
7541
7523
  (0, import_react29.useImperativeHandle)(ref, () => {
7542
7524
  return {
7543
7525
  isOpen,
@@ -7566,60 +7548,60 @@ var TooltipComponent = (0, import_react29.forwardRef)(function Tooltip({
7566
7548
  children
7567
7549
  }
7568
7550
  ),
7569
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7570
- TooltipContainer,
7571
- {
7572
- theme: theme2,
7573
- position,
7574
- align,
7575
- pointerEvents: contentPointerEvents,
7576
- withArrow,
7577
- arrowSize,
7578
- gap,
7579
- isOpen,
7580
- role: "tooltip",
7581
- children: (isOpen || isOpenLate) && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Div_default, { position: "relative", ref: contentRef, children: [
7582
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7583
- Div_default.box,
7584
- {
7585
- position: "relative",
7586
- width: contentWidth,
7587
- minWidth: contentMinWidth,
7588
- backgroundColor: backgroundColor ?? theme2.colors.backgroundContent,
7589
- boxShadow: "0px 10px 20px #00000020",
7590
- paddingBlock: contentPaddingBlock ?? (isSmall ? theme2.styles.gap / 2 : theme2.styles.gap),
7591
- paddingInline: contentPaddingInline ?? (asContextMenu ? 0 : isSmall ? theme2.styles.space / 2 : theme2.styles.space),
7592
- overflow: asContextMenu ? "hidden" : void 0,
7593
- children: content
7594
- }
7595
- ),
7596
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7597
- Div_default,
7598
- {
7599
- position: "absolute",
7600
- width: position === "left" || position === "right" ? totalGap : "100%",
7601
- height: position === "top" || position === "bottom" ? totalGap : "100%",
7602
- top: position === "top" ? "100%" : position === "bottom" ? void 0 : 0,
7603
- bottom: position === "bottom" ? "100%" : position === "top" ? void 0 : 0,
7604
- left: position === "left" ? "100%" : position === "right" ? void 0 : 0,
7605
- right: position === "right" ? "100%" : position === "left" ? void 0 : 0,
7606
- borderTopLeftRadius: 999,
7607
- borderTopRightRadius: 999
7608
- }
7609
- ),
7610
- withArrow && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7611
- Arrow,
7612
- {
7613
- position,
7614
- align,
7615
- sideSpace: theme2.styles.borderRadius,
7616
- size: arrowSize,
7617
- color: backgroundColor ?? theme2.colors.backgroundContent,
7618
- isOpen
7619
- }
7620
- )
7621
- ] })
7622
- }
7551
+ (0, import_react_dom2.createPortal)(
7552
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7553
+ TooltipContainer,
7554
+ {
7555
+ theme: theme2,
7556
+ position,
7557
+ pointerEvents: contentPointerEvents,
7558
+ isOpen,
7559
+ role: "tooltip",
7560
+ ref: tooltipContainerRef,
7561
+ children: (isOpen || isOpenLate) && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Div_default, { position: "relative", ref: contentRef, children: [
7562
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7563
+ Div_default.box,
7564
+ {
7565
+ position: "relative",
7566
+ width: contentWidth,
7567
+ minWidth: contentMinWidth,
7568
+ backgroundColor: backgroundColor ?? theme2.colors.backgroundContent,
7569
+ boxShadow: "0px 10px 20px #00000020",
7570
+ paddingBlock: contentPaddingBlock ?? (isSmall ? theme2.styles.gap / 2 : theme2.styles.gap),
7571
+ paddingInline: contentPaddingInline ?? (asContextMenu ? 0 : isSmall ? theme2.styles.space / 2 : theme2.styles.space),
7572
+ overflow: asContextMenu ? "hidden" : void 0,
7573
+ children: content
7574
+ }
7575
+ ),
7576
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7577
+ Div_default,
7578
+ {
7579
+ position: "absolute",
7580
+ width: position === "left" || position === "right" ? totalGap : "100%",
7581
+ height: position === "top" || position === "bottom" ? totalGap : "100%",
7582
+ top: position === "top" ? "100%" : position === "bottom" ? void 0 : 0,
7583
+ bottom: position === "bottom" ? "100%" : position === "top" ? void 0 : 0,
7584
+ left: position === "left" ? "100%" : position === "right" ? void 0 : 0,
7585
+ right: position === "right" ? "100%" : position === "left" ? void 0 : 0,
7586
+ borderTopLeftRadius: 999,
7587
+ borderTopRightRadius: 999
7588
+ }
7589
+ ),
7590
+ withArrow && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7591
+ Arrow,
7592
+ {
7593
+ position,
7594
+ align,
7595
+ sideSpace: arrowSideSpace,
7596
+ size: arrowSize,
7597
+ color: backgroundColor ?? theme2.colors.backgroundContent,
7598
+ isOpen
7599
+ }
7600
+ )
7601
+ ] })
7602
+ }
7603
+ ),
7604
+ document.body
7623
7605
  )
7624
7606
  ]
7625
7607
  }