mirror of https://github.com/zulip/zulip.git
search: Put typeahead under search bar in the DOM with full width.
Previously the typeahead container was being created at the bottom of `body`, and its width (and `top` and `left`) were being set to move it to the right position. Now it sits in the search box container, which gives it the correct position and width by default. This is better for DOM readability, and is also better for the new 100% width (which is part of the search bar redesign) because it can change width more smoothly with the search bar when the page changes width. This commit adds custom functionality to the bootstrap typeahead to allow the typehead to be placed in the search box container (whereas previously, it could only be appended to `body`).
This commit is contained in:
parent
e3984f119d
commit
7c9677becd
|
@ -90,7 +90,7 @@ export function initialize() {
|
||||||
search_map = suggestions.lookup_table;
|
search_map = suggestions.lookup_table;
|
||||||
return suggestions.strings;
|
return suggestions.strings;
|
||||||
},
|
},
|
||||||
fixed: true,
|
parentElement: "#searchbox_legacy",
|
||||||
items: search_suggestion.max_num_of_search_results,
|
items: search_suggestion.max_num_of_search_results,
|
||||||
helpOnEmptyStrings: true,
|
helpOnEmptyStrings: true,
|
||||||
naturalSearch: true,
|
naturalSearch: true,
|
||||||
|
|
|
@ -15,14 +15,8 @@
|
||||||
width: calc(100% - 2px);
|
width: calc(100% - 2px);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
@media (width < $xl_min) {
|
|
||||||
width: calc(100% - 84px);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (width < $md_min) {
|
@media (width < $md_min) {
|
||||||
/* todo: Figure out why this has to be different
|
width: calc(100% - 42px);
|
||||||
from top-navbar-border at this width and resolve it */
|
|
||||||
width: calc(100% - 123px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search_close_button {
|
.search_close_button {
|
||||||
|
@ -35,6 +29,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.typeahead.dropdown-menu {
|
||||||
|
/* Match the typeahead's width to its parent container. */
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
@media (width < $md_min) {
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.input-append {
|
.input-append {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -2742,8 +2742,8 @@ select.invite-as {
|
||||||
margin-right: 7px;
|
margin-right: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-navbar-container {
|
#navbar-middle {
|
||||||
width: calc(100% - 84px);
|
margin-right: 87px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search_closed .zulip-icon-search {
|
.search_closed .zulip-icon-search {
|
||||||
|
@ -2803,7 +2803,6 @@ select.invite-as {
|
||||||
|
|
||||||
.column-middle-inner {
|
.column-middle-inner {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
margin-right: 15px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-main .column-middle .column-middle-inner {
|
.app-main .column-middle .column-middle-inner {
|
||||||
|
@ -2816,7 +2815,6 @@ select.invite-as {
|
||||||
|
|
||||||
.top-navbar-border {
|
.top-navbar-border {
|
||||||
margin-left: 40px;
|
margin-left: 40px;
|
||||||
width: calc(100% - 108px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search_closed .zulip-icon-search {
|
.search_closed .zulip-icon-search {
|
||||||
|
|
|
@ -103,7 +103,6 @@ test("initialize", ({mock_template}) => {
|
||||||
|
|
||||||
search_suggestion.max_num_of_search_results = 99;
|
search_suggestion.max_num_of_search_results = 99;
|
||||||
$search_query_box.typeahead = (opts) => {
|
$search_query_box.typeahead = (opts) => {
|
||||||
assert.equal(opts.fixed, true);
|
|
||||||
assert.equal(opts.items, 99);
|
assert.equal(opts.items, 99);
|
||||||
assert.equal(opts.naturalSearch, true);
|
assert.equal(opts.naturalSearch, true);
|
||||||
assert.equal(opts.helpOnEmptyStrings, true);
|
assert.equal(opts.helpOnEmptyStrings, true);
|
||||||
|
|
|
@ -86,7 +86,6 @@ run_test("initialize", ({mock_template}) => {
|
||||||
|
|
||||||
search_suggestion.max_num_of_search_results = 999;
|
search_suggestion.max_num_of_search_results = 999;
|
||||||
$search_query_box.typeahead = (opts) => {
|
$search_query_box.typeahead = (opts) => {
|
||||||
assert.equal(opts.fixed, true);
|
|
||||||
assert.equal(opts.items, 999);
|
assert.equal(opts.items, 999);
|
||||||
assert.equal(opts.naturalSearch, true);
|
assert.equal(opts.naturalSearch, true);
|
||||||
assert.equal(opts.helpOnEmptyStrings, true);
|
assert.equal(opts.helpOnEmptyStrings, true);
|
||||||
|
|
|
@ -98,6 +98,13 @@
|
||||||
* We add a new event handler, resizeHandler, for window.on('resize', ...)
|
* We add a new event handler, resizeHandler, for window.on('resize', ...)
|
||||||
* that calls this.show to re-render the typeahead in the correct position.
|
* that calls this.show to re-render the typeahead in the correct position.
|
||||||
*
|
*
|
||||||
|
* 10. Allow typeahead to be located next to its input field in the DOM
|
||||||
|
*
|
||||||
|
* We add a new `parentElement` option which the typeahead can
|
||||||
|
* append to, where before it could only be appended to `body`.
|
||||||
|
* Since it's in the right part of the DOM, we don't need to do
|
||||||
|
* the manual positioning in the show() function.
|
||||||
|
*
|
||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
|
|
||||||
import {insert} from "text-field-edit";
|
import {insert} from "text-field-edit";
|
||||||
|
@ -126,7 +133,7 @@ import {get_string_diff} from "../../src/util";
|
||||||
this.sorter = this.options.sorter || this.sorter
|
this.sorter = this.options.sorter || this.sorter
|
||||||
this.highlighter = this.options.highlighter || this.highlighter
|
this.highlighter = this.options.highlighter || this.highlighter
|
||||||
this.updater = this.options.updater || this.updater
|
this.updater = this.options.updater || this.updater
|
||||||
this.$container = $(this.options.container).appendTo('body')
|
this.$container = $(this.options.container).appendTo(this.options.parentElement || 'body')
|
||||||
this.$menu = $(this.options.menu).appendTo(this.$container)
|
this.$menu = $(this.options.menu).appendTo(this.$container)
|
||||||
this.$header = $(this.options.header_html).appendTo(this.$container)
|
this.$header = $(this.options.header_html).appendTo(this.$container)
|
||||||
this.source = this.options.source
|
this.source = this.options.source
|
||||||
|
@ -207,37 +214,41 @@ import {get_string_diff} from "../../src/util";
|
||||||
this.$header.hide();
|
this.$header.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a parent element was specified, we shouldn't manually
|
||||||
|
// position the element, since it's already in the right place.
|
||||||
|
if (!this.options.parentElement) {
|
||||||
var pos;
|
var pos;
|
||||||
|
|
||||||
if (this.fixed) {
|
if (this.fixed) {
|
||||||
// Relative to screen instead of to page
|
// Relative to screen instead of to page
|
||||||
pos = this.$element[0].getBoundingClientRect();
|
pos = this.$element[0].getBoundingClientRect();
|
||||||
} else {
|
} else {
|
||||||
pos = this.$element.offset();
|
pos = this.$element.offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = $.extend({}, pos, {
|
||||||
|
height: this.$element[0].offsetHeight
|
||||||
|
})
|
||||||
|
|
||||||
|
// Zulip patch: Workaround for iOS safari problems
|
||||||
|
pos.top = this.$element.offset().top;
|
||||||
|
|
||||||
|
var top_pos = pos.top + pos.height
|
||||||
|
if (this.dropup) {
|
||||||
|
top_pos = pos.top - this.$container.outerHeight()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zulip patch: Avoid typeahead going off top of screen.
|
||||||
|
if (top_pos < 0) {
|
||||||
|
top_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$container.css({
|
||||||
|
top: top_pos
|
||||||
|
, left: pos.left
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = $.extend({}, pos, {
|
|
||||||
height: this.$element[0].offsetHeight
|
|
||||||
})
|
|
||||||
|
|
||||||
// Zulip patch: Workaround for iOS safari problems
|
|
||||||
pos.top = this.$element.offset().top;
|
|
||||||
|
|
||||||
var top_pos = pos.top + pos.height
|
|
||||||
if (this.dropup) {
|
|
||||||
top_pos = pos.top - this.$container.outerHeight()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zulip patch: Avoid typeahead going off top of screen.
|
|
||||||
if (top_pos < 0) {
|
|
||||||
top_pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$container.css({
|
|
||||||
top: top_pos
|
|
||||||
, left: pos.left
|
|
||||||
})
|
|
||||||
|
|
||||||
this.$container.show()
|
this.$container.show()
|
||||||
this.shown = true
|
this.shown = true
|
||||||
this.mouse_moved_since_typeahead = false
|
this.mouse_moved_since_typeahead = false
|
||||||
|
|
Loading…
Reference in New Issue