Commit 63f5c4ea authored by Annabel Dunstone Gray's avatar Annabel Dunstone Gray

Merge branch '24150-consistent-dropdown-styles' into 'master'

Homogenize sort and filter dropdown toggles

## What does this MR do?

Homogenizes the style of *filter* and *sort* dropdown toggles (aka buttons) related to:
- *issues* (index, new & edit views)
- *issue boards* (index);
- *merge requests* (index, new, edit);
- *projects* (index and "explore");
- *projects admin* (index);
- *groups* (show and "explore");
- *groups admin* (index);
- *users admin* (index);
- *todos* (index);
- *branches* (index);
- *commits* (index);
- *cycle analytics*;
- *network*;
- *forks*;
- *tags* (index);
- *global search*

Some other dropdowns are incidently concerned:
- project admin (show);
- assigne/due date/milestone/label dropdowns on the issue and board sidebars;
- stage dropdown on the build sidebar;
- merge request and comparison dropdowns for choosing forks and branches;
- ref switcher (e.g. in the blob (show) view or in the graphs view);

Dropdown toggles concerned by #24150 but not covered in this MR:
- Dropdowns for selection MR versions to be compared (in the "Changes" tab of an MR);
- Dropdowns that bring up a list of actions:
  - "Settings" dropdowns (such as the one found on the upper-right corner of all project pages);
  - The download/action/notifications buttons on the main project page;
  - Dropdowns located inside of list items (on list of pipelines, users and groups, for instance);
  - The "Options" button on the commit (show) view;
  - The "+" button on the tree explorer (for creating files, branches, tags, ...)

### TODO
- [ ] Update ui.html if needed

## Are there points in the code the reviewer needs to double check?

Am I changing any other dropdown toggle than listed above?

## Why was this MR needed?

For #24150

## Screenshots (if relevant)

### Issue Index

**Before:**
![issue-index-before](/uploads/1aa358b0b9e79fd3a7467b57cd2b03ec/issue-index-before.png)

**After:**
![issue-index-after](/uploads/7a4159e8927d456ed3f4390072174e49/issue-index-after.png)

### Issue New

**Before:**
![issue-new-before](/uploads/fcfb9c39d2ff8f00827f52d60db5c114/issue-new-before.png)

**After:**
![issue-new-after](/uploads/a0b151d257d8f3e8f98a2873427362ee/issue-new-after.png)

### Merge Request Branch Selector

**Before:**
![merge-request-new-before](/uploads/8dd7b6e8ea38af7aced743386bfb83ca/merge-request-new-before.png)

**After:**
![merge-request-new-after](/uploads/38ad8f5a315344b3bab7e936a84acf7e/merge-request-new-after.png)

### Global Search
![global-search-after](/uploads/f2912b7d91fd286028cb9481d2d53a82/global-search-after.png)

### Cycle Analytics
![cycle-analytics-after](/uploads/248d5ca360bb510aa0f0bfa8a1a00aae/cycle-analytics-after.png)


## Does this MR meet the acceptance criteria?

- [x] [Changelog entry](https://docs.gitlab.com/ce/development/changelog.html) added
- ~~[Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)~~
- ~~API support added~~
- Tests
  - ~~Added for this feature/bug~~
  - [ ] All builds are passing
- ~~Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html)~~
- [ ] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [ ] Branch has no merge conflicts with `master` (if it does - rebase it please)
- [ ] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)

## What are the relevant issue numbers?

#24150

