@ably/ui 7.10.0-dev.e5f4e78 → 7.10.0-dev.e980a00

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import { queryId } from "../dom-query";
2
2
  import AddSearchClient from "addsearch-js-client";
3
3
 
4
- const init = ({ input, container, listContainer, client }) => {
4
+ const init = ({ input, container, listContainer, clear, client }) => {
5
5
  client.setAnalyticsTag("Meganav autocomplete");
6
6
  client.setThrottleTime(400);
7
7
 
@@ -10,15 +10,52 @@ const init = ({ input, container, listContainer, client }) => {
10
10
  listContainer.innerHTML = "";
11
11
  };
12
12
 
13
+ const toggleClearBtn = (query) => {
14
+ if ((query || "").length > 0 && clear) {
15
+ clear.classList.remove("invisible");
16
+ } else if (clear) {
17
+ clear.classList.add("invisible");
18
+ }
19
+ };
20
+
21
+ const markQueryInSuggestion = (suggestion, query) => {
22
+ return suggestion.value.replace(
23
+ query.toLowerCase(),
24
+ `<span class="font-light">${query}</span>`
25
+ );
26
+ };
27
+
28
+ const navigateToUrl = (q) => (window.location = `/search?q=${q}`);
29
+
30
+ const focusNext = (index) => {
31
+ const nextSuggestion = listContainer.querySelector(
32
+ `[data-suggestion-index="${index + 1}"]`
33
+ );
34
+ if (!nextSuggestion) return;
35
+ nextSuggestion.focus();
36
+ };
37
+
38
+ const focusPrevious = (index) => {
39
+ const previousIndex = index - 1;
40
+
41
+ const previousSuggestion = listContainer.querySelector(
42
+ `[data-suggestion-index="${previousIndex}"]`
43
+ );
44
+ if (!previousSuggestion) return;
45
+ previousSuggestion.focus();
46
+ };
47
+
13
48
  const renderResults =
14
49
  (query) =>
15
50
  (results = { suggestions: [] }) => {
51
+ toggleClearBtn(query);
52
+
16
53
  if (results.suggestions.length === 0) {
17
54
  clearResults();
18
55
  return;
19
56
  }
20
57
 
21
- const items = results.suggestions.map((suggestion) => {
58
+ const items = results.suggestions.map((suggestion, index) => {
22
59
  const li = document.createElement("li");
23
60
  const button = document.createElement("button");
24
61
 
@@ -30,16 +67,30 @@ const init = ({ input, container, listContainer, client }) => {
30
67
  "text-left",
31
68
  "rounded",
32
69
  "hover:text-gui-hover",
70
+ "focus:outline-gui-focus",
33
71
  "hover:bg-light-grey"
34
72
  );
35
73
 
36
- button.innerHTML = suggestion.value.replace(
37
- query,
38
- `<span class="font-light">${query}</span>`
39
- );
74
+ button.innerHTML = markQueryInSuggestion(suggestion, query);
75
+
76
+ button.dataset.suggestionIndex = index;
40
77
 
41
78
  button.addEventListener("click", () => {
42
- window.location = `/search?q=${suggestion}`;
79
+ navigateToUrl(suggestion);
80
+ });
81
+
82
+ button.addEventListener("keydown", (e) => {
83
+ const key = e.key;
84
+
85
+ if (key === "ArrowDown") {
86
+ focusNext();
87
+ } else if (key === "ArrowUp" && index - 1 < 0) {
88
+ input.focus();
89
+ } else if (key === "ArrowUp" && index - 1 >= 0) {
90
+ focusPrevious();
91
+ } else if (key === "Enter" || key === "Space") {
92
+ navigateToUrl(suggestion);
93
+ }
43
94
  });
44
95
 
45
96
  li.appendChild(button);
@@ -53,6 +104,12 @@ const init = ({ input, container, listContainer, client }) => {
53
104
 
54
105
  const keyupHandler = (e) => {
55
106
  const query = e.target.value;
107
+ const key = e.key;
108
+
109
+ if (key === "ArrowDown") {
110
+ focusNext(0);
111
+ return;
112
+ }
56
113
 
57
114
  if (!query) {
58
115
  clearResults();
@@ -61,11 +118,27 @@ const init = ({ input, container, listContainer, client }) => {
61
118
  }
62
119
  };
63
120
 
121
+ let clearHandler;
122
+ if (clear) {
123
+ clearHandler = () => {
124
+ input.value = "";
125
+ clear.classList.add("invisible");
126
+ clearResults();
127
+ };
128
+ clear.addEventListener("click", clearHandler);
129
+ }
130
+
64
131
  input.addEventListener("keyup", keyupHandler);
65
132
 
66
133
  return {
67
- teardown: () => input.removeEventListener("keyup", keyupHandler),
68
- clear: () => clearResults(),
134
+ teardown: () => {
135
+ input.removeEventListener("keyup", keyupHandler);
136
+ if (clear) clear.removeEventListener("click", clearHandler);
137
+ },
138
+ clear: () => {
139
+ input.value = "";
140
+ clearResults();
141
+ },
69
142
  };
70
143
  };
71
144
 
@@ -89,7 +162,8 @@ export default () => {
89
162
  parent
90
163
  );
91
164
  const listContainer = queryId("meganav-search-autocomplete-list", parent);
165
+ const clear = queryId("meganav-search-input-clear", parent);
92
166
 
93
- return init({ input, container, listContainer, client });
167
+ return init({ input, container, listContainer, client, clear });
94
168
  });
95
169
  };
@@ -1,18 +1,18 @@
1
1
  <p class="ui-text-overline2 text-cool-black py-12">Popular pages</p>
2
2
 
3
- <div class="flex justify-between items-center overflow-x-scroll">
3
+ <div class="flex justify-between items-center overflow-x-scroll md:overflow-auto">
4
4
  <ul class="flex">
5
5
  <li class="py-12 pr-8 flex-shrink-0">
6
- <%= link_to 'How does Ably work?', abs_url("/docs/how-ably-works"), class: "ui-text-p2 ui-link" %>
6
+ <%= link_to 'How does Ably work?', abs_url("/docs/how-ably-works"), class: "ui-text-p2" %>
7
7
  </li>
8
8
  <li class="py-12 px-8 flex-shrink-0">
9
- <%= link_to 'Quickstart guide', abs_url("/docs/quick-start-guide"), class: "ui-text-p2 ui-link" %>
9
+ <%= link_to 'Quickstart guide', abs_url("/docs/quick-start-guide"), class: "ui-text-p2" %>
10
10
  </li>
11
11
  <li class="py-12 px-8 flex-shrink-0">
12
- <%= link_to 'Publish/Subscribe Messaging', abs_url("/docs/core-features/pubsub"), class: "ui-text-p2 ui-link" %>
12
+ <%= link_to 'Publish/Subscribe Messaging', abs_url("/docs/core-features/pubsub"), class: "ui-text-p2" %>
13
13
  </li>
14
14
  <li class="py-12 pl-8 flex-shrink-0">
15
- <%= link_to 'Platform', abs_url("/docs/how-ably-works"), class: "ui-text-p2 ui-link" %>
15
+ <%= link_to 'Platform', abs_url("/docs/how-ably-works"), class: "ui-text-p2" %>
16
16
  </li>
17
17
  </ul>
18
18
 
@@ -8,25 +8,25 @@ const MeganavSearchSuggestions = ({ absUrl, displaySupportLink }) => {
8
8
  <>
9
9
  <p className="ui-text-overline2 text-cool-black py-12">Popular pages</p>
10
10
 
11
- <div className="flex justify-between items-center overflow-x-scroll">
11
+ <div className="flex justify-between items-center overflow-x-scroll md:overflow-auto">
12
12
  <ul className="flex">
13
13
  <li className="py-12 pr-8 flex-shrink-0">
14
- <a href={absUrl("/docs/how-ably-works")} className="ui-text-p2 ui-link">
14
+ <a href={absUrl("/docs/how-ably-works")} className="ui-text-p2">
15
15
  How does Ably work?
16
16
  </a>
17
17
  </li>
18
18
  <li className="py-12 px-8 flex-shrink-0">
19
- <a href={absUrl("/docs/quick-start-guide")} className="ui-text-p2 ui-link">
19
+ <a href={absUrl("/docs/quick-start-guide")} className="ui-text-p2">
20
20
  Quickstart guide
21
21
  </a>
22
22
  </li>
23
23
  <li className="py-12 px-8 flex-shrink-0">
24
- <a href={absUrl("/docs/core-features/pubsub")} className="ui-text-p2 ui-link">
24
+ <a href={absUrl("/docs/core-features/pubsub")} className="ui-text-p2">
25
25
  Publish/Subscribe Messaging
26
26
  </a>
27
27
  </li>
28
28
  <li className="py-12 pl-8 flex-shrink-0">
29
- <a href={absUrl("/platform")} className="ui-text-p2 ui-link">
29
+ <a href={absUrl("/platform")} className="ui-text-p2">
30
30
  Platform
31
31
  </a>
32
32
  </li>