Skip to content

Commit 02abfaa

Browse files
authored
feat: Added a new prop, updated README, storybook, test files and style fixes (#15)
1 parent 4f9713c commit 02abfaa

8 files changed

Lines changed: 74 additions & 26 deletions

File tree

README.md

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,12 @@ const dataArray = [
4747
avatarUrl: "example.svg"
4848
},
4949
{
50-
name: "Jack"
51-
renderComponent: () => <div className="sample-class"> Sample Component <div>
50+
name: "Jack",
51+
renderComponent: () => (
52+
<div className="sample-class"> Sample Component </div>
53+
)
5254
}
5355
];
54-
5556
```
5657

5758
If no avatarUrl is specified for the user, following default Image will be considered.
@@ -88,7 +89,7 @@ This release includes breaking changes, new features, and updates. Please read t
8889
styles={{
8990
Avatar: () => ({ ...styles }),
9091
Name: () => ({ ...styles }),
91-
ExtraValue: () => ({ ...styles }),
92+
ExtraValue: () => ({ ...styles })
9293
}}
9394
/>
9495
```
@@ -103,7 +104,7 @@ This release includes breaking changes, new features, and updates. Please read t
103104
styles={{
104105
Avatar: () => ({ ...styles }),
105106
Name: () => ({ ...styles }),
106-
ExtraCount: () => ({ ...styles }),
107+
ExtraCount: () => ({ ...styles })
107108
}}
108109
/>
109110
```
@@ -140,7 +141,7 @@ Props that can be passed to the component are listed below:
140141
<td>
141142
To specify the size of the image element
142143
</td>
143-
<td><code>40px</code></td>
144+
<td><code>40</code></td>
144145
</tr>
145146
<tr>
146147
<td><code><b>variant?:</b> 'circular' | 'square' | 'rounded'</code></td>
@@ -159,19 +160,26 @@ Props that can be passed to the component are listed below:
159160
<tr>
160161
<td><code><b>showNameOnHover?:</b> boolean</code></td>
161162
<td>
162-
To show the name of each user on hovering over the user image
163+
To show the name of each user on hovering over the user image. If there is a specified render component in the data array, it will be displayed instead of the name when you hover over the user's image
163164
</td>
164165
<td><code>false</code></td>
166+
</tr>
167+
<tr>
168+
<td><code><b>defaultAvatarImage?:</b> string</code></td>
169+
<td>
170+
To show a default avatar, if no avatarUrl is specified for a user. if there is no specified avatarUrl and defaultAvatarImage, default image will be considered.
171+
</td>
172+
<td><code><img src="./src/assets/default-avatar.svg" alt="" width="40" height="40"/></code></td>
165173
</tr>
166174
<tr>
167-
<td><code><b>onUserClick?:</b> function</code></td>
175+
<td><code><b>onUserClick?:</b>(user: object) => void</code></td>
168176
<td>
169177
A callback function to be triggered on image click
170178
</td>
171179
<td><code>undefined</code></td>
172180
</tr>
173181
<tr>
174-
<td><code><b>onCountClick?:</b> function</code></td>
182+
<td><code><b>onCountClick?:</b>() => void</code></td>
175183
<td>
176184
A callback function to be triggered on additional count(last bubble) click
177185
</td>
@@ -214,3 +222,28 @@ The below code shows all the overridable styles:
214222
- `Avatar` - Overrides the avatar (user image) style
215223
- `Name` - Overrides the user name style
216224
- `ExtraCount` - Overrides the style of additional count displayed at last bubble
225+
226+
Example with the usage of other props
227+
228+
```jsx
229+
<InlineImages
230+
data={dataArray}
231+
styles= {
232+
Avatar: () => ({
233+
border: "1px solid white"
234+
}),
235+
Name: () => ({
236+
color: "white",
237+
fontSize: "16px",
238+
backgroundColor: "grey",
239+
padding: "5px",
240+
borderRadius: "10px"
241+
}),
242+
ExtraCount: () => ({
243+
backgroundColor: "yellow",
244+
border: "1px solid white"
245+
})
246+
}
247+
/>
248+
249+
```

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@
9393
"eslintConfig": {
9494
"extends": "./.eslintrc.json"
9595
},
96+
"prettier": {
97+
"trailingComma": "none"
98+
},
9699
"jest": {
97100
"moduleNameMapper": {
98101
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/scripts/testMock.js",

src/lib/inline-images/Avatar.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import classes from "./styles.module.scss";
88

99
const Avatar = (props: AvatarPropType): JSX.Element => {
1010
const {
11-
avatarUrl = defaultImage,
11+
avatarUrl,
12+
defaultAvatarImage = defaultImage,
1213
variant,
1314
renderComponent,
1415
size,
@@ -32,14 +33,14 @@ const Avatar = (props: AvatarPropType): JSX.Element => {
3233
className={`${variant && classes[variant]} ${
3334
elevateOnHover && classes.elevateOnHover
3435
}`}
35-
src={avatarUrl}
36+
src={avatarUrl || defaultAvatarImage}
3637
style={{
3738
width: `${size}px`,
3839
height: `${size}px`,
3940
...getStyles(Elements.Avatar, styles)
4041
}}
4142
onError={(e: React.SyntheticEvent<HTMLImageElement, Event>): void => {
42-
e.currentTarget.src = defaultImage;
43+
e.currentTarget.src = defaultAvatarImage;
4344
}}
4445
id="avatar-image"
4546
alt="image"
@@ -52,14 +53,14 @@ const Avatar = (props: AvatarPropType): JSX.Element => {
5253
<div
5354
id="avatar-name"
5455
className={classes.name}
55-
style={getStyles(Elements.Name, styles)}
56+
style={{ top: `${size}px`, ...getStyles(Elements.Name, styles) }}
5657
>
5758
{name}
5859
</div>
5960
)
6061
)}
6162
</div>
62-
)
63+
);
6364
};
6465

65-
export default Avatar;
66+
export default Avatar;

src/lib/inline-images/InlineImages.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from "react";
22

3+
import defaultImage from "../../assets/default-avatar.svg";
34
import {
45
DEFAULT_AVATAR_SIZE,
56
DEFAULT_SPACE_BETWEEN_PICS,
@@ -16,6 +17,7 @@ const InlineImages = (props: InlineImagesPropType): JSX.Element => {
1617
totalUserCount,
1718
elevateOnHover,
1819
showNameOnHover,
20+
defaultAvatarImage = defaultImage,
1921
onUserClick,
2022
onCountClick,
2123
size = DEFAULT_AVATAR_SIZE,
@@ -28,7 +30,7 @@ const InlineImages = (props: InlineImagesPropType): JSX.Element => {
2830
<div className={classes.imagesContainer}>
2931
{data?.map((user: AvatarDataType, index: number) => (
3032
<div
31-
key={user && user.name ?`${user.name}-${index}`: index}
33+
key={user && user.name ? `${user.name}-${index}` : index}
3234
className={classes.eachImage}
3335
style={{
3436
left: `${index * spaceBetweenPics}px`
@@ -38,12 +40,13 @@ const InlineImages = (props: InlineImagesPropType): JSX.Element => {
3840
<Avatar
3941
avatarUrl={user.avatarUrl}
4042
name={user.name}
41-
renderComponent = {user.renderComponent}
43+
renderComponent={user.renderComponent}
4244
elevateOnHover={elevateOnHover}
4345
showNameOnHover={showNameOnHover}
4446
onUserClick={(): void => {
4547
if (onUserClick) onUserClick(user);
4648
}}
49+
defaultAvatarImage={defaultAvatarImage}
4750
variant={variant}
4851
size={size}
4952
id={`inline-image-${index}`}
@@ -61,12 +64,17 @@ const InlineImages = (props: InlineImagesPropType): JSX.Element => {
6164
left: `${data?.length * spaceBetweenPics}px`,
6265
width: `${size}px`,
6366
height: `${size}px`,
67+
// Adjust the font size of the value based on the number of digits and size of the bubble
68+
fontSize: `${
69+
size *
70+
(0.4 - 0.03 * Math.log10(Math.abs(totalUserCount - data?.length)))
71+
}px`,
6472
...getStyles(Elements.ExtraCount, styles)
6573
}}
6674
onClick={onCountClick}
6775
id="inline-images-extra-count"
6876
>
69-
{totalUserCount - data?.length} +
77+
+{totalUserCount - data?.length}
7078
</div>
7179
)}
7280
</div>

src/lib/inline-images/styles.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
&:hover + .name{
1919
display: flex;
2020
position: absolute;
21-
top: 40px;
2221
margin-top: 20px;
2322
justify-content: center;
2423
}
2524
}
2625
}
2726
.imagesContainer {
27+
position: relative;
2828
.circular{
2929
border-radius: 50%;
3030
}

src/lib/inline-images/types.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export interface AvatarPropType {
22
avatarUrl?: string,
33
name?: string,
44
variant?: 'circular' | 'square' | 'rounded',
5+
defaultAvatarImage?: string,
56
size?: number,
67
renderComponent?: () => JSX.Element,
78
elevateOnHover?: boolean,
@@ -19,6 +20,7 @@ export interface AvatarDataType {
1920

2021
export interface InlineImagesPropType {
2122
data: AvatarDataType[],
23+
defaultAvatarImage?: string,
2224
totalUserCount?: number,
2325
variant?: 'circular' | 'square' | 'rounded',
2426
elevateOnHover?: boolean,

src/lib/tests/inlineImages.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ test("If additional count displayed on image stack", async () => {
5656

5757
if (dom) {
5858
const extraCount = await getById(dom.container, "inline-images-extra-count");
59-
expect(extraCount.innerHTML).toBe("8 +");
59+
expect(extraCount.innerHTML).toBe("+8");
6060
}
6161
});
6262

src/stories/InlineImages.stories.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default {
1111
parameters: {
1212
// More on Story layout: https://storybook.js.org/docs/react/configure/story-layout
1313
layout: "fullscreen"
14-
},
14+
}
1515
} as ComponentMeta<typeof Component>;
1616

1717
const Template: ComponentStory<typeof Component> = (props) => (
@@ -25,15 +25,15 @@ ComponentWithDefaultImage.args = {
2525
{
2626
avatarUrl: sampleAvatarImage,
2727
name: "Jon Dew"
28-
},
28+
}
2929
],
3030
totalUserCount: 10,
3131
elevateOnHover: true,
3232
showNameOnHover: true
3333
};
3434

35-
export const ComponentWithSpaceInBetween = Template.bind({});
36-
ComponentWithSpaceInBetween.args = {
35+
export const ComponentWithSpaceInBetweenAndDefaultAvatarImage = Template.bind({});
36+
ComponentWithSpaceInBetweenAndDefaultAvatarImage.args = {
3737
data: [
3838
{
3939
name: "Alice Smith"
@@ -47,6 +47,7 @@ ComponentWithSpaceInBetween.args = {
4747
],
4848
spaceBetweenPics: 50,
4949
variant: "square",
50+
defaultAvatarImage: "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460__340.png",
5051
showNameOnHover: true,
5152
styles: {
5253
Name: () => ({
@@ -69,7 +70,7 @@ ComponentWithEventHandlers.args = {
6970
{
7071
avatarUrl: sampleAvatarImage,
7172
name: "Bob Johnson"
72-
},
73+
}
7374
],
7475
totalUserCount: 6,
7576
elevateOnHover: true,
@@ -79,7 +80,7 @@ ComponentWithEventHandlers.args = {
7980
},
8081
onCountClick: () => {
8182
alert(`Clicked on the additional count`);
82-
},
83+
}
8384
};
8485

8586
export const ComponentWithCustomStyles = Template.bind({});

0 commit comments

Comments
 (0)