1 | import { __rest } from "tslib";
|
2 | import * as React from 'react';
|
3 | import { css } from '@patternfly/react-styles';
|
4 | import { DropdownContext } from './dropdownConstants';
|
5 | import { KEYHANDLER_DIRECTION } from '../../helpers/constants';
|
6 | import { preventedEvents } from '../../helpers/util';
|
7 | import { Tooltip } from '../Tooltip';
|
8 | import styles from '@patternfly/react-styles/css/components/Dropdown/dropdown';
|
9 | export class InternalDropdownItem extends React.Component {
|
10 | constructor() {
|
11 | super(...arguments);
|
12 | this.ref = React.createRef();
|
13 | this.additionalRef = React.createRef();
|
14 | this.getInnerNode = (node) => (node && node.childNodes && node.childNodes.length ? node.childNodes[0] : node);
|
15 | this.onKeyDown = (event) => {
|
16 |
|
17 | const innerIndex = event.target === this.ref.current ? 0 : 1;
|
18 | if (!this.props.customChild) {
|
19 | event.preventDefault();
|
20 | }
|
21 | if (event.key === 'ArrowUp') {
|
22 | this.props.context.keyHandler(this.props.index, innerIndex, KEYHANDLER_DIRECTION.UP);
|
23 | event.stopPropagation();
|
24 | }
|
25 | else if (event.key === 'ArrowDown') {
|
26 | this.props.context.keyHandler(this.props.index, innerIndex, KEYHANDLER_DIRECTION.DOWN);
|
27 | event.stopPropagation();
|
28 | }
|
29 | else if (event.key === 'ArrowRight') {
|
30 | this.props.context.keyHandler(this.props.index, innerIndex, KEYHANDLER_DIRECTION.RIGHT);
|
31 | event.stopPropagation();
|
32 | }
|
33 | else if (event.key === 'ArrowLeft') {
|
34 | this.props.context.keyHandler(this.props.index, innerIndex, KEYHANDLER_DIRECTION.LEFT);
|
35 | event.stopPropagation();
|
36 | }
|
37 | else if (event.key === 'Enter' || event.key === ' ') {
|
38 | event.target.click();
|
39 | this.props.enterTriggersArrowDown &&
|
40 | this.props.context.keyHandler(this.props.index, innerIndex, KEYHANDLER_DIRECTION.DOWN);
|
41 | }
|
42 | };
|
43 | this.componentRef = (element) => {
|
44 | this.ref.current = element;
|
45 | const { component } = this.props;
|
46 | const ref = component.ref;
|
47 | if (ref) {
|
48 | if (typeof ref === 'function') {
|
49 | ref(element);
|
50 | }
|
51 | else {
|
52 | ref.current = element;
|
53 | }
|
54 | }
|
55 | };
|
56 | }
|
57 | componentDidMount() {
|
58 | const { context, index, isDisabled, role, customChild, autoFocus } = this.props;
|
59 | const customRef = customChild ? this.getInnerNode(this.ref.current) : this.ref.current;
|
60 | context.sendRef(index, [customRef, customChild ? customRef : this.additionalRef.current], isDisabled, role === 'separator');
|
61 | autoFocus && setTimeout(() => customRef.focus());
|
62 | }
|
63 | componentDidUpdate() {
|
64 | const { context, index, isDisabled, role, customChild } = this.props;
|
65 | const customRef = customChild ? this.getInnerNode(this.ref.current) : this.ref.current;
|
66 | context.sendRef(index, [customRef, customChild ? customRef : this.additionalRef.current], isDisabled, role === 'separator');
|
67 | }
|
68 | extendAdditionalChildRef() {
|
69 | const { additionalChild } = this.props;
|
70 | return React.cloneElement(additionalChild, {
|
71 | ref: this.additionalRef
|
72 | });
|
73 | }
|
74 | render() {
|
75 |
|
76 | const _a = this.props, { className, children, isHovered, context, onClick, component, role, isDisabled, isAriaDisabled, isPlainText, index, href, tooltip, tooltipProps, id, componentID, listItemClassName, additionalChild, customChild, enterTriggersArrowDown, icon, autoFocus, styleChildren, description, inoperableEvents } = _a, additionalProps = __rest(_a, ["className", "children", "isHovered", "context", "onClick", "component", "role", "isDisabled", "isAriaDisabled", "isPlainText", "index", "href", "tooltip", "tooltipProps", "id", "componentID", "listItemClassName", "additionalChild", "customChild", "enterTriggersArrowDown", "icon", "autoFocus", "styleChildren", "description", "inoperableEvents"]);
|
77 |
|
78 | let classes = css(icon && styles.modifiers.icon, isAriaDisabled && styles.modifiers.ariaDisabled, className);
|
79 | if (component === 'a') {
|
80 | additionalProps['aria-disabled'] = isDisabled || isAriaDisabled;
|
81 | }
|
82 | else if (component === 'button') {
|
83 | additionalProps['aria-disabled'] = isDisabled || isAriaDisabled;
|
84 | additionalProps.type = additionalProps.type || 'button';
|
85 | }
|
86 | const renderWithTooltip = (childNode) => tooltip ? (React.createElement(Tooltip, Object.assign({ content: tooltip }, tooltipProps), childNode)) : (childNode);
|
87 | const renderClonedComponent = (element) => React.cloneElement(element, Object.assign(Object.assign({}, (styleChildren && {
|
88 | className: css(element.props.className, classes)
|
89 | })), (this.props.role !== 'separator' && { ref: this.componentRef })));
|
90 | const renderDefaultComponent = (tag) => {
|
91 | const Component = tag;
|
92 | const componentContent = description ? (React.createElement(React.Fragment, null,
|
93 | React.createElement("div", { className: styles.dropdownMenuItemMain },
|
94 | icon && React.createElement("span", { className: css(styles.dropdownMenuItemIcon) }, icon),
|
95 | children),
|
96 | React.createElement("div", { className: styles.dropdownMenuItemDescription }, description))) : (React.createElement(React.Fragment, null,
|
97 | icon && React.createElement("span", { className: css(styles.dropdownMenuItemIcon) }, icon),
|
98 | children));
|
99 | return (React.createElement(Component, Object.assign({}, additionalProps, (isDisabled || isAriaDisabled ? preventedEvents(inoperableEvents) : null), { href: href, ref: this.ref, className: classes, id: componentID }), componentContent));
|
100 | };
|
101 | return (React.createElement(DropdownContext.Consumer, null, ({ onSelect, itemClass, disabledClass, plainTextClass }) => {
|
102 | if (this.props.role !== 'separator') {
|
103 | classes = css(classes, isDisabled && disabledClass, isPlainText && plainTextClass, itemClass, description && styles.modifiers.description);
|
104 | }
|
105 | if (customChild) {
|
106 | return React.cloneElement(customChild, {
|
107 | ref: this.ref,
|
108 | onKeyDown: this.onKeyDown
|
109 | });
|
110 | }
|
111 | return (React.createElement("li", { className: listItemClassName || null, role: role, onKeyDown: this.onKeyDown, onClick: (event) => {
|
112 | if (!isDisabled && !isAriaDisabled) {
|
113 | onClick(event);
|
114 | onSelect(event);
|
115 | }
|
116 | }, id: id },
|
117 | renderWithTooltip(React.isValidElement(component)
|
118 | ? renderClonedComponent(component)
|
119 | : renderDefaultComponent(component)),
|
120 | additionalChild && this.extendAdditionalChildRef()));
|
121 | }));
|
122 | }
|
123 | }
|
124 | InternalDropdownItem.displayName = 'InternalDropdownItem';
|
125 | InternalDropdownItem.defaultProps = {
|
126 | className: '',
|
127 | isHovered: false,
|
128 | component: 'a',
|
129 | role: 'none',
|
130 | isDisabled: false,
|
131 | isPlainText: false,
|
132 | tooltipProps: {},
|
133 |
|
134 | onClick: (event) => undefined,
|
135 | index: -1,
|
136 | context: {
|
137 | keyHandler: () => { },
|
138 | sendRef: () => { }
|
139 | },
|
140 | enterTriggersArrowDown: false,
|
141 | icon: null,
|
142 | styleChildren: true,
|
143 | description: null,
|
144 | inoperableEvents: ['onClick', 'onKeyPress']
|
145 | };
|
146 |
|
\ | No newline at end of file |