typeahead: Hide by default and show container on `show()`.

This avoids a bug (currently only for search) where the page
can be loaded with an empty but visible (half-loaded) search
typeahead.
This commit is contained in:
evykassirer 2024-06-20 14:31:18 -07:00 committed by Tim Abbott
parent b519344dd9
commit 7ae0972c28
2 changed files with 48 additions and 45 deletions

View File

@ -335,53 +335,55 @@ export class Typeahead<ItemType extends string | object> {
} }
this.mouse_moved_since_typeahead = false; this.mouse_moved_since_typeahead = false;
if (this.non_tippy_parent_element) { if (!this.non_tippy_parent_element) {
this.$container.show(); this.instance = tippy.default(this.input_element.$element[0]!, {
// We don't need tippy to position typeaheads which already know where they should be. // Lets typeahead take the width needed to fit the content
return this; // and wraps it if it overflows the visible container.
maxWidth: "none",
delay: [0, 0],
theme: "popover-menu",
placement: this.dropup ? "top-start" : "bottom-start",
popperOptions: {
strategy: "fixed",
modifiers: [
{
// This will only work if there is enough space on the fallback
// placement, otherwise `preventOverflow` will be used to position
// it in the visible space.
name: "flip",
options: {
fallbackPlacements: ["top-start", "bottom-start"],
},
},
{
name: "preventOverflow",
options: {
// This seems required to prevent overflow, maybe because our
// placements are not the usual top, bottom, left, right.
// https://popper.js.org/docs/v2/modifiers/prevent-overflow/#altaxis
altAxis: true,
},
},
],
},
interactive: true,
appendTo: () => document.body,
showOnCreate: true,
content: this.$container[0]!,
// We expect the typeahead creator to handle when to hide / show the typeahead.
trigger: "manual",
arrow: false,
offset: [0, 0],
// We have event handlers to hide the typeahead, so we
// don't want tippy to hide it for us.
hideOnClick: false,
});
} }
this.instance = tippy.default(this.input_element.$element[0]!, {
// Lets typeahead take the width needed to fit the content
// and wraps it if it overflows the visible container.
maxWidth: "none",
delay: [0, 0],
theme: "popover-menu",
placement: this.dropup ? "top-start" : "bottom-start",
popperOptions: {
strategy: "fixed",
modifiers: [
{
// This will only work if there is enough space on the fallback placement, otherwise
// `preventOverflow` will be used to position it in the visible space.
name: "flip",
options: {
fallbackPlacements: ["top-start", "bottom-start"],
},
},
{
name: "preventOverflow",
options: {
// This seems required to prevent overflow, maybe because our placements are
// not the usual top, bottom, left, right.
// https://popper.js.org/docs/v2/modifiers/prevent-overflow/#altaxis
altAxis: true,
},
},
],
},
interactive: true,
appendTo: () => document.body,
showOnCreate: true,
content: this.$container[0]!,
// We expect the typeahead creator to handle when to hide / show the typeahead.
trigger: "manual",
arrow: false,
offset: [0, 0],
// We have event handlers to hide the typeahead, so we
// don't want tippy to hide it for us.
hideOnClick: false,
});
// The container has `display: none` as a default style. We make sure to display
// it. For tippy elements, this must happen after we insert the typeahead into
// the DOM.
this.$container.show();
return this; return this;
} }

View File

@ -1,6 +1,7 @@
/* CSS for Bootstrap typeahead */ /* CSS for Bootstrap typeahead */
.dropdown-menu { .dropdown-menu {
display: none;
padding: 5px 0; padding: 5px 0;
min-width: 160px; min-width: 160px;
list-style: none; list-style: none;