Tabs > Vue > Migrate custom implementations to GlTabs in GitLab
### Instructions
1. First, import `GlTabs` and `GlTab`:
```
import { GlTabs, GlTab } from '@gitlab/ui';
```
2. Add these to your `components` section under `export default`:
```patch
export default {
components: {
+ GlTabs,
+ GlTab,
},
}
```
3. Locate the existing tabs. They might look something like this:
```html
<ul class="nav-links issues-state-filters">
<li :class="{ active: activeTab == 'all' }">
<a href="#" role="button" @click.prevent="changeTab('all')">
Open issues <span class="badge badge-pill"> {{ issuesCount }} </span>
</a>
</li>
<li :class="{ active: activeTab == 'selected' }">
<a href="#" role="button" @click.prevent="changeTab('selected')">
Selected issues <span class="badge badge-pill"> {{ selectedCount }} </span>
</a>
</li>
</ul>
```
4. Now that we've located our existing tabs, we're going to replace them with our new `GlTabs`. If you need to see an existing example, refer to our [existing documentation on Pajamas](https://design.gitlab.com/components/tabs/code) to see how the structure is set up.
5. Keep the existing code visible to make this an easy transition, do this by moving it out of the way, a few lines below where we'll add our new `gl-tabs`. This way, you can easily access the content you need to keep and discard what you don't. Now that you've moved the existing tabs out of the way, add in the new `gl-tabs` component to our HTML:
```html
<gl-tabs>
<gl-tab title="First">
</gl-tab>
<gl-tab title="Second">
</gl-tab>
</gl-tabs>
```
6. Now that we have our new structure, there's a couple things to notice. First is the `title` attribute, this will be the new place for our tab title, whereas in our existing tab structure, it's within the `<a>` tag. Also notice our existing tab structure is using a counter badge. Since we're using a counter badge, we'll need to add some extra code based on our [tabs-with-counter-badges example](https://design.gitlab.com/components/tabs/code) in our docs. Let's add in our new titles and badge count:
```html
<gl-tabs>
<gl-tab>
<template slot="title">
<span>Open issues</span>
<gl-badge size="sm" class="gl-tab-counter-badge">{{ issuesCount }}</gl-badge>
</template>
</gl-tab>
<gl-tab>
<template slot="title">
<span>Selected issues</span>
<gl-badge size="sm" class="gl-tab-counter-badge">{{ selectedCount }}</gl-badge>
</template>
</gl-tab>
</gl-tabs>
```
7. Since we're using a `badge` counter now, we'll also need to import and add `GlBadge` to our import and `components` section:
```
import { GlTabs, GlTab, GlBadge } from '@gitlab/ui';
```
```patch
export default {
components: {
GlTabs,
GlTab,
+ GlBadge,
},
}
```
8. If your tabs don't contain any content, like in this example, they are probably coming in from somewhere else. If that's the case, there will likely be a click event attached to the tabs, like there is in our existing example. Let's bring the click events over to our new tabs:
```html
<gl-tabs>
<gl-tab @click.prevent="changeTab('all')">
<template slot="title">
<span>Open issues</span>
<gl-badge size="sm" class="gl-tab-counter-badge">{{ issuesCount }}</gl-badge>
</template>
</gl-tab>
<gl-tab @click.prevent="changeTab('selected')">
<template slot="title">
<span>Selected issues</span>
<gl-badge size="sm" class="gl-tab-counter-badge">{{ selectedCount }}</gl-badge>
</template>
</gl-tab>
</gl-tabs>
```
9. If you have existing content inside the tabs, just copy and paste it in the correct tabs:
```html
<gl-tabs>
<gl-tab>
<template slot="title">
<span>Open issues</span>
<gl-badge size="sm" class="gl-tab-counter-badge">{{ issuesCount }}</gl-badge>
</template>
If there was existing content, just paste it here.
</gl-tab>
<gl-tab>
<template slot="title">
<span>Selected issues</span>
<gl-badge size="sm" class="gl-tab-counter-badge">{{ selectedCount }}</gl-badge>
</template>
Here could be content for the second tab, if there was any.
</gl-tab>
</gl-tabs>
```
10. That's it!
### Troubleshooting
* If you have questions, please `@mention` a [UX/FE Foundations member](https://about.gitlab.com/company/team/?department=fe-ux-foundations-team) and we will be happy to help.
* There will likely be edge cases that aren't covered by this help doc, if that's the case, again, please reach out to a Foundations member and we will be happy to assist.
### Existing examples that should be replaced
GitLab's codebase contains a few Vue-based tabs implementations that should be replaced with the GitLab UI, Pajamas-compliant, [`GlTabs` component](https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/base-tabs-tabs--default).
Here are the custom implementation at hand:
* [`app/assets/javascripts/vue_shared/components/navigation_tabs.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/3e0b9c0fcda61e5fa30aacae1c1bc6b2b5faabbb/app/assets/javascripts/vue_shared/components/navigation_tabs.vue) is being used in:
* [`app/assets/javascripts/deploy_keys/components/app.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/3e0b9c0fcda61e5fa30aacae1c1bc6b2b5faabbb/app/assets/javascripts/deploy_keys/components/app.vue)
* [`app/assets/javascripts/environments/mixins/environments_mixin.js`](https://gitlab.com/gitlab-org/gitlab/-/blob/3e0b9c0fcda61e5fa30aacae1c1bc6b2b5faabbb/app/assets/javascripts/environments/mixins/environments_mixin.js)
* [`app/assets/javascripts/environments/components/environments_app.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/3e0b9c0fcda61e5fa30aacae1c1bc6b2b5faabbb/app/assets/javascripts/environments/components/environments_app.vue)
* [`app/assets/javascripts/environments/folder/environments_folder_view.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/3e0b9c0fcda61e5fa30aacae1c1bc6b2b5faabbb/app/assets/javascripts/environments/folder/environments_folder_view.vue)
* [`app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/3e0b9c0fcda61e5fa30aacae1c1bc6b2b5faabbb/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue)
* [`ee/app/assets/javascripts/feature_flags/components/feature_flags.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/3e0b9c0fcda61e5fa30aacae1c1bc6b2b5faabbb/ee/app/assets/javascripts/feature_flags/components/feature_flags.vue)
* [`app/assets/javascripts/vue_shared/components/tabs/tabs.js`](https://gitlab.com/gitlab-org/gitlab/-/blob/3e0b9c0fcda61e5fa30aacae1c1bc6b2b5faabbb/app/assets/javascripts/vue_shared/components/tabs/tabs.js) is being used in:
* [`app/assets/javascripts/ide/components/nav_form.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/3e0b9c0fcda61e5fa30aacae1c1bc6b2b5faabbb/app/assets/javascripts/ide/components/nav_form.vue)
* [`app/assets/javascripts/ide/components/pipelines/list.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/3e0b9c0fcda61e5fa30aacae1c1bc6b2b5faabbb/app/assets/javascripts/ide/components/pipelines/list.vue)
* [`app/assets/javascripts/boards/components/modal/tabs.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/3e0b9c0fcda61e5fa30aacae1c1bc6b2b5faabbb/app/assets/javascripts/boards/components/modal/tabs.vue)
* [`app/assets/javascripts/ide/components/repo_tabs.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/3e0b9c0fcda61e5fa30aacae1c1bc6b2b5faabbb/app/assets/javascripts/ide/components/repo_tabs.vue)
* [`ee/app/assets/javascripts/requirements/components/requirements_tabs.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/0a8fe94b438a379479d2c212e70df72c8c83b576/ee/app/assets/javascripts/requirements/components/requirements_tabs.vue)
## Integration strategy
- [ ] Update all child files to use `GlTabs` instead of the custom implementations
- [ ] Remove the custom implementations from the codebase
epic