Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/renderer/components/notifications/AccountHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { type Account, type GitifyError, Size } from '../../types';
import { getAdapter } from '../../utils/forges/registry';
import { openAccountProfile, openHostIssues, openHostPulls } from '../../utils/system/links';
import { getChevronDetails } from '../../utils/ui/display';
import { getChevronIcon } from '../../utils/ui/icons';
import { AvatarWithFallback } from '../avatars/AvatarWithFallback';

export interface AccountHeaderProps {
Expand All @@ -30,7 +31,7 @@ export function AccountHeader({
isCollapsed,
onToggle,
}: Readonly<AccountHeaderProps>) {
const Chevron = getChevronDetails(notificationCount > 0, !isCollapsed, 'account');
const chevron = getChevronDetails(notificationCount > 0, !isCollapsed, 'account');

return (
<Stack
Expand Down Expand Up @@ -82,8 +83,8 @@ export function AccountHeader({

<HoverButton
action={onToggle}
icon={Chevron.icon}
label={Chevron.label}
icon={getChevronIcon(chevron.direction)}
label={chevron.label}
testid="account-toggle"
/>
</HoverGroup>
Expand Down
7 changes: 4 additions & 3 deletions src/renderer/components/notifications/RepositoryHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { isMarkAsDoneFeatureSupported } from '../../utils/api/features';
import { shouldRemoveNotificationsFromState } from '../../utils/notifications/remove';
import { openRepository } from '../../utils/system/links';
import { getChevronDetails } from '../../utils/ui/display';
import { getChevronIcon } from '../../utils/ui/icons';
import { AvatarWithFallback } from '../avatars/AvatarWithFallback';

export interface RepositoryHeaderProps {
Expand Down Expand Up @@ -52,7 +53,7 @@ export function RepositoryHeader({
(notification) => !notification.unread,
);

const Chevron = getChevronDetails(true, !isCollapsed, 'repository');
const chevron = getChevronDetails(true, !isCollapsed, 'repository');

return (
<Stack
Expand Down Expand Up @@ -110,8 +111,8 @@ export function RepositoryHeader({

<HoverButton
action={onToggle}
icon={Chevron.icon}
label={Chevron.label}
icon={getChevronIcon(chevron.direction)}
label={chevron.label}
testid="repository-toggle"
/>
</HoverGroup>
Expand Down
10 changes: 7 additions & 3 deletions src/renderer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,15 +283,19 @@ export enum Size {
XLARGE = 20,
}

/**
* The direction a chevron points.
*/
export type ChevronDirection = 'down' | 'left' | 'right';

/**
* Details for Chevron header accordion.
*/
export interface Chevron {
/**
* The chevron icon.
* The direction the chevron points.
*/
// TODO - improve the type here to be more specific about which icons are allowed, if possible
icon: FC<OcticonProps>;
direction: ChevronDirection;

/**
* The chevron label.
Expand Down
8 changes: 3 additions & 5 deletions src/renderer/utils/ui/display.test.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from '@primer/octicons-react';

import { getChevronDetails, parseInlineCode } from './display';

describe('renderer/utils/ui/display.ts', () => {
describe('getChevronDetails', () => {
it('returns correct chevron details', () => {
expect(getChevronDetails(true, true, 'account')).toEqual({
icon: ChevronDownIcon,
direction: 'down',
label: 'Hide account notifications',
});

expect(getChevronDetails(true, false, 'account')).toEqual({
icon: ChevronRightIcon,
direction: 'right',
label: 'Show account notifications',
});

expect(getChevronDetails(false, false, 'account')).toEqual({
icon: ChevronLeftIcon,
direction: 'left',
label: 'No notifications for account',
});
});
Expand Down
12 changes: 5 additions & 7 deletions src/renderer/utils/ui/display.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from '@primer/octicons-react';

import type { Chevron } from '../../types';

export interface ParsedCodePart {
Expand All @@ -9,12 +7,12 @@ export interface ParsedCodePart {
}

/**
* Returns the appropriate chevron icon and accessible label for a collapsible section.
* Returns the appropriate chevron direction and accessible label for a collapsible section.
*
* @param hasNotifications - Whether the section has any notifications to display.
* @param isVisible - Whether the section is currently expanded/visible.
* @param type - The type of section (`'account'` or `'repository'`).
* @returns A `Chevron` object containing the icon component and its accessible label.
* @returns A `Chevron` object containing the direction and its accessible label.
*/
export function getChevronDetails(
hasNotifications: boolean,
Expand All @@ -23,20 +21,20 @@ export function getChevronDetails(
): Chevron {
if (!hasNotifications) {
return {
icon: ChevronLeftIcon,
direction: 'left',
label: `No notifications for ${type}`,
};
}

if (isVisible) {
return {
icon: ChevronDownIcon,
direction: 'down',
label: `Hide ${type} notifications`,
};
}

return {
icon: ChevronRightIcon,
direction: 'right',
label: `Show ${type} notifications`,
};
}
Expand Down
10 changes: 10 additions & 0 deletions src/renderer/utils/ui/icons.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import {
CheckIcon,
ChevronDownIcon,
ChevronLeftIcon,
ChevronRightIcon,
CommentIcon,
FeedPersonIcon,
FileDiffIcon,
Expand All @@ -10,6 +13,7 @@ import {
import { IconColor } from '../../types';

import {
getChevronIcon,
getDefaultUserIcon,
getPlatformIcon,
getPullRequestReviewIcon,
Expand Down Expand Up @@ -125,4 +129,10 @@ describe('renderer/utils/icons.ts', () => {
expect(getDefaultUserIcon('Organization')).toBe(OrganizationIcon);
expect(getDefaultUserIcon('User')).toBe(FeedPersonIcon);
});

it('getChevronIcon', () => {
expect(getChevronIcon('down')).toBe(ChevronDownIcon);
expect(getChevronIcon('left')).toBe(ChevronLeftIcon);
expect(getChevronIcon('right')).toBe(ChevronRightIcon);
});
});
21 changes: 20 additions & 1 deletion src/renderer/utils/ui/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@ import type { FC } from 'react';

import {
CheckIcon,
ChevronDownIcon,
ChevronLeftIcon,
ChevronRightIcon,
CommentIcon,
FeedPersonIcon,
FileDiffIcon,
type Icon,
MarkGithubIcon,
type OcticonProps,
OrganizationIcon,
ServerIcon,
ShieldCheckIcon,
} from '@primer/octicons-react';

import { IconColor, type PullRequestApprovalIcon, type UserType } from '../../types';
import {
type ChevronDirection,
IconColor,
type PullRequestApprovalIcon,
type UserType,
} from '../../types';
import type { PlatformType } from '../auth/types';

import { BitbucketIcon } from '../../icons/BitbucketIcon';
Expand Down Expand Up @@ -90,3 +99,13 @@ export function getDefaultUserIcon(userType: UserType) {
return FeedPersonIcon;
}
}

const CHEVRON_ICONS: Record<ChevronDirection, Icon> = {
down: ChevronDownIcon,
left: ChevronLeftIcon,
right: ChevronRightIcon,
};

export function getChevronIcon(direction: ChevronDirection): Icon {
return CHEVRON_ICONS[direction];
}
Loading