import { useClampText } from 'use-clamp-text';
import React2, { useState, useMemo, useRef, useLayoutEffect } from 'react';
import { onlyText } from 'react-children-utilities';
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
import { extendTailwindMerge, twMerge as twMerge$1 } from 'tailwind-merge';
import { get, findKey, reduce, parseInt, pick, omit, upperFirst } from 'lodash-es';
import { createClassed } from '@tw-classed/react';
import { createClassed as createClassed$1 } from '@tw-classed/core';
import clsx4 from 'clsx';
import createVariatGroupTransfomer from 'tailwind-group-variant';
import { getByPath as getByPath$1 } from '@clickbar/dot-diver';
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import InformationCircleIcon from '@heroicons/react/24/outline/InformationCircleIcon';
import { paramCase, capitalCase, camelCase, dotCase, headerCase, noCase, pathCase, constantCase, sentenceCase, snakeCase, pascalCase } from 'change-case';

// src/components/ClampText/ClampText.tsx
var twMerge = extendTailwindMerge({
  classGroups: {
    "font-size": [
      {
        // Fixes incorect merging of text size
        text: ["h1", "h2", "h3", "h4", "h5", "h6"]
      }
    ]
  }
});
var { classed } = createClassed({ merger: twMerge });
createClassed$1({ merger: twMerge });

// src/utils/notEmpty.ts
function notEmpty(value) {
  return value !== null && value !== void 0;
}

// src/utils/classed/expandVariant.ts
createVariatGroupTransfomer({});

// src/utils/environment-utils.ts
function isClientSide() {
  return typeof window !== "undefined";
}
function isDevelopment() {
  if (typeof window === "undefined" && typeof process !== "undefined" && process.env.NODE_ENV === "development") {
    return true;
  }
  if (typeof window !== "undefined" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1")) {
    return true;
  }
  return false;
}
function getByPath(object, path, _maxDepth) {
  return getByPath$1(object, path);
}

// src/utils/objectMap.ts
function objectMap(obj, fn) {
  return Object.fromEntries(
    Object.entries(obj).map(([k, v], index) => fn({ key: k, value: v, index, get: getByPath })).filter(notEmpty)
  );
}

// src/utils/pickProps.ts
function generatePropPickerFn(pickedRecord) {
  const pickedKeys = Object.keys(pickedRecord);
  const pickerFn = (props, options) => {
    const { defaultProps } = options ?? {};
    return { ...defaultProps, ...pick(props, pickedKeys) };
  };
  pickerFn.pickedKeys = pickedKeys;
  pickerFn.pickedRecord = pickedRecord;
  pickerFn.omit = (props) => omit(props, pickedKeys);
  return pickerFn;
}
var NO_DEFAULT_VALUE = "_pick_";
function pickProps(props, pickedProps, options) {
  const { shouldValidatePickProp = true } = options ?? {};
  const entries = Object.entries(pickedProps).map(([path, defaultValue]) => {
    const prop = get(props, path);
    if (defaultValue === NO_DEFAULT_VALUE) {
      return [path, prop];
    }
    if (shouldValidatePickProp) {
      validatePickProp(defaultValue, pickedProps);
    }
    return [path, prop ?? defaultValue];
  });
  return Object.fromEntries(entries);
}
function validatePickProp(input, pickedProps) {
  if (isDevelopment()) {
    const startsWith = ["_p", "pick"];
    const isLikelyTypo = typeof input === "string" && startsWith.some((typo) => input.startsWith(typo));
    if (isLikelyTypo) {
      const functionName = "`pickProps`";
      throw new Error(`
      Error thrown from ${functionName}
      
      A possible typo was detected in the arguments passed to the ${functionName} function.

      Expected value: "${NO_DEFAULT_VALUE}"

      Received value: "${input}" \u274C

      ${JSON.stringify(
        objectMap(pickedProps, ({ key, value }) => [
          key,
          value === input ? `${value} \u274C` : value
        ]),
        null,
        2
      )}
 
      If this is intended, add \`shouldValidatePickProp: true\` to the options.

      Note: This error is thrown only during development.

      `);
    }
  }
}

