function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
var _excluded = ["children", "element", "wrapperElement", "className", "css", "role", "prepend", "append", "extraAction", "wrapperProps", "contentProps", "prependProps", "appendProps", "textProps", "tooltipProps", "checked", "isDisabled", "hasAriaDisabled", "isFocused", "isSelected", "isSingleSelection", "selectionMode", "showIndicator", "textWrap", "external", "aria-describedby", "aria-selected", "aria-checked", "data-test-subj", "onClick"],
  _excluded2 = ["href", "target", "rel"],
  _excluded3 = ["ref"];
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], t.indexOf(o) >= 0 || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n) >= 0) continue; t[n] = r[n]; } return t; }
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */

import React, { forwardRef, useEffect, useMemo, useState } from 'react';
// @ts-ignore module doesn't export `createElement`
import PropTypes from "prop-types";
import { createElement } from '@emotion/react';
import classNames from 'classnames';
import { useCombinedRefs, useEuiDisabledElement, useEuiMemoizedStyles } from '../../services';
import { euiListItemLayoutStyles, euiListItemLayoutWrapperStyles } from './_list_item_layout.styles';
import { EuiToolTip } from '../tool_tip';
import { EuiCheckboxControl } from '../form';
import { EuiIcon } from '../icon';
import { isButtonDisabled } from '../button/button_display/_button_display';
import { EuiExternalLinkIcon } from '../link/external_link_icon';
import { jsx as ___EmotionJSX } from "@emotion/react";
export var OPTION_CHECKED_STATES = ['on', 'off', 'mixed', undefined];
var NATIVELY_CHECKABLE_ROLES = ['checkbox', 'menuitemcheckbox', 'radio', 'menuitemradio', 'switch'];
var ROLES_THAT_CAN_BE_MIXED = ['option', 'checkbox', 'menuitemcheckbox'];
var ROLES_THAT_CAN_USE_ARIA_CHECKED = ['option'].concat(NATIVELY_CHECKABLE_ROLES);
var ROLES_THAT_CAN_USE_ARIA_SELECTED = ['tab', 'gridcell', 'option', 'row', 'treeitem'];

// Ensure an exclusive union of either li, div, button, or anchor

/**
 * This is an EUI internal-only layout component that is used to share layout and
 * styles between selection and navigational list components.
 */
