@patternfly/react-core 4.267.13 → 4.268.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "4.267.13",
3
+ "version": "4.268.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",
@@ -71,5 +71,5 @@
71
71
  "react": "^16.8 || ^17 || ^18",
72
72
  "react-dom": "^16.8 || ^17 || ^18"
73
73
  },
74
- "gitHead": "122f28feeb8a8130c8beb9e2504ba34e48b911b1"
74
+ "gitHead": "4464f97977ce3984b4e589711f26993f1f64a23f"
75
75
  }
@@ -3,6 +3,7 @@ import styles from '@patternfly/react-styles/css/components/Dropdown/dropdown';
3
3
  import { css } from '@patternfly/react-styles';
4
4
  import { PickOptional } from '../../helpers/typeUtils';
5
5
  import { getOUIAProps, OUIAProps, getDefaultOUIAId } from '../../helpers';
6
+ import { Spinner } from '../Spinner';
6
7
 
7
8
  export interface DropdownToggleCheckboxProps
8
9
  extends Omit<React.HTMLProps<HTMLInputElement>, 'type' | 'onChange' | 'disabled' | 'checked'>,
@@ -15,6 +16,8 @@ export interface DropdownToggleCheckboxProps
15
16
  isDisabled?: boolean;
16
17
  /** Flag to show if the checkbox is checked */
17
18
  isChecked?: boolean | null;
19
+ /** @beta Flag to show if the checkbox is in progress */
20
+ isInProgress?: boolean | null;
18
21
  /** Alternate Flag to show if the checkbox is checked */
19
22
  checked?: boolean | null;
20
23
  /** A callback for when the checkbox selection changes */
@@ -25,6 +28,10 @@ export interface DropdownToggleCheckboxProps
25
28
  id: string;
26
29
  /** Aria-label of the checkbox */
27
30
  'aria-label': string;
31
+ /** @beta Text describing current loading status or progress */
32
+ defaultProgressAriaValueText?: string;
33
+ /** @beta Aria-label for the default progress icon to describe what is loading */
34
+ defaultProgressAriaLabel?: string;
28
35
  /** Value to overwrite the randomly generated data-ouia-component-id.*/
29
36
  ouiaId?: number | string;
30
37
  /** 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. */
@@ -68,6 +75,9 @@ export class DropdownToggleCheckbox extends React.Component<DropdownToggleCheckb
68
75
  isValid,
69
76
  isDisabled,
70
77
  isChecked,
78
+ isInProgress = false,
79
+ defaultProgressAriaLabel,
80
+ defaultProgressAriaValueText = 'Loading...',
71
81
  children,
72
82
  ouiaId,
73
83
  ouiaSafe,
@@ -77,13 +87,27 @@ export class DropdownToggleCheckbox extends React.Component<DropdownToggleCheckb
77
87
  /* eslint-enable @typescript-eslint/no-unused-vars */
78
88
  ...props
79
89
  } = this.props;
90
+
91
+ const spinner = (
92
+ <Spinner
93
+ diameter="1em"
94
+ isSVG
95
+ aria-valuetext={defaultProgressAriaValueText}
96
+ aria-live="polite"
97
+ aria-label={defaultProgressAriaLabel}
98
+ />
99
+ );
100
+
80
101
  const text = children && (
81
102
  <span className={css(styles.dropdownToggleText, className)} aria-hidden="true" id={`${props.id}-text`}>
82
103
  {children}
83
104
  </span>
84
105
  );
85
106
  return (
86
- <label className={css(styles.dropdownToggleCheck, className)} htmlFor={props.id}>
107
+ <label
108
+ className={css(styles.dropdownToggleCheck, isInProgress && styles.modifiers.inProgress, className)}
109
+ htmlFor={props.id}
110
+ >
87
111
  <input
88
112
  {...props}
89
113
  {...(this.calculateChecked() !== undefined && { onChange: this.handleChange })}
@@ -98,6 +122,7 @@ export class DropdownToggleCheckbox extends React.Component<DropdownToggleCheckb
98
122
  ouiaSafe
99
123
  )}
100
124
  />
125
+ {isInProgress && <span className={css(styles.dropdownToggleProgress, className)}>{spinner}</span>}
101
126
  {text}
102
127
  </label>
103
128
  );
@@ -116,7 +116,7 @@ You may use a `<BadgeToggle>` to display the number of dropdown menu items.
116
116
  ```ts file="./DropdownBadge.tsx"
117
117
  ```
