@manuscripts/style-guide 3.5.16 → 3.5.17

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/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  React components for Manuscripts applications.
4
4
 
5
- ## Example usage
5
+ ## Example usage
6
6
 
7
- ```tsx
7
+ ```tsx
8
8
  import { PrimaryButton } from '@manuscripts/style-guide'
9
9
 
10
10
  const Example: React.FunctionComponent<{
@@ -8,6 +8,23 @@ const jsx_runtime_1 = require("react/jsx-runtime");
8
8
  const react_1 = require("react");
9
9
  const styled_components_1 = __importDefault(require("styled-components"));
10
10
  const icons_1 = require("./icons");
11
+ const INITIALS_PALETTE = [
12
+ '#1a9bc7',
13
+ '#31a056',
14
+ '#e65100',
15
+ '#6a1b9a',
16
+ '#c62828',
17
+ '#1565c0',
18
+ '#558b2f',
19
+ '#00695c',
20
+ ];
21
+ const getInitials = (name) => {
22
+ const words = name.trim().split(/\s+/);
23
+ if (words.length === 1) {
24
+ return words[0].slice(0, 2).toUpperCase();
25
+ }
26
+ return (words[0][0] + words[words.length - 1][0]).toUpperCase();
27
+ };
11
28
  const AvatarContainer = styled_components_1.default.div `
12
29
  display: flex;
13
30
  align-items: center;
@@ -31,11 +48,26 @@ const StyledAvatar = (0, styled_components_1.default)(icons_1.ProfileIcon) `
31
48
  fill: ${(props) => props.color || props.theme.colors.text.info};
32
49
  }
33
50
  `;
51
+ const InitialsCircle = styled_components_1.default.div `
52
+ width: ${(props) => props.size}px;
53
+ height: ${(props) => props.size}px;
54
+ border-radius: 50%;
55
+ background: ${(props) => props.bg};
56
+ color: #ffffff;
57
+ font-weight: bold;
58
+ font-size: ${(props) => Math.round(props.size * 0.4)}px;
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ user-select: none;
63
+ flex-shrink: 0;
64
+ `;
34
65
  const Avatar = (props) => {
35
66
  const [srcError, setSrcError] = (0, react_1.useState)(false);
36
67
  const handleSrcError = (0, react_1.useCallback)(() => {
37
68
  setSrcError(true);
38
69
  }, []);
39
- return ((0, jsx_runtime_1.jsx)(AvatarContainer, { opacity: props.opacity || 1, children: props.src && !srcError ? ((0, jsx_runtime_1.jsx)(RoundedImage, { src: props.src, size: props.size, onError: handleSrcError })) : ((0, jsx_runtime_1.jsx)(StyledAvatar, { height: props.size, width: props.size, color: props.color })) }));
70
+ const showInitials = (!props.src || srcError) && !!props.name;
71
+ return ((0, jsx_runtime_1.jsx)(AvatarContainer, { opacity: props.opacity || 1, children: props.src && !srcError ? ((0, jsx_runtime_1.jsx)(RoundedImage, { src: props.src, size: props.size, onError: handleSrcError })) : showInitials ? ((0, jsx_runtime_1.jsx)(InitialsCircle, { size: props.size, bg: INITIALS_PALETTE[props.name.charCodeAt(0) % INITIALS_PALETTE.length], children: getInitials(props.name) })) : ((0, jsx_runtime_1.jsx)(StyledAvatar, { height: props.size, width: props.size, color: props.color })) }));
40
72
  };
41
73
  exports.Avatar = Avatar;
@@ -30,4 +30,5 @@ const BadgeContainer = styled_components_1.default.div `
30
30
  ? `1px solid ${props.theme.colors.badge[props.$variant].border}`
31
31
  : 'none'};
32
32
  min-width: max-content;
