@ably/ui 7.9.4 → 7.10.0-dev.d8911c4

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.
Files changed (69) hide show
  1. package/core/Meganav/component.css +5 -1
  2. package/core/Meganav/component.js +2 -1
  3. package/core/Meganav/component.js.LICENSE.txt +7 -0
  4. package/core/Meganav.jsx +6162 -2856
  5. package/core/MeganavContentWhyAbly.jsx +2 -2
  6. package/core/MeganavControl/component.js +1 -1
  7. package/core/MeganavControl.jsx +5 -3
  8. package/core/MeganavControlMobileDropdown/component.js +1 -1
  9. package/core/MeganavItemsDesktop.jsx +5 -3
  10. package/core/MeganavItemsMobile.jsx +188 -11
  11. package/core/MeganavItemsSignedIn.jsx +259 -7
  12. package/core/MeganavSearch/component.js +1 -0
  13. package/core/MeganavSearch.jsx +504 -0
  14. package/core/MeganavSearchAutocomplete/component.js +2 -0
  15. package/core/MeganavSearchAutocomplete/component.js.LICENSE.txt +7 -0
  16. package/core/MeganavSearchAutocomplete.jsx +117 -0
  17. package/core/MeganavSearchPanel/component.js +1 -0
  18. package/core/MeganavSearchPanel.jsx +455 -0
  19. package/core/MeganavSearchSuggestions/component.js +1 -0
  20. package/core/MeganavSearchSuggestions.jsx +366 -0
  21. package/core/fonts/.DS_Store +0 -0
  22. package/core/images/.DS_Store +0 -0
  23. package/core/scripts.js +1 -1
  24. package/core/styles.css +2 -15
  25. package/package.json +2 -1
  26. package/preview/vendor/bundle/ruby/3.0.0/bundler/gems/ably-ui-abffd210ec0f/preview/log/.keep +0 -0
  27. package/preview/vendor/bundle/ruby/3.0.0/bundler/gems/ably-ui-abffd210ec0f/preview/tmp/.keep +0 -0
  28. package/preview/vendor/bundle/ruby/3.0.0/bundler/gems/ably-ui-abffd210ec0f/preview/tmp/pids/.keep +0 -0
  29. package/src/.DS_Store +0 -0
  30. package/src/core/.DS_Store +0 -0
  31. package/src/core/Meganav/component.css +5 -1
  32. package/src/core/Meganav/component.html.erb +10 -5
  33. package/src/core/Meganav/component.js +4 -0
  34. package/src/core/Meganav/component.jsx +12 -5
  35. package/src/core/MeganavContentWhyAbly/component.html.erb +1 -1
  36. package/src/core/MeganavContentWhyAbly/component.jsx +1 -1
  37. package/src/core/MeganavControl/component.html.erb +2 -2
  38. package/src/core/MeganavControl/component.js +37 -12
  39. package/src/core/MeganavControl/component.jsx +3 -2
  40. package/src/core/MeganavControl/component.rb +3 -1
  41. package/src/core/MeganavControlMobileDropdown/component.js +122 -0
  42. package/src/core/MeganavItemsMobile/component.html.erb +30 -2
  43. package/src/core/MeganavItemsMobile/component.jsx +33 -2
  44. package/src/core/MeganavItemsSignedIn/component.html.erb +5 -1
  45. package/src/core/MeganavItemsSignedIn/component.jsx +7 -2
  46. package/src/core/MeganavSearch/component.html.erb +15 -0
  47. package/src/core/MeganavSearch/component.js +0 -0
  48. package/src/core/MeganavSearch/component.jsx +33 -0
  49. package/src/core/MeganavSearch/component.rb +13 -0
  50. package/src/core/MeganavSearchAutocomplete/component.html.erb +6 -0
  51. package/src/core/MeganavSearchAutocomplete/component.js +170 -0
  52. package/src/core/MeganavSearchAutocomplete/component.jsx +14 -0
  53. package/src/core/MeganavSearchAutocomplete/component.rb +6 -0
  54. package/src/core/MeganavSearchPanel/component.html.erb +22 -0
  55. package/src/core/MeganavSearchPanel/component.js +0 -0
  56. package/src/core/MeganavSearchPanel/component.jsx +39 -0
  57. package/src/core/MeganavSearchPanel/component.rb +13 -0
  58. package/src/core/MeganavSearchSuggestions/component.html.erb +22 -0
  59. package/src/core/MeganavSearchSuggestions/component.js +0 -0
  60. package/src/core/MeganavSearchSuggestions/component.jsx +49 -0
  61. package/src/core/MeganavSearchSuggestions/component.rb +18 -0
  62. package/src/core/fonts/.DS_Store +0 -0
  63. package/src/core/images/.DS_Store +0 -0
  64. package/src/core/remote-blogs-posts.js +1 -1
  65. package/src/core/remote-session-data.js +1 -1
  66. package/src/core/styles/properties.css +2 -0
  67. package/src/core/styles.components.css +0 -15
  68. package/src/reset/.DS_Store +0 -0
  69. package/tailwind.config.js +2 -0
