diff --git a/.changeset/fix-badge-positioning.md b/.changeset/fix-badge-positioning.md new file mode 100644 index 000000000..a6d3e50cd --- /dev/null +++ b/.changeset/fix-badge-positioning.md @@ -0,0 +1,5 @@ +--- +'default': patch +--- + +Fix badge positioning and alignment across all sidebar components diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..a4a7a41bc --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v24.14.0 diff --git a/src/app/components/message/layout/layout.css.ts b/src/app/components/message/layout/layout.css.ts index 32dedb17d..76b7d1609 100644 --- a/src/app/components/message/layout/layout.css.ts +++ b/src/app/components/message/layout/layout.css.ts @@ -220,6 +220,7 @@ export const PronounPill = style({ export const MessageTextBody = recipe({ base: { wordBreak: 'break-word', + fontSize: '1rem !important', // Override folds Text component to enable page zoom scaling }, variants: { preWrap: { @@ -229,27 +230,27 @@ export const MessageTextBody = recipe({ }, jumboEmoji: { none: { - fontSize: '1em', + fontSize: '1rem !important', lineHeight: 'inherit', }, extraSmall: { - fontSize: '1.25em', + fontSize: '1.25rem !important', lineHeight: '1.4em', }, small: { - fontSize: '1.5em', + fontSize: '1.5rem !important', lineHeight: '1.5em', }, normal: { - fontSize: '1.805em', + fontSize: '1.805rem !important', lineHeight: '1.625em', }, large: { - fontSize: '2.1em', + fontSize: '2.1rem !important', lineHeight: '1.675em', }, extraLarge: { - fontSize: '2.4em', + fontSize: '2.4rem !important', lineHeight: '1.7em', }, }, diff --git a/src/app/components/sidebar/Sidebar.css.ts b/src/app/components/sidebar/Sidebar.css.ts index 76337ed2d..b96307ae0 100644 --- a/src/app/components/sidebar/Sidebar.css.ts +++ b/src/app/components/sidebar/Sidebar.css.ts @@ -142,6 +142,39 @@ export const SidebarItemBadge = recipe({ defaultVariants: { hasCount: false, }, + // Adjust positioning when badge is on a folder (closed folder button) + compoundVariants: [ + { + variants: { + hasCount: true, + }, + style: { + selectors: { + // When the badge is within an item containing a closed folder, adjust position + // to align with the folder's square border + 'div:has(> button[data-id]) &': { + top: toRem(0), + left: 'auto', + right: toRem(0), + }, + }, + }, + }, + { + variants: { + hasCount: false, + }, + style: { + selectors: { + 'div:has(> button[data-id]) &': { + top: toRem(2), + left: 'auto', + right: toRem(2), + }, + }, + }, + }, + ], }); export type SidebarItemBadgeVariants = RecipeVariants; diff --git a/src/app/pages/client/sidebar/AccountSwitcherTab.tsx b/src/app/pages/client/sidebar/AccountSwitcherTab.tsx index 7d2a3ca11..1b722d244 100644 --- a/src/app/pages/client/sidebar/AccountSwitcherTab.tsx +++ b/src/app/pages/client/sidebar/AccountSwitcherTab.tsx @@ -276,7 +276,7 @@ export function AccountSwitcherTab() { )} {(totalBackgroundUnread > 0 || anyBackgroundHighlight) && ( - + - - {(triggerRef) => ( - - {isGroupDM ? ( - - - {groupMembers.map((member) => { - const avatarUrl = member.avatarUrl - ? (mxcUrlToHttp(mx, member.avatarUrl, useAuthentication, 48, 48, 'crop') ?? - undefined) - : undefined; - - return ( - - ( - - {nameInitials(member.displayName || member.userId)} - - )} - /> - - ); - })} - - - ) : ( - - { + if (groupMembers.length !== 1 || !groupMembers[0].avatarUrl) { + return undefined; + } + return ( + mxcUrlToHttp(mx, groupMembers[0].avatarUrl, useAuthentication, 96, 96, 'crop') ?? undefined + ); + }; + + // Render appropriate avatar based on DM type + const renderAvatar = () => { + if (!isGroupDM) { + // Regular DM + return ( + + ( + + {nameInitials(room.name)} + + )} + /> + + ); + } + + if (groupMembers.length === 1) { + // Single member in group DM - fill the space like a normal DM + return ( + + ( + + {nameInitials(groupMembers[0].displayName || groupMembers[0].userId)} + + )} + /> + + ); + } + + // Multiple members in group DM - triangle layout + return ( + + + {groupMembers.map((member) => { + const avatarUrl = member.avatarUrl + ? (mxcUrlToHttp(mx, member.avatarUrl, useAuthentication, 48, 48, 'crop') ?? undefined) + : undefined; + + return ( + + ( - - {nameInitials(room.name)} + + {nameInitials(member.displayName || member.userId)} )} /> - )} + ); + })} + + + ); + }; + + return ( + + + {(triggerRef) => ( + + {renderAvatar()} )} {unread && (unread.total > 0 || unread.highlight > 0) && ( - 0}> - 0} count={unread.total} dm /> + 0} + style={{ + left: unread.total > 0 ? toRem(-6) : toRem(-2), + right: 'auto', + }} + > + 0} + count={unread.highlight > 0 ? unread.highlight : unread.total} + dm + /> )} diff --git a/src/app/pages/client/sidebar/DirectTab.tsx b/src/app/pages/client/sidebar/DirectTab.tsx index b59f852c6..dd2a7d6e8 100644 --- a/src/app/pages/client/sidebar/DirectTab.tsx +++ b/src/app/pages/client/sidebar/DirectTab.tsx @@ -107,7 +107,13 @@ export function DirectTab() { )} {directUnread && ( - 0}> + 0} + style={{ + left: directUnread.total > 0 ? toRem(-6) : toRem(-2), + right: 'auto', + }} + > 0} count={directUnread.highlight > 0 ? directUnread.highlight : directUnread.total} diff --git a/src/app/pages/client/sidebar/HomeTab.tsx b/src/app/pages/client/sidebar/HomeTab.tsx index ba02326ee..611957f33 100644 --- a/src/app/pages/client/sidebar/HomeTab.tsx +++ b/src/app/pages/client/sidebar/HomeTab.tsx @@ -109,7 +109,13 @@ export function HomeTab() { )} {homeUnread && ( - 0}> + 0} + style={{ + left: homeUnread.total > 0 ? toRem(-6) : toRem(-2), + right: 'auto', + }} + > 0} count={homeUnread.highlight > 0 ? homeUnread.highlight : homeUnread.total} diff --git a/src/app/pages/client/sidebar/InboxTab.tsx b/src/app/pages/client/sidebar/InboxTab.tsx index ec3bb21d1..9488d1029 100644 --- a/src/app/pages/client/sidebar/InboxTab.tsx +++ b/src/app/pages/client/sidebar/InboxTab.tsx @@ -1,5 +1,5 @@ import { useNavigate } from 'react-router-dom'; -import { Icon, Icons } from 'folds'; +import { Icon, Icons, toRem } from 'folds'; import { useAtomValue } from 'jotai'; import { SidebarAvatar, @@ -52,7 +52,7 @@ export function InboxTab() { )} {inviteCount > 0 && ( - + )} diff --git a/src/app/pages/client/sidebar/SpaceTabs.tsx b/src/app/pages/client/sidebar/SpaceTabs.tsx index 15ebd518d..a758cc1f8 100644 --- a/src/app/pages/client/sidebar/SpaceTabs.tsx +++ b/src/app/pages/client/sidebar/SpaceTabs.tsx @@ -465,7 +465,13 @@ function SpaceTab({ )} {unread && ( - 0}> + 0} + style={{ + left: unread.total > 0 ? toRem(-6) : toRem(-2), + right: 'auto', + }} + > 0} count={unread.highlight > 0 ? unread.highlight : unread.total} @@ -600,7 +606,13 @@ function ClosedSpaceFolder({ )} {unread && ( - 0}> + 0} + style={{ + left: unread.total > 0 ? toRem(-6) : toRem(-2), + right: 'auto', + }} + > 0} count={unread.highlight > 0 ? unread.highlight : unread.total} diff --git a/src/app/pages/client/sidebar/UnverifiedTab.tsx b/src/app/pages/client/sidebar/UnverifiedTab.tsx index 3aca66551..a6c446b44 100644 --- a/src/app/pages/client/sidebar/UnverifiedTab.tsx +++ b/src/app/pages/client/sidebar/UnverifiedTab.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { Badge, color, Icon, Icons, Text } from 'folds'; +import { Badge, color, Icon, Icons, Text, toRem } from 'folds'; import { SidebarAvatar, SidebarItem, @@ -66,7 +66,7 @@ function UnverifiedIndicator() { )} {!unverified && unverifiedDeviceCount && unverifiedDeviceCount > 0 && ( - + {unverifiedDeviceCount}