@elastic/eui
Version:
Elastic UI Component Library
691 lines (674 loc) • 34.7 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.OPTION_CHECKED_STATES = exports.EuiListItemLayout = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _react2 = require("@emotion/react");
var _classnames = _interopRequireDefault(require("classnames"));
var _services = require("../../services");
var _list_item_layout = require("./_list_item_layout.styles");
var _tool_tip = require("../tool_tip");
var _form = require("../form");
var _icon = require("../icon");
var _button_display = require("../button/button_display/_button_display");
var _external_link_icon = require("../link/external_link_icon");
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"];
/*
* 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.
*/
// @ts-ignore module doesn't export `createElement`
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
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) { (0, _defineProperty2.default)(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; }
var OPTION_CHECKED_STATES = exports.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.
*/
var EuiListItemLayout = exports.EuiListItemLayout = /*#__PURE__*/(0, _react.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 = (0, _objectWithoutProperties2.default)(_ref, _excluded);
var _useState = (0, _react.useState)(null),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
tooltipRef = _useState2[0],
setTooltipRef = _useState2[1]; // Needs to be state and not a ref to trigger useEffect
var _useState3 = (0, _react.useState)(_ariaDescribedBy),
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
ariaDescribedBy = _useState4[0],
setAriaDescribedBy = _useState4[1];
var _ref2 = props,
href = _ref2.href,
target = _ref2.target,
rel = _ref2.rel,
rest = (0, _objectWithoutProperties2.default)(_ref2, _excluded2);
var component = _element === 'a' && isDisabled ? 'button' : _element;
var isLink = component === 'a' && !isDisabled;
var buttonIsDisabled = (0, _button_display.isButtonDisabled)({
href: href,
isDisabled: component === 'button' && isDisabled
});
var _useEuiDisabledElemen = (0, _services.useEuiDisabledElement)({
isDisabled: buttonIsDisabled,
hasAriaDisabled: hasAriaDisabled,
onKeyDown: rest.onKeyDown
}),
disabledRef = _useEuiDisabledElemen.ref,
disabledButtonProps = (0, _objectWithoutProperties2.default)(_useEuiDisabledElemen, _excluded3);
var setCombinedRef = (0, _services.useCombinedRefs)((0, _react.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 = (0, _react.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 = (0, _react.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 = (0, _classnames.default)('euiListItemLayout__wrapper', _wrapperProps === null || _wrapperProps === void 0 ? void 0 : _wrapperProps.className);
var classes = (0, _classnames.default)('euiListItemLayout', className);
var wrapperStyles = (0, _services.useEuiMemoizedStyles)(_list_item_layout.euiListItemLayoutWrapperStyles);
var styles = (0, _services.useEuiMemoizedStyles)(_list_item_layout.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
(0, _react.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
(0, _react.useEffect)(function () {
if (tooltipRef) {
var tooltipId = tooltipRef.id;
setAriaDescribedBy((0, _classnames.default)(tooltipId, _ariaDescribedBy));
}
}, [tooltipRef, _ariaDescribedBy]);
var contentProps = (0, _react.useMemo)(function () {
return _objectSpread(_objectSpread({}, _contentProps), {}, {
css: [styles.euiListItemLayout__content, _contentProps === null || _contentProps === void 0 ? void 0 : _contentProps.css],
className: (0, _classnames.default)('euiListItemLayout__content', _contentProps === null || _contentProps === void 0 ? void 0 : _contentProps.className)
});
}, [_contentProps, styles]);
var textProps = (0, _react.useMemo)(function () {
return _objectSpread(_objectSpread({}, _textProps), {}, {
css: [styles.euiListItemLayout__text, styles.textWrap[textWrap], _textProps === null || _textProps === void 0 ? void 0 : _textProps.css],
className: (0, _classnames.default)('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), {}, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, 'aria-describedby', hasInternalTooltip ? ariaDescribedBy : _ariaDescribedBy), 'data-test-subj', dataTestSubj), "onClick", onClick), rest);
/* Render nodes */
var indicator = (0, _react.useMemo)(function () {
if (showIndicator) {
if (!isSingleSelection) {
return (0, _react2.jsx)(_form.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 (0, _react2.jsx)(_icon.EuiIcon, {
css: styles.euiListItemLayout__icon,
className: "euiListItemLayout__icon",
color: color,
type: icon
});
}
}, [checked, isSingleSelection, showIndicator, isSelected, isDisabled, styles]);
var prepend = (0, _react.useMemo)(function () {
if (_prepend) {
var prependProps = _objectSpread(_objectSpread({}, _prependProps), {}, {
css: [styles.euiListItemLayout__prepend, _prependProps === null || _prependProps === void 0 ? void 0 : _prependProps.css],
className: (0, _classnames.default)('euiListItemLayout__prepend', _prependProps === null || _prependProps === void 0 ? void 0 : _prependProps.className)
});
return (0, _react2.jsx)("span", prependProps, _prepend);
}
}, [_prepend, _prependProps, styles]);
var append = (0, _react.useMemo)(function () {
if (_append) {
var appendProps = _objectSpread(_objectSpread({}, _appendProps), {}, {
css: [styles.euiListItemLayout__append, _appendProps === null || _appendProps === void 0 ? void 0 : _appendProps.css],
className: (0, _classnames.default)('euiListItemLayout__append', _appendProps === null || _appendProps === void 0 ? void 0 : _appendProps.className)
});
return (0, _react2.jsx)("span", appendProps, _append);
}
}, [_append, _appendProps, styles]);
var innerContent = (0, _react2.jsx)("span", contentProps, indicator, prepend, (0, _react2.jsx)("span", textProps, _children, isLink && (0, _react2.jsx)(_external_link_icon.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 ? (0, _react2.jsx)(_tool_tip.EuiToolTip, (0, _extends2.default)({
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 = (0, _react2.createElement)(component, elementProps, content);
var element = !isNonInteractiveComponent && hasToolTip ? (0, _react2.jsx)(_tool_tip.EuiToolTip, (0, _extends2.default)({
ref: setTooltipRef,
content: tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.content,
anchorClassName: "eui-fullWidth"
}, tooltipProps), innerElement) : innerElement;
return WrapperElement ? (0, _react2.jsx)(WrapperElement, wrapperProps, element, isMultiAction && extraAction) : element;
});
EuiListItemLayout.propTypes = {
element: _propTypes.default.oneOfType([_propTypes.default.oneOf(["li"]).isRequired, _propTypes.default.oneOfType([_propTypes.default.oneOfType([_propTypes.default.oneOf(["button"]).isRequired, _propTypes.default.oneOf(["a"]).isRequired]).isRequired, _propTypes.default.oneOf(["div"]).isRequired]).isRequired]).isRequired,
className: _propTypes.default.string,
"aria-label": _propTypes.default.string,
"data-test-subj": _propTypes.default.string,
css: _propTypes.default.any,
/**
* Controls the disabled behavior via the native `disabled` attribute.
*/
isDisabled: _propTypes.default.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.default.bool,
children: _propTypes.default.node,
/**
* Slot for prepended content (icons)
*/
/**
* Slot for prepended content (icons)
*/
/**
* Slot for prepended content (icons)
*/
/**
* Slot for prepended content (icons)
*/
prepend: _propTypes.default.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.default.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.default.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.default.oneOf(["li", "div"]),
wrapperProps: _propTypes.default.shape({
className: _propTypes.default.string,
"aria-label": _propTypes.default.string,
"data-test-subj": _propTypes.default.string,
css: _propTypes.default.any
}),
contentProps: _propTypes.default.shape({
className: _propTypes.default.string,
"aria-label": _propTypes.default.string,
"data-test-subj": _propTypes.default.string,
css: _propTypes.default.any
}),
textProps: _propTypes.default.shape({
className: _propTypes.default.string,
"aria-label": _propTypes.default.string,
"data-test-subj": _propTypes.default.string,
css: _propTypes.default.any
}),
prependProps: _propTypes.default.shape({
className: _propTypes.default.string,
"aria-label": _propTypes.default.string,
"data-test-subj": _propTypes.default.string,
css: _propTypes.default.any
}),
appendProps: _propTypes.default.shape({
className: _propTypes.default.string,
"aria-label": _propTypes.default.string,
"data-test-subj": _propTypes.default.string,
css: _propTypes.default.any
}),
tooltipProps: _propTypes.default.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.default.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.default.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.default.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.default.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.default.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.default.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.default.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.default.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.default.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'
};
}
}