118
118
 
119
- ### Split button
119
+ ### Split button (checkbox)
120
120
 
121
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`.
122
122
 
@@ -125,13 +125,20 @@ The following example shows a split button with a `<DropdownToggleCheckbox>`, wh
125
125
  ```ts file="./DropdownSplitButton.tsx"
126
126
  ```
127
127
 
128
- ### Split button text label
128
+ ### Split button (checkbox with toggle text)
129
129
 
130
130
  Text labels may optionally be used alongside actions within split buttons.
131
131
 
132
132
  ```ts file="./DropdownSplitButtonText.tsx"
133
133
  ```
134
134
 
135
+ ### Split button (progress checkbox)
136
+
137
+ The `isInProgress` property can be used to indicate a progress state by rendering a spinner in place of a checkbox.
138
+
139
+ ```ts isBeta file="./DropdownSplitButtonProgressCheckbox.tsx"
140
+ ```
141
+
135
142
  ### Split button toggle variants
136
143
 
137
144
  Use the `toggleVariant` and `splitButtonVariant` properties to adjust the styling of split button toggles.
@@ -54,7 +54,7 @@ export const DropdownSplitButton: React.FunctionComponent = () => {
54
54
  toggle={
55
55
  <DropdownToggle
56
56
  splitButtonItems={[
57
- <DropdownToggleCheckbox id="split-button-checkbox" key="split-checkbox" aria-label="Select all" />
57
+ <DropdownToggleCheckbox id="split-button-toggle-checkbox" key="split-checkbox" aria-label="Select all" />
58
58
  ]}
59
59
  onToggle={onToggle}
60
60
  id="toggle-split-button"
@@ -0,0 +1,140 @@
1
+ import React from 'react';
2
+ import {
3
+ Dropdown,
4
+ DropdownToggle,
5
+ DropdownToggleCheckbox,
6
+ DropdownItem,
7
+ DropdownSeparator
8
+ } from '@patternfly/react-core';
9
+
10
+ export const DropdownSplitButtonProgressCheckbox: React.FunctionComponent = () => {
11
+ const [isOpen1, setIsOpen1] = React.useState(false);
12
+ const [isOpen2, setIsOpen2] = React.useState(false);
13
+
14
+ const [isChecked1, setIsChecked1] = React.useState(false);
15
+ const [isChecked2, setIsChecked2] = React.useState(false);
16
+
17
+ const [isTimedOut1, setIsTimedOut1] = React.useState(true);
18
+ const [isTimedOut2, setIsTimedOut2] = React.useState(true);
19
+
20
+ const onToggle1 = (isOpen: boolean) => {
21
+ setIsOpen1(isOpen);
22
+ };
23
+
24
+ const onToggle2 = (isOpen: boolean) => {
25
+ setIsOpen2(isOpen);
26
+ };
27
+
28
+ const showProgressIcon1 = () => {
29
+ setIsTimedOut1(false);
30
+ setTimeout(() => setIsTimedOut1(true), 3000);
31
+ };
32
+
33
+ const showProgressIcon2 = () => {
34
+ setIsTimedOut2(false);
35
+ setTimeout(() => setIsTimedOut2(true), 3000);
36
+ };
37
+
38
+ const onFocus1 = () => {
39
+ const element = document.getElementById('toggle-split-button-progress');
40
+ element.focus();
41
+ };
42
+
43
+ const onFocus2 = () => {
44
+ const element = document.getElementById('toggle-split-button-progress-text');
45
+ element.focus();
46
+ };
47
+
48
+ const onChange1 = (checked: boolean) => {
49
+ setIsChecked1(checked);
50
+ showProgressIcon1();
51
+ };
52
+
53
+ const onChange2 = (checked: boolean) => {
54
+ setIsChecked2(checked);
55
+ showProgressIcon2();
56
+ };
57
+
58
+ const onSelect1 = () => {
59
+ setIsOpen1(false);
60
+ onFocus1();
61
+ };
62
+
63
+ const onSelect2 = () => {
64
+ setIsOpen2(false);
65
+ onFocus2();
66
+ };
67
+
68
+ const dropdownItems = [
69
+ <DropdownItem key="link">Link</DropdownItem>,
70
+ <DropdownItem key="action" component="button">
71
+ Action
72
+ </DropdownItem>,
73
+ <DropdownItem key="disabled link" isDisabled href="www.google.com">
74
+ Disabled link
75
+ </DropdownItem>,
76
+ <DropdownItem
77
+ key="disabled action"
78
+ isAriaDisabled
79
+ component="button"
80
+ tooltip="Tooltip for disabled item"
81
+ tooltipProps={{ position: 'top' }}
82
+ >
83
+ Disabled action
84
+ </DropdownItem>,
85
+ <DropdownSeparator key="separator" />,
86
+ <DropdownItem key="separated link">Separated link</DropdownItem>,
87
+ <DropdownItem key="separated action" component="button">
88
+ Separated action
89
+ </DropdownItem>
90
+ ];
91
+
92
+ return (
93
+ <>
94
+ <Dropdown
95
+ onSelect={onSelect1}
96
+ toggle={
97
+ <DropdownToggle
98
+ splitButtonItems={[
99
+ <DropdownToggleCheckbox
100
+ onChange={onChange1}
101
+ isChecked={isChecked1}
102
+ isInProgress={!isTimedOut1}
103
+ id="split-button-progress-toggle-checkbox"
104
+ key="split-progress-checkbox"
105
+ aria-label="Select all"
106
+ />
107
+ ]}
108
+ onToggle={onToggle1}
109
+ id="toggle-split-button-progress"
110
+ />
111
+ }
112
+ isOpen={isOpen1}
113
+ dropdownItems={dropdownItems}
114
+ />{' '}
115
+ <Dropdown
116
+ onSelect={onSelect2}
117
+ toggle={
118
+ <DropdownToggle
119
+ splitButtonItems={[
120
+ <DropdownToggleCheckbox
121
+ onChange={onChange2}
122
+ isChecked={isChecked2}
123
+ isInProgress={!isTimedOut2}
124
+ id="split-button-progress-text-checkbox"
125
+ key="split-progress-checkbox"
126
+ aria-label="Select all"
127
+ >
128
+ 10 selected
129
+ </DropdownToggleCheckbox>
130
+ ]}
131
+ onToggle={onToggle2}
132
+ id="toggle-split-button-progress-text"
133
+ />
134
+ }
135
+ isOpen={isOpen2}
136
+ dropdownItems={dropdownItems}
137
+ />
138
+ </>
139
+ );
140
+ };
@@ -23,49 +23,99 @@ import './page.css';
23
23
 
24
24
  ## Examples
25
25
 
26
- ### Vertical nav
26
+ ### Basic page components
27
+
28
+ A page will typically contain the following components:
29
+
30
+ - A `<Page>` with a `header` that often contains a [masthead](/components/masthead)
31
+ - Mastheads contain the `<PageToggleButton>`, a `<MastheadMain>` that contains a `<MastheadBrand>`, and the page's header toolbar within `<MastheadContent>`.
32
+ - A `<PageSidebar>` for vertical navigation
33
+ - 1 or more `<PageSection>` components
34
+
35
+ ### Vertical navigation
36
+
37
+ To add a vertical sidebar to a `<Page>`, pass a `<PageSidebar>` component into the `sidebar` property. To render navigation in the sidebar, use the `nav` property of the `<PageSidebar>`.
38
+
39
+ The `isNavOpen` property helps facilitate the opening and closing of the sidebar and should be 'true' when the navigation sidebar is visible.
27
40
 
28
41
  ```ts file="./PageVerticalNav.tsx"