See merge request !7583
parents e0a46540 92704298
...@@ -205,7 +205,7 @@ ...@@ -205,7 +205,7 @@
} }
.fa-caret-down, .fa-caret-down,
.fa-caret-up { .fa-chevron-down {
margin-left: 5px; margin-left: 5px;
} }
......
...@@ -8,6 +8,12 @@ ...@@ -8,6 +8,12 @@
} }
} }
@mixin chevron-active {
.fa-chevron-down {
color: $dropdown-toggle-hover-icon-color;
}
}
.open { .open {
.dropdown-menu, .dropdown-menu,
.dropdown-menu-nav { .dropdown-menu-nav {
...@@ -19,53 +25,27 @@ ...@@ -19,53 +25,27 @@
} }
} }
.dropdown-toggle,
.dropdown-menu-toggle { .dropdown-menu-toggle {
@include chevron-active;
border-color: $dropdown-toggle-hover-border-color; border-color: $dropdown-toggle-hover-border-color;
.fa {
color: $dropdown-toggle-hover-icon-color;
}
} }
} }
.dropdown-menu-toggle { .dropdown-toggle {
position: relative; padding: 6px 8px 6px 10px;
width: 160px;
padding: 6px 20px 6px 10px;
background-color: $dropdown-toggle-bg; background-color: $dropdown-toggle-bg;
color: $dropdown-toggle-color; color: $dropdown-toggle-color;
font-size: 15px; font-size: 15px;
text-align: left; text-align: left;
border: 1px solid $border-color; border: 1px solid $border-color;
border-radius: $border-radius-base; border-radius: $border-radius-base;
text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
overflow: hidden;
.fa {
position: absolute;
top: 10px;
right: 8px;
color: $dropdown-toggle-icon-color;
&.fa-spinner {
font-size: 16px;
margin-top: -8px;
}
}
&.no-outline { &.no-outline {
outline: 0; outline: 0;
} }
&:hover, {
border-color: $dropdown-toggle-hover-border-color;
.fa {
color: $dropdown-toggle-hover-icon-color;
}
}
&.large { &.large {
width: 200px; width: 200px;
} }
...@@ -86,6 +66,51 @@ ...@@ -86,6 +66,51 @@
max-width: 100%; max-width: 100%;
padding-right: 25px; padding-right: 25px;
} }
.fa {
color: $dropdown-toggle-icon-color;
}
.fa-chevron-down {
font-size: $dropdown-chevron-size;
position: relative;
top: -3px;
margin-left: 5px;
}
&:hover {
@include chevron-active;
border-color: $dropdown-toggle-hover-border-color;
}
&:focus:active {
@include chevron-active;
border-color: $dropdown-toggle-active-border-color;
}
}
.dropdown-menu-toggle {
@extend .dropdown-toggle;
padding-right: 20px;
position: relative;
width: 160px;
text-overflow: ellipsis;
overflow: hidden;
.fa {
position: absolute;
&.fa-spinner {
font-size: 16px;
margin-top: -8px;
}
}
.fa-chevron-down {
position: absolute;
top: 11px;
right: 8px;
}
} }
.dropdown-menu, .dropdown-menu,
......
...@@ -220,7 +220,7 @@ $dropdown-bg: #fff; ...@@ -220,7 +220,7 @@ $dropdown-bg: #fff;
$dropdown-link-color: #555; $dropdown-link-color: #555;
$dropdown-link-hover-bg: $row-hover; $dropdown-link-hover-bg: $row-hover;
$dropdown-empty-row-bg: rgba(#000, .04); $dropdown-empty-row-bg: rgba(#000, .04);
$dropdown-border-color: rgba(#000, .1); $dropdown-border-color: $border-color;
$dropdown-shadow-color: rgba(#000, .1); $dropdown-shadow-color: rgba(#000, .1);
$dropdown-divider-color: rgba(#000, .1); $dropdown-divider-color: rgba(#000, .1);
$dropdown-header-color: #959494; $dropdown-header-color: #959494;
...@@ -229,13 +229,15 @@ $dropdown-input-color: #555; ...@@ -229,13 +229,15 @@ $dropdown-input-color: #555;
$dropdown-input-focus-border: $focus-border-color; $dropdown-input-focus-border: $focus-border-color;
$dropdown-input-focus-shadow: rgba($dropdown-input-focus-border, .4); $dropdown-input-focus-shadow: rgba($dropdown-input-focus-border, .4);
$dropdown-loading-bg: rgba(#fff, .6); $dropdown-loading-bg: rgba(#fff, .6);
$dropdown-chevron-size: 10px;
$dropdown-toggle-bg: #fff; $dropdown-toggle-bg: #fff;
$dropdown-toggle-color: #626262; $dropdown-toggle-color: #5c5c5c;
$dropdown-toggle-border-color: #eaeaea; $dropdown-toggle-border-color: #e5e5e5;
$dropdown-toggle-hover-border-color: darken($dropdown-toggle-border-color, 15%); $dropdown-toggle-hover-border-color: darken($dropdown-toggle-border-color, 13%);
$dropdown-toggle-active-border-color: darken($dropdown-toggle-border-color, 14%);
$dropdown-toggle-icon-color: #c4c4c4; $dropdown-toggle-icon-color: #c4c4c4;
$dropdown-toggle-hover-icon-color: $dropdown-toggle-hover-border-color; $dropdown-toggle-hover-icon-color: darken($dropdown-toggle-icon-color, 7%);
/* /*
* Buttons * Buttons
......
...@@ -43,7 +43,7 @@ module DropdownsHelper ...@@ -43,7 +43,7 @@ module DropdownsHelper
default_label = data_attr[:default_label] default_label = data_attr[:default_label]
content_tag(:button, class: "dropdown-menu-toggle #{options[:toggle_class] if options.has_key?(:toggle_class)}", id: (options[:id] if options.has_key?(:id)), type: "button", data: data_attr) do content_tag(:button, class: "dropdown-menu-toggle #{options[:toggle_class] if options.has_key?(:toggle_class)}", id: (options[:id] if options.has_key?(:id)), type: "button", data: data_attr) do
output = content_tag(:span, toggle_text, class: "dropdown-toggle-text #{'is-default' if toggle_text == default_label}") output = content_tag(:span, toggle_text, class: "dropdown-toggle-text #{'is-default' if toggle_text == default_label}")
output << icon('caret-down') output << icon('chevron-down')
output.html_safe output.html_safe
end end
end end
......
...@@ -50,13 +50,13 @@ ...@@ -50,13 +50,13 @@
data: { data: todo_actions_options }}) data: { data: todo_actions_options }})
.pull-right .pull-right
.dropdown.inline.prepend-left-10 .dropdown.inline.prepend-left-10
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle{type: 'button', 'data-toggle' => 'dropdown'}
%span.light %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
= sort_title_recently_created = sort_title_recently_created
= icon('caret-down') = icon('chevron-down')
%ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-sort %ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-sort
%li %li
= link_to todos_filter_path(sort: sort_value_priority) do = link_to todos_filter_path(sort: sort_value_priority) do
......
...@@ -17,13 +17,13 @@ ...@@ -17,13 +17,13 @@
.pull-right .pull-right
.dropdown.inline .dropdown.inline
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle{type: 'button', 'data-toggle' => 'dropdown'}
%span.light %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
= sort_title_recently_created = sort_title_recently_created
= icon('caret-down') = icon('chevron-down')
%ul.dropdown-menu.dropdown-menu-align-right %ul.dropdown-menu.dropdown-menu-align-right
%li %li
= link_to explore_groups_path(sort: sort_value_recently_created) do = link_to explore_groups_path(sort: sort_value_recently_created) do
......
- if current_user - if current_user
.dropdown .dropdown
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %button.dropdown-toggle{href: '#', "data-toggle" => "dropdown"}
= icon('globe') = icon('globe')
%span.light Visibility: %span.light Visibility:
- if params[:visibility_level].present? - if params[:visibility_level].present?
= visibility_level_label(params[:visibility_level].to_i) = visibility_level_label(params[:visibility_level].to_i)
- else - else
Any Any
= icon('caret-down') = icon('chevron-down')
%ul.dropdown-menu.dropdown-menu-align-right %ul.dropdown-menu.dropdown-menu-align-right
%li %li
= link_to filter_projects_path(visibility_level: nil) do = link_to filter_projects_path(visibility_level: nil) do
...@@ -20,14 +20,14 @@ ...@@ -20,14 +20,14 @@
- if @tags.present? - if @tags.present?
.dropdown .dropdown
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %button.dropdown-toggle{href: '#', "data-toggle" => "dropdown"}
= icon('tags') = icon('tags')
%span.light Tags: %span.light Tags:
- if params[:tag].present? - if params[:tag].present?
= params[:tag] = params[:tag]
- else - else
Any Any
= icon('caret-down') = icon('chevron-down')
%ul.dropdown-menu.dropdown-menu-align-right %ul.dropdown-menu.dropdown-menu-align-right
%li %li
= link_to filter_projects_path(tag: nil) do = link_to filter_projects_path(tag: nil) do
......
...@@ -12,10 +12,10 @@ ...@@ -12,10 +12,10 @@
= search_field_tag :search, params[:search], { placeholder: 'Filter by branch name', id: 'branch-search', class: 'form-control search-text-input input-short', spellcheck: false } = search_field_tag :search, params[:search], { placeholder: 'Filter by branch name', id: 'branch-search', class: 'form-control search-text-input input-short', spellcheck: false }
.dropdown.inline .dropdown.inline
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle{type: 'button', 'data-toggle' => 'dropdown'}
%span.light %span.light
= projects_sort_options_hash[@sort] = projects_sort_options_hash[@sort]
= icon('caret-down') = icon('chevron-down')
%ul.dropdown-menu.dropdown-menu-align-right %ul.dropdown-menu.dropdown-menu-align-right
%li %li
= link_to filter_branches_path(sort: sort_value_name) do = link_to filter_branches_path(sort: sort_value_name) do
......
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
.title Stage .title Stage
%button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'}
%span.stage-selection More %span.stage-selection More
= icon('caret-down') = icon('chevron-down')
%ul.dropdown-menu %ul.dropdown-menu
- @build.pipeline.stages.each do |stage| - @build.pipeline.stages.each do |stage|
%li %li
......
...@@ -9,13 +9,13 @@ ...@@ -9,13 +9,13 @@
spellcheck: false, data: { 'filter-selector' => 'span.namespace-name' } spellcheck: false, data: { 'filter-selector' => 'span.namespace-name' }
.dropdown .dropdown
%button.dropdown-toggle.btn.sort-forks{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort: %span.light sort:
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
= sort_title_recently_created = sort_title_recently_created
= icon('caret-down') = icon('chevron-down')
%ul.dropdown-menu.dropdown-menu-align-right %ul.dropdown-menu.dropdown-menu-align-right
%li %li
- excluded_filters = [:state, :scope, :label_name, :milestone_id, :assignee_id, :author_id] - excluded_filters = [:state, :scope, :label_name, :milestone_id, :assignee_id, :author_id]
......
...@@ -12,10 +12,10 @@ ...@@ -12,10 +12,10 @@
= search_field_tag :search, params[:search], { placeholder: 'Filter by tag name', id: 'tag-search', class: 'form-control search-text-input input-short', spellcheck: false } = search_field_tag :search, params[:search], { placeholder: 'Filter by tag name', id: 'tag-search', class: 'form-control search-text-input input-short', spellcheck: false }
.dropdown.inline .dropdown.inline
%button.dropdown-toggle.btn{ type: 'button', data: { toggle: 'dropdown'} } %button.dropdown-toggle{ type: 'button', data: { toggle: 'dropdown'} }
%span.light %span.light
= projects_sort_options_hash[@sort] = projects_sort_options_hash[@sort]
= icon('caret-down') = icon('chevron-down')
%ul.dropdown-menu.dropdown-menu-align-right %ul.dropdown-menu.dropdown-menu-align-right
%li %li
= link_to filter_tags_path(sort: sort_value_name) do = link_to filter_tags_path(sort: sort_value_name) do
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
- if params[:project_id].present? - if params[:project_id].present?
= hidden_field_tag :project_id, params[:project_id] = hidden_field_tag :project_id, params[:project_id]
.dropdown .dropdown
%button.dropdown-menu-toggle.btn.js-search-group-dropdown{ type: "button", data: { toggle: "dropdown", default_label: "Group:" } } %button.dropdown-menu-toggle.js-search-group-dropdown{ type: "button", data: { toggle: "dropdown", default_label: "Group:" } }
%span.dropdown-toggle-text %span.dropdown-toggle-text
Group: Group:
- if @group.present? - if @group.present?
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
= dropdown_loading = dropdown_loading
.dropdown.project-filter .dropdown.project-filter
%button.dropdown-menu-toggle.btn.js-search-project-dropdown{ type: "button", data: { toggle: "dropdown", default_label: "Project:" } } %button.dropdown-menu-toggle.js-search-project-dropdown{ type: "button", data: { toggle: "dropdown", default_label: "Project:" } }
%span.dropdown-toggle-text %span.dropdown-toggle-text
Project: Project:
- if @project.present? - if @project.present?
......
.dropdown.inline.prepend-left-10 .dropdown.inline.prepend-left-10
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle{type: 'button', data: {toggle: 'dropdown'}}
%span.light %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
= sort_title_recently_created = sort_title_recently_created
= icon('caret-down') = icon('chevron-down')
%ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-sort %ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-sort
%li %li
= link_to page_filter_path(sort: sort_value_priority, label: true) do = link_to page_filter_path(sort: sort_value_priority, label: true) do
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
%button.dropdown-menu-toggle.js-label-select.js-multiselect{class: classes.join(' '), type: "button", data: dropdown_data} %button.dropdown-menu-toggle.js-label-select.js-multiselect{class: classes.join(' '), type: "button", data: dropdown_data}
%span.dropdown-toggle-text{ class: ("is-default" if selected.nil? || selected.empty?) } %span.dropdown-toggle-text{ class: ("is-default" if selected.nil? || selected.empty?) }
= multi_label_name(selected, "Labels") = multi_label_name(selected, "Labels")
= icon('caret-down') = icon('chevron-down')
.dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable .dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable
= render partial: "shared/issuable/label_page_default", locals: { title: dropdown_title, show_footer: show_footer, show_create: show_create } = render partial: "shared/issuable/label_page_default", locals: { title: dropdown_title, show_footer: show_footer, show_create: show_create }
- if show_create && project && can?(current_user, :admin_label, project) - if show_create && project && can?(current_user, :admin_label, project)
......
---
title: Homogenize filter and sort dropdown look'n'feel
merge_request: 7583
author: David Wagner
...@@ -110,14 +110,14 @@ module SharedIssuable ...@@ -110,14 +110,14 @@ module SharedIssuable
end end
step 'I sort the list by "Oldest updated"' do step 'I sort the list by "Oldest updated"' do
find('button.dropdown-toggle.btn').click find('button.dropdown-toggle').click
page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do
click_link "Oldest updated" click_link "Oldest updated"
end end
end end
step 'I sort the list by "Least popular"' do step 'I sort the list by "Least popular"' do
find('button.dropdown-toggle.btn').click find('button.dropdown-toggle').click
page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do
click_link 'Least popular' click_link 'Least popular'
...@@ -125,7 +125,7 @@ module SharedIssuable ...@@ -125,7 +125,7 @@ module SharedIssuable
end end
step 'I sort the list by "Most popular"' do step 'I sort the list by "Most popular"' do
find('button.dropdown-toggle.btn').click find('button.dropdown-toggle').click
page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do
click_link 'Most popular' click_link 'Most popular'
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment