@ably/ui 7.9.3 → 7.10.0-dev.e5f4e78
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.
- package/core/Logo.jsx +16 -29
- package/core/Meganav/component.css +5 -1
- package/core/Meganav/component.js +2 -1
- package/core/Meganav/component.js.LICENSE.txt +7 -0
- package/core/Meganav.jsx +7721 -4607
- package/core/MeganavContentWhyAbly.jsx +2 -2
- package/core/MeganavControl.jsx +5 -3
- package/core/MeganavControlMobileDropdown/component.js +1 -1
- package/core/MeganavItemsDesktop.jsx +5 -3
- package/core/MeganavItemsMobile.jsx +173 -10
- package/core/MeganavItemsSignedIn.jsx +257 -7
- package/core/MeganavSearch/component.js +1 -0
- package/core/MeganavSearch.jsx +502 -0
- package/core/MeganavSearchAutocomplete/component.js +2 -0
- package/core/MeganavSearchAutocomplete/component.js.LICENSE.txt +7 -0
- package/core/MeganavSearchAutocomplete.jsx +117 -0
- package/core/MeganavSearchPanel/component.js +1 -0
- package/core/MeganavSearchPanel.jsx +454 -0
- package/core/MeganavSearchSuggestions/component.js +1 -0
- package/core/MeganavSearchSuggestions.jsx +366 -0
- package/core/fonts/.DS_Store +0 -0
- package/core/images/.DS_Store +0 -0
- package/core/scripts.js +1 -1
- package/core/styles.css +2 -15
- package/package.json +2 -1
- package/preview/vendor/bundle/ruby/3.0.0/bundler/gems/ably-ui-abffd210ec0f/preview/log/.keep +0 -0
- package/preview/vendor/bundle/ruby/3.0.0/bundler/gems/ably-ui-abffd210ec0f/preview/tmp/.keep +0 -0
- package/preview/vendor/bundle/ruby/3.0.0/bundler/gems/ably-ui-abffd210ec0f/preview/tmp/pids/.keep +0 -0
- package/src/.DS_Store +0 -0
- package/src/core/.DS_Store +0 -0
- package/src/core/Logo/component.jsx +1 -1
- package/src/core/Meganav/component.css +5 -1
- package/src/core/Meganav/component.html.erb +10 -5
- package/src/core/Meganav/component.js +4 -0
- package/src/core/Meganav/component.jsx +12 -5
- package/src/core/MeganavContentWhyAbly/component.html.erb +1 -1
- package/src/core/MeganavContentWhyAbly/component.jsx +1 -1
- package/src/core/MeganavControl/component.html.erb +2 -2
- package/src/core/MeganavControl/component.jsx +3 -2
- package/src/core/MeganavControl/component.rb +3 -1
- package/src/core/MeganavControlMobileDropdown/component.js +31 -0
- package/src/core/MeganavItemsMobile/component.html.erb +14 -1
- package/src/core/MeganavItemsMobile/component.jsx +17 -1
- package/src/core/MeganavItemsSignedIn/component.html.erb +5 -1
- package/src/core/MeganavItemsSignedIn/component.jsx +7 -2
- package/src/core/MeganavSearch/component.html.erb +14 -0
- package/src/core/MeganavSearch/component.js +0 -0
- package/src/core/MeganavSearch/component.jsx +32 -0
- package/src/core/MeganavSearch/component.rb +13 -0
- package/src/core/MeganavSearchAutocomplete/component.html.erb +6 -0
- package/src/core/MeganavSearchAutocomplete/component.js +95 -0
- package/src/core/MeganavSearchAutocomplete/component.jsx +14 -0
- package/src/core/MeganavSearchAutocomplete/component.rb +6 -0
- package/src/core/MeganavSearchPanel/component.html.erb +22 -0
- package/src/core/MeganavSearchPanel/component.js +0 -0
- package/src/core/MeganavSearchPanel/component.jsx +39 -0
- package/src/core/MeganavSearchPanel/component.rb +13 -0
- package/src/core/MeganavSearchSuggestions/component.html.erb +22 -0
- package/src/core/MeganavSearchSuggestions/component.js +0 -0
- package/src/core/MeganavSearchSuggestions/component.jsx +49 -0
- package/src/core/MeganavSearchSuggestions/component.rb +18 -0
- package/src/core/fonts/.DS_Store +0 -0
- package/src/core/images/.DS_Store +0 -0
- package/src/core/remote-blogs-posts.js +1 -1
- package/src/core/remote-session-data.js +1 -1
- package/src/core/styles/properties.css +2 -0
- package/src/core/styles.components.css +0 -15
- package/src/reset/.DS_Store +0 -0
- package/tailwind.config.js +2 -0
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
</li>
|
|
28
28
|
|
|
29
29
|
<li>
|
|
30
|
-
<%= link_to abs_url("/resources
|
|
30
|
+
<%= link_to abs_url("/resources"), class: "group ui-meganav-media py-12" do %>
|
|
31
31
|
<p class="ui-meganav-media-heading">Resources</p>
|
|
32
32
|
<% end %>
|
|
33
33
|
</li>
|
|
@@ -42,7 +42,7 @@ const MeganavContentWhyAbly = ({ absUrl }) => {
|
|
|
42
42
|
</li>
|
|
43
43
|
|
|
44
44
|
<li>
|
|
45
|
-
<a href={absUrl("/resources
|
|
45
|
+
<a href={absUrl("/resources")} className="group ui-meganav-media py-12">
|
|
46
46
|
<p className="ui-meganav-media-heading">Resources</p>
|
|
47
47
|
</a>
|
|
48
48
|
</li>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<%= button_tag(type: "button",
|
|
2
|
-
class: ["ui-meganav-link", "h-64", "flex", "items-center", "group", theme(:text_color)],
|
|
2
|
+
class: ["ui-meganav-link", "h-64", "flex", "items-center", "group", theme(:text_color), additional_css],
|
|
3
3
|
data: { id: "meganav-control" },
|
|
4
|
-
aria: { expanded: false, controls:
|
|
4
|
+
aria: { expanded: false, controls: aria_controls, label: "Show #{content}" }) do -%>
|
|
5
5
|
<%= content -%><%= render(AblyUi::Core::Icon.new(name: "icon-gui-disclosure-arrow", size: "1.5rem", color: "text-cool-black", additional_css: "transform rotate-90 group-hover:text-gui-hover group-focus:text-gui-focus")) %>
|
|
6
6
|
<% end %>
|
|
@@ -3,11 +3,11 @@ import T from "prop-types";
|
|
|
3
3
|
|
|
4
4
|
import Icon from "../Icon/component.jsx";
|
|
5
5
|
|
|
6
|
-
const MeganavControl = ({ ariaControls, children, theme }) => (
|
|
6
|
+
const MeganavControl = ({ ariaControls, children, theme, additionalCSS }) => (
|
|
7
7
|
<button
|
|
8
8
|
type="button"
|
|
9
9
|
data-id="meganav-control"
|
|
10
|
-
className={`ui-meganav-link h-64 flex items-center group ${theme.textColor}`}
|
|
10
|
+
className={`ui-meganav-link h-64 flex items-center group ${additionalCSS} ${theme.textColor}`}
|
|
11
11
|
aria-expanded="false"
|
|
12
12
|
aria-controls={ariaControls}
|
|
13
13
|
aria-label={`Show ${children}`}
|
|
@@ -26,6 +26,7 @@ MeganavControl.propTypes = {
|
|
|
26
26
|
ariaControls: T.string,
|
|
27
27
|
children: T.node,
|
|
28
28
|
theme: T.object,
|
|
29
|
+
additionalCSS: T.string,
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
export default MeganavControl;
|
|
@@ -2,9 +2,11 @@ module AblyUi
|
|
|
2
2
|
module Core
|
|
3
3
|
class MeganavControl < ViewComponent::Base
|
|
4
4
|
include AblyUi::Core::MeganavConfig
|
|
5
|
+
attr_reader :aria_controls, :additional_css
|
|
5
6
|
|
|
6
|
-
def initialize(aria_controls:, theme_name:)
|
|
7
|
+
def initialize(aria_controls:, theme_name:, additional_css: '')
|
|
7
8
|
@aria_controls = aria_controls
|
|
9
|
+
@additional_css = additional_css
|
|
8
10
|
theme_setup(theme_name)
|
|
9
11
|
end
|
|
10
12
|
end
|
|
@@ -7,6 +7,8 @@ const MeganavControlMobileDropdown = ({ clearPanels }) => {
|
|
|
7
7
|
const dropdown = queryId("meganav-mobile-dropdown");
|
|
8
8
|
const menuIcon = queryId("meganav-control-mobile-dropdown-menu");
|
|
9
9
|
const closeIcon = queryId("meganav-control-mobile-dropdown-close");
|
|
10
|
+
const meganavSearchSuggestionsToggle = queryId("meganav-mobile-search-input");
|
|
11
|
+
const meganavSearchSuggestions = queryId("meganav-mobile-search-suggestions");
|
|
10
12
|
|
|
11
13
|
const clickHandler = () => {
|
|
12
14
|
const ariaExpanded = control.getAttribute("aria-expanded");
|
|
@@ -26,12 +28,40 @@ const MeganavControlMobileDropdown = ({ clearPanels }) => {
|
|
|
26
28
|
closeIcon.classList.toggle("hidden");
|
|
27
29
|
};
|
|
28
30
|
|
|
31
|
+
const focusSuggestionsHandler = () => {
|
|
32
|
+
meganavSearchSuggestions.classList.add("max-h-96");
|
|
33
|
+
};
|
|
34
|
+
const blurSuggestionsHandler = (event) => {
|
|
35
|
+
if (
|
|
36
|
+
event.relatedTarget === meganavSearchSuggestions.querySelectorAll("a")[0]
|
|
37
|
+
) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
meganavSearchSuggestions.classList.remove("max-h-96");
|
|
41
|
+
};
|
|
42
|
+
|
|
29
43
|
control.addEventListener("click", clickHandler);
|
|
44
|
+
meganavSearchSuggestionsToggle.addEventListener(
|
|
45
|
+
"focus",
|
|
46
|
+
focusSuggestionsHandler
|
|
47
|
+
);
|
|
48
|
+
meganavSearchSuggestionsToggle.addEventListener(
|
|
49
|
+
"blur",
|
|
50
|
+
blurSuggestionsHandler
|
|
51
|
+
);
|
|
30
52
|
|
|
31
53
|
return {
|
|
32
54
|
teardown: () => {
|
|
33
55
|
control.removeEventListener("click", clickHandler);
|
|
34
56
|
scrollLock.enablePageScroll();
|
|
57
|
+
meganavSearchSuggestionsToggle.removeEventListener(
|
|
58
|
+
"focus",
|
|
59
|
+
focusSuggestionsHandler
|
|
60
|
+
);
|
|
61
|
+
meganavSearchSuggestionsToggle.removeEventListener(
|
|
62
|
+
"blur",
|
|
63
|
+
blurSuggestionsHandler
|
|
64
|
+
);
|
|
35
65
|
},
|
|
36
66
|
clear: () => {
|
|
37
67
|
dropdown.classList.replace("visible", "invisible");
|
|
@@ -39,6 +69,7 @@ const MeganavControlMobileDropdown = ({ clearPanels }) => {
|
|
|
39
69
|
menuIcon.classList.remove("hidden");
|
|
40
70
|
closeIcon.classList.add("hidden");
|
|
41
71
|
scrollLock.enablePageScroll();
|
|
72
|
+
meganavSearchSuggestions.classList.remove("max-h-96");
|
|
42
73
|
},
|
|
43
74
|
};
|
|
44
75
|
};
|
|
@@ -11,7 +11,20 @@
|
|
|
11
11
|
<%= render(AblyUi::Core::MeganavControlMobileDropdown.new(theme_name: @theme_name)) %>
|
|
12
12
|
|
|
13
13
|
<div class="ui-meganav-mobile-dropdown invisible" id="meganav-mobile-dropdown" data-id="meganav-mobile-dropdown">
|
|
14
|
-
<div class="
|
|
14
|
+
<div class="pt-24 pb-16 ui-grid-px bg-white">
|
|
15
|
+
<%= tag.form class: "mb-16", action: abs_url("/search"), method: "get" do %>
|
|
16
|
+
<div class="relative w-full">
|
|
17
|
+
<%= render(AblyUi::Core::Icon.new(name: "icon-gui-search", size: "1.5rem", color: "text-cool-black", additional_css: "absolute top-12 left-16 hover:text-gui-hover")) %>
|
|
18
|
+
<input type="search" name="q" class="ui-input pl-48 h-48" placeholder="Search" data-id="meganav-mobile-search-input" />
|
|
19
|
+
|
|
20
|
+
<%= render(AblyUi::Core::MeganavSearchAutocomplete.new) %>
|
|
21
|
+
</div>
|
|
22
|
+
<% end %>
|
|
23
|
+
|
|
24
|
+
<div class="max-h-0 overflow-hidden transition-all" data-id="meganav-mobile-search-suggestions">
|
|
25
|
+
<%= render(AblyUi::Core::MeganavSearchSuggestions.new(url_base: url_base, display_support_link: false)) %>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
15
28
|
<ul class="mb-16">
|
|
16
29
|
<% panels.each do |panel| %>
|
|
17
30
|
<li class="ui-meganav-mobile-item">
|
|
@@ -2,11 +2,14 @@ import React from "react";
|
|
|
2
2
|
import T from "prop-types";
|
|
3
3
|
|
|
4
4
|
import SignOutLink from "../SignOutLink/component.jsx";
|
|
5
|
+
import MeganavSearchSuggestions from "../MeganavSearchSuggestions/component.jsx";
|
|
6
|
+
import Icon from "../Icon/component.jsx";
|
|
5
7
|
|
|
6
8
|
import MeganavData from "../Meganav/component.json";
|
|
7
9
|
import MeganavControlMobileDropdown from "../MeganavControlMobileDropdown/component.jsx";
|
|
8
10
|
import MeganavControlMobilePanelClose from "../MeganavControlMobilePanelClose/component.jsx";
|
|
9
11
|
import MeganavControlMobilePanelOpen from "../MeganavControlMobilePanelOpen/component.jsx";
|
|
12
|
+
import MeganavSearchAutocomplete from "../MeganavSearchAutocomplete/component.jsx";
|
|
10
13
|
|
|
11
14
|
const MeganavItemsMobile = ({ panels, paths, sessionState, theme, loginLink, absUrl }) => {
|
|
12
15
|
const classNames = `ui-meganav-link ${theme.textColor}`;
|
|
@@ -33,7 +36,20 @@ const MeganavItemsMobile = ({ panels, paths, sessionState, theme, loginLink, abs
|
|
|
33
36
|
<MeganavControlMobileDropdown theme={theme} />
|
|
34
37
|
|
|
35
38
|
<div className="ui-meganav-mobile-dropdown invisible" id="meganav-mobile-dropdown" data-id="meganav-mobile-dropdown">
|
|
36
|
-
<div className="
|
|
39
|
+
<div className="pt-24 pb-16 ui-grid-px bg-white">
|
|
40
|
+
<form className="mb-16" action={absUrl("/search")} method="get">
|
|
41
|
+
<div className="relative w-full">
|
|
42
|
+
<Icon name="icon-gui-search" color="text-cool-black" size="1.5rem" additionalCSS="absolute top-12 left-16 hover:text-gui-hover" />
|
|
43
|
+
<input type="search" name="q" className="ui-input pl-48 h-48" placeholder="Search" data-id="meganav-mobile-search-input" />
|
|
44
|
+
|
|
45
|
+
<MeganavSearchAutocomplete />
|
|
46
|
+
</div>
|
|
47
|
+
</form>
|
|
48
|
+
|
|
49
|
+
<div className="max-h-0 overflow-hidden transition-all" data-id="meganav-mobile-search-suggestions">
|
|
50
|
+
<MeganavSearchSuggestions absUrl={absUrl} displaySupportLink={false} />
|
|
51
|
+
</div>
|
|
52
|
+
|
|
37
53
|
<ul className="mb-16">
|
|
38
54
|
{MeganavData.panels.map((panel) => {
|
|
39
55
|
const PanelComponent = panels[panel.component];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<ul class="hidden md:flex items-center">
|
|
2
2
|
<li class="ui-meganav-item relative">
|
|
3
|
-
<%= render(AblyUi::Core::MeganavControl.new(aria_controls: "account-panel", theme_name: @theme_name)) do %>
|
|
3
|
+
<%= render(AblyUi::Core::MeganavControl.new(aria_controls: "account-panel", theme_name: @theme_name, additional_css: "mr-0")) do %>
|
|
4
4
|
<%= account_name %>
|
|
5
5
|
<% end %>
|
|
6
6
|
|
|
@@ -41,6 +41,10 @@
|
|
|
41
41
|
</div>
|
|
42
42
|
</li>
|
|
43
43
|
|
|
44
|
+
<li>
|
|
45
|
+
<%= render(AblyUi::Core::MeganavSearch.new(url_base: url_base)) %>
|
|
46
|
+
<li>
|
|
47
|
+
|
|
44
48
|
<% if account? %>
|
|
45
49
|
<li class="ml-16">
|
|
46
50
|
<%= link_to "Dashboard", @session_data[:account][:links][:dashboard][:href], class: "ui-btn-secondary p-btn-small" %>
|
|
@@ -3,6 +3,7 @@ import T from "prop-types";
|
|
|
3
3
|
|
|
4
4
|
import MeganavControl from "../MeganavControl/component.jsx";
|
|
5
5
|
import SignOutLink from "../SignOutLink/component.jsx";
|
|
6
|
+
import MeganavSearch from "../MeganavSearch/component.jsx";
|
|
6
7
|
|
|
7
8
|
const truncate = (string, length) => {
|
|
8
9
|
return string?.length && string.length > length ? `${string.slice(0, length - 1)}…` : string;
|
|
@@ -16,7 +17,7 @@ const MeganavItemsSignedIn = ({ sessionState, theme, absUrl }) => {
|
|
|
16
17
|
return (
|
|
17
18
|
<ul className="hidden md:flex items-center">
|
|
18
19
|
<li className="ui-meganav-item relative">
|
|
19
|
-
<MeganavControl ariaControls="account-panel" theme={theme}>
|
|
20
|
+
<MeganavControl ariaControls="account-panel" theme={theme} additionalCSS="mr-0">
|
|
20
21
|
{accountName}
|
|
21
22
|
</MeganavControl>
|
|
22
23
|
|
|
@@ -70,8 +71,12 @@ const MeganavItemsSignedIn = ({ sessionState, theme, absUrl }) => {
|
|
|
70
71
|
</div>
|
|
71
72
|
</li>
|
|
72
73
|
|
|
74
|
+
<li>
|
|
75
|
+
<MeganavSearch absUrl={absUrl} />
|
|
76
|
+
</li>
|
|
77
|
+
|
|
73
78
|
{sessionState.account && (
|
|
74
|
-
<li
|
|
79
|
+
<li>
|
|
75
80
|
<a href={absUrl(sessionState.account.links.dashboard.href)} className="ui-btn-secondary p-btn-small">
|
|
76
81
|
Dashboard
|
|
77
82
|
</a>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<button
|
|
2
|
+
type="button"
|
|
3
|
+
data-id="meganav-control"
|
|
4
|
+
class="h-64 w-24 px-24 pr-48 py-20"
|
|
5
|
+
aria-expanded="false"
|
|
6
|
+
aria-controls="panel-search"
|
|
7
|
+
aria-label="Show Search Panel"
|
|
8
|
+
>
|
|
9
|
+
<%= render(AblyUi::Core::Icon.new(name: "icon-gui-search", size: "1.5rem", color: "text-cool-black", additional_css: "hover:text-gui-hover")) %>
|
|
10
|
+
</button>
|
|
11
|
+
|
|
12
|
+
<div class="ui-meganav-panel invisible" id="panel-search" data-id="meganav-panel">
|
|
13
|
+
<%= render(AblyUi::Core::MeganavSearchPanel.new(url_base: url_base)) %>
|
|
14
|
+
</div>
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import T from "prop-types";
|
|
3
|
+
|
|
4
|
+
import Icon from "../Icon/component.jsx";
|
|
5
|
+
import MeganavSearchPanel from "../MeganavSearchPanel/component.jsx";
|
|
6
|
+
|
|
7
|
+
const MeganavSearch = ({ absUrl }) => {
|
|
8
|
+
return (
|
|
9
|
+
<>
|
|
10
|
+
<button
|
|
11
|
+
type="button"
|
|
12
|
+
data-id="meganav-control"
|
|
13
|
+
className="h-64 w-24 px-24 pr-48 py-20"
|
|
14
|
+
aria-expanded="false"
|
|
15
|
+
aria-controls="panel-search"
|
|
16
|
+
aria-label={`Show Search Panel`}
|
|
17
|
+
>
|
|
18
|
+
<Icon name="icon-gui-search" color="text-cool-black" size="1.5rem" additionalCSS="hover:text-gui-hover" />
|
|
19
|
+
</button>
|
|
20
|
+
|
|
21
|
+
<div className="ui-meganav-panel invisible" id="panel-search" data-id="meganav-panel">
|
|
22
|
+
<MeganavSearchPanel absUrl={absUrl} />
|
|
23
|
+
</div>
|
|
24
|
+
</>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
MeganavSearch.propTypes = {
|
|
29
|
+
absUrl: T.func,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default MeganavSearch;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { queryId } from "../dom-query";
|
|
2
|
+
import AddSearchClient from "addsearch-js-client";
|
|
3
|
+
|
|
4
|
+
const init = ({ input, container, listContainer, client }) => {
|
|
5
|
+
client.setAnalyticsTag("Meganav autocomplete");
|
|
6
|
+
client.setThrottleTime(400);
|
|
7
|
+
|
|
8
|
+
const clearResults = () => {
|
|
9
|
+
container.classList.add("hidden");
|
|
10
|
+
listContainer.innerHTML = "";
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const renderResults =
|
|
14
|
+
(query) =>
|
|
15
|
+
(results = { suggestions: [] }) => {
|
|
16
|
+
if (results.suggestions.length === 0) {
|
|
17
|
+
clearResults();
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const items = results.suggestions.map((suggestion) => {
|
|
22
|
+
const li = document.createElement("li");
|
|
23
|
+
const button = document.createElement("button");
|
|
24
|
+
|
|
25
|
+
button.classList.add(
|
|
26
|
+
"ui-text-menu2",
|
|
27
|
+
"font-medium",
|
|
28
|
+
"p-8",
|
|
29
|
+
"w-full",
|
|
30
|
+
"text-left",
|
|
31
|
+
"rounded",
|
|
32
|
+
"hover:text-gui-hover",
|
|
33
|
+
"hover:bg-light-grey"
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
button.innerHTML = suggestion.value.replace(
|
|
37
|
+
query,
|
|
38
|
+
`<span class="font-light">${query}</span>`
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
button.addEventListener("click", () => {
|
|
42
|
+
window.location = `/search?q=${suggestion}`;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
li.appendChild(button);
|
|
46
|
+
return li;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
listContainer.innerHTML = "";
|
|
50
|
+
items.forEach((item) => listContainer.appendChild(item));
|
|
51
|
+
container.classList.remove("hidden");
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const keyupHandler = (e) => {
|
|
55
|
+
const query = e.target.value;
|
|
56
|
+
|
|
57
|
+
if (!query) {
|
|
58
|
+
clearResults();
|
|
59
|
+
} else {
|
|
60
|
+
client.suggestions(query, renderResults(query));
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
input.addEventListener("keyup", keyupHandler);
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
teardown: () => input.removeEventListener("keyup", keyupHandler),
|
|
68
|
+
clear: () => clearResults(),
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export default () => {
|
|
73
|
+
const apiKey = document.body.dataset.addSearchApiKey;
|
|
74
|
+
if (!apiKey) {
|
|
75
|
+
console.log(`No AddSearch API key provided, skipping search suggestions.`);
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
const client = new AddSearchClient(apiKey);
|
|
79
|
+
|
|
80
|
+
return [
|
|
81
|
+
queryId("meganav-search-input"),
|
|
82
|
+
queryId("meganav-mobile-search-input"),
|
|
83
|
+
]
|
|
84
|
+
.filter((i) => i)
|
|
85
|
+
.map((input) => {
|
|
86
|
+
const parent = input.parentNode;
|
|
87
|
+
const container = queryId(
|
|
88
|
+
"meganav-search-autocomplete-container",
|
|
89
|
+
parent
|
|
90
|
+
);
|
|
91
|
+
const listContainer = queryId("meganav-search-autocomplete-list", parent);
|
|
92
|
+
|
|
93
|
+
return init({ input, container, listContainer, client });
|
|
94
|
+
});
|
|
95
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
const MeganavSearchAutocomplete = () => {
|
|
4
|
+
return (
|
|
5
|
+
<div
|
|
6
|
+
className="absolute w-full mt-8 z-10 hidden shadow-container rounded-lg bg-white border border-mid-grey"
|
|
7
|
+
data-id="meganav-search-autocomplete-container"
|
|
8
|
+
>
|
|
9
|
+
<ol className="m-16" data-id="meganav-search-autocomplete-list"></ol>
|
|
10
|
+
</div>
|
|
11
|
+
);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default MeganavSearchAutocomplete;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<section class="ui-meganav-content grid-cols-12">
|
|
2
|
+
<div class="col-span-8">
|
|
3
|
+
<div class="mb-32">
|
|
4
|
+
<form class="flex items-start" action={absUrl("/search")} method="get">
|
|
5
|
+
<div class="relative w-full">
|
|
6
|
+
<%= render(AblyUi::Core::Icon.new(name: "icon-gui-search", size: "1.5rem", color: "text-cool-black", additional_css:"absolute top-12 left-16")) %>
|
|
7
|
+
<input type="search" name="q" class="ui-input pl-48 h-48" placeholder="Search" data-id="meganav-search-input" />
|
|
8
|
+
|
|
9
|
+
<%= render(AblyUi::Core::MeganavSearchAutocomplete.new) %>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<button type="submit" class="ui-btn-secondary ml-8 sm:ml-16 md:ml-24 xl:ml-32">
|
|
13
|
+
Search
|
|
14
|
+
</button>
|
|
15
|
+
</form>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div class="col-span-12">
|
|
20
|
+
<%= render(AblyUi::Core::MeganavSearchSuggestions.new(url_base: url_base)) %>
|
|
21
|
+
</div>
|
|
22
|
+
</section>
|
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import T from "prop-types";
|
|
3
|
+
|
|
4
|
+
import Icon from "../Icon/component.jsx";
|
|
5
|
+
import MeganavSearchSuggestions from "../MeganavSearchSuggestions/component.jsx";
|
|
6
|
+
import MeganavSearchAutocomplete from "../MeganavSearchAutocomplete/component.jsx";
|
|
7
|
+
|
|
8
|
+
const MeganavSearchPanel = ({ absUrl }) => {
|
|
9
|
+
return (
|
|
10
|
+
<section className="ui-meganav-content grid-cols-12">
|
|
11
|
+
<div className="col-span-8">
|
|
12
|
+
<div className="mb-32">
|
|
13
|
+
<form className="flex items-start" action={absUrl("/search")} method="get">
|
|
14
|
+
<div className="relative w-full">
|
|
15
|
+
<Icon name="icon-gui-search" color="text-cool-black" size="1.5rem" additionalCSS="absolute top-12 left-16" />
|
|
16
|
+
<input type="search" name="q" className="ui-input pl-48 h-48" placeholder="Search" data-id="meganav-search-input" />
|
|
17
|
+
|
|
18
|
+
<MeganavSearchAutocomplete />
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<button type="submit" className="ui-btn-secondary ml-8 sm:ml-16 md:ml-24 xl:ml-32">
|
|
22
|
+
Search
|
|
23
|
+
</button>
|
|
24
|
+
</form>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<div className="col-span-12">
|
|
29
|
+
<MeganavSearchSuggestions displaySupportLink={true} absUrl={absUrl} />
|
|
30
|
+
</div>
|
|
31
|
+
</section>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
MeganavSearchPanel.propTypes = {
|
|
36
|
+
absUrl: T.func,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default MeganavSearchPanel;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<p class="ui-text-overline2 text-cool-black py-12">Popular pages</p>
|
|
2
|
+
|
|
3
|
+
<div class="flex justify-between items-center overflow-x-scroll">
|
|
4
|
+
<ul class="flex">
|
|
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" %>
|
|
7
|
+
</li>
|
|
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" %>
|
|
10
|
+
</li>
|
|
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" %>
|
|
13
|
+
</li>
|
|
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" %>
|
|
16
|
+
</li>
|
|
17
|
+
</ul>
|
|
18
|
+
|
|
19
|
+
<% if display_support_link? %>
|
|
20
|
+
<%= render(AblyUi::Core::FeaturedLink.new(url: abs_url("/support"), text_size: "text-p2")) do %>Support<% end %>
|
|
21
|
+
<% end %>
|
|
22
|
+
</div>
|
|
File without changes
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import T from "prop-types";
|
|
3
|
+
|
|
4
|
+
import FeaturedLink from "../FeaturedLink/component.jsx";
|
|
5
|
+
|
|
6
|
+
const MeganavSearchSuggestions = ({ absUrl, displaySupportLink }) => {
|
|
7
|
+
return (
|
|
8
|
+
<>
|
|
9
|
+
<p className="ui-text-overline2 text-cool-black py-12">Popular pages</p>
|
|
10
|
+
|
|
11
|
+
<div className="flex justify-between items-center overflow-x-scroll">
|
|
12
|
+
<ul className="flex">
|
|
13
|
+
<li className="py-12 pr-8 flex-shrink-0">
|
|
14
|
+
<a href={absUrl("/docs/how-ably-works")} className="ui-text-p2 ui-link">
|
|
15
|
+
How does Ably work?
|
|
16
|
+
</a>
|
|
17
|
+
</li>
|
|
18
|
+
<li className="py-12 px-8 flex-shrink-0">
|
|
19
|
+
<a href={absUrl("/docs/quick-start-guide")} className="ui-text-p2 ui-link">
|
|
20
|
+
Quickstart guide
|
|
21
|
+
</a>
|
|
22
|
+
</li>
|
|
23
|
+
<li className="py-12 px-8 flex-shrink-0">
|
|
24
|
+
<a href={absUrl("/docs/core-features/pubsub")} className="ui-text-p2 ui-link">
|
|
25
|
+
Publish/Subscribe Messaging
|
|
26
|
+
</a>
|
|
27
|
+
</li>
|
|
28
|
+
<li className="py-12 pl-8 flex-shrink-0">
|
|
29
|
+
<a href={absUrl("/platform")} className="ui-text-p2 ui-link">
|
|
30
|
+
Platform
|
|
31
|
+
</a>
|
|
32
|
+
</li>
|
|
33
|
+
</ul>
|
|
34
|
+
{displaySupportLink ? (
|
|
35
|
+
<FeaturedLink url={absUrl("/support")} textSize="text-p2">
|
|
36
|
+
Support
|
|
37
|
+
</FeaturedLink>
|
|
38
|
+
) : null}
|
|
39
|
+
</div>
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
MeganavSearchSuggestions.propTypes = {
|
|
45
|
+
absUrl: T.func,
|
|
46
|
+
displaySupportLink: T.bool,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default MeganavSearchSuggestions;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module AblyUi
|
|
2
|
+
module Core
|
|
3
|
+
class MeganavSearchSuggestions < ViewComponent::Base
|
|
4
|
+
include Util
|
|
5
|
+
|
|
6
|
+
attr_reader :url_base
|
|
7
|
+
|
|
8
|
+
def initialize(url_base:, display_support_link: true)
|
|
9
|
+
@url_base = url_base
|
|
10
|
+
@display_support_link = display_support_link
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def display_support_link?
|
|
14
|
+
@display_support_link
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
Binary file
|
|
Binary file
|
|
@@ -24,21 +24,6 @@
|
|
|
24
24
|
stroke: var(--color-dark-grey);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/* Extend how tailwind does group hover for icons */
|
|
28
|
-
.group {
|
|
29
|
-
&:hover {
|
|
30
|
-
.group-hover\:icon-gui-hover {
|
|
31
|
-
stroke: var(--color-gui-hover);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
&:focus {
|
|
36
|
-
.group-focus\:icon-gui-focus {
|
|
37
|
-
stroke: var(--color-gui-focus);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
27
|
.ui-version-tag {
|
|
43
28
|
@apply inline-block absolute align-top uppercase font-bold whitespace-nowrap;
|
|
44
29
|
|