diff --git a/app/assets/javascripts/design_management/components/design_todo_button.vue b/app/assets/javascripts/design_management/components/design_todo_button.vue
index c614fee17d114c03083bf239905914099dc0b091..013dd1d89f3caebcb9f5a902876adcac51811ad1 100644
--- a/app/assets/javascripts/design_management/components/design_todo_button.vue
+++ b/app/assets/javascripts/design_management/components/design_todo_button.vue
@@ -1,6 +1,6 @@
 <script>
 import todoMarkDoneMutation from '~/graphql_shared/mutations/todo_mark_done.mutation.graphql';
-import TodoButton from '~/vue_shared/components/sidebar/todo_button.vue';
+import TodoButton from '~/vue_shared/components/sidebar/todo_toggle/todo_button.vue';
 import createDesignTodoMutation from '../graphql/mutations/create_design_todo.mutation.graphql';
 import getDesignQuery from '../graphql/queries/get_design.query.graphql';
 import allVersionsMixin from '../mixins/all_versions';
diff --git a/app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue b/app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue
index f0784f2ed10660d32a32b6dcbf81e02c3529e03e..a9c4203af22b2e34f6938ebad512955fcc2f2735 100644
--- a/app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue
+++ b/app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue
@@ -1,13 +1,15 @@
 <script>
-import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
+import { GlButton, GlIcon, GlTooltipDirective } from '@gitlab/ui';
 import { produce } from 'immer';
 import createFlash from '~/flash';
 import { __, sprintf } from '~/locale';
 import { todoQueries, TodoMutationTypes, todoMutations } from '~/sidebar/constants';
