Skip to content

Commit

Permalink
Trigger search addon from flyout input (#108)
Browse files Browse the repository at this point in the history
This is an initial attempt to be able to render the `readthedocs-search`
addon inside the `readthedocs-flyout` one.

I was able to:

- include the `readthedocs-search` tag inside the flyout
- connect the `focusin` event to the input from inside the flyout to
call the search

Each time I click on the input from inside the flyout, it shows a log in
the console (for debugging). However, due to some reason that I don't
know yet, the `readthedocs-search` tag does not contains any HTML inside
ito, so even when the modal is triggered, nothing is shown.

Related #90
  • Loading branch information
humitos authored Sep 7, 2023
1 parent 97e67d8 commit a7a49eb
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 13 deletions.
8 changes: 4 additions & 4 deletions dist/readthedocs-addons.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/readthedocs-addons.js.map

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/events.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const EVENT_READTHEDOCS_SEARCH_SHOW = "readthedocs-search-show";
14 changes: 8 additions & 6 deletions src/flyout.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { classMap } from "lit/directives/class-map.js";

import styleSheet from "./flyout.css";
import { AddonBase } from "./utils";
import { EVENT_READTHEDOCS_SEARCH_SHOW } from "./events";

export class FlyoutElement extends LitElement {
static elementName = "readthedocs-flyout";
Expand Down Expand Up @@ -64,6 +65,12 @@ export class FlyoutElement extends LitElement {
`;
}

showSearch() {
// Dispatch the custom event the search addon is listening to show the modal
const event = new CustomEvent(EVENT_READTHEDOCS_SEARCH_SHOW);
document.dispatchEvent(event);
}

renderSearch() {
// TODO: This is not yet working with the readthedocs-search component yet. The integration
// will be handled separately.
Expand All @@ -72,12 +79,7 @@ export class FlyoutElement extends LitElement {
<dl>
<dt>Search</dt>
<dd>
<form
id="flyout-search-form"
target="_blank"
action="${this.getProjectUrl()}search/"
method="get"
>
<form @focusin="${this.showSearch}" id="flyout-search-form">
<input
type="text"
name="q"
Expand Down
22 changes: 20 additions & 2 deletions src/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import READTHEDOCS_LOGO from "./images/logo-wordmark-dark.svg";

import styleSheet from "./search.css";
import { domReady, CLIENT_VERSION, AddonBase, debounce } from "./utils";
import { EVENT_READTHEDOCS_SEARCH_SHOW } from "./events";
import { html, nothing, render, LitElement } from "lit";
import { unsafeHTML } from "lit-html/directives/unsafe-html.js";
import { classMap } from "lit/directives/class-map.js";
Expand Down Expand Up @@ -506,24 +507,36 @@ export class SearchElement extends LitElement {

if (this.triggerSelector) {
let element = document.querySelector(this.triggerSelector);
if (element !== undefined) {
if (element !== undefined && element !== null) {
element.addEventListener(this.triggerEvent, this._handleShowModalUser);
}
}

// The READTHEDOCS_SEARCH_SHOW event is triggered by "readthedocs-flyout" input
document.addEventListener(
EVENT_READTHEDOCS_SEARCH_SHOW,
this._handleShowModalUser
);
}

disconnectedCallback() {
// TODO: update these methods to make sense when embeding SearchElement into FlyoutElement
document.removeEventListener("keydown", this._handleShowModal);
if (this.triggerSelector) {
let element = document.querySelector(this.triggerSelector);
if (element !== undefined) {
if (element !== undefined && element !== null) {
element.removeEventListener(
this.triggerEvent,
this._handleShowModalUser
);
}
}

document.removeEventListener(
EVENT_READTHEDOCS_SEARCH_SHOW,
this._handleShowModalUser
);

super.disconnectedCallback();
}
}
Expand All @@ -534,9 +547,14 @@ export class SearchAddon extends AddonBase {

// TODO: is it possible to move this `constructor` to the `AddonBase` class?
customElements.define("readthedocs-search", SearchElement);

// If there are no elements found, inject one
let elems = document.querySelectorAll("readthedocs-search");
if (!elems.length) {
elems = [new SearchElement()];

// We cannot use `render(elems[0], document.body)` because there is a race conditions between all the addons.
// So, we append the web-component first and then request an update of it.
document.body.append(elems[0]);
elems[0].requestUpdate();
}
Expand Down

0 comments on commit a7a49eb

Please sign in to comment.