From b3a7f6356b1fd43ee6ede68b4df6759cc4771aa1 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Wed, 14 Oct 2026 08:31:52 -0400 Subject: [PATCH] refactor(renderer): use function declarations for React components Enable oxlint's react/function-component-definition rule (named components as function declarations; anonymous components stay arrow functions) and migrate the renderer's component definitions from React.FC arrows to function declarations, moving each prop type onto its parameter and pruning the FC imports whose only use was the definition. React.FC is retained where it types a component value (a prop or a return type), which the rule does not govern. No runtime behavior change: component output, props, and rendering are identical. Verified with pnpm check (format, lint, types), pnpm test (1901 tests, icon snapshots unchanged), and a lint probe confirming an arrow component now fails the check. --- CONTRIBUTING.md | 1 + src/renderer/App.tsx | 4 +- src/renderer/components/AllRead.tsx | 6 +- src/renderer/components/GlobalEffects.tsx | 6 +- src/renderer/components/GlobalShortcuts.tsx | 6 +- src/renderer/components/Oops.tsx | 6 +- src/renderer/components/Sidebar.tsx | 6 +- .../components/avatars/AvatarWithFallback.tsx | 7 +- src/renderer/components/fields/Checkbox.tsx | 6 +- src/renderer/components/fields/FieldLabel.tsx | 6 +- src/renderer/components/fields/RadioGroup.tsx | 6 +- src/renderer/components/fields/Tooltip.tsx | 6 +- .../components/filters/AccountFilter.tsx | 6 +- .../components/filters/FilterSection.tsx | 6 +- .../components/filters/ReasonFilter.tsx | 6 +- .../RequiresDetailedNotificationsWarning.tsx | 16 ++-- .../filters/ReviewRequestTypeFilter.tsx | 6 +- .../components/filters/SearchFilter.tsx | 6 +- .../filters/SearchFilterSuggestions.tsx | 6 +- .../components/filters/StateFilter.tsx | 6 +- .../components/filters/SubjectTypeFilter.tsx | 6 +- .../components/filters/TokenSearchInput.tsx | 6 +- .../components/filters/UserTypeFilter.tsx | 6 +- src/renderer/components/layout/AppLayout.tsx | 6 +- src/renderer/components/layout/Centered.tsx | 6 +- src/renderer/components/layout/Contents.tsx | 8 +- .../components/layout/EmojiSplash.tsx | 6 +- src/renderer/components/layout/Page.tsx | 6 +- .../LoginWithPersonalAccessTokenForm.tsx | 8 +- .../components/metrics/CommentsPill.tsx | 6 +- .../components/metrics/IssueTypesPill.tsx | 6 +- .../components/metrics/LabelsPill.tsx | 6 +- .../components/metrics/LinkedIssuesPill.tsx | 6 +- .../components/metrics/MetricGroup.tsx | 6 +- .../components/metrics/MetricPill.tsx | 4 +- .../components/metrics/MilestonePill.tsx | 6 +- .../components/metrics/ParentPill.tsx | 6 +- .../components/metrics/ReactionsPill.tsx | 6 +- .../components/metrics/ReviewsPill.tsx | 6 +- .../components/metrics/StackedPrsPill.tsx | 10 +-- .../metrics/SubIssueProgressPill.tsx | 12 ++- .../notifications/AccountHeader.tsx | 8 +- .../notifications/NotificationFooter.tsx | 8 +- .../notifications/NotificationHeader.tsx | 8 +- .../notifications/NotificationList.tsx | 8 +- .../notifications/NotificationRow.tsx | 8 +- .../notifications/NotificationTitle.tsx | 8 +- .../notifications/RepositoryHeader.tsx | 8 +- .../components/primitives/CustomCounter.tsx | 6 +- .../components/primitives/EmojiText.tsx | 6 +- src/renderer/components/primitives/Footer.tsx | 6 +- src/renderer/components/primitives/Header.tsx | 5 +- .../components/primitives/HoverButton.tsx | 10 +-- .../components/primitives/HoverGroup.tsx | 10 +-- src/renderer/components/primitives/Title.tsx | 6 +- .../settings/AppearanceSettings.tsx | 6 +- .../settings/NotificationSettings.tsx | 6 +- .../components/settings/SettingsFooter.tsx | 6 +- .../components/settings/SettingsReset.tsx | 6 +- .../components/settings/SystemSettings.tsx | 6 +- .../components/settings/TraySettings.tsx | 6 +- src/renderer/icons/BitbucketIcon.tsx | 36 ++++---- src/renderer/icons/GitLabIcon.tsx | 36 ++++---- src/renderer/icons/LogoIcon.tsx | 87 +++++++++---------- src/renderer/icons/ScopeStatusIcon.tsx | 8 +- src/renderer/icons/VolumeDownIcon.tsx | 38 ++++---- src/renderer/icons/VolumeUpIcon.tsx | 34 ++++---- src/renderer/routes/AccountScopes.tsx | 5 +- src/renderer/routes/Accounts.tsx | 16 ++-- src/renderer/routes/Filters.tsx | 6 +- src/renderer/routes/Login.tsx | 6 +- src/renderer/routes/Notifications.tsx | 6 +- src/renderer/routes/Settings.tsx | 6 +- .../LoginWithPersonalAccessToken.tsx | 32 +++---- .../gitea/LoginWithPersonalAccessToken.tsx | 28 +++--- .../routes/github/LoginWithDeviceFlow.tsx | 6 +- .../routes/github/LoginWithGitHubCLI.tsx | 6 +- .../routes/github/LoginWithOAuthApp.tsx | 6 +- .../github/LoginWithPersonalAccessToken.tsx | 48 +++++----- .../gitlab/LoginWithPersonalAccessToken.tsx | 40 ++++----- vite.config.mts | 7 ++ 81 files changed, 391 insertions(+), 469 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4ec75ed30..aea7fb27a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -88,6 +88,7 @@ the macOS native vibrancy material, which Chromium cannot render. ### 🎨 Code Style & Conventions - Linting and formatting are configured in `vite.config.mts` (the `lint` and `fmt` blocks). Please run `pnpm check` before submitting a PR. +- Renderer React components are defined as function declarations. `React.FC` is reserved for typing a component value (a prop or return type), never a component definition; `react/function-component-definition` enforces this. - Follow existing file and folder naming conventions. - See [ARCHITECTURE.md](./ARCHITECTURE.md) for the renderer's module layering, state ownership, and side-effect conventions. - Keep commit messages clear and descriptive. diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index 135053ab6..19f4e11ef 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -42,7 +42,7 @@ function RequireAuth({ children }: { children: React.ReactNode }) { return isLoggedIn ? children : ; } -export const App = () => { +export function App() { // Initialize store subscriptions with proper cleanup useEffect(() => { const cleanup = initializeStoreSubscriptions(); @@ -128,4 +128,4 @@ export const App = () => { ); -}; +} diff --git a/src/renderer/components/AllRead.tsx b/src/renderer/components/AllRead.tsx index 608655e8c..2d26162e0 100644 --- a/src/renderer/components/AllRead.tsx +++ b/src/renderer/components/AllRead.tsx @@ -1,4 +1,4 @@ -import { type FC, useMemo } from 'react'; +import { useMemo } from 'react'; import { Constants } from '../constants'; @@ -12,7 +12,7 @@ interface AllReadProps { fullHeight?: boolean; } -export const AllRead: FC = ({ fullHeight = true }: AllReadProps) => { +export function AllRead({ fullHeight = true }: AllReadProps) { const hasFilters = useFiltersStore((s) => s.hasActiveFilters()); const emoji = useMemo(() => randomElement(Constants.EMOJIS.ALL_READ), []); @@ -20,4 +20,4 @@ export const AllRead: FC = ({ fullHeight = true }: AllReadProps) = const heading = `No new ${hasFilters ? 'filtered ' : ''} notifications`; return ; -}; +} diff --git a/src/renderer/components/GlobalEffects.tsx b/src/renderer/components/GlobalEffects.tsx index f44699a31..235096bb4 100644 --- a/src/renderer/components/GlobalEffects.tsx +++ b/src/renderer/components/GlobalEffects.tsx @@ -1,4 +1,4 @@ -import { type FC, useEffect } from 'react'; +import { useEffect } from 'react'; import { useQueryClient } from '@tanstack/react-query'; @@ -23,7 +23,7 @@ import { setTrayIconColorAndTitle } from '../utils/system/tray'; * Owns: theme application, tray icon updates, global shortcut registration, * app reset handling, periodic account refreshes, and notification alerts. */ -export const GlobalEffects: FC = () => { +export function GlobalEffects() { const queryClient = useQueryClient(); const resetAccounts = useAccountsStore((s) => s.reset); @@ -74,4 +74,4 @@ export const GlobalEffects: FC = () => { }, [resetAccounts, resetSettings, resetFilters, queryClient]); return null; -}; +} diff --git a/src/renderer/components/GlobalShortcuts.tsx b/src/renderer/components/GlobalShortcuts.tsx index ef1390ad1..f15626317 100644 --- a/src/renderer/components/GlobalShortcuts.tsx +++ b/src/renderer/components/GlobalShortcuts.tsx @@ -1,4 +1,4 @@ -import { type FC, useEffect } from 'react'; +import { useEffect } from 'react'; import { useShortcutActions } from '../hooks/useShortcutActions'; @@ -8,7 +8,7 @@ import { getNormalizedKey, shouldIgnoreKeyboardEvent } from '../utils/ui/keyboar * Component that registers global keyboard shortcuts for the renderer app. * Mount once inside App, within Router + AppProvider. */ -export const GlobalShortcuts: FC = () => { +export function GlobalShortcuts() { const { shortcuts } = useShortcutActions(); useEffect(() => { @@ -41,4 +41,4 @@ export const GlobalShortcuts: FC = () => { }, [shortcuts]); return null; -}; +} diff --git a/src/renderer/components/Oops.tsx b/src/renderer/components/Oops.tsx index 89a379ef2..51f86bb0c 100644 --- a/src/renderer/components/Oops.tsx +++ b/src/renderer/components/Oops.tsx @@ -1,4 +1,4 @@ -import { type FC, useMemo } from 'react'; +import { useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import { Button } from '@primer/react'; @@ -15,7 +15,7 @@ interface OopsProps { fullHeight?: boolean; } -export const Oops: FC = ({ error, fullHeight = true }: OopsProps) => { +export function Oops({ error, fullHeight = true }: OopsProps) { const navigate = useNavigate(); const err = error ?? Errors.UNKNOWN; @@ -44,4 +44,4 @@ export const Oops: FC = ({ error, fullHeight = true }: OopsProps) => subHeadings={err.descriptions} /> ); -}; +} diff --git a/src/renderer/components/Sidebar.tsx b/src/renderer/components/Sidebar.tsx index 2e3c38941..159126a64 100644 --- a/src/renderer/components/Sidebar.tsx +++ b/src/renderer/components/Sidebar.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { BellIcon, CrosshairsIcon, @@ -21,7 +19,7 @@ import { useAccountsStore, useFiltersStore, useSettingsStore } from '../stores'; import { LogoIcon } from '../icons/LogoIcon'; -export const Sidebar: FC = () => { +export function Sidebar() { const { status, notificationCount, hasUnreadNotifications, isFetching } = useNotifications(); const { shortcuts } = useShortcutActions(); @@ -165,4 +163,4 @@ export const Sidebar: FC = () => { ); -}; +} diff --git a/src/renderer/components/avatars/AvatarWithFallback.tsx b/src/renderer/components/avatars/AvatarWithFallback.tsx index 01344aeaf..eb277ec76 100644 --- a/src/renderer/components/avatars/AvatarWithFallback.tsx +++ b/src/renderer/components/avatars/AvatarWithFallback.tsx @@ -1,4 +1,3 @@ -import type React from 'react'; import type { FC } from 'react'; import { createElement, useState } from 'react'; @@ -20,14 +19,14 @@ export interface AvatarWithFallbackProps { icon?: FC; } -export const AvatarWithFallback: React.FC = ({ +export function AvatarWithFallback({ src, alt, name, size = Size.MEDIUM, userType = 'User', icon, -}) => { +}: AvatarWithFallbackProps) { const [hasBrokenAvatarSource, setHasBrokenAvatarSource] = useState(false); const isNonHuman = isNonHumanUser(userType); @@ -54,4 +53,4 @@ export const AvatarWithFallback: React.FC = ({ )} ); -}; +} diff --git a/src/renderer/components/fields/Checkbox.tsx b/src/renderer/components/fields/Checkbox.tsx index 3b21f7c7d..1cf5a0861 100644 --- a/src/renderer/components/fields/Checkbox.tsx +++ b/src/renderer/components/fields/Checkbox.tsx @@ -1,4 +1,4 @@ -import type { FC, ReactNode } from 'react'; +import type { ReactNode } from 'react'; import { Stack } from '@primer/react'; @@ -19,7 +19,7 @@ export interface CheckboxProps { onChange: (evt: React.ChangeEvent) => void; } -export const Checkbox: FC = ({ visible = true, ...props }: CheckboxProps) => { +export function Checkbox({ visible = true, ...props }: CheckboxProps) { const counter = props?.counter === 0 ? '0' : props.counter; return ( @@ -53,4 +53,4 @@ export const Checkbox: FC = ({ visible = true, ...props }: Checkb ) ); -}; +} diff --git a/src/renderer/components/fields/FieldLabel.tsx b/src/renderer/components/fields/FieldLabel.tsx index 4d9dec3a4..4c09203ce 100644 --- a/src/renderer/components/fields/FieldLabel.tsx +++ b/src/renderer/components/fields/FieldLabel.tsx @@ -1,14 +1,12 @@ -import type { FC } from 'react'; - export interface FieldLabelProps { name: string; label: string; } -export const FieldLabel: FC = (props: FieldLabelProps) => { +export function FieldLabel(props: FieldLabelProps) { return ( ); -}; +} diff --git a/src/renderer/components/fields/RadioGroup.tsx b/src/renderer/components/fields/RadioGroup.tsx index aa6635bfb..8d8cd27de 100644 --- a/src/renderer/components/fields/RadioGroup.tsx +++ b/src/renderer/components/fields/RadioGroup.tsx @@ -1,4 +1,4 @@ -import type { ChangeEvent, FC, ReactNode } from 'react'; +import type { ChangeEvent, ReactNode } from 'react'; import { Stack } from '@primer/react'; @@ -16,7 +16,7 @@ export interface RadioGroupProps { tooltip?: ReactNode | string; } -export const RadioGroup: FC = (props: RadioGroupProps) => { +export function RadioGroup(props: RadioGroupProps) { return ( @@ -44,4 +44,4 @@ export const RadioGroup: FC = (props: RadioGroupProps) => { {props.tooltip && } ); -}; +} diff --git a/src/renderer/components/fields/Tooltip.tsx b/src/renderer/components/fields/Tooltip.tsx index 1c340ca2d..07ff3a163 100644 --- a/src/renderer/components/fields/Tooltip.tsx +++ b/src/renderer/components/fields/Tooltip.tsx @@ -1,4 +1,4 @@ -import { type FC, type ReactNode, useEffect, useRef, useState } from 'react'; +import { type ReactNode, useEffect, useRef, useState } from 'react'; import { QuestionIcon } from '@primer/octicons-react'; import { AnchoredOverlay } from '@primer/react'; @@ -10,7 +10,7 @@ export interface TooltipProps { tooltip: ReactNode | string; } -export const Tooltip: FC = (props: TooltipProps) => { +export function Tooltip(props: TooltipProps) { const [shouldShowTooltipContents, setShouldShowTooltipContents] = useState(false); const scrollContainerRef = useRef(null); @@ -100,4 +100,4 @@ export const Tooltip: FC = (props: TooltipProps) => { ); -}; +} diff --git a/src/renderer/components/filters/AccountFilter.tsx b/src/renderer/components/filters/AccountFilter.tsx index ff452e7d7..8a9ffbec0 100644 --- a/src/renderer/components/filters/AccountFilter.tsx +++ b/src/renderer/components/filters/AccountFilter.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { PersonIcon } from '@primer/octicons-react'; import { Stack, Text } from '@primer/react'; @@ -11,7 +9,7 @@ import { Title } from '../primitives/Title'; import { getAccountUUID } from '../../utils/auth/utils'; -export const AccountFilter: FC = () => { +export function AccountFilter() { const { notifications } = useNotifications(); const accounts = useAccountsStore((s) => s.accounts); const filteredAccounts = useFiltersStore((s) => s.accounts); @@ -46,4 +44,4 @@ export const AccountFilter: FC = () => { ); -}; +} diff --git a/src/renderer/components/filters/FilterSection.tsx b/src/renderer/components/filters/FilterSection.tsx index f5f946071..6a673c677 100644 --- a/src/renderer/components/filters/FilterSection.tsx +++ b/src/renderer/components/filters/FilterSection.tsx @@ -22,7 +22,7 @@ export interface FilterSectionProps { layout?: 'horizontal' | 'vertical'; } -const FilterSectionComponent = ({ +function FilterSectionComponent({ id, title, icon, @@ -30,7 +30,7 @@ const FilterSectionComponent = ({ filterSetting, tooltip, layout = 'vertical', -}: FilterSectionProps) => { +}: FilterSectionProps) { const { notifications } = useNotifications(); const updateFilter = useFiltersStore((s) => s.updateFilter); @@ -102,7 +102,7 @@ const FilterSectionComponent = ({ ); -}; +} // Memoize the component to prevent unnecessary re-renders export const FilterSection = memo(FilterSectionComponent) as typeof FilterSectionComponent; diff --git a/src/renderer/components/filters/ReasonFilter.tsx b/src/renderer/components/filters/ReasonFilter.tsx index d3e3b5a30..6b20b2c43 100644 --- a/src/renderer/components/filters/ReasonFilter.tsx +++ b/src/renderer/components/filters/ReasonFilter.tsx @@ -1,12 +1,10 @@ -import type { FC } from 'react'; - import { NoteIcon } from '@primer/octicons-react'; import { Text } from '@primer/react'; import { reasonFilter } from '../../utils/notifications/filters'; import { FilterSection } from './FilterSection'; -export const ReasonFilter: FC = () => { +export function ReasonFilter() { return ( { tooltip={Filter notifications by reason.} /> ); -}; +} diff --git a/src/renderer/components/filters/RequiresDetailedNotificationsWarning.tsx b/src/renderer/components/filters/RequiresDetailedNotificationsWarning.tsx index df4c8efd3..8b24d7987 100644 --- a/src/renderer/components/filters/RequiresDetailedNotificationsWarning.tsx +++ b/src/renderer/components/filters/RequiresDetailedNotificationsWarning.tsx @@ -1,10 +1,10 @@ -import type { FC } from 'react'; - import { Text } from '@primer/react'; -export const RequiresDetailedNotificationWarning: FC = () => ( - - ⚠️ This filter requires the Detailed Notifications setting to be - enabled. - -); +export function RequiresDetailedNotificationWarning() { + return ( + + ⚠️ This filter requires the Detailed Notifications setting to be + enabled. + + ); +} diff --git a/src/renderer/components/filters/ReviewRequestTypeFilter.tsx b/src/renderer/components/filters/ReviewRequestTypeFilter.tsx index cd30768fe..dcbce054c 100644 --- a/src/renderer/components/filters/ReviewRequestTypeFilter.tsx +++ b/src/renderer/components/filters/ReviewRequestTypeFilter.tsx @@ -1,12 +1,10 @@ -import type { FC } from 'react'; - import { GitPullRequestIcon } from '@primer/octicons-react'; import { Stack, Text } from '@primer/react'; import { reviewRequestTypeFilter } from '../../utils/notifications/filters'; import { FilterSection } from './FilterSection'; -export const ReviewRequestTypeFilter: FC = () => { +export function ReviewRequestTypeFilter() { return ( { } /> ); -}; +} diff --git a/src/renderer/components/filters/SearchFilter.tsx b/src/renderer/components/filters/SearchFilter.tsx index 3fa33a92e..961fc083d 100644 --- a/src/renderer/components/filters/SearchFilter.tsx +++ b/src/renderer/components/filters/SearchFilter.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { CheckCircleFillIcon, CommentIcon, @@ -27,7 +25,7 @@ import { import { RequiresDetailedNotificationWarning } from './RequiresDetailedNotificationsWarning'; import { TokenSearchInput } from './TokenSearchInput'; -export const SearchFilter: FC = () => { +export function SearchFilter() { const updateFilter = useFiltersStore((s) => s.updateFilter); const includeSearchTokens = useFiltersStore((s) => s.includeSearchTokens); const excludeSearchTokens = useFiltersStore((s) => s.excludeSearchTokens); @@ -136,4 +134,4 @@ export const SearchFilter: FC = () => { ); -}; +} diff --git a/src/renderer/components/filters/SearchFilterSuggestions.tsx b/src/renderer/components/filters/SearchFilterSuggestions.tsx index ee211908d..639e1ca20 100644 --- a/src/renderer/components/filters/SearchFilterSuggestions.tsx +++ b/src/renderer/components/filters/SearchFilterSuggestions.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { Popover, Stack, Text } from '@primer/react'; import { cn } from 'cn'; @@ -19,7 +17,7 @@ interface SearchFilterSuggestionsProps { inputValue: string; } -export const SearchFilterSuggestions: FC = ({ open, inputValue }) => { +export function SearchFilterSuggestions({ open, inputValue }: SearchFilterSuggestionsProps) { const detailedNotifications = useSettingsStore((s) => s.detailedNotifications); if (!open) { @@ -56,4 +54,4 @@ export const SearchFilterSuggestions: FC = ({ open ); -}; +} diff --git a/src/renderer/components/filters/StateFilter.tsx b/src/renderer/components/filters/StateFilter.tsx index 83d1797d3..92de2fc6f 100644 --- a/src/renderer/components/filters/StateFilter.tsx +++ b/src/renderer/components/filters/StateFilter.tsx @@ -1,12 +1,10 @@ -import type { FC } from 'react'; - import { IssueOpenedIcon } from '@primer/octicons-react'; import { Text } from '@primer/react'; import { stateFilter } from '../../utils/notifications/filters'; import { FilterSection } from './FilterSection'; -export const StateFilter: FC = () => { +export function StateFilter() { return ( { tooltip={Filter notifications by state.} /> ); -}; +} diff --git a/src/renderer/components/filters/SubjectTypeFilter.tsx b/src/renderer/components/filters/SubjectTypeFilter.tsx index 4d57fba97..5f9161abb 100644 --- a/src/renderer/components/filters/SubjectTypeFilter.tsx +++ b/src/renderer/components/filters/SubjectTypeFilter.tsx @@ -1,12 +1,10 @@ -import type { FC } from 'react'; - import { BellIcon } from '@primer/octicons-react'; import { Text } from '@primer/react'; import { subjectTypeFilter } from '../../utils/notifications/filters'; import { FilterSection } from './FilterSection'; -export const SubjectTypeFilter: FC = () => { +export function SubjectTypeFilter() { return ( { tooltip={Filter notifications by type.} /> ); -}; +} diff --git a/src/renderer/components/filters/TokenSearchInput.tsx b/src/renderer/components/filters/TokenSearchInput.tsx index 3ea8b0c7a..2a9172e6e 100644 --- a/src/renderer/components/filters/TokenSearchInput.tsx +++ b/src/renderer/components/filters/TokenSearchInput.tsx @@ -19,7 +19,7 @@ interface TokenSearchInputProps { const INPUT_KEY_EVENTS: Set = new Set(['Enter', 'Tab', ' ', ',']); -export const TokenSearchInput: FC = ({ +export function TokenSearchInput({ label, icon: Icon, iconColorClass, @@ -27,7 +27,7 @@ export const TokenSearchInput: FC = ({ showSuggestionsOnFocusIfEmpty, onAdd, onRemove, -}) => { +}: TokenSearchInputProps) { const [inputValue, setInputValue] = useState(''); const [shouldShowFilterSuggestions, setShouldShowFilterSuggestions] = useState(false); @@ -103,4 +103,4 @@ export const TokenSearchInput: FC = ({ ); -}; +} diff --git a/src/renderer/components/filters/UserTypeFilter.tsx b/src/renderer/components/filters/UserTypeFilter.tsx index d6c09fcf2..3bbdd1442 100644 --- a/src/renderer/components/filters/UserTypeFilter.tsx +++ b/src/renderer/components/filters/UserTypeFilter.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { DependabotIcon, FeedPersonIcon, @@ -13,7 +11,7 @@ import { Size } from '../../types'; import { userTypeFilter } from '../../utils/notifications/filters'; import { FilterSection } from './FilterSection'; -export const UserTypeFilter: FC = () => { +export function UserTypeFilter() { return ( { } /> ); -}; +} diff --git a/src/renderer/components/layout/AppLayout.tsx b/src/renderer/components/layout/AppLayout.tsx index 3abf7d653..0fae4ed07 100644 --- a/src/renderer/components/layout/AppLayout.tsx +++ b/src/renderer/components/layout/AppLayout.tsx @@ -1,4 +1,4 @@ -import type { FC, ReactNode } from 'react'; +import type { ReactNode } from 'react'; import { Sidebar } from '../Sidebar'; @@ -10,7 +10,7 @@ interface AppLayoutProps { * AppLayout is the main container for the application. * It handles the basic layout with sidebar and content area. */ -export const AppLayout: FC = ({ children }) => { +export function AppLayout({ children }: AppLayoutProps) { const setFocusRef = (el: HTMLButtonElement | null) => { if (el) { el.focus(); @@ -33,4 +33,4 @@ export const AppLayout: FC = ({ children }) => {
{children}
); -}; +} diff --git a/src/renderer/components/layout/Centered.tsx b/src/renderer/components/layout/Centered.tsx index f26c1b266..53d808c63 100644 --- a/src/renderer/components/layout/Centered.tsx +++ b/src/renderer/components/layout/Centered.tsx @@ -1,4 +1,4 @@ -import type { FC, ReactNode } from 'react'; +import type { ReactNode } from 'react'; import { Stack } from '@primer/react'; @@ -7,7 +7,7 @@ interface CenteredProps { fullHeight: boolean; } -export const Centered: FC = (props: CenteredProps) => { +export function Centered(props: CenteredProps) { return ( = (props: CenteredProps) => { {props.children} ); -}; +} diff --git a/src/renderer/components/layout/Contents.tsx b/src/renderer/components/layout/Contents.tsx index 458a59a53..16eba41dc 100644 --- a/src/renderer/components/layout/Contents.tsx +++ b/src/renderer/components/layout/Contents.tsx @@ -1,4 +1,4 @@ -import type { FC, ReactNode } from 'react'; +import type { ReactNode } from 'react'; import { cn } from 'cn'; @@ -13,12 +13,12 @@ interface IContents { * Contents component holds the main content of a page. * It provides proper padding and handles scrolling. */ -export const Contents: FC = ({ +export function Contents({ children, paddingHorizontal = true, paddingBottom = false, scrollFade = false, -}) => { +}: IContents) { return (
= ({ {children}
); -}; +} diff --git a/src/renderer/components/layout/EmojiSplash.tsx b/src/renderer/components/layout/EmojiSplash.tsx index 5979bfcc6..d042d60bf 100644 --- a/src/renderer/components/layout/EmojiSplash.tsx +++ b/src/renderer/components/layout/EmojiSplash.tsx @@ -1,4 +1,4 @@ -import type { FC, ReactNode } from 'react'; +import type { ReactNode } from 'react'; import { Stack } from '@primer/react'; @@ -14,7 +14,7 @@ interface EmojiSplashProps { actions?: ReactNode; } -export const EmojiSplash: FC = (props: EmojiSplashProps) => { +export function EmojiSplash(props: EmojiSplashProps) { return ( @@ -36,4 +36,4 @@ export const EmojiSplash: FC = (props: EmojiSplashProps) => { ); -}; +} diff --git a/src/renderer/components/layout/Page.tsx b/src/renderer/components/layout/Page.tsx index efdf1f56d..9b34d12c5 100644 --- a/src/renderer/components/layout/Page.tsx +++ b/src/renderer/components/layout/Page.tsx @@ -1,4 +1,4 @@ -import type { FC, ReactNode } from 'react'; +import type { ReactNode } from 'react'; interface PageProps { children: ReactNode; @@ -10,10 +10,10 @@ interface PageProps { * It creates a column layout for header, content, and footer. * The height is 100% to fill the parent container. */ -export const Page: FC = ({ children, testId }) => { +export function Page({ children, testId }: PageProps) { return (
{children}
); -}; +} diff --git a/src/renderer/components/login/LoginWithPersonalAccessTokenForm.tsx b/src/renderer/components/login/LoginWithPersonalAccessTokenForm.tsx index 38226b38b..59d552fc4 100644 --- a/src/renderer/components/login/LoginWithPersonalAccessTokenForm.tsx +++ b/src/renderer/components/login/LoginWithPersonalAccessTokenForm.tsx @@ -1,4 +1,4 @@ -import { type FC, type ReactNode, useCallback, useState } from 'react'; +import { type ReactNode, useCallback, useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { BookIcon, EyeClosedIcon, EyeIcon, KeyIcon, SignInIcon } from '@primer/octicons-react'; @@ -61,7 +61,7 @@ export interface LoginWithPersonalAccessTokenFormProps { * Forge-specific route components (`routes/github`, `routes/gitea`) supply * their own copy via props so this form stays free of forge conditionals. */ -export const LoginWithPersonalAccessTokenForm: FC = ({ +export function LoginWithPersonalAccessTokenForm({ forge, title, hostnameCaption = '', @@ -75,7 +75,7 @@ export const LoginWithPersonalAccessTokenForm: FC { +}: LoginWithPersonalAccessTokenFormProps) { const navigate = useNavigate(); const location = useLocation(); const { account: reAuthAccount } = (location.state ?? {}) as LocationState; @@ -275,4 +275,4 @@ export const LoginWithPersonalAccessTokenForm: FC ); -}; +} diff --git a/src/renderer/components/metrics/CommentsPill.tsx b/src/renderer/components/metrics/CommentsPill.tsx index 9352cfb7e..f3161f211 100644 --- a/src/renderer/components/metrics/CommentsPill.tsx +++ b/src/renderer/components/metrics/CommentsPill.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { CommentIcon } from '@primer/octicons-react'; import { IconColor } from '../../types'; @@ -11,7 +9,7 @@ export interface CommentsPillProps { commentCount: number; } -export const CommentsPill: FC = ({ commentCount }) => { +export function CommentsPill({ commentCount }: CommentsPillProps) { if (!commentCount) { return null; } @@ -26,4 +24,4 @@ export const CommentsPill: FC = ({ commentCount }) => { metric={commentCount} /> ); -}; +} diff --git a/src/renderer/components/metrics/IssueTypesPill.tsx b/src/renderer/components/metrics/IssueTypesPill.tsx index 3cc3294d1..e9bc58399 100644 --- a/src/renderer/components/metrics/IssueTypesPill.tsx +++ b/src/renderer/components/metrics/IssueTypesPill.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { IssueOpenedIcon } from '@primer/octicons-react'; import type { GitifyIssueType } from '../../types'; @@ -10,10 +8,10 @@ export interface IssueTypesPillProps { issueType?: GitifyIssueType; } -export const IssueTypesPill: FC = ({ issueType }) => { +export function IssueTypesPill({ issueType }: IssueTypesPillProps) { if (!issueType) { return null; } return ; -}; +} diff --git a/src/renderer/components/metrics/LabelsPill.tsx b/src/renderer/components/metrics/LabelsPill.tsx index c0bcad6d5..05fecafe5 100644 --- a/src/renderer/components/metrics/LabelsPill.tsx +++ b/src/renderer/components/metrics/LabelsPill.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { TagIcon } from '@primer/octicons-react'; import { IssueLabelToken, LabelGroup } from '@primer/react'; @@ -12,7 +10,7 @@ export interface LabelsPillProps { issueFields?: GitifyIssueField[]; } -export const LabelsPill: FC = ({ labels, issueFields }) => { +export function LabelsPill({ labels, issueFields }: LabelsPillProps) { const fieldTokens = (issueFields ?? []).map((field) => ({ text: `${field.name}: ${field.value}`, fillColor: field.fillColor, @@ -54,4 +52,4 @@ export const LabelsPill: FC = ({ labels, issueFields }) => { metric={fieldTokens.length + (labels?.length ?? 0)} /> ); -}; +} diff --git a/src/renderer/components/metrics/LinkedIssuesPill.tsx b/src/renderer/components/metrics/LinkedIssuesPill.tsx index 4d147337f..a96cdab3a 100644 --- a/src/renderer/components/metrics/LinkedIssuesPill.tsx +++ b/src/renderer/components/metrics/LinkedIssuesPill.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { IssueRelatesToIcon } from '@primer/octicons-react'; import { IconColor } from '../../types'; @@ -11,7 +9,7 @@ export interface LinkedIssuesPillProps { linkedIssues: string[]; } -export const LinkedIssuesPill: FC = ({ linkedIssues }) => { +export function LinkedIssuesPill({ linkedIssues }: LinkedIssuesPillProps) { if (!linkedIssues?.length) { return null; } @@ -30,4 +28,4 @@ export const LinkedIssuesPill: FC = ({ linkedIssues }) => metric={linkedIssues.length} /> ); -}; +} diff --git a/src/renderer/components/metrics/MetricGroup.tsx b/src/renderer/components/metrics/MetricGroup.tsx index 6f8b5fe06..2979d59b2 100644 --- a/src/renderer/components/metrics/MetricGroup.tsx +++ b/src/renderer/components/metrics/MetricGroup.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { useSettingsStore } from '../../stores'; import type { GitifyNotification } from '../../types'; @@ -19,7 +17,7 @@ export interface MetricGroupProps { notification: GitifyNotification; } -export const MetricGroup: FC = ({ notification }) => { +export function MetricGroup({ notification }: MetricGroupProps) { const showPills = useSettingsStore((s) => s.showPills); if (!showPills) { @@ -61,4 +59,4 @@ export const MetricGroup: FC = ({ notification }) => { /> ); -}; +} diff --git a/src/renderer/components/metrics/MetricPill.tsx b/src/renderer/components/metrics/MetricPill.tsx index 6b6de1cfa..f8e6ea451 100644 --- a/src/renderer/components/metrics/MetricPill.tsx +++ b/src/renderer/components/metrics/MetricPill.tsx @@ -18,7 +18,7 @@ export interface MetricPillProps { ariaLabel?: string; } -export const MetricPill: FC = (props: MetricPillProps) => { +export function MetricPill(props: MetricPillProps) { const Icon = props.icon; return ( @@ -41,4 +41,4 @@ export const MetricPill: FC = (props: MetricPillProps) => { ); -}; +} diff --git a/src/renderer/components/metrics/MilestonePill.tsx b/src/renderer/components/metrics/MilestonePill.tsx index 5cbe99eb9..a33175a0d 100644 --- a/src/renderer/components/metrics/MilestonePill.tsx +++ b/src/renderer/components/metrics/MilestonePill.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { MilestoneIcon } from '@primer/octicons-react'; import { type GitifyMilestone, IconColor } from '../../types'; @@ -10,7 +8,7 @@ export interface MilestonePillProps { milestone: GitifyMilestone; } -export const MilestonePill: FC = ({ milestone }) => { +export function MilestonePill({ milestone }: MilestonePillProps) { if (!milestone) { return null; } @@ -22,4 +20,4 @@ export const MilestonePill: FC = ({ milestone }) => { icon={MilestoneIcon} /> ); -}; +} diff --git a/src/renderer/components/metrics/ParentPill.tsx b/src/renderer/components/metrics/ParentPill.tsx index 6e695dc34..fce952711 100644 --- a/src/renderer/components/metrics/ParentPill.tsx +++ b/src/renderer/components/metrics/ParentPill.tsx @@ -1,4 +1,4 @@ -import type { FC, MouseEvent } from 'react'; +import type { MouseEvent } from 'react'; import { IssueTrackedByIcon } from '@primer/octicons-react'; @@ -11,7 +11,7 @@ export interface ParentPillProps { parent?: GitifyParentIssue | null; } -export const ParentPill: FC = ({ parent }) => { +export function ParentPill({ parent }: ParentPillProps) { if (!parent) { return null; } @@ -32,4 +32,4 @@ export const ParentPill: FC = ({ parent }) => { onClick={handleClick} /> ); -}; +} diff --git a/src/renderer/components/metrics/ReactionsPill.tsx b/src/renderer/components/metrics/ReactionsPill.tsx index 1ca1c7859..2432e1156 100644 --- a/src/renderer/components/metrics/ReactionsPill.tsx +++ b/src/renderer/components/metrics/ReactionsPill.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { SmileyIcon } from '@primer/octicons-react'; import { IssueLabelToken, LabelGroup } from '@primer/react'; @@ -23,7 +21,7 @@ const reactionEmojiMap: Record = { HEART: '❤️', }; -export const ReactionsPill: FC = ({ reactionsCount, reactionGroups }) => { +export function ReactionsPill({ reactionsCount, reactionGroups }: ReactionsPillProps) { if (!reactionsCount) { return null; } @@ -58,4 +56,4 @@ export const ReactionsPill: FC = ({ reactionsCount, reaction metric={reactionsCount} /> ); -}; +} diff --git a/src/renderer/components/metrics/ReviewsPill.tsx b/src/renderer/components/metrics/ReviewsPill.tsx index fd153e4dc..3d9088a30 100644 --- a/src/renderer/components/metrics/ReviewsPill.tsx +++ b/src/renderer/components/metrics/ReviewsPill.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { CommentIcon } from '@primer/octicons-react'; import { type GitifyPullRequestReviewer, IconColor } from '../../types'; @@ -11,7 +9,7 @@ export interface ReviewsPillProps { reviewers: GitifyPullRequestReviewer[]; } -export const ReviewsPill: FC = ({ reviewers }) => { +export function ReviewsPill({ reviewers }: ReviewsPillProps) { if (!reviewers.length) { return null; } @@ -62,7 +60,7 @@ export const ReviewsPill: FC = ({ reviewers }) => { ) : null} ); -}; +} function getReviewGroups(reviewers: GitifyPullRequestReviewer[]): PullRequestReviewGroup[] { const groups = new Map, string[]>(); diff --git a/src/renderer/components/metrics/StackedPrsPill.tsx b/src/renderer/components/metrics/StackedPrsPill.tsx index db3970c49..e9065c4c2 100644 --- a/src/renderer/components/metrics/StackedPrsPill.tsx +++ b/src/renderer/components/metrics/StackedPrsPill.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { GitMergeIcon } from '@primer/octicons-react'; import { IconColor } from '../../types'; @@ -12,11 +10,7 @@ export interface StackedPrsPillProps { stackDepth?: number; } -export const StackedPrsPill: FC = ({ - isStacked, - stackPosition, - stackDepth, -}) => { +export function StackedPrsPill({ isStacked, stackPosition, stackDepth }: StackedPrsPillProps) { if (!isStacked) { return null; } @@ -32,4 +26,4 @@ export const StackedPrsPill: FC = ({ metric={metric} /> ); -}; +} diff --git a/src/renderer/components/metrics/SubIssueProgressPill.tsx b/src/renderer/components/metrics/SubIssueProgressPill.tsx index 5656335a7..c8c9990f3 100644 --- a/src/renderer/components/metrics/SubIssueProgressPill.tsx +++ b/src/renderer/components/metrics/SubIssueProgressPill.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { type GitifySubIssueProgress, IconColor } from '../../types'; import { MetricPill } from './MetricPill'; @@ -14,11 +12,11 @@ export interface SubIssueProgressWheelProps { size?: number; } -export const SubIssueProgressWheel: FC = ({ +export function SubIssueProgressWheel({ percent = 0, className, size = 12, -}) => { +}: SubIssueProgressWheelProps) { const radius = 6; const circumference = 2 * Math.PI * radius; const clampedPercent = Math.min(100, Math.max(0, percent)); @@ -59,9 +57,9 @@ export const SubIssueProgressWheel: FC = ({ )} ); -}; +} -export const SubIssueProgressPill: FC = ({ progress }) => { +export function SubIssueProgressPill({ progress }: SubIssueProgressPillProps) { if (!progress || progress.total === 0) { return null; } @@ -83,4 +81,4 @@ export const SubIssueProgressPill: FC = ({ progress } metric={`${progress.completed}/${progress.total}`} /> ); -}; +} diff --git a/src/renderer/components/notifications/AccountHeader.tsx b/src/renderer/components/notifications/AccountHeader.tsx index ff5ef936d..544c72d18 100644 --- a/src/renderer/components/notifications/AccountHeader.tsx +++ b/src/renderer/components/notifications/AccountHeader.tsx @@ -1,4 +1,4 @@ -import { type FC, type MouseEvent } from 'react'; +import { type MouseEvent } from 'react'; import { GitPullRequestIcon, IssueOpenedIcon } from '@primer/octicons-react'; import { Button, Stack } from '@primer/react'; @@ -23,13 +23,13 @@ export interface AccountHeaderProps { onToggle: () => void; } -export const AccountHeader: FC = ({ +export function AccountHeader({ account, error, notificationCount, isCollapsed, onToggle, -}) => { +}: AccountHeaderProps) { const Chevron = getChevronDetails(notificationCount > 0, !isCollapsed, 'account'); return ( @@ -89,4 +89,4 @@ export const AccountHeader: FC = ({ ); -}; +} diff --git a/src/renderer/components/notifications/NotificationFooter.tsx b/src/renderer/components/notifications/NotificationFooter.tsx index 21ec7b124..4b63df994 100644 --- a/src/renderer/components/notifications/NotificationFooter.tsx +++ b/src/renderer/components/notifications/NotificationFooter.tsx @@ -1,4 +1,4 @@ -import type { FC, MouseEvent } from 'react'; +import type { MouseEvent } from 'react'; import { RelativeTime, Stack, Text } from '@primer/react'; @@ -15,9 +15,7 @@ export interface NotificationFooterProps { notification: GitifyNotification; } -export const NotificationFooter: FC = ({ - notification, -}: NotificationFooterProps) => { +export function NotificationFooter({ notification }: NotificationFooterProps) { const user = notification.subject.user; const userLabel = user ? getAccountAdapter(notification.account).formatNotificationUser(user) @@ -70,4 +68,4 @@ export const NotificationFooter: FC = ({ ); -}; +} diff --git a/src/renderer/components/notifications/NotificationHeader.tsx b/src/renderer/components/notifications/NotificationHeader.tsx index aeaedd95d..49b4cbfab 100644 --- a/src/renderer/components/notifications/NotificationHeader.tsx +++ b/src/renderer/components/notifications/NotificationHeader.tsx @@ -1,4 +1,4 @@ -import type { FC, MouseEvent } from 'react'; +import type { MouseEvent } from 'react'; import { Stack } from '@primer/react'; @@ -16,9 +16,7 @@ export interface NotificationHeaderProps { notification: GitifyNotification; } -export const NotificationHeader: FC = ({ - notification, -}: NotificationHeaderProps) => { +export function NotificationHeader({ notification }: NotificationHeaderProps) { const showNumber = useSettingsStore((s) => s.showNumber); return ( @@ -51,4 +49,4 @@ export const NotificationHeader: FC = ({ ) ); -}; +} diff --git a/src/renderer/components/notifications/NotificationList.tsx b/src/renderer/components/notifications/NotificationList.tsx index fc4f41b8f..65413853b 100644 --- a/src/renderer/components/notifications/NotificationList.tsx +++ b/src/renderer/components/notifications/NotificationList.tsx @@ -1,4 +1,4 @@ -import { type FC, useCallback, useMemo, useState } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import { LegendList } from '@legendapp/list/react'; @@ -28,10 +28,10 @@ export interface NotificationListProps { * Flattened so one virtualizer windows across group boundaries, and so collapse * and exit-animation state survives rows unmounting on scroll. */ -export const NotificationList: FC = ({ +export function NotificationList({ accountNotifications, showAccountHeader, -}) => { +}: NotificationListProps) { const groupBy = useSettingsStore((s) => s.groupBy); const hasMultipleAccounts = useAccountsStore((s) => s.hasMultipleAccounts()); @@ -184,4 +184,4 @@ export const NotificationList: FC = ({ /> ); -}; +} diff --git a/src/renderer/components/notifications/NotificationRow.tsx b/src/renderer/components/notifications/NotificationRow.tsx index e77525f85..0edba702c 100644 --- a/src/renderer/components/notifications/NotificationRow.tsx +++ b/src/renderer/components/notifications/NotificationRow.tsx @@ -1,5 +1,3 @@ -import { type FC } from 'react'; - import { BellSlashIcon, CheckIcon, ReadIcon } from '@primer/octicons-react'; import { Stack, Text, Tooltip } from '@primer/react'; @@ -34,11 +32,11 @@ export interface NotificationRowProps { onAnimateExit: (animate: boolean) => void; } -export const NotificationRow: FC = ({ +export function NotificationRow({ notification, isAnimatingExit, onAnimateExit, -}: NotificationRowProps) => { +}: NotificationRowProps) { const { markNotificationsAsRead, markNotificationsAsDone, unsubscribeNotification } = useNotifications(); @@ -188,4 +186,4 @@ export const NotificationRow: FC = ({ )} ); -}; +} diff --git a/src/renderer/components/notifications/NotificationTitle.tsx b/src/renderer/components/notifications/NotificationTitle.tsx index 35f90559c..908c00fcb 100644 --- a/src/renderer/components/notifications/NotificationTitle.tsx +++ b/src/renderer/components/notifications/NotificationTitle.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { Text } from '@primer/react'; import { cn } from 'cn'; @@ -12,9 +10,7 @@ interface NotificationTitleProps { title: string; } -export const NotificationTitle: FC = ({ - title, -}: NotificationTitleProps) => { +export function NotificationTitle({ title }: NotificationTitleProps) { const wrapNotificationTitle = useSettingsStore((s) => s.wrapNotificationTitle); const parts = parseInlineCode(title); @@ -34,4 +30,4 @@ export const NotificationTitle: FC = ({ ))} ); -}; +} diff --git a/src/renderer/components/notifications/RepositoryHeader.tsx b/src/renderer/components/notifications/RepositoryHeader.tsx index 7327dab74..a7ecd3cfe 100644 --- a/src/renderer/components/notifications/RepositoryHeader.tsx +++ b/src/renderer/components/notifications/RepositoryHeader.tsx @@ -1,4 +1,4 @@ -import { type FC, type MouseEvent } from 'react'; +import { type MouseEvent } from 'react'; import { CheckIcon, ReadIcon } from '@primer/octicons-react'; import { Button, Stack } from '@primer/react'; @@ -27,14 +27,14 @@ export interface RepositoryHeaderProps { onAnimateExit: (animate: boolean) => void; } -export const RepositoryHeader: FC = ({ +export function RepositoryHeader({ repoName, repoNotifications, isCollapsed, isAnimatingExit, onToggle, onAnimateExit, -}) => { +}: RepositoryHeaderProps) { const { markNotificationsAsRead, markNotificationsAsDone } = useNotifications(); const shouldAnimateExit = shouldRemoveNotificationsFromState(); @@ -117,4 +117,4 @@ export const RepositoryHeader: FC = ({ )} ); -}; +} diff --git a/src/renderer/components/primitives/CustomCounter.tsx b/src/renderer/components/primitives/CustomCounter.tsx index 34a53630a..c2a7c8f60 100644 --- a/src/renderer/components/primitives/CustomCounter.tsx +++ b/src/renderer/components/primitives/CustomCounter.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { Text } from '@primer/react'; import { cn } from 'cn'; @@ -19,7 +17,7 @@ interface CustomCounterProps { * - would show screen vertical scrollbar which is undesirable. * - would not render '0' within a counter. */ -export const CustomCounter: FC = ({ value, scheme = 'secondary' }) => { +export function CustomCounter({ value, scheme = 'secondary' }: CustomCounterProps) { const baseStyles = 'px-2 py-0.25 rounded-full text-[10px] font-medium leading-none min-w-[16px] text-gitify-counter-text'; @@ -30,4 +28,4 @@ export const CustomCounter: FC = ({ value, scheme = 'seconda }; return {value}; -}; +} diff --git a/src/renderer/components/primitives/EmojiText.tsx b/src/renderer/components/primitives/EmojiText.tsx index 1618924cb..8f46d8a06 100644 --- a/src/renderer/components/primitives/EmojiText.tsx +++ b/src/renderer/components/primitives/EmojiText.tsx @@ -1,4 +1,4 @@ -import { type FC, useEffect, useRef } from 'react'; +import { useEffect, useRef } from 'react'; import { convertTextToEmojiImgHtml } from '../../utils/ui/emojis'; @@ -6,7 +6,7 @@ export interface IEmojiText { text: string; } -export const EmojiText: FC = ({ text }) => { +export function EmojiText({ text }: IEmojiText) { const ref = useRef(null); const mountedRef = useRef(true); @@ -33,4 +33,4 @@ export const EmojiText: FC = ({ text }) => { }, [text]); return
; -}; +} diff --git a/src/renderer/components/primitives/Footer.tsx b/src/renderer/components/primitives/Footer.tsx index a60441fd0..3a3224df1 100644 --- a/src/renderer/components/primitives/Footer.tsx +++ b/src/renderer/components/primitives/Footer.tsx @@ -1,4 +1,4 @@ -import type { FC, ReactNode } from 'react'; +import type { ReactNode } from 'react'; import { Stack } from '@primer/react'; @@ -11,7 +11,7 @@ interface FooterProps { * Footer component displays actions at the bottom of the page. * It is fixed to the viewport bottom. */ -export const Footer: FC = ({ children, justify }) => { +export function Footer({ children, justify }: FooterProps) { return (
@@ -19,4 +19,4 @@ export const Footer: FC = ({ children, justify }) => {
); -}; +} diff --git a/src/renderer/components/primitives/Header.tsx b/src/renderer/components/primitives/Header.tsx index 05aa53dde..63eebba2b 100644 --- a/src/renderer/components/primitives/Header.tsx +++ b/src/renderer/components/primitives/Header.tsx @@ -1,4 +1,3 @@ -import type { FC } from 'react'; import { useNavigate } from 'react-router-dom'; import { ArrowLeftIcon, type Icon } from '@primer/octicons-react'; @@ -14,7 +13,7 @@ interface HeaderProps { fetchOnBack?: boolean; } -export const Header: FC = (props: HeaderProps) => { +export function Header(props: HeaderProps) { const navigate = useNavigate(); const { refetchNotifications: fetchNotifications } = useNotifications(); @@ -42,4 +41,4 @@ export const Header: FC = (props: HeaderProps) => {
); -}; +} diff --git a/src/renderer/components/primitives/HoverButton.tsx b/src/renderer/components/primitives/HoverButton.tsx index bbc3f82a6..7b4b491ab 100644 --- a/src/renderer/components/primitives/HoverButton.tsx +++ b/src/renderer/components/primitives/HoverButton.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import type { Icon } from '@primer/octicons-react'; import { IconButton } from '@primer/react'; @@ -14,11 +12,7 @@ interface HoverButtonProps { variant?: VariantType; } -export const HoverButton: FC = ({ - enabled = true, - variant = 'invisible', - ...props -}: HoverButtonProps) => { +export function HoverButton({ enabled = true, variant = 'invisible', ...props }: HoverButtonProps) { return ( enabled && ( = ({ /> ) ); -}; +} diff --git a/src/renderer/components/primitives/HoverGroup.tsx b/src/renderer/components/primitives/HoverGroup.tsx index 4f6461466..e06edad8c 100644 --- a/src/renderer/components/primitives/HoverGroup.tsx +++ b/src/renderer/components/primitives/HoverGroup.tsx @@ -1,4 +1,4 @@ -import type { FC, ReactNode } from 'react'; +import type { ReactNode } from 'react'; import { Stack } from '@primer/react'; @@ -28,11 +28,7 @@ interface HoverGroupProps { * title line or the issue number, and the footer reserves its width so the * pills wrap clear of the buttons. */ -export const HoverGroup: FC = ({ - bgColor, - children, - fullHeight = false, -}: HoverGroupProps) => { +export function HoverGroup({ bgColor, children, fullHeight = false }: HoverGroupProps) { return ( = ({ {children} ); -}; +} diff --git a/src/renderer/components/primitives/Title.tsx b/src/renderer/components/primitives/Title.tsx index f4709c015..360c77de4 100644 --- a/src/renderer/components/primitives/Title.tsx +++ b/src/renderer/components/primitives/Title.tsx @@ -1,4 +1,4 @@ -import type { FC, ReactNode } from 'react'; +import type { ReactNode } from 'react'; import type { Icon } from '@primer/octicons-react'; import { Heading, Stack } from '@primer/react'; @@ -12,7 +12,7 @@ interface TitleProps { tooltip?: ReactNode; } -export const Title: FC = ({ size: _size = 2, ...props }) => { +export function Title({ size: _size = 2, ...props }: TitleProps) { const name = props.children.toLowerCase().replaceAll(' ', '-'); return ( @@ -35,4 +35,4 @@ export const Title: FC = ({ size: _size = 2, ...props }) => { ); -}; +} diff --git a/src/renderer/components/settings/AppearanceSettings.tsx b/src/renderer/components/settings/AppearanceSettings.tsx index 20399fe54..f025c2261 100644 --- a/src/renderer/components/settings/AppearanceSettings.tsx +++ b/src/renderer/components/settings/AppearanceSettings.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { PaintbrushIcon, SyncIcon, ZoomInIcon, ZoomOutIcon } from '@primer/octicons-react'; import { Button, ButtonGroup, IconButton, Select, Stack, Text } from '@primer/react'; @@ -20,7 +18,7 @@ import { resetZoomLevel, } from '../../utils/ui/zoom'; -export const AppearanceSettings: FC = () => { +export function AppearanceSettings() { // Account store values const hasMultipleAccounts = useAccountsStore((s) => s.hasMultipleAccounts()); @@ -193,4 +191,4 @@ export const AppearanceSettings: FC = () => { ); -}; +} diff --git a/src/renderer/components/settings/NotificationSettings.tsx b/src/renderer/components/settings/NotificationSettings.tsx index d6ce79b6e..cd9618334 100644 --- a/src/renderer/components/settings/NotificationSettings.tsx +++ b/src/renderer/components/settings/NotificationSettings.tsx @@ -1,4 +1,4 @@ -import type { FC, MouseEvent } from 'react'; +import type { MouseEvent } from 'react'; import { useNavigate } from 'react-router-dom'; import { @@ -37,7 +37,7 @@ import { GroupBy, Size } from '../../types'; import { hasAlternateScopes, hasRecommendedScopes } from '../../utils/auth/scopes'; import { openGitHubParticipatingDocs } from '../../utils/system/links'; -export const NotificationSettings: FC = () => { +export function NotificationSettings() { const navigate = useNavigate(); // Account store values @@ -418,4 +418,4 @@ export const NotificationSettings: FC = () => { ); -}; +} diff --git a/src/renderer/components/settings/SettingsFooter.tsx b/src/renderer/components/settings/SettingsFooter.tsx index 94bea2d85..86b7861cf 100644 --- a/src/renderer/components/settings/SettingsFooter.tsx +++ b/src/renderer/components/settings/SettingsFooter.tsx @@ -1,4 +1,4 @@ -import { type FC, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import { PersonIcon, XCircleIcon } from '@primer/octicons-react'; import { Button, IconButton, Stack, Tooltip } from '@primer/react'; @@ -12,7 +12,7 @@ import { Footer } from '../primitives/Footer'; import { getAppVersion } from '../../utils/system/comms'; import { openGitifyReleaseNotes } from '../../utils/system/links'; -export const SettingsFooter: FC = () => { +export function SettingsFooter() { const [appVersion, setAppVersion] = useState(null); const { shortcuts } = useShortcutActions(); @@ -63,4 +63,4 @@ export const SettingsFooter: FC = () => { ); -}; +} diff --git a/src/renderer/components/settings/SettingsReset.tsx b/src/renderer/components/settings/SettingsReset.tsx index 3fe9d34dd..9a3989290 100644 --- a/src/renderer/components/settings/SettingsReset.tsx +++ b/src/renderer/components/settings/SettingsReset.tsx @@ -1,12 +1,10 @@ -import type { FC } from 'react'; - import { Button, Stack, useConfirm } from '@primer/react'; import { useSettingsStore } from '../../stores'; import { rendererLogInfo } from '../../utils/core/logger'; -export const SettingsReset: FC = () => { +export function SettingsReset() { const resetSettings = useSettingsStore((s) => s.reset); const confirm = useConfirm(); @@ -39,4 +37,4 @@ export const SettingsReset: FC = () => { ); -}; +} diff --git a/src/renderer/components/settings/SystemSettings.tsx b/src/renderer/components/settings/SystemSettings.tsx index 2702bbf9c..e6dcbe98a 100644 --- a/src/renderer/components/settings/SystemSettings.tsx +++ b/src/renderer/components/settings/SystemSettings.tsx @@ -1,4 +1,4 @@ -import { type FC, useEffect, useRef, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { DeviceDesktopIcon, PencilIcon, SyncIcon } from '@primer/octicons-react'; import { Banner, Button, ButtonGroup, IconButton, Stack, Text } from '@primer/react'; @@ -34,7 +34,7 @@ import { const defaultSettings = DEFAULT_SETTINGS_STATE; -export const SystemSettings: FC = () => { +export function SystemSettings() { const shortcutRegistrationError = useShortcutRegistrationStore( (s) => s.shortcutRegistrationError, ); @@ -399,4 +399,4 @@ export const SystemSettings: FC = () => { ); -}; +} diff --git a/src/renderer/components/settings/TraySettings.tsx b/src/renderer/components/settings/TraySettings.tsx index f74065f63..abfa5c7c0 100644 --- a/src/renderer/components/settings/TraySettings.tsx +++ b/src/renderer/components/settings/TraySettings.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { DevicesIcon } from '@primer/octicons-react'; import { Stack, Text } from '@primer/react'; @@ -12,7 +10,7 @@ import { Checkbox } from '../fields/Checkbox'; import { RadioGroup } from '../fields/RadioGroup'; import { Title } from '../primitives/Title'; -export const TraySettings: FC = () => { +export function TraySettings() { const updateSetting = useSettingsStore((s) => s.updateSetting); // Setting store actions @@ -83,4 +81,4 @@ export const TraySettings: FC = () => { ); -}; +} diff --git a/src/renderer/icons/BitbucketIcon.tsx b/src/renderer/icons/BitbucketIcon.tsx index b1e749769..3793ab8dc 100644 --- a/src/renderer/icons/BitbucketIcon.tsx +++ b/src/renderer/icons/BitbucketIcon.tsx @@ -1,28 +1,28 @@ -import type { FC } from 'react'; - import type { OcticonProps } from '@primer/octicons-react'; /** * Bitbucket brand icon (black-and-white, uses currentColor). - * Implements FC so it is a drop-in for any place that expects an + * Takes OcticonProps so it is a drop-in for any place that expects an * octicon-shaped component. */ -export const BitbucketIcon: FC = ({ +export function BitbucketIcon({ size = 16, fill = 'currentColor', className, ...props -}) => ( - -); +}: OcticonProps) { + return ( + + ); +} diff --git a/src/renderer/icons/GitLabIcon.tsx b/src/renderer/icons/GitLabIcon.tsx index c81eee338..259c934f1 100644 --- a/src/renderer/icons/GitLabIcon.tsx +++ b/src/renderer/icons/GitLabIcon.tsx @@ -1,28 +1,28 @@ -import type { FC } from 'react'; - import type { OcticonProps } from '@primer/octicons-react'; /** * GitLab brand icon (black-and-white, uses currentColor). - * Implements FC so it is a drop-in for any place that expects an + * Takes OcticonProps so it is a drop-in for any place that expects an * octicon-shaped component. */ -export const GitLabIcon: FC = ({ +export function GitLabIcon({ size = 16, fill = 'currentColor', className, ...props -}) => ( - -); +}: OcticonProps) { + return ( + + ); +} diff --git a/src/renderer/icons/LogoIcon.tsx b/src/renderer/icons/LogoIcon.tsx index 9ccda8052..a1a043532 100644 --- a/src/renderer/icons/LogoIcon.tsx +++ b/src/renderer/icons/LogoIcon.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { cn } from 'cn'; import { APPLICATION } from '../../shared/constants'; @@ -18,48 +16,45 @@ const LIGHT_GRADIENT_END = '#FFFFFF'; const DARK_GRADIENT_START = '#22283B'; const DARK_GRADIENT_END = '#555B6E'; -export const LogoIcon: FC = ({ - isDark, - onClick, - size = Size.SMALL, - ...props -}: LogoIconProps) => ( - // oxlint-disable-next-line jsx-a11y/click-events-have-key-events -- Logo is purely decorative - -); + + ); +} diff --git a/src/renderer/icons/ScopeStatusIcon.tsx b/src/renderer/icons/ScopeStatusIcon.tsx index 22525782e..bfc9ff20c 100644 --- a/src/renderer/icons/ScopeStatusIcon.tsx +++ b/src/renderer/icons/ScopeStatusIcon.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { CheckCircleFillIcon, DashIcon, XCircleFillIcon } from '@primer/octicons-react'; export interface ScopeStatusIconProps { @@ -9,12 +7,12 @@ export interface ScopeStatusIconProps { withTestId?: boolean; } -export const ScopeStatusIcon: FC = ({ +export function ScopeStatusIcon({ granted, notApplicable = false, size = 14, withTestId = false, -}) => { +}: ScopeStatusIconProps) { if (notApplicable) { return ( = ({ size={size} /> ); -}; +} diff --git a/src/renderer/icons/VolumeDownIcon.tsx b/src/renderer/icons/VolumeDownIcon.tsx index b29824be1..cb5f7e59c 100644 --- a/src/renderer/icons/VolumeDownIcon.tsx +++ b/src/renderer/icons/VolumeDownIcon.tsx @@ -1,19 +1,19 @@ -import type { FC } from 'react'; - -export const VolumeDownIcon: FC = () => ( - -); +export function VolumeDownIcon() { + return ( + + ); +} diff --git a/src/renderer/icons/VolumeUpIcon.tsx b/src/renderer/icons/VolumeUpIcon.tsx index cfcffbffd..039ea8e22 100644 --- a/src/renderer/icons/VolumeUpIcon.tsx +++ b/src/renderer/icons/VolumeUpIcon.tsx @@ -1,17 +1,17 @@ -import type { FC } from 'react'; - -export const VolumeUpIcon: FC = () => ( - -); +export function VolumeUpIcon() { + return ( + + ); +} diff --git a/src/renderer/routes/AccountScopes.tsx b/src/renderer/routes/AccountScopes.tsx index 285c27476..a224a9ec4 100644 --- a/src/renderer/routes/AccountScopes.tsx +++ b/src/renderer/routes/AccountScopes.tsx @@ -1,4 +1,3 @@ -import type { FC } from 'react'; import { useLocation } from 'react-router-dom'; import { AlertFillIcon, LinkExternalIcon, ShieldCheckIcon } from '@primer/octicons-react'; @@ -27,7 +26,7 @@ interface LocationState { account: Account; } -export const AccountScopesRoute: FC = () => { +export function AccountScopesRoute() { const location = useLocation(); const { account } = location.state as LocationState; @@ -212,4 +211,4 @@ export const AccountScopesRoute: FC = () => { ); -}; +} diff --git a/src/renderer/routes/Accounts.tsx b/src/renderer/routes/Accounts.tsx index 066af7164..f6c6a0e65 100644 --- a/src/renderer/routes/Accounts.tsx +++ b/src/renderer/routes/Accounts.tsx @@ -41,13 +41,13 @@ import { getAdapter, listAdapters } from '../utils/forges/registry'; import { openAccountProfile, openAccountSettings, openHost } from '../utils/system/links'; import { getPlatformIcon } from '../utils/ui/icons'; -const RecommendedScopesIcon: FC = ({ className, ...props }) => ( - -); +function RecommendedScopesIcon({ className, ...props }: OcticonProps) { + return ; +} -const AlternateScopesIcon: FC = ({ className, ...props }) => ( - -); +function AlternateScopesIcon({ className, ...props }: OcticonProps) { + return ; +} function getScopeIcon(account: Account): FC { if (hasRecommendedScopes(account)) { @@ -59,7 +59,7 @@ function getScopeIcon(account: Account): FC { return ShieldCheckIcon; } -export const AccountsRoute: FC = () => { +export function AccountsRoute() { const navigate = useNavigate(); const { logoutFromAccount } = useLogins(); @@ -407,4 +407,4 @@ export const AccountsRoute: FC = () => { ); -}; +} diff --git a/src/renderer/routes/Filters.tsx b/src/renderer/routes/Filters.tsx index 7a7dca6ce..3172a8a17 100644 --- a/src/renderer/routes/Filters.tsx +++ b/src/renderer/routes/Filters.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { FilterIcon, FilterRemoveIcon } from '@primer/octicons-react'; import { Button, Stack, Tooltip } from '@primer/react'; @@ -17,7 +15,7 @@ import { Page } from '../components/layout/Page'; import { Footer } from '../components/primitives/Footer'; import { Header } from '../components/primitives/Header'; -export const FiltersRoute: FC = () => { +export function FiltersRoute() { const clearFilters = useFiltersStore((s) => s.reset); const hasMultipleAccounts = useAccountsStore((s) => s.hasMultipleAccounts()); @@ -53,4 +51,4 @@ export const FiltersRoute: FC = () => { ); -}; +} diff --git a/src/renderer/routes/Login.tsx b/src/renderer/routes/Login.tsx index 525e5dab1..2e85a5f69 100644 --- a/src/renderer/routes/Login.tsx +++ b/src/renderer/routes/Login.tsx @@ -1,4 +1,4 @@ -import { type FC, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; +import { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { Button, Heading, Stack, Text } from '@primer/react'; @@ -24,7 +24,7 @@ function pickPrimaryMethod(adapter: ForgeAdapter): LoginMethodDescriptor | undef return adapter.loginMethods.find((m) => m.variant === 'primary') ?? adapter.loginMethods[0]; } -export const LoginRoute: FC = () => { +export function LoginRoute() { const navigate = useNavigate(); const adapters = listAdapters(); @@ -208,4 +208,4 @@ export const LoginRoute: FC = () => { ); -}; +} diff --git a/src/renderer/routes/Notifications.tsx b/src/renderer/routes/Notifications.tsx index 614df59d4..2e5d65196 100644 --- a/src/renderer/routes/Notifications.tsx +++ b/src/renderer/routes/Notifications.tsx @@ -1,4 +1,4 @@ -import { type FC, useMemo } from 'react'; +import { useMemo } from 'react'; import { useNotifications } from '../hooks/useNotifications'; import { useOnlineStatus } from '../hooks/useOnlineStatus'; @@ -13,7 +13,7 @@ import { getAccountUUID } from '../utils/auth/utils'; import { Errors } from '../utils/core/errors'; import { hasNoAccountErrors } from '../utils/notifications/status'; -export const NotificationsRoute: FC = () => { +export function NotificationsRoute() { const { notifications, status, globalError, hasNotifications } = useNotifications(); const isOnline = useOnlineStatus(); @@ -54,4 +54,4 @@ export const NotificationsRoute: FC = () => { /> ); -}; +} diff --git a/src/renderer/routes/Settings.tsx b/src/renderer/routes/Settings.tsx index 4a98bd4ba..a3bf61be0 100644 --- a/src/renderer/routes/Settings.tsx +++ b/src/renderer/routes/Settings.tsx @@ -1,5 +1,3 @@ -import type { FC } from 'react'; - import { GearIcon } from '@primer/octicons-react'; import { Stack } from '@primer/react'; @@ -13,7 +11,7 @@ import { SettingsReset } from '../components/settings/SettingsReset'; import { SystemSettings } from '../components/settings/SystemSettings'; import { TraySettings } from '../components/settings/TraySettings'; -export const SettingsRoute: FC = () => { +export function SettingsRoute() { return (
@@ -33,4 +31,4 @@ export const SettingsRoute: FC = () => { ); -}; +} diff --git a/src/renderer/routes/bitbucket/LoginWithPersonalAccessToken.tsx b/src/renderer/routes/bitbucket/LoginWithPersonalAccessToken.tsx index f3a1e3c0b..fa1e2a660 100644 --- a/src/renderer/routes/bitbucket/LoginWithPersonalAccessToken.tsx +++ b/src/renderer/routes/bitbucket/LoginWithPersonalAccessToken.tsx @@ -1,18 +1,18 @@ -import type { FC } from 'react'; - import { LoginWithPersonalAccessTokenForm } from '../../components/login/LoginWithPersonalAccessTokenForm'; -export const BitbucketLoginWithPersonalAccessTokenRoute: FC = () => ( - -); +export function BitbucketLoginWithPersonalAccessTokenRoute() { + return ( + + ); +} diff --git a/src/renderer/routes/gitea/LoginWithPersonalAccessToken.tsx b/src/renderer/routes/gitea/LoginWithPersonalAccessToken.tsx index 6a3291402..d806605b4 100644 --- a/src/renderer/routes/gitea/LoginWithPersonalAccessToken.tsx +++ b/src/renderer/routes/gitea/LoginWithPersonalAccessToken.tsx @@ -1,16 +1,16 @@ -import type { FC } from 'react'; - import { LoginWithPersonalAccessTokenForm } from '../../components/login/LoginWithPersonalAccessTokenForm'; -export const GiteaLoginWithPersonalAccessTokenRoute: FC = () => ( - -); +export function GiteaLoginWithPersonalAccessTokenRoute() { + return ( + + ); +} diff --git a/src/renderer/routes/github/LoginWithDeviceFlow.tsx b/src/renderer/routes/github/LoginWithDeviceFlow.tsx index 49b26f855..8c2e1dcbb 100644 --- a/src/renderer/routes/github/LoginWithDeviceFlow.tsx +++ b/src/renderer/routes/github/LoginWithDeviceFlow.tsx @@ -1,4 +1,4 @@ -import { type FC, type ReactNode, useCallback, useEffect, useState } from 'react'; +import { type ReactNode, useCallback, useEffect, useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { @@ -34,7 +34,7 @@ interface LocationState { type ScopeChoice = 'public' | 'full'; -export const GitHubLoginWithDeviceFlowRoute: FC = () => { +export function GitHubLoginWithDeviceFlowRoute() { const navigate = useNavigate(); const location = useLocation(); const { account: reAuthAccount } = (location.state ?? {}) as LocationState; @@ -355,4 +355,4 @@ export const GitHubLoginWithDeviceFlowRoute: FC = () => { )} ); -}; +} diff --git a/src/renderer/routes/github/LoginWithGitHubCLI.tsx b/src/renderer/routes/github/LoginWithGitHubCLI.tsx index 84f7e35e6..e74b579af 100644 --- a/src/renderer/routes/github/LoginWithGitHubCLI.tsx +++ b/src/renderer/routes/github/LoginWithGitHubCLI.tsx @@ -1,4 +1,4 @@ -import { type FC, useCallback, useState } from 'react'; +import { useCallback, useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { SignInIcon, TerminalIcon } from '@primer/octicons-react'; @@ -23,7 +23,7 @@ interface LocationState { account?: Account; } -export const GitHubLoginWithCLIRoute: FC = () => { +export function GitHubLoginWithCLIRoute() { const navigate = useNavigate(); const location = useLocation(); const { account: reAuthAccount } = (location.state ?? {}) as LocationState; @@ -115,4 +115,4 @@ export const GitHubLoginWithCLIRoute: FC = () => { ); -}; +} diff --git a/src/renderer/routes/github/LoginWithOAuthApp.tsx b/src/renderer/routes/github/LoginWithOAuthApp.tsx index 969ebdd1d..aa6df4c7c 100644 --- a/src/renderer/routes/github/LoginWithOAuthApp.tsx +++ b/src/renderer/routes/github/LoginWithOAuthApp.tsx @@ -1,4 +1,4 @@ -import { type FC, useCallback, useState } from 'react'; +import { useCallback, useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { BookIcon, EyeClosedIcon, EyeIcon, PersonIcon, SignInIcon } from '@primer/octicons-react'; @@ -28,7 +28,7 @@ interface LocationState { account?: Account; } -export const GitHubLoginWithOAuthAppRoute: FC = () => { +export function GitHubLoginWithOAuthAppRoute() { const navigate = useNavigate(); const location = useLocation(); const { account: reAuthAccount } = (location.state ?? {}) as LocationState; @@ -213,4 +213,4 @@ export const GitHubLoginWithOAuthAppRoute: FC = () => { ); -}; +} diff --git a/src/renderer/routes/github/LoginWithPersonalAccessToken.tsx b/src/renderer/routes/github/LoginWithPersonalAccessToken.tsx index 36c8c997e..b4b5ff44c 100644 --- a/src/renderer/routes/github/LoginWithPersonalAccessToken.tsx +++ b/src/renderer/routes/github/LoginWithPersonalAccessToken.tsx @@ -1,30 +1,30 @@ -import type { FC } from 'react'; - import { Text, Tooltip } from '@primer/react'; import { LoginWithPersonalAccessTokenForm } from '../../components/login/LoginWithPersonalAccessTokenForm'; import { formatRecommendedOAuthScopes } from '../../utils/auth/scopes'; -export const GitHubLoginWithPersonalAccessTokenRoute: FC = () => ( - - - The{' '} - - - {' '} - will be automatically selected for you. - - -); +export function GitHubLoginWithPersonalAccessTokenRoute() { + return ( + + + The{' '} + + + {' '} + will be automatically selected for you. + + + ); +} diff --git a/src/renderer/routes/gitlab/LoginWithPersonalAccessToken.tsx b/src/renderer/routes/gitlab/LoginWithPersonalAccessToken.tsx index dbe9bcf9b..ab329b1b6 100644 --- a/src/renderer/routes/gitlab/LoginWithPersonalAccessToken.tsx +++ b/src/renderer/routes/gitlab/LoginWithPersonalAccessToken.tsx @@ -1,24 +1,24 @@ -import type { FC } from 'react'; - import { Text } from '@primer/react'; import { LoginWithPersonalAccessTokenForm } from '../../components/login/LoginWithPersonalAccessTokenForm'; -export const GitLabLoginWithPersonalAccessTokenRoute: FC = () => ( - - - Requires the api scope, or a fine-grained token with{' '} - Todo (read, update) and{' '} - User (read) permissions. GitLab shows your To-Do items, - so you will see fewer notifications than on GitHub. - - -); +export function GitLabLoginWithPersonalAccessTokenRoute() { + return ( + + + Requires the api scope, or a fine-grained token with{' '} + Todo (read, update) and{' '} + User (read) permissions. GitLab shows your To-Do + items, so you will see fewer notifications than on GitHub. + + + ); +} diff --git a/vite.config.mts b/vite.config.mts index 9aaf77e5f..11ecf55ae 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -185,6 +185,13 @@ export default defineConfig({ 'default-param-last': 'error', 'default-case': 'error', curly: 'error', + 'react/function-component-definition': [ + 'error', + { + namedComponents: 'function-declaration', + unnamedComponents: 'arrow-function', + }, + ], 'react/exhaustive-deps': 'warn', 'react/rules-of-hooks': 'error', 'react/self-closing-comp': 'error',