@patternfly/react-core 4.234.3 → 4.235.1
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 +27 -0
- package/dist/esm/next/components/Wizard/Wizard.d.ts +40 -0
- package/dist/esm/next/components/Wizard/Wizard.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/Wizard.js +86 -0
- package/dist/esm/next/components/Wizard/Wizard.js.map +1 -0
- package/dist/esm/next/components/Wizard/WizardBody.d.ts +20 -0
- package/dist/esm/next/components/Wizard/WizardBody.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/WizardBody.js +7 -0
- package/dist/esm/next/components/Wizard/WizardBody.js.map +1 -0
- package/dist/esm/next/components/Wizard/WizardContext.d.ts +49 -0
- package/dist/esm/next/components/Wizard/WizardContext.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/WizardContext.js +34 -0
- package/dist/esm/next/components/Wizard/WizardContext.js.map +1 -0
- package/dist/esm/next/components/Wizard/WizardFooter.d.ts +28 -0
- package/dist/esm/next/components/Wizard/WizardFooter.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/WizardFooter.js +11 -0
- package/dist/esm/next/components/Wizard/WizardFooter.js.map +1 -0
- package/dist/esm/next/components/Wizard/WizardHeader.d.ts +21 -0
- package/dist/esm/next/components/Wizard/WizardHeader.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/WizardHeader.js +13 -0
- package/dist/esm/next/components/Wizard/WizardHeader.js.map +1 -0
- package/dist/esm/next/components/Wizard/WizardNav.d.ts +15 -0
- package/dist/esm/next/components/Wizard/WizardNav.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/WizardNav.js +13 -0
- package/dist/esm/next/components/Wizard/WizardNav.js.map +1 -0
- package/dist/esm/next/components/Wizard/WizardNavItem.d.ts +25 -0
- package/dist/esm/next/components/Wizard/WizardNavItem.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/WizardNavItem.js +33 -0
- package/dist/esm/next/components/Wizard/WizardNavItem.js.map +1 -0
- package/dist/esm/next/components/Wizard/WizardStep.d.ts +20 -0
- package/dist/esm/next/components/Wizard/WizardStep.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/WizardStep.js +5 -0
- package/dist/esm/next/components/Wizard/WizardStep.js.map +1 -0
- package/dist/esm/next/components/Wizard/WizardToggle.d.ts +26 -0
- package/dist/esm/next/components/Wizard/WizardToggle.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/WizardToggle.js +81 -0
- package/dist/esm/next/components/Wizard/WizardToggle.js.map +1 -0
- package/dist/esm/next/components/Wizard/hooks/index.d.ts +2 -0
- package/dist/esm/next/components/Wizard/hooks/index.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/hooks/index.js +2 -0
- package/dist/esm/next/components/Wizard/hooks/index.js.map +1 -0
- package/dist/esm/next/components/Wizard/hooks/useWizardFooter.d.ts +8 -0
- package/dist/esm/next/components/Wizard/hooks/useWizardFooter.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/hooks/useWizardFooter.js +20 -0
- package/dist/esm/next/components/Wizard/hooks/useWizardFooter.js.map +1 -0
- package/dist/esm/next/components/Wizard/index.d.ts +12 -0
- package/dist/esm/next/components/Wizard/index.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/index.js +12 -0
- package/dist/esm/next/components/Wizard/index.js.map +1 -0
- package/dist/esm/next/components/Wizard/types.d.ts +69 -0
- package/dist/esm/next/components/Wizard/types.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/types.js +20 -0
- package/dist/esm/next/components/Wizard/types.js.map +1 -0
- package/dist/esm/next/components/Wizard/utils.d.ts +15 -0
- package/dist/esm/next/components/Wizard/utils.d.ts.map +1 -0
- package/dist/esm/next/components/Wizard/utils.js +35 -0
- package/dist/esm/next/components/Wizard/utils.js.map +1 -0
- package/dist/esm/next/components/index.d.ts +1 -1
- package/dist/esm/next/components/index.d.ts.map +1 -1
- package/dist/esm/next/components/index.js +1 -1
- package/dist/esm/next/components/index.js.map +1 -1
- package/dist/js/next/components/Wizard/Wizard.d.ts +40 -0
- package/dist/js/next/components/Wizard/Wizard.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/Wizard.js +90 -0
- package/dist/js/next/components/Wizard/Wizard.js.map +1 -0
- package/dist/js/next/components/Wizard/WizardBody.d.ts +20 -0
- package/dist/js/next/components/Wizard/WizardBody.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/WizardBody.js +12 -0
- package/dist/js/next/components/Wizard/WizardBody.js.map +1 -0
- package/dist/js/next/components/Wizard/WizardContext.d.ts +49 -0
- package/dist/js/next/components/Wizard/WizardContext.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/WizardContext.js +40 -0
- package/dist/js/next/components/Wizard/WizardContext.js.map +1 -0
- package/dist/js/next/components/Wizard/WizardFooter.d.ts +28 -0
- package/dist/js/next/components/Wizard/WizardFooter.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/WizardFooter.js +16 -0
- package/dist/js/next/components/Wizard/WizardFooter.js.map +1 -0
- package/dist/js/next/components/Wizard/WizardHeader.d.ts +21 -0
- package/dist/js/next/components/Wizard/WizardHeader.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/WizardHeader.js +18 -0
- package/dist/js/next/components/Wizard/WizardHeader.js.map +1 -0
- package/dist/js/next/components/Wizard/WizardNav.d.ts +15 -0
- package/dist/js/next/components/Wizard/WizardNav.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/WizardNav.js +18 -0
- package/dist/js/next/components/Wizard/WizardNav.js.map +1 -0
- package/dist/js/next/components/Wizard/WizardNavItem.d.ts +25 -0
- package/dist/js/next/components/Wizard/WizardNavItem.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/WizardNavItem.js +37 -0
- package/dist/js/next/components/Wizard/WizardNavItem.js.map +1 -0
- package/dist/js/next/components/Wizard/WizardStep.d.ts +20 -0
- package/dist/js/next/components/Wizard/WizardStep.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/WizardStep.js +10 -0
- package/dist/js/next/components/Wizard/WizardStep.js.map +1 -0
- package/dist/js/next/components/Wizard/WizardToggle.d.ts +26 -0
- package/dist/js/next/components/Wizard/WizardToggle.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/WizardToggle.js +86 -0
- package/dist/js/next/components/Wizard/WizardToggle.js.map +1 -0
- package/dist/js/next/components/Wizard/hooks/index.d.ts +2 -0
- package/dist/js/next/components/Wizard/hooks/index.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/hooks/index.js +6 -0
- package/dist/js/next/components/Wizard/hooks/index.js.map +1 -0
- package/dist/js/next/components/Wizard/hooks/useWizardFooter.d.ts +8 -0
- package/dist/js/next/components/Wizard/hooks/useWizardFooter.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/hooks/useWizardFooter.js +25 -0
- package/dist/js/next/components/Wizard/hooks/useWizardFooter.js.map +1 -0
- package/dist/js/next/components/Wizard/index.d.ts +12 -0
- package/dist/js/next/components/Wizard/index.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/index.js +17 -0
- package/dist/js/next/components/Wizard/index.js.map +1 -0
- package/dist/js/next/components/Wizard/types.d.ts +69 -0
- package/dist/js/next/components/Wizard/types.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/types.js +29 -0
- package/dist/js/next/components/Wizard/types.js.map +1 -0
- package/dist/js/next/components/Wizard/utils.d.ts +15 -0
- package/dist/js/next/components/Wizard/utils.d.ts.map +1 -0
- package/dist/js/next/components/Wizard/utils.js +41 -0
- package/dist/js/next/components/Wizard/utils.js.map +1 -0
- package/dist/js/next/components/index.d.ts +1 -1
- package/dist/js/next/components/index.d.ts.map +1 -1
- package/dist/js/next/components/index.js +1 -1
- package/dist/js/next/components/index.js.map +1 -1
- package/dist/umd/react-core.css +230 -230
- package/dist/umd/react-core.min.css +734 -734
- package/package.json +5 -5
- package/src/components/Card/examples/Card.md +67 -38
- package/src/components/Wizard/examples/Wizard.md +21 -4
- package/src/demos/CardDemos.md +4 -0
- package/src/next/components/Wizard/Wizard.tsx +184 -0
- package/src/next/components/Wizard/WizardBody.tsx +34 -0
- package/src/next/components/Wizard/WizardContext.tsx +104 -0
- package/src/next/components/Wizard/WizardFooter.tsx +63 -0
- package/src/next/components/Wizard/WizardHeader.tsx +53 -0
- package/src/next/components/Wizard/WizardNav.tsx +41 -0
- package/src/next/components/Wizard/WizardNavItem.tsx +103 -0
- package/src/next/components/Wizard/WizardStep.tsx +23 -0
- package/src/next/components/Wizard/WizardToggle.tsx +209 -0
- package/src/next/components/Wizard/__tests__/Wizard.test.tsx +298 -0
- package/src/next/components/Wizard/examples/Wizard.md +125 -0
- package/src/next/components/Wizard/examples/WizardBasic.tsx +22 -0
- package/src/next/components/Wizard/examples/WizardCustomNav.tsx +46 -0
- package/src/next/components/Wizard/examples/WizardKitchenSink.tsx +170 -0
- package/src/next/components/Wizard/hooks/index.ts +1 -0
- package/src/next/components/Wizard/hooks/useWizardFooter.tsx +22 -0
- package/src/next/components/Wizard/index.ts +11 -0
- package/src/next/components/Wizard/types.tsx +101 -0
- package/src/next/components/Wizard/utils.ts +47 -0
- package/src/next/components/index.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.235.1",
|
|
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",
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"generate": "node scripts/copyStyles.js"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@patternfly/react-icons": "^4.
|
|
54
|
-
"@patternfly/react-styles": "^4.
|
|
55
|
-
"@patternfly/react-tokens": "^4.
|
|
53
|
+
"@patternfly/react-icons": "^4.86.1",
|
|
54
|
+
"@patternfly/react-styles": "^4.85.1",
|
|
55
|
+
"@patternfly/react-tokens": "^4.87.1",
|
|
56
56
|
"focus-trap": "6.9.2",
|
|
57
57
|
"react-dropzone": "9.0.0",
|
|
58
58
|
"tippy.js": "5.1.2",
|
|
@@ -76,5 +76,5 @@
|
|
|
76
76
|
"react": "^16.8.0 || ^17.0.0",
|
|
77
77
|
"react-dom": "^16.8.0 || ^17.0.0"
|
|
78
78
|
},
|
|
79
|
-
"gitHead": "
|
|
79
|
+
"gitHead": "7261b4ef06344b8f4bad002e5c36b140a478d538"
|
|
80
80
|
}
|
|
@@ -9,101 +9,130 @@ ouia: true
|
|
|
9
9
|
import pfLogo from './pfLogo.svg';
|
|
10
10
|
import pfLogoSmall from './pf-logo-small.svg';
|
|
11
11
|
|
|
12
|
-
## Examples
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### Basic cards
|
|
16
|
+
|
|
17
|
+
Basic cards typically have a `<CardTitle>`, `<CardBody>` and `<CardFooter>`. You may omit these components as needed, but it is recommended to at least include a `<CardBody>` to provide details about the card item.
|
|
15
18
|
|
|
16
19
|
```ts file='./CardBasic.tsx'
|
|
17
20
|
```
|
|
18
21
|
|
|
19
|
-
###
|
|
22
|
+
### Modifiers
|
|
23
|
+
|
|
24
|
+
You can further modify the styling of the card's content by using the properties outlined below. In this example, you can enable each modifier by selecting its respective checkbox.
|
|
25
|
+
|
|
26
|
+
Most modifiers can be used in combination with each other, except for `isCompact` and `isLarge`, since they are contradictory.
|
|
20
27
|
|
|
21
28
|
```ts file='./CardWithModifiers.tsx'
|
|
22
29
|
```
|
|
23
30
|
|
|
24
|
-
|
|
31
|
+
| Modifier | Description |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| isCompact | Modifies the card to include compact styling. Should not be used with isLarge. |
|
|
34
|
+
| isFlat | Modifies the card to include flat styling. |
|
|
35
|
+
| isRounded | Modifies the card to include rounded border styling. |
|
|
36
|
+
| isLarge | Modifies the card to be large. Should not be used with isCompact. |
|
|
37
|
+
| isFullHeight | Modifies the card so that it fills the total available height of its container. |
|
|
38
|
+
| isPlain | Modifies the card to include plain styling, which removes the border and background. |
|
|
25
39
|
|
|
26
|
-
```ts file='./CardWithImageAndActions.tsx'
|
|
27
|
-
```
|
|
28
40
|
|
|
29
|
-
### Header
|
|
41
|
+
### Header images and actions
|
|
30
42
|
|
|
31
|
-
|
|
32
|
-
```
|
|
43
|
+
You can include header images within `<CardHeaderMain>` and header actions within `<CardActions>`. The following example includes an image using the [Brand](/components/brand) component, and also includes a kebab dropdown and a checkbox in `<CardActions>`.
|
|
33
44
|
|
|
34
|
-
|
|
45
|
+
`<CardActions>` includes the `hasNoOffset` property, which is `false` by default. When `hasNoOffset` is `false`, a negative margin is applied to help align default-sized card titles with `<CardActions>`.
|
|
35
46
|
|
|
36
|
-
|
|
37
|
-
```
|
|
47
|
+
You may use `hasNoOffset` to remove this negative margin, which better aligns `<CardActions>` in implementations that use large card titles or tall header images, for example.
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
Select the "actions hasNoOffset" checkbox in the example below to illustrate this behavior.
|
|
40
50
|
|
|
41
|
-
```ts file='./
|
|
51
|
+
```ts file='./CardWithImageAndActions.tsx'
|
|
42
52
|
```
|
|
43
53
|
|
|
44
|
-
###
|
|
54
|
+
### Title inline with images and actions
|
|
45
55
|
|
|
46
|
-
|
|
56
|
+
Moving `<CardTitle>` within the `<CardHeader>` will style it inline with any images or actions.
|
|
57
|
+
|
|
58
|
+
```ts file='./CardHeaderInCardHead.tsx'
|
|
47
59
|
```
|
|
48
60
|
|
|
49
|
-
###
|
|
61
|
+
### Card header without title
|
|
50
62
|
|
|
51
|
-
|
|
63
|
+
`<CardActions>` can be placed in the card header even without a `<CardTitle>`.
|
|
64
|
+
|
|
65
|
+
Images can also be placed in the card header within `<CardHeaderMain>` without a `<CardTitle>`.
|
|
66
|
+
|
|
67
|
+
```ts file='./CardOnlyActionsInCardHead.tsx'
|
|
52
68
|
```
|
|
53
69
|
|
|
54
|
-
### With
|
|
70
|
+
### With HTML heading element
|
|
71
|
+
|
|
72
|
+
You may use the `component` property to place the card's title within an HTML heading element.
|
|
55
73
|
|
|
56
|
-
```ts file='./
|
|
74
|
+
```ts file='./CardWithHeadingElement.tsx'
|
|
57
75
|
```
|
|
58
76
|
|
|
59
77
|
### With multiple body sections
|
|
60
78
|
|
|
79
|
+
You may use multiple body sections to visually separate blocks of content.
|
|
80
|
+
|
|
61
81
|
```ts file='./CardWithMultipleBodySections.tsx'
|
|
62
82
|
```
|
|
63
83
|
|
|
64
|
-
### With
|
|
84
|
+
### With a primary body section that fills
|
|
85
|
+
|
|
86
|
+
`<CardBody>` sections will fill the available height of the card when `isFilled` equals `{true}`, which is the default value. Set `isFilled` to `{false}` to disable this behavior for one or more body sections. The remaining available height of the card will be split between any `<CardBody>` section that does not set `isFilled` to `{false}`.
|
|
87
|
+
|
|
88
|
+
A common use case of this is to set all but one body section to `isFilled={false}` so that a primary body section fills the available space of the card as seen in the example below. This example has 3 `<CardBody>` sections, two of which set `isFilled` to `{false}`. The third `<CardBody>` fills the remaining height of the card.
|
|
65
89
|
|
|
66
90
|
```ts file='./CardWithBodySectionFills.tsx'
|
|
67
91
|
```
|
|
68
92
|
|
|
69
|
-
### Selectable
|
|
93
|
+
### Selectable cards
|
|
94
|
+
|
|
95
|
+
Selectable cards can only be selected one at a time, and are intended for use with [primary-detail layout](/demos/primary-detail).
|
|
70
96
|
|
|
71
97
|
```ts file='./CardSelectable.tsx'
|
|
72
98
|
```
|
|
73
99
|
|
|
74
|
-
###
|
|
100
|
+
### Legacy selectable cards
|
|
101
|
+
|
|
102
|
+
The following example shows a legacy implementation of selectable cards. This example uses the `isSelectable` property instead of `isSelectableRaised`, which is the current recommendation for implementation. `isSelectable` applies selectable styling, but does not apply raised styling on hover and selection as `isSelectableRaised` does.
|
|
103
|
+
|
|
104
|
+
```ts file='./CardLegacySelectable.tsx'
|
|
105
|
+
```
|
|
75
106
|
|
|
76
|
-
|
|
107
|
+
### Selectable card accessibility features
|
|
77
108
|
|
|
78
|
-
The
|
|
109
|
+
The following cards demonstrate how the `hasSelectableInput` and `onSelectableInputChange` properties improve accessibility for selectable cards.
|
|
79
110
|
|
|
80
|
-
|
|
111
|
+
The first card sets `hasSelectableInput` to true, which renders a checkbox input that is only visible to, and navigable by, screen readers. This input communicates to assistive technology users that a card is selectable, and if so, also communicates the current selection state.
|
|
81
112
|
|
|
82
|
-
|
|
113
|
+
By default, this input will have an aria-label that corresponds to the `<CardTitle>`. If this isn't defined, then you must pass a custom aria-label using the `selectableInputAriaLabel` property.
|
|
83
114
|
|
|
84
|
-
The
|
|
115
|
+
The first card passes an onChange callback to `onSelectableInputChange` to enable the selection/deselection of the associated card via checkbox input.
|
|
85
116
|
|
|
86
|
-
|
|
117
|
+
The second card does not set `hasSelectableInput` to true, so neither the input nor the selection state is communicated to users of assistive technologies.
|
|
118
|
+
|
|
119
|
+
We recommend navigating this example using a screen reader to best understand both cards.
|
|
87
120
|
|
|
88
121
|
```ts file='./CardSelectableA11yHighlight.tsx'
|
|
89
122
|
```
|
|
90
123
|
|
|
91
|
-
###
|
|
124
|
+
### Expandable cards
|
|
92
125
|
|
|
93
|
-
|
|
94
|
-
```
|
|
126
|
+
A card can be made expandable using the `isExpanded` property. In the collapsed state, only the card header is shown, and the user can click the caret to view the rest of the card content.
|
|
95
127
|
|
|
96
|
-
|
|
128
|
+
Place any content that you want to be hidden within the `<CardExpandableContent>` component.
|
|
97
129
|
|
|
98
130
|
```ts file='./CardExpandable.tsx'
|
|
99
131
|
```
|
|
100
132
|
|
|
101
133
|
### Expandable with icon
|
|
102
134
|
|
|
103
|
-
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### Legacy selectable
|
|
135
|
+
An image can be placed in the card header to show users an icon beside the expansion caret.
|
|
107
136
|
|
|
108
|
-
```ts file='./
|
|
137
|
+
```ts file='./CardExpandableWithIcon.tsx'
|
|
109
138
|
```
|
|
@@ -13,6 +13,8 @@ import SlackHashIcon from '@patternfly/react-icons/dist/esm/icons/slack-hash-ico
|
|
|
13
13
|
import FinishedStep from './FinishedStep';
|
|
14
14
|
import SampleForm from './SampleForm';
|
|
15
15
|
|
|
16
|
+
If you seek a wizard solution that allows for more composition, see the [React next](/components/wizard/react-next) tab.
|
|
17
|
+
|
|
16
18
|
## Examples
|
|
17
19
|
|
|
18
20
|
### Basic
|
|
@@ -54,7 +56,7 @@ class SimpleWizard extends React.Component {
|
|
|
54
56
|
render() {
|
|
55
57
|
const steps = [
|
|
56
58
|
{ name: 'First step', component: <p>Step 1 content</p> },
|
|
57
|
-
{ name: 'Second step', component: <p>Step 2 content</p>, isDisabled: true},
|
|
59
|
+
{ name: 'Second step', component: <p>Step 2 content</p>, isDisabled: true },
|
|
58
60
|
{ name: 'Third step', component: <p>Step 3 content</p> },
|
|
59
61
|
{ name: 'Fourth step', component: <p>Step 4 content</p>, isDisabled: true },
|
|
60
62
|
{ name: 'Review', component: <p>Review step content</p>, nextButtonText: 'Finish' }
|
|
@@ -145,9 +147,24 @@ class IncrementallyEnabledStepsWizard extends React.Component {
|
|
|
145
147
|
|
|
146
148
|
const steps = [
|
|
147
149
|
{ id: 'incrementally-enabled-1', name: 'First step', component: <p>Step 1 content</p> },
|
|
148
|
-
{
|
|
149
|
-
|
|
150
|
-
|
|
150
|
+
{
|
|
151
|
+
id: 'incrementally-enabled-2',
|
|
152
|
+
name: 'Second step',
|
|
153
|
+
component: <p>Step 2 content</p>,
|
|
154
|
+
canJumpTo: stepIdReached >= 2
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: 'incrementally-enabled-3',
|
|
158
|
+
name: 'Third step',
|
|
159
|
+
component: <p>Step 3 content</p>,
|
|
160
|
+
canJumpTo: stepIdReached >= 3
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
id: 'incrementally-enabled-4',
|
|
164
|
+
name: 'Fourth step',
|
|
165
|
+
component: <p>Step 4 content</p>,
|
|
166
|
+
canJumpTo: stepIdReached >= 4
|
|
167
|
+
},
|
|
151
168
|
{
|
|
152
169
|
id: 'incrementally-enabled-5',
|
|
153
170
|
name: 'Review',
|
package/src/demos/CardDemos.md
CHANGED
|
@@ -18,6 +18,8 @@ import chart_color_red_100 from '@patternfly/react-tokens/dist/esm/chart_color_r
|
|
|
18
18
|
|
|
19
19
|
### Horizontal card grid
|
|
20
20
|
|
|
21
|
+
The following demo shows how you may use a `<Grid>` within a card for scenarios that require multiple subsections.
|
|
22
|
+
|
|
21
23
|
```js
|
|
22
24
|
import React from 'react';
|
|
23
25
|
import {
|
|
@@ -263,6 +265,8 @@ class CardGridDemo extends React.Component {
|
|
|
263
265
|
|
|
264
266
|
### Horizontal split
|
|
265
267
|
|
|
268
|
+
The following demo shows how you may utilize `<Grid>` to split a card into two halves, one with an image, and one with text content.
|
|
269
|
+
|
|
266
270
|
```js
|
|
267
271
|
import React from 'react';
|
|
268
272
|
import { Card, CardTitle, CardBody, CardFooter, Grid, GridItem, Button } from '@patternfly/react-core';
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { css } from '@patternfly/react-styles';
|
|
4
|
+
import styles from '@patternfly/react-styles/css/components/Wizard/wizard';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
DefaultWizardFooterProps,
|
|
8
|
+
DefaultWizardNavProps,
|
|
9
|
+
isCustomWizardFooter,
|
|
10
|
+
isWizardParentStep,
|
|
11
|
+
WizardNavStepFunction,
|
|
12
|
+
CustomWizardNavFunction
|
|
13
|
+
} from './types';
|
|
14
|
+
import { buildSteps, normalizeNavStep } from './utils';
|
|
15
|
+
import { useWizardContext, WizardContextProvider } from './WizardContext';
|
|
16
|
+
import { WizardStepProps } from './WizardStep';
|
|
17
|
+
import { WizardFooter } from './WizardFooter';
|
|
18
|
+
import { WizardToggle } from './WizardToggle';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Wrapper for all steps and hosts state, including navigation helpers, within context.
|
|
22
|
+
* The WizardContext provided by default gives any child of wizard access to those resources.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export interface WizardProps extends React.HTMLProps<HTMLDivElement> {
|
|
26
|
+
/** Step components */
|
|
27
|
+
children: React.ReactElement<WizardStepProps> | React.ReactElement<WizardStepProps>[];
|
|
28
|
+
/** Wizard header */
|
|
29
|
+
header?: React.ReactNode;
|
|
30
|
+
/** Wizard footer */
|
|
31
|
+
footer?: DefaultWizardFooterProps | React.ReactElement;
|
|
32
|
+
/** Default wizard nav props or a custom WizardNav (with callback) */
|
|
33
|
+
nav?: DefaultWizardNavProps | CustomWizardNavFunction;
|
|
34
|
+
/** The initial index the wizard is to start on (1 or higher). Defaults to 1. */
|
|
35
|
+
startIndex?: number;
|
|
36
|
+
/** Additional classes spread to the wizard */
|
|
37
|
+
className?: string;
|
|
38
|
+
/** Custom width of the wizard */
|
|
39
|
+
width?: number | string;
|
|
40
|
+
/** Custom height of the wizard */
|
|
41
|
+
height?: number | string;
|
|
42
|
+
/** Callback function when a step in the nav is clicked */
|
|
43
|
+
onNavByIndex?: WizardNavStepFunction;
|
|
44
|
+
/** Callback function after next button is clicked */
|
|
45
|
+
onNext?: WizardNavStepFunction;
|
|
46
|
+
/** Callback function after back button is clicked */
|
|
47
|
+
onBack?: WizardNavStepFunction;
|
|
48
|
+
/** Callback function to save at the end of the wizard, if not specified uses onClose */
|
|
49
|
+
onSave?: () => void;
|
|
50
|
+
/** Callback function to close the wizard */
|
|
51
|
+
onClose?: () => void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const Wizard = (props: WizardProps) => {
|
|
55
|
+
const { startIndex = 1, children, footer, onNavByIndex, onNext, onBack, onSave, onClose, ...internalProps } = props;
|
|
56
|
+
const [currentStepIndex, setCurrentStepIndex] = React.useState(startIndex);
|
|
57
|
+
const steps = buildSteps(children);
|
|
58
|
+
|
|
59
|
+
const goToStepByIndex = (index: number) => {
|
|
60
|
+
const lastStepIndex = steps.length;
|
|
61
|
+
|
|
62
|
+
if (index < 1) {
|
|
63
|
+
index = 1;
|
|
64
|
+
} else if (index > lastStepIndex) {
|
|
65
|
+
index = lastStepIndex;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const currStep = steps[index - 1];
|
|
69
|
+
const prevStep = steps[currentStepIndex - 1];
|
|
70
|
+
setCurrentStepIndex(index);
|
|
71
|
+
|
|
72
|
+
return onNavByIndex?.(normalizeNavStep(currStep), normalizeNavStep(prevStep));
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const goToNextStep = () => {
|
|
76
|
+
// Save when on the last step, otherwise close
|
|
77
|
+
if (currentStepIndex >= steps.length) {
|
|
78
|
+
if (onSave) {
|
|
79
|
+
return onSave();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return onClose?.();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let currStep = steps[currentStepIndex];
|
|
86
|
+
let newStepIndex = currentStepIndex + 1;
|
|
87
|
+
const prevStep = steps[currentStepIndex - 1];
|
|
88
|
+
|
|
89
|
+
// Skip parent step and focus on the first sub-step if they exist
|
|
90
|
+
if (isWizardParentStep(currStep)) {
|
|
91
|
+
newStepIndex += 1;
|
|
92
|
+
currStep = steps[currentStepIndex + 1];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
setCurrentStepIndex(newStepIndex);
|
|
96
|
+
return onNext?.(normalizeNavStep(currStep), normalizeNavStep(prevStep));
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const goToPrevStep = () => {
|
|
100
|
+
if (steps.length < currentStepIndex) {
|
|
101
|
+
// Previous step was removed, just update the currentStep state
|
|
102
|
+
setCurrentStepIndex(steps.length);
|
|
103
|
+
} else {
|
|
104
|
+
let currStep = steps[currentStepIndex - 2];
|
|
105
|
+
let newStepIndex = currentStepIndex - 1;
|
|
106
|
+
const prevStep = steps[currentStepIndex - 1];
|
|
107
|
+
|
|
108
|
+
// // Skip parent step and focus on the step prior
|
|
109
|
+
if (isWizardParentStep(currStep)) {
|
|
110
|
+
newStepIndex -= 1;
|
|
111
|
+
currStep = steps[currentStepIndex - 3];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
setCurrentStepIndex(newStepIndex);
|
|
115
|
+
return onBack?.(normalizeNavStep(currStep), normalizeNavStep(prevStep));
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const goToStepById = (id: number | string) => {
|
|
120
|
+
const stepIndex = steps.findIndex(step => step.id === id) + 1;
|
|
121
|
+
stepIndex > 0 && setCurrentStepIndex(stepIndex);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const goToStepByName = (name: string) => {
|
|
125
|
+
const stepIndex = steps.findIndex(step => step.name === name) + 1;
|
|
126
|
+
stepIndex > 0 && setCurrentStepIndex(stepIndex);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<WizardContextProvider
|
|
131
|
+
steps={steps}
|
|
132
|
+
currentStepIndex={currentStepIndex}
|
|
133
|
+
footer={isCustomWizardFooter(footer) && footer}
|
|
134
|
+
onNext={goToNextStep}
|
|
135
|
+
onBack={goToPrevStep}
|
|
136
|
+
onClose={onClose}
|
|
137
|
+
goToStepById={goToStepById}
|
|
138
|
+
goToStepByName={goToStepByName}
|
|
139
|
+
goToStepByIndex={goToStepByIndex}
|
|
140
|
+
>
|
|
141
|
+
<WizardInternal {...internalProps} footer={footer}>
|
|
142
|
+
{children}
|
|
143
|
+
</WizardInternal>
|
|
144
|
+
</WizardContextProvider>
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// eslint-disable-next-line patternfly-react/no-anonymous-functions
|
|
149
|
+
const WizardInternal = ({ height, width, className, header, footer, nav, ...divProps }: WizardProps) => {
|
|
150
|
+
const { activeStep, steps, footer: customFooter, onNext, onBack, onClose, goToStepByIndex } = useWizardContext();
|
|
151
|
+
|
|
152
|
+
const wizardFooter = customFooter || (
|
|
153
|
+
<WizardFooter
|
|
154
|
+
activeStep={activeStep}
|
|
155
|
+
onNext={onNext}
|
|
156
|
+
onBack={onBack}
|
|
157
|
+
onClose={onClose}
|
|
158
|
+
disableBackButton={activeStep?.id === steps[0]?.id}
|
|
159
|
+
{...footer}
|
|
160
|
+
/>
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<div
|
|
165
|
+
className={css(styles.wizard, className)}
|
|
166
|
+
style={{
|
|
167
|
+
...(height ? { height } : {}),
|
|
168
|
+
...(width ? { width } : {})
|
|
169
|
+
}}
|
|
170
|
+
{...divProps}
|
|
171
|
+
>
|
|
172
|
+
{header}
|
|
173
|
+
<WizardToggle
|
|
174
|
+
steps={steps}
|
|
175
|
+
activeStep={activeStep}
|
|
176
|
+
footer={wizardFooter}
|
|
177
|
+
nav={nav}
|
|
178
|
+
goToStepByIndex={goToStepByIndex}
|
|
179
|
+
/>
|
|
180
|
+
</div>
|
|
181
|
+
);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
Wizard.displayName = 'Wizard';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import styles from '@patternfly/react-styles/css/components/Wizard/wizard';
|
|
4
|
+
import { css } from '@patternfly/react-styles';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Used as a wrapper for WizardStep content, where the wrapping element is customizable.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export interface WizardBodyProps {
|
|
11
|
+
children?: React.ReactNode | React.ReactNode[];
|
|
12
|
+
/** Set to true to remove the default body padding */
|
|
13
|
+
hasNoBodyPadding?: boolean;
|
|
14
|
+
/** An aria-label to use for the wrapper element */
|
|
15
|
+
'aria-label'?: string;
|
|
16
|
+
/** Sets the aria-labelledby attribute for the wrapper element */
|
|
17
|
+
'aria-labelledby'?: string;
|
|
18
|
+
/** Component used as the wrapping content container */
|
|
19
|
+
wrapperElement?: React.ElementType;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const WizardBody = ({
|
|
23
|
+
children,
|
|
24
|
+
hasNoBodyPadding = false,
|
|
25
|
+
'aria-label': ariaLabel,
|
|
26
|
+
'aria-labelledby': ariaLabelledBy,
|
|
27
|
+
wrapperElement: Wrapper = 'div'
|
|
28
|
+
}: WizardBodyProps) => (
|
|
29
|
+
<Wrapper aria-label={ariaLabel} aria-labelledby={ariaLabelledBy} className={css(styles.wizardMain)}>
|
|
30
|
+
<div className={css(styles.wizardMainBody, hasNoBodyPadding && styles.modifiers.noPadding)}>{children}</div>
|
|
31
|
+
</Wrapper>
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
WizardBody.displayName = 'WizardBody';
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { WizardControlStep } from './types';
|
|
3
|
+
import { getActiveStep } from './utils';
|
|
4
|
+
|
|
5
|
+
export interface WizardContextProps {
|
|
6
|
+
/** List of steps */
|
|
7
|
+
steps: WizardControlStep[];
|
|
8
|
+
/** Active step */
|
|
9
|
+
activeStep: WizardControlStep;
|
|
10
|
+
/** Footer element */
|
|
11
|
+
footer: React.ReactElement;
|
|
12
|
+
/** Navigate to the next step */
|
|
13
|
+
onNext: () => void;
|
|
14
|
+
/** Navigate to the previous step */
|
|
15
|
+
onBack: () => void;
|
|
16
|
+
/** Close the wizard */
|
|
17
|
+
onClose: () => void;
|
|
18
|
+
/** Navigate to step by ID */
|
|
19
|
+
goToStepById: (id: number | string) => void;
|
|
20
|
+
/** Navigate to step by name */
|
|
21
|
+
goToStepByName: (name: string) => void;
|
|
22
|
+
/** Navigate to step by index */
|
|
23
|
+
goToStepByIndex: (index: number) => void;
|
|
24
|
+
/** Update the footer with any react element */
|
|
25
|
+
setFooter: (footer: React.ReactElement) => void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const WizardContext = React.createContext({} as WizardContextProps);
|
|
29
|
+
|
|
30
|
+
interface WizardContextRenderProps {
|
|
31
|
+
steps: WizardControlStep[];
|
|
32
|
+
activeStep: WizardControlStep;
|
|
33
|
+
footer: React.ReactElement;
|
|
34
|
+
onNext(): void;
|
|
35
|
+
onBack(): void;
|
|
36
|
+
onClose(): void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface WizardContextProviderProps {
|
|
40
|
+
steps: WizardControlStep[];
|
|
41
|
+
currentStepIndex: number;
|
|
42
|
+
footer: React.ReactElement;
|
|
43
|
+
children: React.ReactElement | ((props: WizardContextRenderProps) => React.ReactElement);
|
|
44
|
+
onNext(): void;
|
|
45
|
+
onBack(): void;
|
|
46
|
+
onClose(): void;
|
|
47
|
+
goToStepById(id: number | string): void;
|
|
48
|
+
goToStepByName(name: string): void;
|
|
49
|
+
goToStepByIndex(index: number): void;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// eslint-disable-next-line patternfly-react/no-anonymous-functions
|
|
53
|
+
export const WizardContextProvider: React.FunctionComponent<WizardContextProviderProps> = ({
|
|
54
|
+
steps: initialSteps,
|
|
55
|
+
footer: initialFooter,
|
|
56
|
+
currentStepIndex,
|
|
57
|
+
children,
|
|
58
|
+
onNext,
|
|
59
|
+
onBack,
|
|
60
|
+
onClose,
|
|
61
|
+
goToStepById,
|
|
62
|
+
goToStepByName,
|
|
63
|
+
goToStepByIndex
|
|
64
|
+
}) => {
|
|
65
|
+
const [steps, setSteps] = React.useState(initialSteps);
|
|
66
|
+
const [footer, setFooter] = React.useState(initialFooter);
|
|
67
|
+
const activeStep = getActiveStep(steps, currentStepIndex);
|
|
68
|
+
|
|
69
|
+
// When the active step changes and the newly active step isn't visited, set the visited flag to true.
|
|
70
|
+
React.useEffect(() => {
|
|
71
|
+
if (activeStep && !activeStep?.visited) {
|
|
72
|
+
setSteps(prevSteps =>
|
|
73
|
+
prevSteps.map(step => {
|
|
74
|
+
if (step.id === activeStep.id) {
|
|
75
|
+
return { ...step, visited: true };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return step;
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
}, [activeStep]);
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<WizardContext.Provider
|
|
86
|
+
value={{
|
|
87
|
+
steps,
|
|
88
|
+
activeStep,
|
|
89
|
+
footer,
|
|
90
|
+
onNext,
|
|
91
|
+
onBack,
|
|
92
|
+
onClose,
|
|
93
|
+
goToStepById,
|
|
94
|
+
goToStepByName,
|
|
95
|
+
goToStepByIndex,
|
|
96
|
+
setFooter
|
|
97
|
+
}}
|
|
98
|
+
>
|
|
99
|
+
{typeof children === 'function' ? children({ activeStep, steps, footer, onNext, onBack, onClose }) : children}
|
|
100
|
+
</WizardContext.Provider>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const useWizardContext = () => React.useContext(WizardContext);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { css } from '@patternfly/react-styles';
|
|
4
|
+
import styles from '@patternfly/react-styles/css/components/Wizard/wizard';
|
|
5
|
+
|
|
6
|
+
import { Button, ButtonVariant } from '../../../components/Button';
|
|
7
|
+
import { WizardControlStep, WizardNavStepFunction } from './types';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Hosts the standard structure of a footer with ties to the active step so that text for buttons can vary from step to step.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export interface WizardFooterProps {
|
|
14
|
+
/** The currently active WizardStep */
|
|
15
|
+
activeStep: WizardControlStep;
|
|
16
|
+
/** Next button callback */
|
|
17
|
+
onNext: () => WizardNavStepFunction | void;
|
|
18
|
+
/** Back button callback */
|
|
19
|
+
onBack: () => WizardNavStepFunction | void;
|
|
20
|
+
/** Cancel link callback */
|
|
21
|
+
onClose: () => void;
|
|
22
|
+
/** Custom text for the Next button. The activeStep's nextButtonText takes precedence. */
|
|
23
|
+
nextButtonText?: React.ReactNode;
|
|
24
|
+
/** Custom text for the Back button */
|
|
25
|
+
backButtonText?: React.ReactNode;
|
|
26
|
+
/** Custom text for the Cancel link */
|
|
27
|
+
cancelButtonText?: React.ReactNode;
|
|
28
|
+
/** Optional flag to disable the first step's back button */
|
|
29
|
+
disableBackButton?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const WizardFooter = ({
|
|
33
|
+
onNext,
|
|
34
|
+
onBack,
|
|
35
|
+
onClose,
|
|
36
|
+
activeStep,
|
|
37
|
+
disableBackButton,
|
|
38
|
+
nextButtonText = 'Next',
|
|
39
|
+
backButtonText = 'Back',
|
|
40
|
+
cancelButtonText = 'Cancel'
|
|
41
|
+
}: WizardFooterProps) => (
|
|
42
|
+
<footer className={css(styles.wizardFooter)}>
|
|
43
|
+
<Button variant={ButtonVariant.primary} type="submit" onClick={onNext} isDisabled={activeStep?.disableNext}>
|
|
44
|
+
{activeStep?.nextButtonText || nextButtonText}
|
|
45
|
+
</Button>
|
|
46
|
+
|
|
47
|
+
{!activeStep?.hideBackButton && (
|
|
48
|
+
<Button variant={ButtonVariant.secondary} onClick={onBack} isDisabled={disableBackButton}>
|
|
49
|
+
{backButtonText}
|
|
50
|
+
</Button>
|
|
51
|
+
)}
|
|
52
|
+
|
|
53
|
+
{!activeStep?.hideCancelButton && (
|
|
54
|
+
<div className={styles.wizardFooterCancel}>
|
|
55
|
+
<Button variant={ButtonVariant.link} onClick={onClose}>
|
|
56
|
+
{cancelButtonText}
|
|
57
|
+
</Button>
|
|
58
|
+
</div>
|
|
59
|
+
)}
|
|
60
|
+
</footer>
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
WizardFooter.displayName = 'WizardFooter';
|