@patternfly/react-core 5.2.0-prerelease.41 → 5.2.0-prerelease.43
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 +10 -0
- package/components/package.json +1 -1
- package/deprecated/package.json +1 -1
- package/dist/dynamic/components/AboutModal/package.json +1 -1
- package/dist/dynamic/components/Accordion/package.json +1 -1
- package/dist/dynamic/components/ActionList/package.json +1 -1
- package/dist/dynamic/components/Alert/package.json +1 -1
- package/dist/dynamic/components/Avatar/package.json +1 -1
- package/dist/dynamic/components/BackToTop/package.json +1 -1
- package/dist/dynamic/components/Backdrop/package.json +1 -1
- package/dist/dynamic/components/BackgroundImage/package.json +1 -1
- package/dist/dynamic/components/Badge/package.json +1 -1
- package/dist/dynamic/components/Banner/package.json +1 -1
- package/dist/dynamic/components/Brand/package.json +1 -1
- package/dist/dynamic/components/Breadcrumb/package.json +1 -1
- package/dist/dynamic/components/Button/package.json +1 -1
- package/dist/dynamic/components/CalendarMonth/package.json +1 -1
- package/dist/dynamic/components/Card/package.json +1 -1
- package/dist/dynamic/components/Checkbox/package.json +1 -1
- package/dist/dynamic/components/Chip/package.json +1 -1
- package/dist/dynamic/components/ClipboardCopy/package.json +1 -1
- package/dist/dynamic/components/CodeBlock/package.json +1 -1
- package/dist/dynamic/components/DataList/package.json +1 -1
- package/dist/dynamic/components/DatePicker/package.json +1 -1
- package/dist/dynamic/components/DescriptionList/package.json +1 -1
- package/dist/dynamic/components/Divider/package.json +1 -1
- package/dist/dynamic/components/DragDrop/package.json +1 -1
- package/dist/dynamic/components/Drawer/package.json +1 -1
- package/dist/dynamic/components/Dropdown/package.json +1 -1
- package/dist/dynamic/components/DualListSelector/package.json +1 -1
- package/dist/dynamic/components/EmptyState/package.json +1 -1
- package/dist/dynamic/components/ExpandableSection/package.json +1 -1
- package/dist/dynamic/components/FileUpload/package.json +1 -1
- package/dist/dynamic/components/Form/package.json +1 -1
- package/dist/dynamic/components/FormSelect/package.json +1 -1
- package/dist/dynamic/components/HelperText/package.json +1 -1
- package/dist/dynamic/components/Hint/package.json +1 -1
- package/dist/dynamic/components/Icon/package.json +1 -1
- package/dist/dynamic/components/InputGroup/package.json +1 -1
- package/dist/dynamic/components/JumpLinks/package.json +1 -1
- package/dist/dynamic/components/Label/package.json +1 -1
- package/dist/dynamic/components/List/package.json +1 -1
- package/dist/dynamic/components/LoginPage/package.json +1 -1
- package/dist/dynamic/components/Masthead/package.json +1 -1
- package/dist/dynamic/components/Menu/package.json +1 -1
- package/dist/dynamic/components/MenuToggle/package.json +1 -1
- package/dist/dynamic/components/Modal/package.json +1 -1
- package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
- package/dist/dynamic/components/Nav/package.json +1 -1
- package/dist/dynamic/components/NotificationBadge/package.json +1 -1
- package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
- package/dist/dynamic/components/NumberInput/package.json +1 -1
- package/dist/dynamic/components/OverflowMenu/package.json +1 -1
- package/dist/dynamic/components/Page/package.json +1 -1
- package/dist/dynamic/components/Pagination/package.json +1 -1
- package/dist/dynamic/components/Panel/package.json +1 -1
- package/dist/dynamic/components/Popover/package.json +1 -1
- package/dist/dynamic/components/Progress/package.json +1 -1
- package/dist/dynamic/components/ProgressStepper/package.json +1 -1
- package/dist/dynamic/components/Radio/package.json +1 -1
- package/dist/dynamic/components/SearchInput/package.json +1 -1
- package/dist/dynamic/components/Select/package.json +1 -1
- package/dist/dynamic/components/Sidebar/package.json +1 -1
- package/dist/dynamic/components/SimpleList/package.json +1 -1
- package/dist/dynamic/components/Skeleton/package.json +1 -1
- package/dist/dynamic/components/SkipToContent/package.json +1 -1
- package/dist/dynamic/components/Slider/package.json +1 -1
- package/dist/dynamic/components/Spinner/package.json +1 -1
- package/dist/dynamic/components/Switch/package.json +1 -1
- package/dist/dynamic/components/Tabs/package.json +1 -1
- package/dist/dynamic/components/Text/package.json +1 -1
- package/dist/dynamic/components/TextArea/package.json +1 -1
- package/dist/dynamic/components/TextInput/package.json +1 -1
- package/dist/dynamic/components/TextInputGroup/package.json +1 -1
- package/dist/dynamic/components/Tile/package.json +1 -1
- package/dist/dynamic/components/TimePicker/package.json +1 -1
- package/dist/dynamic/components/Timestamp/package.json +1 -1
- package/dist/dynamic/components/Title/package.json +1 -1
- package/dist/dynamic/components/ToggleGroup/package.json +1 -1
- package/dist/dynamic/components/Toolbar/package.json +1 -1
- package/dist/dynamic/components/Tooltip/package.json +1 -1
- package/dist/dynamic/components/TreeView/package.json +1 -1
- package/dist/dynamic/components/Truncate/package.json +1 -1
- package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
- package/dist/dynamic/components/Wizard/package.json +1 -1
- package/dist/dynamic/deprecated/components/ApplicationLauncher/package.json +1 -1
- package/dist/dynamic/deprecated/components/ContextSelector/package.json +1 -1
- package/dist/dynamic/deprecated/components/Dropdown/package.json +1 -1
- package/dist/dynamic/deprecated/components/OptionsMenu/package.json +1 -1
- package/dist/dynamic/deprecated/components/PageHeader/package.json +1 -1
- package/dist/dynamic/deprecated/components/Select/package.json +1 -1
- package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
- package/dist/dynamic/deprecated/components/package.json +1 -1
- package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
- package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
- package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
- package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
- package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
- package/dist/dynamic/helpers/constants/package.json +1 -1
- package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
- package/dist/dynamic/helpers/favorites/package.json +1 -1
- package/dist/dynamic/helpers/fileUtils/package.json +1 -1
- package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
- package/dist/dynamic/helpers/package.json +1 -1
- package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
- package/dist/dynamic/helpers/typeUtils/package.json +1 -1
- package/dist/dynamic/helpers/useInterval/package.json +1 -1
- package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
- package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
- package/dist/dynamic/helpers/util/package.json +1 -1
- package/dist/dynamic/layouts/Bullseye/package.json +1 -1
- package/dist/dynamic/layouts/Flex/package.json +1 -1
- package/dist/dynamic/layouts/Gallery/package.json +1 -1
- package/dist/dynamic/layouts/Grid/package.json +1 -1
- package/dist/dynamic/layouts/Level/package.json +1 -1
- package/dist/dynamic/layouts/Split/package.json +1 -1
- package/dist/dynamic/layouts/Stack/package.json +1 -1
- package/dist/dynamic/next/components/Modal/package.json +1 -1
- package/dist/dynamic/next/components/package.json +1 -1
- package/dist/esm/components/Checkbox/Checkbox.d.ts +9 -3
- package/dist/esm/components/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/esm/components/Checkbox/Checkbox.js +16 -8
- package/dist/esm/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/esm/components/DragDrop/index.d.ts +1 -0
- package/dist/esm/components/DragDrop/index.d.ts.map +1 -1
- package/dist/esm/components/DragDrop/index.js +1 -0
- package/dist/esm/components/DragDrop/index.js.map +1 -1
- package/dist/esm/components/DualListSelector/index.d.ts +2 -0
- package/dist/esm/components/DualListSelector/index.d.ts.map +1 -1
- package/dist/esm/components/DualListSelector/index.js +2 -0
- package/dist/esm/components/DualListSelector/index.js.map +1 -1
- package/dist/esm/components/Radio/Radio.d.ts +7 -5
- package/dist/esm/components/Radio/Radio.d.ts.map +1 -1
- package/dist/esm/components/Radio/Radio.js +13 -20
- package/dist/esm/components/Radio/Radio.js.map +1 -1
- package/dist/esm/components/index.d.ts +1 -1
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/components/index.js +1 -1
- package/dist/esm/components/index.js.map +1 -1
- package/dist/js/components/Checkbox/Checkbox.d.ts +9 -3
- package/dist/js/components/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/js/components/Checkbox/Checkbox.js +16 -8
- package/dist/js/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/js/components/DragDrop/index.d.ts +1 -0
- package/dist/js/components/DragDrop/index.d.ts.map +1 -1
- package/dist/js/components/DragDrop/index.js +1 -0
- package/dist/js/components/DragDrop/index.js.map +1 -1
- package/dist/js/components/DualListSelector/index.d.ts +2 -0
- package/dist/js/components/DualListSelector/index.d.ts.map +1 -1
- package/dist/js/components/DualListSelector/index.js +2 -0
- package/dist/js/components/DualListSelector/index.js.map +1 -1
- package/dist/js/components/Radio/Radio.d.ts +7 -5
- package/dist/js/components/Radio/Radio.d.ts.map +1 -1
- package/dist/js/components/Radio/Radio.js +13 -20
- package/dist/js/components/Radio/Radio.js.map +1 -1
- package/dist/js/components/index.d.ts +1 -1
- package/dist/js/components/index.d.ts.map +1 -1
- package/dist/js/components/index.js +1 -1
- package/dist/js/components/index.js.map +1 -1
- package/dist/umd/react-core.min.js +1 -1
- package/helpers/package.json +1 -1
- package/layouts/package.json +1 -1
- package/next/package.json +1 -1
- package/package.json +2 -2
- package/src/components/Checkbox/Checkbox.tsx +63 -29
- package/src/components/Checkbox/__tests__/Checkbox.test.tsx +41 -0
- package/src/components/DataList/examples/DataList.md +2 -2
- package/src/components/DragDrop/examples/DragDrop.md +4 -2
- package/src/components/DragDrop/examples/DragDropBasic.tsx +4 -4
- package/src/components/DragDrop/examples/DragDropMultipleLists.tsx +7 -2
- package/src/components/DragDrop/index.ts +1 -0
- package/src/components/DualListSelector/examples/DualListSelector.md +3 -1
- package/src/components/DualListSelector/index.ts +2 -0
- package/src/components/Radio/Radio.tsx +39 -38
- package/src/components/Radio/__tests__/Radio.test.tsx +41 -0
- package/src/components/index.ts +1 -1
package/helpers/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@patternfly/react-core-helpers","main":"../dist/js/helpers/index.js","module":"../dist/esm/helpers/index.js","typings":"../dist/esm/helpers/index.d.ts","version":"5.2.0-prerelease.
|
|
1
|
+
{"name":"@patternfly/react-core-helpers","main":"../dist/js/helpers/index.js","module":"../dist/esm/helpers/index.js","typings":"../dist/esm/helpers/index.d.ts","version":"5.2.0-prerelease.42","private":true}
|
package/layouts/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@patternfly/react-core-layouts","main":"../dist/js/layouts/index.js","module":"../dist/esm/layouts/index.js","typings":"../dist/esm/layouts/index.d.ts","version":"5.2.0-prerelease.
|
|
1
|
+
{"name":"@patternfly/react-core-layouts","main":"../dist/js/layouts/index.js","module":"../dist/esm/layouts/index.js","typings":"../dist/esm/layouts/index.d.ts","version":"5.2.0-prerelease.42","private":true}
|
package/next/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@patternfly/react-core-next","main":"../dist/js/next/index.js","module":"../dist/esm/next/index.js","typings":"../dist/esm/next/index.d.ts","version":"5.2.0-prerelease.
|
|
1
|
+
{"name":"@patternfly/react-core-next","main":"../dist/js/next/index.js","module":"../dist/esm/next/index.js","typings":"../dist/esm/next/index.d.ts","version":"5.2.0-prerelease.42","private":true}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-core",
|
|
3
|
-
"version": "5.2.0-prerelease.
|
|
3
|
+
"version": "5.2.0-prerelease.43",
|
|
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",
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"react": "^17 || ^18",
|
|
72
72
|
"react-dom": "^17 || ^18"
|
|
73
73
|
},
|
|
74
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "1ae55d8591d99c3d006b0e79fd372efdd8b5b983"
|
|
75
75
|
}
|
|
@@ -8,10 +8,16 @@ import { ASTERISK } from '../../helpers/htmlConstants';
|
|
|
8
8
|
export interface CheckboxProps
|
|
9
9
|
extends Omit<React.HTMLProps<HTMLInputElement>, 'type' | 'onChange' | 'disabled' | 'label'>,
|
|
10
10
|
OUIAProps {
|
|
11
|
-
/** Additional classes added to the checkbox.
|
|
11
|
+
/** Additional classes added to the checkbox wrapper. This wrapper will be div element by default. It will be a label element if
|
|
12
|
+
* isLabelWrapped is true, or it can be overridden by any element specified in the component prop.
|
|
13
|
+
*/
|
|
12
14
|
className?: string;
|
|
13
|
-
/** Additional
|
|
15
|
+
/** Additional classes added to the checkbox input. */
|
|
14
16
|
inputClassName?: string;
|
|
17
|
+
/** Flag to indicate whether the checkbox wrapper element is a <label> element for the checkbox input. Will not apply if a component prop (with a value other than a "label") is specified. */
|
|
18
|
+
isLabelWrapped?: boolean;
|
|
19
|
+
/** Flag to show if the checkbox label is shown before the checkbox input. */
|
|
20
|
+
isLabelBeforeButton?: boolean;
|
|
15
21
|
/** Flag to show if the checkbox selection is valid or invalid. */
|
|
16
22
|
isValid?: boolean;
|
|
17
23
|
/** Flag to show if the checkbox is disabled. */
|
|
@@ -33,7 +39,7 @@ export interface CheckboxProps
|
|
|
33
39
|
description?: React.ReactNode;
|
|
34
40
|
/** Body text of the checkbox */
|
|
35
41
|
body?: React.ReactNode;
|
|
36
|
-
/** Sets the
|
|
42
|
+
/** Sets the checkbox wrapper component to render. Defaults to "div". If set to "label", behaves the same as if isLabelWrapped prop was specified. */
|
|
37
43
|
component?: React.ElementType;
|
|
38
44
|
/** Value to overwrite the randomly generated data-ouia-component-id.*/
|
|
39
45
|
ouiaId?: number | string;
|
|
@@ -52,13 +58,13 @@ class Checkbox extends React.Component<CheckboxProps, CheckboxState> {
|
|
|
52
58
|
static displayName = 'Checkbox';
|
|
53
59
|
static defaultProps: PickOptional<CheckboxProps> = {
|
|
54
60
|
className: '',
|
|
61
|
+
isLabelWrapped: false,
|
|
55
62
|
isValid: true,
|
|
56
63
|
isDisabled: false,
|
|
57
64
|
isRequired: false,
|
|
58
65
|
isChecked: false,
|
|
59
66
|
onChange: defaultOnChange,
|
|
60
|
-
ouiaSafe: true
|
|
61
|
-
component: 'div'
|
|
67
|
+
ouiaSafe: true
|
|
62
68
|
};
|
|
63
69
|
|
|
64
70
|
constructor(props: any) {
|
|
@@ -78,6 +84,8 @@ class Checkbox extends React.Component<CheckboxProps, CheckboxState> {
|
|
|
78
84
|
className,
|
|
79
85
|
inputClassName,
|
|
80
86
|
onChange,
|
|
87
|
+
isLabelWrapped,
|
|
88
|
+
isLabelBeforeButton,
|
|
81
89
|
isValid,
|
|
82
90
|
isDisabled,
|
|
83
91
|
isRequired,
|
|
@@ -89,7 +97,7 @@ class Checkbox extends React.Component<CheckboxProps, CheckboxState> {
|
|
|
89
97
|
body,
|
|
90
98
|
ouiaId,
|
|
91
99
|
ouiaSafe,
|
|
92
|
-
component
|
|
100
|
+
component,
|
|
93
101
|
...props
|
|
94
102
|
} = this.props;
|
|
95
103
|
if (!props.id) {
|
|
@@ -107,31 +115,57 @@ class Checkbox extends React.Component<CheckboxProps, CheckboxState> {
|
|
|
107
115
|
checkedProps.defaultChecked = defaultChecked;
|
|
108
116
|
}
|
|
109
117
|
|
|
118
|
+
const inputRendered = (
|
|
119
|
+
<input
|
|
120
|
+
{...props}
|
|
121
|
+
className={css(styles.checkInput, inputClassName)}
|
|
122
|
+
type="checkbox"
|
|
123
|
+
onChange={this.handleChange}
|
|
124
|
+
aria-invalid={!isValid}
|
|
125
|
+
aria-label={ariaLabel}
|
|
126
|
+
disabled={isDisabled}
|
|
127
|
+
required={isRequired}
|
|
128
|
+
ref={(elem) => elem && (elem.indeterminate = isChecked === null)}
|
|
129
|
+
{...checkedProps}
|
|
130
|
+
{...getOUIAProps(Checkbox.displayName, ouiaId !== undefined ? ouiaId : this.state.ouiaStateId, ouiaSafe)}
|
|
131
|
+
/>
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const wrapWithLabel = (isLabelWrapped && !component) || component === 'label';
|
|
135
|
+
|
|
136
|
+
const Label = wrapWithLabel ? 'span' : 'label';
|
|
137
|
+
const labelRendered = label ? (
|
|
138
|
+
<Label
|
|
139
|
+
className={css(styles.checkLabel, isDisabled && styles.modifiers.disabled)}
|
|
140
|
+
htmlFor={!wrapWithLabel && props.id}
|
|
141
|
+
>
|
|
142
|
+
{label}
|
|
143
|
+
{isRequired && (
|
|
144
|
+
<span className={css(styles.checkLabelRequired)} aria-hidden="true">
|
|
145
|
+
{ASTERISK}
|
|
146
|
+
</span>
|
|
147
|
+
)}
|
|
148
|
+
</Label>
|
|
149
|
+
) : null;
|
|
150
|
+
|
|
151
|
+
const Component = component ?? (wrapWithLabel ? 'label' : 'div');
|
|
152
|
+
|
|
110
153
|
checkedProps.checked = checkedProps.checked === null ? false : checkedProps.checked;
|
|
111
154
|
return (
|
|
112
|
-
<Component
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
{label && (
|
|
127
|
-
<label className={css(styles.checkLabel, isDisabled && styles.modifiers.disabled)} htmlFor={props.id}>
|
|
128
|
-
{label}
|
|
129
|
-
{isRequired && (
|
|
130
|
-
<span className={css(styles.checkLabelRequired)} aria-hidden="true">
|
|
131
|
-
{ASTERISK}
|
|
132
|
-
</span>
|
|
133
|
-
)}
|
|
134
|
-
</label>
|
|
155
|
+
<Component
|
|
156
|
+
className={css(styles.check, !label && styles.modifiers.standalone, className)}
|
|
157
|
+
htmlFor={wrapWithLabel && props.id}
|
|
158
|
+
>
|
|
159
|
+
{isLabelBeforeButton ? (
|
|
160
|
+
<>
|
|
161
|
+
{labelRendered}
|
|
162
|
+
{inputRendered}
|
|
163
|
+
</>
|
|
164
|
+
) : (
|
|
165
|
+
<>
|
|
166
|
+
{inputRendered}
|
|
167
|
+
{labelRendered}
|
|
168
|
+
</>
|
|
135
169
|
)}
|
|
136
170
|
{description && <span className={css(styles.checkDescription)}>{description}</span>}
|
|
137
171
|
{body && <span className={css(styles.checkBody)}>{body}</span>}
|
|
@@ -231,6 +231,47 @@ test('Renders with the provided component', () => {
|
|
|
231
231
|
expect(screen.getByRole('checkbox').parentElement?.tagName).toBe('SPAN');
|
|
232
232
|
});
|
|
233
233
|
|
|
234
|
+
test('Renders with the label wrapper if isLabelWrapped is provided', () => {
|
|
235
|
+
render(<Checkbox id="test-id" isLabelWrapped />);
|
|
236
|
+
|
|
237
|
+
expect(screen.getByRole('checkbox').parentElement?.tagName).toBe('LABEL');
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test('Renders with span element around the inner label text if isLabelWrapped is provided', () => {
|
|
241
|
+
const labelText = 'test checkbox label';
|
|
242
|
+
render(<Checkbox id="test-id" isLabelWrapped label={labelText} />);
|
|
243
|
+
|
|
244
|
+
expect(screen.getByText(labelText).tagName).toBe('SPAN');
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
test('Renders with the provided component although isLabelWrapped is provided', () => {
|
|
248
|
+
render(<Checkbox id="test-id" isLabelWrapped component="h3" />);
|
|
249
|
+
|
|
250
|
+
expect(screen.getByRole('checkbox').parentElement?.tagName).toBe('H3');
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test('Renders with the label wrapper if component is set to label', () => {
|
|
254
|
+
render(<Checkbox id="test-id" component="label" />);
|
|
255
|
+
|
|
256
|
+
expect(screen.getByRole('checkbox').parentElement?.tagName).toBe('LABEL');
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test('Renders with span element around the inner label text if component is set to label', () => {
|
|
260
|
+
const labelText = 'test checkbox label';
|
|
261
|
+
render(<Checkbox id="test-id" component="label" label={labelText} />);
|
|
262
|
+
|
|
263
|
+
expect(screen.getByText(labelText).tagName).toBe('SPAN');
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
test('Renders label before checkbox input if isLabelBeforeButton is provided', () => {
|
|
267
|
+
render(<Checkbox id="test-id" isLabelBeforeButton label={'test checkbox label'} />);
|
|
268
|
+
|
|
269
|
+
const wrapper = screen.getByRole('checkbox').parentElement!;
|
|
270
|
+
|
|
271
|
+
expect(wrapper.children[0].tagName).toBe('LABEL');
|
|
272
|
+
expect(wrapper.children[1].tagName).toBe('INPUT');
|
|
273
|
+
});
|
|
274
|
+
|
|
234
275
|
test(`Spreads additional props`, () => {
|
|
235
276
|
render(<Checkbox id="test-id" data-testid="test-id" />);
|
|
236
277
|
|
|
@@ -86,9 +86,9 @@ import global_BorderWidth_sm from '@patternfly/react-tokens/dist/esm/global_Bord
|
|
|
86
86
|
|
|
87
87
|
### Draggable
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
Note: There is a new recommended drag and drop implementation with full keyboard functionality, which replaces this implementation. To adhere to our new recommendations, refer to the [drag and drop demos](/components/drag-and-drop/react-next-demos).
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
Previously, draggable data lists had their own API for the [drag and drop component](/components/drag-and-drop), which wasn't flexible enough to allow custom styling for items as they are dragged. To address this disparity, `<DragDrop>`, `<Draggable>`, and `<Droppable>` components were added to replace our now deprecated HTML5-based API. Keyboard and screen reader accessibility for the `<DragDrop>` component is still in development.
|
|
92
92
|
|
|
93
93
|
```ts isBeta file="./DataListDraggable.tsx"
|
|
94
94
|
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
id: Drag and drop
|
|
3
3
|
section: components
|
|
4
4
|
propComponents: [DragDrop, Draggable, Droppable, DraggableItemPosition]
|
|
5
|
-
|
|
5
|
+
title: Drag and drop
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You can use the
|
|
8
|
+
You can use the `<DragDrop>` component to move items in or between lists. The `<DragDrop>` component should contain `<Droppable>` components which contain `<Draggable>` components.
|
|
9
9
|
|
|
10
10
|
```ts noLive
|
|
11
11
|
import React from 'react';
|
|
@@ -35,9 +35,11 @@ Note: Keyboard accessibility and screen reader accessibility are still in develo
|
|
|
35
35
|
### Basic
|
|
36
36
|
|
|
37
37
|
```ts file="./DragDropBasic.tsx"
|
|
38
|
+
|
|
38
39
|
```
|
|
39
40
|
|
|
40
41
|
### Multiple lists
|
|
41
42
|
|
|
42
43
|
```ts file="./DragDropMultipleLists.tsx"
|
|
44
|
+
|
|
43
45
|
```
|
|
@@ -20,14 +20,14 @@ const getItems = (count: number) =>
|
|
|
20
20
|
}));
|
|
21
21
|
|
|
22
22
|
const reorder = (list: ItemType[], startIndex: number, endIndex: number) => {
|
|
23
|
-
const result = list;
|
|
23
|
+
const result = [...list];
|
|
24
24
|
const [removed] = result.splice(startIndex, 1);
|
|
25
25
|
result.splice(endIndex, 0, removed);
|
|
26
26
|
return result;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
export const DragDropBasic: React.FunctionComponent = () => {
|
|
30
|
-
const [items, setItems] = React.useState(getItems(10));
|
|
30
|
+
const [items, setItems] = React.useState<ItemType[]>(getItems(10));
|
|
31
31
|
|
|
32
32
|
function onDrop(source: SourceType, dest: DestinationType) {
|
|
33
33
|
if (dest) {
|
|
@@ -42,8 +42,8 @@ export const DragDropBasic: React.FunctionComponent = () => {
|
|
|
42
42
|
return (
|
|
43
43
|
<DragDrop onDrop={onDrop}>
|
|
44
44
|
<Droppable>
|
|
45
|
-
{items.map(({ content }
|
|
46
|
-
<Draggable key={
|
|
45
|
+
{items.map(({ id, content }) => (
|
|
46
|
+
<Draggable key={id} style={{ padding: '8px' }}>
|
|
47
47
|
{content}
|
|
48
48
|
</Draggable>
|
|
49
49
|
))}
|
|
@@ -11,6 +11,11 @@ interface SourceType {
|
|
|
11
11
|
index: number;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
interface MultipleListState {
|
|
15
|
+
items1: ItemType[];
|
|
16
|
+
items2: ItemType[];
|
|
17
|
+
}
|
|
18
|
+
|
|
14
19
|
interface DestinationType extends SourceType {}
|
|
15
20
|
|
|
16
21
|
const getItems = (count: number, startIndex: number) =>
|
|
@@ -35,7 +40,7 @@ const move = (source: ItemType[], destination: ItemType[], sourceIndex: number,
|
|
|
35
40
|
};
|
|
36
41
|
|
|
37
42
|
export const DragDropMultipleLists: React.FunctionComponent = () => {
|
|
38
|
-
const [items, setItems] = React.useState({
|
|
43
|
+
const [items, setItems] = React.useState<MultipleListState>({
|
|
39
44
|
items1: getItems(10, 0),
|
|
40
45
|
items2: getItems(5, 10)
|
|
41
46
|
});
|
|
@@ -84,7 +89,7 @@ export const DragDropMultipleLists: React.FunctionComponent = () => {
|
|
|
84
89
|
{Object.entries(items).map(([key, subitems]) => (
|
|
85
90
|
<SplitItem key={key} style={{ flex: 1 }}>
|
|
86
91
|
<Droppable zone="multizone" droppableId={key}>
|
|
87
|
-
{subitems.map(({ id, content }) => (
|
|
92
|
+
{(subitems as ItemType[]).map(({ id, content }) => (
|
|
88
93
|
<Draggable key={id} style={{ padding: '8px' }}>
|
|
89
94
|
{content}
|
|
90
95
|
</Draggable>
|
|
@@ -87,6 +87,8 @@ The dual list selector can also be built in a composable manner to make customiz
|
|
|
87
87
|
|
|
88
88
|
### Composable with drag and drop
|
|
89
89
|
|
|
90
|
+
Note: There is a new recommended drag and drop implementation with full keyboard functionality, which replaces this implementation. To adhere to our new recommendations, refer to the [drag and drop demos](/components/drag-and-drop/react-next-demos).
|
|
91
|
+
|
|
90
92
|
This example only allows reordering the contents of the "chosen" pane with drag and drop. To make a pane able to be reordered:
|
|
91
93
|
|
|
92
94
|
- wrap the `DualListSelectorPane` in a `DragDrop` component
|
|
@@ -99,7 +101,7 @@ This example only allows reordering the contents of the "chosen" pane with drag
|
|
|
99
101
|
- define an `onDrag` callback which ensures that the drag event will not cross hairs with the `onOptionSelect` click
|
|
100
102
|
event set on the option. Note: the `ignoreNextOptionSelect` state value is used to prevent selection while dragging.
|
|
101
103
|
|
|
102
|
-
|
|
104
|
+
Keyboard and screen reader accessibility for the `<DragDrop>` component is still in development.
|
|
103
105
|
|
|
104
106
|
```ts file="DualListSelectorComposableDragDrop.tsx"
|
|
105
107
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from './DualListSelector';
|
|
2
|
+
export * from './DualListSelectorContext';
|
|
2
3
|
export * from './DualListSelectorControl';
|
|
3
4
|
export * from './DualListSelectorControlsWrapper';
|
|
4
5
|
export * from './DualListSelectorPane';
|
|
5
6
|
export * from './DualListSelectorList';
|
|
6
7
|
export * from './DualListSelectorListItem';
|
|
7
8
|
export * from './DualListSelectorTree';
|
|
9
|
+
export * from './DualListSelectorContext';
|
|
@@ -7,17 +7,17 @@ import { getOUIAProps, OUIAProps, getDefaultOUIAId } from '../../helpers';
|
|
|
7
7
|
export interface RadioProps
|
|
8
8
|
extends Omit<React.HTMLProps<HTMLInputElement>, 'disabled' | 'label' | 'onChange' | 'type'>,
|
|
9
9
|
OUIAProps {
|
|
10
|
-
/** Additional classes added to the radio wrapper.
|
|
11
|
-
* isLabelWrapped is true,
|
|
10
|
+
/** Additional classes added to the radio wrapper. This wrapper will be div element by default. It will be a label element if
|
|
11
|
+
* isLabelWrapped is true, or it can be overridden by any element specified in the component prop.
|
|
12
12
|
*/
|
|
13
13
|
className?: string;
|
|
14
|
-
/** Additional
|
|
14
|
+
/** Additional classes added to the radio input. */
|
|
15
15
|
inputClassName?: string;
|
|
16
16
|
/** Id of the radio. */
|
|
17
17
|
id: string;
|
|
18
|
-
/** Flag to
|
|
18
|
+
/** Flag to indicate whether the radio wrapper element is a native label element for the radio input. Will not apply if a component prop (with a value other than a "label") is specified. */
|
|
19
19
|
isLabelWrapped?: boolean;
|
|
20
|
-
/** Flag to show if the radio label is shown before the radio
|
|
20
|
+
/** Flag to show if the radio label is shown before the radio input. */
|
|
21
21
|
isLabelBeforeButton?: boolean;
|
|
22
22
|
/** Flag to show if the radio is checked. */
|
|
23
23
|
checked?: boolean;
|
|
@@ -39,6 +39,8 @@ export interface RadioProps
|
|
|
39
39
|
description?: React.ReactNode;
|
|
40
40
|
/** Body of the radio. */
|
|
41
41
|
body?: React.ReactNode;
|
|
42
|
+
/** Sets the radio wrapper component to render. Defaults to "div". If set to "label", behaves the same as if isLabelWrapped prop was specified. */
|
|
43
|
+
component?: React.ElementType;
|
|
42
44
|
/** Value to overwrite the randomly generated data-ouia-component-id.*/
|
|
43
45
|
ouiaId?: number | string;
|
|
44
46
|
/** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */
|
|
@@ -88,6 +90,7 @@ class Radio extends React.Component<RadioProps, { ouiaStateId: string }> {
|
|
|
88
90
|
body,
|
|
89
91
|
ouiaId,
|
|
90
92
|
ouiaSafe = true,
|
|
93
|
+
component,
|
|
91
94
|
...props
|
|
92
95
|
} = this.props;
|
|
93
96
|
if (!props.id) {
|
|
@@ -110,41 +113,39 @@ class Radio extends React.Component<RadioProps, { ouiaStateId: string }> {
|
|
|
110
113
|
/>
|
|
111
114
|
);
|
|
112
115
|
|
|
113
|
-
|
|
114
|
-
if (label && isLabelWrapped) {
|
|
115
|
-
labelRendered = <span className={css(styles.radioLabel, isDisabled && styles.modifiers.disabled)}>{label}</span>;
|
|
116
|
-
} else if (label) {
|
|
117
|
-
labelRendered = (
|
|
118
|
-
<label className={css(styles.radioLabel, isDisabled && styles.modifiers.disabled)} htmlFor={props.id}>
|
|
119
|
-
{label}
|
|
120
|
-
</label>
|
|
121
|
-
);
|
|
122
|
-
}
|
|
116
|
+
const wrapWithLabel = (isLabelWrapped && !component) || component === 'label';
|
|
123
117
|
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
{
|
|
129
|
-
|
|
130
|
-
{
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
{inputRendered}
|
|
136
|
-
{labelRendered}
|
|
137
|
-
{descRender}
|
|
138
|
-
{bodyRender}
|
|
139
|
-
</>
|
|
140
|
-
);
|
|
118
|
+
const Label = wrapWithLabel ? 'span' : 'label';
|
|
119
|
+
const labelRendered = label ? (
|
|
120
|
+
<Label
|
|
121
|
+
className={css(styles.radioLabel, isDisabled && styles.modifiers.disabled)}
|
|
122
|
+
htmlFor={!wrapWithLabel && props.id}
|
|
123
|
+
>
|
|
124
|
+
{label}
|
|
125
|
+
</Label>
|
|
126
|
+
) : null;
|
|
127
|
+
|
|
128
|
+
const Component = component ?? (wrapWithLabel ? 'label' : 'div');
|
|
141
129
|
|
|
142
|
-
return
|
|
143
|
-
<
|
|
144
|
-
{
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
130
|
+
return (
|
|
131
|
+
<Component
|
|
132
|
+
className={css(styles.radio, !label && styles.modifiers.standalone, className)}
|
|
133
|
+
htmlFor={wrapWithLabel && props.id}
|
|
134
|
+
>
|
|
135
|
+
{isLabelBeforeButton ? (
|
|
136
|
+
<>
|
|
137
|
+
{labelRendered}
|
|
138
|
+
{inputRendered}
|
|
139
|
+
</>
|
|
140
|
+
) : (
|
|
141
|
+
<>
|
|
142
|
+
{inputRendered}
|
|
143
|
+
{labelRendered}
|
|
144
|
+
</>
|
|
145
|
+
)}
|
|
146
|
+
{description && <span className={css(styles.radioDescription)}>{description}</span>}
|
|
147
|
+
{body && <span className={css(styles.radioBody)}>{body}</span>}
|
|
148
|
+
</Component>
|
|
148
149
|
);
|
|
149
150
|
}
|
|
150
151
|
}
|
|
@@ -100,4 +100,45 @@ describe('Radio', () => {
|
|
|
100
100
|
|
|
101
101
|
expect(myMock).toHaveBeenCalled();
|
|
102
102
|
});
|
|
103
|
+
|
|
104
|
+
test('Renders with the label wrapper if isLabelWrapped is provided', () => {
|
|
105
|
+
render(<Radio id="test-id" name="check" isLabelWrapped />);
|
|
106
|
+
|
|
107
|
+
expect(screen.getByRole('radio').parentElement?.tagName).toBe('LABEL');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test('Renders with span element around the inner label text if isLabelWrapped is provided', () => {
|
|
111
|
+
const labelText = 'test radio label';
|
|
112
|
+
render(<Radio id="test-id" name="check" isLabelWrapped label={labelText} />);
|
|
113
|
+
|
|
114
|
+
expect(screen.getByText(labelText).tagName).toBe('SPAN');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('Renders with the provided component although isLabelWrapped is provided', () => {
|
|
118
|
+
render(<Radio id="test-id" name="check" isLabelWrapped component="h3" />);
|
|
119
|
+
|
|
120
|
+
expect(screen.getByRole('radio').parentElement?.tagName).toBe('H3');
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('Renders with the label wrapper if component is set to label', () => {
|
|
124
|
+
render(<Radio id="test-id" name="check" component="label" />);
|
|
125
|
+
|
|
126
|
+
expect(screen.getByRole('radio').parentElement?.tagName).toBe('LABEL');
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('Renders with span element around the inner label text if component is set to label', () => {
|
|
130
|
+
const labelText = 'test radio label';
|
|
131
|
+
render(<Radio id="test-id" name="check" component="label" label={labelText} />);
|
|
132
|
+
|
|
133
|
+
expect(screen.getByText(labelText).tagName).toBe('SPAN');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test('Renders label before radio input if isLabelBeforeButton is provided', () => {
|
|
137
|
+
render(<Radio id="test-id" name="check" isLabelBeforeButton label={'test radio label'} />);
|
|
138
|
+
|
|
139
|
+
const wrapper = screen.getByRole('radio').parentElement!;
|
|
140
|
+
|
|
141
|
+
expect(wrapper.children[0].tagName).toBe('LABEL');
|
|
142
|
+
expect(wrapper.children[1].tagName).toBe('INPUT');
|
|
143
|
+
});
|
|
103
144
|
});
|
package/src/components/index.ts
CHANGED
|
@@ -22,6 +22,7 @@ export * from './DataList';
|
|
|
22
22
|
export * from './DatePicker';
|
|
23
23
|
export * from './DescriptionList';
|
|
24
24
|
export * from './Divider';
|
|
25
|
+
export * from './DragDrop';
|
|
25
26
|
export * from './Drawer';
|
|
26
27
|
export * from './Dropdown';
|
|
27
28
|
export * from './DualListSelector';
|
|
@@ -76,7 +77,6 @@ export * from './Tooltip';
|
|
|
76
77
|
export * from './NumberInput';
|
|
77
78
|
export * from './TreeView';
|
|
78
79
|
export * from './Wizard';
|
|
79
|
-
export * from './DragDrop';
|
|
80
80
|
export * from './TextInputGroup';
|
|
81
81
|
export * from './Panel';
|
|
82
82
|
export * from './Truncate';
|