{"version":3,"file":"index.mjs","names":[],"sources":["../../src/components/RefToTgphRef/RefToTgphRef.tsx","../../src/components/TgphSlot/TgphSlot.tsx","../../src/components/VisuallyHidden/VisuallyHidden.tsx","../../src/hooks/useControllableState.ts","../../src/hooks/useDeterminateState.ts","../../src/base-ui/createTgphBaseUIRender.tsx","../../src/base-ui/compatibility.ts","../../src/base-ui/inferTriggerNativeButton.ts"],"sourcesContent":["import React from \"react\";\n\nconst FORWARD_REF_SYMBOL = Symbol.for(\"react.forward_ref\");\n\ntype ApplyRefPropsProps = {\n  children: React.ReactNode;\n};\n\ntype Child = React.ReactElement & {\n  $$typeof: symbol;\n  type: { $$typeof: symbol };\n};\n\nconst mergeProps = (\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  slotProps: Record<string, any>,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  childProps: Record<string, any>,\n) => {\n  // Match Slot-style precedence: child props win unless a prop needs composition.\n  const overrideProps = { ...childProps };\n\n  for (const propName in childProps) {\n    const slotPropValue = slotProps[propName];\n    const childPropValue = childProps[propName];\n\n    const isHandler = /^on[A-Z]/.test(propName);\n    if (isHandler) {\n      if (slotPropValue && childPropValue) {\n        overrideProps[propName] = (...args: unknown[]) => {\n          // Child handlers run first so they can observe their original event\n          // before the wrapper primitive reacts to it.\n          childPropValue(...args);\n          slotPropValue(...args);\n        };\n      } else if (slotPropValue) {\n        // Slot-only handlers still need to be forwarded when the child did not\n        // define that interaction prop itself.\n        overrideProps[propName] = slotPropValue;\n      }\n    } else if (propName === \"style\") {\n      // Keep both style objects while preserving child override behavior for\n      // conflicting keys.\n      overrideProps[propName] = { ...slotPropValue, ...childPropValue };\n    } else if (propName === \"className\") {\n      overrideProps[propName] = [slotPropValue, childPropValue]\n        .filter(Boolean)\n        .join(\" \");\n    }\n  }\n\n  return { ...slotProps, ...overrideProps };\n};\n\nconst applyRefProps = (\n  { children, ...props }: ApplyRefPropsProps,\n  ref: React.Ref<unknown>,\n) => {\n  if (!children) return null;\n  const childrenArray = React.Children.toArray(children);\n  return childrenArray.map((child) => {\n    if (React.isValidElement(child)) {\n      const validChild = child as Child;\n      const $$typeof = validChild.$$typeof;\n      const $$typeofType = validChild.type.$$typeof;\n      const childProps = validChild.props as Record<string, unknown>;\n      const tgphRef = childProps.tgphRef;\n\n      if (\n        $$typeof === FORWARD_REF_SYMBOL ||\n        $$typeofType === FORWARD_REF_SYMBOL\n      ) {\n        return React.cloneElement(validChild, {\n          ...mergeProps(props, childProps as Record<string, unknown>),\n          // ForwardRef children may be third-party components that only read\n          // `ref` or Telegraph components that still expect `tgphRef`.\n          tgphRef: tgphRef || ref,\n          ref: tgphRef || ref,\n        } as Record<string, unknown>);\n      }\n\n      return React.cloneElement(validChild, {\n        ...mergeProps(props, childProps as Record<string, unknown>),\n        // Plain function children cannot receive a React ref without warnings,\n        // so bridge through Telegraph's custom ref prop only.\n        tgphRef: tgphRef || ref,\n      } as Record<string, unknown>);\n    }\n\n    return child;\n  });\n};\n\n// This adapter accepts refs for many element types, so keeping the forwarded ref\n// generic avoids forcing every caller into one DOM element shape.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst RefToTgphRef = React.forwardRef<any, any>(\n  ({ children: childrenProp, ...props }, ref) => {\n    // Parent primitives can recreate ref callbacks every render; store the\n    // latest one behind a stable callback so cloned children do not see a new\n    // ref prop and loop.\n    const refStorage = React.useRef(ref);\n\n    // Track the currently mounted node so a ref identity change can be replayed\n    // without waiting for the child to remount.\n    const nodeStorage = React.useRef<unknown>(null);\n\n    React.useEffect(() => {\n      const prevRef = refStorage.current;\n      const currentNode = nodeStorage.current;\n\n      if (prevRef !== ref && currentNode) {\n        // Mirror React's native ref replacement behavior by clearing the old\n        // ref before attaching the latest ref to the already-mounted node.\n        if (typeof prevRef === \"function\") {\n          prevRef(null);\n        } else if (prevRef) {\n          (prevRef as React.MutableRefObject<unknown>).current = null;\n        }\n\n        if (typeof ref === \"function\") {\n          ref(currentNode);\n        } else if (ref) {\n          (ref as React.MutableRefObject<unknown>).current = currentNode;\n        }\n      }\n\n      refStorage.current = ref;\n    });\n\n    const stableRef = React.useCallback((node: unknown) => {\n      // Keep the node available for the effect above if the parent swaps refs\n      // after this callback was attached.\n      nodeStorage.current = node;\n\n      const currentRef = refStorage.current;\n\n      // The callback identity is stable, but the target ref it forwards to is\n      // always the latest parent ref from storage.\n      if (typeof currentRef === \"function\") {\n        currentRef(node);\n      } else if (currentRef) {\n        (currentRef as React.MutableRefObject<unknown>).current = node;\n      }\n    }, []);\n\n    return applyRefProps({ children: childrenProp, ...props }, stableRef);\n  },\n);\nRefToTgphRef.displayName = \"RefToTgphRef\";\n\nexport { RefToTgphRef };\n","import { mergeProps } from \"@base-ui/react/merge-props\";\nimport {\n  Children,\n  type ComponentPropsWithRef,\n  type MutableRefObject,\n  type ReactElement,\n  type ReactNode,\n  type Ref,\n  type RefAttributes,\n  cloneElement,\n  forwardRef,\n  isValidElement,\n  useCallback,\n  useEffect,\n  useRef,\n} from \"react\";\n\n// React marks forwardRef components with this symbol in the element metadata.\n// Checking it lets us decide whether a child can safely receive `ref`.\nconst FORWARD_REF_SYMBOL = Symbol.for(\"react.forward_ref\");\n\ntype TgphSlotProps = ComponentPropsWithRef<\"span\"> &\n  Record<string, unknown> & {\n    children?: ReactNode;\n  };\n\ntype SlottableChildProps = Record<string, unknown> &\n  RefAttributes<HTMLElement> & {\n    tgphRef?: Ref<HTMLElement>;\n  };\n\ntype IntrinsicMergeProps = ComponentPropsWithRef<\"span\">;\n\ntype ElementWithRef = ReactElement<SlottableChildProps> & {\n  $$typeof?: symbol;\n  ref?: Ref<HTMLElement>;\n  type:\n    | string\n    | {\n        $$typeof?: symbol;\n      };\n};\n\ntype WarningGetter = (() => unknown) & {\n  isReactWarning?: boolean;\n};\n\nconst isReactWarningGetter = (\n  getter: (() => unknown) | undefined,\n): getter is WarningGetter => {\n  return Boolean(getter && \"isReactWarning\" in getter && getter.isReactWarning);\n};\n\n// React 18 and 19 expose child refs differently. Reading the wrong location can\n// trigger React's dev warning getter, so mirror Radix's defensive extraction\n// before composing the wrapper ref with the child's existing ref.\nconst getElementRef = (element: ReactElement<SlottableChildProps>) => {\n  const propsRefGetter = Object.getOwnPropertyDescriptor(\n    element.props,\n    \"ref\",\n  )?.get;\n\n  if (isReactWarningGetter(propsRefGetter)) {\n    // React 18 can hide the real ref on the element when props.ref is only the\n    // dev warning getter, so read the element field in that case.\n    return (element as ElementWithRef).ref;\n  }\n\n  const elementRefGetter = Object.getOwnPropertyDescriptor(element, \"ref\")?.get;\n\n  if (isReactWarningGetter(elementRefGetter)) {\n    // React 19 moves refs into props; if element.ref is the warning getter,\n    // prefer the props ref so we do not trip the warning while composing refs.\n    return element.props.ref;\n  }\n\n  return element.props.ref ?? (element as ElementWithRef).ref;\n};\n\nconst setRef = <T,>(ref: Ref<T> | undefined, value: T | null) => {\n  if (typeof ref === \"function\") {\n    ref(value);\n  } else if (ref !== null && ref !== undefined) {\n    (ref as MutableRefObject<T | null>).current = value;\n  }\n};\n\nconst composeRefs = <T,>(...refs: (Ref<T> | undefined)[]) => {\n  return (node: T | null) => {\n    refs.forEach((ref) => setRef(ref, node));\n  };\n};\n\nconst getDefinedRefs = <T,>(refs: (Ref<T> | undefined)[]) => {\n  return refs.filter((ref): ref is Ref<T> => Boolean(ref));\n};\n\nconst areRefsEqual = <T,>(refs: Ref<T>[], nextRefs: Ref<T>[]) => {\n  return (\n    refs.length === nextRefs.length &&\n    refs.every((ref, index) => ref === nextRefs[index])\n  );\n};\n\nconst useStableComposedRefs = <T,>(...refs: (Ref<T> | undefined)[]) => {\n  const definedRefs = getDefinedRefs(refs);\n  const refsStorage = useRef(definedRefs);\n  const previousRefsStorage = useRef(definedRefs);\n  const nodeStorage = useRef<T | null>(null);\n\n  // Keep the returned callback stable while still giving it the latest refs.\n  refsStorage.current = definedRefs;\n\n  useEffect(() => {\n    const previousRefs = previousRefsStorage.current;\n    const currentRefs = refsStorage.current;\n    const currentNode = nodeStorage.current;\n\n    if (currentNode && !areRefsEqual(previousRefs, currentRefs)) {\n      // A child can add or remove refs between renders; clear removed refs and\n      // replay the mounted node to newly introduced refs without remounting it.\n      previousRefs.forEach((ref) => {\n        if (!currentRefs.includes(ref)) {\n          setRef(ref, null);\n        }\n      });\n\n      currentRefs.forEach((ref) => {\n        if (!previousRefs.includes(ref)) {\n          setRef(ref, currentNode);\n        }\n      });\n    }\n\n    previousRefsStorage.current = currentRefs;\n  });\n\n  const stableRef = useCallback((node: T | null) => {\n    // Store the latest node so the effect above can sync refs that appear after\n    // the callback was originally attached.\n    nodeStorage.current = node;\n    composeRefs(...refsStorage.current)(node);\n  }, []);\n\n  return definedRefs.length > 0 ? stableRef : undefined;\n};\n\nconst isIntrinsicElement = (element: ElementWithRef) => {\n  return typeof element.type === \"string\";\n};\n\nconst isForwardRefElement = (element: ElementWithRef) => {\n  return (\n    element.$$typeof === FORWARD_REF_SYMBOL ||\n    (typeof element.type !== \"string\" &&\n      element.type.$$typeof === FORWARD_REF_SYMBOL)\n  );\n};\n\nconst getRefProps = (\n  child: ReactElement<SlottableChildProps>,\n  composedRef: Ref<HTMLElement> | undefined,\n  composedTgphRef: Ref<HTMLElement> | undefined,\n) => {\n  const childTgphRef = child.props.tgphRef;\n\n  if (!composedRef && !childTgphRef) {\n    return {};\n  }\n\n  const element = child as ElementWithRef;\n\n  if (isIntrinsicElement(element)) {\n    return { ref: composedRef };\n  }\n\n  // ForwardRef children already have a standard React ref channel. Only keep\n  // the Telegraph ref channel when the child explicitly opted into tgphRef.\n  if (isForwardRefElement(element)) {\n    return {\n      ...(composedRef ? { ref: composedRef } : {}),\n      ...(childTgphRef && composedTgphRef ? { tgphRef: composedTgphRef } : {}),\n    };\n  }\n\n  // Plain function components cannot receive `ref` without React warnings, so\n  // pass only `tgphRef` for Telegraph-style components that do not forward refs.\n  return {\n    ...(composedTgphRef ? { tgphRef: composedTgphRef } : {}),\n  };\n};\n\nconst TgphSlot = forwardRef<HTMLElement, TgphSlotProps>(\n  ({ children, ...props }, forwardedRef) => {\n    // Match Radix Slot's one-child contract before cloning wrapper props into\n    // the child element.\n    const child = Children.only(children);\n    const slottableChild = isValidElement<SlottableChildProps>(child)\n      ? child\n      : null;\n    // Compose the wrapper ref with whichever ref API the child already uses so\n    // consumers keep their existing `ref` and `tgphRef` behavior.\n    const childRef = slottableChild ? getElementRef(slottableChild) : undefined;\n    const childTgphRef = slottableChild?.props.tgphRef;\n    const composedRef = useStableComposedRefs(forwardedRef, childRef);\n    const composedTgphRef = useStableComposedRefs(forwardedRef, childTgphRef);\n\n    if (!slottableChild) {\n      return null;\n    }\n\n    return cloneElement(slottableChild, {\n      // Merge events, className, and data attributes before assigning the\n      // compatible ref props chosen for this specific child shape.\n      ...mergeProps(\n        props as IntrinsicMergeProps,\n        slottableChild.props as IntrinsicMergeProps,\n      ),\n      ...getRefProps(slottableChild, composedRef, composedTgphRef),\n    });\n  },\n);\nTgphSlot.displayName = \"TgphSlot\";\n\nexport { TgphSlot };\nexport type { TgphSlotProps };\n","import {\n  type CSSProperties,\n  type ComponentPropsWithoutRef,\n  type ReactNode,\n} from \"react\";\n\nimport { TgphSlot } from \"../TgphSlot\";\n\n// Shared a11y-only styles used by migrated primitives that previously relied on\n// Radix VisuallyHidden. Keep this object frozen so callers cannot mutate the\n// base style contract across component instances.\nconst VISUALLY_HIDDEN_STYLES = Object.freeze({\n  position: \"absolute\",\n  border: 0,\n  width: 1,\n  height: 1,\n  padding: 0,\n  margin: -1,\n  overflow: \"hidden\",\n  clip: \"rect(0, 0, 0, 0)\",\n  whiteSpace: \"nowrap\",\n  wordWrap: \"normal\",\n} satisfies CSSProperties);\n\nexport type VisuallyHiddenProps = ComponentPropsWithoutRef<\"span\"> & {\n  asChild?: boolean;\n  children?: ReactNode;\n};\n\nconst getVisuallyHiddenStyle = (\n  style: CSSProperties | undefined,\n): CSSProperties => {\n  return {\n    ...VISUALLY_HIDDEN_STYLES,\n    ...style,\n  };\n};\n\nexport const VisuallyHidden = ({\n  asChild = false,\n  style,\n  ...props\n}: VisuallyHiddenProps) => {\n  const visuallyHiddenProps = {\n    style: getVisuallyHiddenStyle(style),\n    ...props,\n  };\n\n  if (asChild) {\n    // `asChild` lets consumers hide an existing semantic node, such as `label`\n    // or Base UI's title/description element, without adding an extra wrapper.\n    return <TgphSlot {...visuallyHiddenProps} />;\n  }\n\n  return <span {...visuallyHiddenProps} />;\n};\n","import {\n  type SetStateAction,\n  useCallback,\n  useEffect,\n  useRef,\n  useState,\n} from \"react\";\n\nexport type UseControllableStateParams<T> = {\n  defaultProp: T;\n  onChange?: (value: T) => void;\n  prop?: T;\n};\n\nexport const useControllableState = <T>({\n  defaultProp,\n  onChange,\n  prop,\n}: UseControllableStateParams<T>) => {\n  const [uncontrolledValue, setUncontrolledValue] = useState(defaultProp);\n  // Keep the current uncontrolled value available to the setter without making\n  // the setter depend on every value change. That keeps callback identity stable\n  // for component primitives that pass setters through context.\n  const uncontrolledValueRef = useRef(uncontrolledValue);\n  // `undefined` keeps the previous Radix-style contract: anything else means\n  // the caller owns the value and we only emit changes.\n  const isControlled = prop !== undefined;\n  const value = isControlled ? prop : uncontrolledValue;\n\n  useEffect(() => {\n    uncontrolledValueRef.current = uncontrolledValue;\n  }, [uncontrolledValue]);\n\n  const setValue = useCallback(\n    (nextValueOrUpdater: SetStateAction<T>) => {\n      // React-style updater functions need the freshest value from the active\n      // source, not a stale value captured when this setter was created.\n      const currentValue = isControlled ? prop : uncontrolledValueRef.current;\n      const nextValue =\n        typeof nextValueOrUpdater === \"function\"\n          ? (nextValueOrUpdater as (previousValue: T) => T)(currentValue)\n          : nextValueOrUpdater;\n\n      if (Object.is(currentValue, nextValue)) {\n        return;\n      }\n\n      if (!isControlled) {\n        // Update the ref before React commits state so multiple same-tick setter\n        // calls compare against the latest queued uncontrolled value.\n        uncontrolledValueRef.current = nextValue;\n        setUncontrolledValue(nextValue);\n      }\n\n      onChange?.(nextValue);\n    },\n    [isControlled, onChange, prop],\n  );\n\n  return [value, setValue] as const;\n};\n","/*\n * useDeterminateState\n *\n * A hook that returns a state transitioning to a determinate value after a minimum duration.\n * For example, you could use this hook with a button that transitions into a \"loading\" state,\n * ensuring it remains in the \"loading\" state for at least 1000ms. This provides clear feedback\n * to the user that the action is being processed.\n *\n */\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\ntype UseDeterminateStateParams<T> = {\n  value: T;\n  determinateValue: T;\n  minDurationMs?: number;\n};\n\nconst useDeterminateState = <T>({\n  value,\n  determinateValue,\n  minDurationMs = 1000,\n}: UseDeterminateStateParams<T>): T => {\n  const [state, setState] = useState<T>(value);\n  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n  const startTimeRef = useRef<number | null>(null);\n\n  const clearExistingTimeout = () => {\n    if (timeoutRef.current) {\n      clearTimeout(timeoutRef.current);\n      timeoutRef.current = null;\n    }\n  };\n\n  const handleTransition = useCallback(() => {\n    if (value === determinateValue) {\n      clearExistingTimeout();\n      setState(determinateValue);\n      startTimeRef.current = Date.now();\n    } else if (startTimeRef.current !== null) {\n      const elapsedTime = Date.now() - startTimeRef.current;\n      const remainingTime = minDurationMs - elapsedTime;\n\n      if (remainingTime > 0) {\n        clearExistingTimeout();\n        timeoutRef.current = setTimeout(() => {\n          setState(value);\n          startTimeRef.current = null;\n        }, remainingTime);\n      } else {\n        setState(value);\n        startTimeRef.current = null;\n      }\n    } else {\n      setState(value);\n    }\n  }, [value, determinateValue, minDurationMs]);\n\n  useEffect(() => {\n    handleTransition();\n    return clearExistingTimeout;\n  }, [value, handleTransition]);\n\n  return state;\n};\n\nexport { useDeterminateState };\n","import type { ComponentRenderFn, HTMLProps } from \"@base-ui/react/use-render\";\nimport { type ReactElement, type Ref, isValidElement } from \"react\";\n\nimport { TgphSlot } from \"../components/TgphSlot\";\n\ntype PropsWithRef = HTMLProps & {\n  ref?: Ref<unknown>;\n};\n\ntype TgphBaseUIRenderElement<State = Record<string, unknown>> =\n  | ReactElement\n  | ((state: State) => ReactElement);\n\ntype GetRenderElementParams<State> = {\n  element: TgphBaseUIRenderElement<State>;\n  state: State;\n};\n\ntype RenderWithTgphSlotParams = {\n  props: PropsWithRef;\n  renderElement: ReactElement;\n};\n\nconst getRenderElement = <State = Record<string, unknown>,>({\n  element,\n  state,\n}: GetRenderElementParams<State>) => {\n  if (typeof element === \"function\") {\n    return element(state);\n  }\n\n  return element;\n};\n\nconst renderWithTgphSlot = ({\n  props,\n  renderElement,\n}: RenderWithTgphSlotParams) => {\n  // Base UI gives render targets a standard React ref; TgphSlot decides whether\n  // that ref should stay on `ref` or be bridged onto Telegraph's `tgphRef`.\n  const { ref } = props;\n\n  return (\n    <TgphSlot {...props} ref={ref as Ref<HTMLElement>}>\n      {renderElement}\n    </TgphSlot>\n  );\n};\n\nconst createTgphBaseUIRender = <\n  Props extends HTMLProps = HTMLProps,\n  State = Record<string, unknown>,\n>(\n  element: TgphBaseUIRenderElement<State>,\n): ComponentRenderFn<Props, State> => {\n  return (props, state) => {\n    // Base UI may call `render` with live state, so resolve function children\n    // before asking TgphSlot to merge props into the concrete element.\n    const renderElement = getRenderElement({ element, state });\n\n    if (!isValidElement(renderElement)) {\n      return renderElement;\n    }\n\n    // Keep native elements, forwardRef components, and tgphRef-only components\n    // on the same prop/ref composition path.\n    return renderWithTgphSlot({\n      props: props as PropsWithRef,\n      renderElement,\n    });\n  };\n};\n\nexport { createTgphBaseUIRender };\nexport type { TgphBaseUIRenderElement };\n","import type { CSSProperties } from \"react\";\n\nconst ANIMATION_OFFSET = 5;\nconst BASE_UI_DISMISS_REASONS = {\n  escapeKey: \"escape-key\",\n  focusOut: \"focus-out\",\n  outsidePress: \"outside-press\",\n} as const;\n\ntype BaseUIChangeDetails = {\n  event: Event;\n  reason?: string;\n};\n\ntype BaseUIFloatingSide =\n  | \"top\"\n  | \"bottom\"\n  | \"left\"\n  | \"right\"\n  | \"inline-start\"\n  | \"inline-end\";\n\ntype LegacyDismissEventHandler<TEvent extends Event = Event> = (\n  event: TEvent,\n) => void;\n\ntype LegacyDismissHandlers = {\n  onEscapeKeyDown?: LegacyDismissEventHandler<KeyboardEvent>;\n  onFocusOutside?: LegacyDismissEventHandler<FocusEvent | KeyboardEvent>;\n  onInteractOutside?: LegacyDismissEventHandler;\n  onPointerDownOutside?: LegacyDismissEventHandler<\n    MouseEvent | PointerEvent | TouchEvent\n  >;\n};\n\ntype BaseUIPositionerVisibilityStyleParams = {\n  anchorHidden: boolean;\n  hideWhenDetached?: boolean;\n  zIndex?: CSSProperties[\"zIndex\"];\n};\n\nconst callLegacyEventHandler = <TEvent extends Event>(\n  handler: LegacyDismissEventHandler<TEvent> | undefined,\n  event: TEvent,\n) => {\n  handler?.(event);\n  return event.defaultPrevented;\n};\n\nconst callLegacyDismissHandlers = (\n  eventDetails: BaseUIChangeDetails,\n  callbacks: LegacyDismissHandlers,\n) => {\n  const { event, reason } = eventDetails;\n\n  if (reason === BASE_UI_DISMISS_REASONS.escapeKey) {\n    // Radix exposed escape as a typed keyboard callback, so preserve that event\n    // shape even though Base UI sends all dismiss reasons through one details object.\n    return callLegacyEventHandler(\n      callbacks.onEscapeKeyDown,\n      event as KeyboardEvent,\n    );\n  }\n\n  if (reason === BASE_UI_DISMISS_REASONS.outsidePress) {\n    // Radix fired both pointer-specific and generic outside-interaction hooks;\n    // cancellation from either one should block Base UI's dismiss.\n    const pointerDismissPrevented = callLegacyEventHandler(\n      callbacks.onPointerDownOutside,\n      event as MouseEvent | PointerEvent | TouchEvent,\n    );\n    const interactDismissPrevented = callLegacyEventHandler(\n      callbacks.onInteractOutside,\n      event,\n    );\n\n    return pointerDismissPrevented || interactDismissPrevented;\n  }\n\n  if (reason === BASE_UI_DISMISS_REASONS.focusOut) {\n    // Focus-out maps to Radix's focus-specific hook and the broader\n    // interaction hook, matching the previous callback cascade.\n    const focusDismissPrevented = callLegacyEventHandler(\n      callbacks.onFocusOutside,\n      event as FocusEvent | KeyboardEvent,\n    );\n    const interactDismissPrevented = callLegacyEventHandler(\n      callbacks.onInteractOutside,\n      event,\n    );\n\n    return focusDismissPrevented || interactDismissPrevented;\n  }\n\n  return false;\n};\n\nconst getBaseUIMotionOffset = (\n  side: BaseUIFloatingSide | undefined,\n  offset = ANIMATION_OFFSET,\n) => {\n  // Base UI includes logical sides, but Telegraph's existing animation only\n  // offsets physical sides; logical sides intentionally fall through to no offset.\n  if (side === \"top\") {\n    return {\n      y: -offset,\n    };\n  }\n\n  if (side === \"bottom\") {\n    return {\n      y: offset,\n    };\n  }\n\n  if (side === \"left\") {\n    return {\n      x: -offset,\n    };\n  }\n\n  if (side === \"right\") {\n    return {\n      x: offset,\n    };\n  }\n\n  return {};\n};\n\nconst getBaseUIPositionerVisibilityStyle = ({\n  anchorHidden,\n  hideWhenDetached,\n  zIndex,\n}: BaseUIPositionerVisibilityStyleParams): CSSProperties => {\n  return {\n    // Radix's `hideWhenDetached` hid content without unmounting it; Base UI\n    // reports anchor visibility through render state instead.\n    visibility: hideWhenDetached && anchorHidden ? \"hidden\" : undefined,\n    zIndex,\n  };\n};\n\nexport {\n  callLegacyDismissHandlers,\n  getBaseUIMotionOffset,\n  getBaseUIPositionerVisibilityStyle,\n};\nexport type {\n  BaseUIChangeDetails,\n  BaseUIFloatingSide,\n  BaseUIPositionerVisibilityStyleParams,\n  LegacyDismissEventHandler,\n  LegacyDismissHandlers,\n};\n","import { type ReactNode, isValidElement } from \"react\";\n\nimport type { TgphElement } from \"../types/utility\";\n\nconst MOTION_COMPONENT_SYMBOL = Symbol.for(\"motionComponentSymbol\");\nconst NATIVE_BUTTON_RESOLVER_SYMBOL = Symbol.for(\n  \"@telegraph/native-button-resolver\",\n);\n\ntype NativeButtonComponent = string | TgphElement;\n\ntype NativeButtonResolver = (\n  props?: unknown,\n  nativeButton?: boolean,\n) => boolean | undefined;\n\ntype ResolvableComponent = {\n  [MOTION_COMPONENT_SYMBOL]?: NativeButtonComponent;\n  [NATIVE_BUTTON_RESOLVER_SYMBOL]?: NativeButtonResolver;\n};\n\ntype DefineNativeButtonResolverOptions = {\n  component: object;\n  resolver: NativeButtonResolver;\n};\n\ntype DefineNativeButtonResolver = (\n  options: DefineNativeButtonResolverOptions,\n) => void;\n\n// Defines component-specific semantics on a global symbol so separate\n// Telegraph package instances can resolve the same component.\nconst defineNativeButtonResolver: DefineNativeButtonResolver = ({\n  component,\n  resolver,\n}) => {\n  Object.defineProperty(component, NATIVE_BUTTON_RESOLVER_SYMBOL, {\n    configurable: true,\n    value: resolver,\n  });\n};\n\ntype ResolveNativeButtonOptions = {\n  component: NativeButtonComponent;\n  nativeButton?: boolean;\n  props?: unknown;\n};\n\ntype ResolveNativeButton = (\n  options: ResolveNativeButtonOptions,\n) => boolean | undefined;\n\n// Resolves explicit, intrinsic, registered, and Motion component semantics.\n// Unknown components remain undefined unless the caller supplies a value.\nconst resolveNativeButton: ResolveNativeButton = ({\n  component,\n  nativeButton,\n  props,\n}) => {\n  if (typeof component === \"string\") {\n    return nativeButton ?? component === \"button\";\n  }\n\n  if (\n    (typeof component !== \"function\" && typeof component !== \"object\") ||\n    component === null\n  ) {\n    return undefined;\n  }\n\n  const resolvableComponent = component as ResolvableComponent;\n  const resolver = resolvableComponent[NATIVE_BUTTON_RESOLVER_SYMBOL];\n\n  if (resolver) {\n    return resolver(props, nativeButton);\n  }\n\n  const motionComponent = resolvableComponent[MOTION_COMPONENT_SYMBOL];\n\n  if (motionComponent && motionComponent !== component) {\n    return resolveNativeButton({\n      component: motionComponent,\n      nativeButton,\n      props,\n    });\n  }\n\n  return nativeButton;\n};\n\ntype InferTriggerNativeButtonOptions = {\n  asChild: boolean;\n  children: ReactNode;\n  nativeButton?: boolean;\n};\n\ntype InferTriggerNativeButton = (\n  options: InferTriggerNativeButtonOptions,\n) => boolean;\n\n// Resolves composed trigger semantics from its child and otherwise preserves\n// Base UI's native-button default.\nconst inferTriggerNativeButton: InferTriggerNativeButton = ({\n  asChild,\n  children,\n  nativeButton,\n}) => {\n  if (!asChild || !isValidElement(children)) {\n    return nativeButton ?? true;\n  }\n\n  return (\n    resolveNativeButton({\n      component: children.type,\n      nativeButton,\n      props: children.props,\n    }) ?? true\n  );\n};\n\nexport {\n  defineNativeButtonResolver,\n  inferTriggerNativeButton,\n  resolveNativeButton,\n  type DefineNativeButtonResolverOptions,\n  type InferTriggerNativeButtonOptions,\n  type NativeButtonResolver,\n  type ResolveNativeButtonOptions,\n};\n"],"mappings":"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"}