@patternfly/react-core 4.245.0 → 4.247.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/esm/components/DualListSelector/DualListSelectorPane.d.ts +2 -0
- package/dist/esm/components/DualListSelector/DualListSelectorPane.d.ts.map +1 -1
- package/dist/esm/components/DualListSelector/DualListSelectorPane.js +4 -5
- package/dist/esm/components/DualListSelector/DualListSelectorPane.js.map +1 -1
- package/dist/esm/components/SearchInput/SearchInput.d.ts +2 -0
- package/dist/esm/components/SearchInput/SearchInput.d.ts.map +1 -1
- package/dist/esm/components/SearchInput/SearchInput.js +2 -2
- package/dist/esm/components/SearchInput/SearchInput.js.map +1 -1
- package/dist/esm/components/TreeView/TreeView.d.ts.map +1 -1
- package/dist/esm/components/TreeView/TreeView.js +1 -1
- package/dist/esm/components/TreeView/TreeView.js.map +1 -1
- package/dist/esm/components/TreeView/TreeViewListItem.d.ts.map +1 -1
- package/dist/esm/components/TreeView/TreeViewListItem.js +2 -2
- package/dist/esm/components/TreeView/TreeViewListItem.js.map +1 -1
- package/dist/esm/components/TreeView/TreeViewRoot.d.ts +5 -3
- package/dist/esm/components/TreeView/TreeViewRoot.d.ts.map +1 -1
- package/dist/esm/components/TreeView/TreeViewRoot.js +26 -17
- package/dist/esm/components/TreeView/TreeViewRoot.js.map +1 -1
- package/dist/js/components/DualListSelector/DualListSelectorPane.d.ts +2 -0
- package/dist/js/components/DualListSelector/DualListSelectorPane.d.ts.map +1 -1
- package/dist/js/components/DualListSelector/DualListSelectorPane.js +4 -5
- package/dist/js/components/DualListSelector/DualListSelectorPane.js.map +1 -1
- package/dist/js/components/SearchInput/SearchInput.d.ts +2 -0
- package/dist/js/components/SearchInput/SearchInput.d.ts.map +1 -1
- package/dist/js/components/SearchInput/SearchInput.js +2 -2
- package/dist/js/components/SearchInput/SearchInput.js.map +1 -1
- package/dist/js/components/TreeView/TreeView.d.ts.map +1 -1
- package/dist/js/components/TreeView/TreeView.js +1 -1
- package/dist/js/components/TreeView/TreeView.js.map +1 -1
- package/dist/js/components/TreeView/TreeViewListItem.d.ts.map +1 -1
- package/dist/js/components/TreeView/TreeViewListItem.js +2 -2
- package/dist/js/components/TreeView/TreeViewListItem.js.map +1 -1
- package/dist/js/components/TreeView/TreeViewRoot.d.ts +5 -3
- package/dist/js/components/TreeView/TreeViewRoot.d.ts.map +1 -1
- package/dist/js/components/TreeView/TreeViewRoot.js +26 -17
- package/dist/js/components/TreeView/TreeViewRoot.js.map +1 -1
- package/dist/umd/react-core.min.css +3370 -3370
- package/dist/umd/react-core.min.js +2 -2
- package/package.json +2 -2
- package/src/components/Dropdown/examples/Dropdown.md +79 -55
- package/src/components/DualListSelector/DualListSelectorPane.tsx +11 -7
- package/src/components/DualListSelector/__tests__/__snapshots__/DualListSelector.test.tsx.snap +70 -10
- package/src/components/SearchInput/SearchInput.tsx +15 -0
- package/src/components/TreeView/TreeView.tsx +8 -1
- package/src/components/TreeView/TreeViewListItem.tsx +4 -3
- package/src/components/TreeView/TreeViewRoot.tsx +38 -18
- package/src/components/TreeView/__tests__/__snapshots__/TreeView.test.tsx.snap +0 -51
- package/src/demos/ComposableMenu/ComposableMenu.md +7 -2
- package/src/demos/ComposableMenu/examples/ComposableMultipleTypeaheadSelect.tsx +220 -0
- package/src/components/Dropdown/examples/DropdownSplitButtonIndeterminate.tsx +0 -78
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.247.0",
|
|
4
4
|
"description": "This library provides a set of common React components for use with the PatternFly reference implementation.",
|
|
5
5
|
"main": "dist/js/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"react": "^16.8 || ^17 || ^18",
|
|
71
71
|
"react-dom": "^16.8 || ^17 || ^18"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "064d341a881a7ab291add565ed1929cf915ab049"
|
|
74
74
|
}
|
|
@@ -18,133 +18,157 @@ import avatarImg from '../../Avatar/examples/avatarImg.svg';
|
|
|
18
18
|
|
|
19
19
|
## Examples
|
|
20
20
|
|
|
21
|
-
### Basic
|
|
21
|
+
### Basic dropdowns
|
|
22
|
+
|
|
23
|
+
Basic dropdowns present users with a menu of items upon clicking a dropdown toggle. The `isOpen` property is used to determine whether the menu is opened or not.
|
|
24
|
+
|
|
25
|
+
All of the items in a dropdown list are created as `<DropdownItem>` components. The following example shows a few different states of dropdown items. As shown in this example, dropdown items may:
|
|
26
|
+
- Use the `tooltip` property to enable tooltip support.
|
|
27
|
+
- Use the `isDisabled` property to disable an item.
|
|
28
|
+
- Use the `isAriaDisabled` property to style an item as disabled, while still allowing the item to receive keyboard focus and display a tooltip.
|
|
29
|
+
|
|
30
|
+
This example also uses a `<DropdownSeparator>`, which adds a horizontal line that splits the menu into 2 sections.
|
|
22
31
|
|
|
23
32
|
```ts file='./DropdownBasic.tsx'
|
|
24
33
|
```
|
|
25
34
|
|
|
26
|
-
###
|
|
35
|
+
### Autofocus on dropdown expansion
|
|
36
|
+
|
|
37
|
+
A `<DropdownItem>` may use the `autoFocus` property so that it automatically receives focus when the menu is expanded. `autoFocus` cannot be applied to disabled dropdown items.
|
|
27
38
|
|
|
28
39
|
```ts file="./DropdownInitialSelection.tsx"
|
|
29
40
|
```
|
|
30
41
|
|
|
31
|
-
### With groups
|
|
42
|
+
### With groups of items
|
|
43
|
+
|
|
44
|
+
Use the `<DropdownGroup>` component to group sets of related dropdown items together. Use the `isGrouped` property on the `Dropdown` component to indicate that a dropdown contains grouped items.
|
|
32
45
|
|
|
33
46
|
```ts file="./DropdownGroups.tsx"
|
|
34
47
|
```
|
|
35
48
|
|
|
36
|
-
###
|
|
49
|
+
### With item descriptions
|
|
37
50
|
|
|
38
|
-
|
|
51
|
+
A `<DropdownItem>` may use the `description` property to provide users with more context. This description will appear in the menu below the dropdown item it corresponds to.
|
|
52
|
+
|
|
53
|
+
```ts file="./DropdownDescriptions.tsx"
|
|
39
54
|
```
|
|
40
55
|
|
|
41
|
-
###
|
|
56
|
+
### With custom content
|
|
42
57
|
|
|
43
|
-
|
|
58
|
+
You may replace standard dropdown items with custom content. If so, you must style the menu contents and manage focus within your custom implementation.
|
|
59
|
+
|
|
60
|
+
```ts file="./DropdownBasicPanel.tsx"
|
|
44
61
|
```
|
|
45
62
|
|
|
46
|
-
###
|
|
63
|
+
### With router link items
|
|
47
64
|
|
|
48
|
-
|
|
65
|
+
`<DropdownItem>` may use the `component` property to include router links.
|
|
66
|
+
|
|
67
|
+
```ts file="./DropdownRouterLink.tsx"
|
|
49
68
|
```
|
|
50
69
|
|
|
51
|
-
###
|
|
70
|
+
### Toggle styling
|
|
52
71
|
|
|
53
|
-
|
|
72
|
+
You can adjust the styling of a `<DropdownToggle>` using the `toggleVariant` property. `toggleVariant` may be set to 'primary', 'secondary', or 'default'.
|
|
73
|
+
|
|
74
|
+
```ts file="./DropdownPrimaryToggle.tsx"
|
|
54
75
|
```
|
|
55
76
|
|
|
56
|
-
###
|
|
77
|
+
### Plain text toggle
|
|
57
78
|
|
|
58
|
-
|
|
79
|
+
A toggle may be styled as plain text using the `isText` and `isPlain`properties. The following example applies these properties to a `<Dropdown>` component.
|
|
80
|
+
|
|
81
|
+
```ts file="./DropdownPlainTextToggle.tsx"
|
|
59
82
|
```
|
|
60
83
|
|
|
61
|
-
###
|
|
84
|
+
### Disabled toggles
|
|
62
85
|
|
|
63
|
-
|
|
86
|
+
A `<DropdownToggle>` may use the `isDisabled` property to disable the expansion of the dropdown menu.
|
|
87
|
+
|
|
88
|
+
```ts file="./DropdownDisabled.tsx"
|
|
64
89
|
```
|
|
65
90
|
|
|
66
|
-
###
|
|
91
|
+
### Icon toggle
|
|
67
92
|
|
|
68
|
-
|
|
93
|
+
`<DropdownToggle>` may use a recognizable icon instead of a text label if text would take up too much room. Set the `toggleIndicator` property to `{null}` to remove the default dropdown toggle caret.
|
|
94
|
+
|
|
95
|
+
```ts file="./DropdownIconOnly.tsx"
|
|
69
96
|
```
|
|
70
97
|
|
|
71
|
-
###
|
|
98
|
+
### Kebab toggle
|
|
99
|
+
|
|
100
|
+
Use `<KebabToggle>` to replace the default text label and caret with a kebab icon. A kebab toggle can be used to indicate that a dropdown connects to a menu.
|
|
72
101
|
|
|
73
102
|
```ts file="./DropdownKebab.tsx"
|
|
74
103
|
```
|
|
75
104
|
|
|
76
|
-
###
|
|
105
|
+
### Toggle with image
|
|
77
106
|
|
|
78
|
-
|
|
107
|
+
The `icon` property can be used to display an image in the `DropdownToggle` and can be used alongside a text label.
|
|
108
|
+
|
|
109
|
+
```ts file="./DropdownImageAndText.tsx"
|
|
79
110
|
```
|
|
80
111
|
|
|
81
|
-
###
|
|
112
|
+
### Toggle with badge
|
|
82
113
|
|
|
83
|
-
|
|
114
|
+
You may use a `<BadgeToggle>` to display the number of dropdown menu items.
|
|
115
|
+
|
|
116
|
+
```ts file="./DropdownBadge.tsx"
|
|
84
117
|
```
|
|
85
118
|
|
|
86
119
|
### Split button
|
|
87
120
|
|
|
88
|
-
|
|
89
|
-
```
|
|
121
|
+
To combine an action button or other control with a dropdown menu, use a split button. A `<DropdownToggle>` can be rendered as a split button by using the `splitButtonItems` property. Elements to be displayed before the toggle button must be included in `splitButtonItems`.
|
|
90
122
|
|
|
91
|
-
|
|
123
|
+
The following example shows a split button with a `<DropdownToggleCheckbox>`, which is primarily used for bulk select operations on large data sets.
|
|
92
124
|
|
|
93
|
-
```ts file="./
|
|
125
|
+
```ts file="./DropdownSplitButton.tsx"
|
|
94
126
|
```
|
|
95
127
|
|
|
96
|
-
### Split button
|
|
97
|
-
|
|
98
|
-
```ts file="./DropdownSplitButtonIndeterminate.tsx"
|
|
99
|
-
```
|
|
128
|
+
### Split button text label
|
|
100
129
|
|
|
101
|
-
|
|
130
|
+
Text labels may optionally be used alongside actions within split buttons.
|
|
102
131
|
|
|
103
|
-
```ts file="./
|
|
132
|
+
```ts file="./DropdownSplitButtonText.tsx"
|
|
104
133
|
```
|
|
105
134
|
|
|
106
|
-
### Split button
|
|
135
|
+
### Split button toggle variants
|
|
107
136
|
|
|
108
|
-
|
|
109
|
-
```
|
|
137
|
+
Use the `toggleVariant` and `splitButtonVariant` properties to adjust the styling of split button toggles.
|
|
110
138
|
|
|
111
|
-
|
|
139
|
+
The following example uses `toggleVariant="primary"` to apply primary visual styling and `splitButtonVariant="action"` to include an action.
|
|
112
140
|
|
|
113
141
|
```ts file="./DropdownSplitButtonActionPrimary.tsx"
|
|
114
142
|
```
|
|
115
143
|
|
|
116
|
-
###
|
|
144
|
+
### Dropdown alignment
|
|
117
145
|
|
|
118
|
-
|
|
119
|
-
```
|
|
146
|
+
The alignment of a dropdown menu may be changed to better fit the size of a user's browser window. A `<Dropdown>` may use the `alignments` property to indicate how the menu will align at different screen sizes.
|
|
120
147
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
```ts file="./DropdownBasicPanel.tsx"
|
|
148
|
+
```ts file="./DropdownAlignmentOnBreakpoints.tsx"
|
|
124
149
|
```
|
|
125
150
|
|
|
126
|
-
###
|
|
151
|
+
### Right-positioned menu
|
|
127
152
|
|
|
128
|
-
|
|
153
|
+
The following example demonstrates a `<Dropdown>` with a `position` equal to 'right'. By default, a dropdown menu is left-positioned, but a right-positioned menu may work better depending on where your dropdown is placed on a page.
|
|
154
|
+
|
|
155
|
+
```ts file="./DropdownPositionRight.tsx"
|
|
129
156
|
```
|
|
130
157
|
|
|
131
|
-
###
|
|
158
|
+
### Upwards directional menu
|
|
132
159
|
|
|
133
|
-
|
|
160
|
+
The following example demonstrates a `<Dropdown>` with a `direction` equal to 'up'. This will alter the default menu behavior so that the dropdown menu is displayed above the dropdown toggle.
|
|
161
|
+
|
|
162
|
+
```ts file="./DropdownDirectionUp.tsx"
|
|
134
163
|
```
|
|
135
164
|
|
|
136
|
-
###
|
|
165
|
+
### Using document parent element
|
|
137
166
|
|
|
138
|
-
Avoid passing in `document.body`
|
|
167
|
+
Avoid passing in `document.body` to a `<Dropdown>` `menuAppendTo` property. Doing so can cause accessibility issues, such as being unable to navigate `<Dropdown>` options using keyboards or screen readers.
|
|
139
168
|
|
|
140
|
-
Instead append to
|
|
169
|
+
Instead, append to ‘parent’ to avoid sacrificing accessibility.
|
|
141
170
|
|
|
142
|
-
|
|
171
|
+
The following example demonstrates both methods of appending. After making a selection, both dropdowns retain focus on their respective `<Dropdown>`, but the options for the `document.body` variant cannot be navigated via Voice Over.
|
|
143
172
|
|
|
144
173
|
```ts file="./DropdownAppendBodyVsParent.tsx"
|
|
145
174
|
```
|
|
146
|
-
|
|
147
|
-
### Dropdown with descriptions
|
|
148
|
-
|
|
149
|
-
```ts file="./DropdownDescriptions.tsx"
|
|
150
|
-
```
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import styles from '@patternfly/react-styles/css/components/DualListSelector/dual-list-selector';
|
|
3
3
|
import { css } from '@patternfly/react-styles';
|
|
4
|
-
import formStyles from '@patternfly/react-styles/css/components/FormControl/form-control';
|
|
5
4
|
import { DualListSelectorTree, DualListSelectorTreeItemData } from './DualListSelectorTree';
|
|
6
5
|
import { getUniqueId } from '../../helpers';
|
|
7
6
|
import { DualListSelectorListWrapper } from './DualListSelectorListWrapper';
|
|
8
7
|
import { DualListSelectorContext, DualListSelectorPaneContext } from './DualListSelectorContext';
|
|
9
8
|
import { DualListSelectorList } from './DualListSelectorList';
|
|
9
|
+
import { SearchInput } from '../SearchInput';
|
|
10
10
|
|
|
11
11
|
/** Acts as the container for a list of options that are either available or chosen,
|
|
12
12
|
* depending on the pane type (available or chosen). A search input and other actions,
|
|
@@ -57,6 +57,8 @@ export interface DualListSelectorPaneProps {
|
|
|
57
57
|
onSearch?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
58
58
|
/** @hide A callback for when the search input value for changes. To be used when isSearchable is true. */
|
|
59
59
|
onSearchInputChanged?: (value: string, event: React.FormEvent<HTMLInputElement>) => void;
|
|
60
|
+
/** @hide Callback for search input clear button */
|
|
61
|
+
onSearchInputClear?: (event: React.SyntheticEvent<HTMLButtonElement>) => void;
|
|
60
62
|
/** @hide Filter function for custom filtering based on search string. To be used when isSearchable is true. */
|
|
61
63
|
filterOption?: (option: React.ReactNode, input: string) => boolean;
|
|
62
64
|
/** @hide Accessible label for the search input. To be used when isSearchable is true. */
|
|
@@ -81,6 +83,7 @@ export const DualListSelectorPane: React.FunctionComponent<DualListSelectorPaneP
|
|
|
81
83
|
searchInputAriaLabel = '',
|
|
82
84
|
onFilterUpdate,
|
|
83
85
|
onSearchInputChanged,
|
|
86
|
+
onSearchInputClear,
|
|
84
87
|
filterOption,
|
|
85
88
|
id = getUniqueId('dual-list-selector-pane'),
|
|
86
89
|
isDisabled = false,
|
|
@@ -90,8 +93,7 @@ export const DualListSelectorPane: React.FunctionComponent<DualListSelectorPaneP
|
|
|
90
93
|
const { isTree } = React.useContext(DualListSelectorContext);
|
|
91
94
|
|
|
92
95
|
// only called when search input is dynamically built
|
|
93
|
-
const onChange = (e: React.
|
|
94
|
-
const newValue = e.target.value;
|
|
96
|
+
const onChange = (newValue: string, e: React.FormEvent<HTMLInputElement>) => {
|
|
95
97
|
let filtered: React.ReactNode[];
|
|
96
98
|
if (isTree) {
|
|
97
99
|
filtered = options
|
|
@@ -160,12 +162,14 @@ export const DualListSelectorPane: React.FunctionComponent<DualListSelectorPaneP
|
|
|
160
162
|
{searchInput ? (
|
|
161
163
|
searchInput
|
|
162
164
|
) : (
|
|
163
|
-
<
|
|
164
|
-
className={css(formStyles.formControl, formStyles.modifiers.search)}
|
|
165
|
-
type="search"
|
|
165
|
+
<SearchInput
|
|
166
166
|
onChange={isDisabled ? undefined : onChange}
|
|
167
|
+
onClear={
|
|
168
|
+
onSearchInputClear ? onSearchInputClear : e => onChange('', e as React.FormEvent<HTMLInputElement>)
|
|
169
|
+
}
|
|
170
|
+
isDisabled={isDisabled}
|
|
167
171
|
aria-label={searchInputAriaLabel}
|
|
168
|
-
|
|
172
|
+
type="search"
|
|
169
173
|
/>
|
|
170
174
|
)}
|
|
171
175
|
</div>
|
package/src/components/DualListSelector/__tests__/__snapshots__/DualListSelector.test.tsx.snap
CHANGED
|
@@ -1135,11 +1135,41 @@ exports[`DualListSelector with search inputs 1`] = `
|
|
|
1135
1135
|
<div
|
|
1136
1136
|
class="pf-c-dual-list-selector__tools-filter"
|
|
1137
1137
|
>
|
|
1138
|
-
<
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1138
|
+
<div
|
|
1139
|
+
class="pf-c-text-input-group"
|
|
1140
|
+
>
|
|
1141
|
+
<div
|
|
1142
|
+
class="pf-c-text-input-group__main pf-m-icon"
|
|
1143
|
+
>
|
|
1144
|
+
<span
|
|
1145
|
+
class="pf-c-text-input-group__text"
|
|
1146
|
+
>
|
|
1147
|
+
<span
|
|
1148
|
+
class="pf-c-text-input-group__icon"
|
|
1149
|
+
>
|
|
1150
|
+
<svg
|
|
1151
|
+
aria-hidden="true"
|
|
1152
|
+
fill="currentColor"
|
|
1153
|
+
height="1em"
|
|
1154
|
+
role="img"
|
|
1155
|
+
style="vertical-align: -0.125em;"
|
|
1156
|
+
viewBox="0 0 512 512"
|
|
1157
|
+
width="1em"
|
|
1158
|
+
>
|
|
1159
|
+
<path
|
|
1160
|
+
d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"
|
|
1161
|
+
/>
|
|
1162
|
+
</svg>
|
|
1163
|
+
</span>
|
|
1164
|
+
<input
|
|
1165
|
+
aria-label="Available search input"
|
|
1166
|
+
class="pf-c-text-input-group__text-input"
|
|
1167
|
+
type="search"
|
|
1168
|
+
value=""
|
|
1169
|
+
/>
|
|
1170
|
+
</span>
|
|
1171
|
+
</div>
|
|
1172
|
+
</div>
|
|
1143
1173
|
</div>
|
|
1144
1174
|
</div>
|
|
1145
1175
|
<div
|
|
@@ -1360,11 +1390,41 @@ exports[`DualListSelector with search inputs 1`] = `
|
|
|
1360
1390
|
<div
|
|
1361
1391
|
class="pf-c-dual-list-selector__tools-filter"
|
|
1362
1392
|
>
|
|
1363
|
-
<
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1393
|
+
<div
|
|
1394
|
+
class="pf-c-text-input-group"
|
|
1395
|
+
>
|
|
1396
|
+
<div
|
|
1397
|
+
class="pf-c-text-input-group__main pf-m-icon"
|
|
1398
|
+
>
|
|
1399
|
+
<span
|
|
1400
|
+
class="pf-c-text-input-group__text"
|
|
1401
|
+
>
|
|
1402
|
+
<span
|
|
1403
|
+
class="pf-c-text-input-group__icon"
|
|
1404
|
+
>
|
|
1405
|
+
<svg
|
|
1406
|
+
aria-hidden="true"
|
|
1407
|
+
fill="currentColor"
|
|
1408
|
+
height="1em"
|
|
1409
|
+
role="img"
|
|
1410
|
+
style="vertical-align: -0.125em;"
|
|
1411
|
+
viewBox="0 0 512 512"
|
|
1412
|
+
width="1em"
|
|
1413
|
+
>
|
|
1414
|
+
<path
|
|
1415
|
+
d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"
|
|
1416
|
+
/>
|
|
1417
|
+
</svg>
|
|
1418
|
+
</span>
|
|
1419
|
+
<input
|
|
1420
|
+
aria-label="Chosen search input"
|
|
1421
|
+
class="pf-c-text-input-group__text-input"
|
|
1422
|
+
type="search"
|
|
1423
|
+
value=""
|
|
1424
|
+
/>
|
|
1425
|
+
</span>
|
|
1426
|
+
</div>
|
|
1427
|
+
</div>
|
|
1368
1428
|
</div>
|
|
1369
1429
|
</div>
|
|
1370
1430
|
<div
|
|
@@ -70,6 +70,19 @@ export interface SearchInputProps extends Omit<React.HTMLProps<HTMLDivElement>,
|
|
|
70
70
|
hasWordsAttrLabel?: React.ReactNode;
|
|
71
71
|
/** A suggestion for autocompleting. */
|
|
72
72
|
hint?: string;
|
|
73
|
+
/** Type of the input */
|
|
74
|
+
type?:
|
|
75
|
+
| 'text'
|
|
76
|
+
| 'date'
|
|
77
|
+
| 'datetime-local'
|
|
78
|
+
| 'email'
|
|
79
|
+
| 'month'
|
|
80
|
+
| 'number'
|
|
81
|
+
| 'password'
|
|
82
|
+
| 'search'
|
|
83
|
+
| 'tel'
|
|
84
|
+
| 'time'
|
|
85
|
+
| 'url';
|
|
73
86
|
/** @hide A reference object to attach to the input box. */
|
|
74
87
|
innerRef?: React.RefObject<any>;
|
|
75
88
|
/** A flag for controlling the open state of a custom advanced search implementation. */
|
|
@@ -147,6 +160,7 @@ const SearchInputBase: React.FunctionComponent<SearchInputProps> = ({
|
|
|
147
160
|
isDisabled = false,
|
|
148
161
|
appendTo,
|
|
149
162
|
removeFindDomNode = false,
|
|
163
|
+
type = 'text',
|
|
150
164
|
...props
|
|
151
165
|
}: SearchInputProps) => {
|
|
152
166
|
const [isSearchMenuOpen, setIsSearchMenuOpen] = React.useState(false);
|
|
@@ -263,6 +277,7 @@ const SearchInputBase: React.FunctionComponent<SearchInputProps> = ({
|
|
|
263
277
|
aria-label={ariaLabel}
|
|
264
278
|
onKeyDown={onEnter}
|
|
265
279
|
onChange={onChangeHandler}
|
|
280
|
+
type={type}
|
|
266
281
|
/>
|
|
267
282
|
{renderUtilities && (
|
|
268
283
|
<TextInputGroupUtilities>
|
|
@@ -168,7 +168,14 @@ export const TreeView: React.FunctionComponent<TreeViewProps> = ({
|
|
|
168
168
|
{parentItem ? (
|
|
169
169
|
treeViewList
|
|
170
170
|
) : (
|
|
171
|
-
<TreeViewRoot
|
|
171
|
+
<TreeViewRoot
|
|
172
|
+
hasSelectableNodes={hasSelectableNodes}
|
|
173
|
+
hasChecks={hasChecks}
|
|
174
|
+
hasGuides={hasGuides}
|
|
175
|
+
variant={variant}
|
|
176
|
+
className={className}
|
|
177
|
+
{...props}
|
|
178
|
+
>
|
|
172
179
|
{treeViewList}
|
|
173
180
|
</TreeViewRoot>
|
|
174
181
|
)}
|
|
@@ -155,8 +155,10 @@ const TreeViewListItemBase: React.FunctionComponent<TreeViewListItemProps> = ({
|
|
|
155
155
|
const content = (
|
|
156
156
|
<>
|
|
157
157
|
{isCompact && title && <span className={css(styles.treeViewNodeTitle)}>{title}</span>}
|
|
158
|
-
{
|
|
159
|
-
<
|
|
158
|
+
{isSelectable ? (
|
|
159
|
+
<button tabIndex={-1} className={css(styles.treeViewNodeText)}>
|
|
160
|
+
{name}
|
|
161
|
+
</button>
|
|
160
162
|
) : (
|
|
161
163
|
<span className={css(styles.treeViewNodeText)}>{name}</span>
|
|
162
164
|
)}
|
|
@@ -210,7 +212,6 @@ const TreeViewListItemBase: React.FunctionComponent<TreeViewListItemProps> = ({
|
|
|
210
212
|
}
|
|
211
213
|
}
|
|
212
214
|
}}
|
|
213
|
-
tabIndex={isSelectable ? 0 : -1}
|
|
214
215
|
{...(hasCheck && { htmlFor: randomId })}
|
|
215
216
|
{...((hasCheck || (isSelectable && children)) && { id: `label-${randomId}` })}
|
|
216
217
|
>
|
|
@@ -3,18 +3,21 @@ import { css } from '@patternfly/react-styles';
|
|
|
3
3
|
import styles from '@patternfly/react-styles/css/components/TreeView/tree-view';
|
|
4
4
|
import { canUseDOM } from '../../helpers/util';
|
|
5
5
|
import { handleArrows } from '../../helpers';
|
|
6
|
+
import { KeyTypes } from '../../helpers/constants';
|
|
6
7
|
|
|
7
8
|
export interface TreeViewRootProps {
|
|
8
|
-
/** Child nodes of the tree view
|
|
9
|
+
/** Child nodes of the tree view */
|
|
9
10
|
children: React.ReactNode;
|
|
10
|
-
/** Class to add to add if not passed a parentItem property. */
|
|
11
|
-
className?: string;
|
|
12
11
|
/** Flag indicating if the tree view has checkboxes. */
|
|
13
12
|
hasChecks?: boolean;
|
|
14
13
|
/** Flag indicating if tree view has guide lines. */
|
|
15
14
|
hasGuides?: boolean;
|
|
16
15
|
/** Variant presentation styles for the tree view. */
|
|
17
16
|
variant?: 'default' | 'compact' | 'compactNoBackground';
|
|
17
|
+
/** Class to add to add if not passed a parentItem */
|
|
18
|
+
className?: string;
|
|
19
|
+
/** Flag indicating that tree nodes should be independently selectable, even when having children */
|
|
20
|
+
hasSelectableNodes?: boolean;
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
export class TreeViewRoot extends React.Component<TreeViewRootProps> {
|
|
@@ -23,16 +26,29 @@ export class TreeViewRoot extends React.Component<TreeViewRootProps> {
|
|
|
23
26
|
|
|
24
27
|
componentDidMount() {
|
|
25
28
|
if (canUseDOM) {
|
|
26
|
-
window.addEventListener(
|
|
29
|
+
window.addEventListener(
|
|
30
|
+
'keydown',
|
|
31
|
+
this.props.hasChecks || this.props.hasSelectableNodes ? this.handleKeysCheckbox : this.handleKeys
|
|
32
|
+
);
|
|
27
33
|
}
|
|
28
|
-
if (this.props.hasChecks) {
|
|
29
|
-
const firstToggle = this.treeRef.current
|
|
34
|
+
if (this.props.hasChecks || this.props.hasSelectableNodes) {
|
|
35
|
+
const firstToggle = this.treeRef.current.getElementsByClassName('pf-c-tree-view__node-toggle')[0] as HTMLElement;
|
|
30
36
|
if (firstToggle) {
|
|
31
37
|
firstToggle.tabIndex = 0;
|
|
32
38
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
firstInput
|
|
39
|
+
if (this.props.hasChecks) {
|
|
40
|
+
const firstInput = this.treeRef.current.getElementsByTagName('INPUT')[0] as HTMLElement;
|
|
41
|
+
if (firstInput) {
|
|
42
|
+
firstInput.tabIndex = 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (this.props.hasSelectableNodes) {
|
|
46
|
+
const firstTextButton = this.treeRef.current.getElementsByClassName(
|
|
47
|
+
'pf-c-tree-view__node-text'
|
|
48
|
+
)[0] as HTMLElement;
|
|
49
|
+
if (firstTextButton) {
|
|
50
|
+
firstTextButton.tabIndex = 0;
|
|
51
|
+
}
|
|
36
52
|
}
|
|
37
53
|
} else {
|
|
38
54
|
(this.treeRef.current?.getElementsByClassName('pf-c-tree-view__node')[0] as HTMLElement).tabIndex = 0;
|
|
@@ -41,12 +57,15 @@ export class TreeViewRoot extends React.Component<TreeViewRootProps> {
|
|
|
41
57
|
|
|
42
58
|
componentWillUnmount() {
|
|
43
59
|
if (canUseDOM) {
|
|
44
|
-
window.removeEventListener(
|
|
60
|
+
window.removeEventListener(
|
|
61
|
+
'keydown',
|
|
62
|
+
this.props.hasChecks || this.props.hasSelectableNodes ? this.handleKeysCheckbox : this.handleKeys
|
|
63
|
+
);
|
|
45
64
|
}
|
|
46
65
|
}
|
|
47
66
|
|
|
48
67
|
handleKeys = (event: KeyboardEvent) => {
|
|
49
|
-
if (this.treeRef.current
|
|
68
|
+
if (!this.treeRef.current.contains(event.target as HTMLElement)) {
|
|
50
69
|
return;
|
|
51
70
|
}
|
|
52
71
|
const activeElement = document.activeElement;
|
|
@@ -55,8 +74,8 @@ export class TreeViewRoot extends React.Component<TreeViewRootProps> {
|
|
|
55
74
|
el => !el.classList.contains('pf-m-disabled')
|
|
56
75
|
);
|
|
57
76
|
|
|
58
|
-
if (key ===
|
|
59
|
-
(
|
|
77
|
+
if (key === KeyTypes.Space) {
|
|
78
|
+
(activeElement as HTMLElement).click();
|
|
60
79
|
event.preventDefault();
|
|
61
80
|
}
|
|
62
81
|
|
|
@@ -109,14 +128,15 @@ export class TreeViewRoot extends React.Component<TreeViewRootProps> {
|
|
|
109
128
|
};
|
|
110
129
|
|
|
111
130
|
handleKeysCheckbox = (event: KeyboardEvent) => {
|
|
112
|
-
if (this.treeRef.current
|
|
131
|
+
if (!this.treeRef.current.contains(event.target as HTMLElement)) {
|
|
113
132
|
return;
|
|
114
133
|
}
|
|
134
|
+
|
|
115
135
|
const activeElement = document.activeElement;
|
|
116
136
|
const key = event.key;
|
|
117
137
|
|
|
118
|
-
if (key ===
|
|
119
|
-
(
|
|
138
|
+
if (key === KeyTypes.Space) {
|
|
139
|
+
(activeElement as HTMLElement).click();
|
|
120
140
|
event.preventDefault();
|
|
121
141
|
}
|
|
122
142
|
|
|
@@ -126,7 +146,7 @@ export class TreeViewRoot extends React.Component<TreeViewRootProps> {
|
|
|
126
146
|
event,
|
|
127
147
|
treeNodes as HTMLElement[],
|
|
128
148
|
(element: Element) => element.contains(activeElement),
|
|
129
|
-
(element: Element) => element.querySelector('
|
|
149
|
+
(element: Element) => element.querySelector('button,input'),
|
|
130
150
|
[],
|
|
131
151
|
undefined,
|
|
132
152
|
true,
|
|
@@ -168,7 +188,7 @@ export class TreeViewRoot extends React.Component<TreeViewRootProps> {
|
|
|
168
188
|
|
|
169
189
|
render() {
|
|
170
190
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
171
|
-
const { children, hasChecks, hasGuides, variant, className, ...props } = this.props;
|
|
191
|
+
const { children, hasChecks, hasGuides, variant, className, hasSelectableNodes, ...props } = this.props;
|
|
172
192
|
return (
|
|
173
193
|
<div
|
|
174
194
|
className={css(
|