@patternfly/react-core 4.233.1 → 4.234.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 +11 -0
- package/dist/esm/components/MenuToggle/MenuToggle.js +1 -1
- package/dist/esm/components/MenuToggle/MenuToggle.js.map +1 -1
- package/dist/esm/components/Timestamp/Timestamp.d.ts +72 -0
- package/dist/esm/components/Timestamp/Timestamp.d.ts.map +1 -0
- package/dist/esm/components/Timestamp/Timestamp.js +33 -0
- package/dist/esm/components/Timestamp/Timestamp.js.map +1 -0
- package/dist/esm/components/Timestamp/index.d.ts +2 -0
- package/dist/esm/components/Timestamp/index.d.ts.map +1 -0
- package/dist/esm/components/Timestamp/index.js +2 -0
- package/dist/esm/components/Timestamp/index.js.map +1 -0
- package/dist/esm/components/index.d.ts +1 -0
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/components/index.js +1 -0
- package/dist/esm/components/index.js.map +1 -1
- package/dist/js/components/MenuToggle/MenuToggle.js +1 -1
- package/dist/js/components/MenuToggle/MenuToggle.js.map +1 -1
- package/dist/js/components/Timestamp/Timestamp.d.ts +72 -0
- package/dist/js/components/Timestamp/Timestamp.d.ts.map +1 -0
- package/dist/js/components/Timestamp/Timestamp.js +37 -0
- package/dist/js/components/Timestamp/Timestamp.js.map +1 -0
- package/dist/js/components/Timestamp/index.d.ts +2 -0
- package/dist/js/components/Timestamp/index.d.ts.map +1 -0
- package/dist/js/components/Timestamp/index.js +5 -0
- package/dist/js/components/Timestamp/index.js.map +1 -0
- package/dist/js/components/index.d.ts +1 -0
- package/dist/js/components/index.d.ts.map +1 -1
- package/dist/js/components/index.js +1 -0
- package/dist/js/components/index.js.map +1 -1
- package/dist/umd/react-core.css +22392 -22354
- package/dist/umd/react-core.js +798 -757
- package/dist/umd/react-core.min.css +372 -334
- package/dist/umd/react-core.min.js +4 -4
- package/package.json +5 -5
- package/src/components/Button/examples/Button.md +55 -24
- package/src/components/ContextSelector/examples/ContextSelectorBasic.tsx +4 -4
- package/src/components/ContextSelector/examples/ContextSelectorPlainText.tsx +3 -3
- package/src/components/ContextSelector/examples/ContextSelectorWithFooter.tsx +4 -4
- package/src/components/DualListSelector/examples/DualListSelectorComposable.tsx +8 -2
- package/src/components/DualListSelector/examples/DualListSelectorComposableDragDrop.tsx +3 -9
- package/src/components/DualListSelector/examples/DualListSelectorComposableTree.tsx +3 -3
- package/src/components/DualListSelector/examples/DualListSelectorTreeExample.tsx +8 -5
- package/src/components/MenuToggle/MenuToggle.tsx +2 -2
- package/src/components/Timestamp/Timestamp.tsx +134 -0
- package/src/components/Timestamp/__tests__/Timestamp.test.tsx +177 -0
- package/src/components/Timestamp/__tests__/__snapshots__/Timestamp.test.tsx.snap +17 -0
- package/src/components/Timestamp/examples/Timestamp.md +57 -0
- package/src/components/Timestamp/examples/TimestampBasicFormats.tsx +26 -0
- package/src/components/Timestamp/examples/TimestampCustomContent.tsx +20 -0
- package/src/components/Timestamp/examples/TimestampCustomFormat.tsx +6 -0
- package/src/components/Timestamp/examples/TimestampCustomTooltip.tsx +19 -0
- package/src/components/Timestamp/examples/TimestampDefault.tsx +4 -0
- package/src/components/Timestamp/examples/TimestampDefaultTooltip.tsx +18 -0
- package/src/components/Timestamp/index.ts +1 -0
- package/src/components/index.ts +1 -0
- package/src/demos/Button.md +5 -1
- package/src/demos/ComposableMenu/examples/ComposableActionsMenu.tsx +12 -8
- package/src/demos/ComposableMenu/examples/ComposableApplicationLauncher.tsx +12 -11
- package/src/demos/ComposableMenu/examples/ComposableContextSelector.tsx +10 -12
- package/src/demos/ComposableMenu/examples/ComposableDrilldownMenu.tsx +7 -7
- package/src/demos/ComposableMenu/examples/ComposableFlyout.tsx +8 -8
- package/src/demos/ComposableMenu/examples/ComposableSimpleCheckboxSelect.tsx +11 -8
- package/src/demos/ComposableMenu/examples/ComposableSimpleDropdown.tsx +7 -7
- package/src/demos/ComposableMenu/examples/ComposableSimpleSelect.tsx +17 -8
- package/src/demos/ComposableMenu/examples/ComposableTreeViewMenu.tsx +11 -10
- package/src/demos/ComposableMenu/examples/ComposableTypeaheadSelect.tsx +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.234.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",
|
|
@@ -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.85.0",
|
|
54
|
+
"@patternfly/react-styles": "^4.84.0",
|
|
55
|
+
"@patternfly/react-tokens": "^4.86.0",
|
|
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": "fa6869951efc44e52696e065322c40478aa3fad3"
|
|
80
80
|
}
|
|
@@ -16,68 +16,99 @@ import { Link } from '@reach/router';
|
|
|
16
16
|
|
|
17
17
|
## Examples
|
|
18
18
|
|
|
19
|
-
###
|
|
19
|
+
### Variant examples
|
|
20
|
+
|
|
21
|
+
PatternFly supports several button styling variants to be used in different scenarios as needed. The following button variants can be assigned using the `variant` property.
|
|
20
22
|
|
|
21
23
|
```ts file="./ButtonVariations.tsx"
|
|
22
24
|
```
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
| Variant | Description|
|
|
27
|
+
| --- | ---|
|
|
28
|
+
| Primary | Primary buttons are the most visually prominent variant. Use for the most important call to action.|
|
|
29
|
+
| Secondary | Secondary buttons are less visually prominant than primary buttons. Use for general actions on a page that require less emphasis than primary buttons. |
|
|
30
|
+
| Tertiary | Tertiary buttons are the least visually prominent variant. Use to retain a classic button format with less emphasis than primary or secondary buttons. |
|
|
31
|
+
| Danger | Danger buttons may be used for actions that are potentially destructive or difficult/impossible to undo. Danger is an independent variant, but all button variants may use the the `isDanger` property to apply similar styling. |
|
|
32
|
+
| Warning | Warning buttons may be used for actions that change an important setting or behavior, but not in a destructive or irreversible way. |
|
|
33
|
+
| Link | Links are labeled, but have no background or border. Use for actions that require less emphasis, actions that navigate users to another page within the same window, and/or actions that navigate to external pages in a new window. Links may be placed inline with text using the `isInline` property.|
|
|
34
|
+
| Plain | Plain buttons have no styling and are intended to be labeled with icons. |
|
|
35
|
+
| Control | Control buttons can be labeled with text or icons. Primarily intended to be paired with other controls in an [input group](https://www.patternfly.org/v4/components/input-group). |
|
|
36
|
+
|
|
37
|
+
### Disabled buttons
|
|
38
|
+
|
|
39
|
+
To indicate that an action is currently unavailable, all button variations can be disabled using the `isDisabled` property.
|
|
25
40
|
|
|
26
41
|
```ts file="./ButtonDisabled.tsx"
|
|
27
42
|
```
|
|
28
43
|
|
|
29
|
-
###
|
|
44
|
+
### Small buttons
|
|
30
45
|
|
|
31
|
-
|
|
46
|
+
To fit into tight spaces, primary, secondary, tertiary, danger, and warning button variations can be made smaller using the `isSmall` property.
|
|
47
|
+
|
|
48
|
+
```ts file="./ButtonSmall.tsx"
|
|
32
49
|
```
|
|
33
50
|
|
|
34
|
-
###
|
|
51
|
+
### Call to action (CTA) buttons
|
|
35
52
|
|
|
36
|
-
|
|
53
|
+
CTA buttons and links direct users to complete an action. Primary, secondary, tertiary, and link button variants can be styled as CTAs using the `isLarge` property.
|
|
54
|
+
|
|
55
|
+
```ts file="./ButtonCallToAction.tsx"
|
|
37
56
|
```
|
|
38
57
|
|
|
39
|
-
###
|
|
58
|
+
### Block level buttons
|
|
40
59
|
|
|
41
|
-
|
|
60
|
+
Block level buttons span the full width of the parent element and can be enabled using the `isBlock` property.
|
|
61
|
+
|
|
62
|
+
```ts file="./ButtonBlock.tsx"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Progress indicators
|
|
66
|
+
|
|
67
|
+
Progress indicators can be added to buttons to identify that an action is in progress after a click.
|
|
68
|
+
|
|
69
|
+
```ts file="./ButtonProgress.tsx"
|
|
42
70
|
```
|
|
43
71
|
|
|
44
72
|
### Links as buttons
|
|
45
73
|
|
|
74
|
+
Buttons that link to another resource may take the form of primary, secondary, tertiary, or link variants. Use `component="a"` and an `href` property to designate the button's target link.
|
|
75
|
+
|
|
46
76
|
```ts file="./ButtonLinks.tsx"
|
|
47
77
|
```
|
|
48
78
|
|
|
49
79
|
### Inline link as span
|
|
50
80
|
|
|
81
|
+
Inline links should use `component="span"` and the `isInline` property to wrap inline with surrounding text.
|
|
82
|
+
|
|
51
83
|
```ts file="./ButtonInlineSpanLink.tsx"
|
|
52
84
|
```
|
|
53
85
|
|
|
54
|
-
###
|
|
55
|
-
|
|
56
|
-
```ts file="./ButtonBlock.tsx"
|
|
57
|
-
```
|
|
86
|
+
### Router link
|
|
58
87
|
|
|
59
|
-
|
|
88
|
+
Router links can be used for in-app linking in React environments to prevent page reloading.
|
|
60
89
|
|
|
61
|
-
```ts file="./
|
|
90
|
+
```ts file="./ButtonRouterLink.tsx"
|
|
62
91
|
```
|
|
63
92
|
|
|
64
|
-
###
|
|
93
|
+
### Aria-disabled examples
|
|
65
94
|
|
|
66
|
-
|
|
67
|
-
```
|
|
95
|
+
[Accessible Rich Internet Applications (ARIA)](https://www.w3.org/WAI/standards-guidelines/aria/) is a set of roles and attributes specified by the World Wide Web Consortium. ARIA defines ways to make web content and web applications more accessible to people with disabilities.
|
|
68
96
|
|
|
69
|
-
|
|
97
|
+
Buttons that are aria-disabled are similar to normal disabled buttons, except they can receive focus. Every button variant can be aria-disabled using the `isAriaDisabled` property.
|
|
70
98
|
|
|
71
|
-
```ts file="./
|
|
99
|
+
```ts file="./ButtonAriaDisabled.tsx"
|
|
72
100
|
```
|
|
73
101
|
|
|
74
|
-
###
|
|
102
|
+
### Aria-disabled with tooltip
|
|
75
103
|
|
|
76
|
-
|
|
104
|
+
Unlike normal disabled buttons, aria-disabled buttons can support tooltips.
|
|
105
|
+
|
|
106
|
+
```ts file="./ButtonAriaDisabledTooltip.tsx"
|
|
77
107
|
```
|
|
78
108
|
|
|
79
|
-
###
|
|
109
|
+
### Aria-disabled link as button with tooltip
|
|
80
110
|
|
|
81
|
-
|
|
82
|
-
```
|
|
111
|
+
Aria-disabled buttons can operate as links, which also support tooltips.
|
|
83
112
|
|
|
113
|
+
```ts file="./ButtonAriaDisabledLinkTooltip.tsx"
|
|
114
|
+
```
|
|
@@ -48,7 +48,7 @@ export const ContextSelectorBasic: React.FunctionComponent = () => {
|
|
|
48
48
|
setSearchValue(value);
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
const onSearchButtonClick = (
|
|
51
|
+
const onSearchButtonClick = () => {
|
|
52
52
|
const filtered =
|
|
53
53
|
searchValue === ''
|
|
54
54
|
? items
|
|
@@ -71,11 +71,11 @@ export const ContextSelectorBasic: React.FunctionComponent = () => {
|
|
|
71
71
|
screenReaderLabel="Selected Project:"
|
|
72
72
|
>
|
|
73
73
|
{filteredItems.map((item, index) => {
|
|
74
|
-
const [text = null, href =
|
|
75
|
-
typeof item === 'string' ? [item,
|
|
74
|
+
const [text = null, href = undefined, isDisabled] =
|
|
75
|
+
typeof item === 'string' ? [item, undefined, false] : [item.text, item.href, item.isDisabled];
|
|
76
76
|
return (
|
|
77
77
|
<ContextSelectorItem key={index} href={href} isDisabled={isDisabled}>
|
|
78
|
-
{text
|
|
78
|
+
{text}
|
|
79
79
|
</ContextSelectorItem>
|
|
80
80
|
);
|
|
81
81
|
})}
|
|
@@ -47,7 +47,7 @@ export const ContextSelectorPlainText: React.FunctionComponent = () => {
|
|
|
47
47
|
setSearchValue(value);
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
const onSearchButtonClick = (
|
|
50
|
+
const onSearchButtonClick = () => {
|
|
51
51
|
const filtered =
|
|
52
52
|
searchValue === ''
|
|
53
53
|
? items
|
|
@@ -72,8 +72,8 @@ export const ContextSelectorPlainText: React.FunctionComponent = () => {
|
|
|
72
72
|
isText
|
|
73
73
|
>
|
|
74
74
|
{filteredItems.map((item, index) => {
|
|
75
|
-
const [text, href =
|
|
76
|
-
typeof item === 'string' ? [item,
|
|
75
|
+
const [text, href = undefined, isDisabled = false] =
|
|
76
|
+
typeof item === 'string' ? [item, undefined, false] : [item.text, item.href, item.isDisabled];
|
|
77
77
|
return (
|
|
78
78
|
<ContextSelectorItem key={index} href={href} isDisabled={isDisabled}>
|
|
79
79
|
{text}
|
|
@@ -47,7 +47,7 @@ export const ContextSelectorWithFooter: React.FunctionComponent = () => {
|
|
|
47
47
|
setSearchValue(value);
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
const onSearchButtonClick = (
|
|
50
|
+
const onSearchButtonClick = () => {
|
|
51
51
|
const filtered =
|
|
52
52
|
searchValue === ''
|
|
53
53
|
? items
|
|
@@ -78,11 +78,11 @@ export const ContextSelectorWithFooter: React.FunctionComponent = () => {
|
|
|
78
78
|
}
|
|
79
79
|
>
|
|
80
80
|
{filteredItems.map((item, index) => {
|
|
81
|
-
const [text = null, href =
|
|
82
|
-
typeof item === 'string' ? [item,
|
|
81
|
+
const [text = null, href = undefined, isDisabled] =
|
|
82
|
+
typeof item === 'string' ? [item, undefined, false] : [item.text, item.href, item.isDisabled];
|
|
83
83
|
return (
|
|
84
84
|
<ContextSelectorItem key={index} href={href} isDisabled={isDisabled}>
|
|
85
|
-
{text
|
|
85
|
+
{text}
|
|
86
86
|
</ContextSelectorItem>
|
|
87
87
|
);
|
|
88
88
|
})}
|
|
@@ -16,8 +16,14 @@ import AngleDoubleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-d
|
|
|
16
16
|
import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon';
|
|
17
17
|
import PficonSortCommonAscIcon from '@patternfly/react-icons/dist/esm/icons/pficon-sort-common-asc-icon';
|
|
18
18
|
|
|
19
|
+
interface Option {
|
|
20
|
+
text: string;
|
|
21
|
+
selected: boolean;
|
|
22
|
+
isVisible: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
19
25
|
export const DualListSelectorComposable: React.FunctionComponent = () => {
|
|
20
|
-
const [availableOptions, setAvailableOptions] = React.useState([
|
|
26
|
+
const [availableOptions, setAvailableOptions] = React.useState<Option[]>([
|
|
21
27
|
{ text: 'Apple', selected: false, isVisible: true },
|
|
22
28
|
{ text: 'Banana', selected: false, isVisible: true },
|
|
23
29
|
{ text: 'Pineapple', selected: false, isVisible: true },
|
|
@@ -26,7 +32,7 @@ export const DualListSelectorComposable: React.FunctionComponent = () => {
|
|
|
26
32
|
{ text: 'Peach', selected: false, isVisible: true },
|
|
27
33
|
{ text: 'Strawberry', selected: false, isVisible: true }
|
|
28
34
|
]);
|
|
29
|
-
const [chosenOptions, setChosenOptions] = React.useState([]);
|
|
35
|
+
const [chosenOptions, setChosenOptions] = React.useState<Option[]>([]);
|
|
30
36
|
const [availableFilter, setAvailableFilter] = React.useState('');
|
|
31
37
|
const [chosenFilter, setChosenFilter] = React.useState('');
|
|
32
38
|
|
|
@@ -8,20 +8,14 @@ import {
|
|
|
8
8
|
DualListSelectorList,
|
|
9
9
|
DualListSelectorListItem,
|
|
10
10
|
DualListSelectorControlsWrapper,
|
|
11
|
-
DualListSelectorControl
|
|
11
|
+
DualListSelectorControl,
|
|
12
|
+
DraggableItemPosition
|
|
12
13
|
} from '@patternfly/react-core';
|
|
13
14
|
import AngleDoubleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-left-icon';
|
|
14
15
|
import AngleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-left-icon';
|
|
15
16
|
import AngleDoubleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-right-icon';
|
|
16
17
|
import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon';
|
|
17
18
|
|
|
18
|
-
interface SourceType {
|
|
19
|
-
droppableId: string;
|
|
20
|
-
index: number;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
interface DestinationType extends SourceType {}
|
|
24
|
-
|
|
25
19
|
export const DualListSelectorComposableDragDrop: React.FunctionComponent = () => {
|
|
26
20
|
const [ignoreNextOptionSelect, setIgnoreNextOptionSelect] = React.useState(false);
|
|
27
21
|
const [availableOptions, setAvailableOptions] = React.useState([
|
|
@@ -87,7 +81,7 @@ export const DualListSelectorComposableDragDrop: React.FunctionComponent = () =>
|
|
|
87
81
|
}
|
|
88
82
|
};
|
|
89
83
|
|
|
90
|
-
const onDrop = (source:
|
|
84
|
+
const onDrop = (source: DraggableItemPosition, dest?: DraggableItemPosition) => {
|
|
91
85
|
if (dest) {
|
|
92
86
|
const newList = [...chosenOptions];
|
|
93
87
|
const [removed] = newList.splice(source.index, 1);
|
|
@@ -52,7 +52,7 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
|
|
|
52
52
|
if (!node.children || !node.children.length) {
|
|
53
53
|
return [node.id];
|
|
54
54
|
} else {
|
|
55
|
-
let childrenIds = [];
|
|
55
|
+
let childrenIds: string[] = [];
|
|
56
56
|
node.children.forEach(child => {
|
|
57
57
|
childrenIds = [...childrenIds, ...getDescendantLeafIds(child)];
|
|
58
58
|
});
|
|
@@ -77,7 +77,7 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
|
|
|
77
77
|
// Builds a map of child leaf nodes by node id - memoized so that it only rebuilds the list if the data changes.
|
|
78
78
|
const { memoizedLeavesById, memoizedAllLeaves, memoizedNodeText } = React.useMemo(() => {
|
|
79
79
|
let leavesById = {};
|
|
80
|
-
let allLeaves = [];
|
|
80
|
+
let allLeaves: string[] = [];
|
|
81
81
|
let nodeTexts = {};
|
|
82
82
|
data.forEach(foodNode => {
|
|
83
83
|
nodeTexts = { ...nodeTexts, ...buildTextById(foodNode) };
|
|
@@ -129,7 +129,7 @@ export const DualListSelectorComposableTree: React.FunctionComponent<ExampleProp
|
|
|
129
129
|
return true;
|
|
130
130
|
}
|
|
131
131
|
if (areSomeDescendantsSelected(node, isChosen)) {
|
|
132
|
-
return
|
|
132
|
+
return false;
|
|
133
133
|
}
|
|
134
134
|
return false;
|
|
135
135
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { DualListSelector } from '@patternfly/react-core';
|
|
2
|
+
import { DualListSelector, DualListSelectorTreeItemData } from '@patternfly/react-core';
|
|
3
3
|
|
|
4
4
|
export const DualListSelectorTreeExample: React.FunctionComponent = () => {
|
|
5
|
-
const [availableOptions, setAvailableOptions] = React.useState<
|
|
5
|
+
const [availableOptions, setAvailableOptions] = React.useState<DualListSelectorTreeItemData[]>([
|
|
6
6
|
{
|
|
7
7
|
id: 'F1',
|
|
8
8
|
text: 'Folder 1',
|
|
@@ -38,7 +38,7 @@ export const DualListSelectorTreeExample: React.FunctionComponent = () => {
|
|
|
38
38
|
}
|
|
39
39
|
]);
|
|
40
40
|
|
|
41
|
-
const [chosenOptions, setChosenOptions] = React.useState<
|
|
41
|
+
const [chosenOptions, setChosenOptions] = React.useState<DualListSelectorTreeItemData[]>([
|
|
42
42
|
{
|
|
43
43
|
id: 'CF1',
|
|
44
44
|
text: 'Chosen Folder 1',
|
|
@@ -73,7 +73,10 @@ export const DualListSelectorTreeExample: React.FunctionComponent = () => {
|
|
|
73
73
|
}
|
|
74
74
|
]);
|
|
75
75
|
|
|
76
|
-
const onListChange = (
|
|
76
|
+
const onListChange = (
|
|
77
|
+
newAvailableOptions: DualListSelectorTreeItemData[],
|
|
78
|
+
newChosenOptions: DualListSelectorTreeItemData[]
|
|
79
|
+
) => {
|
|
77
80
|
setAvailableOptions(newAvailableOptions.sort());
|
|
78
81
|
setChosenOptions(newChosenOptions.sort());
|
|
79
82
|
};
|
|
@@ -84,7 +87,7 @@ export const DualListSelectorTreeExample: React.FunctionComponent = () => {
|
|
|
84
87
|
isTree
|
|
85
88
|
availableOptions={availableOptions}
|
|
86
89
|
chosenOptions={chosenOptions}
|
|
87
|
-
onListChange={onListChange}
|
|
90
|
+
onListChange={onListChange as any}
|
|
88
91
|
id="dual-list-selector-tree"
|
|
89
92
|
/>
|
|
90
93
|
);
|
|
@@ -87,7 +87,7 @@ export class MenuToggleBase extends React.Component<MenuToggleProps> {
|
|
|
87
87
|
<>
|
|
88
88
|
{icon && <span className={css(styles.menuToggleIcon)}>{icon}</span>}
|
|
89
89
|
{isTypeahead ? children : <span className={css(styles.menuToggleText)}>{children}</span>}
|
|
90
|
-
{badge && <span className={css(styles.menuToggleCount)}>{badge}</span>}
|
|
90
|
+
{React.isValidElement(badge) && <span className={css(styles.menuToggleCount)}>{badge}</span>}
|
|
91
91
|
{isTypeahead ? (
|
|
92
92
|
<button
|
|
93
93
|
type="button"
|
|
@@ -166,7 +166,7 @@ export class MenuToggleBase extends React.Component<MenuToggleProps> {
|
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
export const MenuToggle = React.forwardRef((props
|
|
169
|
+
export const MenuToggle = React.forwardRef<MenuToggleElement, MenuToggleProps>((props, ref) => (
|
|
170
170
|
<MenuToggleBase innerRef={ref} {...props} />
|
|
171
171
|
));
|
|
172
172
|
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import styles from '@patternfly/react-styles/css/components/Timestamp/timestamp';
|
|
3
|
+
import { css } from '@patternfly/react-styles';
|
|
4
|
+
import { Tooltip } from '../Tooltip';
|
|
5
|
+
|
|
6
|
+
export enum TimestampFormat {
|
|
7
|
+
full = 'full',
|
|
8
|
+
long = 'long',
|
|
9
|
+
medium = 'medium',
|
|
10
|
+
short = 'short'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export enum TimestampTooltipVariant {
|
|
14
|
+
default = 'default',
|
|
15
|
+
custom = 'custom'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface TimestampTooltip {
|
|
19
|
+
/** The variant of the tooltip. The "default" variant displays the date passed into
|
|
20
|
+
* the timestamp's date prop as a UTC string.
|
|
21
|
+
*/
|
|
22
|
+
variant: 'default' | 'custom';
|
|
23
|
+
/** Content displayed in the tooltip when using the "custom" variant. */
|
|
24
|
+
content?: React.ReactNode;
|
|
25
|
+
/** Additional props passed to the tooltip. */
|
|
26
|
+
tooltipProps?: any;
|
|
27
|
+
/** A custom suffix to apply to a "default" variant tooltip. */
|
|
28
|
+
suffix?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface TimestampProps extends React.HTMLProps<HTMLSpanElement> {
|
|
32
|
+
/** Displays custom content inside the timestamp, such as a relative time. This prop will
|
|
33
|
+
* override the default content that is displayed. Custom content will not be affected by
|
|
34
|
+
* any props that format or add to displayed content.
|
|
35
|
+
*/
|
|
36
|
+
children?: React.ReactNode;
|
|
37
|
+
/** Class to add to the outer span. */
|
|
38
|
+
className?: string;
|
|
39
|
+
/** Applies custom formatting to the displayed date and/or time. Passing this prop in will
|
|
40
|
+
* override the dateFormat and timeFormat props.
|
|
41
|
+
*/
|
|
42
|
+
customFormat?: { [key: string]: string };
|
|
43
|
+
/** Determines the default content that is displayed inside the timestamp and the value of
|
|
44
|
+
* the inner time element's datetime attribute. */
|
|
45
|
+
date?: Date;
|
|
46
|
+
/** Determines the format of the displayed date in the timestamp and UTC tooltip. Examples:
|
|
47
|
+
* "Full" => Tuesday, August 9, 2022;
|
|
48
|
+
* "Long" => August 9, 2022;
|
|
49
|
+
* "Medium" => Aug 9, 2022;
|
|
50
|
+
* "Short" => 8/9/22
|
|
51
|
+
*/
|
|
52
|
+
dateFormat?: 'full' | 'long' | 'medium' | 'short';
|
|
53
|
+
/** Applies a custom suffix to the displayed content, usually after the time, such as a
|
|
54
|
+
* custom time zone.
|
|
55
|
+
*/
|
|
56
|
+
displaySuffix?: string;
|
|
57
|
+
/** Flag for displaying the time in a 12 hour format. If this prop is not passed in,
|
|
58
|
+
* the hour format will be based on the locale prop's value.
|
|
59
|
+
*/
|
|
60
|
+
is12Hour?: boolean;
|
|
61
|
+
/** Determines which locale to use in the displayed content. Defaults to the current locale
|
|
62
|
+
* when this prop is not passed in. For more information about locale's:
|
|
63
|
+
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation
|
|
64
|
+
*/
|
|
65
|
+
locale?: string;
|
|
66
|
+
/** Determines the format of the displayed time in the timestamp and UTC tooltip. Examples:
|
|
67
|
+
* "Full" => 11:25:00 AM Eastern Daylight Time
|
|
68
|
+
* "Long" => 11:25:00 AM EDT
|
|
69
|
+
* "Medium" => 11:25:00 AM
|
|
70
|
+
* "Short" => 11:25 AM
|
|
71
|
+
*/
|
|
72
|
+
timeFormat?: 'full' | 'long' | 'medium' | 'short';
|
|
73
|
+
/** Adds a tooltip to the timestamp. */
|
|
74
|
+
tooltip?: TimestampTooltip;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export const Timestamp: React.FunctionComponent<TimestampProps> = ({
|
|
78
|
+
children,
|
|
79
|
+
className,
|
|
80
|
+
customFormat,
|
|
81
|
+
date: dateProp = new Date(),
|
|
82
|
+
dateFormat,
|
|
83
|
+
displaySuffix = '',
|
|
84
|
+
is12Hour,
|
|
85
|
+
locale,
|
|
86
|
+
timeFormat,
|
|
87
|
+
tooltip,
|
|
88
|
+
...props
|
|
89
|
+
}: TimestampProps) => {
|
|
90
|
+
const hasTimeFormat = timeFormat && !customFormat;
|
|
91
|
+
const formatOptions = {
|
|
92
|
+
...(dateFormat && !customFormat && { dateStyle: dateFormat }),
|
|
93
|
+
...(customFormat && { ...customFormat }),
|
|
94
|
+
...(is12Hour !== undefined && { hour12: is12Hour })
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const dateAsLocaleString = new Date(dateProp).toLocaleString(locale, {
|
|
98
|
+
...formatOptions,
|
|
99
|
+
...(hasTimeFormat && { timeStyle: timeFormat })
|
|
100
|
+
});
|
|
101
|
+
const defaultDisplay = `${dateAsLocaleString}${displaySuffix ? ' ' + displaySuffix : ''}`;
|
|
102
|
+
|
|
103
|
+
const utcTimeFormat = timeFormat !== 'short' ? 'medium' : 'short';
|
|
104
|
+
const convertToUTCString = (date: Date) => new Date(date).toUTCString().slice(0, -3);
|
|
105
|
+
const utcDateString = new Date(convertToUTCString(dateProp)).toLocaleString(locale, {
|
|
106
|
+
...formatOptions,
|
|
107
|
+
...(hasTimeFormat && { timeStyle: utcTimeFormat })
|
|
108
|
+
});
|
|
109
|
+
const defaultTooltipContent = `${utcDateString}${tooltip?.suffix ? ' ' + tooltip.suffix : ' UTC'}`;
|
|
110
|
+
|
|
111
|
+
const timestamp = (
|
|
112
|
+
<span
|
|
113
|
+
className={css(styles.timestamp, tooltip && styles.modifiers.helpText, className)}
|
|
114
|
+
{...(tooltip && { tabIndex: 0 })}
|
|
115
|
+
{...props}
|
|
116
|
+
>
|
|
117
|
+
<time className="pf-c-timestamp__text" dateTime={props.dateTime || new Date(dateProp).toISOString()}>
|
|
118
|
+
{!children ? defaultDisplay : children}
|
|
119
|
+
</time>
|
|
120
|
+
</span>
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
return tooltip ? (
|
|
124
|
+
<Tooltip
|
|
125
|
+
content={tooltip.variant === TimestampTooltipVariant.default ? defaultTooltipContent : tooltip.content}
|
|
126
|
+
{...tooltip.tooltipProps}
|
|
127
|
+
>
|
|
128
|
+
{timestamp}
|
|
129
|
+
</Tooltip>
|
|
130
|
+
) : (
|
|
131
|
+
timestamp
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
Timestamp.displayName = 'Timestamp';
|