@ably/ui 8.7.0-dev.4de588d → 8.7.0-dev.52da22c

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 (135) hide show
  1. package/README.md +7 -3
  2. package/core/Code/component.js +1 -1
  3. package/core/Code.jsx +108 -88
  4. package/core/CompanyAutocomplete/component.js +2 -1
  5. package/core/CompanyAutocomplete/component.js.LICENSE.txt +1 -0
  6. package/core/ConnectStateWrapper/component.js +1 -1
  7. package/core/ConnectStateWrapper.jsx +7 -7
  8. package/core/ContactFooter/component.js +1 -1
  9. package/core/ContactFooter.jsx +12 -12
  10. package/core/CookieMessage/component.js +1 -1
  11. package/core/CookieMessage.jsx +10 -10
  12. package/core/CustomerLogos/component.js +1 -1
  13. package/core/CustomerLogos.jsx +7 -7
  14. package/core/DropdownMenu/component.js +1 -1
  15. package/core/DropdownMenu.jsx +11 -11
  16. package/core/FeatureFooter/component.js +1 -1
  17. package/core/FeaturedLink/component.js +1 -1
  18. package/core/FeaturedLink.jsx +10 -10
  19. package/core/Flash/component.js +1 -1
  20. package/core/Flash.jsx +19 -19
  21. package/core/Footer/component.css +11 -1
  22. package/core/Footer/component.js +1 -1
  23. package/core/Footer.jsx +71 -76
  24. package/core/Icon/component.js +1 -1
  25. package/core/Icon.jsx +7 -7
  26. package/core/Loader/component.js +1 -1
  27. package/core/Loader.jsx +7 -7
  28. package/core/Logo/component.js +1 -1
  29. package/core/Logo.jsx +7 -7
  30. package/core/Meganav/component.css +59 -20
  31. package/core/Meganav/component.js +1 -1
  32. package/core/Meganav/component.json +1 -1
  33. package/core/Meganav.jsx +955 -1047
  34. package/core/MeganavBlogPostsList/component.js +2 -1
  35. package/core/MeganavBlogPostsList/component.js.LICENSE.txt +1 -0
  36. package/core/MeganavBlogPostsList.jsx +13 -13
  37. package/core/MeganavContentCompany/component.js +1 -1
  38. package/core/MeganavContentCompany.jsx +328 -731
  39. package/core/MeganavContentDevelopers/component.js +1 -1
  40. package/core/MeganavContentDevelopers.jsx +108 -79
  41. package/core/{MeganavContentPlatform → MeganavContentProducts}/component.js +1 -1
  42. package/core/{MeganavContentPlatform.jsx → MeganavContentProducts.jsx} +34 -58
  43. package/core/MeganavContentUseCases/component.js +1 -1
  44. package/core/MeganavContentUseCases.jsx +62 -54
  45. package/core/MeganavControl/component.js +1 -1
  46. package/core/MeganavControl.jsx +10 -10
  47. package/core/MeganavControlMobileDropdown/component.js +1 -1
  48. package/core/MeganavControlMobileDropdown.jsx +11 -11
  49. package/core/MeganavControlMobilePanelClose/component.js +1 -1
  50. package/core/MeganavControlMobilePanelClose.jsx +10 -10
  51. package/core/MeganavControlMobilePanelOpen/component.js +1 -1
  52. package/core/MeganavControlMobilePanelOpen.jsx +10 -10
  53. package/core/MeganavItemsDesktop/component.js +1 -1
  54. package/core/MeganavItemsDesktop.jsx +17 -17
  55. package/core/MeganavItemsMobile/component.js +1 -1
  56. package/core/MeganavItemsMobile.jsx +39 -39
  57. package/core/MeganavItemsSignedIn/component.js +1 -1
  58. package/core/MeganavItemsSignedIn.jsx +33 -33
  59. package/core/MeganavSearch/component.js +1 -1
  60. package/core/MeganavSearch.jsx +23 -23
  61. package/core/MeganavSearchAutocomplete/component.js +1 -1
  62. package/core/MeganavSearchAutocomplete.jsx +4 -4
  63. package/core/MeganavSearchPanel/component.js +1 -1
  64. package/core/MeganavSearchPanel.jsx +19 -19
  65. package/core/MeganavSearchSuggestions/component.js +1 -1
  66. package/core/MeganavSearchSuggestions.jsx +13 -13
  67. package/core/Notice/component.js +1 -1
  68. package/core/Notice.jsx +30 -30
  69. package/core/Showcase/component.js +1 -1
  70. package/core/Showcase.jsx +1 -1
  71. package/core/SignOutLink/component.js +1 -1
  72. package/core/SignOutLink.jsx +7 -7
  73. package/core/Slider/component.js +1 -1
  74. package/core/Slider.jsx +14 -14
  75. package/core/Uptime/component.js +1 -1
  76. package/core/Uptime.jsx +300 -715
  77. package/core/images/best-support-2023.svg +1 -0
  78. package/core/images/fastest-implementation-2023.svg +1 -0
  79. package/core/images/high-performer-2023.svg +1 -0
  80. package/core/images/highest-user-adoption-2023.svg +1 -0
  81. package/core/scripts.js +2 -1
  82. package/core/scripts.js.LICENSE.txt +1 -0
  83. package/core/sprites.svg +93 -0
  84. package/core/styles.css +1 -7
  85. package/package.json +5 -5
  86. package/reset/scripts.js +1 -1
  87. package/reset/styles.css +1 -11
  88. package/src/core/Footer/component.css +11 -1
  89. package/src/core/Footer/component.html.erb +42 -47
  90. package/src/core/Footer/component.jsx +45 -53
  91. package/src/core/HeadwayWidget/HeadwayWidget.jsx +229 -0
  92. package/src/core/HeadwayWidget/index.js +5 -0
  93. package/src/core/Meganav/MeganavHeadwayPortal.jsx +20 -0
  94. package/src/core/Meganav/component.css +59 -18
  95. package/src/core/Meganav/component.json +1 -1
  96. package/src/core/Meganav/component.jsx +15 -11
  97. package/src/core/Meganav/component.rb +4 -4
  98. package/src/core/MeganavContentCompany/component.html.erb +9 -0
  99. package/src/core/MeganavContentCompany/component.jsx +9 -0
  100. package/src/core/MeganavContentDevelopers/component.html.erb +30 -13
  101. package/src/core/MeganavContentDevelopers/component.js +16 -0
  102. package/src/core/MeganavContentDevelopers/component.jsx +35 -15
  103. package/src/core/{MeganavContentPlatform → MeganavContentProducts}/component.html.erb +15 -33
  104. package/src/core/{MeganavContentPlatform → MeganavContentProducts}/component.jsx +18 -39
  105. package/src/core/{MeganavContentPlatform → MeganavContentProducts}/component.rb +1 -1
  106. package/src/core/MeganavContentUseCases/component.html.erb +42 -38
  107. package/src/core/MeganavContentUseCases/component.jsx +41 -38
  108. package/src/core/MeganavItemsDesktop/component.jsx +1 -1
  109. package/src/core/MeganavItemsDesktop/component.rb +1 -1
  110. package/src/core/core.rb +8 -4
  111. package/src/core/icons/icon-display-asset-tracking-col.svg +18 -0
  112. package/src/core/icons/icon-display-data-broadcast-col.svg +26 -0
  113. package/src/core/icons/icon-display-data-synchronization-col.svg +14 -0
  114. package/src/core/icons/icon-display-events-col.svg +13 -0
  115. package/src/core/icons/icon-display-examples-col.svg +11 -0
  116. package/src/core/icons/icon-display-kafka-at-the-edge-col.svg +8 -0
  117. package/src/core/icons/icon-display-push-notifications-col.svg +6 -0
  118. package/src/core/icons/icon-social-x.svg +3 -0
  119. package/src/core/icons/icon-tech-apachekafka.svg +3 -0
  120. package/src/core/images/best-support-2023.svg +1 -0
  121. package/src/core/images/fastest-implementation-2023.svg +1 -0
  122. package/src/core/images/high-performer-2023.svg +1 -0
  123. package/src/core/images/highest-user-adoption-2023.svg +1 -0
  124. package/src/core/styles/text.css +1 -1
  125. package/src/core/utils/syntax-highlighter-registry.js +2 -0
  126. package/src/core/utils/syntax-highlighter.js +5 -0
  127. package/core/.DS_Store +0 -0
  128. package/core/DropdownMenuPreview/component.js +0 -6
  129. package/core/DropdownMenuPreview.jsx +0 -6
  130. package/core/Meganav/component.js.LICENSE.txt +0 -7
  131. package/core/MeganavSearchAutocomplete/component.js.LICENSE.txt +0 -7
  132. package/core/Notice/component.js.LICENSE.txt +0 -9
  133. package/src/.DS_Store +0 -0
  134. package/src/core/.DS_Store +0 -0
  135. /package/src/core/{MeganavContentPlatform → MeganavContentProducts}/component.js +0 -0
