@takaro/lib-components 0.4.3 → 0.4.6
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 +1 -1
- package/src/components/actions/Button/Button.stories.tsx +49 -33
- package/src/components/actions/Button/__snapshots__/Button.test.tsx.snap +1 -1
- package/src/components/actions/ContextMenu/ContextMenu.stories.tsx +1 -0
- package/src/components/actions/ContextMenu/index.tsx +3 -2
- package/src/components/actions/DropdownButton/DropdownButton.stories.tsx +7 -7
- package/src/components/actions/IconButton/__snapshots__/IconButton.test.tsx.snap +1 -1
- package/src/components/data/Drawer/Drawer.stories.tsx +7 -3
- package/src/components/data/Stats/Stat.tsx +104 -25
- package/src/components/data/Stats/Stats.stories.tsx +135 -11
- package/src/components/data/Stats/context.tsx +10 -3
- package/src/components/data/Stats/index.tsx +16 -9
- package/src/components/dialogs/Dialog/Dialog.stories.tsx +8 -4
- package/src/components/feedback/Alert/Alert.stories.tsx +7 -0
- package/src/components/feedback/Alert/__snapshots__/Alert.test.tsx.snap +6 -4
- package/src/components/feedback/Alert/index.tsx +24 -14
- package/src/components/feedback/Alert/style.ts +23 -15
- package/src/components/feedback/Tooltip/Tooltip.stories.tsx +1 -1
- package/src/components/feedback/snacks/Default/default.stories.tsx +6 -5
- package/src/components/feedback/snacks/Drawer/Drawer.stories.tsx +1 -1
- package/src/components/inputs/CheckBox/CheckBox.stories.tsx +1 -1
- package/src/components/inputs/CodeField/CodeField.stories.tsx +1 -1
- package/src/components/inputs/Date/DatePicker/DatePicker.stories.tsx +6 -6
- package/src/components/inputs/FileField/FileField.stories.tsx +3 -4
- package/src/components/inputs/RadioGroup/RadioGroup.stories.tsx +1 -1
- package/src/components/inputs/Switch/Switch.stories.tsx +1 -1
- package/src/components/inputs/TagField/TagField.stories.tsx +1 -1
- package/src/components/inputs/TextAreaField/TextAreaField.stories.tsx +3 -1
- package/src/components/inputs/TextField/TextField.stories.tsx +3 -1
- package/src/components/inputs/ValueConfirmationField/ValueConfirmationField.stories.tsx +1 -1
- package/src/components/inputs/selects/SelectField/SelectField.stories.tsx +2 -2
- package/src/components/inputs/selects/SelectQueryField/SelectQueryField.stories.tsx +3 -3
- package/src/components/navigation/Steppers/SlimStepper/Stepper.stories.tsx +14 -14
- package/src/components/navigation/Steppers/Stepper/Stepper.stories.tsx +8 -8
- package/src/components/other/ActionMenu/ActionMenu.stories.tsx +0 -4
- package/src/components/other/Empty/Empty.stories.tsx +5 -1
- package/src/components/other/PermissionsGuard/PermissionsGuard.stories.tsx +3 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@takaro/lib-components",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Takaro UI is a simple and customizable component library to build React apps faster within the Takaro eco system",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|
|
@@ -25,7 +25,7 @@ export default {
|
|
|
25
25
|
decorators: [(story) => <Wrapper>{story()}</Wrapper>],
|
|
26
26
|
args: {
|
|
27
27
|
size: 'medium',
|
|
28
|
-
|
|
28
|
+
children: 'basic button',
|
|
29
29
|
variant: 'default',
|
|
30
30
|
type: 'button',
|
|
31
31
|
disabled: false,
|
|
@@ -44,127 +44,143 @@ export const Examples = () => (
|
|
|
44
44
|
onClick={() => {
|
|
45
45
|
/* */
|
|
46
46
|
}}
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
>
|
|
48
|
+
Default Button
|
|
49
|
+
</Button>
|
|
49
50
|
<Button
|
|
50
51
|
icon={<Icon size={20} />}
|
|
51
52
|
onClick={() => {
|
|
52
53
|
/* */
|
|
53
54
|
}}
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
>
|
|
56
|
+
Icon Button
|
|
57
|
+
</Button>
|
|
56
58
|
<Button
|
|
57
59
|
disabled
|
|
58
60
|
onClick={() => {
|
|
59
61
|
/* */
|
|
60
62
|
}}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
>
|
|
64
|
+
Disabled Button
|
|
65
|
+
</Button>
|
|
63
66
|
<Button
|
|
64
67
|
isLoading
|
|
65
68
|
onClick={() => {
|
|
66
69
|
/* */
|
|
67
70
|
}}
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
>
|
|
72
|
+
Loading Button
|
|
73
|
+
</Button>
|
|
70
74
|
|
|
71
75
|
{/* Outline */}
|
|
72
76
|
<Button
|
|
73
77
|
onClick={() => {
|
|
74
78
|
/* */
|
|
75
79
|
}}
|
|
76
|
-
text="Outlined Button"
|
|
77
80
|
variant="outline"
|
|
78
|
-
|
|
81
|
+
>
|
|
82
|
+
Outlined Button
|
|
83
|
+
</Button>
|
|
79
84
|
<Button
|
|
80
85
|
icon={<Icon size={20} />}
|
|
81
86
|
onClick={() => {
|
|
82
87
|
/* */
|
|
83
88
|
}}
|
|
84
|
-
text="Icon Button"
|
|
85
89
|
variant="outline"
|
|
86
|
-
|
|
90
|
+
>
|
|
91
|
+
Icon Button
|
|
92
|
+
</Button>
|
|
87
93
|
<Button
|
|
88
94
|
disabled
|
|
89
95
|
onClick={() => {
|
|
90
96
|
/* */
|
|
91
97
|
}}
|
|
92
|
-
text="Disabled Button"
|
|
93
98
|
variant="outline"
|
|
94
|
-
|
|
99
|
+
>
|
|
100
|
+
Disabled Button
|
|
101
|
+
</Button>
|
|
95
102
|
<Button
|
|
96
103
|
isLoading
|
|
97
104
|
onClick={() => {
|
|
98
105
|
/* */
|
|
99
106
|
}}
|
|
100
|
-
text="Loading Button"
|
|
101
107
|
variant="outline"
|
|
102
|
-
|
|
108
|
+
>
|
|
109
|
+
Loading Button
|
|
110
|
+
</Button>
|
|
103
111
|
|
|
104
112
|
{/* Clear */}
|
|
105
113
|
<Button
|
|
106
114
|
onClick={() => {
|
|
107
115
|
/* */
|
|
108
116
|
}}
|
|
109
|
-
text="Clear Button"
|
|
110
117
|
variant="clear"
|
|
111
|
-
|
|
118
|
+
>
|
|
119
|
+
Clear Button
|
|
120
|
+
</Button>
|
|
112
121
|
<Button
|
|
113
122
|
icon={<Icon size={20} />}
|
|
114
123
|
onClick={() => {
|
|
115
124
|
/* */
|
|
116
125
|
}}
|
|
117
|
-
text="Icon Button"
|
|
118
126
|
variant="clear"
|
|
119
|
-
|
|
127
|
+
>
|
|
128
|
+
Icon Button
|
|
129
|
+
</Button>
|
|
120
130
|
<Button
|
|
121
131
|
disabled
|
|
122
132
|
onClick={() => {
|
|
123
133
|
/* */
|
|
124
134
|
}}
|
|
125
|
-
text="Disabled Button"
|
|
126
135
|
variant="clear"
|
|
127
|
-
|
|
136
|
+
>
|
|
137
|
+
Disabled Button
|
|
138
|
+
</Button>
|
|
128
139
|
<Button
|
|
129
140
|
isLoading
|
|
130
141
|
onClick={() => {
|
|
131
142
|
/* */
|
|
132
143
|
}}
|
|
133
|
-
text="Loading Button"
|
|
134
144
|
variant="clear"
|
|
135
|
-
|
|
145
|
+
>
|
|
146
|
+
Loading Button
|
|
147
|
+
</Button>
|
|
136
148
|
|
|
137
149
|
{/* white */}
|
|
138
150
|
<Button
|
|
139
151
|
onClick={() => {
|
|
140
152
|
/* */
|
|
141
153
|
}}
|
|
142
|
-
text="White Button"
|
|
143
154
|
variant="white"
|
|
144
|
-
|
|
155
|
+
>
|
|
156
|
+
White Button
|
|
157
|
+
</Button>
|
|
145
158
|
<Button
|
|
146
159
|
icon={<Icon size={20} />}
|
|
147
160
|
onClick={() => {
|
|
148
161
|
/* */
|
|
149
162
|
}}
|
|
150
|
-
text="Icon Button"
|
|
151
163
|
variant="white"
|
|
152
|
-
|
|
164
|
+
>
|
|
165
|
+
Icon Button
|
|
166
|
+
</Button>
|
|
153
167
|
<Button
|
|
154
168
|
disabled
|
|
155
169
|
onClick={() => {
|
|
156
170
|
/* */
|
|
157
171
|
}}
|
|
158
|
-
text="Disabled Button"
|
|
159
172
|
variant="white"
|
|
160
|
-
|
|
173
|
+
>
|
|
174
|
+
Disabled Button
|
|
175
|
+
</Button>
|
|
161
176
|
<Button
|
|
162
177
|
isLoading
|
|
163
178
|
onClick={() => {
|
|
164
179
|
/* */
|
|
165
180
|
}}
|
|
166
|
-
text="Loading Button"
|
|
167
181
|
variant="white"
|
|
168
|
-
|
|
182
|
+
>
|
|
183
|
+
Loading Button
|
|
184
|
+
</Button>
|
|
169
185
|
</>
|
|
170
186
|
);
|
|
@@ -30,6 +30,7 @@ export const Target: StoryFn<ContextMenuProps> = () => {
|
|
|
30
30
|
|
|
31
31
|
return (
|
|
32
32
|
<Container ref={targetRef}>
|
|
33
|
+
The context menu has a targetRef prop, so it is only triggered on the orange box.
|
|
33
34
|
<ContextMenu targetRef={targetRef}>
|
|
34
35
|
<ContextMenu.Item label="Item 1" />
|
|
35
36
|
<ContextMenu.Item label="Item 2" />
|
|
@@ -95,7 +95,8 @@ export const ContextMenu: FC<ContextMenuProps> & SubComponentTypes = ({ children
|
|
|
95
95
|
let timeout: number;
|
|
96
96
|
|
|
97
97
|
function onContextMenu(e: MouseEvent) {
|
|
98
|
-
|
|
98
|
+
const shouldShowMenu = !targetRef?.current || targetRef.current.contains(e.target as Node);
|
|
99
|
+
if (shouldShowMenu) {
|
|
99
100
|
e.preventDefault();
|
|
100
101
|
refs.setPositionReference({
|
|
101
102
|
getBoundingClientRect() {
|
|
@@ -146,7 +147,7 @@ export const ContextMenu: FC<ContextMenuProps> & SubComponentTypes = ({ children
|
|
|
146
147
|
}
|
|
147
148
|
clearTimeout(timeout);
|
|
148
149
|
};
|
|
149
|
-
}, [refs]);
|
|
150
|
+
}, [refs, targetRef]);
|
|
150
151
|
|
|
151
152
|
return (
|
|
152
153
|
<FloatingPortal>
|
|
@@ -26,34 +26,34 @@ export const Default: StoryFn<DropdownButtonProps> = () => {
|
|
|
26
26
|
<>
|
|
27
27
|
<DropdownButton>
|
|
28
28
|
<Action
|
|
29
|
+
text="Save changes"
|
|
29
30
|
onClick={() => {
|
|
30
31
|
setMessage('save changes event fired');
|
|
31
32
|
}}
|
|
32
|
-
text="Save changes"
|
|
33
33
|
>
|
|
34
34
|
Save changes
|
|
35
35
|
</Action>
|
|
36
36
|
<Action
|
|
37
|
+
text="Save and Schedule"
|
|
37
38
|
onClick={() => {
|
|
38
39
|
setMessage('Save and schedule event fired');
|
|
39
40
|
}}
|
|
40
|
-
text="Save and schedule"
|
|
41
41
|
>
|
|
42
42
|
Save and schedule
|
|
43
43
|
</Action>
|
|
44
44
|
<Action
|
|
45
|
+
text="Save and publish documen"
|
|
45
46
|
onClick={() => {
|
|
46
47
|
setMessage('save and published fired');
|
|
47
48
|
}}
|
|
48
|
-
text="Save and publish"
|
|
49
49
|
>
|
|
50
50
|
Save and publish
|
|
51
51
|
</Action>
|
|
52
52
|
<Action
|
|
53
|
+
text="Export PDF"
|
|
53
54
|
onClick={() => {
|
|
54
55
|
setMessage('Export PDF event fired');
|
|
55
56
|
}}
|
|
56
|
-
text="Export PDF"
|
|
57
57
|
>
|
|
58
58
|
Export PDF
|
|
59
59
|
</Action>
|
|
@@ -69,15 +69,15 @@ export const Description: StoryFn<DropdownButtonProps> = () => {
|
|
|
69
69
|
return (
|
|
70
70
|
<>
|
|
71
71
|
<DropdownButton>
|
|
72
|
-
<Action onClick={() => setMessage('Merge pull request is fired')}
|
|
72
|
+
<Action text="Merge pull request" onClick={() => setMessage('Merge pull request is fired')}>
|
|
73
73
|
<h4>merge pull request</h4>
|
|
74
74
|
<p>All commits from this branch will be added to the base branchh via a merge commit.</p>
|
|
75
75
|
</Action>
|
|
76
|
-
<Action onClick={() => setMessage('Squash and merge is fired')}
|
|
76
|
+
<Action text="Squash and merge" onClick={() => setMessage('Squash and merge is fired')}>
|
|
77
77
|
<h4>Squash and merge</h4>
|
|
78
78
|
<p>The 4 commits from this branch will be combined into one commit in the base branch.</p>
|
|
79
79
|
</Action>
|
|
80
|
-
<Action onClick={() => setMessage('Rebase and merge is fired.')}
|
|
80
|
+
<Action text="Rebase and merge" onClick={() => setMessage('Rebase and merge is fired.')}>
|
|
81
81
|
<h4>Rebase and merge</h4>
|
|
82
82
|
<p>the 4 commits from this branch will be rebased and added to the base branch.</p>
|
|
83
83
|
</Action>
|
|
@@ -60,7 +60,7 @@ export const Default: StoryFn<DrawerOptions> = ({ promptCloseConfirmation }) =>
|
|
|
60
60
|
|
|
61
61
|
return (
|
|
62
62
|
<>
|
|
63
|
-
<Button onClick={() => setOpen(true)}
|
|
63
|
+
<Button onClick={() => setOpen(true)}>Open drawer</Button>
|
|
64
64
|
<Drawer open={open} onOpenChange={setOpen} promptCloseConfirmation={promptCloseConfirmation}>
|
|
65
65
|
<Drawer.Content>
|
|
66
66
|
<Drawer.Heading>Product Details</Drawer.Heading>
|
|
@@ -140,8 +140,12 @@ export const Default: StoryFn<DrawerOptions> = ({ promptCloseConfirmation }) =>
|
|
|
140
140
|
</Drawer.Body>
|
|
141
141
|
<Drawer.Footer>
|
|
142
142
|
<ButtonContainer>
|
|
143
|
-
<Button
|
|
144
|
-
|
|
143
|
+
<Button onClick={() => setOpen(false)} color="background">
|
|
144
|
+
Cancel
|
|
145
|
+
</Button>
|
|
146
|
+
<Button fullWidth type="submit" form="myform">
|
|
147
|
+
Save changes
|
|
148
|
+
</Button>
|
|
145
149
|
</ButtonContainer>
|
|
146
150
|
</Drawer.Footer>
|
|
147
151
|
</Drawer.Content>
|
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
import { FC, useContext } from 'react';
|
|
1
|
+
import { FC, useContext, ReactNode, cloneElement, isValidElement } from 'react';
|
|
2
2
|
import { styled } from '../../../styled';
|
|
3
|
-
import { StatContext, Direction } from './context';
|
|
3
|
+
import { StatContext, Direction, Size } from './context';
|
|
4
|
+
import { AiOutlineArrowUp, AiOutlineArrowDown } from 'react-icons/ai';
|
|
4
5
|
|
|
5
|
-
const Container = styled.div<{
|
|
6
|
+
const Container = styled.div<{ isGrouped: boolean; direction: Direction; size: Size }>`
|
|
6
7
|
background-color: ${({ theme }) => theme.colors.backgroundAlt};
|
|
7
|
-
padding: ${({ theme }) =>
|
|
8
|
+
padding: ${({ theme, size }) => {
|
|
9
|
+
switch (size) {
|
|
10
|
+
case 'small':
|
|
11
|
+
return theme.spacing['1'];
|
|
12
|
+
case 'medium':
|
|
13
|
+
return theme.spacing['2'];
|
|
14
|
+
case 'large':
|
|
15
|
+
return theme.spacing['3'];
|
|
16
|
+
}
|
|
17
|
+
}};
|
|
8
18
|
|
|
9
|
-
${({
|
|
10
|
-
if (
|
|
19
|
+
${({ isGrouped, direction, theme }) => {
|
|
20
|
+
if (isGrouped) {
|
|
11
21
|
if (direction === 'vertical') {
|
|
12
22
|
return `
|
|
13
23
|
&:not(:last-child) {
|
|
@@ -22,7 +32,7 @@ const Container = styled.div<{ hasBorder: boolean; direction: Direction }>`
|
|
|
22
32
|
border-bottom-right-radius: ${theme.borderRadius.medium};
|
|
23
33
|
}
|
|
24
34
|
`;
|
|
25
|
-
} else
|
|
35
|
+
} else {
|
|
26
36
|
return `
|
|
27
37
|
&:not(:last-child) {
|
|
28
38
|
border-right: 1px solid ${theme.colors.secondary};
|
|
@@ -46,18 +56,39 @@ const Container = styled.div<{ hasBorder: boolean; direction: Direction }>`
|
|
|
46
56
|
}};
|
|
47
57
|
|
|
48
58
|
dt {
|
|
49
|
-
font-size: ${({ theme }) =>
|
|
50
|
-
|
|
59
|
+
font-size: ${({ theme, size }) => {
|
|
60
|
+
switch (size) {
|
|
61
|
+
case 'small':
|
|
62
|
+
return theme.fontSize.small;
|
|
63
|
+
case 'medium':
|
|
64
|
+
return theme.fontSize.medium;
|
|
65
|
+
case 'large':
|
|
66
|
+
return theme.fontSize.mediumLarge;
|
|
67
|
+
}
|
|
68
|
+
}};
|
|
69
|
+
color: ${({ theme }) => theme.colors.secondary};
|
|
51
70
|
margin-bottom: ${({ theme }) => theme.spacing['0_5']};
|
|
52
71
|
}
|
|
53
72
|
|
|
54
73
|
dd {
|
|
55
74
|
font-weight: bold;
|
|
56
75
|
color: ${({ theme }) => theme.colors.white};
|
|
57
|
-
font-size: ${({ theme }) =>
|
|
76
|
+
font-size: ${({ theme, size }) => {
|
|
77
|
+
switch (size) {
|
|
78
|
+
case 'small':
|
|
79
|
+
return theme.fontSize.medium;
|
|
80
|
+
case 'medium':
|
|
81
|
+
return theme.fontSize.mediumLarge;
|
|
82
|
+
case 'large':
|
|
83
|
+
return theme.fontSize.large;
|
|
84
|
+
}
|
|
85
|
+
}};
|
|
58
86
|
letter-spacing: 1px;
|
|
59
87
|
margin: 0;
|
|
60
88
|
padding: 0;
|
|
89
|
+
display: flex;
|
|
90
|
+
align-items: center;
|
|
91
|
+
gap: ${({ theme }) => theme.spacing['1']};
|
|
61
92
|
|
|
62
93
|
&.placeholder {
|
|
63
94
|
min-width: 80%;
|
|
@@ -66,34 +97,82 @@ const Container = styled.div<{ hasBorder: boolean; direction: Direction }>`
|
|
|
66
97
|
}
|
|
67
98
|
`;
|
|
68
99
|
|
|
100
|
+
const TrendContainer = styled.span<{ direction: 'up' | 'down' }>`
|
|
101
|
+
display: inline-flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
gap: ${({ theme }) => theme.spacing['0_5']};
|
|
104
|
+
font-size: ${({ theme }) => theme.fontSize.small};
|
|
105
|
+
font-weight: normal;
|
|
106
|
+
color: ${({ theme, direction }) => (direction === 'up' ? theme.colors.success : theme.colors.error)};
|
|
107
|
+
`;
|
|
108
|
+
|
|
109
|
+
const IconWrapper = styled.span`
|
|
110
|
+
display: inline-flex;
|
|
111
|
+
align-items: center;
|
|
112
|
+
margin-right: ${({ theme }) => theme.spacing['0_5']};
|
|
113
|
+
`;
|
|
114
|
+
|
|
115
|
+
export interface TrendConfig {
|
|
116
|
+
direction: 'up' | 'down';
|
|
117
|
+
value: string | number;
|
|
118
|
+
}
|
|
119
|
+
|
|
69
120
|
export interface StatProps {
|
|
70
121
|
description: string;
|
|
71
|
-
value: string;
|
|
72
|
-
|
|
73
|
-
|
|
122
|
+
value: string | number | ReactNode;
|
|
123
|
+
icon?: ReactNode;
|
|
124
|
+
trend?: TrendConfig;
|
|
74
125
|
isLoading?: boolean;
|
|
126
|
+
size?: Size;
|
|
75
127
|
}
|
|
76
128
|
|
|
77
|
-
export const Stat: FC<StatProps> = ({ description, value, isLoading }) => {
|
|
78
|
-
const {
|
|
129
|
+
export const Stat: FC<StatProps> = ({ description, value, icon, trend, isLoading, size: propSize }) => {
|
|
130
|
+
const { grouped, direction, size: contextSize } = useContext(StatContext);
|
|
131
|
+
const size = propSize ?? contextSize;
|
|
132
|
+
|
|
133
|
+
const renderValue = () => {
|
|
134
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
135
|
+
return value.toString();
|
|
136
|
+
}
|
|
137
|
+
return value;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const renderIcon = () => {
|
|
141
|
+
if (!icon) return null;
|
|
142
|
+
if (isValidElement(icon)) {
|
|
143
|
+
return <IconWrapper>{cloneElement(icon, { size: 20 } as any)}</IconWrapper>;
|
|
144
|
+
}
|
|
145
|
+
return <IconWrapper>{icon}</IconWrapper>;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const renderTrend = () => {
|
|
149
|
+
if (!trend) return null;
|
|
150
|
+
const TrendIcon = trend.direction === 'up' ? AiOutlineArrowUp : AiOutlineArrowDown;
|
|
151
|
+
return (
|
|
152
|
+
<TrendContainer direction={trend.direction}>
|
|
153
|
+
<TrendIcon size={14} />
|
|
154
|
+
{trend.value}
|
|
155
|
+
</TrendContainer>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
79
158
|
|
|
80
159
|
if (isLoading) {
|
|
81
160
|
return (
|
|
82
|
-
<Container
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
<dd className="placeholder"></dd>
|
|
86
|
-
</div>
|
|
161
|
+
<Container isGrouped={grouped} direction={direction} size={size} aria-busy="true" aria-label="Loading">
|
|
162
|
+
<dt>{description}</dt>
|
|
163
|
+
<dd className="placeholder"></dd>
|
|
87
164
|
</Container>
|
|
88
165
|
);
|
|
89
166
|
}
|
|
90
167
|
|
|
91
168
|
return (
|
|
92
|
-
<Container
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
169
|
+
<Container isGrouped={grouped} direction={direction} size={size}>
|
|
170
|
+
<dt>{description}</dt>
|
|
171
|
+
<dd>
|
|
172
|
+
{renderIcon()}
|
|
173
|
+
{renderValue()}
|
|
174
|
+
{renderTrend()}
|
|
175
|
+
</dd>
|
|
97
176
|
</Container>
|
|
98
177
|
);
|
|
99
178
|
};
|