29
42
  ```
30
43
 
31
- ### Horizontal nav
44
+ ### Legacy page header
45
+
46
+ This example shows the legacy implementation of a page's vertical navigation. Our updated recommendation advises you to use a masthead and toolbar to make headers, rather than `<PageHeader>` and `<PageHeaderTools>` as shown in the following example.
47
+
48
+ ```ts file="./PageVerticalNavUsingPageHeaderComponent.tsx"
49
+ ```
50
+
51
+ ### Horizontal navigation
52
+
53
+ To add horizontal navigation to the top of a `<Page>`, add the navigation inside of a `<ToolbarItem>` in the `<Toolbar>` that is passed to the `<MastheadContent>` of the `<Masthead>`.
32
54
 
33
55
  ```ts file="./PageHorizontalNav.tsx"
34
56
  ```
35
57
 
36
- ### Tertiary nav
58
+ ### Legacy tertiary navigation
59
+
60
+ [Horizontal sub-navigation](/components/navigation#horizontal-subnav) is now recommended instead of tertiary-level navigation.
61
+
62
+ Tertiary navigation allows you to add an additional navigation menu alongside vertical or horizontal navigation. To create tertiary navigation, use the `tertiaryNav` property. The following example passes `tertiaryNav="Navigation"` into a `<Page>` component.
37
63
 
38
64
  ```ts file="./PageTertiaryNav.tsx"