33
+ text-transform: capitalize;
33
34
  `;
@@ -44,7 +44,7 @@ const selectStyles = (theme, error, variant, listMaxHeight) => ({
44
44
  }),
45
45
  singleValue: (base, state) => ({
46
46
  ...base,
47
- color: state.isDisabled ? '#B3B3B3' : theme.colors.text.primary,
47
+ color: state.isDisabled ? '#B3B3B3' : theme.colors.text.greyMuted,
48
48
  fontFamily: theme.font.family.sans,
49
49
  fontSize: theme.font.size.medium,
50
50
  }),
@@ -2,6 +2,23 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useCallback, useState } from 'react';
3
3
  import styled from 'styled-components';
4
4
  import { ProfileIcon } from './icons';
5
+ const INITIALS_PALETTE = [
6
+ '#1a9bc7',
7
+ '#31a056',
8
+ '#e65100',
9
+ '#6a1b9a',
10
+ '#c62828',
11
+ '#1565c0',
12
+ '#558b2f',
13
+ '#00695c',
14
+ ];
15
+ const getInitials = (name) => {
16
+ const words = name.trim().split(/\s+/);
17
+ if (words.length === 1) {
18
+ return words[0].slice(0, 2).toUpperCase();
19
+ }
20
+ return (words[0][0] + words[words.length - 1][0]).toUpperCase();
21
+ };
5
22
  const AvatarContainer = styled.div `
6
23
  display: flex;
7
24
  align-items: center;
@@ -25,10 +42,25 @@ const StyledAvatar = styled(ProfileIcon) `
25
42
  fill: ${(props) => props.color || props.theme.colors.text.info};
26
43
  }
27
44
  `;
45
+ const InitialsCircle = styled.div `
46
+ width: ${(props) => props.size}px;
47
+ height: ${(props) => props.size}px;
48
+ border-radius: 50%;
49
+ background: ${(props) => props.bg};
50
+ color: #ffffff;
51
+ font-weight: bold;
52
+ font-size: ${(props) => Math.round(props.size * 0.4)}px;
53
+ display: flex;
54
+ align-items: center;
55
+ justify-content: center;
56
+ user-select: none;
57
+ flex-shrink: 0;
58
+ `;
28
59
  export const Avatar = (props) => {
29
60
  const [srcError, setSrcError] = useState(false);
30
61
  const handleSrcError = useCallback(() => {
31
62
  setSrcError(true);
32
63
  }, []);
33
- return (_jsx(AvatarContainer, { opacity: props.opacity || 1, children: props.src && !srcError ? (_jsx(RoundedImage, { src: props.src, size: props.size, onError: handleSrcError })) : (_jsx(StyledAvatar, { height: props.size, width: props.size, color: props.color })) }));
64
+ const showInitials = (!props.src || srcError) && !!props.name;
65
+ return (_jsx(AvatarContainer, { opacity: props.opacity || 1, children: props.src && !srcError ? (_jsx(RoundedImage, { src: props.src, size: props.size, onError: handleSrcError })) : showInitials ? (_jsx(InitialsCircle, { size: props.size, bg: INITIALS_PALETTE[props.name.charCodeAt(0) % INITIALS_PALETTE.length], children: getInitials(props.name) })) : (_jsx(StyledAvatar, { height: props.size, width: props.size, color: props.color })) }));
34
66
  };
@@ -23,4 +23,5 @@ const BadgeContainer = styled.div `
23
23
  ? `1px solid ${props.theme.colors.badge[props.$variant].border}`
24
24
  : 'none'};
25
25
  min-width: max-content;
26
+ text-transform: capitalize;
26
27
  `;
@@ -38,7 +38,7 @@ const selectStyles = (theme, error, variant, listMaxHeight) => ({
38
38
  }),
39
39
  singleValue: (base, state) => ({
40
40
  ...base,
41
- color: state.isDisabled ? '#B3B3B3' : theme.colors.text.primary,
41
+ color: state.isDisabled ? '#B3B3B3' : theme.colors.text.greyMuted,
42
42
  fontFamily: theme.font.family.sans,
43
43
  fontSize: theme.font.size.medium,
44
44
  }),
@@ -19,6 +19,7 @@ interface AvatarProps {
19
19
  size: number;
20
20
  color?: string;
21
21
  opacity?: number;
22
+ name?: string;
22
23
  }
23
24
  export declare const Avatar: React.FC<AvatarProps>;
24
25
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@manuscripts/style-guide",
3
3
  "description": "Shared components for Manuscripts applications",
4
- "version": "3.5.16",
4
+ "version": "3.5.17",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-style-guide",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",