react-better-html 1.1.285 → 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: {
@@ -7453,6 +7418,7 @@ var TooltipComponent = (0, import_react29.forwardRef)(function Tooltip({
7453
7418
  children
7454
7419
  }, ref) {
7455
7420
  const theme2 = (0, import_react_better_core26.useTheme)();
7421
+ const wrapperRef = (0, import_react29.useRef)(null);
7456
7422
  const triggerHolderRef = (0, import_react29.useRef)(null);
7457
7423
  const contentRef = (0, import_react29.useRef)(null);
7458
7424
  const tooltipContainerRef = (0, import_react29.useRef)(null);
@@ -7463,31 +7429,15 @@ 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);
7469
7437
  setIsOpen(true);
7470
7438
  setIsOpenLate(true);
7471
- setTimeout(() => {
7472
- if (!tooltipContainerRef.current) return;
7473
- if (!contentRef.current) return;
7474
- const clientRects = tooltipContainerRef.current.getBoundingClientRect();
7475
- if (clientRects) {
7476
- const { width, height, x, y } = clientRects;
7477
- const topOutside = y < 0;
7478
- const bottomOutside = y + height > window.innerHeight;
7479
- const leftOutside = x < 0;
7480
- const rightOutside = x + width > window.innerWidth;
7481
- if (topOutside) contentRef.current.style.transform = `translateY(${y * -1 + outsideScreenGap}px)`;
7482
- if (bottomOutside)
7483
- contentRef.current.style.transform = `translateY(${window.innerHeight - (y + height) - totalGap}px)`;
7484
- if (leftOutside) contentRef.current.style.transform = `translateX(${x * -1 + outsideScreenGap}px)`;
7485
- if (rightOutside)
7486
- contentRef.current.style.transform = `translateX(${window.innerWidth - (x + width) - totalGap}px)`;
7487
- }
7488
- }, 1);
7489
7439
  onOpen?.();
7490
- }, [disabled, onOpen, outsideScreenGap, totalGap]);
7440
+ }, [disabled, onOpen]);
7491
7441
  const closeTooltip = (0, import_react29.useCallback)(() => {
7492
7442
  setIsOpen(false);
7493
7443
  closeTimerRef.current = setTimeout(() => setIsOpenLate(false), 300);
@@ -7518,6 +7468,36 @@ var TooltipComponent = (0, import_react29.forwardRef)(function Tooltip({
7518
7468
  },
7519
7469
  [trigger, isOpen, closeTooltip]
7520
7470
  );
7471
+ const updateContainerPosition = (0, import_react29.useCallback)(() => {
7472
+ if (!wrapperRef.current || !contentRef.current || !tooltipContainerRef.current) return;
7473
+ const wrapperRect = wrapperRef.current.getBoundingClientRect();
7474
+ const contentWidth2 = contentRef.current.offsetWidth;
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
+ };
7482
+ let expectedLeft;
7483
+ let expectedTop;
7484
+ if (position === "top" || position === "bottom") {
7485
+ expectedTop = position === "top" ? wrapperRect.top - totalGap - contentHeight : wrapperRect.bottom + totalGap;
7486
+ expectedLeft = getCrossAxisStart(wrapperRect.left, wrapperRect.width, contentWidth2);
7487
+ } else {
7488
+ expectedLeft = position === "left" ? wrapperRect.left - totalGap - contentWidth2 : wrapperRect.right + totalGap;
7489
+ expectedTop = getCrossAxisStart(wrapperRect.top, wrapperRect.height, contentHeight);
7490
+ }
7491
+ const getShift = (start, size, viewportSize) => {
7492
+ if (start < outsideScreenGap) return outsideScreenGap - start;
7493
+ if (start + size > viewportSize - outsideScreenGap) return viewportSize - outsideScreenGap - (start + size);
7494
+ return 0;
7495
+ };
7496
+ const shiftX = getShift(expectedLeft, contentWidth2, window.innerWidth);
7497
+ const shiftY = getShift(expectedTop, contentHeight, window.innerHeight);
7498
+ tooltipContainerRef.current.style.left = `${expectedLeft + shiftX}px`;
7499
+ tooltipContainerRef.current.style.top = `${expectedTop + shiftY}px`;
7500
+ }, [position, align, totalGap, outsideScreenGap, arrowAnchorOffset]);
7521
7501
  (0, import_react29.useEffect)(() => {
7522
7502
  if (trigger === "click") {
7523
7503
  document.addEventListener("mousedown", onClickOutside);
@@ -7530,6 +7510,16 @@ var TooltipComponent = (0, import_react29.forwardRef)(function Tooltip({
7530
7510
  if (!disabled) return;
7531
7511
  closeTooltip();
7532
7512
  }, [disabled]);
7513
+ (0, import_react29.useLayoutEffect)(() => {
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]);
7533
7523
  (0, import_react29.useImperativeHandle)(ref, () => {
7534
7524
  return {
7535
7525
  isOpen,
@@ -7546,6 +7536,7 @@ var TooltipComponent = (0, import_react29.forwardRef)(function Tooltip({
7546
7536
  onClick: onClickHolder,
7547
7537
  onMouseEnter,
7548
7538
  onMouseLeave,
7539
+ ref: wrapperRef,
7549
7540
  children: [
7550
7541
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7551
7542
  Div_default,
@@ -7557,61 +7548,60 @@ var TooltipComponent = (0, import_react29.forwardRef)(function Tooltip({
7557
7548
  children
7558
7549
  }
7559
7550
  ),
7560
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7561
- TooltipContainer,
7562
- {
7563
- theme: theme2,
7564
- position,
7565
- align,
7566
- pointerEvents: contentPointerEvents,
7567
- withArrow,
7568
- arrowSize,
7569
- gap,
7570
- isOpen,
7571
- role: "tooltip",
7572
- ref: tooltipContainerRef,
7573
- children: (isOpen || isOpenLate) && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Div_default, { position: "relative", ref: contentRef, children: [
7574
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7575
- Div_default.box,
7576
- {
7577
- position: "relative",
7578
- width: contentWidth,
7579
- minWidth: contentMinWidth,
7580
- backgroundColor: backgroundColor ?? theme2.colors.backgroundContent,
7581
- boxShadow: "0px 10px 20px #00000020",
7582
- paddingBlock: contentPaddingBlock ?? (isSmall ? theme2.styles.gap / 2 : theme2.styles.gap),
7583
- paddingInline: contentPaddingInline ?? (asContextMenu ? 0 : isSmall ? theme2.styles.space / 2 : theme2.styles.space),
7584
- overflow: asContextMenu ? "hidden" : void 0,
7585
- children: content
7586
- }
7587
- ),
7588
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7589
- Div_default,
7590
- {
7591
- position: "absolute",
7592
- width: position === "left" || position === "right" ? totalGap : "100%",
7593
- height: position === "top" || position === "bottom" ? totalGap : "100%",
7594
- top: position === "top" ? "100%" : position === "bottom" ? void 0 : 0,
7595
- bottom: position === "bottom" ? "100%" : position === "top" ? void 0 : 0,
7596
- left: position === "left" ? "100%" : position === "right" ? void 0 : 0,
7597
- right: position === "right" ? "100%" : position === "left" ? void 0 : 0,
7598
- borderTopLeftRadius: 999,
7599
- borderTopRightRadius: 999
7600
- }
7601
- ),
7602
- withArrow && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
7603
- Arrow,
7604
- {
7605
- position,
7606
- align,
7607
- sideSpace: theme2.styles.borderRadius,
7608
- size: arrowSize,
7609
- color: backgroundColor ?? theme2.colors.backgroundContent,
7610
- isOpen
7611
- }
7612
- )
7613
- ] })
7614
- }
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
7615
7605
  )
7616
7606
  ]
7617
7607
  }