@@ -1,18 +1,18 @@
1
1
  <footer class="bg-light-grey font-sans antialiased" data-id="footer">
2
- <div class="max-w-screen-xl mx-auto py-32 sm:py-40 lg:py-64 ui-grid-gap ui-grid-px grid grid-cols-6">
3
- <div class="col-span-full lg:col-span-2">
2
+ <div class="max-w-screen-xl mx-auto py-32 sm:py-40 md:py-64 ui-grid-gap ui-grid-px grid grid-cols-6">
3
+ <div class="col-span-full md:col-span-2">
4
4
  <div class="flex flex-row p-menu-row-snug">
5
5
  <%= image_tag(ably_stack_path, alt: "Ably homepage", class: "mr-24 -mt-16") %>
6
6
  <h2 class="text-overline2 col-span-full font-medium uppercase tracking-widen-0.1">The Ably Platform</h2>
7
7
  </div>
8
- <div class="grid grid-cols-4 lg:col-span-2">
9
- <p class="text-p3 py-16 font-medium p-menu-row-snug col-span-3">
8
+ <div class="md:col-span-4 md:w-3/4 xs:w-3/5 w-full">
9
+ <p class="text-p3 py-16 font-medium p-menu-row-snug">
10
10
  Easily power any realtime experience in your application via a simple API that handles everything realtime.
11
11
  </p>
12
12
  </div>
13
- <ul class="grid xs:grid-cols-2 gap-x-8 md:gap-x-24 xl:gap-x-32 md:grid-cols-1">
13
+ <ul class="grid grid-cols-1">
14
14
  <li class="p-menu-row-snug">
15
- <%= link_to 'Pub/sub messaging', abs_url("/pub-sub-messaging"), class: "ui-footer-menu-row-link" %>
15
+ <%= link_to 'Pub/sub messaging', abs_url("/solutions/channels"), class: "ui-footer-menu-row-link" %>
16
16
  </li>
17
17
  <li class="p-menu-row-snug">
18
18
  <%= link_to 'Push notifications', abs_url("/push-notifications"), class: "ui-footer-menu-row-link" %>
@@ -23,12 +23,9 @@
23
23
  <li class="p-menu-row-snug">
24
24
  <%= link_to 'Multiple protocol messaging', abs_url("/protocols"), class: "ui-footer-menu-row-link" %>
25
25
  </li>
26
- <li class="p-menu-row-snug">
27
- <%= link_to 'Streaming data sources', abs_url("/hub"), class: "ui-footer-menu-row-link" %>
28
- </li>
29
26
  </ul>
30
27
  </div>
31
- <div class="col-span-full xs:col-span-3 lg:col-span-1">
28
+ <div class="col-span-full xs:col-span-3 md:col-span-1">
32
29
  <h2 class="ui-footer-col-title">Ably is for</h2>
33
30
  <ul>
