Repository: gitify-app/gitify
Pull request #997 (2024-04-11 03:56:45)

refactor: field components
This PR includes a number of cleanup and consistency items, including
- consistent naming of components and prop interfaces
- rename optional placeholder -> helpText for checkbox and radio groups
- fix formatting of helpText for checkbox and radio groups
- add optional disabled prop to radio groups
- 100% test coverage (statements, branches, functions, lines, oh my!)


Patch:
diff --git a/.husky/pre-commit b/.husky/pre-commit
index c6254913..db4bafce 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,2 +1,2 @@
 pnpx lint-staged
-pnpm test -- --onlyChanged
+pnpm test
\ No newline at end of file
diff --git a/src/components/fields/Checkbox.tsx b/src/components/fields/Checkbox.tsx
index 7321e26e..20ca3164 100644
--- a/src/components/fields/Checkbox.tsx
+++ b/src/components/fields/Checkbox.tsx
@@ -1,42 +1,47 @@
-interface IFieldCheckbox {
+import type { FC, ReactNode } from 'react';
+
+export interface ICheckbox {
   name: string;
   label: string;
+  helpText?: ReactNode | string;
   checked: boolean;
-  onChange: (evt: React.ChangeEvent<HTMLInputElement>) => void;
-  placeholder?: string;
   disabled?: boolean;
+  onChange: (evt: React.ChangeEvent<HTMLInputElement>) => void;
 }
 
-export const FieldCheckbox = (props: IFieldCheckbox) => {
+export const Checkbox: FC<ICheckbox> = (props: ICheckbox) => {
   return (
-    <div className="flex items-start mt-1 mb-3">
-      <div className="flex items-center h-5">
-        <input
-          type="checkbox"
-          id={props.name}
-          className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
-          checked={props.checked}
-          onChange={props.onChange}
-          disabled={props.disabled}
-        />
-      </div>
+    <div className="mt-1 mb-3 text-sm">
+      <div className="flex items-start">
+        <div className="flex items-center h-5">
+          <input
+            type="checkbox"
+            id={props.name}
+            className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
+            checked={props.checked}
+            onChange={props.onChange}
+            disabled={props.disabled}
+          />
+        </div>
 
-      <div className="ml-3 text-sm">
-        <label
-          htmlFor={props.name}
-          className="font-medium text-gray-700 dark:text-gray-200"
-          style={
-            props.disabled ? { textDecoration: 'line-through' } : undefined
-          }
-        >
-          {props.label}
-        </label>
-        {props.placeholder && (
-          <div className="italic text-gray-500 dark:text-gray-300">
-            {props.placeholder}
-          </div>
-        )}
+        <div className="ml-3 ">
+          <label
+            htmlFor={props.name}
+            className="font-medium text-gray-700 dark:text-gray-200"
+            style={
+              props.disabled ? { textDecoration: 'line-through' } : undefined
+            }
+          >
+            {props.label}
+          </label>
+        </div>
       </div>
+
+      {props.helpText && (
+        <div className="text-xs mt-1 italic text-gray-500 dark:text-gray-300">
+          {props.helpText}
+        </div>
+      )}
     </div>
   );
 };
diff --git a/src/components/fields/FieldInput.tsx b/src/components/fields/FieldInput.tsx
index 93093278..47fcd83f 100644
--- a/src/components/fields/FieldInput.tsx
+++ b/src/components/fields/FieldInput.tsx
@@ -1,7 +1,7 @@
 import type { FC, ReactNode } from 'react';
 import { Field } from 'react-final-form';
 
-export interface IProps {
+export interface IFieldInput {
   name: string;
   type?: string;
   label: string;
@@ -10,10 +10,10 @@ export interface IProps {
   required?: boolean;
 }
 
-export const FieldInput: FC<IProps> = ({
+export const FieldInput: FC<IFieldInput> = ({
   label,
   name,
-  placeholder = '',
+  placeholder,
   helpText,
   type = 'text',
   required = false,
@@ -31,7 +31,7 @@ export const FieldInput: FC<IProps> = ({
 
           <input
             type={type}
-            className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none"
+            className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none text-sm"
             id={input.name}
             placeholder={placeholder}
             required={required}
diff --git a/src/components/fields/RadioGroup.tsx b/src/components/fields/RadioGroup.tsx
index ebf5c18e..c143b75b 100644
--- a/src/components/fields/RadioGroup.tsx
+++ b/src/components/fields/RadioGroup.tsx
@@ -1,68 +1,70 @@
-import type { ChangeEvent } from 'react';
+import type { ChangeEvent, FC, ReactNode } from 'react';
 import type { RadioGroupItem } from '../../types';
 
-export const FieldRadioGroup = ({
-  label,
-  placeholder,
-  name,
-  options,
-  onChange,
-  value,
-}: {
+export interface IRadioGroup {
   name: string;
   label: string;
-  placeholder?: string;
+  helpText?: ReactNode | string;
   options: RadioGroupItem[];
-  onChange: (event: ChangeEvent<HTMLInputElement>) => void;
   value: string;
-}) => {
-  return (
-    <div className="flex items-start mt-1 mb-3">
-      <div className="mr-3 text-sm py-1">
-        <label
-          htmlFor={name}
-          className="font-medium text-gray-700 dark:text-gray-200 "
-        >
-          {label}
-        </label>
+  disabled?: boolean;
+  onChange: (event: ChangeEvent<HTMLInputElement>) => void;
+}
 
-        {placeholder && (
-          <div className="italic text-gray-500 dark:text-gray-300">
-            {placeholder}
-          </div>
-        )}
-      </div>
+export const RadioGroup: FC<IRadioGroup> = (props: IRadioGroup) => {
+  return (
+    <div className="mt-1 mb-3 text-sm">
+      <div className="flex items-start">
+        <div className="mr-3 py-1">
+          <label
+            htmlFor={props.name}
+            className="font-medium text-gray-700 dark:text-gray-200 "
+            style={
+              props.disabled ? { textDecoration: 'line-through' } : undefined
+            }
+          >
+            {props.label}
+          </label>
+        </div>
 
-      <div
-        className="flex items-center space-x-4"
-        role="group"
-        aria-labelledby={name}
-      >
-        {options.map((item) => {
-          return (
-            <div
-              className="flex mt-1"
-              key={`radio_item_${item.value.toLowerCase()}`}
-            >
-              <input
-                type="radio"
-                className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
-                id={`${name}_${item.value.toLowerCase()}`}
-                name={name}
-                value={item.value}
-                onChange={onChange}
-                checked={item.value === value}
-              />
-              <label
-                htmlFor={`${name}_${item.value.toLowerCase()}`}
-                className="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
+        <div
+          className="flex items-center space-x-4"
+          role="group"
+          aria-labelledby={props.name}
+        >
+          {props.options.map((item) => {
+            return (
+              <div
+                className="flex mt-1"
+                key={`radio_item_${item.value.toLowerCase()}`}
               >
-                {item.label}
-              </label>
-            </div>
-          );
-        })}
+                <input
+                  type="radio"
+                  className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
+                  id={`${props.name}_${item.value.toLowerCase()}`}
+                  name={props.name}
+                  value={item.value}
+                  onChange={props.onChange}
+                  checked={item.value === props.value}
+                  disabled={props.disabled}
+                />
+                <label
+                  htmlFor={`${props.name}_${item.value.toLowerCase()}`}
+                  className="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
+                >
+                  {item.label}
+                </label>
+              </div>
+            );
+          })}
+        </div>
       </div>
+
+      {props.helpText && (
+        <div className="text-xs mt-1 italic text-gray-500 dark:text-gray-300">
+          {props.helpText}
+        </div>
+      )}
     </div>
   );
 };
diff --git a/src/routes/LoginWithToken.tsx b/src/routes/LoginWithToken.tsx
index fa533303..2f05eade 100644
--- a/src/routes/LoginWithToken.tsx
+++ b/src/routes/LoginWithToken.tsx
@@ -10,6 +10,8 @@ import type { AuthTokenOptions } from '../types';
 import { openExternalLink } from '../utils/comms';
 import { Constants } from '../utils/constants';
 
+import { format } from 'date-fns';
+
 interface IValues {
   token?: string;
   hostname?: string;
@@ -53,6 +55,9 @@ export const LoginWithToken: FC = () => {
   const renderForm = (formProps: FormRenderProps) => {
     const { handleSubmit, submitting, pristine, values } = formProps;
 
+    const buttonClasses =
+      'rounded bg-gray-300 font-semibold rounded text-sm text-center hover:bg-gray-500 hover:text-white dark:text-black focus:outline-none cursor-pointer';
+
     return (
       <form onSubmit={handleSubmit}>
         <FieldInput
@@ -60,25 +65,21 @@ export const LoginWithToken: FC = () => {
           label="Token"
           placeholder="The 40 characters token generated on GitHub"
           helpText={
-            <>
-              To generate a token, go to GitHub,{' '}
-              <button
-                type="button"
-                className="underline hover:text-gray-500 dark:hover:text-gray-300  cursor-pointer"
-                onClick={() =>
-                  openLink(
-                    'https://github.com/settings/tokens/new?scopes=notifications,read:user,repo&description=gitify_token',
-                  )
-                }
-              >
-                personal access tokens
-              </button>{' '}
-              and create one with the {Constants.AUTH_SCOPE.length} scopes{' '}
-              <span className="underline font-extrabold text-yellow-500">
-                {Constants.AUTH_SCOPE.join(', ')}{' '}
-              </span>
-              .
-            </>
+            <div>
+              <div>
+                Create a Personal Access Token on GitHub and paste above.
+              </div>
+              <div>
+                The required scopes will be selected for you.{' '}
+                <button
+                  type="button"
+                  className={`px-2 py-1 my-2 text-xs ${buttonClasses}`}
+                  onClick={() => openLink(getNewTokenURL())}
+                >
+                  Generate a PAT
+                </button>
+              </div>
+            </div>
           }
         />
 
@@ -86,7 +87,14 @@ export const LoginWithToken: FC = () => {
           name="hostname"
           label="Hostname"
           placeholder="github.company.com"
-          helpText="Defaults to github.com. Change only if you are using GitHub for Enterprise."
+          helpText={
+            <div>
+              <div>Defaults to github.com.</div>
+              <div className="italic">
+                Change only if you are using GitHub Enterprise Server.
+              </div>
+            </div>
+          }
         />
 
         {!isValidToken && (
@@ -96,7 +104,7 @@ export const LoginWithToken: FC = () => {
         )}
 
         <button
-          className="float-right px-4 py-2 my-4 bg-gray-300 font-semibold rounded text-sm text-center hover:bg-gray-500 hover:text-white dark:text-black focus:outline-none"
+          className={`float-right px-4 py-2 my-4 ${buttonClasses}`}
           title="Submit Button"
           disabled={submitting || pristine}
           type="submit"
@@ -134,7 +142,7 @@ export const LoginWithToken: FC = () => {
         </button>
 
         <h3 className="text-lg font-semibold">
-          Login with personal access token
+          Login with Personal Access Token
         </h3>
       </div>
 
@@ -153,3 +161,12 @@ export const LoginWithToken: FC = () => {
     </div>
   );
 };
+
+function getNewTokenURL(): string {
+  const date = format(new Date(), 'PP p');
+  const newTokenURL = new URL('https://github.com/settings/tokens/new');
+  newTokenURL.searchParams.append('description', `Gitify (Created on ${date})`);
+  newTokenURL.searchParams.append('scopes', Constants.AUTH_SCOPE.join(','));
+
+  return newTokenURL.toString();
+}
diff --git a/src/routes/Settings.tsx b/src/routes/Settings.tsx
index 89eb56c2..5d3afdfa 100644
--- a/src/routes/Settings.tsx
+++ b/src/routes/Settings.tsx
@@ -16,8 +16,8 @@ import {
 } from 'react';
 import { useNavigate } from 'react-router-dom';
 
-import { FieldCheckbox } from '../components/fields/Checkbox';
-import { FieldRadioGroup } from '../components/fields/RadioGroup';
+import { Checkbox } from '../components/fields/Checkbox';
+import { RadioGroup } from '../components/fields/RadioGroup';
 import { AppContext } from '../context/App';
 import { Theme } from '../types';
 import { apiRequestAuth } from '../utils/api-requests';
@@ -118,7 +118,7 @@ export const SettingsRoute: FC = () => {
           <legend id="appearance" className="font-semibold mt-2 mb-1">
             Appearance
           </legend>
-          <FieldRadioGroup
+          <RadioGroup
             name="theme"
             label="Theme:"
             value={settings.theme}
@@ -131,7 +131,7 @@ export const SettingsRoute: FC = () => {
               updateSetting('theme', evt.target.value);
             }}
           />
-          <FieldCheckbox
+          <Checkbox
             name="colors"
             label={`Use GitHub-like state colors${
               !colorScope ? ' (requires repo scope)' : ''
@@ -142,7 +142,7 @@ export const SettingsRoute: FC = () => {
             }
             disabled={!colorScope}
           />
-          <FieldCheckbox
+          <Checkbox
             name="showAccountHostname"
             label="Show account hostname"
             checked={settings.showAccountHostname}
@@ -153,10 +153,10 @@ export const SettingsRoute: FC = () => {
         </fieldset>
 
         <fieldset className="mb-3">
-          <legend id="notifications" className="font-semibold  mt-2 mb-1">
+          <legend id="notifications" className="font-semibold mt-2 mb-1">
             Notifications
           </legend>
-          <FieldCheckbox
+          <Checkbox
             name="showOnlyParticipating"
             label="Show only participating"
             checked={settings.participating}
@@ -164,13 +164,13 @@ export const SettingsRoute: FC = () => {
               updateSetting('participating', evt.target.checked)
             }
           />
-          <FieldCheckbox
+          <Checkbox
             name="showBots"
             label="Show notifications from Bot accounts"
             checked={settings.showBots}
             onChange={(evt) => updateSetting('showBots', evt.target.checked)}
           />
-          <FieldCheckbox
+          <Checkbox
             name="markAsDoneOnOpen"
             label="Mark as done on open"
             checked={settings.markAsDoneOnOpen}
@@ -181,18 +181,19 @@ export const SettingsRoute: FC = () => {
         </fieldset>
 
         <fieldset className="mb-3">
-          <legend id="system" className="font-semibold  mt-2 mb-1">
+          <legend id="system" className="font-semibold mt-2 mb-1">
             System
           </legend>
-          <FieldCheckbox
+          <Checkbox
             name="showNotificationsCountInTray"
             label="Show notifications count in tray"
             checked={settings.showNotificationsCountInTray}
             onChange={(evt) =>
               updateSetting('showNotificationsCountInTray', evt.target.checked)
             }
+            helpText="Changes will take effect after restarting the app"
           />
-          <FieldCheckbox
+          <Checkbox
             name="showNotifications"
             label="Show system notifications"
             checked={settings.showNotifications}
@@ -200,14 +201,14 @@ export const SettingsRoute: FC = () => {
               updateSetting('showNotifications', evt.target.checked)
             }
           />
-          <FieldCheckbox
+          <Checkbox
             name="playSound"
             label="Play sound"
             checked={settings.playSound}
             onChange={(evt) => updateSetting('playSound', evt.target.checked)}
           />
           {!isLinux && (
-            <FieldCheckbox
+            <Checkbox
               name="openAtStartUp"
               label="Open at startup"
               checked={settings.openAtStartup}
@@ -244,7 +245,7 @@ export const SettingsRoute: FC = () => {
           <button
             type="button"
             className={footerButtonClass}
-            title={`Logout ${accounts.user.login}`}
+            title={`Logout from ${accounts.user.login}`}
             role="button"
             onClick={logoutUser}
           >


Test patch:
diff --git a/src/components/fields/Checkbox.test.tsx b/src/components/fields/Checkbox.test.tsx
new file mode 100644
index 00000000..95f3496e
--- /dev/null
+++ b/src/components/fields/Checkbox.test.tsx
@@ -0,0 +1,18 @@
+import * as TestRenderer from 'react-test-renderer';
+
+import { Checkbox, type ICheckbox } from './Checkbox';
+
+describe('components/fields/Checkbox.tsx', () => {
+  const props: ICheckbox = {
+    name: 'appearance',
+    label: 'Appearance',
+    helpText: 'This is some helper text',
+    checked: true,
+    onChange: jest.fn(),
+  };
+
+  it('should render', () => {
+    const tree = TestRenderer.create(<Checkbox {...props} />);
+    expect(tree).toMatchSnapshot();
+  });
+});
diff --git a/src/components/fields/FieldInput.test.tsx b/src/components/fields/FieldInput.test.tsx
new file mode 100644
index 00000000..e180d8f1
--- /dev/null
+++ b/src/components/fields/FieldInput.test.tsx
@@ -0,0 +1,28 @@
+import * as TestRenderer from 'react-test-renderer';
+
+import { Form } from 'react-final-form';
+import { FieldInput, type IFieldInput } from './FieldInput';
+
+describe('components/fields/FieldInput.tsx', () => {
+  const props: IFieldInput = {
+    name: 'appearance',
+    label: 'Appearance',
+    placeholder: 'This is some placeholder text',
+    helpText: 'This is some helper text',
+  };
+
+  it('should render', () => {
+    const tree = TestRenderer.create(
+      <Form
+        onSubmit={() => {}}
+        hand
+        render={({ handleSubmit }) => (
+          <form onSubmit={handleSubmit}>
+            <FieldInput {...props} />
+          </form>
+        )}
+      />,
+    );
+    expect(tree).toMatchSnapshot();
+  });
+});
diff --git a/src/components/fields/RadioGroup.test.tsx b/src/components/fields/RadioGroup.test.tsx
index 38763e92..4a902abe 100644
--- a/src/components/fields/RadioGroup.test.tsx
+++ b/src/components/fields/RadioGroup.test.tsx
@@ -2,13 +2,13 @@ import { fireEvent, render, screen } from '@testing-library/react';
 
 import * as TestRenderer from 'react-test-renderer';
 
-import { FieldRadioGroup } from './RadioGroup';
+import { type IRadioGroup, RadioGroup } from './RadioGroup';
 
-describe('components/fields/radiogroup.tsx', () => {
-  const props = {
+describe('components/fields/RadioGroup.tsx', () => {
+  const props: IRadioGroup = {
     label: 'Appearance',
     name: 'appearance',
-    placeholder: 'This is some helper text',
+    helpText: 'This is some helper text',
     options: [
       { label: 'Value 1', value: 'one' },
       { label: 'Value 2', value: 'two' },
@@ -17,13 +17,20 @@ describe('components/fields/radiogroup.tsx', () => {
     value: 'two',
   };
 
-  it('should render ', () => {
-    const tree = TestRenderer.create(<FieldRadioGroup {...props} />);
+  it('should render', () => {
+    const tree = TestRenderer.create(<RadioGroup {...props} />);
+    expect(tree).toMatchSnapshot();
+  });
+
+  it('should render as disabled', () => {
+    const mockProps = { ...props, disabled: true };
+
+    const tree = TestRenderer.create(<RadioGroup {...mockProps} />);
     expect(tree).toMatchSnapshot();
   });
 
   it('should check that NProgress is getting called in getDerivedStateFromProps (loading)', () => {
-    render(<FieldRadioGroup {...props} />);
+    render(<RadioGroup {...props} />);
     fireEvent.click(screen.getByLabelText('Value 1'));
     expect(props.onChange).toHaveBeenCalledTimes(1);
   });
diff --git a/src/components/fields/__snapshots__/Checkbox.test.tsx.snap b/src/components/fields/__snapshots__/Checkbox.test.tsx.snap
new file mode 100644
index 00000000..0138d82b
--- /dev/null
+++ b/src/components/fields/__snapshots__/Checkbox.test.tsx.snap
@@ -0,0 +1,38 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/fields/Checkbox.tsx should render 1`] = `
+<div
+  className="mt-1 mb-3 text-sm"
+>
+  <div
+    className="flex items-start"
+  >
+    <div
+      className="flex items-center h-5"
+    >
+      <input
+        checked={true}
+        className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
+        id="appearance"
+        onChange={[MockFunction]}
+        type="checkbox"
+      />
+    </div>
+    <div
+      className="ml-3 "
+    >
+      <label
+        className="font-medium text-gray-700 dark:text-gray-200"
+        htmlFor="appearance"
+      >
+        Appearance
+      </label>
+    </div>
+  </div>
+  <div
+    className="text-xs mt-1 italic text-gray-500 dark:text-gray-300"
+  >
+    This is some helper text
+  </div>
+</div>
+`;
diff --git a/src/components/fields/__snapshots__/FieldInput.test.tsx.snap b/src/components/fields/__snapshots__/FieldInput.test.tsx.snap
new file mode 100644
index 00000000..145ed199
--- /dev/null
+++ b/src/components/fields/__snapshots__/FieldInput.test.tsx.snap
@@ -0,0 +1,35 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/fields/FieldInput.tsx should render 1`] = `
+<form
+  onSubmit={[Function]}
+>
+  <div
+    className="mt-2"
+  >
+    <label
+      className="block tracking-wide text-grey-dark text-sm font-semibold mb-2"
+      htmlFor="appearance"
+    >
+      Appearance
+    </label>
+    <input
+      className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none"
+      id="appearance"
+      name="appearance"
+      onBlur={[Function]}
+      onChange={[Function]}
+      onFocus={[Function]}
+      placeholder="This is some placeholder text"
+      required={false}
+      type="text"
+      value=""
+    />
+    <div
+      className="mt-3 text-gray-700 dark:text-gray-200 text-xs"
+    >
+      This is some helper text
+    </div>
+  </div>
+</form>
+`;
diff --git a/src/components/fields/__snapshots__/RadioGroup.test.tsx.snap b/src/components/fields/__snapshots__/RadioGroup.test.tsx.snap
index 70e146f0..4d6589d9 100644
--- a/src/components/fields/__snapshots__/RadioGroup.test.tsx.snap
+++ b/src/components/fields/__snapshots__/RadioGroup.test.tsx.snap
@@ -1,67 +1,148 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`components/fields/radiogroup.tsx should render  1`] = `
+exports[`components/fields/RadioGroup.tsx should render 1`] = `
 <div
-  className="flex items-start mt-1 mb-3"
+  className="mt-1 mb-3 text-sm"
 >
   <div
-    className="mr-3 text-sm py-1"
+    className="flex items-start"
   >
-    <label
-      className="font-medium text-gray-700 dark:text-gray-200 "
-      htmlFor="appearance"
+    <div
+      className="mr-3 py-1"
     >
-      Appearance
-    </label>
+      <label
+        className="font-medium text-gray-700 dark:text-gray-200 "
+        htmlFor="appearance"
+      >
+        Appearance
+      </label>
+    </div>
     <div
-      className="italic text-gray-500 dark:text-gray-300"
+      aria-labelledby="appearance"
+      className="flex items-center space-x-4"
+      role="group"
     >
-      This is some helper text
+      <div
+        className="flex mt-1"
+      >
+        <input
+          checked={false}
+          className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
+          id="appearance_one"
+          name="appearance"
+          onChange={[MockFunction]}
+          type="radio"
+          value="one"
+        />
+        <label
+          className="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
+          htmlFor="appearance_one"
+        >
+          Value 1
+        </label>
+      </div>
+      <div
+        className="flex mt-1"
+      >
+        <input
+          checked={true}
+          className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
+          id="appearance_two"
+          name="appearance"
+          onChange={[MockFunction]}
+          type="radio"
+          value="two"
+        />
+        <label
+          className="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
+          htmlFor="appearance_two"
+        >
+          Value 2
+        </label>
+      </div>
     </div>
   </div>
   <div
-    aria-labelledby="appearance"
-    className="flex items-center space-x-4"
-    role="group"
+    className="text-xs mt-1 italic text-gray-500 dark:text-gray-300"
+  >
+    This is some helper text
+  </div>
+</div>
+`;
+
+exports[`components/fields/RadioGroup.tsx should render as disabled 1`] = `
+<div
+  className="mt-1 mb-3 text-sm"
+>
+  <div
+    className="flex items-start"
   >
     <div
-      className="flex mt-1"
+      className="mr-3 py-1"
     >
-      <input
-        checked={false}
-        className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
-        id="appearance_one"
-        name="appearance"
-        onChange={[MockFunction]}
-        type="radio"
-        value="one"
-      />
       <label
-        className="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
-        htmlFor="appearance_one"
+        className="font-medium text-gray-700 dark:text-gray-200 "
+        htmlFor="appearance"
+        style={
+          {
+            "textDecoration": "line-through",
+          }
+        }
       >
-        Value 1
+        Appearance
       </label>
     </div>
     <div
-      className="flex mt-1"
+      aria-labelledby="appearance"
+      className="flex items-center space-x-4"
+      role="group"
     >
-      <input
-        checked={true}
-        className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
-        id="appearance_two"
-        name="appearance"
-        onChange={[MockFunction]}
-        type="radio"
-        value="two"
-      />
-      <label
-        className="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
-        htmlFor="appearance_two"
+      <div
+        className="flex mt-1"
       >
-        Value 2
-      </label>
+        <input
+          checked={false}
+          className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
+          disabled={true}
+          id="appearance_one"
+          name="appearance"
+          onChange={[MockFunction]}
+          type="radio"
+          value="one"
+        />
+        <label
+          className="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
+          htmlFor="appearance_one"
+        >
+          Value 1
+        </label>
+      </div>
+      <div
+        className="flex mt-1"
+      >
+        <input
+          checked={true}
+          className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
+          disabled={true}
+          id="appearance_two"
+          name="appearance"
+          onChange={[MockFunction]}
+          type="radio"
+          value="two"
+        />
+        <label
+          className="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
+          htmlFor="appearance_two"
+        >
+          Value 2
+        </label>
+      </div>
     </div>
   </div>
+  <div
+    className="text-xs mt-1 italic text-gray-500 dark:text-gray-300"
+  >
+    This is some helper text
+  </div>
 </div>
 `;
diff --git a/src/routes/LoginWithToken.test.tsx b/src/routes/LoginWithToken.test.tsx
index 6b5c5e44..cb50d13d 100644
--- a/src/routes/LoginWithToken.test.tsx
+++ b/src/routes/LoginWithToken.test.tsx
@@ -72,7 +72,7 @@ describe('routes/LoginWithToken.tsx', () => {
     expect(validate(values).token).toBe('Invalid token.');
   });
 
-  it("should click on the 'personal access tokens' link and open the browser", async () => {
+  it("should click on the 'Generate a PAT' link and open the browser", async () => {
     render(
       <AppContext.Provider value={{ validateToken: mockValidateToken }}>
         <MemoryRouter>
@@ -81,7 +81,7 @@ describe('routes/LoginWithToken.tsx', () => {
       </AppContext.Provider>,
     );
 
-    fireEvent.click(screen.getByText('personal access tokens'));
+    fireEvent.click(screen.getByText('Generate a PAT'));
 
     expect(openExternalMock).toHaveBeenCalledTimes(1);
   });
diff --git a/src/routes/Settings.test.tsx b/src/routes/Settings.test.tsx
index 26ba42a9..eefc923b 100644
--- a/src/routes/Settings.test.tsx
+++ b/src/routes/Settings.test.tsx
@@ -64,7 +64,7 @@ describe('routes/Settings.tsx', () => {
       );
     });
 
-    fireEvent.click(screen.getByTitle('Logout octocat'));
+    fireEvent.click(screen.getByTitle('Logout from octocat'));
 
     expect(logoutMock).toHaveBeenCalledTimes(1);
 
diff --git a/src/routes/__snapshots__/LoginEnterprise.test.tsx.snap b/src/routes/__snapshots__/LoginEnterprise.test.tsx.snap
index c913860c..109d0a93 100644
--- a/src/routes/__snapshots__/LoginEnterprise.test.tsx.snap
+++ b/src/routes/__snapshots__/LoginEnterprise.test.tsx.snap
@@ -58,7 +58,7 @@ exports[`routes/LoginEnterprise.tsx renders correctly 1`] = `
           Hostname
         </label>
         <input
-          className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none"
+          className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none text-sm"
           id="hostname"
           name="hostname"
           onBlur={[Function]}
@@ -80,7 +80,7 @@ exports[`routes/LoginEnterprise.tsx renders correctly 1`] = `
           Client ID
         </label>
         <input
-          className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none"
+          className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none text-sm"
           id="clientId"
           name="clientId"
           onBlur={[Function]}
@@ -102,7 +102,7 @@ exports[`routes/LoginEnterprise.tsx renders correctly 1`] = `
           Client Secret
         </label>
         <input
-          className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none"
+          className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none text-sm"
           id="clientSecret"
           name="clientSecret"
           onBlur={[Function]}
diff --git a/src/routes/__snapshots__/LoginWithToken.test.tsx.snap b/src/routes/__snapshots__/LoginWithToken.test.tsx.snap
index 79dadca9..36969118 100644
--- a/src/routes/__snapshots__/LoginWithToken.test.tsx.snap
+++ b/src/routes/__snapshots__/LoginWithToken.test.tsx.snap
@@ -39,7 +39,7 @@ exports[`routes/LoginWithToken.tsx renders correctly 1`] = `
     <h3
       className="text-lg font-semibold"
     >
-      Login with personal access token
+      Login with Personal Access Token
     </h3>
   </div>
   <div
@@ -58,7 +58,7 @@ exports[`routes/LoginWithToken.tsx renders correctly 1`] = `
           Token
         </label>
         <input
-          className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none"
+          className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none text-sm"
           id="token"
           name="token"
           onBlur={[Function]}
@@ -72,27 +72,22 @@ exports[`routes/LoginWithToken.tsx renders correctly 1`] = `
         <div
           className="mt-3 text-gray-700 dark:text-gray-200 text-xs"
         >
-          To generate a token, go to GitHub,
-           
-          <button
-            className="underline hover:text-gray-500 dark:hover:text-gray-300  cursor-pointer"
-            onClick={[Function]}
-            type="button"
-          >
-            personal access tokens
-          </button>
-           
-          and create one with the 
-          3
-           scopes
-           
-          <span
-            className="underline font-extrabold text-yellow-500"
-          >
-            read:user, notifications, repo
-             
-          </span>
-          .
+          <div>
+            <div>
+              Create a Personal Access Token on GitHub and paste above.
+            </div>
+            <div>
+              The required scopes will be selected for you.
+               
+              <button
+                className="px-2 py-1 my-2 text-xs rounded bg-gray-300 font-semibold rounded text-sm text-center hover:bg-gray-500 hover:text-white dark:text-black focus:outline-none cursor-pointer"
+                onClick={[Function]}
+                type="button"
+              >
+                Generate a PAT
+              </button>
+            </div>
+          </div>
         </div>
       </div>
       <div
@@ -105,7 +100,7 @@ exports[`routes/LoginWithToken.tsx renders correctly 1`] = `
           Hostname
         </label>
         <input
-          className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none"
+          className="appearance-none block w-full dark:text-gray-800 bg-gray-100 border border-red rounded py-1.5 px-4 mb-2 focus:bg-gray-200 focus:outline-none text-sm"
           id="hostname"
           name="hostname"
           onBlur={[Function]}
@@ -119,11 +114,20 @@ exports[`routes/LoginWithToken.tsx renders correctly 1`] = `
         <div
           className="mt-3 text-gray-700 dark:text-gray-200 text-xs"
         >
-          Defaults to github.com. Change only if you are using GitHub for Enterprise.
+          <div>
+            <div>
+              Defaults to github.com.
+            </div>
+            <div
+              className="italic"
+            >
+              Change only if you are using GitHub Enterprise Server.
+            </div>
+          </div>
         </div>
       </div>
       <button
-        className="float-right px-4 py-2 my-4 bg-gray-300 font-semibold rounded text-sm text-center hover:bg-gray-500 hover:text-white dark:text-black focus:outline-none"
+        className="float-right px-4 py-2 my-4 rounded bg-gray-300 font-semibold rounded text-sm text-center hover:bg-gray-500 hover:text-white dark:text-black focus:outline-none cursor-pointer"
         disabled={true}
         title="Submit Button"
         type="submit"
diff --git a/src/routes/__snapshots__/Settings.test.tsx.snap b/src/routes/__snapshots__/Settings.test.tsx.snap
index 3948a30f..e9448a0e 100644
--- a/src/routes/__snapshots__/Settings.test.tsx.snap
+++ b/src/routes/__snapshots__/Settings.test.tsx.snap
@@ -2,7 +2,7 @@
 
 exports[`routes/Settings.tsx should not be able to enable colors due to missing scope 1`] = `
 <div
-  class="flex items-start mt-1 mb-3"
+  class="flex items-start"
 >
   <div
     class="flex items-center h-5"
@@ -15,7 +15,7 @@ exports[`routes/Settings.tsx should not be able to enable colors due to missing
     />
   </div>
   <div
-    class="ml-3 text-sm"
+    class="ml-3 "
   >
     <label
       class="font-medium text-gray-700 dark:text-gray-200"
@@ -76,122 +76,134 @@ exports[`routes/Settings.tsx should render itself & its children 1`] = `
         Appearance
       </legend>
       <div
-        class="flex items-start mt-1 mb-3"
+        class="mt-1 mb-3 text-sm"
       >
         <div
-          class="mr-3 text-sm py-1"
-        >
-          <label
-            class="font-medium text-gray-700 dark:text-gray-200 "
-            for="theme"
-          >
-            Theme:
-          </label>
-        </div>
-        <div
-          aria-labelledby="theme"
-          class="flex items-center space-x-4"
-          role="group"
+          class="flex items-start"
         >
           <div
-            class="flex mt-1"
+            class="mr-3 py-1"
           >
-            <input
-              checked=""
-              class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
-              id="theme_system"
-              name="theme"
-              type="radio"
-              value="SYSTEM"
-            />
             <label
-              class="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
-              for="theme_system"
+              class="font-medium text-gray-700 dark:text-gray-200 "
+              for="theme"
             >
-              System
+              Theme:
             </label>
           </div>
           <div
-            class="flex mt-1"
+            aria-labelledby="theme"
+            class="flex items-center space-x-4"
+            role="group"
           >
-            <input
-              class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
-              id="theme_light"
-              name="theme"
-              type="radio"
-              value="LIGHT"
-            />
-            <label
-              class="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
-              for="theme_light"
+            <div
+              class="flex mt-1"
             >
-              Light
-            </label>
+              <input
+                checked=""
+                class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
+                id="theme_system"
+                name="theme"
+                type="radio"
+                value="SYSTEM"
+              />
+              <label
+                class="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
+                for="theme_system"
+              >
+                System
+              </label>
+            </div>
+            <div
+              class="flex mt-1"
+            >
+              <input
+                class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
+                id="theme_light"
+                name="theme"
+                type="radio"
+                value="LIGHT"
+              />
+              <label
+                class="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
+                for="theme_light"
+              >
+                Light
+              </label>
+            </div>
+            <div
+              class="flex mt-1"
+            >
+              <input
+                class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
+                id="theme_dark"
+                name="theme"
+                type="radio"
+                value="DARK"
+              />
+              <label
+                class="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
+                for="theme_dark"
+              >
+                Dark
+              </label>
+            </div>
           </div>
+        </div>
+      </div>
+      <div
+        class="mt-1 mb-3 text-sm"
+      >
+        <div
+          class="flex items-start"
+        >
           <div
-            class="flex mt-1"
+            class="flex items-center h-5"
           >
             <input
-              class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300"
-              id="theme_dark"
-              name="theme"
-              type="radio"
-              value="DARK"
+              class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
+              id="colors"
+              type="checkbox"
             />
+          </div>
+          <div
+            class="ml-3 "
+          >
             <label
-              class="ml-3 block text-sm font-medium text-gray-700 dark:text-white"
-              for="theme_dark"
+              class="font-medium text-gray-700 dark:text-gray-200"
+              for="colors"
+              style=""
             >
-              Dark
+              Use GitHub-like state colors
             </label>
           </div>
         </div>
       </div>
       <div
-        class="flex items-start mt-1 mb-3"
+        class="mt-1 mb-3 text-sm"
       >
         <div
-          class="flex items-center h-5"
+          class="flex items-start"
         >
-          <input
-            class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
-            id="colors"
-            type="checkbox"
-          />
-        </div>
-        <div
-          class="ml-3 text-sm"
-        >
-          <label
-            class="font-medium text-gray-700 dark:text-gray-200"
-            for="colors"
-            style=""
+          <div
+            class="flex items-center h-5"
           >
-            Use GitHub-like state colors
-          </label>
-        </div>
-      </div>
-      <div
-        class="flex items-start mt-1 mb-3"
-      >
-        <div
-          class="flex items-center h-5"
-        >
-          <input
-            class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
-            id="showAccountHostname"
-            type="checkbox"
-          />
-        </div>
-        <div
-          class="ml-3 text-sm"
-        >
-          <label
-            class="font-medium text-gray-700 dark:text-gray-200"
-            for="showAccountHostname"
+            <input
+              class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
+              id="showAccountHostname"
+              type="checkbox"
+            />
+          </div>
+          <div
+            class="ml-3 "
           >
-            Show account hostname
-          </label>
+            <label
+              class="font-medium text-gray-700 dark:text-gray-200"
+              for="showAccountHostname"
+            >
+              Show account hostname
+            </label>
+          </div>
         </div>
       </div>
     </fieldset>
@@ -199,79 +211,91 @@ exports[`routes/Settings.tsx should render itself & its children 1`] = `
       class="mb-3"
     >
       <legend
-        class="font-semibold  mt-2 mb-1"
+        class="font-semibold mt-2 mb-1"
         id="notifications"
       >
         Notifications
       </legend>
       <div
-        class="flex items-start mt-1 mb-3"
+        class="mt-1 mb-3 text-sm"
       >
         <div
-          class="flex items-center h-5"
+          class="flex items-start"
         >
-          <input
-            class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
-            id="showOnlyParticipating"
-            type="checkbox"
-          />
-        </div>
-        <div
-          class="ml-3 text-sm"
-        >
-          <label
-            class="font-medium text-gray-700 dark:text-gray-200"
-            for="showOnlyParticipating"
+          <div
+            class="flex items-center h-5"
+          >
+            <input
+              class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
+              id="showOnlyParticipating"
+              type="checkbox"
+            />
+          </div>
+          <div
+            class="ml-3 "
           >
-            Show only participating
-          </label>
+            <label
+              class="font-medium text-gray-700 dark:text-gray-200"
+              for="showOnlyParticipating"
+            >
+              Show only participating
+            </label>
+          </div>
         </div>
       </div>
       <div
-        class="flex items-start mt-1 mb-3"
+        class="mt-1 mb-3 text-sm"
       >
         <div
-          class="flex items-center h-5"
+          class="flex items-start"
         >
-          <input
-            checked=""
-            class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
-            id="showBots"
-            type="checkbox"
-          />
-        </div>
-        <div
-          class="ml-3 text-sm"
-        >
-          <label
-            class="font-medium text-gray-700 dark:text-gray-200"
-            for="showBots"
+          <div
+            class="flex items-center h-5"
           >
-            Show notifications from Bot accounts
-          </label>
+            <input
+              checked=""
+              class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
+              id="showBots"
+              type="checkbox"
+            />
+          </div>
+          <div
+            class="ml-3 "
+          >
+            <label
+              class="font-medium text-gray-700 dark:text-gray-200"
+              for="showBots"
+            >
+              Show notifications from Bot accounts
+            </label>
+          </div>
         </div>
       </div>
       <div
-        class="flex items-start mt-1 mb-3"
+        class="mt-1 mb-3 text-sm"
       >
         <div
-          class="flex items-center h-5"
-        >
-          <input
-            class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
-            id="markAsDoneOnOpen"
-            type="checkbox"
-          />
-        </div>
-        <div
-          class="ml-3 text-sm"
+          class="flex items-start"
         >
-          <label
-            class="font-medium text-gray-700 dark:text-gray-200"
-            for="markAsDoneOnOpen"
+          <div
+            class="flex items-center h-5"
           >
-            Mark as done on open
-          </label>
+            <input
+              class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
+              id="markAsDoneOnOpen"
+              type="checkbox"
+            />
+          </div>
+          <div
+            class="ml-3 "
+          >
+            <label
+              class="font-medium text-gray-700 dark:text-gray-200"
+              for="markAsDoneOnOpen"
+            >
+              Mark as done on open
+            </label>
+          </div>
         </div>
       </div>
     </fieldset>
@@ -279,103 +303,124 @@ exports[`routes/Settings.tsx should render itself & its children 1`] = `
       class="mb-3"
     >
       <legend
-        class="font-semibold  mt-2 mb-1"
+        class="font-semibold mt-2 mb-1"
         id="system"
       >
         System
       </legend>
       <div
-        class="flex items-start mt-1 mb-3"
+        class="mt-1 mb-3 text-sm"
       >
         <div
-          class="flex items-center h-5"
+          class="flex items-start"
         >
-          <input
-            class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
-            id="showNotificationsCountInTray"
-            type="checkbox"
-          />
+          <div
+            class="flex items-center h-5"
+          >
+            <input
+              class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
+              id="showNotificationsCountInTray"
+              type="checkbox"
+            />
+          </div>
+          <div
+            class="ml-3 "
+          >
+            <label
+              class="font-medium text-gray-700 dark:text-gray-200"
+              for="showNotificationsCountInTray"
+            >
+              Show notifications count in tray
+            </label>
+          </div>
         </div>
         <div
-          class="ml-3 text-sm"
+          class="text-xs mt-1 italic text-gray-500 dark:text-gray-300"
         >
-          <label
-            class="font-medium text-gray-700 dark:text-gray-200"
-            for="showNotificationsCountInTray"
-          >
-            Show notifications count in tray
-          </label>
+          Changes will take effect after restarting the app
         </div>
       </div>
       <div
-        class="flex items-start mt-1 mb-3"
+        class="mt-1 mb-3 text-sm"
       >
         <div
-          class="flex items-center h-5"
-        >
-          <input
-            checked=""
-            class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
-            id="showNotifications"
-            type="checkbox"
-          />
-        </div>
-        <div
-          class="ml-3 text-sm"
+          class="flex items-start"
         >
-          <label
-            class="font-medium text-gray-700 dark:text-gray-200"
-            for="showNotifications"
+          <div
+            class="flex items-center h-5"
           >
-            Show system notifications
-          </label>
+            <input
+              checked=""
+              class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
+              id="showNotifications"
+              type="checkbox"
+            />
+          </div>
+          <div
+            class="ml-3 "
+          >
+            <label
+              class="font-medium text-gray-700 dark:text-gray-200"
+              for="showNotifications"
+            >
+              Show system notifications
+            </label>
+          </div>
         </div>
       </div>
       <div
-        class="flex items-start mt-1 mb-3"
+        class="mt-1 mb-3 text-sm"
       >
         <div
-          class="flex items-center h-5"
-        >
-          <input
-            checked=""
-            class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
-            id="playSound"
-            type="checkbox"
-          />
-        </div>
-        <div
-          class="ml-3 text-sm"
+          class="flex items-start"
         >
-          <label
-            class="font-medium text-gray-700 dark:text-gray-200"
-            for="playSound"
+          <div
+            class="flex items-center h-5"
+          >
+            <input
+              checked=""
+              class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
+              id="playSound"
+              type="checkbox"
+            />
+          </div>
+          <div
+            class="ml-3 "
           >
-            Play sound
-          </label>
+            <label
+              class="font-medium text-gray-700 dark:text-gray-200"
+              for="playSound"
+            >
+              Play sound
+            </label>
+          </div>
         </div>
       </div>
       <div
-        class="flex items-start mt-1 mb-3"
+        class="mt-1 mb-3 text-sm"
       >
         <div
-          class="flex items-center h-5"
+          class="flex items-start"
         >
-          <input
-            class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
-            id="openAtStartUp"
-            type="checkbox"
-          />
-        </div>
-        <div
-          class="ml-3 text-sm"
-        >
-          <label
-            class="font-medium text-gray-700 dark:text-gray-200"
-            for="openAtStartUp"
+          <div
+            class="flex items-center h-5"
           >
-            Open at startup
-          </label>
+            <input
+              class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
+              id="openAtStartUp"
+              type="checkbox"
+            />
+          </div>
+          <div
+            class="ml-3 "
+          >
+            <label
+              class="font-medium text-gray-700 dark:text-gray-200"
+              for="openAtStartUp"
+            >
+              Open at startup
+            </label>
+          </div>
         </div>
       </div>
     </fieldset>
@@ -416,7 +461,7 @@ exports[`routes/Settings.tsx should render itself & its children 1`] = `
       <button
         class="hover:text-gray-500 py-1 px-2 my-1 mx-2 focus:outline-none"
         role="button"
-        title="Logout octocat"
+        title="Logout from octocat"
         type="button"
       >
         <svg