akeneo-design-system 0.1.227 → 0.1.229
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/components/Avatar/Avatar.d.ts +1 -8
- package/lib/components/Avatar/Avatar.js +1 -1
- package/lib/components/Avatar/Avatar.js.map +1 -1
- package/lib/components/Avatar/Avatars.d.ts +2 -1
- package/lib/components/Avatar/Avatars.js +19 -3
- package/lib/components/Avatar/Avatars.js.map +1 -1
- package/lib/components/Avatar/types.d.ts +11 -0
- package/lib/components/Avatar/types.js +3 -0
- package/lib/components/Avatar/types.js.map +1 -0
- package/lib/components/Dropdown/Dropdown.d.ts +1 -0
- package/lib/components/Dropdown/Item/Item.js +1 -1
- package/lib/components/Dropdown/Item/Item.js.map +1 -1
- package/lib/components/Dropdown/Surtitle/Surtitle.d.ts +1 -0
- package/lib/components/Input/MultiSelectInput/ChipInput.d.ts +1 -0
- package/lib/components/Input/MultiSelectInput/ChipInput.js +9 -7
- package/lib/components/Input/MultiSelectInput/ChipInput.js.map +1 -1
- package/lib/components/Input/MultiSelectInput/MultiSelectInput.d.ts +2 -1
- package/lib/components/Input/MultiSelectInput/MultiSelectInput.js +4 -4
- package/lib/components/Input/MultiSelectInput/MultiSelectInput.js.map +1 -1
- package/lib/components/KeyFigure/KeyFigure.js +1 -1
- package/lib/components/KeyFigure/KeyFigure.js.map +1 -1
- package/lib/components/Navigation/SubNavigationPanel/SubNavigationPanel.d.ts +2 -0
- package/lib/components/Navigation/SubNavigationPanel/SubNavigationPanel.js +28 -40
- package/lib/components/Navigation/SubNavigationPanel/SubNavigationPanel.js.map +1 -1
- package/lib/components/ProgressBar/ProgressBar.js +3 -3
- package/lib/components/ProgressBar/ProgressBar.js.map +1 -1
- package/lib/components/Tooltip/Tooltip.d.ts +4 -1
- package/lib/components/Tooltip/Tooltip.js +3 -1
- package/lib/components/Tooltip/Tooltip.js.map +1 -1
- package/package.json +1 -1
- package/src/__image_snapshots__/all-visual-tsx-visual-tests-renders-components-inputs-multi-select-input-locked-values-correctly-1-snap.png +0 -0
- package/src/__image_snapshots__/all-visual-tsx-visual-tests-renders-components-navigation-sub-navigation-panel-content-with-collapse-component-correctly-1-snap.png +0 -0
- package/src/__image_snapshots__/all-visual-tsx-visual-tests-renders-components-navigation-sub-navigation-panel-content-without-padding-correctly-1-snap.png +0 -0
- package/src/__image_snapshots__/all-visual-tsx-visual-tests-renders-components-navigation-sub-navigation-panel-scrollable-content-correctly-1-snap.png +0 -0
- package/src/__image_snapshots__/all-visual-tsx-visual-tests-renders-components-progress-bar-width-correctly-1-snap.png +0 -0
- package/src/__image_snapshots__/all-visual-tsx-visual-tests-renders-components-tooltip-with-title-correctly-1-snap.png +0 -0
- package/src/components/Avatar/Avatar.stories.mdx +1 -1
- package/src/components/Avatar/Avatar.tsx +2 -32
- package/src/components/Avatar/Avatars.tsx +27 -5
- package/src/components/Avatar/Avatars.unit.tsx +22 -2
- package/src/components/Avatar/types.ts +34 -0
- package/src/components/Dropdown/Item/Item.tsx +1 -0
- package/src/components/Dropdown/Surtitle/Surtitle.tsx +1 -1
- package/src/components/Input/MultiSelectInput/ChipInput.tsx +14 -4
- package/src/components/Input/MultiSelectInput/MultiSelectInput.stories.mdx +24 -0
- package/src/components/Input/MultiSelectInput/MultiSelectInput.tsx +7 -0
- package/src/components/Input/MultiSelectInput/MultiSelectInput.unit.tsx +20 -0
- package/src/components/KeyFigure/KeyFigure.stories.mdx +5 -1
- package/src/components/KeyFigure/KeyFigure.tsx +2 -0
- package/src/components/Navigation/SubNavigationPanel/SubNavigationPanel.stories.mdx +97 -25
- package/src/components/Navigation/SubNavigationPanel/SubNavigationPanel.tsx +58 -66
- package/src/components/Navigation/SubNavigationPanel/SubNavigationPanel.unit.tsx +3 -3
- package/src/components/ProgressBar/ProgressBar.tsx +1 -17
- package/src/components/Tooltip/Tooltip.stories.mdx +15 -0
- package/src/components/Tooltip/Tooltip.tsx +9 -1
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"names":[],"mappings":"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
|
1
|
+
{"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import React, {useMemo} from 'react';
|
2
2
|
import styled, {css} from 'styled-components';
|
3
3
|
import {useTheme} from '../../hooks';
|
4
|
-
import {Override} from '../../shared';
|
5
4
|
import {AkeneoThemedProps, getColor} from '../../theme';
|
5
|
+
import {AvatarProps} from './types';
|
6
6
|
|
7
7
|
const AvatarContainer = styled.span<AvatarProps & AkeneoThemedProps>`
|
8
8
|
${({size}) =>
|
@@ -31,43 +31,13 @@ const AvatarContainer = styled.span<AvatarProps & AkeneoThemedProps>`
|
|
31
31
|
cursor: ${({onClick}) => (onClick ? 'pointer' : 'default')};
|
32
32
|
`;
|
33
33
|
|
34
|
-
type AvatarProps = Override<
|
35
|
-
React.HTMLAttributes<HTMLSpanElement>,
|
36
|
-
{
|
37
|
-
/**
|
38
|
-
* Username to use as fallback if the avatar is not provided and the Firstname and Lastname are empty.
|
39
|
-
*/
|
40
|
-
username: string;
|
41
|
-
|
42
|
-
/**
|
43
|
-
* Firstname to use as fallback with the Lastname if the avatar is not provided.
|
44
|
-
*/
|
45
|
-
firstName: string;
|
46
|
-
|
47
|
-
/**
|
48
|
-
* Lastname to use as fallback with the Firstname if the avatar is not provided.
|
49
|
-
*/
|
50
|
-
lastName: string;
|
51
|
-
|
52
|
-
/**
|
53
|
-
* Url of the avatar image.
|
54
|
-
*/
|
55
|
-
avatarUrl?: string;
|
56
|
-
|
57
|
-
/**
|
58
|
-
* Size of the avatar.
|
59
|
-
*/
|
60
|
-
size?: 'default' | 'big';
|
61
|
-
}
|
62
|
-
>;
|
63
|
-
|
64
34
|
const Avatar = ({username, firstName, lastName, avatarUrl, size = 'default', ...rest}: AvatarProps) => {
|
65
35
|
const theme = useTheme();
|
66
36
|
|
67
37
|
const fallback = (
|
68
38
|
firstName.trim().charAt(0) + lastName.trim().charAt(0) || username.substring(0, 2)
|
69
39
|
).toLocaleUpperCase();
|
70
|
-
const title = `${firstName} ${lastName}`.trim() || username;
|
40
|
+
const title = `${firstName || ''} ${lastName || ''}`.trim() || username;
|
71
41
|
|
72
42
|
const backgroundColor = useMemo(() => {
|
73
43
|
const colorId = username.split('').reduce<number>((s, l) => s + l.charCodeAt(0), 0);
|
@@ -1,7 +1,8 @@
|
|
1
|
-
import React, {Children} from 'react';
|
1
|
+
import React, {Children, useMemo} from 'react';
|
2
2
|
import styled from 'styled-components';
|
3
3
|
import {Override} from '../../shared';
|
4
4
|
import {AkeneoThemedProps, getColor} from '../../theme';
|
5
|
+
import {AvatarProps} from './types';
|
5
6
|
|
6
7
|
const AvatarListContainer = styled.div<AvatarsProps & AkeneoThemedProps>`
|
7
8
|
display: flex;
|
@@ -16,10 +17,11 @@ const AvatarListContainer = styled.div<AvatarsProps & AkeneoThemedProps>`
|
|
16
17
|
const RemainingAvatar = styled.span`
|
17
18
|
height: 32px;
|
18
19
|
width: 32px;
|
19
|
-
display: inline-block;
|
20
20
|
border: 1px solid ${getColor('grey', 10)};
|
21
21
|
line-height: 32px;
|
22
|
-
|
22
|
+
display: flex;
|
23
|
+
align-items: center;
|
24
|
+
justify-content: center;
|
23
25
|
font-size: 15px;
|
24
26
|
border-radius: 32px;
|
25
27
|
background-color: ${getColor('white')};
|
@@ -29,17 +31,37 @@ type AvatarsProps = Override<
|
|
29
31
|
React.HTMLAttributes<HTMLDivElement>,
|
30
32
|
{
|
31
33
|
max: number;
|
34
|
+
maxTitle?: number;
|
32
35
|
}
|
33
36
|
>;
|
34
37
|
|
35
|
-
const Avatars = ({max, children, ...rest}
|
38
|
+
const Avatars: React.FC<AvatarsProps> = ({max, maxTitle = 10, children, ...rest}) => {
|
36
39
|
const childrenArray = Children.toArray(children);
|
37
40
|
const displayedChildren = childrenArray.slice(0, max);
|
41
|
+
const remainingChildren = childrenArray.slice(max, childrenArray.length + 1);
|
38
42
|
const remainingChildrenCount = childrenArray.length - max;
|
39
43
|
const reverseChildren = displayedChildren.reverse();
|
40
44
|
|
45
|
+
const remainingUsersTitle = useMemo(() => {
|
46
|
+
const remainingNames = remainingChildren
|
47
|
+
.map(child => {
|
48
|
+
if (!React.isValidElement<AvatarProps>(child)) return;
|
49
|
+
const {firstName, lastName, username} = child.props;
|
50
|
+
|
51
|
+
return `${firstName || ''} ${lastName || ''}`.trim() || username;
|
52
|
+
})
|
53
|
+
.slice(0, maxTitle)
|
54
|
+
.join('\n');
|
55
|
+
|
56
|
+
if (remainingChildren.length > maxTitle) {
|
57
|
+
return remainingNames.concat('\n', '...');
|
58
|
+
}
|
59
|
+
|
60
|
+
return remainingNames;
|
61
|
+
}, [maxTitle, remainingChildren]);
|
62
|
+
|
41
63
|
return (
|
42
|
-
<AvatarListContainer {...rest}>
|
64
|
+
<AvatarListContainer title={rest.title || remainingUsersTitle} {...rest}>
|
43
65
|
{remainingChildrenCount > 0 && <RemainingAvatar>+{remainingChildrenCount}</RemainingAvatar>}
|
44
66
|
{reverseChildren}
|
45
67
|
</AvatarListContainer>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import {render, screen} from '../../storybook/test-util';
|
2
|
+
import {fireEvent, render, screen} from '../../storybook/test-util';
|
3
3
|
import {Avatar} from './Avatar';
|
4
4
|
import {Avatars} from './Avatars';
|
5
5
|
|
@@ -24,7 +24,7 @@ test('renders a maximum number of avatars', () => {
|
|
24
24
|
);
|
25
25
|
|
26
26
|
expect(screen.getByTitle('John Doe')).toBeInTheDocument();
|
27
|
-
expect(screen.
|
27
|
+
expect(screen.queryByText('LD')).not.toBeInTheDocument();
|
28
28
|
expect(screen.getByText('+1')).toBeInTheDocument();
|
29
29
|
});
|
30
30
|
|
@@ -39,3 +39,23 @@ test('supports ...rest props', () => {
|
|
39
39
|
|
40
40
|
expect(screen.getByTestId('my_value')).toBeInTheDocument();
|
41
41
|
});
|
42
|
+
|
43
|
+
test('displays remaining users names on plus hover', () => {
|
44
|
+
const invalidChild = 'I should not be in the title';
|
45
|
+
render(
|
46
|
+
<Avatars max={1} maxTitle={1}>
|
47
|
+
<Avatar username="dSchrute" firstName="Dwight" lastName="Schrute" />
|
48
|
+
<Avatar username="mscott" firstName=" " lastName=" " />
|
49
|
+
<Avatar username="kMalone" firstName="Kevin" lastName="Malone" />
|
50
|
+
{invalidChild}
|
51
|
+
</Avatars>
|
52
|
+
);
|
53
|
+
|
54
|
+
expect(screen.getByText('DS')).toBeInTheDocument();
|
55
|
+
expect(screen.getByText('+3')).toBeInTheDocument();
|
56
|
+
// Kevin Malone should not be visible as it should be part of the +1
|
57
|
+
expect(screen.queryByText('mscott')).not.toBeInTheDocument();
|
58
|
+
|
59
|
+
fireEvent.mouseOver(screen.getByText('+3'));
|
60
|
+
expect(screen.getByTitle('mscott ...')).toBeInTheDocument();
|
61
|
+
});
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import {Override} from '../../shared';
|
2
|
+
import React from 'react';
|
3
|
+
|
4
|
+
export type User = {
|
5
|
+
/**
|
6
|
+
* Username to use as fallback if the avatar is not provided and the Firstname and Lastname are empty.
|
7
|
+
*/
|
8
|
+
username: string;
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Firstname to use as fallback with the Lastname if the avatar is not provided.
|
12
|
+
*/
|
13
|
+
firstName: string;
|
14
|
+
|
15
|
+
/**
|
16
|
+
* Lastname to use as fallback with the Firstname if the avatar is not provided.
|
17
|
+
*/
|
18
|
+
lastName: string;
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Url of the avatar image.
|
22
|
+
*/
|
23
|
+
avatarUrl?: string;
|
24
|
+
};
|
25
|
+
|
26
|
+
export type AvatarProps = Override<
|
27
|
+
React.HTMLAttributes<HTMLSpanElement>,
|
28
|
+
User & {
|
29
|
+
/**
|
30
|
+
* Size of the avatar.
|
31
|
+
*/
|
32
|
+
size?: 'default' | 'big';
|
33
|
+
}
|
34
|
+
>;
|
@@ -19,7 +19,7 @@ const Title = styled.span`
|
|
19
19
|
text-overflow: ellipsis;
|
20
20
|
`;
|
21
21
|
|
22
|
-
type SurtitleProps = {label: string};
|
22
|
+
type SurtitleProps = {label: string; children?: React.ReactNode};
|
23
23
|
|
24
24
|
const Surtitle: React.FC<SurtitleProps> = ({label, children, ...rest}) => (
|
25
25
|
<SurtitleContainer {...rest}>
|
@@ -24,7 +24,9 @@ const Container = styled.ul<AkeneoThemedProps & {invalid: boolean}>`
|
|
24
24
|
}
|
25
25
|
`;
|
26
26
|
|
27
|
-
const Chip = styled.li<
|
27
|
+
const Chip = styled.li<
|
28
|
+
AkeneoThemedProps & {isSelected: boolean; readOnly: boolean; isErrored: boolean; isLocked: boolean}
|
29
|
+
>`
|
28
30
|
list-style-type: none;
|
29
31
|
padding: 3px 15px;
|
30
32
|
padding-left: ${({readOnly}) => (readOnly ? '15px' : '4px')};
|
@@ -35,8 +37,8 @@ const Chip = styled.li<AkeneoThemedProps & {isSelected: boolean; readOnly: boole
|
|
35
37
|
align-items: center;
|
36
38
|
height: 30px;
|
37
39
|
box-sizing: border-box;
|
38
|
-
color: ${({readOnly, isErrored}) =>
|
39
|
-
isErrored ? getColor('red', 100) : readOnly ? getColor('grey', 100) : getColor('grey', 140)};
|
40
|
+
color: ${({readOnly, isErrored, isLocked}) =>
|
41
|
+
isErrored ? getColor('red', 100) : readOnly || isLocked ? getColor('grey', 100) : getColor('grey', 140)};
|
40
42
|
`;
|
41
43
|
|
42
44
|
const Input = styled.input`
|
@@ -76,6 +78,10 @@ const ReadOnlyIcon = styled(LockIcon)`
|
|
76
78
|
color: ${getColor('grey', 100)};
|
77
79
|
`;
|
78
80
|
|
81
|
+
const LockedValueIcon = styled(LockIcon)`
|
82
|
+
padding-right: 5px;
|
83
|
+
`;
|
84
|
+
|
79
85
|
const RemoveButton = styled(IconButton)<AkeneoThemedProps & {isErrored: boolean}>`
|
80
86
|
background-color: transparent;
|
81
87
|
margin-left: -3px;
|
@@ -100,6 +106,7 @@ type ChipInputProps = {
|
|
100
106
|
onRemove: (chipCode: string) => void;
|
101
107
|
onSearchChange: (searchValue: string) => void;
|
102
108
|
onFocus?: () => void;
|
109
|
+
lockedValues?: string[];
|
103
110
|
};
|
104
111
|
|
105
112
|
const ChipInput = React.forwardRef<HTMLInputElement, ChipInputProps>(
|
@@ -116,6 +123,7 @@ const ChipInput = React.forwardRef<HTMLInputElement, ChipInputProps>(
|
|
116
123
|
onRemove,
|
117
124
|
onSearchChange,
|
118
125
|
onFocus,
|
126
|
+
lockedValues,
|
119
127
|
}: ChipInputProps,
|
120
128
|
forwardedRef: Ref<HTMLInputElement>
|
121
129
|
) => {
|
@@ -148,10 +156,11 @@ const ChipInput = React.forwardRef<HTMLInputElement, ChipInputProps>(
|
|
148
156
|
<Chip
|
149
157
|
key={chip.code}
|
150
158
|
readOnly={readOnly}
|
159
|
+
isLocked={lockedValues?.includes(chip.code)}
|
151
160
|
isErrored={invalidValue.includes(chip.code)}
|
152
161
|
isSelected={index === value.length - 1 && isLastSelected}
|
153
162
|
>
|
154
|
-
{!readOnly && (
|
163
|
+
{!readOnly && !lockedValues?.includes(chip.code) && (
|
155
164
|
<RemoveButton
|
156
165
|
title={removeLabel}
|
157
166
|
ghost="borderless"
|
@@ -162,6 +171,7 @@ const ChipInput = React.forwardRef<HTMLInputElement, ChipInputProps>(
|
|
162
171
|
isErrored={invalidValue.includes(chip.code)}
|
163
172
|
/>
|
164
173
|
)}
|
174
|
+
{lockedValues?.includes(chip.code) && <LockedValueIcon size={16} />}
|
165
175
|
{chip.label}
|
166
176
|
</Chip>
|
167
177
|
))}
|
@@ -102,6 +102,30 @@ The placeholder text provides tips or examples of items to enter. Placeholder te
|
|
102
102
|
</Story>
|
103
103
|
</Canvas>
|
104
104
|
|
105
|
+
## Variation on locked values
|
106
|
+
|
107
|
+
<Canvas>
|
108
|
+
<Story name="LockedValues">
|
109
|
+
{args => {
|
110
|
+
const [value, setValue] = useState(['en_US', 'fr_FR', 'de_DE']);
|
111
|
+
return (
|
112
|
+
<MultiSelectInput
|
113
|
+
value={value}
|
114
|
+
placeholder="Placeholder"
|
115
|
+
emptyResultLabel="No match found"
|
116
|
+
lockedValues={['en_US', 'fr_FR']}
|
117
|
+
onChange={setValue}
|
118
|
+
>
|
119
|
+
<MultiSelectInput.Option value="en_US">English (United States)</MultiSelectInput.Option>
|
120
|
+
<MultiSelectInput.Option value="fr_FR">French (France)</MultiSelectInput.Option>
|
121
|
+
<MultiSelectInput.Option value="de_DE">German (Germany)</MultiSelectInput.Option>
|
122
|
+
<MultiSelectInput.Option value="es_ES">Spanish (Spain)</MultiSelectInput.Option>
|
123
|
+
</MultiSelectInput>
|
124
|
+
);
|
125
|
+
}}
|
126
|
+
</Story>
|
127
|
+
</Canvas>
|
128
|
+
|
105
129
|
## Variation on invalid
|
106
130
|
|
107
131
|
<Canvas>
|
@@ -146,6 +146,11 @@ type MultiMultiSelectInputProps = Override<
|
|
146
146
|
*/
|
147
147
|
verticalPosition?: VerticalPosition;
|
148
148
|
|
149
|
+
/**
|
150
|
+
* Values that cannot be unselected
|
151
|
+
*/
|
152
|
+
lockedValues?: string[];
|
153
|
+
|
149
154
|
/**
|
150
155
|
* Callback called when the user hit enter on the field.
|
151
156
|
*/
|
@@ -191,6 +196,7 @@ const MultiSelectInput = ({
|
|
191
196
|
onNextPage,
|
192
197
|
onSearchChange,
|
193
198
|
disableInternalSearch = false,
|
199
|
+
lockedValues = [],
|
194
200
|
'aria-labelledby': ariaLabelledby,
|
195
201
|
...rest
|
196
202
|
}: MultiMultiSelectInputProps) => {
|
@@ -289,6 +295,7 @@ const MultiSelectInput = ({
|
|
289
295
|
onSearchChange={handleSearch}
|
290
296
|
onRemove={handleRemove}
|
291
297
|
onFocus={handleFocus}
|
298
|
+
lockedValues={lockedValues}
|
292
299
|
/>
|
293
300
|
{!readOnly && (
|
294
301
|
<ActionContainer>
|
@@ -326,6 +326,26 @@ test('MultiSelectInput supports ...rest props', () => {
|
|
326
326
|
expect(screen.getByTestId('my_value')).toBeInTheDocument();
|
327
327
|
});
|
328
328
|
|
329
|
+
test('MultiSelectInput supports locked values prop', () => {
|
330
|
+
const onChange = jest.fn();
|
331
|
+
render(
|
332
|
+
<MultiSelectInput
|
333
|
+
value={['fr_FR', 'en_US']}
|
334
|
+
data-testid="my_value"
|
335
|
+
removeLabel="Remove"
|
336
|
+
openLabel="Open"
|
337
|
+
emptyResultLabel="Empty result"
|
338
|
+
onChange={onChange}
|
339
|
+
lockedValues={['fr_FR']}
|
340
|
+
>
|
341
|
+
<MultiSelectInput.Option value="en_US">English</MultiSelectInput.Option>
|
342
|
+
<MultiSelectInput.Option value="fr_FR">French</MultiSelectInput.Option>
|
343
|
+
<MultiSelectInput.Option value="es_ES">Spanish</MultiSelectInput.Option>
|
344
|
+
</MultiSelectInput>
|
345
|
+
);
|
346
|
+
expect(screen.getByTestId('my_value')).toBeInTheDocument();
|
347
|
+
});
|
348
|
+
|
329
349
|
test('MultiSelectInput does not support duplicated options', () => {
|
330
350
|
const mockConsole = jest.spyOn(console, 'error').mockImplementation();
|
331
351
|
expect(() => {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import {Meta, Story, ArgsTable, Canvas} from '@storybook/addon-docs';
|
2
2
|
import {KeyFigure, KeyFigureGrid} from './KeyFigure';
|
3
3
|
import * as Icons from '../../icons';
|
4
|
+
import {Tooltip} from '../Tooltip/Tooltip';
|
4
5
|
|
5
6
|
<Meta
|
6
7
|
title="Components/KeyFigure"
|
@@ -71,7 +72,10 @@ Key figures are used in dashboards to illustrate metrics.
|
|
71
72
|
<KeyFigure.Figure>123</KeyFigure.Figure>
|
72
73
|
</KeyFigure>
|
73
74
|
<KeyFigure icon={React.createElement(Icons[args.icon])} title="Key figure 3">
|
74
|
-
<KeyFigure.Figure>
|
75
|
+
<KeyFigure.Figure>
|
76
|
+
456
|
77
|
+
<Tooltip iconSize={16}>More informations on this figure</Tooltip>
|
78
|
+
</KeyFigure.Figure>
|
75
79
|
</KeyFigure>
|
76
80
|
<KeyFigure icon={React.createElement(Icons[args.icon])} title="Key figure 4">
|
77
81
|
<KeyFigure.Figure label="Average:">789454</KeyFigure.Figure>
|
@@ -1,10 +1,12 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
import {
|
7
|
-
import {
|
1
|
+
import {Meta, Story, ArgsTable, Canvas} from '@storybook/addon-docs';
|
2
|
+
import {SubNavigationPanel} from './SubNavigationPanel.tsx';
|
3
|
+
import {SpaceContainer} from '../../../storybook/PreviewGallery';
|
4
|
+
import {useBooleanState} from '../../../hooks';
|
5
|
+
import {MoreVerticalIcon} from '../../../icons';
|
6
|
+
import {Dropdown} from '../../Dropdown/Dropdown';
|
7
|
+
import {Link} from '../../Link/Link';
|
8
|
+
import {useState} from 'react';
|
9
|
+
import {Collapse} from '../../Collapse/Collapse';
|
8
10
|
|
9
11
|
<Meta
|
10
12
|
title="Components/Navigation/SubNavigationPanel"
|
@@ -12,7 +14,7 @@ import { Link } from "../../Link/Link";
|
|
12
14
|
SubNavigationPanel: SubNavigationPanel,
|
13
15
|
'SubNavigationPanel.Collapsed': SubNavigationPanel.Collapsed,
|
14
16
|
}}
|
15
|
-
args={{
|
17
|
+
args={{children: 'Some content', isOpen: true, closeTitle: 'Close', openTitle: 'Open'}}
|
16
18
|
/>
|
17
19
|
|
18
20
|
# SubNavigationPanel
|
@@ -33,9 +35,10 @@ When the panel is collapsed the content is hidden.
|
|
33
35
|
<Canvas>
|
34
36
|
<Story name="Standard">
|
35
37
|
{args => {
|
38
|
+
const [isOpen, open, close] = useBooleanState(true);
|
36
39
|
return (
|
37
40
|
<SpaceContainer height={200}>
|
38
|
-
<SubNavigationPanel {...args} />
|
41
|
+
<SubNavigationPanel {...args} isOpen={isOpen} open={open} close={close} />
|
39
42
|
</SpaceContainer>
|
40
43
|
);
|
41
44
|
}}
|
@@ -44,34 +47,44 @@ When the panel is collapsed the content is hidden.
|
|
44
47
|
|
45
48
|
<ArgsTable story="Standard" />
|
46
49
|
|
47
|
-
## Panel
|
50
|
+
## Panel with scrollable content
|
48
51
|
|
49
52
|
<Canvas>
|
50
|
-
<Story name="
|
53
|
+
<Story name="ScrollableContent">
|
51
54
|
{args => {
|
55
|
+
const [isOpen, open, close] = useBooleanState(true);
|
52
56
|
return (
|
53
57
|
<SpaceContainer height={200}>
|
54
|
-
<SubNavigationPanel {...args} isOpen={
|
58
|
+
<SubNavigationPanel {...args} isOpen={isOpen} open={open} close={close}>
|
59
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
60
|
+
<br />
|
61
|
+
Fusce sed quam pharetra, lacinia nisl at, luctus ex.
|
62
|
+
<br />
|
63
|
+
Donec pretium est a augue dapibus, at semper ipsum vestibulum.
|
64
|
+
<br />
|
65
|
+
Aenean blandit metus a nibh blandit porta.
|
66
|
+
<br />
|
67
|
+
Phasellus placerat ligula sit amet vestibulum tristique.
|
68
|
+
</SubNavigationPanel>
|
55
69
|
</SpaceContainer>
|
56
70
|
);
|
57
71
|
}}
|
58
72
|
</Story>
|
59
73
|
</Canvas>
|
60
74
|
|
61
|
-
|
62
|
-
## Panel with collapsed and expanded content
|
75
|
+
## Panel with collapsed content using Dropdown component
|
63
76
|
|
64
77
|
<Canvas>
|
65
78
|
<Story name="CollapsedExpandedContent">
|
66
79
|
{args => {
|
67
|
-
const [isOpen, open, close] = useBooleanState(
|
80
|
+
const [isOpen, open, close] = useBooleanState(false);
|
68
81
|
const [isDropdownOpen, openDropDown, closeDropDown] = useBooleanState(false);
|
69
82
|
return (
|
70
83
|
<SpaceContainer height={200}>
|
71
84
|
<SubNavigationPanel {...args} isOpen={isOpen} open={open} close={close}>
|
72
85
|
<SubNavigationPanel.Collapsed>
|
73
86
|
<Dropdown>
|
74
|
-
<MoreVerticalIcon title="
|
87
|
+
<MoreVerticalIcon title="More" onClick={openDropDown} />
|
75
88
|
{isDropdownOpen && (
|
76
89
|
<Dropdown.Overlay onClose={closeDropDown}>
|
77
90
|
<Dropdown.ItemCollection>
|
@@ -81,15 +94,74 @@ When the panel is collapsed the content is hidden.
|
|
81
94
|
)}
|
82
95
|
</Dropdown>
|
83
96
|
</SubNavigationPanel.Collapsed>
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
97
|
+
Some content
|
98
|
+
</SubNavigationPanel>
|
99
|
+
</SpaceContainer>
|
100
|
+
);
|
101
|
+
}}
|
102
|
+
</Story>
|
103
|
+
</Canvas>
|
104
|
+
|
105
|
+
## Panel without padding
|
106
|
+
|
107
|
+
<Canvas>
|
108
|
+
<Story name="ContentWithoutPadding">
|
109
|
+
{args => {
|
110
|
+
const [isOpen, open, close] = useBooleanState(true);
|
111
|
+
const [collapse, setCollapse] = useState(1);
|
112
|
+
return (
|
113
|
+
<SpaceContainer height={200}>
|
114
|
+
<SubNavigationPanel {...args} isOpen={isOpen} open={open} close={close} noPadding>
|
115
|
+
Some content
|
116
|
+
</SubNavigationPanel>
|
117
|
+
</SpaceContainer>
|
118
|
+
);
|
119
|
+
}}
|
120
|
+
</Story>
|
121
|
+
</Canvas>
|
122
|
+
|
123
|
+
## Panel using Collapse components
|
124
|
+
|
125
|
+
<Canvas>
|
126
|
+
<Story name="ContentWithCollapseComponent">
|
127
|
+
{args => {
|
128
|
+
const [isOpen, open, close] = useBooleanState(true);
|
129
|
+
const [collapse, setCollapse] = useState(1);
|
130
|
+
return (
|
131
|
+
<SpaceContainer height={200}>
|
132
|
+
<SubNavigationPanel {...args} isOpen={isOpen} open={open} close={close} noPadding>
|
133
|
+
<Collapse
|
134
|
+
label="First Collapse"
|
135
|
+
collapseButtonLabel="Collapse"
|
136
|
+
isOpen={collapse === 1}
|
137
|
+
onCollapse={() => setCollapse(1)}
|
138
|
+
>
|
139
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
140
|
+
<br />
|
141
|
+
Fusce sed quam pharetra, lacinia nisl at, luctus ex.
|
142
|
+
<br />
|
143
|
+
Donec pretium est a augue dapibus, at semper ipsum vestibulum.
|
144
|
+
<br />
|
145
|
+
Aenean blandit metus a nibh blandit porta.
|
146
|
+
<br />
|
147
|
+
Phasellus placerat ligula sit amet vestibulum tristique.
|
148
|
+
</Collapse>
|
149
|
+
<Collapse
|
150
|
+
label="Second Collapse"
|
151
|
+
collapseButtonLabel="Collapse"
|
152
|
+
isOpen={collapse === 2}
|
153
|
+
onCollapse={() => setCollapse(2)}
|
154
|
+
>
|
155
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
156
|
+
<br />
|
157
|
+
Fusce sed quam pharetra, lacinia nisl at, luctus ex.
|
158
|
+
<br />
|
159
|
+
Donec pretium est a augue dapibus, at semper ipsum vestibulum.
|
160
|
+
<br />
|
161
|
+
Aenean blandit metus a nibh blandit porta.
|
162
|
+
<br />
|
163
|
+
Phasellus placerat ligula sit amet vestibulum tristique.
|
164
|
+
</Collapse>
|
93
165
|
</SubNavigationPanel>
|
94
166
|
</SpaceContainer>
|
95
167
|
);
|