// src/utils/getElement.ts
function getElement(elementOrRef) {
  if (!elementOrRef)
    return void 0;
  if (elementOrRef instanceof HTMLElement || elementOrRef instanceof Element) {
    return elementOrRef;
  }
  return elementOrRef.current;
}

// src/utils/getNearestColorSchemeAttribute.ts
function getNearestColorSchemeAttribute(element, fallback = "default") {
  if (!isClientSide() || !element)
    return fallback;
  const nearestScheme = element.closest("[data-color-scheme]")?.getAttribute("data-color-scheme");
  return nearestScheme ?? fallback;
}

// src/hooks/useNearestColorSchemeAttribute.tsx
function useNearestColorSchemeAttribute({
  element
}) {
  const [colorSchemeAttribute, setColorSchemeAttribute] = useState(
    void 0
  );
  useLayoutEffect(() => {
    queueMicrotask(() => {
      const el = getElement(element);
      const colorScheme = getNearestColorSchemeAttribute(el);
      setColorSchemeAttribute(colorScheme);
    });
  }, [element]);
  return colorSchemeAttribute;
}
var TooltipContentElement = classed(
  TooltipPrimitive.TooltipContent,
  "radix-side-top:animate-slide-down-fade",
  "radix-side-right:animate-slide-left-fade",
  "radix-side-bottom:animate-slide-up-fade",
  "radix-side-left:animate-slide-right-fade",
  "inline-flex items-center py-8 px-10",
  "text-sm font-body",
  "rounded",
  "bg-surface-soft text-content-strong",
  "ring-1 ring-inset ring-content-tint",
  "z-50 relative",
  {
    variants: {
      size: {
        xs: "text-xs py-2 px-4",
        sm: "text-sm py-4 px-6",
        md: "text-md py-6 px-8",
        lg: "text-lg py-4 px-12"
      },
      maxWidth: {
        false: "",
        xs: "max-w-[20ch]",
        sm: "max-w-[30ch]",
        md: "max-w-[38ch]",
        lg: "max-w-[65ch]"
      },
      selectNone: {
        true: "select-none"
      }
    },
    defaultVariants: {
      maxWidth: "md",
      selectNone: true
    }
  }
);
var pickTooltipContentProps = generatePropPickerFn({
  style: "_pick_",
  className: "_pick_",
  "aria-label": "_pick_",
  size: "_pick_",
  align: "_pick_",
  maxWidth: "_pick_",
  selectNone: "_pick_",
  side: "_pick_",
  sideOffset: "_pick_",
  alignOffset: "_pick_",
  arrowPadding: "_pick_",
  collisionBoundary: "_pick_",
  collisionPadding: "_pick_",
  sticky: "_pick_",
  hideWhenDetached: "_pick_",
  avoidCollisions: "_pick_",
  stopPropogation: "_pick_",
  onTooltipClick: "_pick_"
});
var Tooltip = (props) => {
  const triggerRef = useRef(null);
  const colorSchemeAttribute = useNearestColorSchemeAttribute({ element: triggerRef });
  const { children, tooltip, triggerProps, triggerAsChild } = pickProps(props, {
    triggerAsChild: true,
    children: "_pick_",
    tooltip: "_pick_",
    triggerProps: {},
    forceMount: "_pick_"
  });
  const tooltipContentProps = pickTooltipContentProps(props);
  const tooltipRootProps = pickProps(props, {
    defaultOpen: "_pick_",
    open: "_pick_",
    onOpenChange: "_pick_",
    delayDuration: "_pick_",
    disableHoverableContent: "_pick_"
  });
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(TooltipPrimitive.Root, { delayDuration: 100, ...tooltipRootProps, children: [
    /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, { asChild: triggerAsChild, ref: triggerRef, ...triggerProps, children }),
    /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(TooltipContent2, { colorScheme: colorSchemeAttribute, ...tooltipContentProps, children: tooltip }) })
  ] }) });
};
var TooltipContent2 = ({
  children,
  colorScheme,
  onTooltipClick,
  stopPropogation,
  side = "bottom",
  asChild,
  ...contentProps
}) => {
  return /* @__PURE__ */ jsx(
    TooltipContentElement,
    {
      size: "md",
      side,
      sideOffset: 4,
      collisionPadding: 4,
      alignOffset: 4,
      "data-color-scheme": colorScheme,
      asChild,
      ...contentProps,
      onClick: (e) => {
        if (stopPropogation) {
          e.stopPropagation();
        }
        onTooltipClick?.(e);
      },
      children
    }
  );
};
Tooltip.Provider = TooltipPrimitive.Provider;
Tooltip.Root = TooltipPrimitive.Root;
Tooltip.Trigger = TooltipPrimitive.Trigger;
Tooltip.Portal = TooltipPrimitive.Portal;
Tooltip.PrimitiveContent = TooltipPrimitive.Content;
Tooltip.Content = TooltipContent2;
classed(
  InformationCircleIcon,
  "rounded-full min-w-[24px] min-h-[24px] h-full w-full"
);
classed("button", "focus:ring-boundary-tint rounded-full");
function Wrap({
  children,
  if: conditionProp,
  wrap: wrapper,
  fallback
}) {
  const fallbackWrapperFn = fallback ?? ((c) => /* @__PURE__ */ jsx(Fragment, { children: c }));
  if (!Boolean(conditionProp))
    return fallbackWrapperFn(children);
  const getCondition = () => {
    if (typeof conditionProp === "object") {
      return findKey(conditionProp, (e) => Boolean(e));
    }
    return conditionProp;
  };
  const condition = getCondition();
  const getWrapperFn = () => {
    if (typeof wrapper === "function")
      return wrapper;
    if (typeof wrapper === "object" && typeof condition === "string" && condition in wrapper) {
      return wrapper[condition];
    }
    return fallbackWrapperFn;
  };
  const wrapperFn = getWrapperFn();
  if (typeof condition === "boolean") {
    return Boolean(condition) ? wrapperFn(children) : /* @__PURE__ */ jsx(Fragment, { children });
  }
  return wrapperFn(children);
}
var stringCaseFns = {
  param: paramCase,
  capital: capitalCase,
  capitalize: upperFirst,
  camel: camelCase,
  dot: dotCase,
  header: headerCase,
  noCase,
  path: pathCase,
  constant: constantCase,
  sentence: sentenceCase,
  snake: snakeCase,
  pascal: pascalCase
};
function changeCase(str, stringCase) {
  if (typeof str !== "string") {
    return void 0;
  }
  const caseFn = stringCaseFns[stringCase];
  return caseFn(str);
}

