Skip to content

Commit 5fac34e

Browse files
feat(Dropdown): Add new prop so Links are treated better (#3889)
* feat(Dropdown): Add new prop so Links are treated better When prop is used, class is applied to child so that the link is full-width and even clicking on the padding gets you where you need to go. Link color also remains black. Fixes #3641 * Fix wrapper, remove examples * Reworked with new prop; adjusted css concatenation tool * modification to allow react children * examples Co-authored-by: Joachim Schuler <jschuler@redhat.com>
1 parent 013ff15 commit 5fac34e

File tree

2 files changed

+63
-25
lines changed

2 files changed

+63
-25
lines changed

packages/react-core/src/components/Dropdown/InternalDropdownItem.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,18 +151,15 @@ export class InternalDropdownItem extends React.Component<InternalDropdownItemPr
151151
} = this.props;
152152
/* eslint-enable @typescript-eslint/no-unused-vars */
153153
const Component = component as any;
154-
let isComponentReactElement = false;
155154
let classes: string;
155+
const isChildReactElement = React.isValidElement(children);
156+
156157
if (Component === 'a') {
157158
additionalProps['aria-disabled'] = isDisabled;
158159
additionalProps.tabIndex = isDisabled ? -1 : additionalProps.tabIndex;
159160
} else if (Component === 'button') {
160161
additionalProps.disabled = isDisabled;
161162
additionalProps.type = additionalProps.type || 'button';
162-
} else if (React.isValidElement(Component)) {
163-
// Render a custom wrapper component, for example router Link component
164-
// instead of our wrapper
165-
isComponentReactElement = true;
166163
}
167164

168165
const renderWithTooltip = (childNode: React.ReactNode) =>
@@ -202,9 +199,11 @@ export class InternalDropdownItem extends React.Component<InternalDropdownItemPr
202199
id={id}
203200
>
204201
{renderWithTooltip(
205-
isComponentReactElement ? (
206-
React.cloneElement(Component as React.ReactHTMLElement<any>, {
202+
isChildReactElement ? (
203+
React.cloneElement(children as React.ReactElement<any>, {
207204
...additionalProps,
205+
ref: this.ref,
206+
id,
208207
className: css(classes, itemClass, variant === 'icon' && styles.modifiers.icon)
209208
})
210209
) : (

packages/react-core/src/components/Dropdown/examples/Dropdown.md

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ typescript: true
99

1010
import { Dropdown, DropdownToggle, DropdownToggleCheckbox, DropdownItem, DropdownItemIcon, DropdownSeparator, DropdownPosition, DropdownDirection, KebabToggle, DropdownGroup, DropdownToggleAction } from '@patternfly/react-core';
1111
import { ThIcon, CaretDownIcon, CogIcon, BellIcon, CubesIcon } from '@patternfly/react-icons';
12+
import { Link } from '@reach/router';
1213

1314
## Examples
1415

@@ -1105,26 +1106,64 @@ class DropdownPanel extends React.Component {
11051106
}
11061107
```
11071108

1108-
## React router link usage
1109+
```js title=React-Router-Link-Usage
1110+
import React from 'react';
1111+
import {
1112+
Button,
1113+
Dropdown,
1114+
DropdownToggle,
1115+
DropdownItem,
1116+
DropdownSeparator,
1117+
DropdownPosition,
1118+
DropdownDirection,
1119+
KebabToggle
1120+
} from '@patternfly/react-core';
1121+
import { Link } from '@reach/router';
1122+
import { ThIcon, CaretDownIcon } from '@patternfly/react-icons';
11091123

1110-
A react-router Link may be wrapped by DropdownItem or used directly within Dropdown. Here's some example JSX:
1124+
class RouterDropdown extends React.Component {
1125+
constructor(props) {
1126+
super(props);
1127+
this.state = {
1128+
isOpen: false
1129+
};
1130+
this.onToggle = isOpen => {
1131+
this.setState({
1132+
isOpen
1133+
});
1134+
};
1135+
this.onSelect = event => {
1136+
this.setState({
1137+
isOpen: !this.state.isOpen
1138+
});
1139+
this.onFocus();
1140+
};
1141+
this.onFocus = () => {
1142+
const element = document.getElementById('toggle-id');
1143+
element.focus();
1144+
};
1145+
}
11111146

1112-
<!-- eslint-skip -->
1113-
```js noLive
1114-
/** Wrapped Link for DropdownItem list **/
1115-
<DropdownItem key="link">
1116-
<Link to={'/'}>Link</Link>
1117-
</DropdownItem>
1147+
render() {
1148+
const { isOpen } = this.state;
1149+
const dropdownItems = [
1150+
<DropdownItem key="routerlink">
1151+
<Link to="/">Link</Link>
1152+
</DropdownItem>
1153+
];
11181154

1119-
/** Direct child of Dropdown **/
1120-
<Dropdown
1121-
onSelect={this.onSelect}
1122-
toggle={
1123-
<DropdownToggle onToggle={this.onToggle}>
1124-
Expanded Dropdown
1125-
</DropdownToggle>
1155+
return (
1156+
<Dropdown
1157+
onSelect={this.onSelect}
1158+
toggle={
1159+
<DropdownToggle id="toggle-id" onToggle={this.onToggle} iconComponent={CaretDownIcon}>
1160+
Dropdown
1161+
</DropdownToggle>
1162+
}
1163+
isOpen={isOpen}
1164+
dropdownItems={dropdownItems}
1165+
/>
1166+
);
11261167
}
1127-
isOpen={isOpen}>
1128-
<Link to={'/'}>Link</Link>
1129-
</Dropdown>
1168+
}
11301169
```

0 commit comments

Comments
 (0)