import React, { ReactNode } from 'react';
import { ButtonProps } from '../button/interfaces';
import { ExpandToViewport } from '../dropdown/interfaces';
import { IconProps } from '../icon/interfaces';
import { BaseComponentProps } from '../types/base-component';
import { BaseNavigationDetail, CancelableEventHandler } from '../types/events';
/**
 * @awsuiSystem core
 */
import { NativeAttributes } from '../types/native-attributes';
export interface ButtonDropdownProps extends BaseComponentProps, ExpandToViewport {
  /**
   * Array of objects with a number of supported types.
   *
   * The following properties are supported across all types:
   *
   * - `type` (string) - The type of the item. Can be `action`, `group`, `checkbox`. Defaults to `action` if `items` undefined and `group` otherwise.
   * - `id` (string) - allows to identify the item that the user clicked on. Mandatory for individual items, optional for categories.
   * - `text` (string) - description shown in the menu for this item. Mandatory for individual items, optional for categories.
   * - `lang` (string) - (Optional) The language of the item, provided as a BCP 47 language tag.
   * - `disabled` (boolean) - whether the item is disabled. Disabled items are not clickable, but they can be highlighted with the keyboard to make them accessible.
   * - `disabledReason` (string) - (Optional) Displays text near the `text` property when item is disabled. Use to provide additional context.
   * - `description` (string) - additional data that will be passed to a `data-description` attribute. **Deprecated**, has no effect.
   * - `ariaLabel` (string) - (Optional) - ARIA label of the item element.
   * - `dataAttributes` (Record<string, string>) - (Optional) Custom data attributes for the item element. Attribute names are automatically prefixed with "data-". The "testid" key is reserved.
   *
   * ### action
   *
   * - `href` (string) - (Optional) Defines the target URL of the menu item, turning it into a link.
   * - `download` (boolean | string) - (Optional) Indicates that the link should be downloaded when clicked. Only works when `href` is also provided. If set to `true`, the browser will use the filename from the URL. If set to a string, that string will be used as the suggested filename.
   * - `external` (boolean) - Marks a menu item as external by adding an icon after the menu item text. The link will open in a new tab when clicked. Note that this only works when `href` is also provided.
   * - `externalIconAriaLabel` (string) - Adds an `aria-label` to the external icon.
   * - `iconName` (string) - (Optional) Specifies the name of the icon, used with the [icon component](/components/icon/).
   * - `iconAlt` (string) - (Optional) Specifies alternate text for the icon when using `iconUrl`.
   * - `iconUrl` (string) - (Optional) Specifies the URL of a custom icon.
   * - `iconSvg` (ReactNode) - (Optional) Custom SVG icon. Equivalent to the `svg` slot of the [icon component](/components/icon/).
   * - `secondaryText` (string) - (Optional) Further information about the action that appears below the label.
   * - `labelTag` (string) - (Optional) - A label tag that provides additional guidance, shown next to the label.
   *
   * ### checkbox
   *
   * When `type` is set to "checkbox", the values set to `href`, `external` and `externalIconAriaLabel` will be ignored.
   *
   * - `checked` (boolean) - Controls the state of the checkbox item.
   * - `iconName` (string) - (Optional) Specifies the name of the icon, used with the [icon component](/components/icon/).
   * - `iconAlt` (string) - (Optional) Specifies alternate text for the icon when using `iconUrl`.
   * - `iconUrl` (string) - (Optional) Specifies the URL of a custom icon.
   * - `iconSvg` (ReactNode) - (Optional) Custom SVG icon. Equivalent to the `svg` slot of the [icon component](/components/icon/).
   * - `secondaryText` (string) - (Optional) Further information about the action that appears below the label.
   * - `labelTag` (string) - (Optional) - A label tag that provides additional guidance, shown next to the label.
   *
   * ### group
   *
   * - `items` (ReadonlyArray<Item>) - an array of item objects. Items will be rendered as nested menu items but only for the first nesting level, multi-nesting is not supported.
   * An item which belongs to nested group has the following properties: `id`, `text`, `disabled`, and `description`.
   *
   */
  items: ReadonlyArray<ButtonDropdownProps.ItemOrGroup>;
  /**
   * Specifies a render function to render custom options in the dropdown menu.
   *
   * The item inside the props has a different shape depending on its type:
   *
   *
   * ### action
   *
   * - `type` ('action') - The item type.
   * - `index` (number) - The item's position relative to its parent.
   * - `option` (Item) - The original item configuration.
   * - `highlighted` (boolean) - Whether the item is currently highlighted.
   * - `disabled` (boolean) - Whether the item is disabled.
   * - `parent` (GroupRenderItem | null) - The parent group item, if any.
   *
   * ### checkbox
   *
   * - `type` ('checkbox') - The item type.
   * - `index` (number) - The item's position relative to its parent.
   * - `option` (CheckboxItem) - The original item configuration.
   * - `disabled` (boolean) - Whether the item is disabled.
   * - `highlighted` (boolean) - Whether the item is currently highlighted.
   * - `checked` (boolean) - Controls the state of the checkbox item.
   * - `parent` (GroupRenderItem | null) - The parent group item, if any.
   *
   * ### group
   *
   * - `type` ('group') - The item type.
   * - `index` (number) - The item's position in the list.
   * - `option` (ItemGroup) - The original item configuration.
   * - `disabled` (boolean) - Whether the item is disabled.
   * - `highlighted` (boolean) - Whether the item is currently highlighted.
   * - `expanded` (boolean) - Whether the group is expanded.
   * - `expandDirection` ('vertical' | 'horizontal') - The direction in which the group expands.
   *
   * When providing a custom `renderItem` implementation, it fully replaces the default visual rendering and content for that item.
   * The component still manages focus, keyboard interactions, and selection state, but it no longer applies its default item layout or typography.
   *
   * When returning `null`, the default styling will be applied.
   */
  renderItem?: ButtonDropdownProps.ItemRenderer;
  /**
   * Determines whether the button dropdown is disabled. Users cannot interact with the control if it's disabled.
   */
  disabled?: boolean;
  /**
   * Provides a reason why the button dropdown is disabled (only when `disabled` is `true`).
   * If provided, the disabled button becomes focusable.
   */
  disabledReason?: string;
  /**
   * Renders the button as being in a loading state. It takes precedence over the `disabled` if both are set to `true`.
   * It prevents clicks.
   */
  loading?: boolean;
  /**
   * Specifies the text that screen reader announces when the button dropdown is in a loading state.
   */
  loadingText?: string;
  /** Determines the general styling of the button dropdown.
   * * `primary` for primary buttons
   * * `normal` for secondary buttons
   * * `icon` for icon buttons
   * * `inline-icon` for icon buttons with no outer padding
   */
  variant?: ButtonDropdownProps.Variant;
  /**
   * Specifies the name of the icon used in the button dropdown trigger, used with the [icon component](/components/icon/).
   * Defaults to `ellipsis`. Applies to the `icon` and `inline-icon` variants only.
   */
  iconName?: IconProps.Name;
  /**
   * Specifies alternate text for a custom icon, for use with `iconUrl`. Applies to the `icon` and `inline-icon` variants only.
   */
  iconAlt?: string;
  /**
   * Specifies the URL of a custom icon. Applies to the `icon` and `inline-icon` variants only.
   *
   * If you set both `iconUrl` and `iconSvg`, `iconSvg` will take precedence.
   */
  iconUrl?: string;
  /**
   * Custom SVG icon. Equivalent to the `svg` slot of the [icon component](/components/icon/).
   * Applies to the `icon` and `inline-icon` variants only.
   *
   * If you set both `iconUrl` and `iconSvg`, `iconSvg` will take precedence.
   */
  iconSvg?: React.ReactNode;
  /**
   * Controls expandability of the item groups.
   */
  expandableGroups?: boolean;
  /**
   * Adds `aria-label` to the button dropdown trigger.
   * Use this to provide an accessible name for buttons that don't have visible text.
   */
  ariaLabel?: string;
  /**
   * Text displayed in the button dropdown trigger.
   * @displayname text
   */
  children?: React.ReactNode;
  /**
   * Called when the user clicks on an item, and the item is not disabled.  The event detail object contains the id of the clicked item.
   */
  onItemClick?: CancelableEventHandler<ButtonDropdownProps.ItemClickDetails>;
  /**
   * Called when the user clicks on an item with the left mouse button without pressing
   * modifier keys (that is, CTRL, ALT, SHIFT, META), and the item has an `href` set.
   */
  onItemFollow?: CancelableEventHandler<ButtonDropdownProps.ItemClickDetails>;
  /**
   * A standalone action that is shown prior to the dropdown trigger.
   * Use it with "primary" and "normal" variant only.
   *
   * Main action properties:
   * * `text` (string) - Specifies the text shown in the main action.
   * * `external` (boolean) - Marks the main action as external by adding an icon after the text. The link will open in a new tab when clicked. Note that this only works when `href` is also provided.
   * * `externalIconAriaLabel` (string) - Adds an ARIA label to the external icon.
   *
   * The main action also supports the following properties of the [button](/components/button/?tabId=api) component:
   * `ariaLabel`, `disabled`, `loading`, `loadingText`, `href`, `target`, `rel`, `download`, `iconAlt`, `iconName`, `iconUrl`, `iconSvg`, `onClick`, `onFollow`.
   */
  mainAction?: ButtonDropdownProps.MainAction;
  /**
   * Sets the button width to be 100% of the parent container width. Button content is centered.
   */
  fullWidth?: boolean;
  /**
   * Attributes to add to the native `button` element.
   * Some attributes will be automatically combined with internal attribute values:
   * - `className` will be appended.
   * - Event handlers will be chained, unless the default is prevented.
   *
   * We do not support using this attribute to apply custom styling.
   *
   * @awsuiSystem core
   */
  nativeTriggerAttributes?: NativeAttributes<React.ButtonHTMLAttributes<HTMLButtonElement>>;
  /**
   * Attributes to add to the native element of the `mainAction`.
   *
   * Specify either `button` for a standard main action, or `anchor` if `html` is set.
   *
   * Some attributes will be automatically combined with internal attribute values:
   * - `className` will be appended.
   * - Event handlers will be chained, unless the default is prevented.
   *
   * We do not support using this attribute to apply custom styling.
   *
   * @awsuiSystem core
   */
  nativeMainActionAttributes?: {
    button?: NativeAttributes<React.ButtonHTMLAttributes<HTMLButtonElement>>;
    anchor?: NativeAttributes<React.AnchorHTMLAttributes<HTMLAnchorElement>>;
  };
}
export declare namespace ButtonDropdownProps {
  type Variant = 'normal' | 'primary' | 'icon' | 'inline-icon';
  type ItemType = 'action' | 'group';
  interface ActionRenderItem {
    type: 'action';
    index: number;
    option: Item;
    highlighted: boolean;
    disabled: boolean;
    parent: GroupRenderItem | null;
  }
  interface CheckboxRenderItem {
    type: 'checkbox';
    index: number;
    option: CheckboxItem;
    disabled: boolean;
    highlighted: boolean;
    checked: boolean;
    parent: GroupRenderItem | null;
  }
  interface GroupRenderItem {
    type: 'group';
    index: number;
    option: ItemGroup;
    disabled: boolean;
    highlighted: boolean;
    expanded: boolean;
    expandDirection: 'vertical' | 'horizontal';
  }
  type RenderItem = ActionRenderItem | CheckboxRenderItem | GroupRenderItem;
  type ItemRenderer = (props: {
    item: ButtonDropdownProps.RenderItem;
  }) => ReactNode | null;
  interface MainAction {
    text?: string;
    ariaLabel?: string;
    onClick?: CancelableEventHandler<ButtonProps.ClickDetail>;
    onFollow?: CancelableEventHandler<ButtonProps.FollowDetail>;
    disabled?: boolean;
    disabledReason?: string;
    loading?: boolean;
    loadingText?: string;
    href?: string;
    target?: string;
    rel?: string;
    download?: boolean | string;
    external?: boolean;
    externalIconAriaLabel?: string;
    iconAlt?: string;
    iconName?: IconProps.Name;
    iconUrl?: string;
    iconSvg?: React.ReactNode;
  }
  interface Item {
    itemType?: ItemType;
    id: string;
    text: string;
    secondaryText?: string;
    ariaLabel?: string;
    lang?: string;
    disabled?: boolean;
    disabledReason?: string;
    /**
     * @deprecated Has no effect.
     */
    description?: string;
    href?: string;
    download?: boolean | string;
    external?: boolean;
    externalIconAriaLabel?: string;
    iconAlt?: string;
    iconName?: IconProps.Name;
    iconUrl?: string;
    iconSvg?: React.ReactNode;
    labelTag?: string;
    dataAttributes?: Record<string, string>;
  }
  interface CheckboxItem extends Omit<ButtonDropdownProps.Item, 'href' | 'download' | 'external' | 'externalIconAriaLabel' | 'itemType'> {
    itemType: 'checkbox';
    checked: boolean;
  }
  interface ItemGroup extends Omit<Item, 'id' | 'text' | 'itemType' | 'secondaryText' | 'labelTag'> {
    itemType?: 'group';
    id?: string;
    text?: string;
    items: Items;
  }
  type ItemOrGroup = Item | CheckboxItem | ItemGroup;
  type Items = ReadonlyArray<ItemOrGroup>;
  interface ItemClickDetails extends BaseNavigationDetail {
    id: string;
    checked?: boolean;
  }
  interface Ref {
    /**
     * Focuses the underlying native button. If a main action is defined this will focus that button.
     */
    focus(options?: FocusOptions): void;
    /**
     * Focuses the underlying native button for the dropdown.
     */
    focusDropdownTrigger(options?: FocusOptions): void;
  }
}
export interface ButtonDropdownSettings {
  hasExpandableGroups: boolean;
  isInRestrictedView?: boolean;
}
export interface HighlightProps {
  targetItem: ButtonDropdownProps.ItemOrGroup | null;
  isHighlighted: (item: ButtonDropdownProps.ItemOrGroup) => boolean;
  isKeyboardHighlight: (item: ButtonDropdownProps.ItemOrGroup) => boolean;
  isExpanded: (group: ButtonDropdownProps.ItemGroup) => boolean;
  highlightItem: (item: ButtonDropdownProps.ItemOrGroup) => void;
}
export type GroupToggle = (item: ButtonDropdownProps.ItemGroup, event: React.SyntheticEvent) => void;
export type ItemActivate = (item: ButtonDropdownProps.Item | ButtonDropdownProps.CheckboxItem, event: React.MouseEvent | React.KeyboardEvent) => void;
export interface LinkItem extends ButtonDropdownProps.Item {
  href: string;
}
export interface CustomTriggerProps {
  triggerRef: React.Ref<HTMLElement>;
  testUtilsClass: string;
  ariaLabel: string | undefined;
  disabled: boolean;
  disabledReason?: string;
  isOpen: boolean;
  onClick: () => void;
  ariaExpanded: boolean;
}