{"version":3,"file":"useNativeButton.mjs","names":[],"sources":["../../src/hooks/useNativeButton.ts"],"sourcesContent":["import { isValidElement, type ReactElement, type ReactNode, useMemo } from 'react';\n\nexport interface UseNativeButtonOptions {\n  /**\n   * The children element that will be used as the trigger\n   */\n  children: ReactNode;\n  /**\n   * User-provided nativeButton prop\n   */\n  nativeButton?: boolean;\n  /**\n   * Additional nativeButton from trigger props (for DropdownMenu)\n   */\n  triggerNativeButton?: boolean;\n}\n\nexport interface UseNativeButtonResult {\n  /**\n   * Whether the trigger element is a native button\n   */\n  isNativeButtonTriggerElement: boolean;\n  /**\n   * The resolved nativeButton value to pass to Base UI components\n   */\n  resolvedNativeButton: boolean | undefined;\n}\n\n/**\n * Map of component displayNames to their nativeButton values.\n * Components that render native <button> elements should be true,\n * components that render non-button elements should be false.\n */\nconst NATIVE_BUTTON_MAP: Record<string, boolean> = {\n  A: false,\n  ActionIcon: false,\n  ActionIconGroup: false,\n  Alert: false,\n  Avatar: false,\n  AvatarGroup: false,\n  Block: false,\n  BottomGradientButton: true,\n  Burger: false,\n  Button: true,\n  Center: false,\n  Checkbox: false,\n  CheckboxGroup: false,\n  Collapse: false,\n  ColorSwatches: false,\n  CopyButton: false,\n  DownloadButton: false,\n  EditableText: false,\n  Empty: false,\n  FileTypeIcon: false,\n  Flexbox: false,\n  FluentEmoji: false,\n  GradientButton: true,\n  Highlighter: false,\n  Hotkey: false,\n  Icon: false,\n  Image: false,\n  Img: false,\n  Input: false,\n  InputNumber: false,\n  InputPassword: false,\n  List: false,\n  ListItem: false,\n  Select: false,\n  Switch: false,\n  Markdown: false,\n  MaterialFileTypeIcon: false,\n  Segmented: false,\n  Skeleton: false,\n  SkeletonAvatar: false,\n  SkeletonBlock: false,\n  SkeletonButton: false,\n  SkeletonParagraph: false,\n  SkeletonTags: false,\n  SkeletonTitle: false,\n  Snippet: false,\n  Tag: false,\n  Text: false,\n  TextArea: false,\n  ThemeSwitch: false,\n  Video: false,\n};\n\n/**\n * Get the displayName of a React component from an element.\n * Handles function components, forwardRef, memo, etc.\n */\nfunction getComponentDisplayName(element: ReactElement): string | undefined {\n  const type = element.type;\n\n  if (typeof type === 'string') return undefined;\n\n  if (typeof type === 'function') {\n    return (type as any).displayName || type.name;\n  }\n\n  if (typeof type === 'object' && type !== null) {\n    // Handle forwardRef, memo, etc.\n    const displayName =\n      (type as any).displayName ||\n      (type as any).render?.displayName ||\n      (type as any).render?.name ||\n      (type as any).type?.displayName ||\n      (type as any).type?.name;\n    return displayName;\n  }\n\n  return undefined;\n}\n\n/**\n * Hook to resolve nativeButton prop for Base UI trigger components.\n *\n * When using `render`, Base UI expects the rendered element to be a native <button> by default.\n * If we can infer it's not, we opt out to avoid warnings (users can still override via `nativeButton`).\n */\nexport function useNativeButton({\n  children,\n  nativeButton,\n  triggerNativeButton,\n}: UseNativeButtonOptions): UseNativeButtonResult {\n  const isNativeButtonTriggerElement = useMemo(() => {\n    if (!isValidElement(children)) return false;\n    return typeof children.type === 'string' && children.type === 'button';\n  }, [children]);\n\n  const resolvedNativeButton = useMemo(() => {\n    // User-provided nativeButton takes highest priority\n    if (nativeButton !== undefined) return nativeButton;\n    // Trigger props nativeButton (for DropdownMenu) takes second priority\n    if (triggerNativeButton !== undefined) return triggerNativeButton;\n    // If it's a native button element, return true\n    if (isNativeButtonTriggerElement) return true;\n    // If children is not a valid element, let Base UI decide\n    if (!isValidElement(children)) return undefined;\n    // If it's a string type but not a button (e.g., 'div'), return false\n    if (typeof children.type === 'string') return false;\n\n    // Check if it's a known component from the library\n    const displayName = getComponentDisplayName(children);\n    if (displayName && displayName in NATIVE_BUTTON_MAP) {\n      return NATIVE_BUTTON_MAP[displayName];\n    }\n\n    // For unknown React components, default to false to avoid warnings\n    // since most custom components don't render native buttons\n    return false;\n  }, [children, isNativeButtonTriggerElement, nativeButton, triggerNativeButton]);\n\n  return {\n    isNativeButtonTriggerElement,\n    resolvedNativeButton,\n  };\n}\n"],"mappings":";;;;;;;AAiCA,MAAM,oBAA6C;CACjD,GAAG;CACH,YAAY;CACZ,iBAAiB;CACjB,OAAO;CACP,QAAQ;CACR,aAAa;CACb,OAAO;CACP,sBAAsB;CACtB,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,eAAe;CACf,UAAU;CACV,eAAe;CACf,YAAY;CACZ,gBAAgB;CAChB,cAAc;CACd,OAAO;CACP,cAAc;CACd,SAAS;CACT,aAAa;CACb,gBAAgB;CAChB,aAAa;CACb,QAAQ;CACR,MAAM;CACN,OAAO;CACP,KAAK;CACL,OAAO;CACP,aAAa;CACb,eAAe;CACf,MAAM;CACN,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,sBAAsB;CACtB,WAAW;CACX,UAAU;CACV,gBAAgB;CAChB,eAAe;CACf,gBAAgB;CAChB,mBAAmB;CACnB,cAAc;CACd,eAAe;CACf,SAAS;CACT,KAAK;CACL,MAAM;CACN,UAAU;CACV,aAAa;CACb,OAAO;CACR;;;;;AAMD,SAAS,wBAAwB,SAA2C;CAC1E,MAAM,OAAO,QAAQ;AAErB,KAAI,OAAO,SAAS,SAAU,QAAO,KAAA;AAErC,KAAI,OAAO,SAAS,WAClB,QAAQ,KAAa,eAAe,KAAK;AAG3C,KAAI,OAAO,SAAS,YAAY,SAAS,KAQvC,QALG,KAAa,eACb,KAAa,QAAQ,eACrB,KAAa,QAAQ,QACrB,KAAa,MAAM,eACnB,KAAa,MAAM;;;;;;;;AAa1B,SAAgB,gBAAgB,EAC9B,UACA,cACA,uBACgD;CAChD,MAAM,+BAA+B,cAAc;AACjD,MAAI,CAAC,eAAe,SAAS,CAAE,QAAO;AACtC,SAAO,OAAO,SAAS,SAAS,YAAY,SAAS,SAAS;IAC7D,CAAC,SAAS,CAAC;AAyBd,QAAO;EACL;EACA,sBAzB2B,cAAc;AAEzC,OAAI,iBAAiB,KAAA,EAAW,QAAO;AAEvC,OAAI,wBAAwB,KAAA,EAAW,QAAO;AAE9C,OAAI,6BAA8B,QAAO;AAEzC,OAAI,CAAC,eAAe,SAAS,CAAE,QAAO,KAAA;AAEtC,OAAI,OAAO,SAAS,SAAS,SAAU,QAAO;GAG9C,MAAM,cAAc,wBAAwB,SAAS;AACrD,OAAI,eAAe,eAAe,kBAChC,QAAO,kBAAkB;AAK3B,UAAO;KACN;GAAC;GAAU;GAA8B;GAAc;GAAoB,CAAC;EAK9E"}