34
31
  <li class="p-menu-row-snug">
@@ -49,9 +46,6 @@
49
46
  <li class="p-menu-row-snug">
50
47
  <%= link_to 'Healthcare', abs_url("/solutions/healthcare"), class: "ui-footer-menu-row-link" %>
51
48
  </li>
52
- <li class="p-menu-row-snug">
53
- <%= link_to 'Streaming data sources', abs_url("/hub"), class: "ui-footer-menu-row-link" %>
54
- </li>
55
49
  <li class="p-menu-row-snug">
56
50
  <%= link_to 'eCommerce & Retail', abs_url("/solutions/ecommerce-and-retail"), class: "ui-footer-menu-row-link" %>
57
51
  </li>
@@ -66,7 +60,7 @@
66
60
  </li>
67
61
  </ul>
68
62
  </div>
69
- <div class="col-span-full xs:col-span-3 lg:col-span-1">
63
+ <div class="col-span-full xs:col-span-3 md:col-span-1">
70
64
  <h2 class="ui-footer-col-title">Developers</h2>
71
65
  <ul>
72
66
  <li class="p-menu-row-snug">
@@ -87,13 +81,13 @@
87
81
  <li class="p-menu-row-snug">
88
82
  <%= link_to 'SDKs', abs_url("/download"), class: "ui-footer-menu-row-link" %>
89
83
  </li>
90
- <li class="p-menu-row-snug flex items-center">
84
+ <li class="p-menu-row-snug flex items-center -mt-4">
91
85
  <a class="pr-8 ui-footer-menu-row-link" href="https://status.ably.com/">System status</a>
92
- <iframe class="w-24 h-24 mt-4" src="https://status.ably.com/embed/icon" allowtransparency="true" frameborder="0" scrolling="no"></iframe>
86
+ <iframe class="w-20 h-20 mb-2" src="https://status.ably.com/embed/icon" allowtransparency="true" frameborder="0" scrolling="no"></iframe>
93
87
  </li>
94
88
  </ul>
95
89
  </div>
96
- <div class="col-span-full xs:col-span-3 lg:col-span-1">
90
+ <div class="col-span-full xs:col-span-3 md:col-span-1">
97
91
  <h2 class="ui-footer-col-title">WHY ABLY</h2>
98
92
  <ul>
99
93
  <li class="p-menu-row-snug">
@@ -116,7 +110,7 @@
116
110
  </li>
117
111
  </ul>
118
112
  </div>
119
- <div class="col-span-full xs:col-span-3 lg:col-span-1">
113
+ <div class="col-span-full xs:col-span-3 md:col-span-1">
120
114
  <h2 class="ui-footer-col-title">ABOUT</h2>
121
115
  <ul>
122
116
  <li class="p-menu-row-snug">
@@ -144,16 +138,16 @@
144
138
  </div>
145
139
  </div>
146
140
  <div class="max-w-screen-xl ui-grid-px mx-auto">
147
- <hr class="border-t border-mid-grey" />
141
+ <hr class="border-t border-mid-grey my-0"/>
148
142
  </div>
149
143
  <%# Twitter + Glassdoor SM * above + Glassdoor XS + Badges %>
150
- <div class="max-w-screen-xl mx-auto py-24 md:py-40 lg:py-32 grid ui-grid-gap ui-grid-px sm:grid-cols-2">
151
- <div class="">
152
- <div class="flex flex-col lg:flex-row flex-auto ml-8 sm:col-span-1 lg:col-span-2">
144
+ <div class="max-w-screen-xl mx-auto py-16 grid ui-grid-gap ui-grid-px sm:grid-cols-2">
145
+ <div class="md:flex md:items-center">
146
+ <div class="flex flex-col md:flex-row flex-auto ml-8 sm:col-span-1 md:col-span-2">
153
147
  <div class="">
154
- <div class="flex items-center pb-24">
155
- <a class="h-24 pr-24 text-cool-black hover:text-icon-twitter" href="https://twitter.com/ablyrealtime" title="Ably on Twitter">
156
- <%= render(AblyUi::Core::Icon.new(name: "twitter", size: "1.5rem")) %>
148
+ <div class="flex pb-24">
149
+ <a class="h-24 pr-24 text-cool-black hover:text-icon-twitter" href="https://twitter.com/ablyrealtime" title="Ably on X">
150
+ <%= render(AblyUi::Core::Icon.new(name: "icon-social-x", size: "1.5rem")) %>
157
151
  </a>
158
152
  <a
159
153
  class="h-24 pr-24 text-cool-black hover:text-icon-linkedin"
@@ -172,7 +166,7 @@
172
166
  </div>
173
167
  <%# GLASSDOOR on SM and Above %>
174
168
  <div class="xs:hidden sm:block ui-footer-glassdoor">
175
- <div class="flex sm:pt-24 lg:pt-0 sm:border-t sm:border-l-0 lg:border-t-0 lg:border-l sm:border-mid-grey sm:w-3/4 lg:w-full lg:pl-24">
169
+ <div class="flex sm:pt-24 md:pt-0 sm:border-t sm:border-l-0 md:border-t-0 md:border-l sm:border-mid-grey sm:w-3/4 md:w-full md:pl-24">
176
170
  <a
177
171
  href="https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm"
178
172
  class="h-24 text-cool-black hover:text-icon-glassdoor"
@@ -194,7 +188,7 @@
194
188
  <div class="border-t border-mid-grey w-full"></div>
195
189
  <div class="flex py-24">
196
190
  <a
197
- class="h-24 pr-24 text-cool-black hover:text-icon-glassdoor"
191
+ class="h-24 pr-16 text-cool-black hover:text-icon-glassdoor"
198
192
  href="https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm"
199
193
  title="Ably reviews on glassdoor"
200
194
  >
@@ -209,50 +203,51 @@
209
203
  </div>
210
204
  </div>
211
205
  </div>
