From 0e290a84012ed9d2138cb6bc31b5db9c62e330c9 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 23 Mar 2016 15:23:45 +0000 Subject: [PATCH 1/7] Started arrow key movement on dropdowns --- app/assets/javascripts/gl_dropdown.js.coffee | 57 +++++++++++++++++-- .../stylesheets/framework/dropdowns.scss | 11 +++- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 0fea2a69cb7..8686cb99848 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -96,6 +96,7 @@ class GitLabDropdown LOADING_CLASS = "is-loading" PAGE_TWO_CLASS = "is-page-two" ACTIVE_CLASS = "is-active" + CURRENT_INDEX = 0 FILTER_INPUT = '.dropdown-input .dropdown-input-field' @@ -218,6 +219,8 @@ class GitLabDropdown return true opened: => + @addArrowKeyEvent() + contentHtml = $('.dropdown-content', @dropdown).html() if @remote && contentHtml is "" @remote.execute() @@ -228,6 +231,7 @@ class GitLabDropdown @dropdown.trigger('shown.gl.dropdown') hidden: (e) => + @removeArrayKeyEvent() if @options.filterable @dropdown .find(".dropdown-input-field") @@ -322,8 +326,8 @@ class GitLabDropdown ).join('') noResults: -> - html = "
  • " - html += "" + html = "
  • " @@ -343,7 +347,7 @@ class GitLabDropdown selectedObject = @renderedData[selectedIndex] value = if @options.id then @options.id(selectedObject, el) else selectedObject.id field = @dropdown.parent().find("input[name='#{fieldName}'][value='#{value}']") - + if el.hasClass(ACTIVE_CLASS) el.removeClass(ACTIVE_CLASS) field.remove() @@ -384,8 +388,53 @@ class GitLabDropdown # simulate a click on the first link $(selector).trigger "click" + addArrowKeyEvent: -> + ARROW_KEY_CODES = [38, 40] + $input = @dropdown.find(".dropdown-input-field") + + selector = '.dropdown-content li:not(.divider)' + if @dropdown.find(".dropdown-toggle-page").length + selector = ".dropdown-page-one #{selector}" + + $('body').on 'keydown', (e) => + currentKeyCode = e.keyCode + + if ARROW_KEY_CODES.indexOf(currentKeyCode) >= 0 + e.preventDefault() + e.stopPropagation() + + $listItems = $(selector, @dropdown) + + if @options.filterable + $input.blur() + + if currentKeyCode is 40 + # Move down + CURRENT_INDEX += 1 if CURRENT_INDEX < $listItems.length + else if currentKeyCode is 38 + # Move up + CURRENT_INDEX -= 1 if CURRENT_INDEX > 0 + + @highlightRowAtIndex(CURRENT_INDEX) + + return false + + removeArrayKeyEvent: -> + $('body').off 'keydown' + + highlightRowAtIndex: (index, prevIndex) -> + # Remove the class for the previously focused row + $('.is-focused', @dropdown).removeClass 'is-focused' + + # Update the class for the row at the specific index + selector = ".dropdown-content li:not(.divider):eq(#{index})" + if @dropdown.find(".dropdown-toggle-page").length + selector = ".dropdown-page-one #{selector}" + + $listItem = $(selector, @dropdown) + $listItem.addClass "is-focused" + $.fn.glDropdown = (opts) -> return @.each -> if (!$.data @, 'glDropdown') $.data(@, 'glDropdown', new GitLabDropdown @, opts) - diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 82dc1acbd01..fe03c040e68 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -104,6 +104,14 @@ padding: 0 10px; } + .is-focused { + a { + background-color: $dropdown-link-hover-bg; + text-decoration: none; + outline: 0; + } + } + .divider { height: 1px; margin: 8px 10px; @@ -132,8 +140,7 @@ overflow: hidden; &:hover, - &:focus, - &.is-focused { + &:focus { background-color: $dropdown-link-hover-bg; text-decoration: none; outline: 0; From b244317a38f80740bd1508362316c8e70424f14c Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 24 Mar 2016 10:26:15 +0000 Subject: [PATCH 2/7] Scrolls the dropdown content down --- app/assets/javascripts/gl_dropdown.js.coffee | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 8686cb99848..094b1a12408 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -96,7 +96,7 @@ class GitLabDropdown LOADING_CLASS = "is-loading" PAGE_TWO_CLASS = "is-page-two" ACTIVE_CLASS = "is-active" - CURRENT_INDEX = 0 + CURRENT_INDEX = -1 FILTER_INPUT = '.dropdown-input .dropdown-input-field' @@ -410,7 +410,7 @@ class GitLabDropdown if currentKeyCode is 40 # Move down - CURRENT_INDEX += 1 if CURRENT_INDEX < $listItems.length + CURRENT_INDEX += 1 if CURRENT_INDEX < ($listItems.length - 1) else if currentKeyCode is 38 # Move up CURRENT_INDEX -= 1 if CURRENT_INDEX > 0 @@ -434,6 +434,18 @@ class GitLabDropdown $listItem = $(selector, @dropdown) $listItem.addClass "is-focused" + # Dropdown content scroll area + $dropdownContent = $listItem.closest('.dropdown-content') + dropdownContentBottom = $dropdownContent.prop('offsetTop') + $dropdownContent.prop('offsetHeight') + + # Get the offset bottom of the list item + listItemBottom = $listItem.prop('offsetTop') + $listItem.prop('offsetHeight') + console.log listItemBottom, dropdownContentBottom + + if listItemBottom > dropdownContentBottom + # Scroll the dropdown content down + $dropdownContent.scrollTop(listItemBottom - dropdownContentBottom) + $.fn.glDropdown = (opts) -> return @.each -> if (!$.data @, 'glDropdown') From 858eee9ee851e6346e38582ab4b102fc038490c0 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 24 Mar 2016 11:01:23 +0000 Subject: [PATCH 3/7] Correctly scrolls the dropdown up & down with arrow keys --- app/assets/javascripts/gl_dropdown.js.coffee | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 094b1a12408..e7572e4eda9 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -436,15 +436,22 @@ class GitLabDropdown # Dropdown content scroll area $dropdownContent = $listItem.closest('.dropdown-content') - dropdownContentBottom = $dropdownContent.prop('offsetTop') + $dropdownContent.prop('offsetHeight') + dropdownScrollTop = $dropdownContent.prop('scrollTop') + dropdownContentHeight = $dropdownContent.prop('offsetHeight') + dropdownContentTop = $dropdownContent.prop('offsetTop') + dropdownContentBottom = dropdownContentTop + dropdownContentHeight # Get the offset bottom of the list item - listItemBottom = $listItem.prop('offsetTop') + $listItem.prop('offsetHeight') - console.log listItemBottom, dropdownContentBottom + listItemHeight = $listItem.prop('offsetHeight') + listItemTop = $listItem.prop('offsetTop') + listItemBottom = listItemTop + listItemHeight - if listItemBottom > dropdownContentBottom + if listItemBottom > dropdownContentBottom + dropdownScrollTop # Scroll the dropdown content down $dropdownContent.scrollTop(listItemBottom - dropdownContentBottom) + else if listItemTop < dropdownContentTop + dropdownScrollTop + # Scroll the dropdown content up + $dropdownContent.scrollTop(listItemTop - dropdownContentTop) $.fn.glDropdown = (opts) -> return @.each -> From 29872c39055d55118cc8b9249caeb659041fea97 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 24 Mar 2016 12:12:08 +0000 Subject: [PATCH 4/7] Enter triggers the currently highlighted element click --- app/assets/javascripts/gl_dropdown.js.coffee | 25 ++++++++++---------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index e7572e4eda9..1937e5367db 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -146,11 +146,11 @@ class GitLabDropdown data: => return @fullData callback: (data) => + CURRENT_INDEX = -1 @parseData data - @highlightRow 1 enterCallback: => if @enterCallback - @selectFirstRow() + @selectRowAtIndex 0 # Event listeners @@ -380,10 +380,11 @@ class GitLabDropdown return selectedObject - selectFirstRow: -> - selector = '.dropdown-content li:first-child a' + selectRowAtIndex: (index) -> + selector = ".dropdown-content li:not(.divider):eq(#{index}) a" + if @dropdown.find(".dropdown-toggle-page").length - selector = ".dropdown-page-one .dropdown-content li:first-child a" + selector = ".dropdown-page-one #{selector}" # simulate a click on the first link $(selector).trigger "click" @@ -403,6 +404,7 @@ class GitLabDropdown e.preventDefault() e.stopPropagation() + PREV_INDEX = CURRENT_INDEX $listItems = $(selector, @dropdown) if @options.filterable @@ -415,23 +417,22 @@ class GitLabDropdown # Move up CURRENT_INDEX -= 1 if CURRENT_INDEX > 0 - @highlightRowAtIndex(CURRENT_INDEX) + @highlightRowAtIndex($listItems, CURRENT_INDEX) if CURRENT_INDEX isnt PREV_INDEX return false + if currentKeyCode is 13 + @selectRowAtIndex CURRENT_INDEX + removeArrayKeyEvent: -> $('body').off 'keydown' - highlightRowAtIndex: (index, prevIndex) -> + highlightRowAtIndex: ($listItems, index) -> # Remove the class for the previously focused row $('.is-focused', @dropdown).removeClass 'is-focused' # Update the class for the row at the specific index - selector = ".dropdown-content li:not(.divider):eq(#{index})" - if @dropdown.find(".dropdown-toggle-page").length - selector = ".dropdown-page-one #{selector}" - - $listItem = $(selector, @dropdown) + $listItem = $listItems.eq(index) $listItem.addClass "is-focused" # Dropdown content scroll area From a103fcb7cb14b3bf9f7af44409c79331274e9adc Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 29 Mar 2016 12:57:10 +0100 Subject: [PATCH 5/7] Moved back some css classes --- app/assets/javascripts/gl_dropdown.js.coffee | 6 +++--- app/assets/stylesheets/framework/dropdowns.scss | 11 ++--------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 1937e5367db..5a555175291 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -326,8 +326,8 @@ class GitLabDropdown ).join('') noResults: -> - html = "" @@ -433,7 +433,7 @@ class GitLabDropdown # Update the class for the row at the specific index $listItem = $listItems.eq(index) - $listItem.addClass "is-focused" + $listItem.find('a:first-child').addClass "is-focused" # Dropdown content scroll area $dropdownContent = $listItem.closest('.dropdown-content') diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index fe03c040e68..82dc1acbd01 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -104,14 +104,6 @@ padding: 0 10px; } - .is-focused { - a { - background-color: $dropdown-link-hover-bg; - text-decoration: none; - outline: 0; - } - } - .divider { height: 1px; margin: 8px 10px; @@ -140,7 +132,8 @@ overflow: hidden; &:hover, - &:focus { + &:focus, + &.is-focused { background-color: $dropdown-link-hover-bg; text-decoration: none; outline: 0; From f76066b9fb17cd0aace49e353d57ce05976f27e8 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 31 Mar 2016 08:55:12 +0100 Subject: [PATCH 6/7] Fixed issue based on feedback --- app/assets/javascripts/gl_dropdown.js.coffee | 47 +++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 5a555175291..466213496e2 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -1,5 +1,6 @@ class GitLabDropdownFilter BLUR_KEYCODES = [27, 40] + ARROW_KEY_CODES = [38, 40] HAS_VALUE_CLASS = "has-value" constructor: (@input, @options) -> @@ -22,19 +23,23 @@ class GitLabDropdownFilter # Key events timeout = "" @input.on "keyup", (e) => + keyCode = e.which + + return if ARROW_KEY_CODES.indexOf(keyCode) >= 0 + if @input.val() isnt "" and !$inputContainer.hasClass HAS_VALUE_CLASS $inputContainer.addClass HAS_VALUE_CLASS else if @input.val() is "" and $inputContainer.hasClass HAS_VALUE_CLASS $inputContainer.removeClass HAS_VALUE_CLASS - if e.keyCode is 13 and @input.val() isnt "" + if keyCode is 13 and @input.val() isnt "" if @options.enterCallback @options.enterCallback() return clearTimeout timeout timeout = setTimeout => - blur_field = @shouldBlur e.keyCode + blur_field = @shouldBlur keyCode search_text = @input.val() if blur_field and @filterInputBlur @@ -96,7 +101,7 @@ class GitLabDropdown LOADING_CLASS = "is-loading" PAGE_TWO_CLASS = "is-page-two" ACTIVE_CLASS = "is-active" - CURRENT_INDEX = -1 + currentIndex = -1 FILTER_INPUT = '.dropdown-input .dropdown-input-field' @@ -146,7 +151,7 @@ class GitLabDropdown data: => return @fullData callback: (data) => - CURRENT_INDEX = -1 + currentIndex = -1 @parseData data enterCallback: => if @enterCallback @@ -311,11 +316,11 @@ class GitLabDropdown if @highlight text = @highlightTextMatches(text, @filterInput.val()) - html = "
  • " - html += "" - html += text - html += "" - html += "
  • " + html = "
  • + + #{text} + +
  • " return html @@ -398,31 +403,31 @@ class GitLabDropdown selector = ".dropdown-page-one #{selector}" $('body').on 'keydown', (e) => - currentKeyCode = e.keyCode + currentKeyCode = e.which if ARROW_KEY_CODES.indexOf(currentKeyCode) >= 0 e.preventDefault() - e.stopPropagation() + e.stopImmediatePropagation() - PREV_INDEX = CURRENT_INDEX + PREV_INDEX = currentIndex $listItems = $(selector, @dropdown) - if @options.filterable - $input.blur() + # if @options.filterable + # $input.blur() if currentKeyCode is 40 # Move down - CURRENT_INDEX += 1 if CURRENT_INDEX < ($listItems.length - 1) + currentIndex += 1 if currentIndex < ($listItems.length - 1) else if currentKeyCode is 38 # Move up - CURRENT_INDEX -= 1 if CURRENT_INDEX > 0 + currentIndex -= 1 if currentIndex > 0 - @highlightRowAtIndex($listItems, CURRENT_INDEX) if CURRENT_INDEX isnt PREV_INDEX + @highlightRowAtIndex($listItems, currentIndex) if currentIndex isnt PREV_INDEX return false if currentKeyCode is 13 - @selectRowAtIndex CURRENT_INDEX + @selectRowAtIndex currentIndex removeArrayKeyEvent: -> $('body').off 'keydown' @@ -437,13 +442,13 @@ class GitLabDropdown # Dropdown content scroll area $dropdownContent = $listItem.closest('.dropdown-content') - dropdownScrollTop = $dropdownContent.prop('scrollTop') - dropdownContentHeight = $dropdownContent.prop('offsetHeight') + dropdownScrollTop = $dropdownContent.scrollTop() + dropdownContentHeight = $dropdownContent.outerHeight() dropdownContentTop = $dropdownContent.prop('offsetTop') dropdownContentBottom = dropdownContentTop + dropdownContentHeight # Get the offset bottom of the list item - listItemHeight = $listItem.prop('offsetHeight') + listItemHeight = $listItem.outerHeight() listItemTop = $listItem.prop('offsetTop') listItemBottom = listItemTop + listItemHeight From 8e3f5ebaa080bec65b35c21b8a70f84c7ed9fa63 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 5 Apr 2016 09:07:40 +0100 Subject: [PATCH 7/7] CS multiline --- app/assets/javascripts/gl_dropdown.js.coffee | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 466213496e2..6a825a67a14 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -331,11 +331,11 @@ class GitLabDropdown ).join('') noResults: -> - html = "" + html = "" highlightRow: (index) -> if @filterInput.val() isnt ""