39
65
  ```
40
66
 
41
- ### With or without fill
67
+ ### Uncontrolled navigation
68
+
69
+ When the `isManagedSidebar` property is true, it manages the sidebar open/close state, removing the need to pass both `isNavOpen` into the `<PageSidebar>` and `onNavToggle` into the `<PageHeader>`.
70
+
71
+ ```ts file="./PageUncontrolledNav.tsx"
72
+ ```
73
+
74
+ ### Filled page sections
75
+
76
+ By default, the last page section is "filled", meaning it fills the available vertical space of a page.
77
+
78
+ To change the default behavior, use the `isFilled` property. To make other page sections "filled", set `isFilled` equal to "true". To disable the last page section from being "filled", set `isFilled` equal to "false".
42
79
 
43
80
  ```ts file="./PageWithOrWithoutFill.tsx"
44
81
  ```
45
82
 
46
83
  ### Main section padding
47
84
 
48
- ```ts file="./PageMainSectionPadding.tsx"
49
- ```
85
+ To adjust the padding of a `<PageSection>`, you can pass in different values to the `padding` property. These values should be aligned to a specific breakpoint: 'default', 'sm', 'md', 'lg', 'xl', and '2xl'. Each breakpoint passed into the property should be given a value of either ‘padding’ or ‘noPadding’.
50
86
 
51
- ### Uncontrolled nav
87
+ As the page's viewport width increases, breakpoints inherit the padding behavior of the previous breakpoint. For example, padding that is set on 'lg' also applies to 'xl' and '2xl'.
52
88
 
53
- ```ts file="./PageUncontrolledNav.tsx"
89
+ To remove padding entirely, pass 'noPadding' to the `default` breakpoint. For example, the second section in this example passes in `padding={{ default: 'noPadding' }}`. Since no specific breakpoints are mentioned, every breakpoint will have 'noPadding'.
90
+
91
+ To add padding at specific breakpoints, pass in "padding" at those breakpoints. For example, the third section in this example passes in `padding={{ default: 'noPadding', md: 'padding' }}`. At 'md', 'lg', 'xl', and '2xl' breakpoints, the default value will be overwritten, and padding will be added.
92
+
93
+ To remove padding at specific breakpoints, pass in 'noPadding' at those breakpoints. For example, the fourth section in this example passes in `padding={{ md: 'noPadding' }}`, which means that 'md', 'lg' 'xl', and '2xl' breakpoints will have `noPadding`.
94
+
95
+ ```ts file="./PageMainSectionPadding.tsx"
54
96
  ```
55
97
 
56
98
  ### Group section
57
99
 
58
- ```ts file="./PageGroupSection.tsx"
59
- ```
100
+ To group page content sections, add 1 or more `<PageGroup>` components to a `<Page>`.
60
101
 
61
- ### Vertical nav using PageHeader component
102
+ The following example adds a group containing `<PageNavigation>`, `<PageBreadcrumb>`, and `<PageSection>` components.
62
103
 
63
- This example is provided because PageHeader and PageHeaderTools are still in use; however, going forward Masthead and Toolbar should be used to make headers rather than PageHeader and PageHeaderTools.
104
+ To add additional components and information to a group, you may use the following properties:
64
105
 
65
- ```ts file="./PageVerticalNavUsingPageHeaderComponent.tsx"
106
+ - To indicate that a breadcrumb should be in a group, use `isBreadcrumbGrouped`.
107
+ - To indicate that tertiary navigation should be in a group, use `isTertiaryNavGrouped`.
108
+ - To specify additional group content, use `additionalGroupedContent`.
109
+
110
+
111
+ ```ts file="./PageGroupSection.tsx"
66
112
  ```
67
113
 
68
114
  ### Centered section
69
115
 
116
+ By default, a page section spans the width of the page. To reduce the width of a section, use the `isWidthLimited` property. To center align width-limited page sections, use the `isCenterAligned` property. When the main content area of a page is wider than the value of a centered, width-limited page section's `--pf-c-page--section--m-limit-width--MaxWidth` custom property, the section will automatically be centered.
117
+
118
+ The content in this example is placed in a card to better illustrate how the section behaves when it is centered, but a card is not required to center a page section.
119
+
70
120
  ```ts file="./PageCenteredSection.tsx"
71
121
  ```