212
- <div class="col-span-full sm:col-span-1 inline-flex sm:ml-auto">
213
- <%= image_tag(highest_user_adoption, alt: "Highest User Adoption 2022", class: "mr-24 w-96 h-96") %>
214
- <%= image_tag(users_love_us, alt: "Users Love Us", class: "mr-24 w-96 h-96") %>
215
- <%= image_tag(highest_performer, alt: "High Performer 2022", class: "mr-24 w-96 h-96") %>
206
+ <div class="col-span-full sm:col-span-1 inline-flex sm:ml-auto sm:items-center">
207
+ <%= image_tag(highest_user_adoption, alt: "Highest User Adoption 2023", class: "mr-24 h-80") %>
208
+ <%= image_tag(best_support, alt: "Best Support 2023", class: "mr-24 h-80") %>
209
+ <%= image_tag(fastest_implementation, alt: "Fastest Implementation 2023", class: "mr-24 h-80") %>
210
+ <%= image_tag(highest_performer, alt: "High Performer 2023", class: "mr-24 h-80") %>
216
211
  </div>
217
212
  </div>
218
213
  <div class="max-w-screen-xl ui-grid-px mx-auto">
219
- <hr class="border-t border-mid-grey" />
214
+ <hr class="border-t border-mid-grey my-0"/>
220
215
  </div>
221
- <div class="max-w-screen-xl mx-auto py-24 md:py-40 lg:py-32 md:grid md:grid-cols-2 ui-grid-gap ui-grid-px ">
222
- <div class="flex flex-col flex-auto pb-40 ml-8 col-span-full md:col-span-1">
223
- <div class="inline-flex">
216
+ <div class="max-w-screen-xl mx-auto py-24 sm:py-40 md:py-32 md:grid md:grid-cols-2 ui-grid-gap ui-grid-px">
217
+ <div class="flex ml-8 col-span-full sm:col-span-1 md:pb-16 items-center ui-footer-bottom-links">
218
+ <div class="flex">
224
219
  <%= link_to 'Cookies', abs_url("/privacy"), class: "pr-24 ui-footer-link" %>
225
220
  <%= link_to 'Legals', abs_url("/legals"), class: "pr-24 ui-footer-link" %>
226
221
  <%= link_to 'Data Protection', abs_url("/data-protection"), class: "pr-24 ui-footer-link" %>
227
222
  <%= link_to 'Privacy', abs_url("/privacy"), class: "ui-footer-link" %>
228
223
  </div>
229
224
  </div>
230
- <div class="xs:grid xs:grid-cols-2 sm:grid-cols-4 xs:pl-16 md:pl-0 ">
225
+ <div class="xs:grid xs:grid-cols-2 sm:grid-cols-4 xs:pl-16 sm:pl-8 md:justify-items-end">
231
226
  <div class="flex mr-24">
232
- <%= render(AblyUi::Core::Icon.new(name: "icon-gui-tick", color: "text-active-orange", size: "1.5rem", additional_css:"bg-white rounded-full mr-12")) %>
227
+ <%= render(AblyUi::Core::Icon.new(name: "icon-gui-tick", color: "text-active-orange", size: "1.5rem", additional_css:"bg-white rounded-full mr-12 ui-footer-tick-icon")) %>
233
228
  <div>
234
- <p class="ui-footer-compliance-text font-medium">SOC 2 Type 2</p>
229
+ <p class="ui-footer-compliance-text font-medium whitespace-nowrap">SOC 2 Type 2</p>
235
230
  <p class="ui-footer-compliance-text font-light mb-24">Certified</p>
236
231
  </div>
237
232
  </div>
238
- <div class="flex mr-24 sm:col-start-2">
239
- <%= render(AblyUi::Core::Icon.new(name: "icon-gui-tick", color: "text-active-orange", size: "1.5rem", additional_css:"bg-white rounded-full mr-12")) %>
233
+ <div class="flex mr-24 md:col-start-2">
234
+ <%= render(AblyUi::Core::Icon.new(name: "icon-gui-tick", color: "text-active-orange", size: "1.5rem", additional_css:"bg-white rounded-full mr-12 ui-footer-tick-icon")) %>
240
235
  <div>
241
- <p class="ui-footer-compliance-text font-medium">HIPAA</p>
236
+ <p class="ui-footer-compliance-text font-medium whitespace-nowrap">HIPAA</p>
242
237
  <p class="ui-footer-compliance-text font-light mb-24">Compliant</p>
243
238
  </div>
244
239
  </div>
245
- <div class="flex mr-24 sm:col-start-3">
246
- <%= render(AblyUi::Core::Icon.new(name: "icon-gui-tick", color: "text-active-orange", size: "1.5rem", additional_css:"bg-white rounded-full mr-12")) %>
240
+ <div class="flex mr-24 md:col-start-3">
241
+ <%= render(AblyUi::Core::Icon.new(name: "icon-gui-tick", color: "text-active-orange", size: "1.5rem", additional_css:"bg-white rounded-full mr-12 ui-footer-tick-icon")) %>
247
242
  <div>
248
- <p class="ui-footer-compliance-text font-medium">EU GDPR</p>
243
+ <p class="ui-footer-compliance-text font-medium whitespace-nowrap">EU GDPR</p>
249
244
  <p class="ui-footer-compliance-text font-light mb-24">Certified</p>
250
245
  </div>
251
246
  </div>
252
- <div class="flex mr-24 sm:col-start-4">
253
- <%= render(AblyUi::Core::Icon.new(name: "icon-gui-tick", color: "text-active-orange", size: "1.5rem", additional_css:"bg-white rounded-full mr-12")) %>
247
+ <div class="flex mr-24 md:col-start-4">
248
+ <%= render(AblyUi::Core::Icon.new(name: "icon-gui-tick", color: "text-active-orange", size: "1.5rem", additional_css:"bg-white rounded-full mr-12 ui-footer-tick-icon")) %>
254
249
  <div>