@@ -0,0 +1,170 @@
1
+ import { queryId } from "../dom-query";
2
+ import AddSearchClient from "addsearch-js-client";
3
+
4
+ const init = ({ input, container, listContainer, clear, 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 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 = (suggestionValue, query) => {
22
+ return suggestionValue.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
+
48
+ const renderResults =
49
+ (query) =>
50
+ (results = { suggestions: [] }) => {
51
+ toggleClearBtn(query);
52
+
53
+ if (results.suggestions.length === 0) {
54
+ clearResults();
55
+ return;
56
+ }
57
+
58
+ const items = results.suggestions.map((suggestion, index) => {
59
+ const li = document.createElement("li");
60
+ const button = document.createElement("button");
61
+ button.type = "button";
62
+
63
+ button.classList.add(
64
+ "ui-text-menu2",
65
+ "font-medium",
66
+ "p-8",
67
+ "w-full",
68
+ "text-left",
69
+ "rounded",
70
+ "hover:text-gui-hover",
71
+ "focus:outline-gui-focus",
72
+ "hover:bg-light-grey"
73
+ );
74
+
75
+ button.innerHTML = markQueryInSuggestion(suggestion.value, query);
76
+
77
+ button.dataset.suggestionIndex = index;
78
+
79
+ button.addEventListener("click", () => {
80
+ navigateToUrl(suggestion.value);
81
+ });
82
+
83
+ button.addEventListener("keydown", (e) => {
84
+ const key = e.key;
85
+
86
+ if (key === "ArrowDown") {
87
+ focusNext(index);
88
+ } else if (key === "ArrowUp" && index - 1 < 0) {
89
+ input.focus();
90
+ } else if (key === "ArrowUp" && index - 1 >= 0) {
91
+ focusPrevious(index);
92
+ } else if (key === "Enter" || key === "Space") {
93
+ navigateToUrl(suggestion.value);
94
+ }
95
+ });
96
+
97
+ li.appendChild(button);
98
+ return li;
99
+ });
100
+
101
+ listContainer.innerHTML = "";
102
+ items.forEach((item) => listContainer.appendChild(item));
103
+ container.classList.remove("hidden");
104
+ };
105
+
106
+ const keyupHandler = (e) => {
107
+ const query = e.target.value;
108
+ const key = e.key;
109
+
110
+ if (key === "ArrowDown") {
111
+ focusNext(0);
112
+ return;
113
+ }
114
+
115
+ if (!query) {
116
+ clearResults();
117
+ } else {
118
+ client.suggestions(query, renderResults(query));
119
+ }
120
+ };
121
+
122
+ let clearHandler;
123
+ if (clear) {
124
+ clearHandler = () => {
125
+ input.value = "";
126
+ clear.classList.add("invisible");
127
+ clearResults();
128
+ };
129
+ clear.addEventListener("click", clearHandler);
130
+ }
131
+
132
+ input.addEventListener("keyup", keyupHandler);
133
+
134
+ return {
135
+ teardown: () => {
136
+ input.removeEventListener("keyup", keyupHandler);
137
+ if (clear) clear.removeEventListener("click", clearHandler);
138
+ },
139
+ clear: () => {
140
+ input.value = "";
141
+ clearResults();
142
+ },
143
+ };
144
+ };
145
+
146
+ export default () => {
147
+ const apiKey = document.body.dataset.addSearchApiKey;
148
+ if (!apiKey) {
149
+ console.log(`No AddSearch API key provided, skipping search suggestions.`);
150
+ return [];
151
+ }
152
+ const client = new AddSearchClient(apiKey);
153
+
154
+ return [
155
+ queryId("meganav-search-input"),
156
+ queryId("meganav-mobile-search-input"),
157
+ ]
158
+ .filter((i) => i)
159
+ .map((input) => {
160
+ const parent = input.parentNode;
161
+ const container = queryId(
162
+ "meganav-search-autocomplete-container",
163
+ parent
164
+ );
165
+ const listContainer = queryId("meganav-search-autocomplete-list", parent);
166
+ const clear = queryId("meganav-search-input-clear", parent);
167
+
168
+ return init({ input, container, listContainer, client, clear });
169
+ });
170
+ };
@@ -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,6 @@
1
+ module AblyUi
2
+ module Core
3
+ class MeganavSearchAutocomplete < ViewComponent::Base
4
+ end
5
+ end
6
+ end
@@ -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" autocomplete="off" 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" autoComplete="off" 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,13 @@
1
+ module AblyUi
2
+ module Core
3
+ class MeganavSearchPanel < ViewComponent::Base
4
+ include Util
5
+
6
+ attr_reader :url_base
7
+
8
+ def initialize(url_base:)
9
+ @url_base = url_base
10
+ end
11
+ end
12
+ end
13
+ end
@@ -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 md:overflow-auto">
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" %>
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" %>
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" %>
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" %>
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-hidden">
12
+ <ul className="flex transition-transform">
13
+ <li className="py-12 pr-8 flex-shrink-0">
14
+ <a href={absUrl("/docs/how-ably-works")} className="ui-text-p2">
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">
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">
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">
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
@@ -3,7 +3,7 @@ import { isJsonResponse } from "./remote-data-util";
3
3
  const fetchBlogPosts = async (store, blogUrl) => {
4
4
  try {
5
5
  if (!blogUrl) {
6
- console.warn(
6
+ console.log(
7
7
  `Skipping fetching blog posts, invalid blogUrl: "${blogUrl}"`
8
8
  );
9
9
  return;
@@ -11,7 +11,7 @@ const fetchSessionData = async (store, sessionUrl) => {
11
11
 
12
12
  try {
13
13
  if (!sessionUrl) {
14
- console.warn(
14
+ console.log(
15
15
  `Skipping fetching session, invalid sessionUrl: "${sessionUrl}"`
16
16
  );
17
17
  sessionLoaded();
@@ -117,7 +117,9 @@
117
117
 
118
118
  --spacing-0: 0px;
119
119
  --spacing-1: 1px;
120
+ --spacing-2: 0.125rem;
120
121
  --spacing-4: 0.25rem;
122
+ --spacing-6: 0.375rem;
121
123
  --spacing-8: 0.5rem;
122
124
  --spacing-12: 0.75rem;
123
125
  --spacing-14: 0.875rem;
@@ -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
 
Binary file
@@ -114,7 +114,9 @@ module.exports = {
114
114
  spacing: {
115
115
  0: "var(--spacing-0)",
116
116
  1: "var(--spacing-1)",
117
+ 2: "var(--spacing-2)",
117
118
  4: "var(--spacing-4)",
119
+ 6: "var(--spacing-6)",
118
120
  8: "var(--spacing-8)",
119
121
  12: "var(--spacing-12)",
120
122
  14: "var(--spacing-14)",