superdesk-ui-framework 3.0.17 → 3.0.19
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/app/styles/_avatar.scss +175 -25
- package/app/styles/design-tokens/_new-colors.scss +35 -2
- package/app-typescript/components/Icon.tsx +7 -1
- package/app-typescript/components/ShowPopup.tsx +173 -0
- package/app-typescript/components/Spacer.tsx +0 -8
- package/app-typescript/components/WithPagination.tsx +4 -4
- package/app-typescript/components/WithPopover.tsx +43 -0
- package/app-typescript/components/avatar/avatar-action-add.tsx +27 -0
- package/app-typescript/components/avatar/avatar-group.tsx +86 -0
- package/app-typescript/components/avatar/avatar-image.tsx +26 -0
- package/app-typescript/components/avatar/avatar-number.tsx +16 -0
- package/app-typescript/components/avatar/avatar-placeholder.tsx +35 -0
- package/app-typescript/components/avatar/avatar-text.tsx +19 -0
- package/app-typescript/components/avatar/avatar-wrapper.tsx +72 -0
- package/app-typescript/components/avatar/avatar.tsx +48 -0
- package/app-typescript/components/avatar/interfaces.ts +3 -0
- package/app-typescript/index.ts +8 -4
- package/dist/avatar_dummy.svg +4 -0
- package/dist/examples.bundle.js +3271 -2470
- package/dist/react/Avatar.tsx +628 -307
- package/dist/superdesk-ui.bundle.css +139 -27
- package/dist/superdesk-ui.bundle.js +2689 -1846
- package/dist/vendor.bundle.js +22 -22
- package/examples/pages/react/Avatar.tsx +628 -307
- package/images/avatar_dummy.svg +4 -0
- package/package.json +2 -1
- package/react/components/Icon.d.ts +1 -0
- package/react/components/Icon.js +1 -1
- package/react/components/ShowPopup.d.ts +10 -0
- package/react/components/ShowPopup.js +158 -0
- package/react/components/Spacer.d.ts +30 -0
- package/react/components/Spacer.js +86 -0
- package/react/components/WithPagination.d.ts +1 -1
- package/react/components/WithPagination.js +3 -3
- package/react/components/WithPopover.d.ts +18 -0
- package/react/components/WithPopover.js +65 -0
- package/react/components/avatar/avatar-action-add.d.ts +9 -0
- package/react/components/avatar/avatar-action-add.js +59 -0
- package/react/components/avatar/avatar-group.d.ts +18 -0
- package/react/components/avatar/avatar-group.js +104 -0
- package/react/components/avatar/avatar-image.d.ts +9 -0
- package/react/components/avatar/avatar-image.js +62 -0
- package/react/components/avatar/avatar-number.d.ts +9 -0
- package/react/components/avatar/avatar-number.js +56 -0
- package/react/components/avatar/avatar-placeholder.d.ts +14 -0
- package/react/components/avatar/avatar-placeholder.js +57 -0
- package/react/components/avatar/avatar-text.d.ts +9 -0
- package/react/components/avatar/avatar-text.js +54 -0
- package/react/components/avatar/avatar-wrapper.d.ts +26 -0
- package/react/components/{Avatar.js → avatar/avatar-wrapper.js} +16 -57
- package/react/components/avatar/avatar.d.ts +17 -0
- package/react/components/avatar/avatar.js +59 -0
- package/react/components/avatar/interfaces.d.ts +3 -0
- package/react/components/avatar/interfaces.js +2 -0
- package/react/index.d.ts +8 -4
- package/react/index.js +20 -11
- package/app-typescript/components/Avatar.tsx +0 -122
- package/dist/avatar_64.png +0 -0
- package/react/components/Avatar.d.ts +0 -42
@@ -0,0 +1,86 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import classNames from 'classnames';
|
3
|
+
import {Avatar, IPropsAvatar} from './avatar';
|
4
|
+
import {AvatarWrapper} from './avatar-wrapper';
|
5
|
+
import {AvatarContentNumber} from './avatar-number';
|
6
|
+
import {AvatarPlaceholder, IPropsAvatarPlaceholder} from './avatar-placeholder';
|
7
|
+
|
8
|
+
export type IAvatarInGroup = Omit<IPropsAvatar, 'size'>;
|
9
|
+
export type IAvatarPlaceholderInGroup = Omit<IPropsAvatarPlaceholder, 'size'>;
|
10
|
+
|
11
|
+
export type IAvatarGroupItem = IAvatarInGroup | IAvatarPlaceholderInGroup;
|
12
|
+
|
13
|
+
type IGap = 'none' | 'small'| 'medium'| 'large';
|
14
|
+
|
15
|
+
export interface IPropsAvatarGroup {
|
16
|
+
size: IPropsAvatar['size'];
|
17
|
+
items: Array<IAvatarGroupItem>;
|
18
|
+
|
19
|
+
/**
|
20
|
+
* maximum number of avatars to shown inline; defaults to 4
|
21
|
+
* if exceeded, "+1"/"+2"/"+n" button will be shown
|
22
|
+
*/
|
23
|
+
max?: number | 'show-all';
|
24
|
+
}
|
25
|
+
|
26
|
+
function isAvatar(item: IAvatarInGroup | IAvatarPlaceholderInGroup): item is IAvatarInGroup {
|
27
|
+
return (item as any)['kind'] == null;
|
28
|
+
}
|
29
|
+
|
30
|
+
export class AvatarGroup extends React.PureComponent<IPropsAvatarGroup> {
|
31
|
+
render() {
|
32
|
+
const {size, items} = this.props;
|
33
|
+
const someIconsHaveExtraElements = items.filter(isAvatar).some(
|
34
|
+
({icon, administratorIndicator}) => icon != null || administratorIndicator != null,
|
35
|
+
);
|
36
|
+
const gap: IGap = someIconsHaveExtraElements ? 'medium' : 'none';
|
37
|
+
|
38
|
+
const max: number = (() => {
|
39
|
+
if (this.props.max === 'show-all') {
|
40
|
+
return this.props.items.length;
|
41
|
+
} else if (this.props.max == null) {
|
42
|
+
return 4;
|
43
|
+
} else {
|
44
|
+
return this.props.max;
|
45
|
+
}
|
46
|
+
})();
|
47
|
+
const itemsOverLimit = items.length - max;
|
48
|
+
|
49
|
+
return (
|
50
|
+
<div
|
51
|
+
className={classNames(
|
52
|
+
'sd-avatar-group',
|
53
|
+
'sd-avatar-group--stacked',
|
54
|
+
`sd-avatar-group--stacked--gap-${gap}`,
|
55
|
+
)}
|
56
|
+
role='group'
|
57
|
+
>
|
58
|
+
{
|
59
|
+
items.slice(0, max).map((item, index) => {
|
60
|
+
if (isAvatar(item)) {
|
61
|
+
return (
|
62
|
+
<Avatar {...item} key={index} size={size} />
|
63
|
+
);
|
64
|
+
} else {
|
65
|
+
return (
|
66
|
+
<AvatarPlaceholder
|
67
|
+
{...item}
|
68
|
+
key={index}
|
69
|
+
size={this.props.size}
|
70
|
+
/>
|
71
|
+
);
|
72
|
+
}
|
73
|
+
})
|
74
|
+
}
|
75
|
+
|
76
|
+
{
|
77
|
+
itemsOverLimit > 0 && (
|
78
|
+
<AvatarWrapper size={size} isEmpty={false}>
|
79
|
+
<AvatarContentNumber number={`${itemsOverLimit}`} />
|
80
|
+
</AvatarWrapper>
|
81
|
+
)
|
82
|
+
}
|
83
|
+
</div>
|
84
|
+
);
|
85
|
+
}
|
86
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import {IPropsBase} from './interfaces';
|
3
|
+
|
4
|
+
interface IPropsImageAvatar extends IPropsBase {
|
5
|
+
imageUrl?: string | null; // defaults to a placeholder image
|
6
|
+
}
|
7
|
+
|
8
|
+
export class AvatarContentImage extends React.PureComponent<IPropsImageAvatar> {
|
9
|
+
render() {
|
10
|
+
if (this.props.imageUrl == null) {
|
11
|
+
return (
|
12
|
+
<span className="sd-avatar-content sd-avatar-content--dummy-img" title={this.props.tooltipText}>
|
13
|
+
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
14
|
+
<circle cx="100" cy="100" r="100" fill="white" fill-opacity="0.01"/>
|
15
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M40 153V145.384C40 141.557 41.16 137.981 43.16 135C49.14 126.057 66.24 119.711 77.14 118C82.74 117.115 90.16 116.538 100 116.538C109.84 116.538 117.26 117.115 122.86 118C133.76 119.711 150.86 126.057 156.84 135C158.84 137.981 160 141.557 160 145.384V153C150 165 130 180 100 180C70 180 50 165 40 153ZM100 30C122.08 30 140 47.2307 140 68.4614C140 89.6922 122.08 106.923 100 106.923C77.92 106.923 60 89.6922 60 68.4614C60 47.2307 77.92 30 100 30Z" fill="var(--sd-colour-avatar-dummy)" fill-opacity="1"/>
|
16
|
+
</svg>
|
17
|
+
</span>);
|
18
|
+
} else {
|
19
|
+
return (
|
20
|
+
<span className="sd-avatar-content" title={this.props.tooltipText} >
|
21
|
+
<img src={this.props.imageUrl} />
|
22
|
+
</span>
|
23
|
+
);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import {IPropsBase} from './interfaces';
|
3
|
+
|
4
|
+
interface IPropsNumberAvatar extends IPropsBase {
|
5
|
+
number: string;
|
6
|
+
}
|
7
|
+
|
8
|
+
export class AvatarContentNumber extends React.PureComponent<IPropsNumberAvatar> {
|
9
|
+
render() {
|
10
|
+
return (
|
11
|
+
<span className="sd-avatar-content sd-avatar-content--number">
|
12
|
+
<span>+{this.props.number}</span>
|
13
|
+
</span>
|
14
|
+
);
|
15
|
+
}
|
16
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import {AvatarWrapper} from './avatar-wrapper';
|
3
|
+
import {AvatarContentAdd} from './avatar-action-add';
|
4
|
+
|
5
|
+
export interface IPropsAvatarPlaceholder {
|
6
|
+
// kind is used to it's easy to add
|
7
|
+
// other types of placeholders without breaking existing usages
|
8
|
+
kind: 'plus-button';
|
9
|
+
tooltip?: string | null; // nullable, but mandatory to communicate importance
|
10
|
+
|
11
|
+
size: 'x-small' | 'small' | 'medium' | 'large' | 'x-large' | 'xx-large';
|
12
|
+
|
13
|
+
icon?: {
|
14
|
+
name: string;
|
15
|
+
color?: string;
|
16
|
+
};
|
17
|
+
|
18
|
+
onClick?(): void;
|
19
|
+
}
|
20
|
+
|
21
|
+
export class AvatarPlaceholder extends React.PureComponent<IPropsAvatarPlaceholder> {
|
22
|
+
render() {
|
23
|
+
const {size, tooltip, icon} = this.props;
|
24
|
+
|
25
|
+
return (
|
26
|
+
<AvatarWrapper
|
27
|
+
size={size}
|
28
|
+
isEmpty={false}
|
29
|
+
icon={icon}
|
30
|
+
>
|
31
|
+
<AvatarContentAdd tooltipText={tooltip ?? undefined} onClick={this.props.onClick} />
|
32
|
+
</AvatarWrapper>
|
33
|
+
);
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import {IPropsBase} from './interfaces';
|
3
|
+
|
4
|
+
interface IPropsTextAvatar extends IPropsBase {
|
5
|
+
text: string; // limited to 3 characters
|
6
|
+
}
|
7
|
+
|
8
|
+
export class AvatarContentText extends React.PureComponent<IPropsTextAvatar> {
|
9
|
+
render() {
|
10
|
+
return (
|
11
|
+
<span
|
12
|
+
className="sd-avatar-content sd-avatar-content--text"
|
13
|
+
title={this.props.tooltipText}
|
14
|
+
>
|
15
|
+
<span>{this.props.text.slice(0, 3)}</span>
|
16
|
+
</span>
|
17
|
+
);
|
18
|
+
}
|
19
|
+
}
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import classNames from 'classnames';
|
3
|
+
import {Icon} from '../Icon';
|
4
|
+
|
5
|
+
interface IPropsAvatarWrapper {
|
6
|
+
size?: 'x-small' | 'small' | 'medium' | 'large' | 'x-large' | 'xx-large'; // defaults to medium
|
7
|
+
statusIndicator?: {
|
8
|
+
status: 'online' | 'offline';
|
9
|
+
tooltipText?: string;
|
10
|
+
};
|
11
|
+
administratorIndicator?: {
|
12
|
+
enabled: boolean;
|
13
|
+
tooltipText?: string;
|
14
|
+
};
|
15
|
+
children: React.ReactNode;
|
16
|
+
'data-test-id'?: string;
|
17
|
+
isEmpty?: boolean;
|
18
|
+
icon?: {
|
19
|
+
name: string;
|
20
|
+
color?: string;
|
21
|
+
};
|
22
|
+
|
23
|
+
}
|
24
|
+
|
25
|
+
/**
|
26
|
+
* @deprecated use AvatarV2
|
27
|
+
*/
|
28
|
+
export class AvatarWrapper extends React.PureComponent<IPropsAvatarWrapper> {
|
29
|
+
render() {
|
30
|
+
const {icon} = this.props;
|
31
|
+
|
32
|
+
return (
|
33
|
+
<span
|
34
|
+
className={classNames('sd-avatar', {
|
35
|
+
'sd-avatar--x-small': this.props.size === 'x-small',
|
36
|
+
'sd-avatar--small': this.props.size === 'small',
|
37
|
+
'sd-avatar--medium': this.props.size === 'medium' || this.props.size == null,
|
38
|
+
'sd-avatar--large': this.props.size === 'large',
|
39
|
+
'sd-avatar--x-large': this.props.size === 'x-large',
|
40
|
+
'sd-avatar--xx-large': this.props.size === 'xx-large',
|
41
|
+
'sd-avatar--indicator-status--online' : this.props.statusIndicator?.status === 'online',
|
42
|
+
'sd-avatar--indicator-status--offline' : this.props.statusIndicator?.status === 'offline',
|
43
|
+
'sd-avatar--empty-light': this.props.isEmpty,
|
44
|
+
})}
|
45
|
+
data-test-id={this.props['data-test-id']}
|
46
|
+
title={this.props.statusIndicator != null ? this.props.statusIndicator.tooltipText : ""}
|
47
|
+
>
|
48
|
+
{this.props.children}
|
49
|
+
|
50
|
+
{
|
51
|
+
this.props.administratorIndicator?.enabled === true
|
52
|
+
? (
|
53
|
+
<i
|
54
|
+
className="icon-settings sd-avatar--indicator-admin"
|
55
|
+
title={this.props.administratorIndicator.tooltipText}
|
56
|
+
/>
|
57
|
+
)
|
58
|
+
: null
|
59
|
+
}
|
60
|
+
|
61
|
+
{
|
62
|
+
icon != null && (
|
63
|
+
<span className="sd-avatar__icon">
|
64
|
+
<Icon name={icon.name} color={icon.color} />
|
65
|
+
</span>
|
66
|
+
)
|
67
|
+
}
|
68
|
+
|
69
|
+
</span>
|
70
|
+
);
|
71
|
+
}
|
72
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import {AvatarContentImage} from './avatar-image';
|
3
|
+
import {AvatarWrapper} from './avatar-wrapper';
|
4
|
+
import {AvatarContentText} from './avatar-text';
|
5
|
+
|
6
|
+
export interface IPropsAvatar {
|
7
|
+
imageUrl: string | null; // nullable, but mandatory to communicate importance
|
8
|
+
tooltip: string | null; // nullable, but mandatory to communicate importance
|
9
|
+
|
10
|
+
/** 3 letters max */
|
11
|
+
initials: string | null; // nullable, but mandatory to communicate importance
|
12
|
+
|
13
|
+
size: 'x-small' | 'small' | 'medium' | 'large' | 'x-large' | 'xx-large';
|
14
|
+
|
15
|
+
statusIndicator?: 'online' | 'offline';
|
16
|
+
administratorIndicator?: boolean;
|
17
|
+
icon?: {
|
18
|
+
name: string;
|
19
|
+
color?: string;
|
20
|
+
};
|
21
|
+
}
|
22
|
+
|
23
|
+
export class Avatar extends React.PureComponent<IPropsAvatar> {
|
24
|
+
render() {
|
25
|
+
const {imageUrl, initials, size, statusIndicator, administratorIndicator, icon, tooltip} = this.props;
|
26
|
+
|
27
|
+
return (
|
28
|
+
<AvatarWrapper
|
29
|
+
size={size}
|
30
|
+
statusIndicator={statusIndicator ? {status: statusIndicator, tooltipText: ''} : undefined}
|
31
|
+
administratorIndicator={administratorIndicator ? {enabled: true, tooltipText: ''} : undefined}
|
32
|
+
icon={icon}
|
33
|
+
isEmpty={false}
|
34
|
+
>
|
35
|
+
{
|
36
|
+
imageUrl != null || initials == null
|
37
|
+
? (
|
38
|
+
<AvatarContentImage imageUrl={imageUrl} tooltipText={tooltip ?? undefined} />
|
39
|
+
)
|
40
|
+
: (
|
41
|
+
<AvatarContentText text={initials} tooltipText={tooltip ?? undefined} />
|
42
|
+
)
|
43
|
+
}
|
44
|
+
|
45
|
+
</AvatarWrapper>
|
46
|
+
);
|
47
|
+
}
|
48
|
+
}
|
package/app-typescript/index.ts
CHANGED
@@ -11,10 +11,12 @@ export { Popover } from './components/Popover';
|
|
11
11
|
export { Label } from './components/Label';
|
12
12
|
export { Badge } from './components/Badge';
|
13
13
|
export { Alert } from './components/Alert';
|
14
|
-
export { AvatarWrapper } from './components/
|
15
|
-
export { AvatarContentText } from './components/
|
16
|
-
export { AvatarContentImage } from './components/
|
17
|
-
export { AvatarGroup } from './components/
|
14
|
+
export { AvatarWrapper } from './components/avatar/avatar-wrapper';
|
15
|
+
export { AvatarContentText } from './components/avatar/avatar-text';
|
16
|
+
export { AvatarContentImage } from './components/avatar/avatar-image';
|
17
|
+
export { AvatarGroup } from './components/avatar/avatar-group';
|
18
|
+
export { Avatar } from './components/avatar/avatar';
|
19
|
+
export { AvatarPlaceholder } from './components/avatar/avatar-placeholder';
|
18
20
|
export { IconButton } from './components/IconButton';
|
19
21
|
export { IconLabel } from './components/IconLabel';
|
20
22
|
export { Tooltip } from './components/Tooltip';
|
@@ -92,6 +94,8 @@ export { TableList, TableListItem } from './components/Lists/TableList';
|
|
92
94
|
export { ContentListItem } from './components/Lists/ContentList';
|
93
95
|
export { MultiSelect } from './components/MultiSelect';
|
94
96
|
export { ResizablePanels } from './components/ResizablePanels';
|
97
|
+
export { WithPopover } from './components/WithPopover';
|
98
|
+
export { Spacer, SpacerBlock } from './components/Spacer';
|
95
99
|
|
96
100
|
// declare non-typescript exports to prevent errors
|
97
101
|
export declare const ToggleBoxNext: any;
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<circle cx="100" cy="100" r="100" fill="white" fill-opacity="0.01"/>
|
3
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M40 153V145.384C40 141.557 41.16 137.981 43.16 135C49.14 126.057 66.24 119.711 77.14 118C82.74 117.115 90.16 116.538 100 116.538C109.84 116.538 117.26 117.115 122.86 118C133.76 119.711 150.86 126.057 156.84 135C158.84 137.981 160 141.557 160 145.384V153C150 165 130 180 100 180C70 180 50 165 40 153ZM100 30C122.08 30 140 47.2307 140 68.4614C140 89.6922 122.08 106.923 100 106.923C77.92 106.923 60 89.6922 60 68.4614C60 47.2307 77.92 30 100 30Z" fill="var(--sd-colour-interactive)" fill-opacity="0.6"/>
|
4
|
+
</svg>
|