Skip to content

Commit 4e4521a

Browse files
authored
Merge pull request #231 from Just-Insane/fix/badge-positioning
Fix badge positioning and alignment across sidebar components
2 parents 99499ba + 9b68143 commit 4e4521a

11 files changed

Lines changed: 170 additions & 63 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'default': patch
3+
---
4+
5+
Fix badge positioning and alignment across all sidebar components

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v24.14.0

src/app/components/message/layout/layout.css.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ export const PronounPill = style({
226226
export const MessageTextBody = recipe({
227227
base: {
228228
wordBreak: 'break-word',
229+
fontSize: '1rem !important', // Override folds Text component to enable page zoom scaling
229230
},
230231
variants: {
231232
preWrap: {
@@ -235,27 +236,27 @@ export const MessageTextBody = recipe({
235236
},
236237
jumboEmoji: {
237238
none: {
238-
fontSize: '1em',
239+
fontSize: '1rem !important',
239240
lineHeight: 'inherit',
240241
},
241242
extraSmall: {
242-
fontSize: '1.25em',
243+
fontSize: '1.25rem !important',
243244
lineHeight: '1.4em',
244245
},
245246
small: {
246-
fontSize: '1.5em',
247+
fontSize: '1.5rem !important',
247248
lineHeight: '1.5em',
248249
},
249250
normal: {
250-
fontSize: '1.805em',
251+
fontSize: '1.805rem !important',
251252
lineHeight: '1.625em',
252253
},
253254
large: {
254-
fontSize: '2.1em',
255+
fontSize: '2.1rem !important',
255256
lineHeight: '1.675em',
256257
},
257258
extraLarge: {
258-
fontSize: '2.4em',
259+
fontSize: '2.4rem !important',
259260
lineHeight: '1.7em',
260261
},
261262
},

src/app/components/sidebar/Sidebar.css.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,39 @@ export const SidebarItemBadge = recipe({
142142
defaultVariants: {
143143
hasCount: false,
144144
},
145+
// Adjust positioning when badge is on a folder (closed folder button)
146+
compoundVariants: [
147+
{
148+
variants: {
149+
hasCount: true,
150+
},
151+
style: {
152+
selectors: {
153+
// When the badge is within an item containing a closed folder, adjust position
154+
// to align with the folder's square border
155+
'div:has(> button[data-id]) &': {
156+
top: toRem(0),
157+
left: 'auto',
158+
right: toRem(0),
159+
},
160+
},
161+
},
162+
},
163+
{
164+
variants: {
165+
hasCount: false,
166+
},
167+
style: {
168+
selectors: {
169+
'div:has(> button[data-id]) &': {
170+
top: toRem(2),
171+
left: 'auto',
172+
right: toRem(2),
173+
},
174+
},
175+
},
176+
},
177+
],
145178
});
146179
export type SidebarItemBadgeVariants = RecipeVariants<typeof SidebarItemBadge>;
147180

src/app/pages/client/sidebar/AccountSwitcherTab.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ export function AccountSwitcherTab() {
276276
)}
277277
</SidebarItemTooltip>
278278
{(totalBackgroundUnread > 0 || anyBackgroundHighlight) && (
279-
<SidebarItemBadge hasCount>
279+
<SidebarItemBadge hasCount style={{ left: toRem(-6), right: 'auto' }}>
280280
<UnreadBadge
281281
highlight={anyBackgroundHighlight}
282282
count={anyBackgroundHighlight ? totalBackgroundHighlight : totalBackgroundUnread}

src/app/pages/client/sidebar/DirectDMsList.tsx

Lines changed: 91 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useMemo, useState, useCallback } from 'react';
22
import { useNavigate } from 'react-router-dom';
3-
import { Avatar, Text, Box } from 'folds';
3+
import { Avatar, Text, Box, toRem } from 'folds';
44
import { useAtomValue } from 'jotai';
55
import { Room, SyncState } from '$types/matrix-sdk';
66
import { useDirects } from '$state/hooks/roomList';
@@ -56,62 +56,105 @@ function DMItem({ room, selected }: DMItemProps) {
5656
// Get unread info for badge
5757
const unread = roomToUnread.get(room.roomId);
5858

59-
return (
60-
<SidebarItem active={selected}>
61-
<SidebarItemTooltip tooltip={room.name}>
62-
{(triggerRef) => (
63-
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={handleClick} size="400">
64-
{isGroupDM ? (
65-
<Box className={css.GroupAvatarContainer}>
66-
<Box className={css.GroupAvatarRow}>
67-
{groupMembers.map((member) => {
68-
const avatarUrl = member.avatarUrl
69-
? (mxcUrlToHttp(mx, member.avatarUrl, useAuthentication, 48, 48, 'crop') ??
70-
undefined)
71-
: undefined;
72-
73-
return (
74-
<Avatar
75-
key={member.userId}
76-
size="200"
77-
radii="300"
78-
className={css.GroupAvatar}
79-
>
80-
<UserAvatar
81-
userId={member.userId}
82-
src={avatarUrl}
83-
alt={member.displayName || member.userId}
84-
renderFallback={() => (
85-
<Text as="span" size="T300">
86-
{nameInitials(member.displayName || member.userId)}
87-
</Text>
88-
)}
89-
/>
90-
</Avatar>
91-
);
92-
})}
93-
</Box>
94-
</Box>
95-
) : (
96-
<Avatar size="400" radii="400">
97-
<RoomAvatar
98-
roomId={room.roomId}
99-
src={getDirectRoomAvatarUrl(mx, room, 96, useAuthentication)}
100-
alt={room.name}
59+
// Determine avatar src for single group DM member to avoid nested ternary
60+
const getSingleMemberAvatarSrc = () => {
61+
if (groupMembers.length !== 1 || !groupMembers[0].avatarUrl) {
62+
return undefined;
63+
}
64+
return (
65+
mxcUrlToHttp(mx, groupMembers[0].avatarUrl, useAuthentication, 96, 96, 'crop') ?? undefined
66+
);
67+
};
68+
69+
// Render appropriate avatar based on DM type
70+
const renderAvatar = () => {
71+
if (!isGroupDM) {
72+
// Regular DM
73+
return (
74+
<Avatar size="400" radii="400">
75+
<RoomAvatar
76+
roomId={room.roomId}
77+
src={getDirectRoomAvatarUrl(mx, room, 96, useAuthentication)}
78+
alt={room.name}
79+
renderFallback={() => (
80+
<Text as="span" size="H6">
81+
{nameInitials(room.name)}
82+
</Text>
83+
)}
84+
/>
85+
</Avatar>
86+
);
87+
}
88+
89+
if (groupMembers.length === 1) {
90+
// Single member in group DM - fill the space like a normal DM
91+
return (
92+
<Avatar size="400" radii="400">
93+
<UserAvatar
94+
userId={groupMembers[0].userId}
95+
src={getSingleMemberAvatarSrc()}
96+
alt={groupMembers[0].displayName || groupMembers[0].userId}
97+
renderFallback={() => (
98+
<Text as="span" size="H6">
99+
{nameInitials(groupMembers[0].displayName || groupMembers[0].userId)}
100+
</Text>
101+
)}
102+
/>
103+
</Avatar>
104+
);
105+
}
106+
107+
// Multiple members in group DM - triangle layout
108+
return (
109+
<Box className={css.GroupAvatarContainer}>
110+
<Box className={css.GroupAvatarRow}>
111+
{groupMembers.map((member) => {
112+
const avatarUrl = member.avatarUrl
113+
? (mxcUrlToHttp(mx, member.avatarUrl, useAuthentication, 48, 48, 'crop') ?? undefined)
114+
: undefined;
115+
116+
return (
117+
<Avatar key={member.userId} size="200" radii="300" className={css.GroupAvatar}>
118+
<UserAvatar
119+
userId={member.userId}
120+
src={avatarUrl}
121+
alt={member.displayName || member.userId}
101122
renderFallback={() => (
102-
<Text as="span" size="H6">
103-
{nameInitials(room.name)}
123+
<Text as="span" size="T300">
124+
{nameInitials(member.displayName || member.userId)}
104125
</Text>
105126
)}
106127
/>
107128
</Avatar>
108-
)}
129+
);
130+
})}
131+
</Box>
132+
</Box>
133+
);
134+
};
135+
136+
return (
137+
<SidebarItem active={selected}>
138+
<SidebarItemTooltip tooltip={room.name}>
139+
{(triggerRef) => (
140+
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={handleClick} size="400">
141+
{renderAvatar()}
109142
</SidebarAvatar>
110143
)}
111144
</SidebarItemTooltip>
112145
{unread && (unread.total > 0 || unread.highlight > 0) && (
113-
<SidebarItemBadge hasCount={unread.total > 0}>
114-
<UnreadBadge highlight={unread.highlight > 0} count={unread.total} dm />
146+
<SidebarItemBadge
147+
hasCount={unread.total > 0}
148+
style={{
149+
left: unread.total > 0 ? toRem(-6) : toRem(-2),
150+
right: 'auto',
151+
}}
152+
>
153+
<UnreadBadge
154+
highlight={unread.highlight > 0}
155+
count={unread.highlight > 0 ? unread.highlight : unread.total}
156+
dm
157+
/>
115158
</SidebarItemBadge>
116159
)}
117160
</SidebarItem>

src/app/pages/client/sidebar/DirectTab.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,13 @@ export function DirectTab() {
107107
)}
108108
</SidebarItemTooltip>
109109
{directUnread && (
110-
<SidebarItemBadge hasCount={directUnread.total > 0}>
110+
<SidebarItemBadge
111+
hasCount={directUnread.total > 0}
112+
style={{
113+
left: directUnread.total > 0 ? toRem(-6) : toRem(-2),
114+
right: 'auto',
115+
}}
116+
>
111117
<UnreadBadge
112118
highlight={directUnread.highlight > 0}
113119
count={directUnread.highlight > 0 ? directUnread.highlight : directUnread.total}

src/app/pages/client/sidebar/HomeTab.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,13 @@ export function HomeTab() {
109109
)}
110110
</SidebarItemTooltip>
111111
{homeUnread && (
112-
<SidebarItemBadge hasCount={homeUnread.total > 0}>
112+
<SidebarItemBadge
113+
hasCount={homeUnread.total > 0}
114+
style={{
115+
left: homeUnread.total > 0 ? toRem(-6) : toRem(-2),
116+
right: 'auto',
117+
}}
118+
>
113119
<UnreadBadge
114120
highlight={homeUnread.highlight > 0}
115121
count={homeUnread.highlight > 0 ? homeUnread.highlight : homeUnread.total}

src/app/pages/client/sidebar/InboxTab.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useNavigate } from 'react-router-dom';
2-
import { Icon, Icons } from 'folds';
2+
import { Icon, Icons, toRem } from 'folds';
33
import { useAtomValue } from 'jotai';
44
import {
55
SidebarAvatar,
@@ -52,7 +52,7 @@ export function InboxTab() {
5252
)}
5353
</SidebarItemTooltip>
5454
{inviteCount > 0 && (
55-
<SidebarItemBadge hasCount>
55+
<SidebarItemBadge hasCount style={{ left: toRem(-6), right: 'auto' }}>
5656
<UnreadBadge highlight count={inviteCount} />
5757
</SidebarItemBadge>
5858
)}

src/app/pages/client/sidebar/SpaceTabs.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,13 @@ function SpaceTab({
465465
)}
466466
</SidebarItemTooltip>
467467
{unread && (
468-
<SidebarItemBadge hasCount={unread.total > 0}>
468+
<SidebarItemBadge
469+
hasCount={unread.total > 0}
470+
style={{
471+
left: unread.total > 0 ? toRem(-6) : toRem(-2),
472+
right: 'auto',
473+
}}
474+
>
469475
<UnreadBadge
470476
highlight={unread.highlight > 0}
471477
count={unread.highlight > 0 ? unread.highlight : unread.total}
@@ -600,7 +606,13 @@ function ClosedSpaceFolder({
600606
)}
601607
</SidebarItemTooltip>
602608
{unread && (
603-
<SidebarItemBadge hasCount={unread.total > 0}>
609+
<SidebarItemBadge
610+
hasCount={unread.total > 0}
611+
style={{
612+
left: unread.total > 0 ? toRem(-6) : toRem(-2),
613+
right: 'auto',
614+
}}
615+
>
604616
<UnreadBadge
605617
highlight={unread.highlight > 0}
606618
count={unread.highlight > 0 ? unread.highlight : unread.total}

0 commit comments

Comments
 (0)