-import TodoButton from '~/vue_shared/components/sidebar/todo_button.vue';
+import { todoLabel } from '~/vue_shared/components/sidebar/todo_toggle//utils';
+import TodoButton from '~/vue_shared/components/sidebar/todo_toggle/todo_button.vue';
 
 export default {
   components: {
+    GlButton,
     GlIcon,
     TodoButton,
   },
@@ -96,7 +98,7 @@ export default {
       return this.hasTodo ? 'todo-done' : 'todo-add';
     },
     tootltipTitle() {
-      return this.hasTodo ? __('Mark as done') : __('Add a to do');
+      return todoLabel(this.hasTodo);
     },
   },
   methods: {
@@ -173,16 +175,21 @@ export default {
       class="hide-collapsed"
       @click.stop.prevent="toggleTodo"
     />
-    <div v-if="isClassicSidebar" class="sidebar-collapsed-icon sidebar-collapsed-container">
+    <gl-button
+      v-if="isClassicSidebar"
+      category="tertiary"
+      type="reset"
+      class="sidebar-collapsed-icon sidebar-collapsed-container gl-rounded-0! gl-shadow-none!"
+      @click.stop.prevent="toggleTodo"
+    >
       <gl-icon
-        v-gl-tooltip
+        v-gl-tooltip.left.viewport
         :title="tootltipTitle"
         :size="16"
         :class="{ 'todo-undone': hasTodo }"
         :name="collapsedButtonIcon"
         :aria-label="collapsedButtonIcon"
-        @click.stop.prevent="toggleTodo"
       />
-    </div>
+    </gl-button>
   </div>
 </template>
diff --git a/app/assets/javascripts/sidebar/mount_sidebar.js b/app/assets/javascripts/sidebar/mount_sidebar.js
index 380ec1f7527181383ed895a8d88f00dc0e8c4236..dd1b439c482e3fa29b4c658a57900e913c38a293 100644
--- a/app/assets/javascripts/sidebar/mount_sidebar.js
+++ b/app/assets/javascripts/sidebar/mount_sidebar.js
@@ -2,6 +2,8 @@ import $ from 'jquery';
 import Vue from 'vue';
 import VueApollo from 'vue-apollo';
 import createFlash from '~/flash';
+import { TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants';
+import { convertToGraphQLId } from '~/graphql_shared/utils';
 import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
 import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
 import { IssuableType } from '~/issue_show/constants';
@@ -22,7 +24,6 @@ import SidebarDropdownWidget from '~/sidebar/components/sidebar_dropdown_widget.
 import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue';
 import { apolloProvider } from '~/sidebar/graphql';
 import trackShowInviteMemberLink from '~/sidebar/track_invite_members';
-import { toIssueGid, toMergeRequestGid } from '~/sidebar/utils';
 import Translate from '../vue_shared/translate';
 import SidebarAssignees from './components/assignees/sidebar_assignees.vue';
 import CopyEmailToClipboard from './components/copy_email_to_clipboard.vue';
@@ -64,7 +65,10 @@ function mountSidebarToDoWidget() {
       createElement('sidebar-todo-widget', {
         props: {
           fullPath: projectPath,
-          issuableId: isInIssuePage() || isInDesignPage() ? toIssueGid(id) : toMergeRequestGid(id),
+          issuableId:
+            isInIssuePage() || isInDesignPage()
+              ? convertToGraphQLId(TYPE_ISSUE, id)
+              : convertToGraphQLId(TYPE_MERGE_REQUEST, id),
           issuableIid: iid,
           issuableType:
             isInIssuePage() || isInDesignPage() ? IssuableType.Issue : IssuableType.MergeRequest,
diff --git a/app/assets/javascripts/sidebar/utils.js b/app/assets/javascripts/sidebar/utils.js
index 06bb1ee59f173e9a74dfb74d75706e39d8529ea3..20cd4ce9d99d7641734749a781f2fd60cd2dfee7 100644
--- a/app/assets/javascripts/sidebar/utils.js
+++ b/app/assets/javascripts/sidebar/utils.js
@@ -1,5 +1 @@
 export const toLabelGid = (id) => `gid://gitlab/Label/${id}`;
-
-export const toIssueGid = (id) => `gid://gitlab/Issue/${id}`;
-
-export const toMergeRequestGid = (id) => `gid://gitlab/MergeRequest/${id}`;
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/todo_button.stories.js b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.stories.js
similarity index 90%
rename from app/assets/javascripts/vue_shared/components/sidebar/todo_button.stories.js
rename to app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.stories.js
index db4d8724a0d9f6dd8a0ec7b78231d9bd56cad900..d2afc02233efc966d8e3e632a406b7f3a1e21788 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/todo_button.stories.js
+++ b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.stories.js
@@ -4,7 +4,7 @@ import TodoButton from './todo_button.vue';
 
 export default {
   component: TodoButton,
-  title: 'vue_shared/components/todo_button',
+  title: 'vue_shared/components/todo_toggle/todo_button',
 };
 
 const Template = (args, { argTypes }) => ({
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/todo_button.vue b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue
similarity index 92%
rename from app/assets/javascripts/vue_shared/components/sidebar/todo_button.vue
rename to app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue
index a35171835153e473ffaaf42fa703fe8877d11a8b..e6229cf0a937abc1445824eef7ae4dd7003b259a 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/todo_button.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue
@@ -1,6 +1,6 @@
 <script>
 import { GlButton } from '@gitlab/ui';
-import { __ } from '~/locale';
+import { todoLabel } from './utils';
 
 export default {
   components: {
@@ -15,7 +15,7 @@ export default {
   },
   computed: {
     buttonLabel() {
-      return this.isTodo ? __('Mark as done') : __('Add a to do');
+      return todoLabel(this.isTodo);
     },
   },
   methods: {
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/utils.js b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/utils.js
new file mode 100644
index 0000000000000000000000000000000000000000..59e72a2ffe34c23e0c80e751307936aff801b2b6
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/utils.js
@@ -0,0 +1,5 @@
+import { __ } from '~/locale';
+
+export const todoLabel = (hasTodo) => {
+  return hasTodo ? __('Mark as done') : __('Add a to do');
+};
diff --git a/doc/development/fe_guide/storybook.md b/doc/development/fe_guide/storybook.md
index 986eafb11da455d9a208c1133a00743617024049..15225cc1debbb3843a6754420747c66998f9b586 100644
--- a/doc/development/fe_guide/storybook.md
+++ b/doc/development/fe_guide/storybook.md
@@ -47,5 +47,5 @@ To add a story:
 
    Notes:
    - Specify the `title` field of the story as the component's file path from the `javascripts/` directory,
-     e.g. if the component is located at `app/assets/javascripts/vue_shared/components/sidebar/todo_button.vue`, specify the `title` as
+     e.g. if the component is located at `app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue`, specify the `title` as
      `vue_shared/components/To-do Button`. This will ensure the Storybook navigation maps closely to our internal directory structure.
diff --git a/spec/frontend/design_management/components/design_todo_button_spec.js b/spec/frontend/design_management/components/design_todo_button_spec.js
index 816de32d2db6855aa0008ee3cba542b5f24f24cd..757bf50c5278348615fabb954fa8bd650772867a 100644
--- a/spec/frontend/design_management/components/design_todo_button_spec.js
+++ b/spec/frontend/design_management/components/design_todo_button_spec.js
@@ -2,7 +2,7 @@ import { shallowMount, mount } from '@vue/test-utils';
 import DesignTodoButton from '~/design_management/components/design_todo_button.vue';
 import createDesignTodoMutation from '~/design_management/graphql/mutations/create_design_todo.mutation.graphql';
 import todoMarkDoneMutation from '~/graphql_shared/mutations/todo_mark_done.mutation.graphql';
-import TodoButton from '~/vue_shared/components/sidebar/todo_button.vue';
+import TodoButton from '~/vue_shared/components/sidebar/todo_toggle/todo_button.vue';
 import mockDesign from '../mock_data/design';
 
 const mockDesignWithPendingTodos = {
diff --git a/spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js b/spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js
index 8190545f7d4dc973fe13fb95add481d93c296b0c..23f1753c4bf655294a51be7fd0c2928778200f24 100644
--- a/spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js
+++ b/spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js
@@ -7,7 +7,7 @@ import waitForPromises from 'helpers/wait_for_promises';
 import createFlash from '~/flash';
 import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue';
 import epicTodoQuery from '~/sidebar/queries/epic_todo.query.graphql';
-import TodoButton from '~/vue_shared/components/sidebar/todo_button.vue';
+import TodoButton from '~/vue_shared/components/sidebar/todo_toggle/todo_button.vue';
 import { todosResponse, noTodosResponse } from '../../mock_data';
 
 jest.mock('~/flash');
diff --git a/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js b/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
index 123a995ad57783db77a6c85b4ec961eaa0e9061c..de3e1ccfb03104e3e7aba9dcd54ad75806aed920 100644
--- a/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
@@ -1,6 +1,6 @@
 import { GlButton } from '@gitlab/ui';
 import { shallowMount, mount } from '@vue/test-utils';
-import TodoButton from '~/vue_shared/components/sidebar/todo_button.vue';
+import TodoButton from '~/vue_shared/components/sidebar/todo_toggle/todo_button.vue';
 
 describe('Todo Button', () => {
   let wrapper;