255
- <p class="ui-footer-compliance-text font-medium">256-bit AES</p>
250
+ <p class="ui-footer-compliance-text font-medium whitespace-nowrap">256-bit AES</p>
256
251
  <p class="ui-footer-compliance-text font-light mb-24">Encryption</p>
257
252
  </div>
258
253
  </div>
@@ -9,21 +9,21 @@ export default function Footer({ paths, urlBase }) {
9
9
 
10
10
  return (
11
11
  <footer className="bg-light-grey font-sans antialiased" data-id="footer">
12
- <div className="max-w-screen-xl mx-auto py-32 sm:py-40 lg:py-64 ui-grid-gap ui-grid-px grid grid-cols-6">
13
- <div className="col-span-full lg:col-span-2">
12
+ <div className="max-w-screen-xl mx-auto py-32 sm:py-40 md:py-64 ui-grid-gap ui-grid-px grid grid-cols-6">
13
+ <div className="col-span-full md:col-span-2">
14
14
  <div className="flex flex-row p-menu-row-snug">
15
15
  <img className="mr-24 -mt-16" src={paths.ablyStack} alt="Ably homepage" />
16
16
  <h2 className="text-overline2 col-span-full font-medium uppercase tracking-widen-0.1">The Ably Platform</h2>
17
17
  </div>
18
- <div className="grid grid-cols-4 lg:col-span-2">
19
- <p className="text-p3 py-16 font-medium p-menu-row-snug col-span-3">
18
+ <div className="md:col-span-4 md:w-3/4 xs:w-3/5 w-full">
19
+ <p className="text-p3 py-16 font-medium p-menu-row-snug">
20
20
  Easily power any realtime experience in your application via a simple API that handles everything realtime.
21
21
  </p>
22
22
  </div>
23
23
 
24
- <ul className="grid xs:grid-cols-2 gap-x-8 md:gap-x-24 xl:gap-x-32 md:grid-cols-1">
24
+ <ul className="grid grid-cols-1">
25
25
  <li className="p-menu-row-snug">
26
- <a href={absUrl("/pub-sub-messaging")} className="ui-footer-menu-row-link">
26
+ <a href={absUrl("/solutions/channels")} className="ui-footer-menu-row-link">
27
27
  Pub/sub messaging
28
28
  </a>
29
29
  </li>
@@ -42,15 +42,10 @@ export default function Footer({ paths, urlBase }) {
42
42
  Multiple protocol messaging
43
43
  </a>
44
44
  </li>
45
- <li className="p-menu-row-snug">
46
- <a href={absUrl("/hub")} className="ui-footer-menu-row-link">
47
- Streaming data sources
48
- </a>
49
- </li>
50
45
  </ul>
51
46
  </div>
52
47
 
53
- <div className="col-span-full xs:col-span-3 lg:col-span-1">
48
+ <div className="col-span-full xs:col-span-3 md:col-span-1">
54
49
  <h2 className="ui-footer-col-title">Ably is for</h2>
55
50
  <ul>
56
51
  <li className="p-menu-row-snug">
@@ -83,11 +78,6 @@ export default function Footer({ paths, urlBase }) {
83
78
  Healthcare
84
79
  </a>
85
80
  </li>
86
- <li className="p-menu-row-snug">
87
- <a href={absUrl("/hub")} className="ui-footer-menu-row-link">
88
- Streaming data sources
89
- </a>
90
- </li>
91
81
  <li className="p-menu-row-snug">
92
82
  <a href={absUrl("/solutions/ecommerce-and-retail")} className="ui-footer-menu-row-link">
93
83
  eCommerce &amp; Retail
@@ -111,7 +101,7 @@ export default function Footer({ paths, urlBase }) {
111
101
  </ul>
112
102
  </div>
113
103
 
114
- <div className="col-span-full xs:col-span-3 lg:col-span-1">
104
+ <div className="col-span-full xs:col-span-3 md:col-span-1">
115
105
  <h2 className="ui-footer-col-title">Developers</h2>
116
106
  <ul>
117
107
  <li className="p-menu-row-snug">
@@ -144,12 +134,12 @@ export default function Footer({ paths, urlBase }) {
144
134
  SDKs
145
135
  </a>
146
136
  </li>
147
- <li className="p-menu-row-snug flex items-center">
137
+ <li className="p-menu-row-snug flex items-center -mt-4">
148
138
  <a className="pr-8 ui-footer-menu-row-link" href="https://status.ably.com/">
149
139
  System status
150
140
  </a>
151
141
  <iframe
152
- className="w-24 h-24 mt-4"
142
+ className="w-20 h-20 mb-2"
153
143
  src="https://status.ably.com/embed/icon"
154
144
  allowtransparency="true"
155
145
  frameBorder="0"
@@ -160,7 +150,7 @@ export default function Footer({ paths, urlBase }) {
160
150
  </ul>
161
151
  </div>
162
152
 
163
- <div className="col-span-full xs:col-span-3 lg:col-span-1">
153
+ <div className="col-span-full xs:col-span-3 md:col-span-1">
164
154
  <h2 className="ui-footer-col-title">WHY ABLY</h2>
165
155
  <ul>
166
156
  <li className="p-menu-row-snug">
@@ -196,7 +186,7 @@ export default function Footer({ paths, urlBase }) {
196
186
  </ul>
197
187
  </div>
198
188
 
199
- <div className="col-span-full xs:col-span-3 lg:col-span-1">
189
+ <div className="col-span-full xs:col-span-3 md:col-span-1">
200
190
  <h2 className="ui-footer-col-title">ABOUT</h2>
201
191
  <ul>
202
192
  <li className="p-menu-row-snug">
@@ -238,16 +228,16 @@ export default function Footer({ paths, urlBase }) {
238
228
  </div>
239
229
  </div>
240
230
  <div className="max-w-screen-xl ui-grid-px mx-auto">
241
- <hr className="border-t border-mid-grey" />
231
+ <hr className="border-t border-mid-grey my-0" />
242
232
  </div>
243
- {/* Twitter + Glassdoor SM * above + Glassdoor XS + Badges*/}
244
- <div className="max-w-screen-xl mx-auto py-24 md:py-40 lg:py-32 grid ui-grid-gap ui-grid-px sm:grid-cols-2">
245
- <div className="">
246
- <div className="flex flex-col lg:flex-row flex-auto ml-8 sm:col-span-1 lg:col-span-2">
233
+ {/* Twitter + Glassdoor SM & above + Glassdoor XS + Badges*/}
234
+ <div className="max-w-screen-xl mx-auto py-16 grid ui-grid-gap ui-grid-px sm:grid-cols-2">
235
+ <div className="md:flex md:items-center">
236
+ <div className="flex flex-col md:flex-row flex-auto ml-8 sm:col-span-1 md:col-span-2">
247
237
  <div className="">
248
- <div className="flex items-center pb-24">
249
- <a className="h-24 pr-24 text-cool-black hover:text-icon-twitter" href="https://twitter.com/ablyrealtime" title="Ably on Twitter">
250
- <Icon name="twitter" size="1.5rem" />
238
+ <div className="flex pb-24">
239
+ <a className="h-24 pr-24 text-cool-black hover:text-icon-twitter" href="https://twitter.com/ablyrealtime" title="Ably on X">
240
+ <Icon name="icon-social-x" size="1.5rem" />
251
241
  </a>
252
242
  <a
253
243
  className="h-24 pr-24 text-cool-black hover:text-icon-linkedin"
@@ -266,7 +256,7 @@ export default function Footer({ paths, urlBase }) {
266
256
  </div>
267
257
  {/* GLASSDOOR on SM and Above */}
268
258
  <div className="xs:hidden sm:block ui-footer-glassdoor">
269
- <div className="flex sm:pt-24 lg:pt-0 sm:border-t sm:border-l-0 lg:border-t-0 lg:border-l sm:border-mid-grey sm:w-3/4 lg:w-full lg:pl-24">
259
+ <div className="flex sm:pt-24 md:pt-0 sm:border-t sm:border-l-0 md:border-t-0 md:border-l sm:border-mid-grey sm:w-3/4 md:w-full md:pl-24">
270
260
  <a
271
261
  href="https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm"
272
262
  className="h-24 text-cool-black hover:text-icon-glassdoor"
@@ -288,7 +278,7 @@ export default function Footer({ paths, urlBase }) {
288
278
  <div className="border-t border-mid-grey w-full"></div>
289
279
  <div className="flex py-24">
290
280
  <a
291
- className="h-24 pr-24 text-cool-black hover:text-icon-glassdoor"
281
+ className="h-24 pr-16 text-cool-black hover:text-icon-glassdoor"
292
282
  href="https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm"
293
283
  title="Ably reviews on glassdoor"
294
284
  >
@@ -304,19 +294,20 @@ export default function Footer({ paths, urlBase }) {
304
294
  </div>
305
295
  </div>
306
296
 
307
- <div className="col-span-full sm:col-span-1 inline-flex sm:ml-auto">
308
- <img className="mr-24 w-96 h-96" src={paths.highestUserAdoption} alt="Highest User Adoption 2022" />
309
- <img className="mr-24 w-96 h-96" src={paths.usersLoveUs} alt="Users Love Us" />
310
- <img className="mr-24 w-96 h-96" src={paths.highestPerformer} alt="High Performer 2022" />
297
+ <div className="col-span-full sm:col-span-1 inline-flex sm:ml-auto sm:items-center">
298
+ <img className="mr-24 h-80" src={paths.highestUserAdoption} alt="Highest User Adoption 2023" />
299
+ <img className="mr-24 h-80" src={paths.bestSupport} alt="Best Support 2023" />
300
+ <img className="mr-24 h-80" src={paths.fastestImplementation} alt="Fastest Implementation 2023" />
301
+ <img className="mr-24 h-80" src={paths.highestPerformer} alt="High Performer 2023" />
311
302
  </div>
312
303
  </div>
313
304
 
314
305
  <div className="max-w-screen-xl ui-grid-px mx-auto">
315
- <hr className="border-t border-mid-grey" />
306
+ <hr className="border-t border-mid-grey my-0" />
316
307
  </div>
317
- <div className="max-w-screen-xl mx-auto py-24 md:py-40 lg:py-32 md:grid md:grid-cols-2 ui-grid-gap ui-grid-px ">
318
- <div className="flex flex-col flex-auto pb-40 ml-8 col-span-full md:col-span-1">
319
- <div className="inline-flex">
308
+ <div className="max-w-screen-xl mx-auto py-24 sm:py-40 md:py-32 md:grid md:grid-cols-2 ui-grid-gap ui-grid-px">
309
+ <div className="flex ml-8 col-span-full sm:col-span-1 md:pb-16 items-center ui-footer-bottom-links">
310
+ <div className="flex">
320
311
  <a href={absUrl("/privacy")} className="pr-24 ui-footer-link">
321
312
  Cookies
322
313
  </a>
@@ -331,32 +322,32 @@ export default function Footer({ paths, urlBase }) {
331
322
  </a>
332
323
  </div>
333
324
  </div>
334
- <div className="xs:grid xs:grid-cols-2 sm:grid-cols-4 xs:pl-16 md:pl-0 ">
325
+ <div className="xs:grid xs:grid-cols-2 sm:grid-cols-4 xs:pl-16 sm:pl-8 md:justify-items-end">
335
326
  <div className="flex mr-24">
336
- <Icon name="icon-gui-tick" color="text-active-orange" size="1.5rem" additionalCSS="bg-white rounded-full mr-12" />
327
+ <Icon name="icon-gui-tick" color="text-active-orange" size="1.5rem" additionalCSS="bg-white rounded-full mr-12 ui-footer-tick-icon" />
337
328
  <div>
338
- <p className="ui-footer-compliance-text font-medium">SOC 2 Type 2</p>
329
+ <p className="ui-footer-compliance-text font-medium whitespace-nowrap">SOC 2 Type 2</p>
339
330
  <p className="ui-footer-compliance-text font-light mb-24">Certified</p>
340
331
  </div>
341
332
  </div>
342
- <div className="flex mr-24 sm:col-start-2">
343
- <Icon name="icon-gui-tick" color="text-active-orange" size="1.5rem" additionalCSS="bg-white rounded-full mr-12" />
333
+ <div className="flex mr-24 md:col-start-2">
334
+ <Icon name="icon-gui-tick" color="text-active-orange" size="1.5rem" additionalCSS="bg-white rounded-full mr-12 ui-footer-tick-icon" />
344
335
  <div>
345
- <p className="ui-footer-compliance-text font-medium">HIPAA</p>
336
+ <p className="ui-footer-compliance-text font-medium whitespace-nowrap">HIPAA</p>
346
337
  <p className="ui-footer-compliance-text font-light mb-24">Compliant</p>
347
338
  </div>
348
339
  </div>
349
- <div className="flex mr-24 sm:col-start-3">
350
- <Icon name="icon-gui-tick" color="text-active-orange" size="1.5rem" additionalCSS="bg-white rounded-full mr-12" />
340
+ <div className="flex mr-24 md:col-start-3">
341
+ <Icon name="icon-gui-tick" color="text-active-orange" size="1.5rem" additionalCSS="bg-white rounded-full mr-12 ui-footer-tick-icon" />
351
342
  <div>
352
- <p className="ui-footer-compliance-text font-medium">EU GDPR</p>
343
+ <p className="ui-footer-compliance-text font-medium whitespace-nowrap">EU GDPR</p>
353
344
  <p className="ui-footer-compliance-text font-light mb-24">Certified</p>
354
345
  </div>
355
346
  </div>
356
- <div className="flex mr-24 sm:col-start-4">
357
- <Icon name="icon-gui-tick" color="text-active-orange" size="1.5rem" additionalCSS="bg-white rounded-full mr-12" />
347
+ <div className="flex mr-24 md:col-start-4">
348
+ <Icon name="icon-gui-tick" color="text-active-orange" size="1.5rem" additionalCSS="bg-white rounded-full mr-12 ui-footer-tick-icon" />
358
349
  <div>
359
- <p className="ui-footer-compliance-text font-medium">256-bit AES</p>
350
+ <p className="ui-footer-compliance-text font-medium whitespace-nowrap">256-bit AES</p>
360
351
  <p className="ui-footer-compliance-text font-light mb-24">Encryption</p>
361
352
  </div>
362
353
  </div>
@@ -371,7 +362,8 @@ Footer.propTypes = {
371
362
  ablyStack: T.string,
372
363
  highestPerformer: T.string,
373
364
  highestUserAdoption: T.string,
374
- usersLoveUs: T.string,
365
+ bestSupport: T.string,
366
+ fastestImplementation: T.string,
375
367
  }),
376
368
  urlBase: T.string,
377
369
  };
@@ -0,0 +1,229 @@
1
+ import PropTypes from "prop-types";
2
+ import React, { useCallback, useEffect, useRef } from "react";
3
+
4
+ const HeadwayWidgetClassName = "HW_widget_component";
5
+ const HeadwayWidgetSelector = "." + HeadwayWidgetClassName;
6
+ const HeadwayWidgetTriggerClassName = "HW_trigger";
7
+ const HeadwayWidgetTriggerSelector = "." + HeadwayWidgetTriggerClassName;
8
+
9
+ const HeadwayWidgetTrigger = ({ widgetId, component, children }) => {
10
+ const Component = component || "div";
11
+ const className = HeadwayWidgetTriggerClassName + `_${widgetId}`;
12
+
13
+ return <Component className={className}>{children}</Component>;
14
+ };
15
+
16
+ HeadwayWidgetTrigger.defaultProps = {
17
+ widgetId: "widget-1",
18
+ };
19
+
20
+ const HeadwayWidget = ({
21
+ id,
22
+ account,
23
+ children,
24
+ widgetPosition,
25
+ badgePosition,
26
+ component,
27
+ trigger,
28
+ onWidgetReady,
29
+ onShowWidget,
30
+ onShowDetails,
31
+ onReadMore,
32
+ onHideWidget,
33
+ styles,
34
+ options,
35
+ translations,
36
+ ...rest
37
+ }) => {
38
+ const onWidgetReadyRef = useRef(onWidgetReady);
39
+ const onShowWidgetRef = useRef(onShowWidget);
40
+ const onShowDetailsRef = useRef(onShowDetails);
41
+ const onReadMoreRef = useRef(onReadMore);
42
+ const onHideWidgetRef = useRef(onHideWidget);
43
+ const optionsRef = useRef(options);
44
+ useEffect(() => {
45
+ onWidgetReadyRef.current = onWidgetReady || (options.callbacks && options.callbacks.onWidgetReady);
46
+ onShowWidgetRef.current = onShowWidget || (options.callbacks && options.callbacks.onShowWidget);
47
+ onShowDetailsRef.current = onShowDetails || (options.callbacks && options.callbacks.onShowDetails);
48
+ onReadMoreRef.current = onReadMore || (options.callbacks && options.callbacks.onReadMore);
49
+ onHideWidgetRef.current = onHideWidget || (options.callbacks && options.callbacks.onHideWidget);
50
+ optionsRef.current = options;
51
+ });
52
+
53
+ const handleWidgetReady = useCallback(() => onWidgetReadyRef.current && onWidgetReadyRef.current(), []);
54
+ const handleShowWidget = useCallback(() => onShowWidgetRef.current && onShowWidgetRef.current(), []);
55
+ const handleShowDetails = useCallback(() => onShowDetailsRef.current && onShowDetailsRef.current(), []);
56
+ const handleReadMore = useCallback(() => onReadMoreRef.current && onReadMoreRef.current(), []);
57
+ const handleHideWidget = useCallback(() => onHideWidgetRef.current && onHideWidgetRef.current(), []);
58
+
59
+ const initHeadway = useCallback(() => {
60
+ const hwConfig = {
61
+ selector: HeadwayWidgetSelector + `_${id}`,
62
+ account: account || options.account,
63
+ trigger: trigger ? HeadwayWidgetSelector + `_${id}` : options.trigger || HeadwayWidgetTriggerSelector + `_${id}`,
64
+ callbacks: {
65
+ onWidgetReady: handleWidgetReady,
66
+ onShowWidget: handleShowWidget,
67
+ onShowDetails: handleShowDetails,
68
+ onReadMore: handleReadMore,
69
+ onHideWidget: handleHideWidget,
70
+ },
71
+ translations,
72
+ widgetPosition,
73
+ badgePosition,
74
+ __component: true,
75
+ styles,
76
+ ...options,
77
+ };
78
+
79
+ const widget = window.Headway.getNewWidget();
80
+ widget.init(hwConfig);
81
+
82
+ return () => {
83
+ widget.destroy();
84
+ };
85
+ }, [account, trigger, handleWidgetReady, handleShowWidget, handleShowDetails, handleReadMore, handleHideWidget, badgePosition, widgetPosition, translations]);
86
+
87
+ useEffect(() => {
88
+ let destroy;
89
+ if (window.Headway) {
90
+ destroy = initHeadway();
91
+ } else {
92
+ const head = document.getElementsByTagName("head")[0];
93
+ const script = document.createElement("script");
94
+ script.type = "text/javascript";
95
+ const p = new Promise((resolve) => {
96
+ script.onload = () => {
97
+ const d = initHeadway();
98
+ resolve(d);
99
+ };
100
+ });
101
+
102
+ destroy = () => {
103
+ p.then((d) => d());
104
+ };
105
+ script.src = "https://cdn.headwayapp.co/widget.js";
106
+ head.appendChild(script);
107
+ }
108
+ return destroy;
109
+ }, [initHeadway]);
110
+
111
+ const Component = component || "div";
112
+
113
+ return (
114
+ <Component className={HeadwayWidgetClassName + `_${id}`} {...rest} style={{ position: "relative", display: "inline-block" }}>
115
+ {children}
116
+ </Component>
117
+ );
118
+ };
119
+
120
+ export default HeadwayWidget;
121
+
122
+ HeadwayWidget.propTypes = {
123
+ /**
124
+ * account of your Headway.
125
+ */
126
+ account: PropTypes.string.isRequired,
127
+ /**
128
+ * id of the Widget. It is required if you have more than one widget instance on the page.
129
+ */
130
+ id: PropTypes.string,
131
+ /**
132
+ * position of a badge
133
+ */
134
+ badgePosition: PropTypes.oneOf([
135
+ "top-left",
136
+ "top-center",
137
+ "top-right",
138
+ "center-left",
139
+ "center",
140
+ "center-right",
141
+ "bottom-left",
142
+ "bottom-center",
143
+ "bottom-right",
144
+ ]),
145
+ /**
146
+ * badge relative widget position
147
+ */
148
+ widgetPosition: PropTypes.oneOf(["top-left", "top-right", "center-left", "center-right", "bottom-left", "bottom-right"]),
149
+ /**
150
+ * callback fired when widget has loaded
151
+ */
152
+ onWidgetReady: PropTypes.func,
153
+ /**
154
+ * callback fired when widget is shown
155
+ */
156
+ onShowWidget: PropTypes.func,
157
+ /**
158
+ * callback fired when an item in the widget is clicked
159
+ */
160
+ onShowDetails: PropTypes.func,
161
+ /**
162
+ * callback fired when user clicks on readMore link
163
+ */
164
+ onReadMore: PropTypes.func,
165
+ /**
166
+ * callback fired when user closes the widget
167
+ */
168
+ onHideWidget: PropTypes.func,
169
+ /**
170
+ * Translating the text inside of the widget
171
+ * */
172
+ translations: PropTypes.shape({
173
+ title: PropTypes.string,
174
+ labels: PropTypes.shape({
175
+ new: PropTypes.string,
176
+ update: PropTypes.string,
177
+ improvement: PropTypes.string,
178
+ }),
179
+ readMore: PropTypes.string,
180
+ footer: PropTypes.string,
181
+ }),
182
+ /**
183
+ * options defined in classic object format. Read more at https://docs.headwayapp.co/widget
184
+ */
185
+ options: PropTypes.shape({
186
+ account: PropTypes.string,
187
+ callbacks: PropTypes.shape({
188
+ onWidgetReady: PropTypes.func,
189
+ onShowWidget: PropTypes.func,
190
+ onShowDetails: PropTypes.func,
191
+ onReadMore: PropTypes.func,
192
+ onHideWidget: PropTypes.func,
193
+ }),
194
+ translations: PropTypes.shape({
195
+ title: PropTypes.string,
196
+ labels: PropTypes.shape({
197
+ new: PropTypes.string,
198
+ update: PropTypes.string,
199
+ improvement: PropTypes.string,
200
+ }),
201
+ readMore: PropTypes.string,
202
+ footer: PropTypes.string,
203
+ }),
204
+ trigger: PropTypes.string,
205
+ }),
206
+
207
+ component: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
208
+ children: PropTypes.node,
209
+ trigger: PropTypes.string,
210
+ styles: PropTypes.object,
211
+ };
212
+
213
+ HeadwayWidget.defaultProps = {
214
+ account: "",
215
+ id: "widget-1",
216
+ badgePosition: "bottom-right",
217
+ widgetPosition: "bottom-right",
218
+ styles: {},
219
+ translations: {},
220
+ options: {},
221
+ };
222
+
223
+ HeadwayWidgetTrigger.propTypes = {
224
+ widgetId: PropTypes.string.isRequired,
225
+ component: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
226
+ children: PropTypes.node,
227
+ };
228
+
229
+ export { HeadwayWidgetTrigger };