export var EuiListItemLayout = /*#__PURE__*/forwardRef(function (_ref, ref) {
  var _tooltipProps$anchorP;
  var _children = _ref.children,
    _ref$element = _ref.element,
    _element = _ref$element === void 0 ? 'li' : _ref$element,
    wrapperElement = _ref.wrapperElement,
    className = _ref.className,
    css = _ref.css,
    role = _ref.role,
    _prepend = _ref.prepend,
    _append = _ref.append,
    extraAction = _ref.extraAction,
    _wrapperProps = _ref.wrapperProps,
    _contentProps = _ref.contentProps,
    _prependProps = _ref.prependProps,
    _appendProps = _ref.appendProps,
    _textProps = _ref.textProps,
    _tooltipProps = _ref.tooltipProps,
    checked = _ref.checked,
    isDisabled = _ref.isDisabled,
    _ref$hasAriaDisabled = _ref.hasAriaDisabled,
    hasAriaDisabled = _ref$hasAriaDisabled === void 0 ? false : _ref$hasAriaDisabled,
    isFocused = _ref.isFocused,
    isSelected = _ref.isSelected,
    _ref$isSingleSelectio = _ref.isSingleSelection,
    isSingleSelection = _ref$isSingleSelectio === void 0 ? true : _ref$isSingleSelectio,
    _selectionMode = _ref.selectionMode,
    _ref$showIndicator = _ref.showIndicator,
    showIndicator = _ref$showIndicator === void 0 ? true : _ref$showIndicator,
    _ref$textWrap = _ref.textWrap,
    textWrap = _ref$textWrap === void 0 ? 'truncate' : _ref$textWrap,
    external = _ref.external,
    _ariaDescribedBy = _ref['aria-describedby'],
    _ariaSelected = _ref['aria-selected'],
    _ariaChecked = _ref['aria-checked'],
    _ref$dataTestSubj = _ref['data-test-subj'],
    dataTestSubj = _ref$dataTestSubj === void 0 ? 'euiListItemLayout' : _ref$dataTestSubj,
    onClick = _ref.onClick,
    props = _objectWithoutProperties(_ref, _excluded);
  var _useState = useState(null),
    _useState2 = _slicedToArray(_useState, 2),
    tooltipRef = _useState2[0],
    setTooltipRef = _useState2[1]; // Needs to be state and not a ref to trigger useEffect
  var _useState3 = useState(_ariaDescribedBy),
    _useState4 = _slicedToArray(_useState3, 2),
    ariaDescribedBy = _useState4[0],
    setAriaDescribedBy = _useState4[1];
  var _ref2 = props,
    href = _ref2.href,
    target = _ref2.target,
    rel = _ref2.rel,
    rest = _objectWithoutProperties(_ref2, _excluded2);
  var component = _element === 'a' && isDisabled ? 'button' : _element;
  var isLink = component === 'a' && !isDisabled;
  var buttonIsDisabled = isButtonDisabled({
    href: href,
    isDisabled: component === 'button' && isDisabled
  });
  var _useEuiDisabledElemen = useEuiDisabledElement({
      isDisabled: buttonIsDisabled,
      hasAriaDisabled: hasAriaDisabled,
      onKeyDown: rest.onKeyDown
    }),
    disabledRef = _useEuiDisabledElemen.ref,
    disabledButtonProps = _objectWithoutProperties(_useEuiDisabledElemen, _excluded3);
  var setCombinedRef = useCombinedRefs(useMemo(function () {
    return [disabledRef, ref];
  }, [disabledRef, ref]));
  var hasToolTip = !!_tooltipProps;
  var isNonInteractiveComponent = ['li', 'div'].includes(component);
  var isInteractiveComponent = ['button', 'a'].includes(component) || ['button', 'link'].includes(role !== null && role !== void 0 ? role : '');
  var isInteractive = isInteractiveComponent || !!onClick;
  /* Multi-action: component is interactive (button/a) and has an additional action passed via `extraAction`,
  which requires to not nest interactive elements. The wrapper is the outermost styled container and owns
  hover/focus/selected styles.
  Single-action: component (li/div) is the outermost element and owns all styles. */
  var isMultiAction = extraAction != null && isInteractiveComponent;
  var WrapperElement = isMultiAction ? wrapperElement !== null && wrapperElement !== void 0 ? wrapperElement : 'li' : isInteractiveComponent ? wrapperElement : undefined;
  var hasWrapper = WrapperElement != null;

  // aria-checked is intended to be used with role="checkbox" but
  // the MDN documentation lists it as a possibility for role="option".
  // See https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-checked
  // and https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/option_role
  var ariaChecked = useMemo(function () {
    if (!role) return undefined;
    if (!ROLES_THAT_CAN_USE_ARIA_CHECKED.includes(role)) return undefined;
    switch (checked) {
      case 'on':
      case 'off':
        return true;
      case 'mixed':
        if (ROLES_THAT_CAN_BE_MIXED.includes(role)) {
          return 'mixed';
        } else {
          return false;
        }
      default:
        return _ariaChecked !== null && _ariaChecked !== void 0 ? _ariaChecked : false;
    }
  }, [role, checked, _ariaChecked]);
  var defaultSelectionMode = useMemo(function () {
    if (!isSingleSelection) {
      return 'checked';
    }
    if (role && NATIVELY_CHECKABLE_ROLES.includes(role)) {
      return 'checked';
    }
    return 'selected';
  }, [isSingleSelection, role]);
  var selectionMode = _selectionMode !== null && _selectionMode !== void 0 ? _selectionMode : defaultSelectionMode;
  var hasAriaChecked = (selectionMode === 'checked' ? ariaChecked : undefined) !== undefined;
  var hasAriaSelected = ROLES_THAT_CAN_USE_ARIA_SELECTED.includes(role !== null && role !== void 0 ? role : '');
  var hasCustomAriaSelected = _ariaSelected != null;

  /* Styles */

  var wrapperClasses = classNames('euiListItemLayout__wrapper', _wrapperProps === null || _wrapperProps === void 0 ? void 0 : _wrapperProps.className);
  var classes = classNames('euiListItemLayout', className);
  var wrapperStyles = useEuiMemoizedStyles(euiListItemLayoutWrapperStyles);
  var styles = useEuiMemoizedStyles(euiListItemLayoutStyles);
  var interactiveStyles = [isInteractive && styles.isInteractive, isFocused && styles.isFocused, (isSingleSelection || !showIndicator) && isSelected && styles.isSelected, (isSingleSelection || !showIndicator) && isSelected && isFocused && styles.isSelectedFocused];
  var wrapperCssStyles = [wrapperStyles.euiListItemLayout__wrapper, extraAction && wrapperStyles.hasExtraAction, !isDisabled && hasWrapper && interactiveStyles, hasWrapper && css, isDisabled && hasWrapper && styles.isDisabled];
  var cssStyles = [styles.euiListItemLayout, hasWrapper && styles.euiListItemLayout__action, !isDisabled && !hasWrapper && interactiveStyles, !hasWrapper && css, isDisabled && styles.isDisabled, hasAriaDisabled && buttonIsDisabled && hasToolTip && styles.buttonIsDisabled];

  // Manually trigger the tooltip on keyboard focus
  useEffect(function () {
    if (!tooltipRef || isFocused == null || !hasAriaDisabled && isDisabled) {
      return;
    }
    if (isFocused) {
      tooltipRef.showToolTip();
    } else {
      tooltipRef.hideToolTip();
    }
  }, [isFocused, isDisabled, hasAriaDisabled, tooltipRef]);

  /* Props */

  // Manually set the `aria-describedby` id on the wrapper
  useEffect(function () {
    if (tooltipRef) {
      var tooltipId = tooltipRef.id;
      setAriaDescribedBy(classNames(tooltipId, _ariaDescribedBy));
    }
  }, [tooltipRef, _ariaDescribedBy]);
  var contentProps = useMemo(function () {
    return _objectSpread(_objectSpread({}, _contentProps), {}, {
      css: [styles.euiListItemLayout__content, _contentProps === null || _contentProps === void 0 ? void 0 : _contentProps.css],
      className: classNames('euiListItemLayout__content', _contentProps === null || _contentProps === void 0 ? void 0 : _contentProps.className)
    });
  }, [_contentProps, styles]);
  var textProps = useMemo(function () {
    return _objectSpread(_objectSpread({}, _textProps), {}, {
      css: [styles.euiListItemLayout__text, styles.textWrap[textWrap], _textProps === null || _textProps === void 0 ? void 0 : _textProps.css],
      className: classNames('euiListItemLayout__text', _textProps === null || _textProps === void 0 ? void 0 : _textProps.className)
    });
  }, [_textProps, textWrap, styles]);

  /**
   * ARIA selection attribute appliance:
   * - multi-selection + checkable role -> `aria-checked`
   * - multi-selection + non-checkable, selectable role -> `aria-selected`
   * - multi-selection + non-checkable, non-selectable role -> `aria-current`
   * - single-selection + checkable role -> `aria-checked`
   * - single-selection + non-checkable, selectable role -> `aria-selected`
   * - single-selection + non-checkable, non-selectable role -> `aria-current`
   */

  // added to selection list items only (`component=li/div`)
  var selectionProps = isNonInteractiveComponent && !isInteractiveComponent ? {
    role: role,
    'aria-checked': hasAriaChecked ? ariaChecked : undefined,
    'aria-selected': !hasAriaChecked && hasAriaSelected ? isSelected : undefined,
    'aria-current': !hasAriaChecked && !hasAriaSelected && isSelected ? 'true' : undefined
  } : {};

  // added to navigational list items only (`component=button/a`)
  var navigationalProps = isInteractiveComponent ? {
    /* supports aria-checked as custom `role` can enable checked states */
    'aria-checked': hasAriaChecked ? ariaChecked : undefined,
    'aria-current': !hasAriaChecked && !hasCustomAriaSelected && isSelected ? 'true' : undefined,
    // indicates currently active navigation item
    /* allow manual `aria-selected` overrides; By default a list of navigational elements likely uses `aria-current` but using
    a button with appropriate `role` within a selection list could still be valid, though weird (e.g. custom EuiSuperSelect) */
    'aria-selected': !hasAriaChecked && hasCustomAriaSelected ? isSelected : undefined // indicates current selected item
  } : {};
  var linkProps = ['a'].includes(component) && !isDisabled ? {
    href: href,
    target: target,
    rel: rel
  } : {};
  var disabledProps = isDisabled ? buttonIsDisabled ? disabledButtonProps : {
    disabled: component === 'button' ? isDisabled : undefined,
    'aria-disabled': component !== 'button' ? isDisabled : undefined
  } : {};
  var wrapperProps = _objectSpread(_objectSpread({
    'data-test-subj': "".concat(dataTestSubj, "-wrapper")
  }, _wrapperProps), {}, {
    className: wrapperClasses,
    css: [wrapperCssStyles, _wrapperProps === null || _wrapperProps === void 0 ? void 0 : _wrapperProps.css]
  });
  var tooltipProps = _objectSpread(_objectSpread({}, _tooltipProps), {}, {
    anchorProps: _objectSpread(_objectSpread({}, _tooltipProps === null || _tooltipProps === void 0 ? void 0 : _tooltipProps.anchorProps), {}, {
      css: [isDisabled && styles.tooltip.isDisabled, _tooltipProps === null || _tooltipProps === void 0 || (_tooltipProps$anchorP = _tooltipProps.anchorProps) === null || _tooltipProps$anchorP === void 0 ? void 0 : _tooltipProps$anchorP.css]
    })
  });
  var hasInternalTooltip = isNonInteractiveComponent && hasToolTip;
  var elementProps = _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
    ref: setCombinedRef,
    role: role,
    className: classes,
    css: cssStyles
  }, selectionProps), navigationalProps), linkProps), disabledProps), {}, _defineProperty(_defineProperty(_defineProperty({}, 'aria-describedby', hasInternalTooltip ? ariaDescribedBy : _ariaDescribedBy), 'data-test-subj', dataTestSubj), "onClick", onClick), rest);

  /* Render nodes */

  var indicator = useMemo(function () {
    if (showIndicator) {
      if (!isSingleSelection) {
        return ___EmotionJSX(EuiCheckboxControl, {
          className: "euiListItemLayout__checkbox",
          checked: checked === 'on',
          disabled: isDisabled,
          indeterminate: checked === 'mixed',
          excluded: checked === 'off'
        });
      }
      var _resolveIconAndColor = resolveIconAndColor(checked, isSelected, isDisabled),
        icon = _resolveIconAndColor.icon,
        color = _resolveIconAndColor.color;
      return ___EmotionJSX(EuiIcon, {
        css: styles.euiListItemLayout__icon,
        className: "euiListItemLayout__icon",
        color: color,
        type: icon
      });
    }
  }, [checked, isSingleSelection, showIndicator, isSelected, isDisabled, styles]);
  var prepend = useMemo(function () {
    if (_prepend) {
      var prependProps = _objectSpread(_objectSpread({}, _prependProps), {}, {
        css: [styles.euiListItemLayout__prepend, _prependProps === null || _prependProps === void 0 ? void 0 : _prependProps.css],
        className: classNames('euiListItemLayout__prepend', _prependProps === null || _prependProps === void 0 ? void 0 : _prependProps.className)
      });
      return ___EmotionJSX("span", prependProps, _prepend);
    }
  }, [_prepend, _prependProps, styles]);
  var append = useMemo(function () {
    if (_append) {
      var appendProps = _objectSpread(_objectSpread({}, _appendProps), {}, {
        css: [styles.euiListItemLayout__append, _appendProps === null || _appendProps === void 0 ? void 0 : _appendProps.css],
        className: classNames('euiListItemLayout__append', _appendProps === null || _appendProps === void 0 ? void 0 : _appendProps.className)
      });
      return ___EmotionJSX("span", appendProps, _append);
    }
  }, [_append, _appendProps, styles]);
  var innerContent = ___EmotionJSX("span", contentProps, indicator, prepend, ___EmotionJSX("span", textProps, _children, isLink && ___EmotionJSX(EuiExternalLinkIcon, {
    css: styles.externalIcon,
    external: external,
    target: target,
    size: "m"
  })), append, !isMultiAction && extraAction);
  /* for non interactive elements, specifically semantic li we need to
  ensure that the li is the outer element to be a valid child of a wrapping ul */
  var content = hasInternalTooltip ? ___EmotionJSX(EuiToolTip, _extends({
    ref: setTooltipRef,
    content: tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.content,
    anchorClassName: "eui-fullWidth"
  }, tooltipProps), innerContent) : innerContent;

  /* Uses `createElement` to side step having to specify element types. Since this is an
  internal-only component and we're specifying separate types for each element, we can safely
  assume the right props are passed at this point.
  It uses the import from @emotion/react to ensure the `css` props works as in JSX. */
  var innerElement = createElement(component, elementProps, content);
  var element = !isNonInteractiveComponent && hasToolTip ? ___EmotionJSX(EuiToolTip, _extends({
    ref: setTooltipRef,
    content: tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.content,
    anchorClassName: "eui-fullWidth"
  }, tooltipProps), innerElement) : innerElement;
  return WrapperElement ? ___EmotionJSX(WrapperElement, wrapperProps, element, isMultiAction && extraAction) : element;
});
EuiListItemLayout.propTypes = {
  element: PropTypes.oneOfType([PropTypes.oneOf(["li"]).isRequired, PropTypes.oneOfType([PropTypes.oneOfType([PropTypes.oneOf(["button"]).isRequired, PropTypes.oneOf(["a"]).isRequired]).isRequired, PropTypes.oneOf(["div"]).isRequired]).isRequired]).isRequired,
  className: PropTypes.string,
  "aria-label": PropTypes.string,
  "data-test-subj": PropTypes.string,
  css: PropTypes.any,
  /**
     * Controls the disabled behavior via the native `disabled` attribute.
     */
  isDisabled: PropTypes.bool,
  /**
     * NOTE: Beta feature, may be changed or removed in the future
     *
     * Changes the native `disabled` attribute to `aria-disabled` to preserve focusability.
     * This results in a semantically disabled button without the default browser handling of the disabled state.
     *
     * Use e.g. when a disabled button should have a tooltip.
     */
  hasAriaDisabled: PropTypes.bool,
  children: PropTypes.node,
  /**
       * Slot for prepended content (icons)
       */
  /**
       * Slot for prepended content (icons)
       */
  /**
       * Slot for prepended content (icons)
       */
  /**
       * Slot for prepended content (icons)
       */
  prepend: PropTypes.node,
  /**
       * Slot for additional appended content (e.g. badges)
       * Use extraAction instead for interactive elements.
       */
  /**
       * Slot for additional appended content (e.g. badges)
       * Use extraAction instead for interactive elements.
       */
  /**
       * Slot for additional appended content (e.g. badges)
       * Use extraAction instead for interactive elements.
       */
  /**
       * Slot for additional appended content (e.g. badges)
       * Use extraAction instead for interactive elements.
       */
  append: PropTypes.node,
  /**
       * Slot for additional interactive appended content (extra actions)
       */
  /**
       * Slot for additional interactive appended content (extra actions)
       */
  /**
       * Slot for additional interactive appended content (extra actions)
       */
  /**
       * Slot for additional interactive appended content (extra actions)
       */
  extraAction: PropTypes.node,
  /**
       * Set to manually define the wrapping element for navigational items (`component=button/a`).
       * This has no effect when `component=li/div`.
       * @default 'li'
       */
  /**
       * Set to manually define the wrapping element for navigational items (`component=button/a`).
       * This has no effect when `component=li/div`.
       * @default 'li'
       */
  /**
       * Set to manually define the wrapping element for navigational items (`component=button/a`).
       * This has no effect when `component=li/div`.
       * @default 'li'
       */
  /**
       * Set to manually define the wrapping element for navigational items (`component=button/a`).
       * This has no effect when `component=li/div`.
       * @default 'li'
       */
  wrapperElement: PropTypes.oneOf(["li", "div"]),
  wrapperProps: PropTypes.shape({
    className: PropTypes.string,
    "aria-label": PropTypes.string,
    "data-test-subj": PropTypes.string,
    css: PropTypes.any
  }),
  contentProps: PropTypes.shape({
    className: PropTypes.string,
    "aria-label": PropTypes.string,
    "data-test-subj": PropTypes.string,
    css: PropTypes.any
  }),
  textProps: PropTypes.shape({
    className: PropTypes.string,
    "aria-label": PropTypes.string,
    "data-test-subj": PropTypes.string,
    css: PropTypes.any
  }),
  prependProps: PropTypes.shape({
    className: PropTypes.string,
    "aria-label": PropTypes.string,
    "data-test-subj": PropTypes.string,
    css: PropTypes.any
  }),
  appendProps: PropTypes.shape({
    className: PropTypes.string,
    "aria-label": PropTypes.string,
    "data-test-subj": PropTypes.string,
    css: PropTypes.any
  }),
  tooltipProps: PropTypes.any,
  /**
       * Controls the item checked indicator and applies a semantic `aria-checked` attribute.
       * Ensure to pass an appropriate `role` for the item that supports semantic
       * `checked` state. For no/other role(s) `checked` only controls the visual checked indicator.
       *
       * Leave `undefined` to indicate not selected. Pass a string of
       * 'on' to indicate inclusion, 'off' to indicate exclusion,
       * or 'mixed' to indicate inclusion for some.
       *
       * When using `singleSelection=true` it's expected to only use the values `on` or `undefined`
       * to toggle between checked and not checked.
       */
  /**
       * Controls the item checked indicator and applies a semantic `aria-checked` attribute.
       * Ensure to pass an appropriate `role` for the item that supports semantic
       * `checked` state. For no/other role(s) `checked` only controls the visual checked indicator.
       *
       * Leave `undefined` to indicate not selected. Pass a string of
       * 'on' to indicate inclusion, 'off' to indicate exclusion,
       * or 'mixed' to indicate inclusion for some.
       *
       * When using `singleSelection=true` it's expected to only use the values `on` or `undefined`
       * to toggle between checked and not checked.
       */
  /**
       * Controls the item checked indicator and applies a semantic `aria-checked` attribute.
       * Ensure to pass an appropriate `role` for the item that supports semantic
       * `checked` state. For no/other role(s) `checked` only controls the visual checked indicator.
       *
       * Leave `undefined` to indicate not selected. Pass a string of
       * 'on' to indicate inclusion, 'off' to indicate exclusion,
       * or 'mixed' to indicate inclusion for some.
       *
       * When using `singleSelection=true` it's expected to only use the values `on` or `undefined`
       * to toggle between checked and not checked.
       */
  /**
       * Controls the item checked indicator and applies a semantic `aria-checked` attribute.
       * Ensure to pass an appropriate `role` for the item that supports semantic
       * `checked` state. For no/other role(s) `checked` only controls the visual checked indicator.
       *
       * Leave `undefined` to indicate not selected. Pass a string of
       * 'on' to indicate inclusion, 'off' to indicate exclusion,
       * or 'mixed' to indicate inclusion for some.
       *
       * When using `singleSelection=true` it's expected to only use the values `on` or `undefined`
       * to toggle between checked and not checked.
       */
  checked: PropTypes.any,
  /**
       * Controls the item selection state within a list (not the checked indicator).
       * It applies an `aria-selected` or `aria-current` attributes depending on `component` and `role`.
       * It adds a visual selected style when `isSingleSelection=true` or `showIndicator=false`.
       */
  /**
       * Controls the item selection state within a list (not the checked indicator).
       * It applies an `aria-selected` or `aria-current` attributes depending on `component` and `role`.
       * It adds a visual selected style when `isSingleSelection=true` or `showIndicator=false`.
       */
  /**
       * Controls the item selection state within a list (not the checked indicator).
       * It applies an `aria-selected` or `aria-current` attributes depending on `component` and `role`.
       * It adds a visual selected style when `isSingleSelection=true` or `showIndicator=false`.
       */
  /**
       * Controls the item selection state within a list (not the checked indicator).
       * It applies an `aria-selected` or `aria-current` attributes depending on `component` and `role`.
       * It adds a visual selected style when `isSingleSelection=true` or `showIndicator=false`.
       */
  isSelected: PropTypes.bool,
  /**
       * Highlights the item as currently navigated item within a listbox.
       * The item is not actually focused, it will only be styled as active.
       */
  /**
       * Highlights the item as currently navigated item within a listbox.
       * The item is not actually focused, it will only be styled as active.
       */
  /**
       * Highlights the item as currently navigated item within a listbox.
       * The item is not actually focused, it will only be styled as active.
       */
  /**
       * Highlights the item as currently navigated item within a listbox.
       * The item is not actually focused, it will only be styled as active.
       */
  isFocused: PropTypes.bool,
  /**
       * Toggles between multi-selection (renders checkbox indicators) and
       * single-selection (renders icon indicators).
       * @default true
       */
  /**
       * Toggles between multi-selection (renders checkbox indicators) and
       * single-selection (renders icon indicators).
       * @default true
       */
  /**
       * Toggles between multi-selection (renders checkbox indicators) and
       * single-selection (renders icon indicators).
       * @default true
       */
  /**
       * Toggles between multi-selection (renders checkbox indicators) and
       * single-selection (renders icon indicators).
       * @default true
       */
  isSingleSelection: PropTypes.bool,
  /**
       * Manually overrides the selection type (checkbox vs selection) for checkable/selectable roles.
       * This controls whether `aria-checked` or `aria-selected` attributes are set.
       * For no `role` or unsupported roles, this has no effect and `aria-current` is applied.
       *
       * By default when unset, it's handled internally based on `isSingleSelection`
       * and applies `aria-checked` to multi-selection and `aria-selected` to single-selection.
       *
       * Use only when you need to manually adjust this, e.g. for a single-selection
       * multi-state checkbox item (supports exclusion or indeterminate).
       */
  /**
       * Manually overrides the selection type (checkbox vs selection) for checkable/selectable roles.
       * This controls whether `aria-checked` or `aria-selected` attributes are set.
       * For no `role` or unsupported roles, this has no effect and `aria-current` is applied.
       *
       * By default when unset, it's handled internally based on `isSingleSelection`
       * and applies `aria-checked` to multi-selection and `aria-selected` to single-selection.
       *
       * Use only when you need to manually adjust this, e.g. for a single-selection
       * multi-state checkbox item (supports exclusion or indeterminate).
       */
  /**
       * Manually overrides the selection type (checkbox vs selection) for checkable/selectable roles.
       * This controls whether `aria-checked` or `aria-selected` attributes are set.
       * For no `role` or unsupported roles, this has no effect and `aria-current` is applied.
       *
       * By default when unset, it's handled internally based on `isSingleSelection`
       * and applies `aria-checked` to multi-selection and `aria-selected` to single-selection.
       *
       * Use only when you need to manually adjust this, e.g. for a single-selection
       * multi-state checkbox item (supports exclusion or indeterminate).
       */
  /**
       * Manually overrides the selection type (checkbox vs selection) for checkable/selectable roles.
       * This controls whether `aria-checked` or `aria-selected` attributes are set.
       * For no `role` or unsupported roles, this has no effect and `aria-current` is applied.
       *
       * By default when unset, it's handled internally based on `isSingleSelection`
       * and applies `aria-checked` to multi-selection and `aria-selected` to single-selection.
       *
       * Use only when you need to manually adjust this, e.g. for a single-selection
       * multi-state checkbox item (supports exclusion or indeterminate).
       */
  selectionMode: PropTypes.oneOf(["checked", "selected"]),
  /**
       * Controls the visibility of the indicator.
       * @default true
       */
  /**
       * Controls the visibility of the indicator.
       * @default true
       */
  /**
       * Controls the visibility of the indicator.
       * @default true
       */
  /**
       * Controls the visibility of the indicator.
       * @default true
       */
  showIndicator: PropTypes.bool,
  /**
       * Native `role` attribute.
       * If you pass a custom role make sure to align `selectionMode` where needed as well.
       * Set it to `checked` when the role natively supports checked states and to `selected` otherwise.
       */
  /**
       * Native `role` attribute.
       * If you pass a custom role make sure to align `selectionMode` where needed as well.
       * Set it to `checked` when the role natively supports checked states and to `selected` otherwise.
       */
  /**
       * Native `role` attribute.
       * If you pass a custom role make sure to align `selectionMode` where needed as well.
       * Set it to `checked` when the role natively supports checked states and to `selected` otherwise.
       */
  /**
       * Native `role` attribute.
       * If you pass a custom role make sure to align `selectionMode` where needed as well.
       * Set it to `checked` when the role natively supports checked states and to `selected` otherwise.
       */
  role: PropTypes.any,
  /**
       * How to handle long text within the item.
       * @default 'truncate'
       */
  /**
       * How to handle long text within the item.
       * @default 'truncate'
       */
  /**
       * How to handle long text within the item.
       * @default 'truncate'
       */
  /**
       * How to handle long text within the item.
       * @default 'truncate'
       */
  textWrap: PropTypes.oneOf(["truncate", "wrap"]),
  /**
     * Set to true to show an icon indicating that it is an external link;
     * Defaults to true if `target="_blank"`
     */
  external: PropTypes.bool
};
EuiListItemLayout.displayName = 'EuiListItemLayout';

/* Internal helpers */

function resolveIconAndColor(checked, isSelected, isDisabled) {
  switch (checked) {
    case 'on':
      return {
        icon: 'check',
        color: isDisabled ? 'subdued' : isSelected ? 'primary' : 'text'
      };
    case 'off':
      return {
        icon: 'cross',
        color: isDisabled ? 'subdued' : isSelected ? 'primary' : 'text'
      };
    case 'mixed':
      return {
        icon: 'minus',
        color: isDisabled ? 'subdued' : isSelected ? 'primary' : 'text'
      };
    case undefined:
    default:
      return {
        icon: 'empty',
        color: isDisabled ? 'subdued' : 'text'
      };
  }
}