// src/utils/measureElement.ts
function measureElement(elementOrRef, options) {
  const { includeMargin = false, excludePadding = false, excludeBorder = false } = options ?? {};
  const el = getElement(elementOrRef);
  const signs = {
    margin: includeMargin ? 1 : 0,
    padding: excludePadding ? -1 : 0,
    border: excludeBorder ? -1 : 0
  };
  const cssAttributes = getCssAttributeDataMap(el);
  function getSize(value, property) {
    const sum = reduce(
      signs,
      (acc, sign, key) => {
        const size = cssAttributes[key][property];
        return acc + size * sign;
      },
      value
    );
    return Math.round(sum);
  }
  const {
    width = 0,
    height = 0,
    top = 0,
    bottom = 0,
    left = 0,
    right = 0
  } = el?.getBoundingClientRect() ?? {};
  const {
    offsetTop = 0,
    offsetLeft = 0,
    offsetWidth = 0,
    offsetHeight = 0,
    scrollLeft = 0,
    scrollWidth = 0,
    scrollTop = 0,
    scrollHeight = 0,
    clientWidth = 0,
    clientHeight = 0
  } = el ?? {};
  const measurements = {
    width: getSize(width, "width"),
    height: getSize(height, "height"),
    top: getSize(top, "top"),
    bottom: getSize(bottom, "bottom"),
    left: getSize(left, "left"),
    right: getSize(right, "right"),
    offsetTop,
    offsetLeft,
    offsetHeight,
    offsetWidth,
    clientWidth,
    clientHeight,
    scrollLeft,
    scrollWidth,
    scrollTop,
    scrollHeight
  };
  return measurements;
}
function getCssAttributeDataMap(el) {
  return objectMap(["margin", "border", "padding"], ({ value: attribute }) => {
    const properties = objectMap(["top", "bottom", "left", "right"], ({ value: baseProperty }) => {
      const attributeKey = `${attribute}${changeCase(baseProperty, "capitalize")}`;
      const value = el ? parseInt(getComputedStyle(el)[attributeKey]) : 0;
      return [baseProperty, value];
    });
    const { left, right, top, bottom } = properties;
    const width = left + right;
    const height = top + bottom;
    const attributeData = { width, height, left, right, top, bottom };
    return [attribute, attributeData];
  });
}
var ClampText = ({
  className,
  children,
  maxLines = 2,
  debounceTime,
  charWidth,
  showMoreInCollapisbleArea: showMoreInCollapisbleAreaProp,
  showMoreInTooltip: showMoreInTooltipProp,
  clampedElementType = "children",
  expandedElementType = "children",
  onExpandedChange,
  expanded: expandedProp,
  tooltipProps
}) => {
  const showMoreInTooltip = showMoreInTooltipProp;
  const showMoreInCollapisbleArea = showMoreInCollapisbleAreaProp ?? !showMoreInTooltip;
  const text = onlyText(children);
  const [expanded, setExpanded] = useState(false);
  function expand(v) {
    const enabled = v === void 0 ? !expanded : v;
    setExpanded(enabled);
    onExpandedChange?.(enabled);
  }
  const [ref, { clampedText, noClamp, key }] = useClampText({
    text,
    ellipsis: 8,
    lines: maxLines,
    debounceTime,
    charWidth,
    expanded: expandedProp ?? expanded
  });
  const isClamped = !noClamp;
  const [tooltipOpen, setTooltipOpen] = useState(false);
  const renderClampedReactNode = !expanded && clampedElementType === "children";
  const textElement = useMemo(() => {
    const clampedElement = expandedElementType === "children" ? truncateReactChildren(children, clampedText.length) : clampedText;
    const expandedElement = expandedElementType === "children" ? children : clampedText;
    return expanded ? expandedElement : clampedElement;
  }, [expanded, children, clampedText, expandedElementType]);
  return /* @__PURE__ */ jsx(
    Wrap,
    {
      if: showMoreInTooltip,
      wrap: (c) => {
        const { maxTooltipWidth, tooltipWidth, minTooltipWidth } = tooltipProps ?? {};
        return /* @__PURE__ */ jsxs(Tooltip.Root, { delayDuration: 100, open: tooltipOpen, disableHoverableContent: true, children: [
          /* @__PURE__ */ jsx(Tooltip.Trigger, { asChild: true, children: c }),
          /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx(
            Tooltip.Content,
            {
              colorScheme: "inverse",
              side: "bottom",
              className: "shadow-md shadow-palette-black/50",
              align: "center",
              selectNone: false,
              onTooltipClick: () => {
                setTooltipOpen(false);
              },
              size: "sm",
              maxWidth: false,
              style: {
                width: tooltipWidth,
                minWidth: minTooltipWidth,
                maxWidth: maxTooltipWidth ?? measureElement(ref).width
              },
              children: text
            }
          ) })
        ] });
      },
      children: /* @__PURE__ */ jsxs("div", { ref, className: twMerge$1(className, "relative group"), children: [
        /* @__PURE__ */ jsx(
          "span",
          {
            className: clsx4({
              "mr-8": expanded,
              "opacity-100 relative ": renderClampedReactNode,
              "whitespace-nowrap": !expanded && maxLines === 1
            }),
            children: textElement
          }
        ),
        expanded && /* @__PURE__ */ jsx(CollapseButton, { onClick: () => expand(false), children: "Collapse" }),
        isClamped && /* @__PURE__ */ jsx(
          Wrap,
          {
            if: showMoreInTooltip,
            wrap: (c) => {
              return /* @__PURE__ */ jsxs(
                Tooltip.Root,
                {
                  delayDuration: 150,
                  disableHoverableContent: true,
                  onOpenChange: (open) => {
                    setTooltipOpen(open);
                  },
                  children: [
                    /* @__PURE__ */ jsx(Tooltip.Trigger, { asChild: true, children: c }),
                    /* @__PURE__ */ jsx(
                      Tooltip.PrimitiveContent,
                      {
                        onPointerDownOutside: (e) => {
                          e.preventDefault();
                        }
                      }
                    )
                  ]
                }
              );
            },
            children: /* @__PURE__ */ jsx(
              EllipsisButton,
              {
                clickable: showMoreInCollapisbleArea,
                onClick: () => {
                  if (showMoreInCollapisbleArea) {
                    expand(true);
                  }
                },
                children: "..."
              }
            )
          }
        )
      ] }, key)
    }
  );
};
var TruncationButtonElement = classed(
  "button",
  "m-0 p-0 [font-size:inherit] text-inerit inline",
  "relative before-absolute-content",
  "leading-sm",
  "cursor-pointer",
  {
    variants: {
      clickable: {
        false: "cursor-default",
        true: "cursor-pointer"
      },
      enterAnimation: {
        true: clsx4(
          "opacity-0 ",
          "animate-fade-out ",
          "group-hover:animate-scale-in ",
          "group-hover:opacity-100 ",
          "group-hover:px-8 "
        )
      }
    }
  }
);
var TruncationButtonBackgroundElement = classed(
  "span",
  "absolute -inset-y-2 -inset-x-4 rounded-sm z-0 transition-colors shrink-0",
  {
    variants: {
      rounded: {
        sm: "rounded-sm",
        md: "rounded"
      },
      border: {
        true: "ring-1 ring-highlight-high"
      },
      backgroundHover: {
        true: "hover:!bg-highlight-high"
      },
      backgroundVisible: {
        true: "bg-highlight-subtle"
      },
      backgroundVisibleOnGroupHover: {
        true: "group-hover:bg-highlight-subtle"
      }
    },
    defaultVariants: {
      backgroundVisible: true,
      backgroundHover: true
    }
  }
);
var EllipsisButtonElement = classed(
  TruncationButtonElement,
  "group-hover:translate-x-6 transition-transform shrink-0 w-0"
);
var EllipsisButton = ({
  children,
  onClick,
  ...props
}) => {
  const clickable = Boolean(onClick);
  return /* @__PURE__ */ jsx(EllipsisButtonElement, { clickable, onClick, ...props, children: /* @__PURE__ */ jsxs("span", { className: "shrink-0 min-w-fit relative", children: [
    /* @__PURE__ */ jsx(
      TruncationButtonBackgroundElement,
      {
        backgroundHover: clickable,
        backgroundVisible: false,
        backgroundVisibleOnGroupHover: true,
        rounded: "md"
      }
    ),
    children
  ] }) });
};
var CollapseButtonElement = classed(TruncationButtonElement, "scale-90 select-none");
var CollapseButton = ({
  children,
  ...props
}) => {
  return /* @__PURE__ */ jsxs(CollapseButtonElement, { ...props, children: [
    children,
    /* @__PURE__ */ jsx(TruncationButtonBackgroundElement, { backgroundHover: true, backgroundVisible: true, border: true, rounded: "sm" })
  ] });
};
function truncateReactChildren(children, maxLength) {
  let currentLength = 0;
  const truncateChildrenRecursively = (child) => {
    if (currentLength >= maxLength) {
      return null;
    }
    if (typeof child === "string" || typeof child === "number") {
      const remainingLength = maxLength - currentLength;
      const truncatedText = child.toString().substring(0, remainingLength);
      currentLength += truncatedText.length;
      return truncatedText;
    }
    if (React2.isValidElement(child)) {
      const childProps = child.props;
      const renderChildren = childProps?.renderChildren;
      const childrenToProcess = renderChildren ? renderChildren() : childProps.children;
      const truncatedChildren2 = React2.Children.toArray(childrenToProcess).map(truncateChildrenRecursively).filter((child2) => child2 !== null);
      return React2.cloneElement(child, child.props, truncatedChildren2);
    }
    return null;
  };
  const truncatedChildren = React2.Children.toArray(children).map(truncateChildrenRecursively).filter((child) => child !== null);
  return truncatedChildren;
}

export { ClampText };
//# sourceMappingURL=out.js.map
//# sourceMappingURL=index.js.map