Buttons > HAML/Ruby > Migrate to Pajamas::ButtonComponent
There are HAML templates and Ruby files that do not use Pajamas compliant abstractions. These should be migrated to one of the following methods: - `Pajamas::ButtonComponent` - `link_button_to` - `form.submit ... pajamas_button: true` See the examples below to help you figure out which is best. ### :exclamation: Exclusions :exclamation: Most of these issues were created with automation, so there might be some which aren't valid. These should _not_ be picked up. If you find one which looks invalid (see below) please ask `@gitlab-org/manage/foundations/engineering` on the issue for guidance. This epic **excludes**: 1. Any buttons that are related to dropdowns, whether that's the trigger/toggle, as they will be handled in https://gitlab.com/groups/gitlab-org/-/epics/1059. If the file you're looking at includes `dropdown` in either its name or content somewhere, there's a good chance it's not valid for a button migration. 2. Buttons that look like links, as there's some overlap with https://gitlab.com/groups/gitlab-org/-/epics/4232. ### Quick links: [[_TOC_]] ### Help us keep the noise to a minimum 🤫 We don't want to have lots of one-liner Merge Requests, as each MR triggers a CI pipeline and some overhead for both the author and reviewers. We think around **5 buttons per MR** is a good number. This may mean assigning yourself to more than one issue. In your MR, link to all issues it addresses. #### What if my issue only has only one or two buttons to migrate? In this case, please consider picking up other issues to work on and include in your MR until you have around 5 buttons to migrate. #### What if my issue has lots buttons to migrate? In this case, please migrate all of the buttons in that file. There's no need to add more into your MR, and there's no need to split your MR up. ## Migration strategies The `Pajamas::ButtonComponent` supports the same set of options as the [`GlButton`](https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/base-button--default) except the `label` property and `emoji` slot as they do not seem to be used. If you find the case which `Pajamas::ButtonComponent` does not support you can: 1. :track_next: Ping `@gitlab-org/manage/foundations/engineering` mentioning that, leave the issue alone and pick the next one 2. :muscle: if you feel empowered to contribute to `Pajamas::ButtonComponent` - feel free to implement the missing functionality and still ping the people from above :wink: ### Example 1: <code>%button</code> ```diff - %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded_by_default? ? _('Collapse') : _('Expand') ``` ### Example 2: `button_tag` ```diff - = button_tag 'Commit changes', id: 'commit-changes', class: 'gl-button btn btn-confirm js-commit-button qa-commit-button' + = render Pajamas::ButtonComponent.new(variant: :confirm, button_options: { id: 'commit-changes', class: 'js-commit-button qa-commit-button' }) do + = _('Commit changes') ``` ### Example 3: `link_to` (link buttons) ```diff - = link_to s_('TagsPage|Cancel'), project_tags_path(@project), class: 'gl-button btn btn-default btn-cancel' + = render Pajamas::ButtonComponent.new(href: project_tags_path(@project)) do + = s_('TagsPage|Cancel') ``` There is also a `link_button_to` helper that was added in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121772. So the above example could also be migrated like this: ```diff - = link_to s_('TagsPage|Cancel'), project_tags_path(@project), class: 'gl-button btn btn-default btn-cancel' + = link_button_to s_('TagsPage|Cancel'), project_tags_path(@project) ``` See that MR for more examples of how to use that helper. ### Example 4: `link_to` (link buttons with icons) ```diff - = link_to new_import_github_path(ci_cd_only: true), class: 'btn gl-button btn-default js-import-github', data: { track_label: "#{track_label}", track_property: 'github', track_action: "click_button", track_value: "" } do - = sprite_icon('github', css_class: 'gl-button-icon') - GitHub + = render Pajamas::ButtonComponent.new(href: new_import_github_path(ci_cd_only: true), icon: 'github', button_options: { class: 'js-import-github', data: { track_label: "#{track_label}", track_property: 'github', track_action: "click_button", track_value: "" } }) do + GitHub ``` or with the `link_button_to` helper: ```diff - = link_to new_import_github_path(ci_cd_only: true), class: 'btn gl-button btn-default js-import-github', data: { track_label: "#{track_label}", track_property: 'github', track_action: "click_button", track_value: "" } do - = sprite_icon('github', css_class: 'gl-button-icon') - GitHub + = link_button_to new_import_github_path(ci_cd_only: true), class: 'js-import-github', data: { track_label: "#{track_label}", track_property: 'github', track_action: "click_button", track_value: "" }, icon: 'github' do + GitHub ``` ### Example 5: Implicit submit buttons Buttons inside forms default to `type="submit"` where our `Pajamas::ButtonComponent` implicitly always sets `type="button"`, since that's the more common use case for us. To override the default type, provide the `type` argument to the component. Make sure to rebase on `master` as the support for the `type` parameter was just [merged](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89797). ```diff - = button_tag 'Commit changes', id: 'commit-changes', class: 'gl-button btn btn-confirm js-commit-button qa-commit-button' + = render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, button_options: { id: 'commit-changes', class: 'js-commit-button qa-commit-button'}) do + = _('Commit changes') ``` ### Example 6: `button_to` helper The [`button_to` Rails helper](https://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-button_to) creates a button wrapped in a form. The same effect can be achieved with `Pajamas::ButtonComponent` and its `method` option. ```diff -= button_to _("Reset registration token"), reset_token_url, method: :put += render Pajamas::ButtonComponent.new(method: :put, href: reset_token_url }) do + = _('Reset registration token') ``` ### Example 7: `button_tag` in Ruby files ```diff - button = button_tag(type: :button, class: 'btn btn-danger custom-class') do - content_tag(:span, 'hello', class: 'gl-font-weight-bold') + button = render Pajamas::ButtonComponent.new(variant: :danger, button_text_classes: 'gl-font-weight-bold', button_options: { class: 'custom-class' }) do + content_tag(:span, 'hello') end ``` ### Forms and <code>form.submit</code> These examples were taken from https://gitlab.com/groups/gitlab-org/-/epics/8537. #### Example 8.0 (important) The new behavior is only available if the form uses our custom form builder, not the Rails default. So if the submit button is part of a `= form_for ...`, then change that to `= gitlab_ui_form_for` first. ```diff - = form_for @application_setting, url: some_path do |f| + = gitlab_ui_form_for @application_setting, url: some_path do |f| ``` #### Example 8.1 Remove the CSS classes that styled it as a button, and add the `pajamas_button: true` option instead. ```diff - = f.submit _('Save changes'), class: 'gl-button btn-confirm' + = f.submit _('Save changes'), pajamas_button: true ``` #### Example 8.2 Leave any other attributes (ids, data, disabled, ...) untouched. ```diff - = f.submit _('Save changes'), class: 'gl-button btn btn-confirm gl-mt-5', data: { qa_selector: 'save_changes_button' }, disabled: true + = f.submit _('Save changes'), class: 'gl-mt-5', data: { qa_selector: 'save_changes_button' }, disabled: true, pajamas_button: true ``` ### Example 9: `clipboard_button` 1. Replace calls to the `deprecated_clipboard_button` helper with `clipboard_button`. 2. Remove redundant classes, like `gl-button`. 3. Replace classes like `btn-confirm` with `variant: :confirm`. 4. Any other clean up that makes sense. ```diff - = deprecated_clipboard_button(target: '#clone_url', title: _("Copy URL"), class: "input-group-text gl-button btn-default btn-clipboard") + = clipboard_button(target: '#clone_url', title: _("Copy URL"), variant: :default, category: :primary, size: :medium) ``` More examples in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/126574 and https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130409. ## Deprecated variants If the button you're migrating uses the `btn-info`, `btn-success`, or `btn-warning` classes, it should use a non-deprecated variant instead - `Pajamas::ButtonComponent` does not support deprecated variants. | Deprecated variant | Becomes | | ------ | ------ | | `info` | usually `confirm` | | `success` | `confirm` or `default` | | `warning` | Determined case-by-case; ask ~UX for guidance | ## Thanks! Thank you for helping with these migrations :handshake:
epic