Skip to content

Commit a6c125d

Browse files
feat(content-sidebar): select and hover state for threaded feed items (#3162)
* feat(content-sidebar): select and hover state for threaded feed items * feat(content-sidebar): select and hover state for threaded feed items
1 parent 729f6f1 commit a6c125d

File tree

14 files changed

+272
-54
lines changed

14 files changed

+272
-54
lines changed

src/elements/content-sidebar/activity-feed/activity-feed/ActiveState.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ type Props = {
6363
onSuccess: ?Function,
6464
onError: ?Function,
6565
) => void,
66+
onCommentSelect?: (id: string | null) => void,
6667
onHideReplies?: (id: string, replies: Array<CommentType>) => void,
6768
onReplyCreate?: (parentId: string, parentType: CommentFeedItemType, text: string) => void,
6869
onReplyDelete?: ({ id: string, parentId: string, permissions: BoxCommentPermission }) => void,
@@ -105,6 +106,7 @@ const ActiveState = ({
105106
onAppActivityDelete,
106107
onCommentDelete,
107108
onCommentEdit,
109+
onCommentSelect = noop,
108110
onHideReplies = noop,
109111
onReplyCreate = noop,
110112
onReplyDelete = noop,
@@ -118,6 +120,9 @@ const ActiveState = ({
118120
onVersionInfo,
119121
translations,
120122
}: Props): React.Node => {
123+
const onCommentSelectHandler = (itemId: string) => (isSelected: boolean) => {
124+
onCommentSelect(isSelected ? itemId : null);
125+
};
121126
const onHideRepliesHandler = (parentId: string) => (lastReply: CommentType) => {
122127
onHideReplies(parentId, [lastReply]);
123128
};
@@ -171,6 +176,7 @@ const ActiveState = ({
171176
onReplyCreate={onReplyCreateHandler(item.id, item.type)}
172177
onReplyDelete={onReplyDeleteHandler(item.id)}
173178
onReplyEdit={onReplyUpdateHandler(item.id)}
179+
onReplySelect={onCommentSelectHandler(item.id)}
174180
onShowReplies={onShowRepliesHandler(item.id, item.type)}
175181
repliesTotalCount={item.total_reply_count}
176182
replies={item.replies}
@@ -185,6 +191,7 @@ const ActiveState = ({
185191
mentionSelectorContacts={mentionSelectorContacts}
186192
onDelete={onCommentDelete}
187193
onEdit={onCommentEdit}
194+
onSelect={onCommentSelectHandler(item.id)}
188195
permissions={{
189196
can_delete: getProp(item.permissions, 'can_delete', false),
190197
can_edit: getProp(item.permissions, 'can_edit', false),
@@ -265,6 +272,7 @@ const ActiveState = ({
265272
onReplyCreate={onReplyCreateHandler(item.id, item.type)}
266273
onReplyDelete={onReplyDeleteHandler(item.id)}
267274
onReplyEdit={onReplyUpdateHandler(item.id)}
275+
onReplySelect={onCommentSelectHandler(item.id)}
268276
onShowReplies={onShowRepliesHandler(item.id, item.type)}
269277
repliesTotalCount={item.total_reply_count}
270278
replies={item.replies}

src/elements/content-sidebar/activity-feed/activity-feed/ActivityFeed.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,14 @@ type Props = {
9797
type State = {
9898
isInputOpen: boolean,
9999
isScrolled: boolean,
100+
selectedItemId: string | null,
100101
};
101102

102103
class ActivityFeed extends React.Component<Props, State> {
103104
state = {
104105
isScrolled: false,
105106
isInputOpen: false,
107+
selectedItemId: null,
106108
};
107109

108110
activeFeedItemRef = React.createRef<null | HTMLElement>();
@@ -244,10 +246,21 @@ class ActivityFeed extends React.Component<Props, State> {
244246
versionInfoHandler(data);
245247
};
246248

249+
setSelectedItem = (itemId: string | null) => {
250+
const { hasReplies } = this.props;
251+
if (!hasReplies) {
252+
return;
253+
}
254+
this.setState({ selectedItemId: itemId });
255+
};
256+
247257
isFeedItemActive = <T, U: { id: string, type: T }>({ id, type }: U): boolean => {
248258
const { activeFeedEntryId, activeFeedEntryType } = this.props;
259+
const { selectedItemId } = this.state;
260+
261+
const isSelected = selectedItemId === id;
249262

250-
return id === activeFeedEntryId && type === activeFeedEntryType;
263+
return selectedItemId ? isSelected : id === activeFeedEntryId && type === activeFeedEntryType;
251264
};
252265

253266
isCommentFeedItemActive = <T, U: { id: string, replies?: Array<Comment>, type: T }>(item: U): boolean => {
@@ -382,6 +395,7 @@ class ActivityFeed extends React.Component<Props, State> {
382395
onAppActivityDelete={onAppActivityDelete}
383396
onCommentDelete={hasCommentPermission ? onCommentDelete : noop}
384397
onCommentEdit={hasCommentPermission ? onCommentUpdate : noop}
398+
onCommentSelect={this.setSelectedItem}
385399
onHideReplies={onHideReplies}
386400
onReplyCreate={hasCommentPermission ? onReplyCreate : noop}
387401
onReplyDelete={hasCommentPermission ? onReplyDelete : noop}

src/elements/content-sidebar/activity-feed/activity-feed/ActivityThread.js

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type Props = {
3838
onSuccess: ?Function,
3939
onError: ?Function,
4040
) => void,
41+
onReplySelect?: (isSelected: boolean) => void,
4142
onShowReplies?: () => void,
4243
replies?: Array<CommentType>,
4344
repliesTotalCount?: number,
@@ -58,6 +59,7 @@ const ActivityThread = ({
5859
onReplyCreate,
5960
onReplyDelete = noop,
6061
onReplyEdit = noop,
62+
onReplySelect = noop,
6163
onShowReplies = noop,
6264
replies = [],
6365
repliesTotalCount = 0,
@@ -72,6 +74,14 @@ const ActivityThread = ({
7274
}
7375
};
7476

77+
const handleFormFocusOrShow = () => {
78+
onReplySelect(true);
79+
};
80+
81+
const handleFormHide = () => {
82+
onReplySelect(false);
83+
};
84+
7585
const renderButton = () => {
7686
if (isAlwaysExpanded || isRepliesLoading) {
7787
return null;
@@ -110,34 +120,40 @@ const ActivityThread = ({
110120
}
111121
return (
112122
<div className="bcs-ActivityThread" data-testid="activity-thread">
113-
<div className="bcs-ActivityThread-content">
114-
{children}
123+
<div className="bcs-ActivityThread-selectWrapper">
124+
<div className="bcs-ActivityThread-content">
125+
{children}
126+
127+
{renderButton()}
115128

116-
{renderButton()}
129+
{repliesTotalCount > 0 && repliesLength > 0 && (
130+
<ActivityThreadReplies
131+
currentUser={currentUser}
132+
getAvatarUrl={getAvatarUrl}
133+
getMentionWithQuery={getMentionWithQuery}
134+
getUserProfileUrl={getUserProfileUrl}
135+
isRepliesLoading={isRepliesLoading}
136+
mentionSelectorContacts={mentionSelectorContacts}
137+
onDelete={onReplyDelete}
138+
onEdit={onReplyEdit}
139+
onSelect={onReplySelect}
140+
replies={replies}
141+
translations={translations}
142+
/>
143+
)}
144+
</div>
117145

118-
{repliesTotalCount > 0 && repliesLength > 0 && (
119-
<ActivityThreadReplies
120-
currentUser={currentUser}
121-
getAvatarUrl={getAvatarUrl}
146+
{onReplyCreate && (
147+
<ActivityThreadReplyForm
122148
getMentionWithQuery={getMentionWithQuery}
123-
getUserProfileUrl={getUserProfileUrl}
124-
isRepliesLoading={isRepliesLoading}
125149
mentionSelectorContacts={mentionSelectorContacts}
126-
onDelete={onReplyDelete}
127-
onEdit={onReplyEdit}
128-
replies={replies}
129-
translations={translations}
150+
onFocus={handleFormFocusOrShow}
151+
onHide={handleFormHide}
152+
onShow={handleFormFocusOrShow}
153+
onReplyCreate={onReplyCreate}
130154
/>
131155
)}
132156
</div>
133-
134-
{onReplyCreate ? (
135-
<ActivityThreadReplyForm
136-
getMentionWithQuery={getMentionWithQuery}
137-
mentionSelectorContacts={mentionSelectorContacts}
138-
onReplyCreate={onReplyCreate}
139-
/>
140-
) : null}
141157
</div>
142158
);
143159
};

src/elements/content-sidebar/activity-feed/activity-feed/ActivityThread.scss

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,43 @@
11
@import '../../../common/variables';
22

3+
$sidebarActivityFeedSelectedItemBorderWidth: 2px;
4+
$sidebarActivityFeedSelectedItemSpacingHorizontal: $bdl-grid-unit * 2;
5+
$sidebarActivityFeedSelectedItemInnerSpacingHorizontal: $sidebarActivityFeedSpacingHorizontal - $sidebarActivityFeedSelectedItemSpacingHorizontal - $sidebarActivityFeedSelectedItemBorderWidth;
6+
37
.bcs-ActivityThread {
8+
padding-bottom: $sidebarActivityFeedSpacingVertical;
49
box-shadow: 0 1px 0 0 $bdl-gray-10;
510

11+
&:hover {
12+
background-color: $bdl-light-blue-05;
13+
}
14+
15+
.bcs-ActivityCard {
16+
padding: 10px $sidebarActivityFeedSpacingHorizontal $sidebarActivityFeedSpacingVertical;
17+
}
18+
619
.bcs-ActivityThread-toggle {
720
color: $bdl-box-blue;
821

922
&,
1023
&:hover,
1124
&:active {
12-
margin-top: -$bdl-grid-unit * 2; // to decreased spacing with parent comment
25+
margin-bottom: $sidebarActivityFeedSpacingVertical;
1326
margin-left: $sidebarActivityFeedSpacingHorizontal;
1427
font-weight: bold;
1528
}
1629
}
1730

18-
.bcs-ActivityCard {
19-
margin: $sidebarActivityFeedSpacingVertical $sidebarActivityFeedSpacingHorizontal;
20-
padding: 0;
31+
.bcs-SelectableActivityCard[aria-disabled=false] {
32+
&:hover,
33+
&:focus {
34+
background-color: transparent;
35+
box-shadow: none;
36+
}
2137
}
2238

2339
.bcs-AnnotationActivity-menu {
24-
top: 0;
40+
top: 10px;
2541
}
2642

2743
.bcs-Comment-timestamp {
@@ -36,3 +52,50 @@
3652
outline: auto;
3753
}
3854
}
55+
56+
.bcs-ActivityItem.bcs-is-focused .bcs-ActivityThread {
57+
padding-bottom: 0;
58+
box-shadow: none;
59+
60+
&,
61+
&:hover {
62+
background-color: $white;
63+
}
64+
65+
.bcs-ActivityThread-selectWrapper {
66+
margin: 0 $sidebarActivityFeedSelectedItemSpacingHorizontal;
67+
padding-bottom: $sidebarActivityFeedSpacingVertical - $sidebarActivityFeedSelectedItemBorderWidth;
68+
background-color: $bdl-light-blue-05;
69+
border: $sidebarActivityFeedSelectedItemBorderWidth $bdl-box-blue solid;
70+
border-radius: $bdl-border-radius-size-med;
71+
}
72+
73+
.bcs-ActivityThread-content > .bcs-ActivityCard {
74+
padding-top: 10px - $sidebarActivityFeedSelectedItemBorderWidth;
75+
padding-left: $sidebarActivityFeedSelectedItemInnerSpacingHorizontal;
76+
}
77+
78+
.bcs-ActivityThreadReplies {
79+
padding-left: $sidebarActivityFeedSelectedItemInnerSpacingHorizontal;
80+
81+
&::before {
82+
left: $sidebarActivityFeedSelectedItemInnerSpacingHorizontal;
83+
}
84+
}
85+
86+
.bcs-ActivityThread-toggle,
87+
.bcs-ActivityThreadReplyForm-toggle {
88+
margin-left: $sidebarActivityFeedSelectedItemInnerSpacingHorizontal;
89+
}
90+
}
91+
92+
.be .bcs-activity-feed .bcs-activity-feed-items-container .bcs-ActivityItem.bcs-is-focused .bcs-ActivityThread .bcs-ActivityCard {
93+
padding-right: $sidebarActivityFeedSelectedItemInnerSpacingHorizontal;
94+
box-shadow: none;
95+
animation: none;
96+
}
97+
98+
// Disable legacy annotation select indicator (orange bar)
99+
.be .bcs-activity-feed-annotation-activity.bcs-ActivityItem.bcs-is-focused .bcs-ActivityThread .bcs-ActivityCard::before {
100+
content: none;
101+
}

src/elements/content-sidebar/activity-feed/activity-feed/ActivityThreadReplies.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type Props = {
1919
mentionSelectorContacts?: SelectorItems<>,
2020
onDelete?: Function,
2121
onEdit?: Function,
22+
onSelect: (isSelected: boolean) => void,
2223
replies: Array<CommentType>,
2324
translations?: Translations,
2425
};
@@ -32,6 +33,7 @@ const ActivityThreadReplies = ({
3233
mentionSelectorContacts,
3334
onDelete,
3435
onEdit,
36+
onSelect,
3537
replies,
3638
translations,
3739
}: Props) => {
@@ -62,6 +64,7 @@ const ActivityThreadReplies = ({
6264
mentionSelectorContacts={mentionSelectorContacts}
6365
onDelete={onDelete}
6466
onEdit={onEdit}
67+
onSelect={onSelect}
6568
permissions={getReplyPermissions(reply)}
6669
translations={translations}
6770
/>

src/elements/content-sidebar/activity-feed/activity-feed/ActivityThreadReplies.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
.bcs-ActivityThreadReplies {
44
position: relative;
5+
margin-bottom: $sidebarActivityFeedSpacingVertical;
56
padding-left: $sidebarActivityFeedSpacingHorizontal;
67

78
&::before {
@@ -14,6 +15,16 @@
1415
border-radius: $bdl-border-radius-size;
1516
content: '';
1617
}
18+
19+
.bcs-ActivityCard {
20+
&:first-child {
21+
padding-top: 0;
22+
}
23+
24+
&:last-child {
25+
padding-bottom: 0;
26+
}
27+
}
1728
}
1829

1930
.bcs-ActivityThreadReplies-loading {

0 commit comments

Comments
 (0)